Skip to content

fix(web): fold interim turn responses - #215

Merged
rynfar merged 3 commits into
pylonfrom
upstream/2026-08-31-turn-folding
Aug 31, 2026
Merged

rynfar merged 3 commits into
pylonfrom
upstream/2026-08-31-turn-folding

Conversation

@rynfar

@rynfar rynfar commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

A settled turn kept both its first and its terminal assistant message visible, so a
turn that opened with a long interim response left that response permanently
expanded above the "Worked for ..." row. The duration row then sat between two
messages instead of leading into the answer.

Settled turns now keep only the terminal assistant message. Everything before it
folds behind the duration row, so the fold reads as "worked for N, here is the
result". Agent-spawn CTA rows still never fold.

Adopted from upstream pingdotgg/t3code#8828 (17c48f7fc), cherry-picked clean.

This is a deliberate behaviour change, not a bug fix — it changes what is
visible on every settled turn. Called out because it is worth a look in a real
client before it lands, not just a green test run.

Verified: vp test run --dir apps/web apps/web/src/components/chat/MessagesTimeline.logic.test.ts apps/web/src/components/chat/MessagesTimeline.test.tsx
(90 passed), vp run -F @t3tools/web typecheck (exit 0, no errors).

Reviewed and integrated with Claude Opus 5 in Claude Code.


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

(cherry picked from commit 17c48f7fc1af66110706b013bf41901ebcd8aedb)
@github-actions github-actions Bot added size:S vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Aug 31, 2026
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 13.6 KiB 13.5 KiB −32 B (−0.2%) 15.1 KiB
Codex Thread snapshot wire 6.9 KiB 6.9 KiB 0 B (0.0%) 7.3 KiB
Codex Live turn WebSocket wire 6.6 KiB 6.6 KiB −32 B (−0.5%) 7.8 KiB
Codex Live turn WebSocket decoded 57.2 KiB 57.1 KiB −44 B (−0.1%) 66.4 KiB
Codex Live turn messages 10 9 −1 (−10.0%) 21
Claude Total thread wire 13.6 KiB 13.5 KiB −63 B (−0.5%) 15.1 KiB
Claude Thread snapshot wire 6.9 KiB 6.9 KiB −12 B (−0.2%) 7.3 KiB
Claude Live turn WebSocket wire 6.6 KiB 6.6 KiB −51 B (−0.8%) 7.8 KiB
Claude Live turn WebSocket decoded 58.1 KiB 58.0 KiB −44 B (−0.1%) 66.4 KiB
Claude Live turn messages 10 9 −1 (−10.0%) 21

Baseline: 9ade80d · PR result: 97aaed8 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.5 KiB
  • Claude decoded thread snapshot: 110.2 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Review follow-up on the #8828 port. Folding everything before the terminal
message assumes that message is the answer. A turn that ends with no text at
all renders as "Worked for 22s" above "(empty response)", with the substantive
response folded out of sight and no hidden-item count on the fold row. The
comment upstream deleted named exactly this case. The first assistant message
now stays visible when the terminal message carries no text; a terse but
non-empty closing message still folds, which is the change's intent.
@rynfar

rynfar commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator Author

Adversarial review confirmed the mechanics are clean — firstAssistantEntry had no remaining references, group.terminalEntry is null-safe, the zero-hidden short circuit still holds, and the turn-diff "changed files" chip stays on the terminal message rather than folding away. Two findings.

Fixed: a turn that ends with no text folded away its own answer. With the first-message exemption gone, a settled turn whose terminal assistant message is empty renders as Worked for 22s above (empty response), with the substantive response hidden and no item count on the fold row. The comment upstream deleted named exactly this case and no substitute guard replaced it. The first assistant message now stays visible when the terminal message carries no text.

I deliberately kept this narrow. My first attempt also exempted short terminal messages (under 80 chars), which broke upstream's own fixture where the turn ends "Verification finished." — that is upstream's product call about terse closers, not a defect, so a terse-but-non-empty ending still folds. Only the empty case is guarded. Regression test added.

Not fixed — belongs with the mobile sequence. apps/mobile/src/lib/threadActivity.ts:1261 still exempts the first assistant message from folding, so web and mobile now render the same settled turn differently. The two fold implementations are duplicated and drifting. I'm holding this for the mobile batch, where #8793 already moves work-log presentation into client-runtime — that is the right moment to converge the two rather than patch mobile in a web PR.

Re-verified: MessagesTimeline.logic.test.ts 47 passed, MessagesTimeline.test.tsx 42 passed, @t3tools/web typecheck clean.

@rynfar
rynfar merged commit 5e3fd47 into pylon Aug 31, 2026
19 checks passed
@rynfar
rynfar deleted the upstream/2026-08-31-turn-folding branch August 31, 2026 20:49
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.

2 participants