feat(agents): enable conservative retries by default for transient errors#449
Open
MarioCadenas wants to merge 1 commit into
Open
feat(agents): enable conservative retries by default for transient errors#449MarioCadenas wants to merge 1 commit into
MarioCadenas wants to merge 1 commit into
Conversation
…ent errors
Agent stream defaults previously set retry { enabled: false }. Enable a
conservative default (attempts: 2, 500ms..4s backoff) so a transient serving
error (5xx / 429 / connection reset) doesn't fail the whole turn. Non-retryable
errors (4xx, AppKitError isRetryable=false) are still never retried.
Streaming safety: in executeStream the RetryInterceptor wraps only the
synchronous creation of the adapter async generator; token emission and tool
dispatch run during yield* iteration, outside the interceptor chain. A transient
error thrown after the first streamed event therefore cannot be retried, so
retries can never re-emit tokens or re-run a tool side-effect. Only a failure
during generator setup (before any output) is retried. Added defaults.test.ts
asserting the conservative values and proving no mid-stream replay.
Co-authored-by: Isaac
Signed-off-by: MarioCadenas <MarioCadenas@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Agents previously disabled retries entirely —
agentStreamDefaultssetretry: { enabled: false }. A single transient serving error (5xx, 429, connection reset) would fail the whole turn.This enables a conservative default that reuses the existing
RetryInterceptor(exponential backoff with full jitter, only retries transient/retryable errors):AppKitErrorwithisRetryable=false) are still never retried — seeisRetryableErrorininterceptors/retry.ts.No new retry logic was added; only the default config value changed.
Streaming / non-idempotency safety (the scope applied)
The agents plugin consumes
retryin exactly one place: the streaming/chatpath viaexecuteStream(agents.ts:1162). This change is streaming-replay-safe by construction, not by configuration:executeStream, the interceptor chain wrapswrappedFn = async () => fn(signal), wherefnis the async generator function for the turn.wrappedFnresolves immediately and theRetryInterceptorsees success on attempt 1.yield*iteration — which runs outside the interceptor chain.The non-streaming
/invocationsand/responsespath (_runAgentNonStreaming) does not route throughexecute()/executeStream()at all, so this default does not affect it.Tests
Added
packages/appkit/src/plugins/agents/tests/defaults.test.ts:attempts === 2, bounded backoff caps).RetryInterceptorexactly asexecuteStreamdoes, throws a 5xx after the first yielded token, and asserts the generator body ran once and the tool side-effect fired once (no replay).Verification
pnpm --filter=@databricks/appkit typecheck— clean.retry.test.ts: 19 passed; newdefaults.test.ts: 3 passed.biome checkon changed files — no fixes/errors.This pull request and its description were written by Isaac.