Skip to content

fix(desktop/transcript): accurate insight-turn jumps — auto behavior + item-height estimate#349

Merged
physercoe merged 1 commit into
physercoe:mainfrom
agentfleets:desktop/insight-jump-fix
Jul 20, 2026
Merged

fix(desktop/transcript): accurate insight-turn jumps — auto behavior + item-height estimate#349
physercoe merged 1 commit into
physercoe:mainfrom
agentfleets:desktop/insight-jump-fix

Conversation

@agentfleets

Copy link
Copy Markdown
Collaborator

What

Fixes a director-reported bug in the agent transcript's INSIGHT view: clicking different turns (or error rows) jumped to the same — wrong — position instead of the turn's location.

Two surgical changes, both in desktop/src/surfaces/AgentTranscript.tsx:

  1. scrollToSeq now calls scrollToIndex with behavior: 'auto' instead of 'smooth'.
  2. The insight Virtuoso gets defaultItemHeight={120} (parity with the live list).

Root cause

Verified against the react-virtuoso 4.18.10 sources (node_modules/react-virtuoso/dist/index.mjs, scrollToIndex system ~:1100-1160):

  • For an off-screen (unmeasured) target, Virtuoso computes the target offset from estimated row heights — a running average of the rows measured so far. Transcript cards vary wildly in height, and the insight list had no defaultItemHeight, so early-measured rows skewed the average. Estimates for distant indices overshot, and the browser clamped the scroll at the same max offset (bottom) — hence different turns landing at the same position.
  • Virtuoso's smooth path only retries the landing when smoothScrollTargetReached fires, and a hard setTimeout(..., 1200) cleanup cuts that retry chain mid-flight, leaving the list wherever the last estimated fling stopped.
  • The 'auto' path instead re-fires scrollToIndex on every listRefresh (debounced 150ms) until the list stops changing — it converges to the true offset as rows get measured.

The 1.4s ev-flash that already follows a jump gives the user the orientation the smooth animation was providing, so nothing is lost visually. The added defaultItemHeight={120} improves the estimate the auto-retry converges from.

Side effect (intentional improvement, not scope creep): the live-mode lens stepper uses the same scrollToSeq, so its long-distance jumps are now accurate too.

How verified

  • Root cause verified against react-virtuoso 4.18.10 sources (no device available — CI is the gate).
  • npm ci && npm run build (desktop): clean (tsc + vite).
  • bash scripts/lint-desktop-tokens.sh: clean (66 off-token, all <= baseline, no phantom tokens).
  • git diff origin/main --stat: 1 file changed, 15 insertions(+), 1 deletion(-) — desktop/src/surfaces/AgentTranscript.tsx only.
  • No new user-visible strings (i18n untouched); no CSS, manifest, or version changes.

@physercoe physercoe left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — approve. Focused on what CI can't catch (correctness/regressions).

  • Diff matches the description; only two hunks in AgentTranscript.tsx (behavior smoothauto; defaultItemHeight={120} on the insight Virtuoso).
  • scrollToSeq is shared by both the live lens stepper and insight jumps; auto fixes the same estimated-height overshoot for both — consistent, no live-path regression.
  • defaultItemHeight={120} matches the live list exactly, so the two instances are now consistent; it only seeds the pre-measurement estimate.
  • The 1.4s ev-flash the PR cites for orientation genuinely exists and is applied on jump, so nothing visual is lost by dropping the smooth animation.
  • No index/off-by-one/behavior-string bugs; index < 0 guarded.

Non-blocking (pre-existing, not introduced here): a single virtuosoRef is shared by both Virtuoso instances — safe only because exactly one renders per mode.

@physercoe
physercoe merged commit 31f6346 into physercoe:main Jul 20, 2026
6 checks passed
physercoe pushed a commit that referenced this pull request Jul 20, 2026
physercoe pushed a commit that referenced this pull request Jul 20, 2026
…rity (#332)

Two director-reported insight-mode bugs, both fixed against the mobile
InsightTranscript reference (lib/widgets/insight_transcript.dart):

1. Turn jumps landed at the same position. A turn's `start_seq` anchors to a
   turn.start marker, which is ALWAYS_HIDDEN (never a rendered row), so the exact
   `findIndex(seq)` returned -1 and scrollToSeq bailed without moving the view.
   #349's smooth→auto change couldn't help — the index never resolved. Now, when
   there's no exact row, seek lands on the nearest visible row AT OR AFTER the
   target (the turn's first rendered event), mirroring insight_transcript.dart:1404
   ("the anchor may be a hidden marker (ACP turn.start) or filtered out"). Flash
   the row actually landed on.

2. Insight showed telemetry the live feed hides ("started M2", turn.start,
   turn.result, usage, lifecycle). Insight now applies the SAME isHiddenInFeed
   filter as live (insight_transcript.dart:1377), with a Details toggle in the
   nav header to reveal the verbose-only tier (parity with mobile's verbose chip).

Build (tsc + vite) + lint-desktop-tokens clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants