[verified] fix: scope model changes to the active profile
This commit is contained in:
+115
-2
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user