Skip to content

/v1/chat/completions does NOT restore gateway alias on response.model (inconsistent with /v1/messages two-step rewrite) #334

Description

@moonming

Behavior inconsistency between two surfaces

Endpoint Customer-visible response.model
/v1/chat/completions upstream id (verbatim from upstream echo)
/v1/messages gateway-facing alias (DP rewrites upstream id → alias on the way out)

Confirmed by audit + existing pinned tests

/v1/messages performs a two-step model rewrite (alias→upstream on request, upstream→alias on response) at crates/aisix-proxy/src/messages.rs:142-249, 335-339. This is pinned by dashboard/tests/e2e/dp-messages-anthropic-roundtrip-live.spec.ts:193 which asserts body.model === modelName (the dashboard alias).

/v1/chat/completions does NOT perform the inbound rewrite:

  • crates/aisix-proxy/src/chat.rs:985 calls render_response(now, upstream).
  • crates/aisix-proxy/src/render.rs:81-103 constructs ChatCompletion { model: resp.model, ... } from the bridge's parsed upstream response.
  • crates/aisix-provider-openai/src/wire.rs:186-223 response_into_chat_response sets ChatResponse.model = raw.model.
  • This is pinned by dashboard/tests/e2e/dp-completions-live.spec.ts which explicitly asserts body.model === 'gpt-3.5-turbo-instruct' (the upstream id) with the comment "Model rewrite: response carries the upstream id, not the proxy-side display name."

Why this matters

Customer SDKs that branch on the model field (e.g. caching layers, billing reconciliation, dashboard analytics that match alias) get the upstream id on /v1/chat/completions but the alias on /v1/messages. A customer using both endpoints sees two different model names for the same Model resource. LiteLLM and Portkey both restore the alias on both endpoints (verified against LiteLLM docs and runtime behavior).

Question for triage

Pick a direction:

(a) Restore alias on both endpoints (the LiteLLM/Portkey convention). Pro: consistent customer experience, alias is what the dashboard displays. Con: dp-completions-live test needs updating to assert alias instead of upstream id, which is a behavior change for any external consumer that depends on the current shape.

(b) Drop alias restoration from /v1/messages to match /v1/chat/completions. Pro: simpler code (no two-step rewrite). Con: customer doesn't see the alias they configured — leaks upstream id, surprises Anthropic SDK users who pinned alias.

(c) Document the inconsistency as intentional and add UI/SDK notes. Pro: zero code change. Con: confusing, hard to justify product-wise.

My read: (a) is the right answer for a managed-gateway product but is a breaking-change for body.model consumers, so should be gated/documented or coordinated with major version.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions