mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
174 lines
5.1 KiB
Python
174 lines
5.1 KiB
Python
import asyncio
|
|
import threading
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from gateway.config import Platform, StreamingConfig
|
|
from gateway.platforms.base import MessageEvent, MessageType
|
|
from gateway.run import GatewayRunner
|
|
from gateway.session import SessionSource
|
|
|
|
|
|
def _make_source(platform=Platform.TELEGRAM):
|
|
return SessionSource(
|
|
platform=platform,
|
|
chat_id="6493121275",
|
|
chat_name="Test Chat",
|
|
chat_type="dm",
|
|
user_id="6493121275",
|
|
user_name="Tyler",
|
|
thread_id=None,
|
|
)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_gateway_clarify_callback_round_trip():
|
|
runner = GatewayRunner.__new__(GatewayRunner)
|
|
adapter = MagicMock()
|
|
adapter.send = AsyncMock()
|
|
runner.adapters = {Platform.TELEGRAM: adapter}
|
|
runner._pending_clarify = {}
|
|
source = _make_source()
|
|
|
|
callback = runner._build_clarify_callback(
|
|
source=source,
|
|
session_key="telegram:6493121275",
|
|
loop=asyncio.get_running_loop(),
|
|
metadata=None,
|
|
)
|
|
|
|
result_box = {}
|
|
|
|
def worker():
|
|
result_box["result"] = callback("Pick a color", ["red", "blue"])
|
|
|
|
thread = threading.Thread(target=worker)
|
|
thread.start()
|
|
|
|
for _ in range(20):
|
|
if runner._pending_clarify:
|
|
break
|
|
await asyncio.sleep(0.05)
|
|
|
|
for _ in range(20):
|
|
if adapter.send.await_count:
|
|
break
|
|
await asyncio.sleep(0.05)
|
|
|
|
assert "telegram:6493121275" in runner._pending_clarify
|
|
adapter.send.assert_awaited_once()
|
|
sent_text = adapter.send.await_args.args[1]
|
|
assert "Pick a color" in sent_text
|
|
assert "1. red" in sent_text
|
|
assert "2. blue" in sent_text
|
|
|
|
entry = runner._pending_clarify["telegram:6493121275"]
|
|
entry["response"] = "blue"
|
|
entry["event"].set()
|
|
|
|
thread.join(timeout=2)
|
|
assert result_box["result"] == "blue"
|
|
assert "telegram:6493121275" not in runner._pending_clarify
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_handle_pending_clarify_consumes_numeric_reply():
|
|
runner = GatewayRunner.__new__(GatewayRunner)
|
|
runner._pending_clarify = {
|
|
"telegram:6493121275": {
|
|
"question": "Pick a color",
|
|
"choices": ["red", "blue"],
|
|
"response": None,
|
|
"event": threading.Event(),
|
|
"user_id": "6493121275",
|
|
}
|
|
}
|
|
event = MessageEvent(
|
|
text="2",
|
|
message_type=MessageType.TEXT,
|
|
source=_make_source(),
|
|
)
|
|
|
|
result = await runner._handle_pending_clarify(event, "telegram:6493121275")
|
|
|
|
assert result == ""
|
|
entry = runner._pending_clarify["telegram:6493121275"]
|
|
assert entry["response"] == "blue"
|
|
assert entry["event"].is_set()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_run_agent_wires_clarify_callback_to_agent(monkeypatch):
|
|
runner = GatewayRunner.__new__(GatewayRunner)
|
|
runner.adapters = {}
|
|
runner.config = MagicMock()
|
|
runner.config.streaming = StreamingConfig()
|
|
runner._running_agents = {}
|
|
runner._running_agents_ts = {}
|
|
runner._session_model_overrides = {}
|
|
runner._agent_cache = {}
|
|
runner._agent_cache_lock = None
|
|
runner._provider_routing = {
|
|
"only": None,
|
|
"ignore": None,
|
|
"order": None,
|
|
"sort": None,
|
|
"require_parameters": False,
|
|
"data_collection": None,
|
|
}
|
|
runner._fallback_model = None
|
|
runner._prefill_messages = None
|
|
runner._ephemeral_system_prompt = ""
|
|
runner._session_db = None
|
|
runner._pending_clarify = {}
|
|
runner.hooks = MagicMock()
|
|
runner.hooks.loaded_hooks = False
|
|
runner._load_reasoning_config = lambda: None
|
|
runner._load_service_tier = lambda: None
|
|
runner._resolve_session_agent_runtime = lambda **kw: (
|
|
"anthropic/claude-sonnet-4",
|
|
{
|
|
"api_key": "test-key",
|
|
"base_url": "https://openrouter.ai/api/v1",
|
|
"provider": "openrouter",
|
|
"api_mode": "chat_completions",
|
|
},
|
|
)
|
|
runner._resolve_turn_agent_config = lambda message, model, runtime: {
|
|
"model": model,
|
|
"runtime": runtime,
|
|
"request_overrides": None,
|
|
}
|
|
runner._build_clarify_callback = lambda **kw: (lambda question, choices: "blue")
|
|
runner._get_proxy_url = lambda: None
|
|
|
|
class FakeAgent:
|
|
def __init__(self, *args, **kwargs):
|
|
self.clarify_callback = None
|
|
self.tools = []
|
|
|
|
def run_conversation(self, user_message=None, **kwargs):
|
|
return {
|
|
"final_response": self.clarify_callback("Pick a color", ["red", "blue"]),
|
|
"messages": [],
|
|
"api_calls": 1,
|
|
"completed": True,
|
|
}
|
|
|
|
monkeypatch.setattr("gateway.run._load_gateway_config", lambda: {"display": {}})
|
|
|
|
source = _make_source()
|
|
with patch("run_agent.AIAgent", FakeAgent), patch(
|
|
"hermes_cli.tools_config._get_platform_tools", return_value=[]
|
|
):
|
|
result = await runner._run_agent(
|
|
message="hello",
|
|
context_prompt="",
|
|
history=[],
|
|
source=source,
|
|
session_id="session-1",
|
|
session_key="telegram:6493121275",
|
|
)
|
|
|
|
assert result["final_response"] == "blue"
|