Skip to content

fix(web): a failed turn folds its trajectory like any other turn - #67

Merged
Quinntyx merged 1 commit into
mainfrom
fix/agent-trajectory-folding
Oct 29, 2026
Merged

Quinntyx merged 1 commit into
mainfrom
fix/agent-trajectory-folding

Conversation

@Quinntyx

Copy link
Copy Markdown
Owner

Problem

A failed turn stops folding. Any run that ends in a failure renders its trajectory inline — one row per tool call, per thinking block — with the failure card underneath. A turn that ran three commands and thought once produced six rows instead of a folded turn, which is the wall of rows this fixes.

The cause is in the timeline derivation: deriveMessagesTimelineRows and deriveTimelineTurnFolds passed every failed run into the folds' unfoldedRunIds, and itemizedFailedRunIds forced each entry of a failed run onto its own row. pingdotgg#24937 only exempted usage-limit pauses from that itemization, which is why the break looked intermittent: a usage-limit failure kept a floating work-toggle and everything else itemized.

Change

  • apps/web/src/components/chat/MessagesTimeline.logic.ts: failed runs are no longer excluded from folding, and itemizedFailedRunIds plus its per-entry branch are gone. A failed turn folds like a completed one and keeps the existing trajectory summary.
  • The failure item is explicitly skipped when collecting hidden entries, so collapsing never hides the failure card or its retry affordance. Expanding the fold puts the work behind the usual work toggle instead of itemizing it.
  • apps/web/src/components/chat/MessagesTimeline.logic.test.ts: the failed turn transcript table now covers latest/historical × provider_error/usage_limit with a thinking block in the fixture, and asserts the fold, the retained failure card, and the grouped expansion.

Scope and approval

A small, focused fix of a rendering bug in one web logic module; no server, contract, or provider change. It reverses the one part of pingdotgg#24937 that itemized non-usage-limit failures while keeping its intent — usage-limit pauses stay grouped — and makes all failures consistent instead of splitting on failure class. The failure card stays visible, so nothing a reader needs to act on is hidden.

Verification

Failing first on main with the same fixture (3 commands, 1 thinking block, 1 failure), then passing with the fix:

case before after
latest provider_error message, work, work, work, work, work message, turn-fold, work
historical provider_error message, work, work, work message, turn-fold, work
latest usage_limit message, work-toggle, work message, turn-fold, work

The trailing work row in every case is the failure card, and it keeps its message and timestamp. Expanding produces message, turn-fold, work-toggle, work: one toggle containing the three tools and the thinking block, plus the card. The compact variant (tools stripped) now folds its thinking block too: message, turn-fold, message, work, assistant-meta.

  • apps/web/src/components/chat/MessagesTimeline.logic.test.ts: 94 passed.
  • vp run check:changed: format, lint, knip, typecheck, and tests pass.

No pixel capture is attached: this task did not drive the browser client, so the evidence above is the rendered row structure from the derivation function rather than a screenshot. Mobile has a separate timeline renderer and is untouched.

Made with DeepSeek V4.1 Flash via the pi coding harness, t3main profile.

Failed runs were excluded from turn folding and their entries itemized, so
a failed turn rendered one row per tool call, thinking block, and
notification. Only usage-limit pauses kept a group, because pingdotgg#24937 skipped
itemizing them; every other failure exploded.

Drop the carve-out: failed turns fold, group their work behind the usual
toggle when expanded, and never hide the failure card itself.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S labels Oct 29, 2026
@Quinntyx
Quinntyx merged commit bb63fa4 into main Oct 29, 2026
7 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant