fix(agent): retry OpenRouter 429s at the fetch boundary - #667
Open
yzxcj797 wants to merge 1 commit into
Open
Conversation
OpenRouter's platform-side 429s (free-models-per-min) carry no Retry-After, which the LangChain AsyncCaller classifies as non-retryable capacity and turns into an immediate abort, so OPENWIKI_PROVIDER_RETRY_ATTEMPTS never applied and ~50s of agent work was discarded on the first 429 (langchain-ai#664). langchain-ai#461's createProviderRetryFetch only reaches ChatOpenAI-backed transports -- ChatOpenRouter has no configuration option -- and its flat 1s fallback cannot ride out a per-minute window anyway. Retry in installOpenRouterDebugFetch, which already wraps every OpenRouter chat-completions fetch: - honour Retry-After (seconds or HTTP-date), then OpenRouter's X-RateLimit-Reset epoch (unix-ms, seconds-magnitude detection, small margin), then exponential backoff (1s doubling, 30s cap); header- derived waits are defensively capped at 5 min; - spend the existing OPENWIKI_PROVIDER_RETRY_ATTEMPTS budget; - only retry when the request is re-sendable (string/absent body, not a Request carrying a body) and propagate abort signals through the wait; - keep the diagnostics contract: the final non-ok response is captured for attachOpenRouterDebugInfo, retries emit debug lines.
|
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.
Summary
Fixes #664.
An OpenRouter free-tier
429(noRetry-After) aborted the whole run on first occurrence: LangChain'sAsyncCallerclassifies aRetry-After-less 429 as non-retryable capacity and throws immediately, soOPENWIKI_PROVIDER_RETRY_ATTEMPTSwas never spent. #461'screateProviderRetryFetchcan't help here — it rides the OpenAI SDKconfigurationoption, whichChatOpenRouterdoesn't accept — and its flat 1 s fallback couldn't ride out a per-minute window regardless.What this does
Retries at the fetch boundary
installOpenRouterDebugFetchalready owns (it wraps every OpenRouter chat-completions fetch):Retry-After(seconds or HTTP-date) →X-RateLimit-Reset(unix-ms epoch, with seconds-magnitude detection for providers that send seconds, plus a 250 ms margin so the retry lands after the window actually resets) → exponential backoff (1 s doubling, capped at 30 s). Header-derived waits are defensively capped at 5 minutes.OPENWIKI_PROVIDER_RETRY_ATTEMPTS(default 3), resolved tolerantly at install time so an invalid env value still surfaces through run-config validation with itsconfigstage attribution.init, andinputisn't aRequestobject carrying a body (a consumed stream body can't be re-sent).attachOpenRouterDebugInfo(Error Diagnosticsblock), and each retry emits a debug line (openrouter.retry attempt=N/M delayMs=…).Tests
test/agent/openrouter-retry.test.ts(vitest, followsgemini-retry.test.tsconventions):Retry-After-less 429 withX-RateLimit-Resetis retried and the wait honours the reset instant;1 + Nfetch calls, final 429 returned to the caller with diagnostics captured;fetchErrordiagnostics;computeOpenRouterRetryDelayMs:Retry-Afterseconds and HTTP-date, ms- and seconds-epoch resets, exponential growth with caps.