mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-01 07:01:41 +00:00
fix(gateway): wire clarify callback for messaging sessions
This commit is contained in:
parent
a521005fe5
commit
78633e58de
2 changed files with 301 additions and 2 deletions
174
tests/gateway/test_clarify_callback.py
Normal file
174
tests/gateway/test_clarify_callback.py
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
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"
|
||||
Loading…
Add table
Add a link
Reference in a new issue