mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-07 07:42:13 +03:00
combo.ts's isContextOverflow400() guard required the literal word
'context' in the 400 error body before letting a combo fall through to
the next target. Kimi's exact wording ('Your request exceeded model
token limit: 262144 (requested: 308458)') never says 'context', so the
guard misclassified it as a body-specific error and halted the whole
combo instead of trying the next (larger-context) target.
accountFallback.ts's CONTEXT_OVERFLOW_PATTERNS already recognized this
wording one layer below (via checkFallbackError -> shouldFallback), so
the two independently-maintained classifiers disagreed and the
stricter one won. Export CONTEXT_OVERFLOW_PATTERNS from
accountFallback.ts and reuse it inside combo.ts's
isContextOverflow400() so both layers share a single source of truth.
Regression test: tests/unit/repro-6637-kimi-token-limit.test.ts
(RED on unfixed code -> GREEN after the fix). Existing #4519 guard
tests (tests/unit/combo-param-validation-fallback-4519.test.ts) still
pass, including the negative case that a genuinely body-specific 400
is NOT misclassified as overflow.
This commit is contained in:
committed by
GitHub
parent
a49ac1755d
commit
afbd9361a7
1
changelog.d/fixes/6637-6637-combo-kimi-fallback.md
Normal file
1
changelog.d/fixes/6637-6637-combo-kimi-fallback.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(routing): recognize Kimi-style "exceeded model token limit" 400 as context overflow so combo fallback continues to the next target (#6637)
|
||||
@@ -189,7 +189,10 @@ export const OAUTH_INVALID_TOKEN_SIGNALS = [
|
||||
// Context overflow patterns — the prompt exceeds the model's maximum context length.
|
||||
// Different providers phrase this differently. Used to decide whether a 400 error
|
||||
// should trigger combo fallback (a different model may have a larger context window).
|
||||
const CONTEXT_OVERFLOW_PATTERNS = [
|
||||
// Exported so combo.ts's isContextOverflow400() guard (open-sse/services/combo.ts)
|
||||
// can reuse this single source of truth instead of maintaining its own,
|
||||
// independently-drifting pattern list (see issue #6637).
|
||||
export const CONTEXT_OVERFLOW_PATTERNS = [
|
||||
/\binput is too long\b/i,
|
||||
/\binput too long\b/i,
|
||||
/\bcontext.*(too long|exceeded|overflow|limit)/i,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import {
|
||||
checkFallbackError,
|
||||
classifyLockoutReason,
|
||||
CONTEXT_OVERFLOW_PATTERNS,
|
||||
decayModelFailureCount,
|
||||
formatRetryAfter,
|
||||
getModelLockoutInfo,
|
||||
@@ -663,7 +664,12 @@ export function isContextOverflow400(errorText) {
|
||||
return (
|
||||
/\bcontext.*(?:length_exceeded|too long|overflow|exceeded|window|limit)\b/i.test(errorText) ||
|
||||
/exceeds.*context/i.test(errorText) ||
|
||||
/your input exceeds/i.test(errorText)
|
||||
/your input exceeds/i.test(errorText) ||
|
||||
// Reuse accountFallback.ts's CONTEXT_OVERFLOW_PATTERNS (single source of truth)
|
||||
// so wording like Kimi's "exceeded model token limit" — which never says the
|
||||
// literal word "context" — is still recognized as an overflow/fallback-worthy
|
||||
// 400 instead of halting the whole combo (issue #6637).
|
||||
CONTEXT_OVERFLOW_PATTERNS.some((p) => p.test(errorText))
|
||||
);
|
||||
}
|
||||
/** @param {string} errorText */
|
||||
|
||||
41
tests/unit/repro-6637-kimi-token-limit.test.ts
Normal file
41
tests/unit/repro-6637-kimi-token-limit.test.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
// Repro probe for issue #6637: combo stops fallback after Kimi total token-limit 400.
|
||||
//
|
||||
// Observed provider response (Kimi, verbatim from the issue report):
|
||||
// "Invalid request: Your request exceeded model token limit: 262144 (requested: 308458)"
|
||||
//
|
||||
// combo.ts's #2101 guard (handleComboChat) treats a 400 as a combo-halting
|
||||
// "body-specific" error UNLESS isContextOverflow400() or isParamValidation400()
|
||||
// recognizes it as a context/param overflow that should fall through to the next
|
||||
// combo target. Kimi's exact wording ("... exceeded model token limit ...") does
|
||||
// NOT contain the literal word "context", so isContextOverflow400() misses it even
|
||||
// though accountFallback.ts's OWN CONTEXT_OVERFLOW_PATTERNS (used one layer below,
|
||||
// to decide fallbackResult.shouldFallback) explicitly matches `/\btoken limit\b/i`
|
||||
// and `/\bmax.*token/i`. The two classifiers disagree, and the stricter one wins,
|
||||
// so the combo halts instead of trying the next (larger-context) target.
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import { isContextOverflow400, isParamValidation400 } from "../../open-sse/services/combo.ts";
|
||||
|
||||
const KIMI_ERROR_TEXT =
|
||||
"Invalid request: Your request exceeded model token limit: 262144 (requested: 308458)";
|
||||
|
||||
test("#6637: Kimi's 'exceeded model token limit' 400 must be classified as context/token overflow (not body-specific)", () => {
|
||||
// This is the exact predicate combo.ts checks before deciding to abort the
|
||||
// whole combo instead of falling through to the next target (combo.ts ~L2038-2049):
|
||||
// if (status === 400 && fallbackResult.shouldFallback &&
|
||||
// !isContextOverflow400(errorText) && !isParamValidation400(errorText) && ...)
|
||||
// -> "stopping combo"
|
||||
//
|
||||
// For the fallback to proceed to the next target, at least one of these must be true.
|
||||
const isRecognizedAsOverflow = isContextOverflow400(KIMI_ERROR_TEXT) || isParamValidation400(KIMI_ERROR_TEXT);
|
||||
|
||||
assert.equal(
|
||||
isRecognizedAsOverflow,
|
||||
true,
|
||||
`Expected Kimi's "exceeded model token limit" 400 to be classified as context/token ` +
|
||||
`overflow so combo fallback continues to the next target, but neither ` +
|
||||
`isContextOverflow400() nor isParamValidation400() matched it. This causes ` +
|
||||
`handleComboChat's #2101 guard to treat it as a body-specific error and halt the ` +
|
||||
`whole combo (bug #6637).`
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user