[Feature] Inbound model name normalization: case, vendor prefix, and suffix stripping
[Feature] Inbound model name normalization: case, vendor prefix, and suffix stripping
Prerequisites
- I have searched existing issues and discussions to avoid duplicates.
- I have read the related discussion in #7296.
Problem to solve
Bifrost already resolves provider-less model names through its model catalog, and #7296 proposes exposing provider-agnostic IDs on the read side (/v1/models). However, the write side (inbound request routing) has no normalization for cosmetic or aliased model name variations.
A client sending:
POST /v1/chat/completions
{"model": "ZAI/GLM_5_2:free"}will fail to route correctly unless the exact string ZAI/GLM_5_2:free is registered. The same applies for:
- Case variants:
Gpt-4o,gpt-4o,GPT-4O - Vendor prefix:
openai/gpt-4o,azure/gpt-4o - Marketing/suffix noise:
gemini-2.0-flash:free,glm-5.2[免费],claude-sonnet-4.6-fast
KeyAliases.ResolveConfig handles case-insensitive matching (via strings.EqualFold), but only within alias table lookups — bare model names sent outside an alias config bypass this entirely. There is no general pipeline that normalizes an inbound model name before routing.
Proposed solution
Add an optional inbound model name normalization pipeline to Bifrost core, with three priority levels:
P0 — Case normalization (highest priority)
Normalize all inbound model names to lowercase before routing. This is the single highest-impact, lowest-risk change.
- Input:
Gpt-4o,GPT-4O,gpt-4o→ all resolve togpt-4o - This aligns with the existing convention: most providers register their models in lowercase, and
DefaultMatchFnsalready treats model comparisons as case-insensitive viastrings.EqualFold.
P1 — Vendor prefix stripping
Strip the provider/ prefix from inbound model names before looking up the provider's model catalog. Since Bifrost already knows which provider the request is targeting (via key config), the prefix is redundant for routing.
- Input:
openai/gpt-4o→gpt-4o - Input:
azure/gpt-4o→gpt-4o - Input:
zai/glm-5.2→glm-5.2
The strip should target the last / prefix, so namespace-style colons (provider:model) or paths inside the model name itself are preserved.
P2 — Suffix stripping (nice to have)
Strip common marketing/capability suffixes that don't affect the base model identity:
- Colon suffixes:
glm-5.2:free→glm-5.2 - Dash-token suffixes (configurable token list):
gemini-2.0-flash-fast→gemini-2.0-flashwhenfastis a configured suffix token - Bracket suffixes:
claude-sonnet-4.6[test]→claude-sonnet-4.6
Source: maximhq/bifrost