Skip to content

feat(account-fallback): add daily quota lockout for quota_exhausted errors - #1644

Closed
clousky2020 wants to merge 3 commits into
cheaper-inference:release/v3.7.1from
clousky2020:fix/daily-quota-v3
Closed

clousky2020 wants to merge 3 commits into
cheaper-inference:release/v3.7.1from
clousky2020:fix/daily-quota-v3

Conversation

@clousky2020

Copy link
Copy Markdown
Contributor

Summary

  • Add model-level daily quota lockout for any provider that signals daily quota exhaustion
  • Complete zh-CN translations across costs, audit, providers, settings, evals, docs, and agents pages

Changes

  • open-sse/services/accountFallback.ts: when reason is quota_exhausted, set cooldown to tomorrow 0:00
  • src/sse/handlers/chat.ts: detect daily quota errors via isDailyQuotaExhausted() helper and lock model
  • tests/unit/account-fallback-service.test.ts: add unit tests for quota_exhausted cooldown
  • src/i18n/messages/: complete 1500+ zh-CN translations with proper fullwidth punctuation

🤖 Generated with Claude Code

clousky2020 and others added 3 commits April 27, 2026 10:32
… errors

- when reason is "quota_exhausted" and exactCooldownMs is not provided, set cooldown to milliseconds until tomorrow 0:00
- refactor getMsUntilTomorrow to use Date.now() consistently and cap at 24 hours for DST edge cases

🐛 fix(chat): handle daily quota exhaustion before generic rate limiting

- detect "today's quota" error string from providers like ModelScope/Kimi
- use recordModelLockoutFailure with quota_exhausted reason to lock the specific model until next day 0:00
- conditionally skip generic rate_limited fallback when daily quota exhaustion already handled

✅ test(account-fallback): add unit tests for quota_exhausted cooldown

- verify lockout cooldown is set to milliseconds until tomorrow 0:00 for quota_exhausted reason
- verify regular backoff (profile baseCooldownMs) is used for non-quota reasons
…ling

- Replace hardcoded string check with isDailyQuotaExhausted helper
- Cast result.error to string before .match() to avoid runtime errors
- Rename local variable to dailyQuotaExhausted to avoid shadowing helper function
- Translate comments to English for codebase consistency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ents

- Restore fullwidth Chinese punctuation (,。:) in zh-CN.json that was incorrectly changed to ASCII
- Translate remaining Chinese comments in chat.ts to English
- Translate Chinese comments in account-fallback-service.test.ts to English

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements a daily quota lockout mechanism that ensures accounts are cooled down until midnight when a 'quota_exhausted' error occurs. It includes updates to the account fallback service to calculate time until the next day, logic in the chat handler to detect these errors and lock specific models, and corresponding unit tests. Feedback focuses on broadening the error status code detection to include 402 (Payment Required) and improving the robustness of the model name extraction regex to support localized Chinese error messages.

Comment thread src/sse/handlers/chat.ts
// Daily quota lockout overrides subsequent rate_limited lockout, ensuring lockout until tomorrow 0:00
let dailyQuotaExhausted = false;
const errorStr = String(result.error || "");
if (result.status === 429 && isDailyQuotaExhausted(errorStr)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The daily quota check is currently restricted to 429 status codes. However, some providers (and the unit tests added in this PR, see line 549 of account-fallback-service.test.ts) use 402 (Payment Required) to signal daily quota exhaustion. This check should be broadened to ensure model-level lockout works for all daily quota errors. Additionally, ensure the isDailyQuotaExhausted helper is updated to support Chinese keywords (e.g., "今日额度") to properly support providers like ModelScope.

Suggested change
if (result.status === 429 && isDailyQuotaExhausted(errorStr)) {
if ((result.status === 429 || result.status === 402) && isDailyQuotaExhausted(errorStr)) {

Comment thread src/sse/handlers/chat.ts
const errorStr = String(result.error || "");
if (result.status === 429 && isDailyQuotaExhausted(errorStr)) {
// Parse which model is quota-limited
const match = errorStr.match(/today's quota for model ([^,]+)/);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The regex for extracting the model name is brittle and only supports one specific English pattern. Since this PR includes Chinese localization and targets Chinese providers like ModelScope/Kimi, it should also handle Chinese error patterns (e.g., 模型 ([^ ]+) 的今日额度).

Suggested change
const match = errorStr.match(/today's quota for model ([^,]+)/);
const match = errorStr.match(/today's quota for model ([^,]+)/) || errorStr.match(/模型\s*([^ ]+)\s*的今日额度/);

diegosouzapw added a commit that referenced this pull request Apr 27, 2026
…rrors (#1644)

When a provider returns 429 with quota_exhausted reason, set cooldown until
tomorrow 00:00 instead of exponential backoff. Includes isDailyQuotaExhausted()
detection in chat handler and unit tests.

Co-authored-by: clousky2020 <clousky2020@users.noreply.github.com>
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Thanks @clousky2020 for this excellent daily quota lockout feature! 🎉 We translated the Chinese comments to English and integrated your changes into release/v3.7.1 (commit 78b845b). The daily quota lockout with midnight reset is a great improvement for ModelScope and Kimi users. This will ship with the next release. We appreciate your contribution!

This was referenced Apr 30, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…rrors (cheaper-inference#1644)

When a provider returns 429 with quota_exhausted reason, set cooldown until
tomorrow 00:00 instead of exponential backoff. Includes isDailyQuotaExhausted()
detection in chat handler and unit tests.

Co-authored-by: clousky2020 <clousky2020@users.noreply.github.com>
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…rrors (cheaper-inference#1644)

When a provider returns 429 with quota_exhausted reason, set cooldown until
tomorrow 00:00 instead of exponential backoff. Includes isDailyQuotaExhausted()
detection in chat handler and unit tests.

Co-authored-by: clousky2020 <clousky2020@users.noreply.github.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…rrors (cheaper-inference#1644)

When a provider returns 429 with quota_exhausted reason, set cooldown until
tomorrow 00:00 instead of exponential backoff. Includes isDailyQuotaExhausted()
detection in chat handler and unit tests.

Co-authored-by: clousky2020 <clousky2020@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants