Skip to content

feat(web): make the agent-session Overview a verdict-first triage page - #637

Open
JeremyFunk wants to merge 4 commits into
mainfrom
feat/agent-session-overview-v3
Open

feat(web): make the agent-session Overview a verdict-first triage page#637
JeremyFunk wants to merge 4 commits into
mainfrom
feat/agent-session-overview-v3

Conversation

@JeremyFunk

@JeremyFunk JeremyFunk commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

What

The session detail Overview now answers the question a reader opens it with — did this session work, and if not, what exactly went wrong — instead of offering a fourth way to browse the turns next to Traces, Flow and Transcript.

  • Verdict band: Failed — <label> on the final turn (with an Open failing span deep link), Completed, with N findings, or Completed cleanly — the clean state says what the claim covers (no errors, refusals, truncated replies, stalls, or repetition).
  • Findings list (replaces the turn-by-turn digest and the rail's Failures section): discrete claims in the instrumentation's own vocabulary, red where the outcome was affected and amber where something merely looks wrong. Every row opens the span that is its evidence in the Traces view.
  • Turn health strip: one cell per turn, colored by what the findings attribute to it — spatial orientation without a turn browser. The time bar stays, with a longest-gap caption; the rail keeps cost / tokens / agents / tools.

Detectors (session-findings.ts)

All deterministic reads of captured spans, no scoring or inference:

  • grouped failure events (shared failureEvents, so verdict, list and counts cannot disagree), with prompt-growth evidence on context-window deaths where usage was reported
  • truncated replies: finish_reason length/max_tokens, deduped at the deepest reporter
  • the same tool called ≥8× within one turn
  • ≥30s of no span activity inside a turn (gaps between turns are the user thinking, never a finding)

"Terminal" means the group containing the span the final turn died on, not "occurred in the final turn" — a retried rate limit inside the failing turn stays a non-terminal finding.

Verification

  • 275 web agent-session tests pass, including new coverage for every detector and all three verdicts; typecheck and lint clean.
  • Browser-verified on /lab/agent-session: verdict and findings render over the fixture, the strip flags the failing turns, and clicking a finding lands in Traces with the span expanded and its error banner showing.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

The Overview answered "what happened" but never "was that okay?" — its
turn-by-turn digest was a fourth turn browser next to Traces, Flow and
Transcript, and on a failed session nothing linked the page to the
failing span.

The page now leads with a verdict (failed / completed with findings /
completed cleanly) and a findings list: discrete claims in the
instrumentation's own vocabulary, each linking the span that is its
evidence via the Traces view. Detectors are deterministic reads of the
captured spans — grouped failure events, truncated replies
(finish_reason length, deduped at the deepest reporter), the same tool
called 8+ times within one turn, and 30s+ stalls inside a turn. A
per-turn health strip replaces the digest for spatial orientation; the
time bar and the rail stay, minus the rail's Failures section, which
the findings list absorbs.

"Terminal" means the group containing the span the final turn died on,
not "occurred in the final turn" — a retried rate limit in the failing
turn stays a non-terminal finding.
A failed tool call is recorded as a value on an Ok span — error.type
tool_error with the message in gen_ai.tool.call.result and no status
message — so the finding row rendered bare, answering neither what went
wrong nor whether it is actionable. The evidence line now falls back to
the tool call's recorded result, read tolerantly: Maple's own agent
stamps a plain string, other vendors wrap the message in an object or
an MCP-style content array.
Maple's own toolCallJson records a bare error string as {"result": "…"}
(and an over-budget one as {truncated, prefix}), so the finding row's
prose walk found no message under its error-shaped keys and rendered
bare. Verified against the captured spans in the warehouse: the failing
query_data call carries exactly that envelope. `result` and `prefix`
join the keys the walk tries.
…ronological

The verdict sat above the two-column split, pushing the rail down and
leaving dead space beside the findings — it now leads the left column,
so Cost by model top-aligns with it. The time bar draws chronological
occupancy intervals (a mid-session stall is a hole where it happened,
not an idle block pinned left) while the legend keeps summed segments;
sub-half-percent slivers stay on the bar and drop only from the legend.
The shape strip's caption says "with errors" rather than "failed" — a
red cell marks a turn something went wrong inside, which may well have
closed cleanly, and "failed" contradicted a Completed verdict above it.
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.

1 participant