Skip to content

fix(model): only strip /v1 from OpenCode URLs on fresh provider resolution - #14919

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

fix(model): only strip /v1 from OpenCode URLs on fresh provider resolution#14919
aniruddhaadak80 wants to merge 1 commit into
NousResearch:mainfrom
aniruddhaadak80:fix/model-switch-opencode-v1-strip

Conversation

@aniruddhaadak80

Copy link
Copy Markdown
Contributor

Summary

Fixes #14879

The /model command unconditionally strips /v1 from OpenCode base URLs when api_mode == "anthropic_messages", but this breaks models that need /v1 in the URL when the user switches models on the same provider (where the URL was already correct from a prior resolution).

Root Cause

In switch_model(), the /v1 stripping regex runs whenever:

  1. api_mode == "anthropic_messages"
  2. Provider is opencode-zen or opencode-go

But it didn't check whether the URL was freshly resolved or was carried over from the current session. When a user on opencode-go switches from one model to another (same provider), the base_url is already in the correct form and stripping /v1 corrupts it.

Changes

hermes_cli/model_switch.pyswitch_model():

  • Added (provider_changed or explicit_provider) to the /v1 strip condition
  • /v1 is now only stripped when the URL was freshly resolved via resolve_runtime_provider() (i.e., the provider changed or was explicitly specified)
  • When switching models on the same provider, the base_url is left as-is
  • Updated the comment block to document this behavior

Testing

  • Provider switch (e.g., openrouteropencode-go): provider_changed=True/v1 stripped as before
  • Same-provider model switch (e.g., model A → model B on opencode-go): provider_changed=False, explicit_provider=""/v1 preserved (bug fixed)
  • Explicit provider (e.g., /model sonnet --provider opencode-go): explicit_provider="opencode-go"/v1 stripped correctly
  • Non-OpenCode providers: condition short-circuits at target_provider check → no change

Checklist

  • Follows Conventional Commits format
  • Single logical change
  • No breaking changes
  • Existing tests unaffected

…ution

The /v1 suffix stripping for OpenCode anthropic_messages endpoints
was applied unconditionally, including when switching models on the
same provider where the base_url was already correct from a prior
resolution. This caused models that legitimately need /v1 in the
URL to break when switching between them.

Add a guard so /v1 is only stripped when the URL was freshly
resolved (provider_changed or explicit_provider). When the user
stays on the same provider and just switches models, the base_url
is already in the correct form and must not be modified.

Closes NousResearch#14879
Copilot AI review requested due to automatic review settings April 24, 2026 04:57
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard labels Apr 24, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the investigation @aniruddhaadak80 — but I have to close this without merging.

Current main already handles this scenario correctly (fixed by PR #4508 on April 2, 22 days before #14879 was filed). E2E-verified with the exact repro from the issue:

current_provider=minimax, current_model=MiniMax-M2.7
raw_input='opencode-go glm-5.1'
→ result: base_url='https://opencode.ai/zen/go/v1', api_mode='chat_completions'  ✓

The /v1 is preserved because opencode_model_api_mode('opencode-go', 'glm-5') correctly returns chat_completions (not anthropic_messages), so the strip condition at model_switch.py:862 short-circuits.

The proposed change regresses 4 existing tests in tests/hermes_cli/test_model_switch_opencode_anthropic.py:

  • test_switch_to_minimax_m27_strips_v1
  • test_switch_to_minimax_m25_strips_v1
  • test_trailing_slash_also_stripped
  • test_switch_to_claude_sonnet_strips_v1

These guard the same-provider anthropic_messages switch case (e.g. opencode-go model-A → model-B where B is MiniMax). Gating the strip on provider_changed or explicit_provider skips the strip in exactly the case the tests assert it's required, causing the double-/v1/messages bug to return.

The underlying issue #14879 will be closed too — the user was on a version predating PR #4508.

Appreciate the detailed PR body with the three-case analysis — just happened to land against a scenario already covered.

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

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] /model command strips /v1 from OpenCode Go endpoint when switching from MiniMax provider

4 participants