Repository navigation
fix(context): uncataloged combo members no longer clamp the runtime combo limit to generic 128k - #15053
Merged
diegosouzapw merged 1 commit intoSep 29, 2026
Conversation
…ombo limit to generic 128k Refs diegosouzapw#14931. Part 1 of a 3-part series on the context-guard false kill: - Part 1 (this PR): sibling-side limit resolution - Part 2: estimator calibration against provider-reported usage - Part 3: proactive-compression log basis labels The issue stays open until all three land. getComboTargetTokenLimit() resolved every sibling through the non-specific-aware getTokenLimit(), so a member with no catalog/registry/ heuristic window contributed the generic 128000 catch-all to resolveComboContextLimit()'s Math.min() — the sibling-side mirror of the asymmetry diegosouzapw#10734 closed for advertised combos via getSourcedTokenLimit(). One uncataloged member dragged the whole combo's guard down to a guess, false-killing ~50k-real-token Codex requests (diegosouzapw#14931). Now the helper returns undefined for known-source-less targets; chatCore's existing numeric filter drops them, and a combo whose known siblings are all larger inherits min(known sibling windows) instead of the baseless 128000. When every member is unknown the resolver still falls back to the generic default on its own (source=fallback), and combo-explicit context_length / target-specific windows keep their precedence unchanged. A false-negative here is recoverable (upstream 400 -> combo failover) while the false-positive it removes was not — see the diegosouzapw#14931 discussion for the trade-off analysis.
This was referenced Sep 29, 2026
Merged
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.
TL;DR (plain language)
The context guard resolves a combo's window as roughly "the smallest member's window". A member whose window nobody knows answered 128,000 anyway — a generic constant that has nothing to do with the deployment — and dragged the whole combo down to that guess. After this PR, an unknown member says "unknown" instead of guessing, so the combo runs at the smallest window it actually knows about, and only falls back to the generic 128,000 when no member's window is known.
This is the runtime sibling-side mirror of the rule #10734/#10793 already applied to advertised combos via
getSourcedTokenLimit()— owner-confirmed in #14931 (root cause #2).The incident, concretely (from #14931): combo
coding-pool=qwen3.8-27b(uncataloged → generic 128000) +deepseek-v4-flash-0731(catalog match → 1,000,000).Math.minpicked 128,000, the guard 400'd a request the provider measured at 49,822 real tokens, and Codex CLI's retries turned that into a 503 storm. One log line told the story:Combo context limit: 128000 (source=combo-min).Change
getComboTargetTokenLimit()(its only caller is chatCore's combo-limit array) now resolves throughgetSourcedTokenLimit(): a target whose window resolves solely to the non-specificDEFAULT_LIMITS.defaultreturnsundefined, and chatCore's existing numeric filter drops it from the array.resolveComboContextLimit()'s precedence chain is untouched:context_length(operator declaration) →min(...known sibling windows)— previouslymin(...all windows, unknowns = 128000)→source=fallback).min(128000, sibling)→ 128000 false killmin(known siblings)→ sibling windowcontext_lengthWhy inheriting a sibling's window is the right default
This answers the concern raised in the #14931 thread that dropping the generic value "turns a too-small limit into a too-large one" when the executing member is the unknown one:
min(known siblings)is at least the real window of an operator-curated sibling in the same pool — for the incident combo that is 1,000,000 vs qwen's real 262,144: overly wide, but a far better prior than a blind guess.context_length, per-model context overrides /CONTEXT_LENGTH_*env, catalog entries. This PR only removes the baseless constant from the chain.Testing
tests/unit/combo-target-token-limit-8716.test.ts— the fix(backend): combo compression-limit null.toUpperCase() when target modelStr has no provider prefix #8716 no-crash contract keeps passing; the both-providers-missing case now assertsundefined(was: a positive number), with a comment pointing at fix(backend): Context guard rejects Codex CLI at ~50k real tokens: chars/4 estimator over-counts ~1MB of tool schemas 5-6x, checked against a generic 128k fallback limit (model catalog miss → combo-min) #14931.tests/unit/chatcore-combo-sibling-specific-14931.test.ts— new, end-to-end throughhandleChatCore: a ~150k-estimated request against an [unknown member, 1M sibling] combo is no longer rejected (context_length_exceeded/limit 128000must not appear), while a ~1.15M-estimated request is still rejected citing the inherited 1,000,000 — the guard keeps its teeth.tests/unit/resolveComboContextLimit.test.ts,tests/unit/combo-context-generic-default-10734.test.ts— precedence chain regressions green.check-open-sse-typecheck(0 errors),check-complexity-ratchets,check-t11-any-budgetpass; no frozen file touched.