-
Notifications
You must be signed in to change notification settings - Fork 1.1k
fix(combos): classify a hopping 413 when the combo exhausts its targets #4150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2791,6 +2791,10 @@ export async function handleComboResponses( | |
| logCtx.routeDecision = comboRouteDecisionTrace(config, comboId, pick, requestedModel); | ||
|
|
||
| let lastFailure: Response | null = null; | ||
| // The exhausted-combo mapping below runs outside the loop, where `failure.upstreamCode` | ||
| // is gone, so carry the loop's own classification decision instead of re-deriving a | ||
| // weaker one from the status alone (#4149). | ||
| let lastFailureClassifiesOverflow = false; | ||
| while (pick) { | ||
| if (options.abortSignal?.aborted) return clientCancelledResponse(); | ||
| const childLog: RequestLogContext = { | ||
|
|
@@ -3003,6 +3007,7 @@ export async function handleComboResponses( | |
| const classifyOverflow = failure.response.status === 413 | ||
| && (wantsStream || (failure.upstreamCode !== "outbound_body_too_large" | ||
| && failure.upstreamCode !== "translation_buffer_limit")); | ||
| lastFailureClassifiesOverflow = classifyOverflow; | ||
|
Comment on lines
3007
to
+3010
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a non-streaming combo exhausts its targets because each target fails the local context-window preflight, AGENTS.md reference: src/AGENTS.md:L19-L19 Useful? React with 👍 / 👎. |
||
| if (storedPool401ReplayDispatched) { | ||
| if (failureDecision === "hop" && unreadableEncryptedAgentTask && !comboPayloadReadable) { | ||
| const recoveredTarget = await pickWithWait({ | ||
|
|
@@ -3089,9 +3094,11 @@ export async function handleComboResponses( | |
| } | ||
| if ( | ||
| lastFailure?.status === 413 | ||
| && (rawBody as { stream?: unknown } | null)?.stream === true | ||
| && lastFailureClassifiesOverflow | ||
| ) { | ||
| return streamingContextOverflowResponse(requestedModel, options.translatorBudget); | ||
| return (rawBody as { stream?: unknown } | null)?.stream === true | ||
| ? streamingContextOverflowResponse(requestedModel, options.translatorBudget) | ||
| : jsonContextOverflowResponse(); | ||
| } | ||
| return lastFailure!; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Preserve
input_admission_refusedfor exhausted combos.When a combo child fails the local input-admission check at Lines 3857-3876, it returns HTTP 413 with
input_admission_refused. This condition records that failure asclassifyOverflow = truebecause it excludes onlyoutbound_body_too_largeandtranslation_buffer_limit. After all targets are exhausted, Lines 3097-3101 replace the final response withjsonContextOverflowResponse(), so the client loses the local diagnostic.Exclude
input_admission_refusedfromclassifyOverflowbefore assigninglastFailureClassifiesOverflow.Suggested fix
🤖 Prompt for AI Agents