hermes - ✅(Solved) Fix [Bug]: CLI --global model switch does not persist/clear model.base_url and model.api_mode [3 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#25106Fetched 2026-05-14 03:48:55
View on GitHub
Comments
0
Participants
1
Timeline
8
Reactions
0
Author
Participants
Timeline (top)
labeled ×5cross-referenced ×3

Root Cause

The CLI global-save path does not persist the complete model runtime tuple returned by the model switch resolver.

Fix Action

Fixed

PR fix notes

PR #25131: fix(agent): persist complete model runtime state on /model switch

Description (problem / solution / changelog)

Summary

Both gateway /model and CLI /model --global now persist the complete runtime tuple to config.yaml:

model.default
model.provider
model.base_url      # NEW: was missing or conditionally written
model.api_mode      # NEW: was never persisted

Before

Gateway /model (gateway/run.py):

model_cfg["default"] = result.new_model
model_cfg["provider"] = result.target_provider
if result.base_url:                    # ← only writes when truthy
    model_cfg["base_url"] = result.base_url
# api_mode: never persisted

CLI /model --global (cli.py, 2 locations):

save_config_value("model.default", result.new_model)
if result.provider_changed:
    save_config_value("model.provider", result.target_provider)
# base_url: never persisted
# api_mode: never persisted

After

Gateway — unconditional with empty-string clearing:

model_cfg["base_url"] = result.base_url or ""
model_cfg["api_mode"] = result.api_mode or ""

CLI — two additional save_config_value calls:

save_config_value("model.base_url", result.base_url or "")
save_config_value("model.api_mode", result.api_mode or "")

Impact

Fixes the class of bugs where switching models leaves stale endpoint/protocol state:

ScenarioBeforeAfter
Switch from custom → built-in providerOld base_url survivesCleared to ""
Switch from anthropic_messages → openaiOld api_mode survivesCleared to ""
Switch to a provider with explicit base_urlNot persisted (CLI)Persisted correctly
Restart gateway after /model switchMay use stale endpointUses correct state

Testing

  • 5 new tests covering all persistence paths
  • 29 existing model-switch tests passing (0 regressions)

Files changed

FileChange
gateway/run.pyPersist base_url + api_mode unconditionally
cli.pyAdd save_config_value for base_url + api_mode (2 locations)
tests/gateway/test_model_switch_config_persistence.pyNew: 5 tests

Closes #25107 Closes #25106 See also #25105 (kimi-for-coding alias normalization — separate issue)

Changed files

  • cli.py (modified, +6/-0)
  • gateway/run.py (modified, +3/-2)
  • tests/gateway/test_model_switch_config_persistence.py (added, +209/-0)

PR #25137: fix: persist CLI model runtime state

Description (problem / solution / changelog)

Bug

CLI /model --global only persisted model.default and sometimes model.provider. It did not persist the resolved model.base_url/model.api_mode, and it did not clear stale runtime fields after switching away from custom/Anthropic-compatible providers.

Fixes #25106

Summary

Persist the complete CLI model runtime state via a config read-modify-write: default, provider, base_url, and api_mode. Empty base_url/api_mode now remove stale values. The success message is only printed after save_config succeeds.

TDD / ATDD coverage

  • Added a focused regression test that reproduces the reported behavior.
  • Implemented the minimal production change needed to satisfy the regression.
  • Re-ran the targeted test file to guard nearby behavior.

Test plan

  • /Users/mudrii/src/hermes/hermes-agent/venv/bin/python -m pytest tests/hermes_cli/test_apply_model_switch_result_context.py -q -o 'addopts=' -> 6 passed

Review notes

  • Kept the change scoped to the issue-specific runtime path.
  • No secrets are persisted or logged.

Changed files

  • cli.py (modified, +52/-10)
  • tests/hermes_cli/test_apply_model_switch_result_context.py (modified, +183/-0)

PR #25138: fix: persist gateway model runtime state

Description (problem / solution / changelog)

Bug

Gateway /model --global persisted model.default/provider and sometimes base_url, but omitted api_mode and left stale base_url/api_mode values in config.yaml when switching providers.

Fixes #25107

Summary

Update gateway /model --global persistence to write default/provider/base_url/api_mode and remove stale base_url/api_mode when the resolved switch has empty runtime fields. This keeps gateway config aligned with the actual session override.

TDD / ATDD coverage

  • Added a focused regression test that reproduces the reported behavior.
  • Implemented the minimal production change needed to satisfy the regression.
  • Re-ran the targeted test file to guard nearby behavior.

Test plan

  • /Users/mudrii/src/hermes/hermes-agent/venv/bin/python -m pytest tests/gateway/test_model_command_persistence.py tests/gateway/test_session_model_reset.py -q -o 'addopts=' -> 5 passed

Review notes

  • Kept the change scoped to the issue-specific runtime path.
  • No secrets are persisted or logged.

Changed files

  • gateway/run.py (modified, +9/-0)
  • tests/gateway/test_model_command_persistence.py (added, +122/-0)

Code Example

save_config_value("model.default", result.new_model)
if result.provider_changed:
    save_config_value("model.provider", result.target_provider)

---

model.base_url
model.api_mode

---

model.default
model.provider
model.base_url
model.api_mode

---

save_config_value("model.base_url", result.base_url or "")
save_config_value("model.api_mode", result.api_mode or "")
RAW_BUFFERClick to expand / collapse

Bug Description

The CLI global model switch path persists only part of the resolved runtime state.

Current behavior in the affected CLI save paths is effectively:

save_config_value("model.default", result.new_model)
if result.provider_changed:
    save_config_value("model.provider", result.target_provider)

but it does not persist or clear:

model.base_url
model.api_mode

This allows stale endpoint/protocol state from the previous provider to survive in config.yaml after a global model switch.

Expected Behavior

A global model switch should persist the complete resolved runtime tuple, or explicitly clear empty/stale values:

model.default
model.provider
model.base_url
model.api_mode

If the new provider does not need an explicit base_url or api_mode, Hermes should save an empty value or remove the stale one instead of leaving the previous provider's value in place.

Actual Behavior

model.base_url and model.api_mode can remain from the previous provider. A later session may then route the new model using the old provider's endpoint/protocol.

Examples of possible corruption:

  • stale model.base_url: https://api.kimi.com/coding/v1 survives after switching away from Kimi
  • stale model.api_mode: anthropic_messages or codex_responses survives when the new provider expects chat_completions
  • stale custom endpoint remains after switching to a native provider

Reproduction

  1. Configure Hermes for a provider that sets explicit model.base_url and/or non-default model.api_mode.
  2. Switch globally to another provider/model via CLI global model-switch flow.
  3. Inspect ~/.hermes/config.yaml.
  4. Observe model.default / model.provider are updated but old model.base_url / model.api_mode may remain.
  5. Start a new session and observe runtime resolution can use stale endpoint/protocol state.

Root Cause

The CLI global-save path does not persist the complete model runtime tuple returned by the model switch resolver.

Suggested Fix

After a successful global switch, also save:

save_config_value("model.base_url", result.base_url or "")
save_config_value("model.api_mode", result.api_mode or "")

at every global CLI save site that persists model.default / model.provider.

Related Existing Reports / PRs

This is related to, but not fully covered by:

  • #3685: stale api_mode after provider switch
  • #3726: partial fix for one model-selection path
  • #2078: historical stale endpoint fix
  • #6551: asks to persist full model triples on global switch

This report tracks the remaining current-main CLI global-save path explicitly.

Environment

  • Hermes Agent current main around commit 4fdfdf674
  • Config file: ~/.hermes/config.yaml
  • Surface: CLI global model switch

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix [Bug]: CLI --global model switch does not persist/clear model.base_url and model.api_mode [3 pull requests, 1 participants]