#7343·bifrost

[Feature] Inbound model name normalization: case, vendor prefix, and suffix stripping

Author: YoungSxCreated Sep 19, 2026Updated Sep 22, 2026

[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 to gpt-4o
  • This aligns with the existing convention: most providers register their models in lowercase, and DefaultMatchFns already treats model comparisons as case-insensitive via strings.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-4ogpt-4o
  • Input: azure/gpt-4ogpt-4o
  • Input: zai/glm-5.2glm-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:freeglm-5.2
  • Dash-token suffixes (configurable token list): gemini-2.0-flash-fastgemini-2.0-flash when fast is a configured suffix token
  • Bracket suffixes: claude-sonnet-4.6[test]claude-sonnet-4.6