Skip to content

fix(hermes): refresh model.base_url on provider switch#2760

Open
lihan3238 wants to merge 1 commit into
farion1231:mainfrom
lihan3238:fix-2757-hermes-base-url
Open

fix(hermes): refresh model.base_url on provider switch#2760
lihan3238 wants to merge 1 commit into
farion1231:mainfrom
lihan3238:fix-2757-hermes-base-url

Conversation

@lihan3238
Copy link
Copy Markdown

Summary

Fixes #2757. apply_switch_defaults in src-tauri/src/hermes_config.rs used ..current struct-update to preserve user customizations (context_length, max_tokens, extra). But this also silently preserved base_url across provider switches — so when the user switched from DeepSeek to Kimi For Coding, the model.base_url field in ~/.hermes/config.yaml kept pointing at DeepSeek. Auxiliary services (title generation, session search) then 404'd against the wrong endpoint.

The issue reporter (@KaisvenZ) provided a complete root-cause analysis including DB-vs-yaml diff evidence and pseudocode for the fix.

Change

src-tauri/src/hermes_config.rs apply_switch_defaults:

+    let new_base_url = settings_config
+        .get("base_url")
+        .and_then(|v| v.as_str())
+        .map(|s| s.trim().to_string())
+        .filter(|s| !s.is_empty());
+
     let current = get_model_config()?.unwrap_or_default();
     let merged = HermesModelConfig {
         default: first_model_id.or(current.default.clone()),
         provider: Some(provider_id.to_string()),
+        base_url: new_base_url.or(current.base_url.clone()),
         ..current
     };

Use the new provider's settings_config.base_url when set, falling back to the existing value when the new provider's settings omits base_url (so a user override survives a switch to a provider that does not declare its own).

Docstring updated to spell out the new precedence.

Tests

Added two regression tests:

The four pre-existing apply_switch_defaults tests continue to pass unchanged. None of them asserted base_url with a non-empty settings.base_url value — they covered:

  • (sets_default_and_provider) settings had base_url but didn't assert on it → still passes; new behavior just makes the assertion possible
  • (preserves_user_context_length) settings lacked base_url, asserts user override is preserved → still works (falls back to current via .or())
  • (updates_provider_even_without_models) settings had base_url but didn't assert on it → still passes
  • (keeps_old_default_when_first_model_id_is_blank) settings lacked base_url → still works

Behavior change note

This change refreshes model.base_url whenever the new provider declares one, which is a user-visible behavior change. The previous code would have kept a manually-edited model.base_url even across a provider switch. Two views are reasonable:

  • Issue reporter's view (this PR): provider switching is a "use this provider's settings" gesture; provider-specific fields including base_url should refresh.
  • Alternative view: user-set overrides should always win, even across provider switches.

Happy to defer if you prefer the alternative — the simplest revert is to drop the base_url: line in the struct literal and remove the new test. I went with the issue-reporter's view because the breakage they describe (404s on auxiliary services) is consistent and affects real users, and because the previous "always preserve" behavior was implicit in the ..current rather than explicitly designed.

Verification

  • cargo fmt --check passes locally
  • Could not run cargo test locally (Tauri build needs pkg-config + libssl-dev system packages I don't have sudo for); diff is small and identical in shape to surrounding tested code, relying on the backend CI job to verify.

apply_switch_defaults uses struct-update (..current) to preserve user
customizations (context_length / max_tokens / extra), but this also
silently preserved base_url across provider switches. Auxiliary services
(title generation, session search) then hit the previous provider and
returned HTTP 404.

Use the new providers settings_config.base_url when set, falling back to
the existing value when the new providers settings omit base_url (so a
user override survives a switch to a provider that does not declare one).

Add two regression tests:
- updates_base_url_to_new_provider: covers the issue farion1231#2757 reproduction
- ignores_blank_base_url_in_settings: guards the user-override fallback

The four pre-existing apply_switch_defaults tests continue to pass
unchanged (none of them asserted base_url with a non-empty
settings.base_url, so the new behavior does not regress them).

Closes farion1231#2757
@farion1231
Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Hermes model.base_url not updated when switching providers (HTTP 404 on auxiliary services)

2 participants