Deep Agents
A LangChain callback handler that classifies Deep Agent tool calls into planning, sub-agent, filesystem and sandbox events.
pip install "axonpush[deepagents]"Requires Python 3.11 or newer, the deepagents package does not support
3.10.
Deep Agents build on LangGraph, so the handler is a LangChain callback
handler. What it adds over the LangChain integration
is knowing what Deep Agents’ built-in tools mean: planning, sub-agent
delegation, the virtual filesystem, and sandbox execution each get their own
event identifier instead of a generic tool.*.
Attach the handler
from deepagents import create_deep_agent
from axonpush import AxonPush
from axonpush.integrations.deepagents import AxonPushDeepAgentHandler
client = AxonPush()
handler = AxonPushDeepAgentHandler(client, channel_id, agent_id="deep-agent")
agent = create_deep_agent(
tools=[my_tool],
system_prompt="You are a research assistant.",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "Research AI agent frameworks"}]},
config={"callbacks": [handler]},
)
handler.flush(timeout=2.0)client and channel_id are positional.
get_deepagent_handler(client, channel_id, **kwargs) picks the sync or async
class for you based on the client type.
Constructor
AxonPushDeepAgentHandler(
client, # AxonPush - positional
channel_id, # str UUID - positional
*,
agent_id="deepagent",
trace_id=None,
metadata=None,
mode=None, # "background" (default) | "sync"
queue_size=1000,
shutdown_timeout=2.0,
)The async handler takes max_pending=1000 instead of queue_size /
shutdown_timeout.
What gets published
Chain and LLM callbacks behave exactly as they do in the LangChain integration:
| Identifier | Event type |
|---|---|
chain.start / chain.end / chain.error | agent.start / agent.end / agent.error |
llm.start / llm.end | agent.start / agent.end |
llm.token | agent.llm.token |
tool.error | agent.error |
Tool calls are classified by name:
| Tool | Start identifier | End identifier | Event type on start |
|---|---|---|---|
write_todos | planning.update | planning.complete | agent.tool_call.start |
task | subagent.spawn | subagent.complete | agent.handoff |
read_file, ls, glob, grep | filesystem.read | filesystem.read.complete | agent.tool_call.start |
write_file, edit_file and the other filesystem tools | filesystem.write | filesystem.write.complete | agent.tool_call.start |
execute | sandbox.execute | sandbox.execute.complete | agent.tool_call.start |
| anything else | tool.<name>.start | tool.end | agent.tool_call.start |
Spawning a sub-agent is the one that changes type: task emits
agent.handoff on start, so the dashboard draws it as a delegation rather
than as another tool call.
The filesystem tool set is read from deepagents itself, so it tracks the
library rather than a hard-coded list here.
Every event carries framework: "deepagents" in metadata.
Trace shape and LangGraph metadata
Identical to the LangChain handler:
run_id becomes span_id, parent_run_id becomes parent_event_id, and
langgraph_node, langgraph_step, langgraph_triggers, thread_id,
run_type and tags are promoted into event metadata. Sub-agents therefore
nest under the parent agent’s span rather than appearing beside it.
Flush before you exit
handler.flush(timeout=2.0)
handler.close()await handler.aflush(...) / await handler.aclose() on the async handler.