Skip to content

Commit 0530c50

Browse files
committed
fix(api): route openai/ and gpt- model prefixes to OpenAi provider
metadata_for_model returned None for unknown models like openai/gpt-4.1-mini, causing detect_provider_kind to fall through to auth-sniffer order. If ANTHROPIC_API_KEY was set, the model was silently misrouted to Anthropic and the user got a confusing 'missing Anthropic credentials' error. Fix: add explicit prefix checks for 'openai/' and 'gpt-' in metadata_for_model so the model name wins over env-var presence. Regression test added: openai_namespaced_model_routes_to_openai_not_anthropic - 'openai/gpt-4.1-mini' routes to OpenAi - 'gpt-4o' routes to OpenAi Reported and reproduced by gaebal-gajae against current main. 81 api lib tests passing, 0 failing.
1 parent eff0765 commit 0530c50

1 file changed

Lines changed: 34 additions & 0 deletions

File tree

  • rust/crates/api/src/providers

rust/crates/api/src/providers/mod.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,18 @@ pub fn metadata_for_model(model: &str) -> Option<ProviderMetadata> {
169169
default_base_url: openai_compat::DEFAULT_XAI_BASE_URL,
170170
});
171171
}
172+
// Explicit provider-namespaced models (e.g. "openai/gpt-4.1-mini") must
173+
// route to the correct provider regardless of which auth env vars are set.
174+
// Without this, detect_provider_kind falls through to the auth-sniffer
175+
// order and misroutes to Anthropic if ANTHROPIC_API_KEY is present.
176+
if canonical.starts_with("openai/") || canonical.starts_with("gpt-") {
177+
return Some(ProviderMetadata {
178+
provider: ProviderKind::OpenAi,
179+
auth_env: "OPENAI_API_KEY",
180+
base_url_env: "OPENAI_BASE_URL",
181+
default_base_url: openai_compat::DEFAULT_OPENAI_BASE_URL,
182+
});
183+
}
172184
None
173185
}
174186

@@ -352,6 +364,28 @@ mod tests {
352364
);
353365
}
354366

367+
#[test]
368+
fn openai_namespaced_model_routes_to_openai_not_anthropic() {
369+
// Regression: "openai/gpt-4.1-mini" was misrouted to Anthropic when
370+
// ANTHROPIC_API_KEY was set because metadata_for_model returned None
371+
// and detect_provider_kind fell through to auth-sniffer order.
372+
// The model prefix must win over env-var presence.
373+
let kind = super::metadata_for_model("openai/gpt-4.1-mini")
374+
.map(|m| m.provider)
375+
.unwrap_or_else(|| detect_provider_kind("openai/gpt-4.1-mini"));
376+
assert_eq!(
377+
kind,
378+
ProviderKind::OpenAi,
379+
"openai/ prefix must route to OpenAi regardless of ANTHROPIC_API_KEY"
380+
);
381+
382+
// Also cover bare gpt- prefix
383+
let kind2 = super::metadata_for_model("gpt-4o")
384+
.map(|m| m.provider)
385+
.unwrap_or_else(|| detect_provider_kind("gpt-4o"));
386+
assert_eq!(kind2, ProviderKind::OpenAi);
387+
}
388+
355389
#[test]
356390
fn keeps_existing_max_token_heuristic() {
357391
assert_eq!(max_tokens_for_model("opus"), 32_000);

0 commit comments

Comments
 (0)