diff --git a/CHANGELOG.md b/CHANGELOG.md index dfd13a1ae..9efbb243d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - Agents: auto-recover from compaction context overflow by resetting the session and retrying; propagate overflow details from embedded runs so callers can recover. - MiniMax: strip malformed tool invocation XML; include `MiniMax-VL-01` in implicit provider for image pairing. - Onboarding/Auth: honor `CLAWDBOT_AGENT_DIR` / `PI_CODING_AGENT_DIR` when writing auth profiles (MiniMax). (#829) — thanks @roshanasingh4. +- Anthropic: handle `overloaded_error` with a friendly message and failover classification. (#832) — thanks @danielz1z. - Anthropic: merge consecutive user turns (preserve newest metadata) before validation to avoid incorrect role errors. - Messaging: enforce context isolation for message tool sends; keep typing indicators alive during tool execution. - Auto-reply: `/status` allowlist behavior, reasoning-tag enforcement on fallback, and system-event enqueueing for elevated/reasoning toggles. diff --git a/src/agents/pi-embedded-helpers.test.ts b/src/agents/pi-embedded-helpers.test.ts index bdf2a7db0..938e4b654 100644 --- a/src/agents/pi-embedded-helpers.test.ts +++ b/src/agents/pi-embedded-helpers.test.ts @@ -209,6 +209,11 @@ describe("classifyFailoverReason", () => { expect(classifyFailoverReason("resource has been exhausted")).toBe( "rate_limit", ); + expect( + classifyFailoverReason( + '{"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}', + ), + ).toBe("rate_limit"); expect(classifyFailoverReason("invalid request format")).toBe("format"); expect(classifyFailoverReason("credit balance too low")).toBe("billing"); expect(classifyFailoverReason("deadline exceeded")).toBe("timeout"); @@ -265,6 +270,15 @@ describe("formatAssistantErrorText", () => { "Message ordering conflict", ); }); + + it("returns a friendly message for Anthropic overload errors", () => { + const msg = makeAssistantError( + '{"type":"error","error":{"details":null,"type":"overloaded_error","message":"Overloaded"},"request_id":"req_123"}', + ); + expect(formatAssistantErrorText(msg)).toBe( + "The AI service is temporarily overloaded. Please try again in a moment.", + ); + }); }); describe("sanitizeToolCallId", () => { diff --git a/src/agents/pi-embedded-helpers.ts b/src/agents/pi-embedded-helpers.ts index 7acdd2e52..89588701d 100644 --- a/src/agents/pi-embedded-helpers.ts +++ b/src/agents/pi-embedded-helpers.ts @@ -419,7 +419,10 @@ const ERROR_PATTERNS = { "resource_exhausted", "usage limit", ], - overloaded: [/overloaded_error|"type"\s*:\s*"overloaded"/i, "overloaded"], + overloaded: [ + /overloaded_error|"type"\s*:\s*"overloaded_error"/i, + "overloaded", + ], timeout: [ "timeout", "timed out", diff --git a/src/auto-reply/reply.triggers.test.ts b/src/auto-reply/reply.triggers.test.ts index 9925b27bf..ce593fade 100644 --- a/src/auto-reply/reply.triggers.test.ts +++ b/src/auto-reply/reply.triggers.test.ts @@ -1456,7 +1456,7 @@ describe("trigger handling", () => { const text = Array.isArray(res) ? res[0]?.text : res?.text; expect(text).toBe( - "⚠️ Context overflow - conversation too long. Starting fresh might help!", + "⚠️ Context overflow — prompt too large for this model. Try a shorter message or a larger-context model.", ); expect(runEmbeddedPiAgent).toHaveBeenCalledOnce(); });