Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/agents/realtime/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class RealtimeToolStart:
"""The agent that updated."""

tool: Tool
"""The tool being called."""

arguments: str
"""The arguments passed to the tool as a JSON string."""

info: RealtimeEventInfo
"""Common info for all events, such as the context."""
Expand All @@ -86,6 +90,9 @@ class RealtimeToolEnd:
tool: Tool
"""The tool that was called."""

arguments: str
"""The arguments passed to the tool as a JSON string."""

output: Any
"""The output of the tool call."""

Expand Down
2 changes: 2 additions & 0 deletions src/agents/realtime/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ async def _handle_tool_call(
info=self._event_info,
tool=function_map[event.name],
agent=agent,
arguments=event.arguments,
)
)

Expand All @@ -436,6 +437,7 @@ async def _handle_tool_call(
tool=func_tool,
output=result,
agent=agent,
arguments=event.arguments,
)
)
elif event.name in handoff_map:
Expand Down
15 changes: 14 additions & 1 deletion tests/realtime/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -986,13 +986,15 @@ async def test_function_tool_execution_success(
assert isinstance(tool_start_event, RealtimeToolStart)
assert tool_start_event.tool == mock_function_tool
assert tool_start_event.agent == mock_agent
assert tool_start_event.arguments == '{"param": "value"}'

# Check tool end event
tool_end_event = await session._event_queue.get()
assert isinstance(tool_end_event, RealtimeToolEnd)
assert tool_end_event.tool == mock_function_tool
assert tool_end_event.output == "function_result"
assert tool_end_event.agent == mock_agent
assert tool_end_event.arguments == '{"param": "value"}'

@pytest.mark.asyncio
async def test_function_tool_with_multiple_tools_available(self, mock_model, mock_agent):
Expand Down Expand Up @@ -1111,6 +1113,7 @@ async def test_function_tool_exception_handling(
assert session._event_queue.qsize() == 1
tool_start_event = await session._event_queue.get()
assert isinstance(tool_start_event, RealtimeToolStart)
assert tool_start_event.arguments == "{}"

# But no tool output should have been sent and no end event queued
assert len(mock_model.sent_tool_outputs) == 0
Expand All @@ -1133,10 +1136,20 @@ async def test_tool_call_with_complex_arguments(

await session._handle_tool_call(tool_call_event)

# Verify arguments were passed correctly
# Verify arguments were passed correctly to tool
call_args = mock_function_tool.on_invoke_tool.call_args
assert call_args[0][1] == complex_args

# Verify tool_start event includes arguments
tool_start_event = await session._event_queue.get()
assert isinstance(tool_start_event, RealtimeToolStart)
assert tool_start_event.arguments == complex_args

# Verify tool_end event includes arguments
tool_end_event = await session._event_queue.get()
assert isinstance(tool_end_event, RealtimeToolEnd)
assert tool_end_event.arguments == complex_args

@pytest.mark.asyncio
async def test_tool_call_with_custom_call_id(self, mock_model, mock_agent, mock_function_tool):
"""Test that tool context receives correct call_id"""
Expand Down