Repository navigation
Conversation
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).
…isolation + surface errors (cheaper-inference#5595) (cheaper-inference#5686)
… 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.
…t reds are not missed (cheaper-inference#5644) Integrated into release/v3.8.43.
…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
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Thanks @Witroch4 — the percentage-only output design is solid (privacy-aware, reuses the existing
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 .
|
Update deployed and verified for early Claude weekly resets. What changed in the latest commit:
Production verification:
Validation run:
|
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
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
…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>
* 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>
|
Thanks @Witroch4 — all of your work from this branch has now landed in
Everything here is now shipped, so closing this PR. CHANGELOG credits you on each entry. For future contributions, please branch from and target |
…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>
…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>
Problem
@@om-usageis 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
/api/usage/om-usage?provider=....Solution
@@om-usageandGET /api/usage/om-usageoutput to percentage-only remaining quota text.Daily/Weeklypercent-left with reset timers.effectiveLeft = (realLeft - cutoff) / (100 - cutoff) * 100, clamped to0..100.10% leftdisplays as0% left.USD Costdrilldown button/modal and/api/usage/provider-window-costsendpoint.docs/i18n/*/CHANGELOG.mdfor3.8.43because the repository pre-commitdocs-syncgate was failing before the feature commit.Behavior Notes
Example HTTP output now uses only percentages:
No USD amounts are emitted by
@@om-usageor the HTTP usage endpoint. USD values remain available in the dashboard drilldown where they belong.Feature Retention
@@om-usagebase behavior: retained.GET /api/usage/om-usage: retained and extended.bypassQuotaPolicy): retained.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.tsDISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-key-usage-limits.test.tsDISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/provider-window-costs.test.tsDISABLE_SQLITE_AUTO_BACKUP=true node --import tsx/esm --test tests/unit/api-manager-usage-command.test.ts tests/unit/apikeys-usage-command.test.tsnpx eslint <changed files>npm run typecheck:corenpm run buildnpm run check:migration-numberingnpm run check:docs-syncdocker 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:20128with image:omniroute:om-usage-percent-cutoff-20260701195316Validation:
running healthy.curl -I http://100.64.0.1:20128/loginreturnedHTTP/1.1 200 OK.GET /api/usage/om-usage?provider=claudereturnedHTTP 200with percentage-only personal and provider quota output./opt/omniroute/data-backup-20260701195956-before-om-usage-percent-cutoff.tgz/opt/omniroute/docker-compose.yml.bak-20260701195956-before-om-usage-percent-cutoffKnown 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
usageCommandShowUsdcolumn.