opencode-zen and opencode-go each serve both anthropic_messages
(e.g. minimax-m2.7) and chat_completions (e.g. deepseek-v4-flash)
models behind a single base_url. The api_mode resolver in
hermes_cli/runtime_provider.py honoured the persisted
model_cfg.api_mode (set by the previous default model) before checking
the opencode model registry, so /model deepseek-v4-flash from a session
whose default was minimax-m2.7 inherited 'anthropic_messages', stripped
'/v1' from base_url (the Anthropic SDK adds its own /v1/messages), and
404'd.
Promote the opencode detection branch above the configured_mode check
in both api_mode resolution paths:
- _resolve_runtime_from_pool_entry (pool-backed providers)
- _resolve_api_key_runtime (api-key providers, fallback path)
Both branches now call opencode_model_api_mode(provider, effective_model)
unconditionally for opencode-zen/go before considering any persisted
api_mode, so the mode always reflects the model the user just switched
to.
Existing tests pass (12/12 in tests/hermes_cli/test_model_switch_opencode_anthropic.py).
Fixes#16878