Skip to content

Improve self-service provider quota visibility - #2931

Merged
diegosouzapw merged 1 commit into
cheaper-inference:mainfrom
guanbear:feature/self-service-provider-quotas
May 31, 2026
Merged

diegosouzapw merged 1 commit into
cheaper-inference:mainfrom
guanbear:feature/self-service-provider-quotas

Conversation

@guanbear

@guanbear guanbear commented May 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Extend GET /api/v1/me/status account quota visibility from the single Codex case to all provider-limit connections the API key is allowed to use.
  • Add accountQuotas for multi-provider quota entries while preserving the existing accountQuota compatibility field when exactly one entry is returned.
  • Address follow-up polish from Add self-service API key usage status #2908: Date/ISO budget timestamp normalization, explicit modal button types, and i18n usage for the permissions modal management description.
  • Update design docs, OpenSpec, and BDD scenarios for allowed-connection provider quotas.

Behavior Notes

  • self:account-quota remains opt-in and disabled by default.
  • Explicit allowedConnections are resolved one by one; unrestricted keys enumerate all active provider-limit connections because they may use all of them.
  • Per-connection quota fetch failures return an unavailable entry without hiding successful provider quota entries.
  • Explicit connection lookup failures return an unavailable connection_lookup_failed entry; unrestricted connection-list failures keep own usage visible with an empty accountQuotas array.
  • Raw upstream payloads and provider secrets are still not returned.

