Skip to content
Changelog

Claude subagent tool calls point to the tool that delegated them

October 12, 20261 min read

Agno's ClaudeAgent copies the parent_tool_use_id that the Claude Agent SDK puts on subagent messages into a new parent_tool_call_id field on ToolExecution. The field appears on streamed ToolCallStartedEvent and ToolCallCompletedEvent, and on the tools stored with the run.

When Claude hands work to a subagent through its Agent tool, the subagent's own Bash and Read calls used to land in the run as a flat list next to the parent's calls. Now each of them names the Agent call that started it, and calls Claude makes itself keep None.

# real output, scripted Claude SDK messages in place of the model
ToolCallStartedEvent    Agent tool_call_id=toolu_agent  parent_tool_call_id=None
ToolCallStartedEvent    Bash  tool_call_id=toolu_bash   parent_tool_call_id=toolu_agent
ToolCallCompletedEvent  Bash  tool_call_id=toolu_bash   parent_tool_call_id=toolu_agent
ToolCallStartedEvent    Read  tool_call_id=toolu_read   parent_tool_call_id=toolu_agent
ToolCallCompletedEvent  Read  tool_call_id=toolu_read   parent_tool_call_id=toolu_agent
ToolCallCompletedEvent  Agent tool_call_id=toolu_agent  parent_tool_call_id=None
ToolCallStartedEvent    Bash  tool_call_id=toolu_bash2  parent_tool_call_id=None
ToolCallCompletedEvent  Bash  tool_call_id=toolu_bash2  parent_tool_call_id=None

In that run the SDK left the parent id off the Read result, and the completed event still carries toolu_agent, because ClaudeAgent keeps the lineage from the start message. Streamed completion events also keep the SDK's error flag on a failed subagent tool as tool_call_error. Tracing integrations can read the field to draw a subagent's spans under the Agent span that delegated them.

Learn more about running Claude and tracing in the documentation.

Frequently asked questions

Read parent_tool_call_id on the ToolExecution, on the stored run or on ToolCallStartedEvent and ToolCallCompletedEvent. A subagent's tool call holds the id of the Agent tool call that delegated to it, and a top-level call holds None.

Yes. It serializes with ToolExecution, so runs loaded from the database keep it. Records written before the field existed load with parent_tool_call_id=None.

ClaudeAgent copies the parent id from the tool's start message onto its completion, so both events for the call carry the same lineage.

Shipped around the same time