| """Tests for gateway /fast support and Priority Processing routing.""" |
|
|
| import sys |
| import threading |
| import types |
| from types import SimpleNamespace |
| from unittest.mock import AsyncMock, patch |
|
|
| import pytest |
| import yaml |
|
|
| import gateway.run as gateway_run |
| from gateway.config import Platform |
| from gateway.platforms.base import MessageEvent |
| from gateway.session import SessionSource |
|
|
|
|
| class _CapturingAgent: |
| last_init = None |
| last_run = None |
|
|
| def __init__(self, *args, **kwargs): |
| type(self).last_init = dict(kwargs) |
| self.tools = [] |
|
|
| def run_conversation(self, user_message, conversation_history=None, task_id=None, persist_user_message=None): |
| type(self).last_run = { |
| "user_message": user_message, |
| "conversation_history": conversation_history, |
| "task_id": task_id, |
| "persist_user_message": persist_user_message, |
| } |
| return { |
| "final_response": "ok", |
| "messages": [], |
| "api_calls": 1, |
| "completed": True, |
| } |
|
|
|
|
| def _install_fake_agent(monkeypatch): |
| fake_run_agent = types.ModuleType("run_agent") |
| fake_run_agent.AIAgent = _CapturingAgent |
| monkeypatch.setitem(sys.modules, "run_agent", fake_run_agent) |
|
|
|
|
| def _make_runner(): |
| runner = object.__new__(gateway_run.GatewayRunner) |
| runner.adapters = {} |
| runner._ephemeral_system_prompt = "" |
| runner._prefill_messages = [] |
| runner._reasoning_config = None |
| runner._service_tier = None |
| runner._provider_routing = {} |
| runner._fallback_model = None |
| runner._smart_model_routing = {} |
| runner._running_agents = {} |
| runner._pending_model_notes = {} |
| runner._session_db = None |
| runner._agent_cache = {} |
| runner._agent_cache_lock = threading.Lock() |
| runner._session_model_overrides = {} |
| runner.hooks = SimpleNamespace(loaded_hooks=False) |
| runner.config = SimpleNamespace(streaming=None) |
| runner.session_store = SimpleNamespace( |
| get_or_create_session=lambda source: SimpleNamespace(session_id="session-1"), |
| load_transcript=lambda session_id: [], |
| ) |
| runner._get_or_create_gateway_honcho = lambda session_key: (None, None) |
| runner._enrich_message_with_vision = AsyncMock(return_value="ENRICHED") |
| return runner |
|
|
|
|
| def _make_source() -> SessionSource: |
| return SessionSource( |
| platform=Platform.TELEGRAM, |
| chat_id="12345", |
| chat_type="dm", |
| user_id="user-1", |
| ) |
|
|
|
|
| def _make_event(text: str) -> MessageEvent: |
| return MessageEvent(text=text, source=_make_source(), message_id="m1") |
|
|
|
|
| def test_turn_route_injects_priority_processing_without_changing_runtime(): |
| runner = _make_runner() |
| runner._service_tier = "priority" |
| runtime_kwargs = { |
| "api_key": "***", |
| "base_url": "https://openrouter.ai/api/v1", |
| "provider": "openrouter", |
| "api_mode": "chat_completions", |
| "command": None, |
| "args": [], |
| "credential_pool": None, |
| } |
|
|
| with patch("agent.smart_model_routing.resolve_turn_route", return_value={ |
| "model": "gpt-5.4", |
| "runtime": dict(runtime_kwargs), |
| "label": None, |
| "signature": ("gpt-5.4", "openrouter", "https://openrouter.ai/api/v1", "chat_completions", None, ()), |
| }): |
| route = gateway_run.GatewayRunner._resolve_turn_agent_config(runner, "hi", "gpt-5.4", runtime_kwargs) |
|
|
| assert route["runtime"]["provider"] == "openrouter" |
| assert route["runtime"]["api_mode"] == "chat_completions" |
| assert route["request_overrides"] == {"service_tier": "priority"} |
|
|
|
|
| def test_turn_route_skips_priority_processing_for_unsupported_models(): |
| runner = _make_runner() |
| runner._service_tier = "priority" |
| runtime_kwargs = { |
| "api_key": "***", |
| "base_url": "https://openrouter.ai/api/v1", |
| "provider": "openrouter", |
| "api_mode": "chat_completions", |
| "command": None, |
| "args": [], |
| "credential_pool": None, |
| } |
|
|
| with patch("agent.smart_model_routing.resolve_turn_route", return_value={ |
| "model": "gpt-5.3-codex", |
| "runtime": dict(runtime_kwargs), |
| "label": None, |
| "signature": ("gpt-5.3-codex", "openrouter", "https://openrouter.ai/api/v1", "chat_completions", None, ()), |
| }): |
| route = gateway_run.GatewayRunner._resolve_turn_agent_config(runner, "hi", "gpt-5.3-codex", runtime_kwargs) |
|
|
| assert route["request_overrides"] is None |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_handle_fast_command_persists_config(monkeypatch, tmp_path): |
| runner = _make_runner() |
|
|
| monkeypatch.setattr(gateway_run, "_hermes_home", tmp_path) |
| monkeypatch.setattr(gateway_run, "_load_gateway_config", lambda: {}) |
| monkeypatch.setattr(gateway_run, "_resolve_gateway_model", lambda config=None: "gpt-5.4") |
|
|
| response = await runner._handle_fast_command(_make_event("/fast fast")) |
|
|
| assert "FAST" in response |
| assert runner._service_tier == "priority" |
|
|
| saved = yaml.safe_load((tmp_path / "config.yaml").read_text(encoding="utf-8")) |
| assert saved["agent"]["service_tier"] == "fast" |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_run_agent_passes_priority_processing_to_gateway_agent(monkeypatch, tmp_path): |
| _install_fake_agent(monkeypatch) |
| runner = _make_runner() |
|
|
| (tmp_path / "config.yaml").write_text("agent:\n service_tier: fast\n", encoding="utf-8") |
| monkeypatch.setattr(gateway_run, "_hermes_home", tmp_path) |
| monkeypatch.setattr(gateway_run, "_env_path", tmp_path / ".env") |
| monkeypatch.setattr(gateway_run, "load_dotenv", lambda *args, **kwargs: None) |
| monkeypatch.setattr(gateway_run, "_load_gateway_config", lambda: {}) |
| monkeypatch.setattr(gateway_run, "_resolve_gateway_model", lambda config=None: "gpt-5.4") |
| monkeypatch.setattr( |
| gateway_run, |
| "_resolve_runtime_agent_kwargs", |
| lambda: { |
| "provider": "openrouter", |
| "api_mode": "chat_completions", |
| "base_url": "https://openrouter.ai/api/v1", |
| "api_key": "***", |
| }, |
| ) |
|
|
| import hermes_cli.tools_config as tools_config |
| monkeypatch.setattr(tools_config, "_get_platform_tools", lambda user_config, platform_key: {"core"}) |
|
|
| _CapturingAgent.last_init = None |
| result = await runner._run_agent( |
| message="hi", |
| context_prompt="", |
| history=[], |
| source=_make_source(), |
| session_id="session-1", |
| session_key="agent:main:telegram:dm:12345", |
| ) |
|
|
| assert result["final_response"] == "ok" |
| assert _CapturingAgent.last_init["service_tier"] == "priority" |
| assert _CapturingAgent.last_init["request_overrides"] == {"service_tier": "priority"} |
|
|