| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- import json
- import pytest
- from agent_lab.application.event_agent import EventAgent
- from agent_lab.application.tools import ToolDefinition, ToolExecutionContext, ToolRegistry
- from agent_lab.domain.events import ToolCallEvent
- from agent_lab.domain.messages import ChatMessage
- @pytest.mark.asyncio
- async def test_event_agent_resolves_tool_arguments_from_history():
- agent = EventAgent(enabled_tools=["handoff_note"])
- event = ToolCallEvent(
- id="call_1",
- name="handoff_note",
- arguments={"message": "chat agent argument should be ignored"},
- raw_arguments='{"message":"chat agent argument should be ignored"}',
- )
- history = [
- ChatMessage(role="user", content="debug this event flow"),
- ChatMessage(role="assistant", content="I need the event agent."),
- ]
- reply = await agent.handle(event, history=history)
- assert reply.role == "tool"
- assert reply.tool_call_id == "call_1"
- assert reply.name == "handoff_note"
- assert json.loads(reply.content) == {
- "tool": "handoff_note",
- "message": "I need the event agent.",
- }
- @pytest.mark.asyncio
- async def test_event_agent_returns_registry_errors_for_disabled_and_unknown_tools():
- registry = ToolRegistry(
- [
- ToolDefinition(
- name="handoff_note",
- description="Send a note to the event agent.",
- parameters={"type": "object"},
- handler=lambda event: {"tool": event.name, "message": "handled"},
- )
- ]
- )
- disabled_reply = await EventAgent(
- enabled_tools=[],
- registry=registry,
- ).handle(
- ToolCallEvent(
- id="call_1",
- name="handoff_note",
- arguments={"message": "inspect this event"},
- raw_arguments='{"message":"inspect this event"}',
- )
- )
- unknown_reply = await EventAgent(
- enabled_tools=["missing_tool"],
- registry=registry,
- ).handle(
- ToolCallEvent(
- id="call_2",
- name="missing_tool",
- arguments={},
- raw_arguments="{}",
- )
- )
- assert json.loads(disabled_reply.content) == {
- "tool": "handoff_note",
- "error": "tool disabled",
- }
- assert json.loads(unknown_reply.content) == {
- "tool": "missing_tool",
- "error": "unknown tool",
- }
- @pytest.mark.asyncio
- async def test_event_agent_returns_structured_error_when_tool_handler_raises():
- def fail_tool(event: ToolCallEvent) -> dict:
- raise RuntimeError("boom")
- registry = ToolRegistry(
- [
- ToolDefinition(
- name="handoff_note",
- description="Send a note to the event agent.",
- parameters={"type": "object"},
- handler=fail_tool,
- )
- ]
- )
- event = ToolCallEvent(
- id="call_1",
- name="handoff_note",
- arguments={"message": "inspect this event"},
- raw_arguments='{"message":"inspect this event"}',
- )
- reply = await EventAgent(
- enabled_tools=["handoff_note"],
- registry=registry,
- ).handle(event)
- assert reply.role == "tool"
- assert reply.tool_call_id == "call_1"
- assert json.loads(reply.content) == {
- "tool": "handoff_note",
- "error": "tool handler failed: boom",
- }
- @pytest.mark.asyncio
- async def test_event_agent_argument_resolver_receives_agent_config_context():
- captured_contexts: list[ToolExecutionContext] = []
- def resolve_arguments(
- event: ToolCallEvent,
- context: ToolExecutionContext,
- ) -> dict:
- captured_contexts.append(context)
- return {
- "message": context.system_prompt,
- "thinking": context.extra_body["thinking"]["type"],
- }
- registry = ToolRegistry(
- [
- ToolDefinition(
- name="handoff_note",
- description="Send a note to the event agent.",
- parameters={"type": "object"},
- handler=lambda event: {
- "tool": event.name,
- "message": event.arguments["message"],
- "thinking": event.arguments["thinking"],
- },
- argument_resolver=resolve_arguments,
- )
- ]
- )
- event = ToolCallEvent(
- id="call_1",
- name="handoff_note",
- arguments={},
- raw_arguments="{}",
- )
- reply = await EventAgent(
- enabled_tools=["handoff_note"],
- registry=registry,
- ).handle(
- event,
- history=[ChatMessage(role="user", content="debug this")],
- system_prompt="Use strict tool parameters.",
- extra_body={"thinking": {"type": "disabled"}},
- )
- assert captured_contexts[0].history[0].content == "debug this"
- assert json.loads(reply.content) == {
- "tool": "handoff_note",
- "message": "Use strict tool parameters.",
- "thinking": "disabled",
- }
|