Skip to content

feat(api-keys): enforce per-key service tier overrides - #13554

Open
JxnLexn wants to merge 6 commits into
diegosouzapw:release/v3.8.52from
JxnLexn:dev/api-key-codex-service-mode
Open

JxnLexn wants to merge 6 commits into
diegosouzapw:release/v3.8.52from
JxnLexn:dev/api-key-codex-service-mode

Conversation

@JxnLexn

@JxnLexn JxnLexn commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Allow an API key to inherit existing behavior or force Standard (default), Fast/Priority (priority), or Flex (flex) for the OpenAI OAuth provider (codex). Other providers, including regular OpenAI API-key connections, remain unchanged.

  • Persist the setting through existing authenticated key-management GET/PATCH endpoints and expose a confirm-before-save selector in per-key routing settings.
  • Give a forced per-key mode precedence over client service_tier, global service-mode settings and connection defaults.
  • Enforce the mode for resolved combo legs, native Responses, Chat Completions, retries and Responses WebSocket preparation using request-local credential context.
  • Send an explicit service_tier: "default" for Standard, so an account/global Priority default cannot reappear.
  • Do not let compatibility auto-learning silently strip a forced tier. Return the provider error instead.
  • Reject forced-mode requests using the app-server transport, whose adapter cannot enforce service tiers, rather than silently ignoring the setting.

Existing and newly created keys default to inherit. This does not grant provider/model access or guarantee a tier is available for an account.

Related Issues

Historical base-red report #12732 is now closed. Current CI failures must be assessed on their own merits.

The feature was initially based on release/v3.8.51 at 152d95108c9c3d557562311ffed63240a511eb31. No fork deployment workflow, container configuration, admission hotfix, or provider-catalog patch is included.

Validation

  • Change type: routing / DB / API / UI
  • node --import tsx/esm --test tests/integration/api-key-codex-service-mode.test.ts — 12 passed, rerun on this branch.
  • npm run check:migration-numbering — passed.
  • npm run check:db-rules — passed.
  • Diff checked against the current release tip; git diff --check passed.
  • Automated regression tests included.
  • Full repository lint, production build and coverage matrix: left to PR CI, not claimed green locally.

The equivalent fork deployment was verified with a short-lived restricted key: both native Responses and Chat through a combo returned HTTP 200 and captured provider requests contained service_tier: "default" despite client priority. The test key was deleted and existing keys stayed unchanged. This live check verifies Standard enforcement; Priority/Flex availability for every real account is not claimed.

Tests Added Or Updated

  • tests/integration/api-key-codex-service-mode.test.ts: migration defaults/constraints, management API round-trip, metadata-cache invalidation, all three forced tiers, inherited precedence, isolation, combo legs, retries, no silent downgrade, app-server rejection and WebSocket preparation.

Coverage Notes

Tests use isolated storage and a mocked upstream, including the final serialized provider body. Full coverage was not measured locally.

Reviewer Notes

Migration: 179_api_key_codex_service_mode.sql adds a constrained TEXT column with default inherit; the legacy-column fallback uses the same definition. No existing key setting is force-changed. Confirm the migration number is still free if the release branch advances before merge.

This branch does not depend on the new editor: the selector is wired into the existing per-key routing card. If the editor PR lands first, place that same section in its selected-key workspace. If the reasoning reliability PR lands first, preserve both request-local credential contexts at their overlapping preparation sites.

Related independent PRs

All three target the same release tip directly, not each other. Shared-file overlaps may need small integration resolutions after the first PR lands; unrelated fork-only changes are deliberately excluded.

Review follow-up: reconciled with release tip ac52d4d9e; the migration is now 179, avoiding the released 177/178 migrations. The 12 integration tests, migration-numbering gate, DB rules, changelog integrity and core typecheck pass. See the review reply for cross-PR integration evidence.

diegosouzapw added a commit that referenced this pull request Sep 14, 2026
#13248)

