Skip to content

feat(aliases): provider and model aliases across router, API, CLI and GUI (#2463) - #2610

Merged
lidge-jun merged 3 commits into
devfrom
codex/2463-aliases-merged
Aug 25, 2026
Merged

lidge-jun merged 3 commits into
devfrom
codex/2463-aliases-merged

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Aug 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

Closes #2463. Real routed slugs are things like google-antigravity/gemini-3-pro-preview-11-2025, and the user types them into Codex's picker, /model, CLI flags and combo targets. This adds a user-chosen short name that resolves on all of those surfaces.

Aliases are a resolution and display layer, never a storage format. selectedModels, disabledModels, combos and usage rows keep canonical slugs only, so an alias can be renamed or deleted without touching persisted state, and slugEquals / the visibility filters are untouched. /v1/models annotates rows with alias_of rather than adding alias rows — the annotate-only reading of the design's open question 1, so no existing client sees a row it does not recognise.

Resolution extends the ladder at exactly two points rather than one: qualified head/tail aliases sit below combo aliases, so anything a combo already claims keeps its meaning; bare aliases sit after every existing bare step and immediately before the defaultProvider fallback. That ordering is what makes the collision rules sufficient — an alias can never shadow something that resolves earlier.

One deliberate behavior change, and it is tested in both directions: a bare id that today reaches the defaultProvider fallback resolves via alias when the user defined a matching one. That only fires for aliases the user created or a built-in set they explicitly enabled, which is the point of defining an alias. Users with no aliases configured are unaffected, which has its own test.

Built-ins are patterns, not ids, so a snapshot suffix does not stale them. When two models on one provider match the same rule, the built-in is disabled for that provider rather than guessed — deterministic beats "latest wins", and the user resolves it with an explicit entry.

Verification

bun x tsc --noEmit                            exit 0
bun test <alias + convergence + catalog>      242 pass / 0 fail
bun run build:gui                             ok
bun run lint:gui                              no errors

Falsified per hunk: removing qualified resolution fails the qualified and ambiguity tests; removing the late bare-alias hook fails the bare-fallback and ambiguity tests; removing built-in derivation fails the aggregator test. Each was restored before the final run. The GUI was rendered against a stubbed management API, not trusted to typecheck — the first render exposed provider-header wrapping, which was fixed and re-rendered.

Merge note (why this PR carries a merge commit)

The branch was cut before #2464 landed, and the two features collide in 13 files: nine locale tails, the Models page, the config schema, the model routes and the convergence contract. Every conflict is two additive features that both have to survive, so none of it was resolved by taking a side.

Locale files were merged with git merge-file --union — both branches append disjoint keys at the same tail. model-routes.ts keeps both route blocks in order, taking the convergence count 10 → 13.

The one that mattered: #2464's companion test sliced from its acknowledge route to /api/catalog, and the alias routes now sit in between. Left alone it would have silently swallowed three alias convergence calls and counted them as the discovery route's — passing while asserting nothing. It is retargeted to the next route so each assertion bounds only its own handler.

Checklist

  • Targets dev
  • Focused regression tests, including ladder ordering and every collision rejection
  • docs-site/ updated
  • Strings added to all nine locales
  • No credential, auth, workflow or release-automation surface touched

Summary by CodeRabbit

  • New Features

    • Added provider and model aliases for shorter, case-insensitive model selection.
    • Added the ocx alias command to list, set, remove, and manage default aliases.
    • Added GUI controls for editing aliases, viewing their sources, and identifying stale aliases.
    • Added configurable built-in aliases with global and provider-level controls.
    • Added alias support to model discovery, routing, and request history.
  • Documentation

    • Documented alias configuration, resolution behavior, CLI usage, and conflict handling.
    • Added localized alias-management text across supported languages.

Semantic resolution across 13 files. Both branches touched the same tail
positions in nine locale files, the Models page, the config schema, the model
routes and the convergence contract, so this is not a take-ours/take-theirs
merge - every conflict is two additive features that must both survive.

Locales: git merge-file --union, since both sides append disjoint keys.

model-routes.ts: both route blocks kept in order; the convergence count goes
10 -> 13 (two model-discovery routes plus three alias routes).

codex-convergence-contract.test.ts: the model-discovery companion test sliced
to /api/catalog, which the alias routes now sit before - a fixed far boundary
would have swallowed their convergence calls and counted them as the discovery
route's. Retargeted to the next route so each assertion still bounds only its
own handler.
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner August 25, 2026 19:51
@lidge-jun
lidge-jun merged commit 05ced3c into dev Aug 25, 2026
5 of 7 checks passed
@lidge-jun
lidge-jun deleted the codex/2463-aliases-merged branch August 25, 2026 19:51
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@coderabbitai

coderabbitai Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1257fd86-c5f9-47b3-9d9a-6d8378b3d35f

📥 Commits

Reviewing files that changed from the base of the PR and between 9593b24 and 42a8102.

📒 Files selected for processing (32)
  • docs-site/src/content/docs/reference/cli.md
  • docs-site/src/content/docs/reference/configuration.md
  • gui/src/i18n/de.ts
  • gui/src/i18n/en.ts
  • gui/src/i18n/fr.ts
  • gui/src/i18n/ja.ts
  • gui/src/i18n/ko.ts
  • gui/src/i18n/ru.ts
  • gui/src/i18n/tr.ts
  • gui/src/i18n/zh-TW.ts
  • gui/src/i18n/zh.ts
  • gui/src/icons.tsx
  • gui/src/pages/Models.tsx
  • src/cli/alias.ts
  • src/cli/dispatch.ts
  • src/cli/registry.ts
  • src/combos/types.ts
  • src/config.ts
  • src/providers/default-aliases.ts
  • src/router.ts
  • src/server/auth-cors.ts
  • src/server/chat-completions.ts
  • src/server/index.ts
  • src/server/management/model-routes.ts
  • src/server/request-log.ts
  • src/server/responses/core.ts
  • src/types/config.ts
  • src/types/provider.ts
  • src/usage/log.ts
  • tests/alias-management-api.test.ts
  • tests/codex-convergence-contract.test.ts
  • tests/provider-model-aliases.test.ts

📝 Walkthrough

Walkthrough

This change adds provider and model aliases across configuration, routing, management APIs, CLI commands, model discovery, request logging, GUI controls, localization, tests, and reference documentation.

Changes

Alias contracts and effective resolution

Layer / File(s) Summary
Alias contracts and effective resolution
src/types/config.ts, src/types/provider.ts, src/config.ts, src/providers/default-aliases.ts, src/combos/types.ts, docs-site/src/content/docs/reference/configuration.md
Configuration supports provider aliases, model aliases, provider-level default-alias overrides, and global built-in aliases. Load-time sanitization removes invalid or colliding values. Built-in aliases are generated and resolved case-insensitively. Combo aliases reject collisions with provider and model aliases.

Alias routing and request metadata

Layer / File(s) Summary
Alias routing and request metadata
src/router.ts, src/server/index.ts, src/server/chat-completions.ts, src/server/responses/core.ts, src/server/request-log.ts, src/usage/log.ts, src/server/auth-cors.ts, tests/provider-model-aliases.test.ts
Routing resolves qualified and unqualified aliases, preserves slash-qualified native models, reports ambiguity, and exposes effective aliases during model discovery. Request logs retain the originally requested alias. Tests cover precedence, fallback, ambiguity, native-model protection, and built-in alias eligibility.

Management APIs and CLI

Layer / File(s) Summary
Management APIs and CLI
src/server/management/model-routes.ts, src/cli/alias.ts, src/cli/dispatch.ts, src/cli/registry.ts, tests/alias-management-api.test.ts, tests/codex-convergence-contract.test.ts, docs-site/src/content/docs/reference/cli.md
Management routes list, validate, persist, and remove aliases, and toggle default-alias policies. The ocx alias command supports list, set, remove, defaults, and JSON output. Tests cover persistence, conflicts, and catalog convergence.

GUI alias controls and localization

Layer / File(s) Summary
GUI alias controls and localization
gui/src/pages/Models.tsx, gui/src/icons.tsx, gui/src/i18n/*.ts
The Models page displays provider and model aliases, source and stale status, editable controls, and global or provider default-alias settings. A pencil icon and alias-management localization keys were added across supported catalogs.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Router
  participant AliasResolver
  participant Provider
  Client->>Router: request with provider/model alias
  Router->>AliasResolver: resolveModelAlias(requested)
  AliasResolver->>Provider: inspect effective aliases and known model IDs
  Provider-->>AliasResolver: native model ID
  AliasResolver-->>Router: resolved model
  Router-->>Client: routed completion
Loading

Suggested reviewers: ingwannu, wibias, luvs01

✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/2463-aliases-merged

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • UI screenshot required.

What to do

  • Add a screenshot of the UI change to the PR description.

Automatic draft conversion failed (token cannot change draft status). Please convert this pull request to a draft manually. The required enforce-target check will keep failing until every issue above is resolved.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 42a8102204

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/router.ts
Comment on lines +675 to +677
const nativeModel = known.includes(decoded)
? decoded
: resolveModelAlias(config, prov, known, requestedModel) ?? decoded;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Canonicalize aliases before storing combo targets

When a combo target is configured as alpha/tiny and tiny is a model alias, combo validation accepts and persists the alias verbatim; this new qualified resolution then makes it work only while that alias exists. Renaming or removing the alias leaves the combo pointing at tiny, which is subsequently passed upstream as an unknown native model despite aliases being intended as rename-safe presentation metadata. Resolve model aliases to their canonical native IDs in the combo write path before persisting targets.

Useful? React with 👍 / 👎.

Comment on lines +301 to +303
const heldBy = Object.entries(next).find(([other, alias]) => other !== id && alias.toLowerCase() === lower)?.[0]
?? known.find(native => native.toLowerCase() === lower)
?? Object.entries(config.combos ?? {}).find(([, combo]) => comboPublicModelId("", combo).toLowerCase() === lower)?.[0];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject aliases that collide with encoded native model IDs

For a provider containing native vendor/model, the API accepts assigning vendor-model as an alias for another model because this check compares only exact native IDs. Both bare and qualified vendor-model are resolved by the existing slash-ID codec to vendor/model before alias lookup, so the saved alias silently selects the wrong model and is unusable. Include each known model's encodeRoutedModelId form in this collision check.

Useful? React with 👍 / 👎.

tarunravi pushed a commit to tarunravi/opencodex that referenced this pull request Sep 14, 2026
… GUI (lidge-jun#2463) (lidge-jun#2610)

* feat(aliases): add provider and model short names

* fix(logs): retain requested model aliases
agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
… GUI (lidge-jun#2463) (lidge-jun#2610)

* feat(aliases): add provider and model short names

* fix(logs): retain requested model aliases
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant