fix(ai): detect z.ai context overflow

closes #1937
This commit is contained in:
Mario Zechner
2026-03-08 00:18:16 +01:00
parent d48843ea55
commit ade6a35e75
3 changed files with 16 additions and 8 deletions

View File

@@ -2,6 +2,10 @@
## [Unreleased] ## [Unreleased]
### Fixed
- Fixed context overflow detection to recognize z.ai `model_context_window_exceeded` errors surfaced through OpenAI-compatible stop reason handling ([#1937](https://github.com/badlogic/pi-mono/issues/1937))
## [0.57.0] - 2026-03-07 ## [0.57.0] - 2026-03-07
### Added ### Added

View File

@@ -38,6 +38,7 @@ const OVERFLOW_PATTERNS = [
/context window exceeds limit/i, // MiniMax /context window exceeds limit/i, // MiniMax
/exceeded model token limit/i, // Kimi For Coding /exceeded model token limit/i, // Kimi For Coding
/too large for model with \d+ maximum context length/i, // Mistral /too large for model with \d+ maximum context length/i, // Mistral
/model_context_window_exceeded/i, // z.ai non-standard finish_reason surfaced as error text
/context[_ ]length[_ ]exceeded/i, // Generic fallback /context[_ ]length[_ ]exceeded/i, // Generic fallback
/too many tokens/i, // Generic fallback /too many tokens/i, // Generic fallback
/token limit exceeded/i, // Generic fallback /token limit exceeded/i, // Generic fallback

View File

@@ -384,29 +384,32 @@ describe("Context overflow error handling", () => {
// ============================================================================= // =============================================================================
// z.ai // z.ai
// Special case: Sometimes accepts overflow silently, sometimes rate limits // Special case: may return explicit overflow error text, may accept overflow silently,
// Detection via usage.input > contextWindow when successful // or may rate limit instead
// ============================================================================= // =============================================================================
describe.skipIf(!process.env.ZAI_API_KEY)("z.ai", () => { describe.skipIf(!process.env.ZAI_API_KEY)("z.ai", () => {
it("glm-4.5-flash - should detect overflow via isContextOverflow (silent overflow or rate limit)", async () => { it("glm-4.5-flash - should detect overflow via isContextOverflow when z.ai reports it", async () => {
const model = getModel("zai", "glm-4.5-flash"); const model = getModel("zai", "glm-4.5-flash");
const result = await testContextOverflow(model, process.env.ZAI_API_KEY!); const result = await testContextOverflow(model, process.env.ZAI_API_KEY!);
logResult(result); logResult(result);
// z.ai behavior is inconsistent: // z.ai behavior is inconsistent:
// - Sometimes returns explicit overflow error text via non-standard finish_reason handling
// - Sometimes accepts overflow and returns successfully with usage.input > contextWindow // - Sometimes accepts overflow and returns successfully with usage.input > contextWindow
// - Sometimes returns rate limit error // - Sometimes returns rate limit error
// Either way, isContextOverflow should detect it (via usage check or we skip if rate limited) if (result.stopReason === "error") {
if (result.stopReason === "stop") { if (result.errorMessage?.match(/model_context_window_exceeded/i)) {
expect(isContextOverflow(result.response, model.contextWindow)).toBe(true);
} else {
console.log(" z.ai returned non-overflow error (possibly rate limited), skipping overflow detection");
}
} else if (result.stopReason === "stop") {
if (result.hasUsageData && result.usage.input > model.contextWindow) { if (result.hasUsageData && result.usage.input > model.contextWindow) {
expect(isContextOverflow(result.response, model.contextWindow)).toBe(true); expect(isContextOverflow(result.response, model.contextWindow)).toBe(true);
} else { } else {
console.log(" z.ai returned stop without overflow usage data, skipping overflow detection"); console.log(" z.ai returned stop without overflow usage data, skipping overflow detection");
} }
} else {
// Rate limited or other error - just log and pass
console.log(" z.ai returned error (possibly rate limited), skipping overflow detection");
} }
}, 120000); }, 120000);
}); });