Skip to content

fix(core): continue retryable failures after durable output - #45861

Merged
rekram1-node merged 1 commit into
v2from
continue-retryable
Aug 28, 2026
Merged

fix(core): continue retryable failures after durable output#45861
rekram1-node merged 1 commit into
v2from
continue-retryable

Conversation

@rekram1-node

Copy link
Copy Markdown
Collaborator

Summary

A retryable failure arriving after the assistant produced durable output had no recovery path. The pre-output retry gate requires !outputStarted, and the continuation gate only matched interrupted-stream shapes (Transport read failures, incomplete streams). A provider that streams partial output and then reports a retryable error — an overloaded/rate-limit/server error event inside the stream, or any unrecognized failure — matched neither gate and durably failed the turn, even though the same failure before output would have retried.

The continuation gate now also accepts any failure the retry policy considers retry-eligible:

  • Before: continue when isInterruptedStream(failure) and output started.
  • After: continue when isInterruptedStream(failure) || isRetryable(failure) and output started.

isInterruptedStream stays in the condition rather than being replaced: WebSocket read failures can carry delivery: "accepted" or "rejected", which the retry policy rejects for full resends but which must keep taking the continuation path after durable output.

Behavior notes

  • Continuations already run through the same retry schedule as pre-output retries, so the new cases inherit jittered exponential backoff, provider retry-after floors, the 15-minute cap, and the shared five-attempt budget with no policy changes. A mid-stream rate limit now waits out its retry-after before continuing.
  • The recovery keeps the persisted partial assistant message, publishes the durable step failure, and continues with the existing synthetic continuation prompt — identical mechanics to incomplete-stream continuation.
  • Non-retryable failures after output (invalid request, auth, quota, content policy, context overflow) still settle terminally, unchanged.

Verification

  • New scenarios: mid-stream rate limit continues after honoring retry-after exactly; unrecognized mid-stream provider failure continues with backoff.
  • Three existing scenarios asserted durable settlement using a retryable transport fixture after output; their intent is fragment flushing and tool settlement, so they now use a non-retryable InvalidRequest fixture.
  • Full isolated Core suite: 3783 pass / 39 skip / 0 fail. bun typecheck and formatting pass in packages/core.

@rekram1-node
rekram1-node merged commit 8e25e83 into v2 Aug 28, 2026
10 checks passed
@rekram1-node
rekram1-node deleted the continue-retryable branch August 28, 2026 17:35
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