diff --git a/src/core/api/providers/cerebras.ts b/src/core/api/providers/cerebras.ts index 23881f7525..921371e1d4 100644 --- a/src/core/api/providers/cerebras.ts +++ b/src/core/api/providers/cerebras.ts @@ -192,7 +192,18 @@ export class CerebrasHandler implements ApiHandler { } catch (error: any) { // Enhanced error handling for Cerebras API if (error?.status === 429 || error?.code === "rate_limit_exceeded") { - // Rate limit error - will be handled by retry decorator with patient backoff + // Check if this is actually a context window error disguised as rate limit + // Cerebras rate limiter counts input tokens, so oversized context can trigger 429 + const errorMessage = String(error?.message || "") + const isContextRelated = /reduce.*length|context.*length|too.*many.*tokens|tokens.*exceed|input.*too.*long/i.test( + errorMessage, + ) + if (isContextRelated) { + // Preserve original error so context window detection can catch it + error.status = 400 // Treat as bad request for context window detection + throw error + } + // Regular rate limit error - will be handled by retry decorator with patient backoff const _limits = this.getRateLimits() throw new Error(`Cerebras API rate limit exceeded.`) } else if (error?.status === 401) { @@ -203,8 +214,9 @@ export class CerebrasHandler implements ApiHandler { // Server errors - retryable throw new Error(`Cerebras API server error (${error.status}): ${error.message || "Unknown server error"}`) } else if (error?.status === 400) { - // Client errors - not retryable - throw new Error(`Cerebras API bad request: ${error.message || "Invalid request parameters"}`) + // Client errors (including context window exceeded) - preserve original error + // so checkIsCerebrasContextWindowError can detect it and trigger compaction + throw error } // Re-throw original error for other cases diff --git a/src/core/context/context-management/context-error-handling.ts b/src/core/context/context-management/context-error-handling.ts index f51919652f..5b5c05fb58 100644 --- a/src/core/context/context-management/context-error-handling.ts +++ b/src/core/context/context-management/context-error-handling.ts @@ -67,7 +67,21 @@ function checkIsCerebrasContextWindowError(response: any): boolean { const status = response?.status ?? response?.code ?? response?.error?.status ?? response?.response?.status const message: string = String(response?.message || response?.error?.message || "") - return String(status) === "400" && message.includes("Please reduce the length of the messages or completion") + if (String(status) !== "400") { + return false + } + + // Known Cerebras context window error patterns + const CEREBRAS_CONTEXT_PATTERNS = [ + /reduce.*length.*messages.*completion/i, + /\bcontext\s*(?:length|window)\b/i, + /\bmaximum\s*context\b/i, + /\b(?:input\s*)?tokens?\s*exceed/i, + /\btoo\s*many\s*tokens?\b/i, + /input is too long/i, + ] as const + + return CEREBRAS_CONTEXT_PATTERNS.some((pattern) => pattern.test(message)) } catch { return false } diff --git a/src/utils/model-utils.ts b/src/utils/model-utils.ts index 9e94dcc606..f3034c0529 100644 --- a/src/utils/model-utils.ts +++ b/src/utils/model-utils.ts @@ -97,6 +97,8 @@ export function isGLMModelFamily(id: string): boolean { return ( modelId.includes("glm-4.6") || modelId.includes("glm-4.5") || + modelId.includes("glm-4.7") || + modelId.includes("zai-glm") || // Cerebras pattern (e.g., zai-glm-4.7) modelId.includes("z-ai/glm") || modelId.includes("zai-org/glm") ) @@ -163,7 +165,8 @@ export function isNextGenModelFamily(id: string): boolean { isGemini3ModelFamily(modelId) || isNextGenOpenSourceModelFamily(modelId) || isDeepSeek32ModelFamily(modelId) || - isDeepSeekNativeModelFamily(modelId) + isDeepSeekNativeModelFamily(modelId) || + isGLMModelFamily(modelId) ) }