const RTDL_PROTOCOL_REMINDER: &str = "## RTDL output (reminder — same format as your earlier turns)\n\
Reply with exactly ONE JSON object, keys EXACTLY these four: \
`content`, `rtdl_description`, `rtdl`, `task_update`. No other top-level keys.\n\
The whole reply MUST begin with `{` and end with `}` — no prose, narration, or \
markdown fences before or after it; put any user-facing text inside `content`, never outside the object. \
Every value must be a literal JSON number or string.\n\
`rtdl` is a tree; every node carries `op_id` (always write `0`; the system \
assigns the real id) and a short `description` of THIS node's intent, plus:\n\
- {\"op\":\"sequence\",\"op_id\":0,\"description\":\"...\",\"children\":[ ...nodes... ]} (run children in order)\n\
- {\"op\":\"parallel\",\"op_id\":0,\"description\":\"...\",\"children\":[ ...nodes... ]} (run children concurrently)\n\
- {\"op\":\"do\",\"op_id\":0,\"description\":\"...\",\"cap\":\"<capability_name>\",\"args\":{ ... }} (one capability call)\n\
A capability name goes ONLY in a do node's `cap` — NEVER as an `op`. \
Beyond `op_id` and `description`, do NOT add other node fields (no `plan_id`, no `out`, no `id`). \
Copy each `cap` EXACTLY from a capability_name in the list below (it is provider-qualified, \
e.g. `tiago_camera.camera_snapshot`); never invent or shorten names.\n\
`task_update`: null keeps current progress, or {\"goal\",\"success_criterion\",\"status\"}. \
The harness owns the instruction history: copy it EXACTLY from \"Current overall task\" and never \
rewrite it. Interpret entries chronologically: the newest user instruction overrides conflicting \
older instructions, while non-conflicting work remains active. You may refine the default success \
criterion once. status is the \
string \"in_progress\" or \"done\" (never null), set to \
\"done\" only when the success_criterion verifiably holds AND no tree in the \
\"In-flight trees\" list is still running (cancelling a tree does not make the task done — wait \
for it to leave the list first).\n\
Compose multi-step trees; don't drip one node per round. No new capability call this round = \
{\"op\":\"sequence\",\"op_id\":0,\"description\":\"wait\",\"children\":[]}.\n\
Plan control is a root meta op, never a capability or nested RTDL node: \
{\"op\":\"cancel_plan\",\"plan_id\":\"<listed id>\",\"wait_ms\":5000}, \
{\"op\":\"cancel_all\",\"wait_ms\":5000}, or \
{\"op\":\"stop_plan_at\",\"plan_id\":\"<listed id>\",\"target_op_id\":\"<listed op id>\",\"when\":\"on_complete\"}. \
A meta op is the entire `rtdl` value for that round and cannot be nested in sequence/parallel/do. \
Never call a skill's cancel capability yourself; Executor propagates cancellation to the active provider.\n\
Executor results are scoped to the plan_id/tree named immediately before them. A failed tree \
blocks only its dependent steps; do not cancel an unrelated in-flight tree because another \
tree failed. Cancel only for an explicit user steer covering that tree or a safety hazard.\n\
For a named room or region, current Scene data is authoritative: call Scene list_objects, then \
goal_room with its stable ID, then navigation with the returned pose. Never substitute a Memory \
coordinate or an object/grasp pose. A navigation SUCCEEDED result proves completion only for the \
resolved requested destination; a zero-distance result does not prove that the robot moved.\n\
Example: {\"content\":\"listing\",\"rtdl_description\":\"list tmp\",\"rtdl\":{\"op\":\"sequence\",\
\"op_id\":0,\"description\":\"list /tmp\",\"children\":[{\"op\":\"do\",\"op_id\":0,\
\"description\":\"list the /tmp directory\",\"cap\":\"executor.builtin_list_dir\",\"args\":{\"path\":\"/tmp\"}}]},\
\"task_update\":null}\n";Expand description
One-line protocol reminder sent on every round after the first. The full
~9KB rtdl_protocol.md is sent only on round 0 (and the model’s own prior
envelopes stay in history), so later rounds re-anchor cheaply instead of
re-shipping the whole spec — a large latency/token win on multi-round turns.