Skip to content

fix(opencode): preserve /v1 in base_url when switching from anthropic_messages to chat_completions models - #16885

Closed
quannon wants to merge 1 commit into
NousResearch:mainfrom
quannon:fix/opencode-v1-strip
Closed

fix(opencode): preserve /v1 in base_url when switching from anthropic_messages to chat_completions models#16885
quannon wants to merge 1 commit into
NousResearch:mainfrom
quannon:fix/opencode-v1-strip

Conversation

@quannon

@quannon quannon commented Apr 28, 2026

Copy link
Copy Markdown

Summary

When using the opencode-go provider with a config default model that uses anthropic_messages mode (e.g. minimax-m2.7) and switching to a chat_completions model (e.g. deepseek-v4-flash) via the /model slash command, the base_url loses /v1, resulting in an HTTP 404 error.

Fixes: #16878

Root Cause

In runtime_provider.py, the non-pool "API-key providers" block (~lines 1213-1237), when the credential pool is exhausted:

  1. configured_mode = _parse_api_mode(model_cfg.get("api_mode")) reads "anthropic_messages" from the stale config
  2. This stale mode is applied before the opencode-go/zen api_mode detection can run
  3. The opencode block was an elif, so it never ran when configured_mode was truthy

Fix Applied

Promoted opencode-go/zen detection to an explicit if block that runs before the configured_mode override, so it always correctly detects api_mode based on the target model.

Same change applied to _resolve_runtime_from_pool_entry for consistency.

Verification

# default=minimax-m2.7 → switch to deepseek-v4-flash
resolve_runtime_provider(requested="opencode-go", target_model="deepseek-v4-flash")
# → api_mode="chat_completions", base_url="https://opencode.ai/zen/go/v1" ✓

# reverse: default=deepseek-v4-flash → switch to minimax-m2.7
resolve_runtime_provider(requested="opencode-go", target_model="minimax-m2.7")
# → api_mode="anthropic_messages", base_url="https://opencode.ai/zen/go" ✓

Tests

12/12 passing: python -m pytest tests/hermes_cli/test_model_switch_opencode_anthropic.py -v

…_messages to chat_completions models

In runtime_provider.py, the non-pool API-key providers block was applying
stale configured_mode (e.g. anthropic_messages from a minimax default)
before the opencode-go/zen api_mode detection could run, causing /v1
to be stripped when switching to deepseek-v4-flash (which needs
chat_completions).

Fix by promoting opencode-go/zen detection to run unconditionally for
opencode providers, bypassing the configured_mode override. Same change
applied to _resolve_runtime_from_pool_entry for consistency.

Fixes: NousResearch#16878
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard labels Apr 28, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the fix, @quannon! The bug you identified is real and your analysis of the root cause is exactly right.

Unfortunately, an independent fix for the same issue landed on main about 7 hours before this PR was opened — likely authored in parallel:

  • Commit: b52ceccfafix(opencode): re-derive api_mode per target model on /model switch
  • Shipped in: v2026.4.30
  • File: hermes_cli/runtime_provider.py — both _resolve_runtime_from_pool_entry (line 263) and the api-key-providers path (line 1295) were updated with the same structural change you proposed: promoting the opencode-zen/go detection to an explicit if block above the configured_mode override.

The fix also explicitly cites #16878. Since the same change is already live in the latest release, this PR is superseded.

This review was performed by the automated hermes-sweeper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: /v1 stripped from base_url when switching models via /model with opencode-go provider

3 participants