test_event_agent.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import json
  2. import pytest
  3. from agent_lab.application.event_agent import EventAgent
  4. from agent_lab.application.tools import ToolDefinition, ToolRegistry
  5. from agent_lab.domain.events import ToolCallEvent
  6. from agent_lab.domain.messages import ChatMessage
  7. @pytest.mark.asyncio
  8. async def test_event_agent_resolves_tool_arguments_from_history():
  9. agent = EventAgent(enabled_tools=["handoff_note"])
  10. event = ToolCallEvent(
  11. id="call_1",
  12. name="handoff_note",
  13. arguments={"message": "chat agent argument should be ignored"},
  14. raw_arguments='{"message":"chat agent argument should be ignored"}',
  15. )
  16. history = [
  17. ChatMessage(role="user", content="debug this event flow"),
  18. ChatMessage(role="assistant", content="I need the event agent."),
  19. ]
  20. reply = await agent.handle(event, history=history)
  21. assert reply.role == "tool"
  22. assert reply.tool_call_id == "call_1"
  23. assert reply.name == "handoff_note"
  24. assert json.loads(reply.content) == {
  25. "tool": "handoff_note",
  26. "message": "I need the event agent.",
  27. }
  28. @pytest.mark.asyncio
  29. async def test_event_agent_returns_registry_errors_for_disabled_and_unknown_tools():
  30. registry = ToolRegistry(
  31. [
  32. ToolDefinition(
  33. name="handoff_note",
  34. description="Send a note to the event agent.",
  35. parameters={"type": "object"},
  36. handler=lambda event: {"tool": event.name, "message": "handled"},
  37. )
  38. ]
  39. )
  40. disabled_reply = await EventAgent(
  41. enabled_tools=[],
  42. registry=registry,
  43. ).handle(
  44. ToolCallEvent(
  45. id="call_1",
  46. name="handoff_note",
  47. arguments={"message": "inspect this event"},
  48. raw_arguments='{"message":"inspect this event"}',
  49. )
  50. )
  51. unknown_reply = await EventAgent(
  52. enabled_tools=["missing_tool"],
  53. registry=registry,
  54. ).handle(
  55. ToolCallEvent(
  56. id="call_2",
  57. name="missing_tool",
  58. arguments={},
  59. raw_arguments="{}",
  60. )
  61. )
  62. assert json.loads(disabled_reply.content) == {
  63. "tool": "handoff_note",
  64. "error": "tool disabled",
  65. }
  66. assert json.loads(unknown_reply.content) == {
  67. "tool": "missing_tool",
  68. "error": "unknown tool",
  69. }
  70. @pytest.mark.asyncio
  71. async def test_event_agent_returns_structured_error_when_tool_handler_raises():
  72. def fail_tool(event: ToolCallEvent) -> dict:
  73. raise RuntimeError("boom")
  74. registry = ToolRegistry(
  75. [
  76. ToolDefinition(
  77. name="handoff_note",
  78. description="Send a note to the event agent.",
  79. parameters={"type": "object"},
  80. handler=fail_tool,
  81. )
  82. ]
  83. )
  84. event = ToolCallEvent(
  85. id="call_1",
  86. name="handoff_note",
  87. arguments={"message": "inspect this event"},
  88. raw_arguments='{"message":"inspect this event"}',
  89. )
  90. reply = await EventAgent(
  91. enabled_tools=["handoff_note"],
  92. registry=registry,
  93. ).handle(event)
  94. assert reply.role == "tool"
  95. assert reply.tool_call_id == "call_1"
  96. assert json.loads(reply.content) == {
  97. "tool": "handoff_note",
  98. "error": "tool handler failed: boom",
  99. }