This sample directory contains tests for concurrency issues that can occur when multiple agents or runners share toolsets and execute tools concurrently. The tests verify that closing one runner or completing one AgentTool call does not interrupt tools being executed by other runners or AgentTool calls that share the same toolset.
-
mock_tools.py: Common mock tools and toolsets used by all testsMockTool: A mock tool that waits for adone_eventbefore completingMockMcpToolset: A mock MCP toolset with a closed event for testing concurrency
-
runner_shared_toolset/: Tests concurrent runner behavior with shared toolsets- Tests the scenario where two
InMemoryRunnerinstances share the same agent and toolset - Verifies that closing one runner doesn't interrupt tools being executed by the other runner
- Tests the scenario where two
-
agent_tool_parallel/: Tests parallel AgentTool call behavior- Tests the scenario where a root agent calls a sub-agent via
AgentToolmultiple times in parallel - Verifies that
AgentToolManagerproperly handles parallel execution ofAgentToolcalls that share the same agent
- Tests the scenario where a root agent calls a sub-agent via
Both test scenarios address similar concurrency issues:
-
Runner Shared Toolset: When multiple
Runnerinstances share the same agent (and thus the same toolset), closing one runner should not interrupt tools being executed by other runners. -
AgentTool Parallel Calls: When a root agent calls a sub-agent via
AgentToolmultiple times in parallel, eachAgentToolcall creates aRunnerthat uses the same sub-agent. When oneAgentToolcall completes and its runner closes, other parallel calls should not be interrupted.
# Run the test script directly
python -m contributing.samples.adk_concurrent_agent_tool_call.runner_shared_toolset.main
# Or use the ADK CLI
adk run contributing/samples/adk_concurrent_agent_tool_call/runner_shared_toolset# Run the test script directly
python -m contributing.samples.adk_concurrent_agent_tool_call.agent_tool_parallel.main
# Or use the ADK CLI
adk run contributing/samples/adk_concurrent_agent_tool_call/agent_tool_parallelA mock tool that waits for a done_event before completing. It checks if the toolset's closed_event is set during execution and raises an error if interrupted.
A mock MCP toolset that simulates a stateful protocol. It creates a new MockTool instance on each get_tools() call (not cached), which is important for testing the concurrency scenario.
Both tests should verify:
- Tools should start executing concurrently
- When one runner/AgentTool call completes, other parallel executions should continue
- All parallel executions should complete successfully without being interrupted
- No "interrupted" errors should appear in the events
- Concurrent Tool Execution: Verifies that multiple runners/AgentTool calls can execute tools from the same toolset simultaneously
- Toolset Closure Handling: Ensures that closing one runner doesn't affect tools being executed by other runners
- State Management: Tests that shared toolset state is properly managed across multiple runners/AgentTool calls
- Error Detection: Checks for interruption errors in parallel executions
Both tests use monkey patching to track when tools are called:
- Patches
functions.__call_tool_asyncto track running tools - Uses
asyncio.Eventto synchronize tool execution - Monitors events to detect any interruption errors
- AgentTool: The tool that wraps an agent and allows it to be called as a tool
- AgentToolManager: Manages runner registration and toolset cleanup for
AgentTool - Runner: The execution engine that orchestrates agent execution
- BaseToolset: Base class for toolsets that can be shared across multiple runners