fix(agent-loop): mark finalized prefixes durable-interrupted; never finalize failed attempts

Review round findings:

- Clear the streaming attempt before the request-error waterfall: a cancel
  landing during recovery (typically the llm/retry backoff, after clients
  reset the streamed rendering) must not resurrect the failed stream's
  prefix. Provider failures commit nothing, now including that window.
- Record interrupted: true on the cancellation-finalized assistant/message.
  The chat projection keeps the settled prefix classified as interrupted
  (Stopped chip, restored web goldens), and request inspection leaves the
  request uncompleted so the step boundary classifies it as before.
- Pin the recovery-window and retry-discard semantics with content-bearing
  failed streams in cancel.spec; update the ACP late-end expectation to the
  finalized-prefix transcript.
- Mention interruptedBlocks() in the assembler stream-lifecycle JSDoc.
This commit is contained in:
creatixchu
2026-08-10 13:10:43 +08:00
parent 3e02c06d7f
commit 87f24bb991
31 changed files with 217 additions and 97 deletions
+2 -1
View File
@@ -270,7 +270,8 @@ interface TokenUsage {
* {@link ContentBlock}s and a final assistant {@link Message}.
*
* The agent loop feeds it while logging raw chunks for replay fidelity, then
* reads `blocks()` / `message()` / `usage` / `finish` once the stream ends.
* reads `blocks()` / `message()` / `usage` / `finish` once the stream ends,
* or `interruptedBlocks()` when cancellation cut the stream short.
*
* Tolerant of delta-only protocols (no block-start/end); deltas arriving for
* an index already closed by `block-end` are ignored (malformed stream) so a