router-for-me / router-for-me/CLIProxyAPI

Feature: support wildcard patterns in oauth-model-alias (matching is exact-only)

Open
#5,366 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
52.5k
Forks
7.9k
Avg merge
1d 3h
Merged PRs (30d)
60

Description

Problem

oauth-model-alias resolves the client-visible model name with case-insensitive exact comparison only:

  • sdk/cliproxy/auth/oauth_model_alias.goresolveUpstreamModelFromAliases() compares with strings.EqualFold(alias, key)
  • sdk/cliproxy/auth/oauth_model_alias.goresolveUpstreamModelFromAliasTable() looks the alias up in a precompiled map[string]… keyed by the lowercased alias

modelAliasLookupCandidates() only strips a supported thinking/effort suffix, so the candidate set is [requestedModel, baseModel] — nothing else is normalized.

The repository already contains two wildcard matchers, but neither is reachable from alias resolution:

matcher location only consumer
matchWildcard sdk/cliproxy/service_models.go applyExcludedModels (oauth-excluded-models)
matchModelPattern internal/runtime/executor/helps/payload_helpers.go payload rules

So alias: "claude-haiku-4-5-*" is stored and compared as a literal model id and never matches anything.

Why it matters

Any client that sends dated model ids forces a config edit every time the upstream id changes. The concrete case is Claude Code: it sends its native model ids on every path, including a dated id for its background/side queries (e.g. claude-haiku-4-5-20251001).

There are two failure shapes, and the second one is the reason I am filing this:

  1. Loud — no alias for the id, so the request fails outright (unknown provider for model claude-haiku-4-5-20251001, HTTP 502). This is what #1596 reported.
  2. Silent — recent Claude Code versions do not surface an error when the small/background model is unroutable; they fall back to the main model instead. Nothing in the logs looks wrong, the session behaves normally, and every background side query is quietly answered by the main model. A single date-suffix bump on the upstream id is enough to trigger it, and there is no signal until someone inspects per-model request counts.

An exact alias cannot survive a suffix bump. A wildcard (claude-haiku-4-5-*) can.

Prior art

#1596 (opened 2026-02-15, closed 2026-02-17) is the same underlying need on the Antigravity channel. A commenter there proposed exactly this feature:

oauth-model-alias:
  antigravity:
    - name: "claude-sonnet-4-5"
      alias: "claude-haiku-*"

and noted that payload config already supports wildcards on model names. That proposal received no maintainer response, has no linked PR, and was closed together with the original routing report two days later — so the request was never tracked on its own. Filing it standalone here.

Note that payload rules are not a workaround: they wildcard-match the model name but can only set parameters. On the Codex path the executor overwrites model with the routed baseModel immediately after applying payload config, and routing/credential selection happens before the executor runs at all — an unaliased model never gets that far.

Proposal

Let Alias contain * (matching zero or more characters), with the same semantics as the existing matchers and the case-insensitivity the alias path already uses:

oauth-model-alias:
  codex:
    - name: "gpt-5.6-luna"
      alias: "claude-haiku-4-5-*"

Behaviour:

  • Exact aliases always win. Wildcards are consulted only after the existing exact pass finds nothing, so no existing configuration changes behaviour.
  • Among wildcards, the first match in configuration order wins.
  • Wildcard aliases are routing-only and are not published in /v1/models, because a pattern is not a model id. The upstream model keeps its own catalog entry, so fork is not meaningful on a wildcard entry.
  • Scope: oauth-model-alias and the per-auth model_aliases attribute. Provider models: alias lists are left unchanged.

I have a patch ready and will open a PR referencing this issue.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in sdk/cliproxy/auth/oauth_model_alias.go at resolveUpstreamModelFromAliases() and resolveUpstreamModelFromAliasTable(), then read matchWildcard in sdk/cliproxy/service_models.go and matchModelPattern in internal/runtime/executor/helps/payload_helpers.go. Done means exact aliases still take precedence, wildcard order is preserved, dated ids resolve through both alias scopes, and wildcard entries are excluded from model publication.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, authentication, backend
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.