Merged after renumbering. `176_provider_connection_synced_models_at.sql` collided with `176_xp_action_counts.sql` (#12651), which made the migration runner abort on every DB open. Renamed to **177**; the doc count moves 173 → 174 across README.md, AGENTS.md, llm.txt and the i18n mirrors (operator-approved, 206 numeric substitutions and nothing else).

- `check:migration-numbering`: OK, 174 migrations, no duplicates
- `check:docs-counts` migrations: ✓
- 84/84 across the NVIDIA suite plus the seven DB-touching suites the collision had taken down
- ESLint and `typecheck:core`: exit 0

Heads-up for whoever lands next: **177 is claimed by eight other open PRs** (#13610, #13602, #13580, #13554, #13405, #13331, #13177, #13116) and 176 by #13373 and #13102. With this merged, all of them need to renumber at merge time — `check:migration-numbering` forbids new gaps, so the next free number is always the only valid one.

⚠️ base-red inherited: #12732
@diegosouzapw

Copy link
Copy Markdown
Owner

Really solid piece of work — the request-local Symbol-tagged credentials approach for the
forced tier (never persisted, never client-settable, dropped by JSON.stringify so it can't leak
into logs) is a clean way to thread this through 5 different dispatch points without touching
persisted state. Ran your integration test on this branch: 12/12 passing (first attempt timed
out under heavy shared-devbox load from other PRs being probed in parallel — not your test; a
retry with more headroom completed cleanly). One blocking item: 177_api_key_codex_service_mode.sql
now collides with 177_provider_connection_synced_models_at.sql, merged to the release branch
after this PR was opened — please renumber and re-run check:migration-numbering. Also missing
a changelog fragment under changelog.d/features/. Heads-up for whoever integrates this with
#13555 (the dedicated routing editor): both of you touch ReasoningRoutingRules.tsx — yours is
a small, isolated 2-line insertion so it should merge cleanly, but flagging so the order is
deliberate.

@JxnLexn

JxnLexn commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — fixed the migration collision and added changelog.d/features/13554-api-key-service-mode.md in 63aa4d2, then reconciled this branch with release tip ac52d4d in 9e1e617. The migration and its regression test now use 179_api_key_codex_service_mode.sql; released migrations 177 and 178 are preserved. I also updated the PR description so it no longer points at 177.

Validation on the reconciled branch:

  • npm run check:migration-numbering — passed.
  • npm run check:db-rules — passed.
  • npm run check:changelog-integrity — passed.
  • npm run typecheck:core — passed.
  • node --import tsx/esm --test tests/integration/api-key-codex-service-mode.test.ts — 12/12 passed.

A separate checkout combining the editor, reasoning-reliability and adaptive-effort PRs passes 40 focused runtime tests and 6 editor tests. The editor overlap needs a small deliberate merge resolution: retain the redesigned workspace and insert the service-mode section for the selected key. The reasoning overlap must retain both request-local credential contexts. No sibling implementation was added to this PR. Full PR CI has not been awaited.

JxnLexn and others added 2 commits September 16, 2026 01:21
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
diegosouzapw added a commit to Bl0ck154/OmniRoute that referenced this pull request Sep 16, 2026
…ken)

Renamed 180_api_key_preferred_connections.sql to 184_api_key_preferred_connections.sql: the
release tip landed 180_memory_fts_au_conditional_memory_id.sql after this PR's previous
renumbering pass. Slot 184 is the owner-assigned number for this PR among the 7 PRs
that collided on the 180 slot (diegosouzapw#13610=181, diegosouzapw#12962=182, diegosouzapw#12967=183, diegosouzapw#13102=184,
diegosouzapw#13222=185, diegosouzapw#13373=186, diegosouzapw#13554=187).

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Slot 180 now collides with the tip's 180_memory_fts_au_conditional_memory_id.sql
(diegosouzapw#13331, merged 2026-09-16). The maintainer assigned 187 as the coordinated
slot for this PR among the six others contending for the same range.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
diegosouzapw added a commit to ahmedhosnypro/OmniRoute that referenced this pull request Sep 16, 2026
Six open PRs claimed migration slot 180 after diegosouzapw#13331 landed it on the
release tip; the owner assigned diegosouzapw#13373 slot 186 in the sequence
(diegosouzapw#13610=181, diegosouzapw#12962=182, diegosouzapw#12967=183, diegosouzapw#13102=184, diegosouzapw#13222=185,
diegosouzapw#13373=186, diegosouzapw#13554=187).

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw diegosouzapw added the deferred-v3.8.52 Grande demais / suspeito para o lote atual; precisa de sessão dedicada no ciclo v3.8.52 label Sep 25, 2026
@diegosouzapw diegosouzapw changed the title feat(api-keys): enforce per-key service tier overrides [defer] feat(api-keys): enforce per-key service tier overrides Sep 25, 2026
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…ouzapw#12849) (diegosouzapw#13248)

Merged after renumbering. `176_provider_connection_synced_models_at.sql` collided with `176_xp_action_counts.sql` (diegosouzapw#12651), which made the migration runner abort on every DB open. Renamed to **177**; the doc count moves 173 → 174 across README.md, AGENTS.md, llm.txt and the i18n mirrors (operator-approved, 206 numeric substitutions and nothing else).

- `check:migration-numbering`: OK, 174 migrations, no duplicates
- `check:docs-counts` migrations: ✓
- 84/84 across the NVIDIA suite plus the seven DB-touching suites the collision had taken down
- ESLint and `typecheck:core`: exit 0

Heads-up for whoever lands next: **177 is claimed by eight other open PRs** (diegosouzapw#13610, diegosouzapw#13602, diegosouzapw#13580, diegosouzapw#13554, diegosouzapw#13405, diegosouzapw#13331, diegosouzapw#13177, diegosouzapw#13116) and 176 by diegosouzapw#13373 and diegosouzapw#13102. With this merged, all of them need to renumber at merge time — `check:migration-numbering` forbids new gaps, so the next free number is always the only valid one.

⚠️ base-red inherited: diegosouzapw#12732
@diegosouzapw
diegosouzapw changed the base branch from release/v3.8.51 to release/v3.8.52 September 29, 2026 11:25
@diegosouzapw

Copy link
Copy Markdown
Owner

Re-homed to release/v3.8.52: v3.8.51 entered its release freeze, so the branch now belongs to the release captain and development continues on the next cycle. Nothing is wrong with this PR — it just needed a live base. No action needed from you; CI will re-run against the new base.

@diegosouzapw diegosouzapw changed the title [defer] feat(api-keys): enforce per-key service tier overrides feat(api-keys): enforce per-key service tier overrides Oct 1, 2026
@diegosouzapw diegosouzapw removed the deferred-v3.8.52 Grande demais / suspeito para o lote atual; precisa de sessão dedicada no ciclo v3.8.52 label Oct 1, 2026

This branch has not been deployed

No deployments
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