fix: cross-provider model pick causes Connection lost on non-OpenRouter profiles
Root cause: resolve_model_provider() had a branch:
if config_provider and config_provider != 'openrouter' and prefix in _PROVIDER_MODELS:
return bare, prefix, None
When Camanji profile (config_provider='anthropic') picked openai/gpt-5.4-mini
from the OpenRouter dropdown, prefix='openai' matched _PROVIDER_MODELS and
config_provider was not 'openrouter', so it returned ('gpt-5.4-mini', 'openai', None).
The agent then demanded OPENAI_API_KEY directly -- not found -- RuntimeError --
stream crashed -- 'Connection lost'.
Fix: if prefix != config_provider (cross-provider selection), always route through
openrouter with the full provider/model string. Only strip the prefix and call a
direct provider API when the config_provider EXACTLY matches the model prefix.
Cases verified:
openrouter + openai/gpt-5.4-mini -> (openai/gpt-5.4-mini, openrouter) ✓
anthropic + openai/gpt-5.4-mini -> (openai/gpt-5.4-mini, openrouter) ✓ FIXED
anthropic + anthropic/claude-... -> (claude-..., anthropic) ✓
anthropic + claude-sonnet-4-6 bare -> (claude-sonnet-4-6, anthropic) ✓
openrouter + anthropic/claude-... -> (anthropic/claude-..., openrouter) ✓
Tests: 426 passed, 0 failed.
This commit is contained in:
@@ -373,15 +373,16 @@ def resolve_model_provider(model_id: str):
|
||||
|
||||
if '/' in model_id:
|
||||
prefix, bare = model_id.split('/', 1)
|
||||
# If prefix matches config provider, strip it and use that provider directly
|
||||
# If prefix matches config provider exactly, strip it and use that provider directly.
|
||||
# e.g. config=anthropic, model=anthropic/claude-... → bare name to anthropic API
|
||||
if config_provider and prefix == config_provider:
|
||||
return bare, config_provider, config_base_url
|
||||
# If the config provider is openrouter (or unset/None), pass the full
|
||||
# provider/model string through -- OpenRouter uses this as its model ID.
|
||||
# Only strip the prefix and switch to a direct-API provider when the
|
||||
# config is explicitly set to that direct provider.
|
||||
if config_provider and config_provider != 'openrouter' and prefix in _PROVIDER_MODELS:
|
||||
return bare, prefix, None
|
||||
# If prefix does NOT match config provider, the user picked a cross-provider model
|
||||
# from the OpenRouter dropdown (e.g. config=anthropic but picked openai/gpt-5.4-mini).
|
||||
# In this case always route through openrouter with the full provider/model string.
|
||||
# Never strip the prefix and try a direct-API call to a provider whose key may not exist.
|
||||
if prefix in _PROVIDER_MODELS and prefix != config_provider:
|
||||
return model_id, 'openrouter', None
|
||||
|
||||
return model_id, config_provider, config_base_url
|
||||
|
||||
|
||||
Reference in New Issue
Block a user