-
Notifications
You must be signed in to change notification settings - Fork 634
Description
Summary
When using experimental Agent Teams with ClaudeSDKClient, teammate messages sent via SendMessage are never received by the lead because the SDK session terminates before the next turn.
Environment
- Claude Code version: 2.1.42
- Claude Agent SDK version: 0.1.36
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
Root Cause
In interactive mode, messages are delivered between turns as <teammate-message> blocks. In SDK mode, the session ends when receive_response() yields a ResultMessage—there is no "next turn" to receive messages.
Interactive mode timeline:
Lead turn 1: spawn teammate, send message → turn ends
Lead turn 2: <teammate-message> delivered → lead processes it
SDK mode timeline:
Lead turn 1: spawn teammate, send message → ResultMessage → session terminates
(no turn 2 exists to receive the message)
Reproduction Steps
Pseudocode:
async with ClaudeSDKClient(options=options) as client:
await client.query("""
1. Create a team
2. Spawn a teammate to call an MCP tool
3. Wait for teammate to send you the result via SendMessage
4. Submit results
""")
async for message in client.receive_response():
if isinstance(message, ResultMessage):
break # Session ends here, teammate message never arrivesExpected Behavior
Teammate messages should be delivered before the session terminates, or there should be a mechanism to poll/wait for pending messages.
Why This Matters
- Agent Teams are designed for multi-agent coordination
- SDK mode is required for programmatic orchestration (CI/CD, automation, pipelines)
- Without this, Agent Teams cannot be used in any non-interactive context
Stopgap Solution
Simple cases: sleep to keep session alive
For basic coordination, the lead can sleep 5 after spawning a teammate. This keeps the session alive long enough for the teammate to complete work and write to a file:
# Lead instructions
"1. Spawn teammate to call MCP tool and write result to /tmp/result.txt
2. Run 'sleep 5' to wait for teammate
3. Read /tmp/result.txt"Complex cases: secondary store with polling
For multi-step coordination or variable completion times, it is possible to use a secondary store (file, database, or in-memory) with a polling loop:
- Teammate writes output to store instead of SendMessage
- Lead polls store in a loop until result appears
- Lead processes result before session ends
Both workarounds defeat the purpose of the SendMessage abstraction.
Potential Fix
You could block until messages are delivered from one or more agents using a receive_responses() tool that has a max timeout. You could modify the system prompt to sleep loop until agents complete, or a critical error is discovered.