Deep Agent
A planning-capable RocketRide agent built on the Deep Agents library, with optional managed sub-agents for hierarchical delegation.
What it does
Runs an agent loop via deepagents.create_deep_agent (built on LangChain/LangGraph), which layers strategic planning, persistent state, and long-context management on top of the standard LangChain tool-calling loop. The package ships two node variants:
- Deep Agent (
agent_deepagent): the orchestrator. Consumesquestionsand producesanswers, runs standalone with its own tools, and registers as a tool (classType: ["agent", "tool"]) so a parent agent can delegate to it via<nodeId>.run_agent. - Deep Agent Subagent (
agent_deepagent_subagent): a managed worker (classType: ["deepagent"]). It has noquestionslane and cannot be invoked directly or called as a tool; it must be wired into a Deep Agent via thedeepagentinvoke channel, which delegates to it based on itsdescription.
Sub-agents are optional: with none connected, the Deep Agent behaves as a standard single-agent node. Inference is routed through the host LLM channel using a JSON envelope protocol, so any LLM that can follow JSON instructions works; native function-calling support is not required. Agent lifecycle progress (tool calls, LLM calls, agent steps) is streamed as SSE thinking events.
Configuration
Lanes
Lanes (Deep Agent only): questions -> answers. The Subagent declares no lanes; it is driven by an orchestrator, not by direct questions.
Deep Agent invoke channels
| Channel | Required | Description |
|---|---|---|
llm | yes (min 1) | LLM used by the agent |
tool | no | Tools available to the agent (via control-plane invoke) |
deepagent | no | Deep Agent Subagent nodes for hierarchical delegation |
Deep Agent Subagent invoke channels
| Channel | Required | Description |
|---|---|---|
llm | yes (min 1) | LLM this sub-agent thinks with |
tool | no | Tools available to this sub-agent |
The sub-agent's LLM and tool channels are independent of the orchestrator's. When the orchestrator delegates, the sub-agent's LLM and tool calls are routed back through this node's own channels.
Both variants use an Advanced Mode toggle (default Off): when Off, the node is edited through the Instructions list; when On, the prompt fields are exposed directly.
Deep Agent
| Field | Type | Description |
|---|---|---|
description | string | Default empty. The orchestrator reads this description to decide when to delegate to this sub-agent. Keep it specific and action-oriented, this is the only signal the orchestrator uses to pick a sub-agent. |
system_prompt | string | Default empty. Instructions that define this sub-agent's role and behaviour. Leave blank to use the default. |
instructions | array | Additional instructions to guide this sub-agent. Each line is appended to the system prompt. |
advanced_mode | boolean | Default false. When enabled, replace the Instructions list with a direct System Prompt field for full control. |
agent_description | string | Default empty. What does this agent do? Describe its purpose and capabilities, this helps parent agents select and invoke it correctly. |
Deep Agent Subagent
| Field | Type / Default | Description |
|---|---|---|
description | string, "" | Always visible. The orchestrator reads this to decide when to delegate; it is the only signal used to pick a sub-agent. Keep it specific and action-oriented. |
advanced_mode | boolean, false | Off shows instructions; On shows system_prompt for full control. |
instructions | array, [] | Additional instructions; each line is appended to the system prompt. (Advanced Mode Off) |
system_prompt | string, "" | Instructions that define this sub-agent's role and behaviour. Blank uses the built-in default. (Advanced Mode On) |
The final system prompt is composed as the base system_prompt (or the built-in fallback when blank) with each non-empty instruction appended on its own line.
Tool calling
The host LLM is opaque to the driver, so tool calling uses a JSON envelope protocol: each LLM call is prefixed with a system preamble instructing the model to output exactly one JSON object in one of three shapes:
- Single tool call:
{"type":"tool_call","name":"server.tool","args":{...}} - Parallel tool calls:
{"type":"tool_calls","calls":[{"name":"...","args":{...}}, ...]} - Final answer:
{"type":"final","content":"..."}
The plural tool_calls form dispatches all entries concurrently (LangGraph's async ToolNode fans them out via asyncio.gather), which is what unlocks parallel sub-agent delegation in a single turn.
Up to 3 attempts are made when the LLM produces malformed JSON, and a tolerant parser extracts the first balanced JSON object, rescuing responses wrapped in markdown fences, followed by trailing prose, or stacked with a stray second object (a common failure mode: a duplicate call or hallucinated final appended after a tool_call).
Host tool descriptors are converted to LangChain BaseTool instances with typed Pydantic input schemas built from each tool's JSON-Schema inputSchema; tool execution and LLM calls are bridged off the event loop via asyncio.to_thread so concurrent calls do not serialize.
Hierarchical delegation
Connect one or more Deep Agent Subagent nodes to the deepagent invoke channel to turn the Deep Agent into an orchestrator. On each run:
- The orchestrator fans out a
describeinvoke to every connected Subagent node. - Each sub-agent returns its name, description, system prompt, instructions, and a reference to its own engine channels.
- The orchestrator builds a
deepagents.middleware.subagents.SubAgentrecord per descriptor, wiring each sub-agent's LLM and tools to its own channels, and passes them tocreate_deep_agent(subagents=...). - The orchestrator's LLM gains a
task(description, subagent_type)tool it calls to delegate work. Each sub-agent runs in its ownAgentContextthat inherits the run metadata, so SSE events route back to the same logical run.
Give each sub-agent its own LLM, tools, and a clear description: the description is the only signal the orchestrator uses to choose a delegate. A Subagent can be connected to multiple orchestrators simultaneously; each orchestrator independently includes it in its own hierarchical run. A describe failure on one node is logged and skipped, not fatal to the run.
Using as a tool
The Deep Agent (not the Subagent) exposes itself as an invokable tool, <nodeId>.run_agent, so parent agents can delegate to it in nested pipelines.
- Input:
{query: string, context?: object}.querymust be a non-empty string;context, when provided, is attached to the question as aRocketRide.agent.tool_context.v1JSON payload. - Output:
{content, meta, stack}.
When agent_description is non-empty it is included in the tool's description so parent agents can select this agent correctly.
Observability
The driver emits SSE thinking events throughout a run: host-tool discovery count, sub-agent collection count, agent start, per-tool start/completion/error (with tool name and input length), LLM call start/completion/error, and agent thinking/done transitions.
Schema
Deep Agent (services.agent.json)
| Field | Type | Description | Default |
|---|---|---|---|
advanced_mode | boolean | Advanced Mode When enabled, replace the Instructions list with direct Agent Description and System Prompt fields for full control. | false |
agent_description | string | Agent description What does this agent do? Describe its purpose and capabilities, this helps parent agents select and invoke it correctly. | "" |
instructions | array | Instructions Additional instructions to guide the agent. Each line is appended to the system prompt. | |
system_prompt | string | System prompt Instructions that define this agent's role and behaviour. Leave blank to use the default. | "" |
Deep Agent Subagent (services.subagent.json)
| Field | Type | Description | Default |
|---|---|---|---|
advanced_mode | boolean | Advanced Mode When enabled, replace the Instructions list with a direct System Prompt field for full control. | false |
description | string | Description The orchestrator reads this description to decide when to delegate to this sub-agent. Keep it specific and action-oriented, this is the only signal the orchestrator uses to pick a sub-agent. | "" |
instructions | array | Instructions Additional instructions to guide this sub-agent. Each line is appended to the system prompt. | |
system_prompt | string | System prompt Instructions that define this sub-agent's role and behaviour. Leave blank to use the default. | "" |
Dependencies
deepagentslangchainlangchain-corepydantic