fix(errors): recover from Z.AI token-limit errors (#111744)

* fix(errors): classify Z.AI token-limit overflow

* fix(zai): own token overflow classification

* fix(zai): classify live prompt overflow errors

---------

Co-authored-by: Altay <altay@hey.com>
This commit is contained in:
ooiuuii
2026-07-20 17:11:40 +03:00
committed by GitHub
co-authored by Altay
parent 154a49a78b
commit 570f8b4d9e
4 changed files with 34 additions and 2 deletions
+4
View File
@@ -385,6 +385,10 @@ export default definePluginEntry({
}),
],
resolveDynamicModel: (ctx) => resolveGlm5ForwardCompatModel(ctx),
matchesContextOverflowError: ({ errorMessage }) =>
/\b(?:tokens? in request more than max tokens? allowed|prompt exceeds max(?:imum)? length)\b/i.test(
errorMessage,
),
...buildProviderReplayFamilyHooks({
family: "openai-compatible",
dropReasoningFromHistory: false,
+2
View File
@@ -57,6 +57,8 @@ describe("provider overflow messages", () => {
"Error: 400 Input length (265330) exceeds model's maximum context length (262144).",
"Provider returned error: Input length 131393 exceeds the maximum allowed input length of 131,040 tokens.",
"Input length 131393 exceeds maximum allowed input length of 131040 token",
"code 1210: tokens in request more than max tokens allowed",
"code 1261: Prompt exceeds max length",
])("detects %s", (text) => {
expect(isContextOverflow(errorMessage(text), 262_144)).toBe(true);
});
+8 -2
View File
@@ -33,7 +33,9 @@ export function isConfiguredContextSizeOverflowError(errorMessage: string): bool
* - Kimi For Coding: "Your request exceeded model token limit: X (requested: Y)"
* - Cerebras: "400/413 status code (no body)"
* - Mistral: "Prompt contains X tokens ... too large for model with Y maximum context length"
* - z.ai: Does NOT error, accepts overflow silently - handled via usage.input > contextWindow
* - z.ai: May return "tokens in request more than max tokens allowed" (code 1210),
* "Prompt exceeds max length" (code 1261), or accept overflow silently; handled via the
* error patterns or usage.input > contextWindow
* - Xiaomi MiMo: Truncates input to fill contextWindow exactly, then returns finish_reason "length"
* with output=0 (no room left to generate). Detected via stopReason "length" + zero output +
* input filling the context window.
@@ -56,6 +58,8 @@ const OVERFLOW_PATTERNS = [
/greater than the context length/i, // LM Studio
/context window exceeds limit/i, // MiniMax
/exceeded model token limit/i, // Kimi For Coding
/tokens? in request more than max tokens? allowed/i, // Z.AI / Zhipu GLM error 1210
/prompt exceeds max(?:imum)? length/i, // Z.AI / Zhipu GLM error 1261
/too large for model with \d+ maximum context length/i, // Mistral
CONFIGURED_CONTEXT_SIZE_OVERFLOW_RE, // DS4 server
/model_context_window_exceeded/i, // z.ai non-standard finish_reason surfaced as error text
@@ -115,10 +119,12 @@ function resolveContextInputTokens(message: AssistantMessage): number | undefine
* - llama.cpp: "exceeds the available context size"
* - LM Studio: "greater than the context length"
* - Kimi For Coding: "exceeded model token limit: X (requested: Y)"
* - z.ai: "tokens in request more than max tokens allowed" or "Prompt exceeds max length"
*
* **Unreliable detection:**
* - z.ai: Sometimes accepts overflow silently (detectable via usage.input > contextWindow),
* sometimes returns rate limit errors. Pass contextWindow param to detect silent overflow.
* sometimes returns rate limit errors instead of the explicit overflow error above. Pass
* contextWindow param to detect silent overflow.
* - Xiaomi MiMo: Truncates input to fit contextWindow then returns stopReason "length" with
* output=0. Pass contextWindow param to detect via the "filled context + zero output" signal.
* - Ollama: May truncate input silently for some setups, but may also return explicit
@@ -800,6 +800,26 @@ export function describeZAIProviderRuntimeContract(load: ProviderRuntimeContract
});
});
it("owns Z.AI token-limit overflow classification", () => {
const provider = requireProviderContractProvider("zai");
expect(
provider.matchesContextOverflowError?.({
errorMessage: "code 1210: tokens in request more than max tokens allowed",
}),
).toBe(true);
expect(
provider.matchesContextOverflowError?.({
errorMessage: "code 1261: Prompt exceeds max length",
}),
).toBe(true);
expect(
provider.matchesContextOverflowError?.({
errorMessage: "code 1210: invalid request parameters",
}),
).toBe(false);
});
it("owns usage auth resolution", async () => {
const provider = requireProviderContractProvider("zai");
await expect(