You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a streaming request fails mid-stream and the retry succeeds, the failed attempt's assistant/chunk events stay in the session log as orphan data: the final assistant/message only references the second attempt's chunks via sourceEventSeqs, yet the first attempt's chunks are never deleted or marked. Replay/UI renders phantom half-generated assistant content; token counting and compaction double-count the failed content.
Evidence
packages/core/agent-loop/src/agent.ts:343-371:
forawait(constchunkofstream){signal.throwIfAborted()chunkSeqs.push(this.session.append('assistant/chunk',{ turn, step, chunk }).seq)// chunk persisted per-eventassembler.push(chunk)}
...
if(action?.kind!=='retry'){thrownewLlmError(...)}continue// ← retry: the failed attempt's already-appended chunk events are never cleaned up
Chunks have no surfaceOp, so the surface-replace on success cannot shadow them. The failed attempt's chunks are consumed by replay/token-counting/compaction but are not part of the final message's sourceEventSeqs.
Repro (verified)
Scripted adapter emits partial then an error finish; the retry succeeds. Result: 9 chunk events in the log, the final message references only 6 — seq 7,8,9 are orphans. Existing request-error.spec.ts only covers pre-stream failures, not this path. Verified with a temporary vitest case (removed afterward; no repo changes).
Suggested fix
On retry/terminal failure, delete or mark the failed attempt's chunk events (needs a session delete primitive, or an attempt-group marker consumers skip), or buffer chunks and persist only after the stream succeeds (trade-off: loses mid-crash recovery fidelity).
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Summary
When a streaming request fails mid-stream and the retry succeeds, the failed attempt's
assistant/chunkevents stay in the session log as orphan data: the finalassistant/messageonly references the second attempt's chunks viasourceEventSeqs, yet the first attempt's chunks are never deleted or marked. Replay/UI renders phantom half-generated assistant content; token counting and compaction double-count the failed content.Evidence
packages/core/agent-loop/src/agent.ts:343-371:Chunks have no
surfaceOp, so the surface-replace on success cannot shadow them. The failed attempt's chunks are consumed by replay/token-counting/compaction but are not part of the final message'ssourceEventSeqs.Repro (verified)
Scripted adapter emits
partialthen an error finish; the retry succeeds. Result: 9 chunk events in the log, the final message references only 6 — seq 7,8,9 are orphans. Existingrequest-error.spec.tsonly covers pre-stream failures, not this path. Verified with a temporary vitest case (removed afterward; no repo changes).Suggested fix
On retry/terminal failure, delete or mark the failed attempt's chunk events (needs a session delete primitive, or an attempt-group marker consumers skip), or buffer chunks and persist only after the stream succeeds (trade-off: loses mid-crash recovery fidelity).
Verified at master
47f9438.All reactions