Summary
Calling deepseek/deepseek-v4-pro fails with an OpenAIError / NotFoundError, while deepseek/deepseek-v4-flash works fine. The root cause is that is_responses_api_model() incorrectly classifies any
OpenAI-compatible model whose name ends in -pro as a Responses-API-only model — preventing the Chat Completions fallback.
Root Cause
In utils/llm_providers.py, is_responses_api_model() was designed to identify native OpenAI models that require the Responses API (e.g. gpt-5.2-pro):
- Before fix
bare = name_lower.split("/")[-1] if "/" in name_lower else name_lower
return "codex" in bare or bare.endswith("-pro")
The function correctly guards against non-OPENAI provider types, but does not guard against third-party OpenAI-compatible providers (those with a custom base_url). DeepSeek is registered as openai_compatible:
true, so its models are routed through ProviderType.OPENAI — causing deepseek-v4-pro to match bare.endswith("-pro").
The call path that exposes the bug:
- call_llm_provider() sees ProviderType.OPENAI → calls should_use_responses_api() → True
- Tries POST /v1/responses against https://api.deepseek.com/v1 → 404 / not implemented
- Exception handler calls is_responses_api_model() → True (due to -pro suffix) → re-raises instead of falling back
- deepseek-v4-flash has the same steps 1–2, but step 3 returns False → falls back to Chat Completions → succeeds
Fix
is_responses_api_model() should only enforce Responses-API-only semantics for native OpenAI endpoints. Third-party providers with a custom base_url should be excluded:
- After fix — added before the bare-name check
if config.base_url is not None and "api.openai.com" not in config.base_url:
return False
This makes the guard consistent: -pro-suffixed models on custom endpoints are allowed to fall back to Chat Completions, just like any other OpenAI-compatible model.
Affected versions
Any version where deepseek-v4-pro is listed as a model and is_responses_api_model uses bare.endswith("-pro") without a base_url guard.
Files changed
- pantheon/utils/llm_providers.py — is_responses_api_model(): skip the -pro check when config.base_url is set and does not point to api.openai.com
Summary
Calling deepseek/deepseek-v4-pro fails with an OpenAIError / NotFoundError, while deepseek/deepseek-v4-flash works fine. The root cause is that is_responses_api_model() incorrectly classifies any
OpenAI-compatible model whose name ends in -pro as a Responses-API-only model — preventing the Chat Completions fallback.
Root Cause
In utils/llm_providers.py, is_responses_api_model() was designed to identify native OpenAI models that require the Responses API (e.g. gpt-5.2-pro):
bare = name_lower.split("/")[-1] if "/" in name_lower else name_lower
return "codex" in bare or bare.endswith("-pro")
The function correctly guards against non-OPENAI provider types, but does not guard against third-party OpenAI-compatible providers (those with a custom base_url). DeepSeek is registered as openai_compatible:
true, so its models are routed through ProviderType.OPENAI — causing deepseek-v4-pro to match bare.endswith("-pro").
The call path that exposes the bug:
Fix
is_responses_api_model() should only enforce Responses-API-only semantics for native OpenAI endpoints. Third-party providers with a custom base_url should be excluded:
if config.base_url is not None and "api.openai.com" not in config.base_url:
return False
This makes the guard consistent: -pro-suffixed models on custom endpoints are allowed to fall back to Chat Completions, just like any other OpenAI-compatible model.
Affected versions
Any version where deepseek-v4-pro is listed as a model and is_responses_api_model uses bare.endswith("-pro") without a base_url guard.
Files changed