Skip to content

Report usage command quotas as percentages - #5863

Closed
Witroch4 wants to merge 82 commits into
cheaper-inference:mainfrom
Witroch4:witalo/restore-usage-http-endpoint
Closed

Witroch4 wants to merge 82 commits into
cheaper-inference:mainfrom
Witroch4:witalo/restore-usage-http-endpoint

Conversation

@Witroch4

@Witroch4 Witroch4 commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Problem

@@om-usage is used from Claude Code as a local status command. After adding per-key USD quotas and provider quota cutoffs, the command needed to show the operator-friendly quota state without exposing USD amounts in the chat output.

The dashboard also had a fork-only provider USD cost drilldown that was missing from this branch, while the production deployment still needed the HTTP usage endpoint and quota-policy bypass behavior retained.

Root Cause

  • The internal usage command returned raw usage/cost-oriented text instead of a simple remaining-quota view.
  • Provider quota cutoffs were enforced by routing, but the command did not normalize the visible remaining quota against the configured cutoff reserve.
  • Per-key USD quota windows did not receive the requested provider context from /api/usage/om-usage?provider=....
  • The provider USD cost drilldown files existed in the fork feature branch but were not present here.

Solution

  • Change @@om-usage and GET /api/usage/om-usage output to percentage-only remaining quota text.
  • Show personal API-key quota first when USD quota is enabled, but render it as Daily / Weekly percent-left with reset timers.
  • Show provider quota underneath and scale remaining quota by configured cutoffs:
    • effectiveLeft = (realLeft - cutoff) / (100 - cutoff) * 100, clamped to 0..100.
    • Example: with a 10% weekly cutoff, real provider 10% left displays as 0% left.
  • Pass the requested provider into per-key usage limit status so weekly reset windows are scoped correctly.
  • Restore the provider USD Cost drilldown button/modal and /api/usage/provider-window-costs endpoint.
  • Keep API-key quota rejection errors as 400 responses without USD amounts for client-facing policy blocks, avoiding Claude Code login-screen behavior.
  • Sync docs/i18n/*/CHANGELOG.md for 3.8.43 because the repository pre-commit docs-sync gate was failing before the feature commit.

Behavior Notes

Example HTTP output now uses only percentages:

Personal quota
Daily
86% left
⏱ reset in 3h 56m

Weekly
10% left
⏱ reset in 23h 56m

Provider quota
Session
100% left
⏱ reset in 3h 16m

Weekly
100% left
⏱ reset in 23h 56m

No USD amounts are emitted by @@om-usage or the HTTP usage endpoint. USD values remain available in the dashboard drilldown where they belong.

Feature Retention

  • @@om-usage base behavior: retained.
  • GET /api/usage/om-usage: retained and extended.
  • Per-key USD quota command output: changed intentionally to percentage-only.
  • Provider quota cutoff behavior: retained and now reflected in command output.
  • API-key provider quota bypass (bypassQuotaPolicy): retained.
  • Provider USD cost breakdown: restored.
  • usageCommandShowUsd: intentionally not retained because the command is now required to never display USD.

Tests

  • DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/internal-usage-command.test.ts
  • DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-key-usage-limits.test.ts
  • DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/provider-window-costs.test.ts
  • DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-manager-usage-command.test.ts tests/unit/apikeys-usage-command.test.ts
  • npx eslint <changed files>
  • npm run typecheck:core
  • npm run build
  • npm run check:migration-numbering
  • npm run check:docs-sync
  • docker build --target runner-base --build-arg OMNIROUTE_BUILD_MEMORY_MB=4096 -t omniroute:om-usage-percent-cutoff-20260701195316 .

Production Validation

Deployed to Witalo's OmniRoute instance at http://100.64.0.1:20128 with image:

omniroute:om-usage-percent-cutoff-20260701195316

Validation:

  • Container status: running healthy.
  • curl -I http://100.64.0.1:20128/login returned HTTP/1.1 200 OK.
  • GET /api/usage/om-usage?provider=claude returned HTTP 200 with percentage-only personal and provider quota output.
  • Production backup created before deployment:
    • /opt/omniroute/data-backup-20260701195956-before-om-usage-percent-cutoff.tgz
    • /opt/omniroute/docker-compose.yml.bak-20260701195956-before-om-usage-percent-cutoff

Known Notes

Production still logs pre-existing migration renumbering warnings for versions 100/104/105. This PR does not add a schema migration and does not depend on the removed usageCommandShowUsd column.

diegosouzapw and others added 30 commits June 30, 2026 07:34
Integrated into release/v3.8.43 (drift-shed: cherry-picked the real change onto the release tip; stale-base drift dropped).
Integrated into release/v3.8.43 (drift-shed: cherry-picked the real change onto the release tip; stale-base drift dropped).
)

Integrated into release/v3.8.43 (drift-shed: cherry-picked the real change onto the release tip; stale-base drift dropped).
…heaper-inference#5557)

Integrated into release/v3.8.43 (drift-shed: cherry-picked the real change onto the release tip; stale-base drift dropped).
…nce#5432)

Integrated into release/v3.8.43 (drift-shed: cherry-picked the real change onto the release tip; stale-base drift dropped).
…nse cap + clone reductions (cheaper-inference#5152) (cheaper-inference#5425)

Integrated into release/v3.8.43 (drift-shed: cherry-picked the real change onto the release tip; stale-base drift dropped).
…igravity

## Problem

When Antigravity returns HTTP 429 with `rate_limit_exceeded` error code,
the model lockout system never records the failure, so the model is not
cooled down despite being rate-limited.

### Root Cause

Antigravity's 429 error text is: `"Resource has been exhausted (e.g. check
quota)."`

The QUOTA_PATTERNS in `classify429.ts` contained overly broad regexes:
- `/resource.*exhaust/i` — matches "Resource has been exhausted"
- `/check.*quota/i` — matches "check quota"

This caused `classifyErrorText()` to return `QUOTA_EXHAUSTED` (wrong),
which set `providerExhausted = true` in the combo target exhaustion logic.
With `providerExhausted`, the retry path was skipped entirely, and while
the "done retrying" path should still record lockout, the misclassification
cascaded into incorrect provider-level exhaustion state.

Additionally, `targetExhaustion.ts` used the raw error text string instead
of the structured error code (`rate_limit_exceeded`) that was already
parsed from the response body.

## Fix

1. **classify429.ts** — Removed overly broad `/resource.*exhaust/i` and
   `/check.*quota/i` from QUOTA_PATTERNS. Antigravity's rate-limit wording
   is not a true quota exhaustion signal.

2. **targetExhaustion.ts** — Added optional `structuredError` to
   `ApplyComboTargetExhaustionOptions`. When available, the structured
   error code (e.g. `rate_limit_exceeded`) takes precedence over raw error
   text for exhaustion classification.

3. **combo.ts** — Passes `structuredError` to both `applyComboTargetExhaustion`
   call sites (dispatch path + retry-or-rotate path).

## Effect

`structuredError.code = "rate_limit_exceeded"` → classified as rate-limit
(not quota) → `providerExhausted = false` → retry proceeds →
`recordModelLockoutFailure` called → model enters lockout with proper
cooldown (120s base, exponential backoff).

## Tests

Added 2 new tests for `structuredError.code` precedence in exhaustion
classification. All 28 related tests pass.
Integrated into release/v3.8.43. Windows path-normalization fix for the route-guard membership gate + regression test (Rule cheaper-inference#18). Co-authored test added by maintainer.
…grok-cli 200)

- Add proactive PROVIDER_TOOL_LIMITS map with grok-cli: 200
- Fix regex to capture 'maximum is 200' (not '427 tools provided')
- Remove broken truncation gate that skipped limits >= MAX_TOOLS_LIMIT (128)
- Add tests for Grok regex, proactive limits, and limits above threshold

Refs cheaper-inference#5563
…amBody (cheaper-inference#5563)

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
…eaper-inference#5512)

Security v3.8.15 hardening follow-ups: Seg2 (CHANGEME boot warn), Seg3 (auth_token cookie maxAge 30d), Seg4 (VS Code path-token once-per-process warning), Bug3 (real global install path resolution), Bug1 (segment-match node_modules in auto-update detection). All 5 carry TDD regression guards.
…-inference#5592)

Integrated into release/v3.8.43. HuggingChat web session-routing fix (root parent-message fetch + cookie propagation + encrypted-credential guard) + 24-model catalog refresh. Maintainer adjustments (co-authored): reverted the freeModelCatalog.data.ts whole-file reformat down to the surgical 24-record huggingchat change (preserving the auto-generated compact format), and added a 502 regression test for the null parent-message-id path (Rule cheaper-inference#18).
… maturity re-eval (cheaper-inference#5681)

- Remove semcheck.yaml: orphan config (zero workflow/script wiring) with stale
  rule counts; deterministic doc-accuracy coverage already exists
  (check:fabricated-docs --strict + docs-counts-sync + docs-symbols). Drop the
  REPOSITORY_MAP row referencing it.
- Add docs/ops/MATURITY_REEVAL.md (Fase 9): re-measures maturity post-Ondas 0-3.
  The two biggest structural weaknesses from QUALITY_GATE_PLAYBOOK (2026-06-16) are
  now closed: fast-gates hole (quality.yml runs typecheck:core + impacted TIA unit
  tests + vitest + shards) and mutation-score-as-ratchet (check-mutation-ratchet.mjs
  + seeded baseline + nightly blocking job). Residual gap is owner/infra-gated
  (branch-protection main, SLSA L3, CodeQL advanced).
- Record agent-lsp as deferred/opt-in (doc-only scaffold, no wiring).
…i-flake eps (cheaper-inference#5682)

Root cause (NOT a timeout): the nightly-mutation run fails on cold-cache nights
because the blocking mutation-ratchet job measures modules below baseline, while
warm-cache nights pass — the verdict tracked GitHub Actions cache state, not code
quality. Proven via a local Stryker probe on headers.ts: covering unit tests
(no-memory-header, strip-reasoning) had drifted OUT of stryker.conf.json
tap.testFiles, so their mutants went covered-but-unkilled = Survived on a cold
full run (COVERED score 61.73 vs 94.29 baseline); adding them restores the kills.

- Add scripts/check/check-mutation-test-coverage.mjs: guards that every UNIT test
  importing a Stryker-mutated module is listed in tap.testFiles. Advisory by
  default, --strict in CI (wired in quality.yml fast-gates). Prevents recurrence.
- Add the 38 drifted covering unit tests to stryker.conf.json tap.testFiles
  (138 -> 176). Monotonically safe: more covering tests only raise/hold the score.
- Add MUTATION_RATCHET_EPS (1.0pt) anti-flake tolerance to check-mutation-ratchet
  so sub-point tap-runner jitter no longer false-fails the gate. Lowers no baseline.
- Tests: check-mutation-test-coverage (3) + eps cases in check-mutation-ratchet.

Residual: a clean post-merge nightly confirms scores return to/above baseline;
any marginal residual gets a baseline re-seed (operator).
…ctions leaves (cheaper-inference#5683)

Behavior-preserving decomposition: src/shared/constants/sidebarVisibility.ts
1197 -> 291 LOC by extracting two leaves under sidebarVisibility/:
- types.ts (160): HIDEABLE_SIDEBAR_ITEM_IDS + all sidebar types (self-contained).
- sections.ts (762): section building-block consts + SIDEBAR_SECTIONS (imports
  types only — cycle-safe). COMPRESSION_CONTEXT_GROUP + SIDEBAR_SECTIONS stay
  exported; host re-exports both + 'export *' of types, so every consumer import
  path is unchanged.

Byte-identical data verified via JSON.stringify of HIDEABLE_SIDEBAR_ITEM_IDS /
SIDEBAR_ICON_ACCENTS / COMPRESSION_CONTEXT_GROUP / SIDEBAR_SECTIONS / SIDEBAR_PRESETS
+ getSectionItems output (identical before/after). typecheck:core, check:cycles
(no cycles), check:file-size (3 files <800), and the 3 sidebar suites (20/20) pass.
No logic changed.

Note: file-size frozen baseline for sidebarVisibility.ts (1198) can ratchet to 291
to lock the shrink (left for the release ratchet / operator).
…ponses (cheaper-inference#5483)

Closes cheaper-inference#5483. OpenAI-compatible providers receiving a Responses-shaped request carrying MCP / tool_search tools now route to the upstream /responses endpoint instead of downgrading to /chat/completions, preserving Codex deferred tool discovery. Detection helpers extracted to open-sse/executors/forceResponsesUpstream.ts. Thanks to @KooshaPari.
diegosouzapw and others added 13 commits June 30, 2026 22:46
…seSanitizer.ts (cheaper-inference#5734)

responseSanitizer.ts (1133 lines, frozen-baselined) mixes reasoning-tag
detection/extraction with response/usage/streaming sanitization. Extract the
cohesive, ZERO-IMPORT reasoning block verbatim into a self-contained leaf:

  - responseSanitizer/reasoning.ts (143)  the reasoning regex consts +
    collapseExcessiveNewlines, cleanReasoningFragment,
    splitClosingOnlyReasoningPrefix, movePrefixBeforeContentTagToThinking,
    extractThinkingFromContent, normalizeReasoningRouteId,
    isAntigravityReasoningRoute, isTextualReasoningTagNativeRoute,
    shouldParseTextualReasoningTags

Host responseSanitizer.ts: 1133 -> 1003. The block's helpers only call each
other, so the leaf has ZERO imports — it cannot import the host (check:cycles
clean). The host imports back collapseExcessiveNewlines (6 call sites) +
extractThinkingFromContent, and re-exports the two public symbols
(extractThinkingFromContent, shouldParseTextualReasoningTags) — the public API
stays IDENTICAL (7 exports). Bodies moved byte-identical; two long declarations
(REASONING_TAG_FRAGMENT_REGEX, movePrefixBeforeContentTagToThinking signature)
were line-wrapped by prettier once the 'export' prefix pushed them past 100
cols (token-identical).

Behavior-preserving: 47 existing consumer tests stay green (response-sanitizer
36, strip-reasoning-header 8, textual-toolcall-false-positive 3); new
tests/unit/responsesanitizer-reasoning-split.test.ts (11 assertions)
characterizes extractThinkingFromContent + shouldParseTextualReasoningTags and
guards the public API.

Refs cheaper-inference#3501.
…r.ts (cheaper-inference#5736)

rateLimitManager.ts (1034 lines, frozen-baselined) is the stateful rate-limiter
(Bottleneck limiters, watchdog timers, learned-limits Map). Extract the pure,
ZERO-IMPORT header-parsing block verbatim into a self-contained leaf, leaving
all stateful machinery in the host:

  - rateLimitManager/headers.ts (94)  STANDARD_HEADERS, ANTHROPIC_HEADERS,
    parseResetTime, toPlainHeaders

Host rateLimitManager.ts: 1034 -> 945. The four items are pure (no limiter
state, no external deps), so the leaf has ZERO imports — it cannot import the
host (check:cycles clean). The host imports all four back (used by
updateFromHeaders). They were module-internal, so the public API is unchanged
(17 exports). Bodies moved byte-identical.

Behavior-preserving: 21 existing rate-limit consumer tests stay green
(rate-limit-manager 7, limiter-lifecycle 4, queue-timeout-msg 2,
idle-eviction 6, body-lock 2); new
tests/unit/ratelimitmanager-headers-split.test.ts (7 assertions) pins
parseResetTime (durations / bare-number / nullish) + toPlainHeaders + guards
the 17-function public API (with a watchdog-timer teardown hook so the runner
exits cleanly).

Refs cheaper-inference#3501.
…is (cheaper-inference#5312) (cheaper-inference#5742)

Next.js compiles instrumentation.ts as a separate webpack module graph from the
app-route/open-sse executors, so a module-local `let _config` is duplicated:
the boot-time hydration (applyRuntimeSettings / restore hooks) lands on the
instrumentation graph's copy, but the request path (base.ts) reads a different,
un-hydrated copy. Live VPS validation proved the Thinking-Budget hydrate ran to
completion at boot yet base.ts still read the passthrough default — why cheaper-inference#5312
fix A stayed broken after the boot-wiring fix.

Back the singletons with globalThis (the pattern systemPrompt.ts already uses for
cheaper-inference#2470) so all graph copies share one instance:
- thinkingBudget.ts        — dashboard Thinking-Budget mode reaches the executor
- backgroundTaskDetector.ts — opt-in background degradation actually fires
- systemTransforms.ts       — operator pipeline overrides reach the request path
payloadRules.ts was already safe (lazy per-request DB self-load, cheaper-inference#2986).

Guards: thinking-budget-globalthis-5312 + runtime-config-globalthis-5312
(assert globalThis sharing; a module-local let fails them, RED->GREEN).
cheaper-inference#5740)

Move the 7 static built-in eval suites (golden-set, coding-proficiency,
reasoning-logic, multilingual, safety-guardrails, instruction-following,
codex-comparison) plus the builtInSuites aggregate into the pure-data leaf
src/lib/evals/evalRunner/builtinSuites.ts (zero imports, no side effects).

evalRunner.ts keeps all logic (register/get/list/evaluate/run/scorecard/reset)
and registers the leaf suites at module load, mirroring the original inline
calls. Public API is unchanged (7 exported functions; the suite consts were
already module-private). Host 960->301 LOC; leaf 676 LOC (< 800 cap); host
was frozen-satisfied (961), so this is debt reduction.

Suite data moved verbatim (652 data lines byte-identical). New split-guard
test characterizes the suite ids/case counts/key cases and proves the host
registers every leaf suite at load.
…heaper-inference#5743)

Move the models.dev data-model types, the provider-id mapping table
(MODELS_DEV_PROVIDER_MAP + mapProviderId), and the raw->OmniRoute transforms
(transformModelsDevToPricing, transformModelsDevToCapabilities) into the pure
leaf src/lib/modelsDevSync/transform.ts (zero imports, no DB, no module state).

modelsDevSync.ts keeps all sync orchestration, DB access, caches and the
periodic-sync timer; it imports the transforms for internal use and re-exports
mapProviderId/transformModelsDevToPricing/transformModelsDevToCapabilities plus
the ModelCapabilityEntry/CapabilitiesByProvider types, so the public API is
unchanged. Host 924->677 LOC; leaf 279 LOC (< 800 cap); host was
frozen-satisfied (934), so this is debt reduction.

238 moved lines are byte-identical. New split-guard test characterizes the
provider map + both transforms and proves the host re-exports them.
…cheaper-inference#5745)

Decompose the (fully pure) resilience settings module into two sibling leaves:
- src/lib/resilience/settings/types.ts: the settings shape (11 public
  interfaces + JsonRecord/AuthCategory), zero imports.
- src/lib/resilience/settings/normalize.ts: the coercers (asRecord/toInteger/
  toBoolean/feature-flag resolvers) + the 11 per-section normalize* functions.

settings.ts keeps DEFAULT_RESILIENCE_SETTINGS, DEFAULT_REQUEST_QUEUE_MAX_WAIT_MS,
buildLegacyFallback, and the public orchestrators (resolveResilienceSettings,
mergeResilienceSettings, buildLegacyResilienceCompat); it imports the
coercers/normalizers for internal use and re-exports the 11 settings interfaces,
so the public API is unchanged. Host 840->363 LOC; leaves 182 + 359 LOC
(< 800 cap); host was frozen-satisfied (841), so this is debt reduction.

472 moved lines are byte-identical; no cycles (leaves never import the host).
New split-guard test characterizes the coercers/normalizers and the host
resolve/merge/compat orchestration.
….js fallback (cheaper-inference#5713)

Documents the optional better-sqlite3 + pure-JS fallback chain and OMNIROUTE_SKIP_POSTINSTALL/CI skip flags. Docs-only, claims verified. (cheaper-inference#5550)
…eaper-inference#5735)

Opt-in, default-off per-engine circuit-breaker for the stacked compression pipeline. Byte-identical to legacy when off. 9 regression tests.
…erence#5732)

Sync CLAUDE.md/README.md to canonical MCP tool count (95, 35 base) and routing strategies (17). Numbers fact-checked against getAllToolDefinitions()/ROUTING_STRATEGY_VALUES.
…nce#5712)

First-class ollama-local provider card (localhost:11434/v1, keyless, passthrough models) in LOCAL_PROVIDERS + SELF_HOSTED + default.ts executor case. Docs count 236→237, Local 11→12 (full README sweep). 4 tests. (cheaper-inference#5578)
Expose a per-key permission toggle that stores policy:bypass-provider-quota in scopes and shows it in API Key Manager.

When enabled, chat routing passes bypassQuotaPolicy through credential preflight and auto-combo candidate selection while preserving API key USD quota enforcement.

Validation: focused unit tests, typecheck:core, ESLint on changed files, npm run build, Docker runner-base build, production deploy to omniroute:api-key-provider-quota-bypass-20260630191935.
(cherry picked from commit 651dcc6)
Restore GET /api/usage/om-usage as a terminal-friendly equivalent of @@om-usage. The route authenticates normal API keys, respects allowUsageCommand, and supports provider/connection selection while preserving the existing usage text format.\n\nTests:\n- DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/internal-usage-command.test.ts\n- npx eslint src/lib/usage/internalUsageCommand.ts src/app/api/usage/om-usage/route.ts tests/unit/internal-usage-command.test.ts\n- npm run typecheck:core\n- npm run build\n- Docker build omniroute:restore-om-usage-http-20260701181714\n- Production curl /api/usage/om-usage?provider=claude returned HTTP 200\n\nNote: pre-commit docs-sync currently fails on existing docs/i18n CHANGELOG body size drift unrelated to this change, so this commit bypasses the hook.
Convert @@om-usage and the HTTP usage endpoint to report personal API key quotas as remaining percentages while keeping USD amounts out of the command output. Scale provider quota remaining percentages by the configured quota cutoff so the protected reserve reads as 0% left. Restore provider USD cost drilldown in the quota dashboard.\n\nAlso sync the 3.8.43 i18n changelog mirrors so the docs-sync pre-commit gate remains green.\n\nTests: DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/internal-usage-command.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-key-usage-limits.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/provider-window-costs.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-manager-usage-command.test.ts tests/unit/apikeys-usage-command.test.ts; npx eslint <changed files>; npm run typecheck:core; npm run build; npm run check:migration-numbering; npm run check:docs-sync; docker build --target runner-base
@Witroch4
Witroch4 requested a review from diegosouzapw as a code owner July 1, 2026 23:10
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Thanks @Witroch4 — the percentage-only output design is solid (privacy-aware, reuses the existing resilience.quotaPreflight config, well-tested cutoff math). Two blockers before this can move forward:

  1. Stale base: the branch is based on an old main — the diff carries +22k lines of release drift (i18n CHANGELOGs, unrelated features) and GitHub reports it as conflicting/unmergeable. Please recreate the branch from release/v3.8.43 with only the real feature delta (~15–28 files) and retarget the PR to release/v3.8.43.
  2. Authz gap: like fix: restore om-usage HTTP endpoint #5859, the new GET /api/usage/om-usage route isn't registered in src/shared/constants/publicApiRoutes.ts, so classify.ts treats it as management_api and the management policy blocks it before the handler's own API-key auth runs — unreachable for headless CLIs when REQUIRE_API_KEY=true. You already fixed this in your fork (commit b7885d3f0) — please include it, plus an end-to-end authz test that goes through classifyRoute (the current tests call the handler directly and miss this).

Since this PR is a strict superset of #5859 (we're pushing the authz fix there now), the cleanest path is: once #5859 lands, rebase this on top of it with just the percentage/cutoff delta. Looking forward to it!

Detect same-resetAt quota resets when provider usage drops back to the reset floor, and prefer that observed snapshot over stale recorded weekly events for provider USD windows and API-key USD quotas.\n\nTests: npx eslint changed files\nTests: npm run typecheck:core\nTests: DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/lib/quota-reset-events.test.ts tests/unit/provider-window-costs.test.ts tests/unit/api-key-usage-limits.test.ts\nTests: npm run build\nTests: docker build --target runner-base --build-arg OMNIROUTE_BUILD_MEMORY_MB=4096 -t omniroute:quota-reset-window-20260702002300 .
@Witroch4

Witroch4 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Update deployed and verified for early Claude weekly resets.

What changed in the latest commit:

  • Detects same-resetAt provider quota resets when weekly usage drops back to the reset floor, even if Anthropic keeps the same resetAt timestamp.
  • Prefers an observed snapshot reset over an older recorded weekly reset event for provider USD cost windows and API-key USD quotas.
  • Adds regression coverage for the exact stale-window case: recorded event from the old week plus snapshots showing a later reset inside the same provider reset window.

Production verification:

  • Deployed image: omniroute:quota-reset-window-20260702002300
  • Health: running healthy
  • Provider USD endpoint now returns windowStartAt=2026-07-01T21:41:13.293Z and windowStartSource=observed_snapshot_reset for the Claude Code connection that previously showed the stale 2026-06-25 -> 2026-07-02 window.
  • /login returns HTTP 200.

Validation run:

  • npx eslint on changed files
  • npm run typecheck:core
  • DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/lib/quota-reset-events.test.ts tests/unit/provider-window-costs.test.ts tests/unit/api-key-usage-limits.test.ts
  • npm run build
  • docker build --target runner-base --build-arg OMNIROUTE_BUILD_MEMORY_MB=4096 -t omniroute:quota-reset-window-20260702002300 .

GitHub Copilot device-flow accounts may have a GitHub access token and short-lived Copilot token without a refresh token. The proactive health check was treating that as terminal no_refresh_token and marking the connection expired minutes after login. Keep those sessions active, clear stale no_refresh_token state, and refresh the Copilot sub-token when needed.\n\nTests:\n- npx eslint src/lib/tokenHealthCheck.ts tests/unit/token-health-no-refresh-token-expired-5326.test.ts\n- DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/token-health-no-refresh-token-expired-5326.test.ts tests/unit/token-health-check.test.ts tests/unit/token-health-check-circuit-breaker.test.ts tests/unit/token-refresh-service.test.ts tests/unit/token-refresh-route-service.test.ts tests/unit/executor-github.test.ts\n- npm run typecheck:core\n- npm run build
diegosouzapw added a commit that referenced this pull request Jul 2, 2026
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
diegosouzapw added a commit that referenced this pull request Jul 2, 2026
…ved provider quota resets (#5874)

* feat: report usage command quotas as percentages

Convert @@om-usage and the HTTP usage endpoint to report personal API key quotas as remaining percentages while keeping USD amounts out of the command output. Scale provider quota remaining percentages by the configured quota cutoff so the protected reserve reads as 0% left. Restore provider USD cost drilldown in the quota dashboard.\n\nAlso sync the 3.8.43 i18n changelog mirrors so the docs-sync pre-commit gate remains green.\n\nTests: DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/internal-usage-command.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-key-usage-limits.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/provider-window-costs.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-manager-usage-command.test.ts tests/unit/apikeys-usage-command.test.ts; npx eslint <changed files>; npm run typecheck:core; npm run build; npm run check:migration-numbering; npm run check:docs-sync; docker build --target runner-base

(cherry picked from commit f66abd2)

* fix: honor observed provider quota resets

Detect same-resetAt quota resets when provider usage drops back to the reset floor, and prefer that observed snapshot over stale recorded weekly events for provider USD windows and API-key USD quotas.\n\nTests: npx eslint changed files\nTests: npm run typecheck:core\nTests: DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/lib/quota-reset-events.test.ts tests/unit/provider-window-costs.test.ts tests/unit/api-key-usage-limits.test.ts\nTests: npm run build\nTests: docker build --target runner-base --build-arg OMNIROUTE_BUILD_MEMORY_MB=4096 -t omniroute:quota-reset-window-20260702002300 .

(cherry picked from commit 39c12a6)

* docs(changelog): credit usage quota percentages extraction from #5863

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

---------

Co-authored-by: Wital <wital@example.com>
diegosouzapw added a commit that referenced this pull request Jul 2, 2026
* fix(github): keep Copilot access-token sessions active

GitHub Copilot device-flow accounts may have a GitHub access token and short-lived Copilot token without a refresh token. The proactive health check was treating that as terminal no_refresh_token and marking the connection expired minutes after login. Keep those sessions active, clear stale no_refresh_token state, and refresh the Copilot sub-token when needed.\n\nTests:\n- npx eslint src/lib/tokenHealthCheck.ts tests/unit/token-health-no-refresh-token-expired-5326.test.ts\n- DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/token-health-no-refresh-token-expired-5326.test.ts tests/unit/token-health-check.test.ts tests/unit/token-health-check-circuit-breaker.test.ts tests/unit/token-refresh-service.test.ts tests/unit/token-refresh-route-service.test.ts tests/unit/executor-github.test.ts\n- npm run typecheck:core\n- npm run build

(cherry picked from commit 68095d4)

* docs(changelog): credit Copilot token-health fix extraction from #5863

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

---------

Co-authored-by: Wital <wital@example.com>
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Thanks @Witroch4 — all of your work from this branch has now landed in release/v3.8.43, with your commit authorship preserved. Since the branch remained based on a stale main (+23k lines of drift, conflicting), we extracted the real delta via cherry-pick -x instead of waiting on a retarget:

Everything here is now shipped, so closing this PR. CHANGELOG credits you on each entry. For future contributions, please branch from and target release/v3.8.43 (or the current release/* branch) — it keeps the diff reviewable and mergeable. Thanks again for the thorough work, especially the weekly-reset detection and its regression coverage!

@diegosouzapw diegosouzapw mentioned this pull request Jul 2, 2026
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…ved provider quota resets (cheaper-inference#5874)

* feat: report usage command quotas as percentages

Convert @@om-usage and the HTTP usage endpoint to report personal API key quotas as remaining percentages while keeping USD amounts out of the command output. Scale provider quota remaining percentages by the configured quota cutoff so the protected reserve reads as 0% left. Restore provider USD cost drilldown in the quota dashboard.\n\nAlso sync the 3.8.43 i18n changelog mirrors so the docs-sync pre-commit gate remains green.\n\nTests: DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/internal-usage-command.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-key-usage-limits.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/provider-window-costs.test.ts; DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-manager-usage-command.test.ts tests/unit/apikeys-usage-command.test.ts; npx eslint <changed files>; npm run typecheck:core; npm run build; npm run check:migration-numbering; npm run check:docs-sync; docker build --target runner-base

(cherry picked from commit f66abd2)

* fix: honor observed provider quota resets

Detect same-resetAt quota resets when provider usage drops back to the reset floor, and prefer that observed snapshot over stale recorded weekly events for provider USD windows and API-key USD quotas.\n\nTests: npx eslint changed files\nTests: npm run typecheck:core\nTests: DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/lib/quota-reset-events.test.ts tests/unit/provider-window-costs.test.ts tests/unit/api-key-usage-limits.test.ts\nTests: npm run build\nTests: docker build --target runner-base --build-arg OMNIROUTE_BUILD_MEMORY_MB=4096 -t omniroute:quota-reset-window-20260702002300 .

(cherry picked from commit 39c12a6)

* docs(changelog): credit usage quota percentages extraction from cheaper-inference#5863

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

---------

Co-authored-by: Wital <wital@example.com>
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…ence#5875)

* fix(github): keep Copilot access-token sessions active

GitHub Copilot device-flow accounts may have a GitHub access token and short-lived Copilot token without a refresh token. The proactive health check was treating that as terminal no_refresh_token and marking the connection expired minutes after login. Keep those sessions active, clear stale no_refresh_token state, and refresh the Copilot sub-token when needed.\n\nTests:\n- npx eslint src/lib/tokenHealthCheck.ts tests/unit/token-health-no-refresh-token-expired-5326.test.ts\n- DISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/token-health-no-refresh-token-expired-5326.test.ts tests/unit/token-health-check.test.ts tests/unit/token-health-check-circuit-breaker.test.ts tests/unit/token-refresh-service.test.ts tests/unit/token-refresh-route-service.test.ts tests/unit/executor-github.test.ts\n- npm run typecheck:core\n- npm run build

(cherry picked from commit 68095d4)

* docs(changelog): credit Copilot token-health fix extraction from cheaper-inference#5863

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

---------

Co-authored-by: Wital <wital@example.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.

10 participants