proxy: allow sibling failover for BYOK gateway turns via held gateway keys - #1104
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
PR author is not in the allowed authors list. |
|
Claude finished @devin-ai-integration[bot]'s task —— View job Comment-length lint
Posted 3 committable suggestions on comment-length nits (advisory only):
|
workweave-bot
left a comment
There was a problem hiding this comment.
Advisory only — comment-length nits. Won't block merge.
|
Claude finished @devin-ai-integration[bot]'s task —— View job Comment-length lint
No comment blocks warrant flagging — all added blocks are already at or below the ~5-line threshold and explain genuinely non-obvious WHY (credential-reuse invariant, 401 reasoning, ranking preference). Nothing to post. |
Summary
BYOK disables all failover (
shouldFailover): a foreign provider would 401 on the customer's credentials. In the Snowflake POC's grok run this meant every gatewaystatus=0timeout that survived same-binding retries killed the session — 189 failed calls, 41 sessions ended on an error row, 30/97 tasks lost at least one session — even though the same installation held a second gateway key (anthropic_gateway/opus) that could have served the turn.This carves out the one BYOK case where failover is credential-safe: rescuing onto a sibling model reachable through a gateway key the request itself holds.
siblingFailoverDecisionnow branches for gateway-exclusive requests (gatewayProvidersForRequest(ctx)non-empty) intogatewaySiblingDecision: walks the sameCandidateModels/PairedModelorder and context-fit checks, but resolves each candidate against the request's own gateway aliases instead of deployment-keyed providers:Off-failed-provider candidates still rank first (grok on openai_gateway → opus via anthropic_gateway), same-gateway aliases second; anything not aliased by a held gateway key is never a candidate, so direct-vendor bindings stay unreachable.
siblingViablegate inProxyMessagesloosens froms.shouldFailover(ctx)to:where
gatewaySiblingAllowedrequires the chosen sibling's provider to be one of the request's held gateway keys. Baseline and subscription failover are untouched; the rescue-chain ordering, prelude-buffer/commit semantics, and credential re-resolution (resolveAndInjectCredentialspicks the same BYOK gateway key) are unchanged.Tests: gateway rescue via the other held gateway key, no rescue onto a deployment-keyed vendor binding the gateway doesn't alias, and same-gateway alias rescue.
internal/proxytests,go vet,wv router tc,wv router tall pass.Follow-up to #1101 (gateway session affinity) from the same incident; independent change, no dependency between the two.
Link to Devin session: https://app.devin.ai/sessions/85739dd5156f4ffd9b4ce1941cd91e13
Open in Devin Desktop: https://app.devin.ai/desktop/session/85739dd5156f4ffd9b4ce1941cd91e13?variant=devin
Requested by: @steventohme