fix: provider selection not persisting when switching via hermes model#881
Merged
Conversation
Two related bugs prevented users from reliably switching providers: 1. OPENAI_BASE_URL poisoning OpenRouter resolution: When a user with a custom endpoint ran /model openrouter:model, _resolve_openrouter_runtime picked up OPENAI_BASE_URL instead of the OpenRouter URL, causing model validation to probe the wrong API and reject valid models. Fix: skip OPENAI_BASE_URL when requested_provider is explicitly 'openrouter'. 2. Provider never saved to config: _save_model_choice() could save config.model as a plain string. All five _model_flow_* functions then checked isinstance(model, dict) before writing the provider — which silently failed on strings. With no provider in config, auto-detection would pick up stale credentials (e.g. Codex desktop app) instead of the user's explicit choice. Fix: _save_model_choice() now always saves as dict format. All flow functions also normalize string->dict as a safety net before writing provider. Adds 4 regression tests. 2873 tests pass.
1 task
angelburgosrosado
pushed a commit
to angelburgosrosado/hermes-agent
that referenced
this pull request
Apr 27, 2026
…0162f8d fix: provider selection not persisting when switching via hermes model
02356abc
pushed a commit
to 02356abc/hermes-agent
that referenced
this pull request
May 14, 2026
…0162f8d fix: provider selection not persisting when switching via hermes model
olympus-terminal
pushed a commit
to olympus-terminal/hermes-agent
that referenced
this pull request
May 16, 2026
…0162f8d fix: provider selection not persisting when switching via hermes model
Egavasyug
pushed a commit
to Egavasyug/hermes-agent
that referenced
this pull request
Jun 10, 2026
…0162f8d fix: provider selection not persisting when switching via hermes model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two related bugs prevented users from reliably switching providers via
hermes modeland/model:Bug 1: OPENAI_BASE_URL poisons OpenRouter resolution
When a user has a custom endpoint (
OPENAI_BASE_URLset) and tries/model openrouter:anthropic/claude-opus-4.6, the runtime provider resolution picks upOPENAI_BASE_URLinstead of the OpenRouter URL. Model validation probes the wrong API and rejects valid models.Fix: Skip
OPENAI_BASE_URLin the URL resolution chain when the user explicitly requestsopenrouter.Bug 2: Provider never saved to config after model selection
_save_model_choice()could saveconfig.modelas a plain string (not a dict). All five_model_flow_*functions then checkedisinstance(model, dict)before writing the provider — which silently failed on strings. With no provider in config,resolve_requested_provider()fell through to"auto"detection, which would pick up stale credentials (e.g. Codex desktop app tokens) instead of the user's explicit choice.Fix:
_save_model_choice()now always saves in dict format:{"default": model_id}Files Changed
hermes_cli/runtime_provider.py— skip OPENAI_BASE_URL for explicit openrouterhermes_cli/auth.py— _save_model_choice always uses dict formathermes_cli/main.py— 5 flow functions hardenedtests/test_runtime_provider_resolution.py— 1 regression testtests/test_model_provider_persistence.py— 3 regression testsTest Plan
hermes modelnow correctly persistsprovider: kimi-codingto config even whenconfig.modelstarted as a plain string/model openrouter:modelworks correctly whenOPENAI_BASE_URLis set to a custom endpoint