Skip to main content
View source

RocketRide Wave

View as Markdown

RocketRide's native wave-planning agent ("RocketRide Wave"), an experimental agent node that plans each step as a wave of parallel tool calls and uses keyed memory to stay token-efficient.

What it does

Runs an iterative planning loop built directly on the RocketRide architecture: there is no third-party agent framework underneath. Each iteration the LLM plans a batch of tool calls, all tools in the batch run in parallel, results are stored in keyed memory, and the loop repeats until the LLM signals done or max_waves is reached.

Token efficiency comes from a two-level memory model: the planning prompt only ever sees structural summaries of tool results (field names, array lengths, sample values). Raw data stays in the memory store and is pulled on demand via the built-in memory.peek tool (JMESPath extraction, implemented with the jmespath library) or embedded into the final answer via {{memory.ref:...}} template tags resolved at render time.

The node has classType ["agent", "tool"]: besides answering questions on its own lane, it exposes a run_agent tool so parent agents can invoke it for hierarchical agent orchestration.

This node is experimental.


Configuration

FieldTypeDescription
agent_descriptionstringDefault empty. What does this agent do? Describe its purpose and capabilities, this helps parent agents select and invoke it correctly.
instructionsarrayAdditional instructions to guide the agent's planning and responses.
max_wavesintegerDefault 10. Maximum number of planning iterations before the synthesis fallback fires.
profilestringDefault "default".

A single default profile exposes all three fields.


Connections

Invoke channels (control-plane)

ChannelRequiredDescription
llmyes (max 1)LLM used by the agent for planning and synthesis
toolnoTools available to the agent via control-plane invoke
memoryyes (max 1)Keyed memory store for the agent

The memory channel is required. Connect a memory node before running.

Lanes

LaneDirectionDescription
questionsinIncoming questions that start an agent run
answersoutFinal answer emitted when the run completes

Agent-callable tools

run_agent

Exposes this node as a tool to parent agents (addressed as <nodeId>.run_agent).

FieldTypeDescription
querystring (required)The question for the agent. Must be a non-empty string.
contextobject (optional)Extra context passed to the agent as a JSON context block.

Output: {content, meta, stack}. When invoked as a tool, the result is returned to the caller instead of being emitted on the answers lane.

memory.peek

Built-in tool executed locally inside the executor (not routed through the tool pipeline). Lets the LLM extract specific values from memory on demand.

FieldTypeDescription
keystring (required)Memory key to read from (e.g. wave-0.r1).
pathstring (optional)JMESPath expression to extract a specific field or slice (e.g. rows[0:5].city). Arrays are capped at 50 items per call.
offsetinteger (optional)Character offset for chunk reading (default 0). Only when path is omitted.
lengthinteger (optional)Characters to return for chunk reading (default 8000). Only when path is omitted.

Peek results are not stored back into memory. The LLM should capture extracted values in scratch and then remove the peek result key in the same response.


How the wave loop works

  1. Plan: one LLM call per wave. The prompt contains all connected tool descriptors (one compact JSON line each, plus the memory.peek descriptor), the operator's instructions, memory-usage rules, persistent scratch notes, and structural summaries of all prior results. The LLM responds with either {"thought", "scratch", "remove", "tool_calls": [...]} or {"thought", "scratch", "remove", "done": true, "answer": "..."}.
  2. Execute: all tool calls in the batch run concurrently (max 8 threads, 120 s timeout each). Each result is stored in memory under a key like wave-0.r0 and only a structural summary is kept in the wave history. {{memory.ref:...}} tags inside tool arguments are resolved before invocation, so the LLM can compose tool inputs from previously stored results.
  3. Prune: memory keys listed in the LLM's remove field are cleared from the store and stripped from wave history, keeping the planning prompt lean on long-running tasks. Tool errors are returned to the LLM as context rather than aborting the run, so it can recover or change approach.
  4. Repeat until done: true or max_waves is hit. On done, any {{memory.ref:...}} references in the answer are resolved before delivery. If the wave limit is reached without done, a synthesis fallback asks the LLM to produce a best-effort answer from all gathered result summaries. An empty plan (no tool_calls, no done) also short-circuits to synthesis instead of looping.

Progress is surfaced to the UI over the thinking SSE lane: per-wave planning status, the LLM's one-sentence thought, which tools are running, and step completion.


Memory system

The agent uses a two-level memory model to stay token-efficient:

  • Structural summaries: always visible in the planning prompt as "Previous tool results". Show data shape (field names, array lengths, first rows, truncated string previews with char counts) without loading raw values into context.
  • memory.peek: built-in tool the LLM calls on demand to extract specific values via JMESPath (e.g. rows[0:5].city). Arrays are capped at 50 items per call; large raw values can be paged as text with offset/length (default chunk 8000 chars, with total_chars reported so the LLM can page). Peek results are not stored back into memory.
  • {{memory.ref:key}}: embeds the stored value by key at render time. An exact full-string match returns the native type (dict, list, and so on); inside larger strings the value is substituted as text.
  • {{memory.ref:key:format}}: renders bulk data in a specific format without ever loading it into LLM context.
  • {{memory.ref:key:format:path}}: extracts a nested JMESPath path from the stored value before formatting (e.g. rows[0:20]). The path is the last segment, so it may itself contain colons (slice notation). All variants are resolved by the executor at render time, in tool arguments and in the final answer.

The LLM also maintains a scratch field: persistent working notes (memory keys, extracted values, intermediate calculations) that carry forward across waves. When the LLM is done with a result key it signals remove: ["wave-0.r0"] to evict it.


Formats

Built-in formatters for {{memory.ref:key:format}} (no LLM call):

FormatOutput
markdown_tableMarkdown table with header and separator rows
html_tableHTML <table> with <thead>/<tbody>, values escaped
csvCSV with header row (proper quoting via Python csv module)
jsonPretty-printed JSON
textPlain-text key: value blocks per row

Tabular formatters accept several input shapes: a bare list of dicts, {"rows": [...]} (standard database-driver output), a dict with a single list-of-dicts value, or a single dict treated as a one-row table. Any unknown format string (e.g. "bullet list") falls back to a secondary LLM call that renders the data in the requested style.


Schema

FieldTypeDescriptionDefault
agent_descriptionstringAgent description
What does this agent do? Describe its purpose and capabilities, this helps parent agents select and invoke it correctly.
""
agent_rocketride.profilestringProfile"default"
instructionsarrayInstructions
Additional instructions to guide the agent's planning and responses.
max_wavesintegerMax Waves
Maximum number of planning iterations before the synthesis fallback fires.
10

Dependencies

  • jmespath