Verification

  • DISABLE_SQLITE_AUTO_BACKUP=true node --max-old-space-size=8192 --import tsx --import ./open-sse/utils/setupPolyfill.ts --test --test-force-exit tests/unit/api-key-self-service.test.ts tests/unit/api-manager-page-static.test.ts tests/unit/api-manager-scope-preservation.test.ts tests/unit/api-key-scope-validation.test.ts tests/unit/api/v1-me-status-route.test.ts tests/unit/budget-route-auth.test.ts — 22/22 pass
  • node --max-old-space-size=4096 --import tsx --test --test-force-exit --test-concurrency=4 --test-shard=4/8 tests/unit/*.test.ts — 906/906 pass
  • npm run typecheck:core — pass
  • npm run lint -- --quiet — pass
  • npm run check:docs-sync — pass
  • npm run i18n:sync-ui:dry && npm run i18n:check-ui-coverage — pass; dry-run reports existing missing locale keys, coverage passes
  • git diff --check && rg -n "sk-4bf65f1c839de16d|100\.68\.118\.98|guanzhicheng\.com" docs src tests || true — pass/no matches
  • npm run build — pass

@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 refactors the self-service API key status endpoint to support returning multiple provider account quotas (accountQuotas) instead of restricting the output to a single connection or returning an ambiguity error. It updates BDD features, specifications, and unit tests to reflect this change, including support for unrestricted keys and isolated per-connection fetch failures. Additionally, it ensures backwards compatibility by retaining the single accountQuota field when only one quota is returned. In the UI, it updates the permissions modal to use i18n keys and explicit button types. Feedback on the code changes suggests improving resilience by adding .catch handlers to the connection retrieval calls (getProviderConnectionById and getProviderConnections) to prevent potential database or retrieval failures from causing a 500 error.

Comment thread src/lib/usage/apiKeySelfService.ts Outdated
Comment on lines +231 to +234
const rawConnections =
allowedConnections.length > 0
? await Promise.all(allowedConnections.map((id) => deps.getProviderConnectionById(id)))
: await deps.getProviderConnections({ isActive: true });

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

To ensure the self-service status API is resilient against individual connection fetch failures or database query rejections, consider adding .catch(() => null) to getProviderConnectionById and .catch(() => []) to getProviderConnections. This prevents a single failing connection from causing the entire request to fail with a 500 error.

  const rawConnections =
    allowedConnections.length > 0
      ? await Promise.all(
          allowedConnections.map((id) =>
            deps.getProviderConnectionById(id).catch(() => null)
          )
        )
      : await deps.getProviderConnections({ isActive: true }).catch(() => []);

@guanbear
guanbear force-pushed the feature/self-service-provider-quotas branch from 4c09cbc to 76528a5 Compare May 30, 2026 06:30
@guanbear

guanbear commented May 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Addressed the review feedback on connection retrieval resilience in the latest push. Explicit connection lookup failures now return a per-connection unavailable entry with connection_lookup_failed, while unrestricted connection-list failures keep own usage visible and return an empty accountQuotas array. Added unit coverage plus BDD/OpenSpec/design docs for the behavior.

@guanbear
guanbear force-pushed the feature/self-service-provider-quotas branch from 76528a5 to 472001b Compare May 30, 2026 06:43
@guanbear

Copy link
Copy Markdown
Contributor Author

Also addressed the Unit Tests 4/8 CI failure seen on the previous run. The failing chatCore timeout test used a hard-coded 150ms pending-request polling window; under the full shard load it could observe no pending detail before asserting. The latest push uses the existing wait helper default and the exact CI shard command now passes locally: 906/906.

@kilo-code-bot

kilo-code-bot Bot commented May 30, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

The changes in this PR are well-implemented and thoroughly tested. Key improvements:

  1. Multi-provider quota visibility — Extended from Codex-only to all USAGE_SUPPORTED_PROVIDERS (12 providers including antigravity, agy, claude, cursor, codex, kimi-coding, glm, etc.)

  2. Backward compatibility — The accountQuota field is preserved as a compatibility alias when exactly one quota entry exists

  3. Isolated error handling — Each connection's quota fetch failures are isolated without hiding successful results; lookup failures return connection_lookup_failed entries

  4. Date normalization — Properly handles ISO strings, Date objects, and timestamps for budget fields

  5. UI improvements — Added explicit type="button" attributes to switch buttons and i18n support for managementAccessDesc

  6. Test coverage — Comprehensive tests for multi-connection scenarios, fetch failures, and lookup failures

Observation (unchanged code): The Ban Toggle button (line ~1901) in the PermissionsModal does not have type="button" while other switch buttons in the same component now do. This is existing code not changed in this PR, but would be worth addressing for consistency in a follow-up.

Files Reviewed (5 files)
  • src/lib/usage/apiKeySelfService.ts — Core logic with proper error isolation
  • src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx — UI improvements with button types and i18n
  • tests/unit/api-key-self-service.test.ts — Comprehensive test coverage
  • tests/unit/api-manager-page-static.test.ts — Static analysis tests
  • docs/bdd/self-service-api-key-usage.feature — BDD specification updates

Reviewed by nemotron-3-super-120b-a12b-20230311:free · 121,871 tokens

@guanbear
guanbear force-pushed the feature/self-service-provider-quotas branch from 472001b to 8f0c97a Compare May 30, 2026 07:18
@guanbear

Copy link
Copy Markdown
Contributor Author

Addressed the E2E Tests 2/6 failure from the previous run. The create-key modal now keeps validation errors reachable after the new self-service controls make the dialog taller: on invalid names it scrolls/focuses back to the key name field and the modal body has a viewport-aware max height. Verified locally with the exact failing shard command: npx playwright test tests/e2e/*.spec.ts --shard=2/6 (11/11 passed), plus the focused PR unit tests, build, typecheck, lint, docs sync, i18n coverage, diff check, and secret scan.

@guanbear
guanbear force-pushed the feature/self-service-provider-quotas branch from 8f0c97a to 54cec88 Compare May 30, 2026 07:48
@guanbear

Copy link
Copy Markdown
Contributor Author

Follow-up for the latest E2E Tests 2/6 timeout: the cancelled job was blocked on a networkidle wait in combo-unification.spec.ts, after the target page had already rendered. I replaced those waits with the existing UI assertions/actions so the test waits on visible app state instead of background network quiescence.

Local verification after the patch:

  • npx playwright test tests/e2e/combo-unification.spec.ts -g "combos page exposes strategy tabs and intelligent panel" -> 1/1 passed
  • npx playwright test tests/e2e/*.spec.ts --shard=2/6 -> 11/11 passed
  • npm run lint -- --quiet
  • git diff --check
  • secret scan for previously shared deployment values

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Thank you for your contribution! This PR has been reviewed and integrated into the upcoming v3.8.8 release. 🎉

@diegosouzapw
diegosouzapw merged commit e51ab94 into cheaper-inference:main May 31, 2026
85 checks passed
@diegosouzapw diegosouzapw mentioned this pull request Jun 2, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
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