fix(agents): classify Anthropic extra-usage billing (#61608) (thanks @neeravmakwana)

This commit is contained in:
Neerav Makwana
2026-04-06 08:21:53 -04:00
committed by GitHub
parent 7df5f70242
commit ad2df63547
3 changed files with 19 additions and 0 deletions

View File

@@ -74,6 +74,7 @@ Docs: https://docs.openclaw.ai
- Telegram/reasoning: only create a Telegram reasoning preview lane when the session is explicitly `reasoning:stream`, so hidden `<think>` traces from streamed replies stop surfacing as chat previews on normal sessions. Thanks @vincentkoc.
- Telegram/native command menu: trim long menu descriptions before dropping commands so sub-100 command sets can still fit Telegram's payload budget and keep more `/` entries visible. (#61129) Thanks @neeravmakwana.
- Telegram/startup: bound `deleteWebhook`, `getMe`, and `setWebhook` startup requests while keeping the longer `getUpdates` poll timeout, so wedged Telegram control-plane calls stop hanging startup indefinitely. (#61601) Thanks @neeravmakwana.
- Agents/failover: classify Anthropic "extra usage" exhaustion as billing so same-turn model fallback still triggers when Claude blocks long-context requests on usage limits. (#61608) Thanks @neeravmakwana.
- Discord: keep REST, webhook, and monitor traffic on the configured proxy, preserve component-only media sends, honor `@everyone` and `@here` mention gates, keep ACK reactions on the active account, and split voice connect/playback timeouts so auto-join is more reliable. (#57465, #60361, #60345) Thanks @geekhuashan.
- Discord/reply tags: strip leaked `[[reply_to_current]]` control tags from preview text and honor explicit reply-tag threading during final delivery, so Discord replies stay attached to the triggering message instead of printing reply metadata into chat.
- Discord/replies: replace the unshipped `replyToOnlyWhenBatched` flag with `replyToMode: "batched"` so native reply references only attach on debounced multi-message turns while explicit reply tags still work.

View File

@@ -127,6 +127,8 @@ describe("isBillingErrorMessage", () => {
"Insufficient USD or Diem balance to complete request. Visit https://venice.ai/settings/api to add credits.",
"This model requires more credits to use",
"This endpoint require more credits",
"You're out of extra usage. Add more at claude.ai/settings/usage and keep going.",
"Extra usage is required for long context requests.",
],
expected: true,
},
@@ -215,6 +217,20 @@ describe("isBillingErrorMessage", () => {
expect(isBillingErrorMessage(sample)).toBe(true);
expect(classifyFailoverReason(sample)).toBe("billing");
});
it("classifies Anthropic extra-usage exhaustion variants as billing", () => {
const samples = [
"You're out of extra usage. Add more at claude.ai/settings/usage and keep going.",
"Extra usage is required for long context requests.",
'{"type":"error","error":{"type":"invalid_request_error","message":"You\'re out of extra usage. Add more at claude.ai/settings/usage and keep going."}}',
'{"type":"error","error":{"type":"invalid_request_error","message":"Extra usage is required for long context requests."}}',
];
for (const sample of samples) {
expect(isBillingErrorMessage(sample)).toBe(true);
expect(classifyFailoverReason(sample, { provider: "anthropic" })).toBe("billing");
}
});
});
describe("isCloudCodeAssistFormatError", () => {

View File

@@ -120,6 +120,8 @@ const ERROR_PATTERNS = {
"insufficient balance",
"insufficient usd or diem balance",
/requires?\s+more\s+credits/i,
/out of extra usage/i,
/extra usage is required(?: for long context requests)?/i,
],
authPermanent: HIGH_CONFIDENCE_AUTH_PERMANENT_PATTERNS,
auth: [...AMBIGUOUS_AUTH_ERROR_PATTERNS, ...COMMON_AUTH_ERROR_PATTERNS],