[verified] fix: scope model changes to the active profile

This commit is contained in:
2026-09-09 18:03:32 +00:00
parent 1d85d7af6b
commit aa705f7dd0
3 changed files with 184 additions and 12 deletions
+115 -2
View File
@@ -16,6 +16,7 @@ import json
import threading
import time
from pathlib import Path
from types import SimpleNamespace
from typing import Any, Dict, List, Optional
import pytest
@@ -703,7 +704,7 @@ class TestBridge:
from pheby import hermes_bridge as hb
import hermes_cli.config as hermes_config
import hermes_cli.model_switch as model_switch
import hermes_cli.model_switch_providers as model_switch_providers
monkeypatch.setattr(hb, "_load_cfg", lambda: {
"model": {"default": "m1", "provider": "test"},
"providers": {"test": {"base_url": "http://example"}},
@@ -713,7 +714,7 @@ class TestBridge:
hermes_config, "get_compatible_custom_providers",
lambda _cfg: [{"name": "test", "base_url": "http://example"}])
monkeypatch.setattr(
model_switch, "list_picker_providers", fake_list_picker_providers)
model_switch_providers, "list_picker_providers", fake_list_picker_providers)
snapshot = await hb.models_snapshot()
assert snapshot["providers"][0]["slug"] == "test"
@@ -721,6 +722,118 @@ class TestBridge:
assert captured["excluded_providers"] == ["hidden"]
assert captured["custom_providers"][0]["name"] == "test"
@pytest.mark.asyncio
async def test_model_set_uses_profile_secret_scope_and_current_result_fields(
self, tmp_path, monkeypatch):
from agent.secret_scope import (
get_secret, reset_secret_scope, set_multiplex_active,
set_secret_scope,
)
from pheby import hermes_bridge as hb
import hermes_cli.config as hermes_config
import hermes_cli.model_switch as model_switch
(tmp_path / ".env").write_text(
"OPENROUTER_API_KEY=scoped-openrouter-key\n", encoding="utf-8")
monkeypatch.setenv("HERMES_HOME", str(tmp_path))
monkeypatch.setattr(hb, "_load_cfg", lambda: {
"model": {"default": "gpt-old", "provider": "openai-codex"},
})
monkeypatch.setattr(
hermes_config, "get_compatible_custom_providers", lambda _cfg: [])
def fake_switch_model(*_args, **_kwargs):
assert get_secret("OPENROUTER_API_KEY") == "scoped-openrouter-key"
return SimpleNamespace(
success=True,
new_model="z-ai/glm-5.3-flash",
target_provider="openrouter",
api_key="scoped-openrouter-key",
base_url="https://openrouter.ai/api/v1",
api_mode="chat_completions",
request_overrides={},
runtime_capabilities={"native_compaction": False},
)
monkeypatch.setattr(model_switch, "switch_model", fake_switch_model)
class Store:
saved = None
def peek_session_id(self, _session_key):
return "session-1"
def set_model_override(self, _session_key, override):
self.saved = override
store = Store()
class Runner:
def __init__(self):
self._session_model_overrides = {}
self.evicted = []
def _evict_cached_agent(self, session_key):
self.evicted.append(session_key)
runner = Runner()
monkeypatch.setattr(hb, "_session_store", lambda: store)
monkeypatch.setattr(hb, "_runner", lambda: runner)
outer_token = set_secret_scope(None)
set_multiplex_active(True)
try:
result = await hb.set_model("glm-flash", "openrouter", "conv")
finally:
set_multiplex_active(False)
reset_secret_scope(outer_token)
assert result == {
"ok": True,
"model": "z-ai/glm-5.3-flash",
"provider": "openrouter",
"scope": "conversation",
}
assert store.saved == {
"model": "z-ai/glm-5.3-flash",
"provider": "openrouter",
}
assert runner._session_model_overrides[
"agent:main:pheby:dm:conv"] == {
"model": "z-ai/glm-5.3-flash",
"provider": "openrouter",
"api_key": "scoped-openrouter-key",
"base_url": "https://openrouter.ai/api/v1",
"api_mode": "chat_completions",
"request_overrides": {},
"capabilities": {"native_compaction": False},
}
assert runner.evicted == ["agent:main:pheby:dm:conv"]
@pytest.mark.asyncio
async def test_model_set_surfaces_current_hermes_error_message(
self, monkeypatch):
from pheby import hermes_bridge as hb
import hermes_cli.config as hermes_config
import hermes_cli.model_switch as model_switch
monkeypatch.setattr(hb, "_load_cfg", lambda: {"model": {}})
monkeypatch.setattr(
hermes_config, "get_compatible_custom_providers", lambda _cfg: [])
monkeypatch.setattr(
model_switch,
"switch_model",
lambda *_args, **_kwargs: SimpleNamespace(
success=False,
error_message="OpenRouter credentials unavailable",
),
)
result = await hb.set_model("z-ai/glm-5.3-flash", "openrouter", None)
assert result["ok"] is False
assert result["code"] == proto.ERR_BAD_REQUEST
assert result["message"] == "OpenRouter credentials unavailable"
@pytest.mark.asyncio
async def test_cancel_run_interrupts_agent(self, tmp_path):
server = make_server(tmp_path)