mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-06 07:51:53 +00:00
fix(model): match custom provider by active base url
This commit is contained in:
parent
60bb98e003
commit
d9829ab45f
2 changed files with 220 additions and 54 deletions
|
|
@ -327,6 +327,118 @@ class TestCustomProviderModelSwitch:
|
|||
assert config["custom_providers"][0]["api_key"] == "${NEURALWATT_API_KEY}"
|
||||
assert "sk-live-neuralwatt-secret" not in saved
|
||||
|
||||
def test_bare_custom_current_provider_matches_env_base_url_before_first_fallback(
|
||||
self, config_home, monkeypatch
|
||||
):
|
||||
"""`hermes model` must mark the custom provider matching model.base_url
|
||||
as current instead of falling back to the first saved custom provider.
|
||||
|
||||
Regression: with ``model.provider: custom`` and multiple
|
||||
``custom_providers`` entries, the CLI resolved bare ``custom`` through
|
||||
``resolve_custom_provider()``, whose compatibility fallback returns the
|
||||
first entry. A config with Cerebras first and NeuralWatt active then
|
||||
showed Cerebras as current.
|
||||
"""
|
||||
from hermes_cli.main import select_provider_and_model
|
||||
|
||||
config_path = config_home / "config.yaml"
|
||||
config_path.write_text(
|
||||
"model:\n"
|
||||
" default: kimi-k2.6-fast\n"
|
||||
" provider: custom\n"
|
||||
" base_url: ${NEURALWATT_API_BASE}\n"
|
||||
" api_key: ${NEURALWATT_API_KEY}\n"
|
||||
"providers: {}\n"
|
||||
"custom_providers:\n"
|
||||
"- name: Cerebras.ai\n"
|
||||
" base_url: ${CEREBRAS_API_BASE}\n"
|
||||
" api_key: ${CEREBRAS_API_KEY}\n"
|
||||
" model: qwen-3-235b-a22b-instruct-2507\n"
|
||||
" models: []\n"
|
||||
"- name: NeuralWatt\n"
|
||||
" base_url: ${NEURALWATT_API_BASE}\n"
|
||||
" api_key: ${NEURALWATT_API_KEY}\n"
|
||||
" model: kimi-k2.6-fast\n"
|
||||
" models: []\n"
|
||||
)
|
||||
monkeypatch.setenv("CEREBRAS_API_BASE", "https://api.cerebras.ai/v1")
|
||||
monkeypatch.setenv("CEREBRAS_API_KEY", "sk-live-cerebras-secret")
|
||||
monkeypatch.setenv("NEURALWATT_API_BASE", "https://api.neuralwatt.com/v1")
|
||||
monkeypatch.setenv("NEURALWATT_API_KEY", "sk-live-neuralwatt-secret")
|
||||
|
||||
captured: dict = {}
|
||||
|
||||
def _capture_and_cancel(labels, default=0):
|
||||
captured["labels"] = labels
|
||||
captured["default"] = default
|
||||
return len(labels) - 1 # Leave unchanged
|
||||
|
||||
with patch("hermes_cli.main._prompt_provider_choice",
|
||||
side_effect=_capture_and_cancel), \
|
||||
patch("builtins.print"):
|
||||
select_provider_and_model()
|
||||
|
||||
labels = captured["labels"]
|
||||
default_label = labels[captured["default"]]
|
||||
assert "NeuralWatt" in default_label
|
||||
assert "currently active" in default_label
|
||||
assert "Cerebras.ai" not in default_label
|
||||
assert not any(
|
||||
"Cerebras.ai" in label and "currently active" in label
|
||||
for label in labels
|
||||
)
|
||||
|
||||
def test_named_custom_provider_selection_preserves_base_url_env_ref(
|
||||
self, config_home, monkeypatch
|
||||
):
|
||||
"""Selecting an env-backed custom provider should not expand its
|
||||
``base_url`` template into ``model.base_url`` on disk."""
|
||||
import yaml
|
||||
from hermes_cli.main import select_provider_and_model
|
||||
|
||||
config_path = config_home / "config.yaml"
|
||||
config_path.write_text(
|
||||
"model:\n"
|
||||
" default: old-model\n"
|
||||
" provider: openrouter\n"
|
||||
"custom_providers:\n"
|
||||
"- name: NeuralWatt\n"
|
||||
" base_url: ${NEURALWATT_API_BASE}\n"
|
||||
" api_key: ${NEURALWATT_API_KEY}\n"
|
||||
" model: qwen3.6-35b-fast\n"
|
||||
" models: []\n"
|
||||
)
|
||||
monkeypatch.setenv("NEURALWATT_API_BASE", "https://api.neuralwatt.com/v1")
|
||||
monkeypatch.setenv("NEURALWATT_API_KEY", "sk-live-neuralwatt-secret")
|
||||
|
||||
def _pick_neuralwatt(labels, default=0):
|
||||
for i, label in enumerate(labels):
|
||||
if "NeuralWatt" in label:
|
||||
return i
|
||||
raise AssertionError(
|
||||
f"NeuralWatt entry missing from provider menu: {labels}"
|
||||
)
|
||||
|
||||
with patch("hermes_cli.main._prompt_provider_choice",
|
||||
side_effect=_pick_neuralwatt), \
|
||||
patch("hermes_cli.models.fetch_api_models",
|
||||
return_value=["qwen3.6-35b-fast"]) as mock_fetch, \
|
||||
patch.dict("sys.modules", {"simple_term_menu": None}), \
|
||||
patch("builtins.input", return_value="1"), \
|
||||
patch("builtins.print"):
|
||||
select_provider_and_model()
|
||||
|
||||
mock_fetch.assert_called_once()
|
||||
probe_args, _ = mock_fetch.call_args
|
||||
assert probe_args[1] == "https://api.neuralwatt.com/v1"
|
||||
|
||||
saved = config_path.read_text()
|
||||
config = yaml.safe_load(saved) or {}
|
||||
assert config["model"]["base_url"] == "${NEURALWATT_API_BASE}"
|
||||
assert config["model"]["api_key"] == "${NEURALWATT_API_KEY}"
|
||||
assert "https://api.neuralwatt.com/v1" not in saved
|
||||
assert "sk-live-neuralwatt-secret" not in saved
|
||||
|
||||
def test_key_env_providers_dict_entry_does_not_add_api_key(
|
||||
self, config_home, monkeypatch
|
||||
):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue