Tool reference¶
Generated from strands_robots/tools/ by docs/hooks/tool_reference.py at build - do not edit.
Every tool returns the same envelope, {"status": ..., "content": [{"text": "..."}]}, read through
result["content"][0]["text"] and never through invented keys - see the
tool result contract. A tool marked as taking the agent's tool context can stop
and ask an operator before it acts.
68 tools, generated from the source at build time.
Core¶
Cameras, teleoperation, training, rollout, poses, the serial bus, the mesh and the ROS transports.
download_assets, gr00t_inference, harness_memory, lerobot_camera, lerobot_teleoperate, lerobot_train, load_episode, pose_tool, read_predicate_verdict, robot_mesh, run_policy, sample_frames, serial_tool, train_policy, use_lerobot, use_ros, use_rosbridge, use_rtps, write_label
download_assets¶
Download and manage robot model assets (MJCF XML + meshes).
strands_robots.tools.download_assets
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
'download' |
download | list | status. status marks each robot [ok] (assets present) or [--] (missing). |
robots |
str | None |
None |
Comma-separated names (e.g. so100,panda). Omit for all. A non-empty value that names no robot (",") is refused rather than read as "all". |
category |
str | None |
None |
Filter: arm, bimanual, hand, humanoid, mobile, mobile_manip |
force |
bool |
False |
Re-fetch a robot whose assets are already present, replacing the cached directory. A posture, so a non-boolean is refused rather than read by truthiness - force="false" would otherwise select the re-fetch it spells the skipping of. |
gr00t_inference¶
Manage GR00T N1 inference services in Docker containers.
strands_robots.tools.gr00t_inference
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | Action to perform (see Actions above). |
checkpoint_path |
str | None |
None |
Path to model checkpoint directory (required for start/restart). |
policy_name |
str | None |
None |
Optional name for the policy service (for registration/tracking). |
port |
int |
5555 |
Port for the inference service. Must be an int in 1-65535. Defaults to 5555 (ZMQ) or auto-switches to 8000 when http_server=True. |
data_config |
str |
'fourier_gr1_arms_only' |
Embodiment data config name (see Data configs above). N1.5/N1.6 only. Must be a lowercase [a-z][a-z0-9_]+ selector token - it is passed to the server's --data-config flag, which reports a name it cannot read only in the container log. |
embodiment_tag |
str |
'gr1' |
Embodiment tag for the model (e.g., gr1, so100, libero_sim). Must be a lowercase [a-z][a-z0-9_]+ selector token. |
denoising_steps |
int |
4 |
Number of denoising steps for action generation (default: 4). Must be a positive integer. Ignored by protocol="n1.7", whose entrypoint takes no --denoising-steps flag. N1.5/N1.6 only - the N1.7 server reads this from the checkpoint. |
host |
str |
'0.0.0.0' |
Host address to bind the service to (default: 0.0.0.0). |
container_name |
str | None |
None |
Specific Docker container name. Auto-detected if omitted. |
timeout |
int |
60 |
Seconds to wait for service startup (default: 60). Must be a positive finite number - the wait is a poll loop, so a non-positive budget never polls and a non-finite one never gives up. |
use_tensorrt |
bool |
False |
Enable TensorRT acceleration (default: False). Must be a boolean; it also decides whether the three dtype options are read. |
trt_engine_path |
str |
'gr00t_engine' |
Directory for TensorRT engine cache (default: gr00t_engine). |
vit_dtype |
str |
'fp8' |
ViT precision with TensorRT - fp16 or fp8 (default: fp8). Must be a lowercase [a-z][a-z0-9_]+ token; read only when use_tensorrt=True. |
llm_dtype |
str |
'nvfp4' |
LLM precision with TensorRT - fp16, nvfp4, or fp8 (default: nvfp4). Must be a lowercase [a-z][a-z0-9_]+ token; read only when use_tensorrt=True. |
dit_dtype |
str |
'fp8' |
DiT precision with TensorRT - fp16 or fp8 (default: fp8). Must be a lowercase [a-z][a-z0-9_]+ token; read only when use_tensorrt=True. |
http_server |
bool |
False |
Use HTTP REST API instead of ZMQ (default: False). Must be a boolean; it moves the default port from 5555 to 8000. |
api_token |
str | None |
None |
API token for authentication. Falls back to GROOT_API_TOKEN env var. |
protocol |
str |
'n1.5' |
Server protocol version - "n1.5" (default), "n1.6", or "n1.7". Determines which inference-service entrypoint and flag set is exec'd in the container. See "Server protocol versions" above. |
use_sim_policy_wrapper |
bool |
False |
When protocol="n1.7", append --use-sim-policy-wrapper to the server command. Required for sim evaluation (LIBERO, RoboCasa, …) - the wrapper translates simulator-side observations into the format the policy expects. Must be a boolean under protocol="n1.7"; ignored for N1.5 / N1.6 (no equivalent flag). |
deterministic |
bool |
False |
Run the server through the packaged determinism wrapper (strands_robots.policies.groot.server_wrapper) instead of the bare run_gr00t_server entrypoint. The wrapper sets cudnn.deterministic=True / cudnn.benchmark=False / CUBLAS_WORKSPACE_CONFIG=":4096:8" and patches the server-side Gr00tPolicy.reset (a no-op upstream) to reseed torch / numpy / random per episode from the client-forwarded seed - required for bit-exact run-to-run reproducibility (e.g. CI pinning a success_rate). start_container bind-mounts the wrapper read-only at a fixed container path; the mount source is library-resolved, never caller-supplied, so the tool's volume lockdown holds. Requires protocol="n1.7" (the wrapper hands off to the N1.7 entrypoint) - other protocols fail closed rather than silently dropping the flag. Honors the operator env vars STRANDS_GR00T_SERVER_SEED (default seed, 42) and STRANDS_GR00T_STRICT_DETERMINISTIC=1 (strict torch deterministic-algorithms mode) by forwarding them into the container. Must be a boolean. Default False - byte-identical to the previous behavior. |
hf_repo |
str | None |
None |
HuggingFace dataset/model id (e.g., "nvidia/GR00T-N1.7-LIBERO"). Required for download_checkpoint. Read by download_checkpoint and by lifecycle="full". |
hf_subfolder |
str | None |
None |
Subfolder pattern within the HF repo (e.g., "libero_spatial"). When set, only files matching <subfolder>/* are downloaded. |
hf_local_dir |
str | None |
None |
Where to download the checkpoint. Defaults to $STRANDS_BASE_DIR/checkpoints/<basename(hf_repo)>. Also the host side of the /data/checkpoints bind mount, so under /home it is confined to that checkpoints dir and the Hugging Face cache; the system temp dir is admitted too. Anywhere else under a protected prefix is refused. |
hf_token |
str | None |
None |
HuggingFace API token, for gated repos. Falls back to the HF_TOKEN / HUGGING_FACE_HUB_TOKEN env vars, which is the preferred way to supply it - a token passed here travels through the tool call. |
lifecycle |
str |
'full' |
Which phase action="lifecycle" runs: "full" (default - chain build_image → download_checkpoint → start_container → start and wait for the port) or "teardown" (remove the container). Ignored by every other action. |
remove_volumes |
bool |
False |
Under lifecycle="teardown", also remove the container's docker volumes. Must be a boolean - it is checked rather than read by truthiness, because "false" would otherwise select the deletion it reads as declining. Default False, which preserves the checkpoint and HuggingFace-cache mounts; passing True discards downloaded checkpoints, so a later lifecycle="full" re-downloads. |
force |
bool |
False |
Override the idempotence of the setup steps - rebuild the image, re-download the checkpoint, or recreate the container even when the artefact is already present. Must be a boolean. Default False, which makes a re-run after a crash resume rather than repeat work. |
Returns. Dict with operation results. Common fields: - status: "success" or "error" - message: Human-readable description For start/restart: port, checkpoint_path, container_name, protocol, data_config, embodiment_tag, denoising_steps, endpoint (HTTP only), tensorrt (if enabled) For status: port, service_status ("running" or "not_running"), protocol For list: services (list of {port, protocol, status}) For find_containers: containers (list of {name, image, status, ports})
harness_memory¶
Persist and retrieve harness memory: task solution traces + global rules.
strands_robots.tools.harness_memory
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | Action to perform. |
task |
str | None |
None |
Task key, matched exactly on later runs. Must match ^[a-zA-Z0-9_-]+\Z (max 128 chars; no dots, so use "task_v2" rather than "task.v2"). |
trace |
list[dict[str, Any]] | None |
None |
Solution skeleton: list of primitive-invocation dicts, one per step, e.g. {"action": "run_policy", "instruction": "grasp the bowl"}. Spatial values are reference bindings, not replay targets. |
summary |
dict[str, Any] | None |
None |
Semantic summary: task description, strategy, pitfalls to avoid ("avoid" list), success flag. |
kind |
str | None |
None |
Rule kind for append_rule: "success_rule" or "failure_model". |
text |
str | None |
None |
Rule text for append_rule (single line, max 2000 chars). |
backend |
str | None |
None |
Optional provenance: simulation backend the trace was collected on (e.g. "mujoco"). |
robot |
str | None |
None |
Optional provenance: robot the trace was collected with (e.g. "so100"). |
Returns. Dict containing status and response content.
lerobot_camera¶
Advanced LeRobot-based camera tool for professional camera management.
strands_robots.tools.lerobot_camera
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
'list' |
Action to perform - "discover": Discover all available cameras (OpenCV + RealSense) - "list": List camera details and configurations - "capture": Capture single image from camera - "capture_batch": Capture from multiple cameras simultaneously - "record": Record video sequence from camera - "preview": Show live preview from camera - "test": Test camera functionality and performance - "configure": Configure camera settings and save |
camera_type |
str |
'opencv' |
Camera type ("opencv" or "realsense"). "realsense" needs the Intel SDK installed on top of lerobot; without it the action is refused naming that install, rather than reported as unsupported. |
camera_id |
int | str | None |
None |
Camera device ID (int for index, str for path like "/dev/video0") |
save_path |
str |
'./lerobot_captures' |
Directory to save captured images/videos |
filename |
str | None |
None |
Custom filename (without extension). Resolved inside save_path; a value naming a location outside it is refused rather than written there. |
camera_ids |
list[int | str] | None |
None |
Cameras to capture from in one capture_batch call - a list of distinct ids, each an int index or a device path string. Omit it for the default robot cameras. An empty list selects no camera and is refused rather than widened to those defaults; a single id passed as a bare string is refused rather than read one camera per character. |
width |
int |
640 |
Frame width in pixels (a positive whole number) |
height |
int |
480 |
Frame height in pixels (a positive whole number) |
fps |
int |
30 |
Frames per second (a positive whole number) |
color_mode |
str |
'RGB' |
Color mode; one of "RGB" or "BGR", compared case-insensitively. Any other value is refused rather than silently read as "BGR". |
rotation |
str |
'NO_ROTATION' |
Image rotation; one of "NO_ROTATION", "ROTATE_90", "ROTATE_180" or "ROTATE_270", compared case-insensitively. Any other value is refused rather than silently read as "NO_ROTATION". |
format |
str |
'jpg' |
Image format ("jpg", "png", "bmp"). Becomes the saved file's extension, so like filename it is resolved inside save_path and refused if it names a location outside it. The image returned alongside the file is encoded as JPEG only for a JPEG request; any other format is carried back losslessly as PNG, so the inline copy has the frame's own pixels. |
capture_duration |
float |
5.0 |
Duration for video recording (positive seconds) |
preview_duration |
float |
10.0 |
Duration for preview display (positive seconds) |
async_mode |
bool |
False |
Use async reading for better performance. A boolean; it selects a read path rather than scaling one, so any other value is refused rather than read as its opposite. |
timeout_ms |
float |
1000 |
Timeout for async operations (positive milliseconds; read only when async_mode is on) |
warmup |
bool |
True |
Enable camera warmup on connection. A boolean, refused rather than read by truthiness - it is also recorded in the saved configuration, so a non-boolean would persist there. |
save_config |
bool |
False |
Save camera configuration to file. A boolean, refused rather than read by truthiness: it writes a file, so a truthy spelling of off would leave one behind. |
Returns. Dict containing status and detailed camera operation results
lerobot_teleoperate¶
Advanced LeRobot teleoperation tool with recording capabilities for robot training data collection.
strands_robots.tools.lerobot_teleoperate
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
'start' |
Action to perform (start, stop, list, status, replay) |
session_name |
str | None |
None |
Session identifier (auto-generated for start, required for stop/status) |
background |
bool |
True |
Run session in background with logging (default: True). Must be a boolean: it selects an execution posture rather than scaling a quantity, so a truthy spelling of off such as "false" is refused rather than detaching the session it reads as declining to detach. |
robot_type |
str |
'so101_follower' |
Robot type identifier |
robot_port |
str | None |
'/dev/ttyACM0' |
Serial port for single-arm robots |
robot_id |
str | None |
None |
Robot instance identifier |
robot_cameras |
dict[str, Any] | None |
None |
Camera configuration dictionary (see Camera Configuration Format above for the options and their domains) |
robot_left_arm_port |
str | None |
None |
Left arm port for bimanual robots |
robot_right_arm_port |
str | None |
None |
Right arm port for bimanual robots |
teleop_type |
str | None |
'so101_leader' |
Teleoperator type identifier |
teleop_port |
str | None |
'/dev/ttyACM1' |
Serial port for single-arm teleoperators |
teleop_id |
str | None |
None |
Teleoperator instance identifier |
teleop_left_arm_port |
str | None |
None |
Left arm port for bimanual teleoperators |
teleop_right_arm_port |
str | None |
None |
Right arm port for bimanual teleoperators |
dataset_repo_id |
str | None |
None |
HuggingFace dataset repository ID (enables recording mode) |
dataset_single_task |
str | None |
None |
Task description for recordings |
dataset_num_episodes |
int |
50 |
Number of episodes to record |
dataset_fps |
int |
30 |
Recording frame rate |
dataset_episode_time_s |
int |
60 |
Episode duration in seconds |
dataset_reset_time_s |
int |
60 |
Reset time between episodes |
dataset_root |
str | None |
None |
Local dataset storage directory. When omitted for a recording, an explicit root is still pinned (resolved from dataset_repo_id under $HF_LEROBOT_HOME) and returned as dataset_root in the result. lerobot HEAD stamps a fresh record's repo_id with a _YYYYMMDD_HHMMSS timestamp (affecting the Hub push target and dataset metadata); pinning the root keeps the on-disk data at the requested location regardless, so downstream train/verify steps find it. Use record_resume=True to append instead. |
dataset_video |
bool |
True |
Enable video encoding |
dataset_push_to_hub |
bool |
False |
Upload dataset to HuggingFace Hub |
record_resume |
bool |
False |
Append to an existing dataset at the resolved root (lerobot-record --resume true) instead of creating a fresh one. Resume preserves the existing (already-stamped) repo_id rather than re-stamping, so repeated sessions accumulate in one dataset. |
replay_episode |
int |
0 |
Episode number to replay |
display_data |
bool |
False |
Show live camera feeds and telemetry |
fps |
int |
60 |
Teleoperation control loop frequency |
teleop_time_s |
float | None |
None |
Session duration limit |
play_sounds |
bool |
True |
Enable lerobot's spoken event announcements ("Recording episode 3", "Stop recording"). Effective for recording, replay and dagger; plain teleoperation emits no audio and ignores it. Must be a boolean - a string such as "false" is refused rather than read by truthiness, since every non-empty string is truthy. |
auto_accept_calibration |
bool |
True |
Answer the calibration prompt on the session's behalf, by writing two newlines into the process's stdin shortly after it starts. Withhold it (False) to answer the prompt yourself; nothing reports that stdin was written to, so an unintended acceptance is not visible afterwards. A write that fails is reported at WARNING, since by then the start result has already told the caller the session started. Must be a boolean, on the same reasoning as background. |
policy_path |
str | None |
None |
Checkpoint the dagger action rolls out autonomously between human takeovers. Required for dagger; ignored by every other action. |
dagger_record_autonomous |
bool |
False |
Record the autonomous rollout episodes into the corrections dataset as well, rather than only the teleoperated takeovers. Must be a boolean; a truthy spelling of off would otherwise land autonomous episodes in a corrections dataset. |
dagger_input_device |
str |
'keyboard' |
How the operator seizes control during a dagger rollout - "keyboard" (default) or "pedal". Any other value is refused. |
dagger_num_episodes |
int | None |
None |
Cap on the corrections collected in one dagger session. A positive whole number, or None for no cap. |
Returns. Dict with operation status and results: { "status": "success|error", "content": [{"text": "Description of operation"}], "session_name": "session_id", # for start action "pid": 12345, # process ID for background sessions "command": "full_command_executed", "log_file": "/tmp/session.log", # for background sessions "sessions": {...}, # for list action "uptime": 123.45, # session uptime in seconds; None when the # record states no usable start time "is_running": true # for status action }
lerobot_train¶
Fine-tune a LeRobot policy on a local dataset by wrapping lerobot-train.
Takes the agent's tool context (@tool(context=True)) - the seam it prompts an operator through.
strands_robots.tools.lerobot_train
| Parameter | Type | Default | Description |
|---|---|---|---|
dataset_root |
str | None |
None |
Local LeRobot v3 dataset directory (must contain meta/info.json). Read by start only, which refuses to launch without it; status, stop and list look a session up by name and never read it. |
policy_type |
str |
'act' |
Policy architecture (act, diffusion, vqbet, tdmpc, smolvla, pi0, pi05, pi0_fast, groot, xvla, ...). |
pretrained_path |
str | None |
None |
HF id or local path to initialize weights from (gated checkpoints need HF_TOKEN in the environment). |
output_dir |
str | None |
None |
Where to write run outputs; defaults to <dataset_root>/../train_out/<job_name>. |
job_name |
str |
'strands_ft' |
Run name used in the default output_dir and lerobot logs. |
steps |
int |
20000 |
Number of training steps. |
batch_size |
int |
8 |
Training batch size. |
save_freq |
int |
5000 |
Checkpoint save frequency in steps. A whole number; a non-positive value disables periodic saving (only the final checkpoint is written), and a fractional, non-finite, boolean or non-numeric cadence is refused before the run starts because lerobot decodes the flag into an int field. |
device |
str |
'cuda' |
Torch device type, optionally with an index (cuda, cuda:0, cpu, mps). Refused before launch if torch cannot parse it; only the spelling is graded, so naming a device this machine does not have is allowed. |
dtype |
str | None |
None |
Policy dtype (bfloat16, float32) for policies whose lerobot config declares a dtype field (e.g. the pi0 family, xvla). Default None lets lerobot pick; ACT and most policies have no dtype field, and passing dtype= for them raises before launch. |
gradient_checkpointing |
bool |
False |
Trade compute for memory on supported policies. |
lora |
bool |
False |
Enable LoRA/PEFT fine-tuning (full-VLM fit on one GPU). |
lora_r |
int | None |
None |
LoRA rank. |
lora_alpha |
int | None |
None |
LoRA alpha (scaling = lora_alpha / r). |
lora_target_modules |
str | None |
None |
PEFT target module spec (e.g. "all-linear"). |
train_expert_only |
bool |
False |
Freeze the VLM, train only the action expert (policies exposing train_expert_only: pi0/pi05/smolvla). |
val_episodes |
int | None |
None |
A positive integer below the dataset's episode count, or None for no held-out set. Reserves the LAST N episodes as a held-out validation split, evaluated every save_freq steps so each checkpoint has a validation loss beside it. |
num_gpus |
int |
1 |
Number of GPUs; >1 launches via accelerate --multi_gpu. |
push_to_hub |
bool |
False |
Push the trained checkpoint to the HF Hub at the end. Publishing is an outward-facing action, so a true value requires operator approval through tool_context. A headless run pre-approves it with STRANDS_TRAIN_EXTRA_FLAGS_ALLOW=policy.push_to_hub: this parameter is gated under the policy.-prefixed key, the only spelling LeRobot accepts (push_to_hub is a field of its policy config, not of the train config). The bare push_to_hub allowlist entry clears the raw extra_flags={'push_to_hub': True} passthrough instead -- one flag, two spellings, two entries. The default false value emits the flag unchanged and is not gated. |
resume |
bool |
False |
Resume from the latest checkpoint under output_dir when present. |
action |
str |
'start' |
One of start, status, stop, list. |
session_name |
str | None |
None |
Session identifier (auto-generated on start; required for status/stop). |
extra_flags |
dict[str, Any] | None |
None |
Passthrough dict of additional lerobot-train flags, e.g. {"policy.optimizer_lr": 1e-4} -> --policy.optimizer_lr=0.0001. A key that abbreviates a gated flag is gated as that flag, because the trainer's parser honors unambiguous prefixes: {"ou": "/x"} reaches output_dir, so it needs the same approval, and the same STRANDS_TRAIN_EXTRA_FLAGS_ALLOW=output_dir entry clears it. |
Returns. Dict with status ("success" or "error") and a content list of {"text": ...} items, plus action-specific keys (session_name, pid, command, log_file, output_dir, sessions, is_running, uptime). uptime is seconds, and is None when the session record states no usable start time - see strands_robots.tools._process_stop.session_uptime, which is what the reported Uptime field says instead.
load_episode¶
Describe one recorded episode: length, features, and label state.
strands_robots.tools.episode_judge
| Parameter | Type | Default | Description |
|---|---|---|---|
root |
str |
required | Dataset root directory (the directory containing meta/). |
episode |
int |
required | Episode index to describe, a non-negative whole number. |
Returns. Structured result whose JSON payload carries episode, length (frame count), total_episodes, fps, camera_keys, state_names, has_deterministic_verdict and has_judge_label.
pose_tool¶
Advanced robot pose management tool with fine motor control.
Takes the agent's tool context (@tool(context=True)) - the seam it prompts an operator through.
strands_robots.tools.pose_tool
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | Action to perform |
robot_id |
str |
'so101_follower' |
Robot identifier for pose storage. Becomes part of the pose file's name, so a value resolving outside the storage directory is refused rather than written there. |
port |
str | None |
'/dev/ttyACM0' |
Serial port for robot communication |
calibration |
str | None |
None |
Path of the calibration JSON lerobot-calibrate wrote for this arm, e.g. what strands_robots.drivers.feetech.bus.lerobot_calibration_path returns. Unset reads and commands the servo's full rotation. |
pose_name |
str | None |
None |
Name for pose operations |
motor_name |
str | None |
None |
Motor name for single motor operations |
position |
float | None |
None |
Target position in degrees (or 0-100% for gripper). A finite number within the motor's measured travel - a value outside it is refused rather than clamped to the mechanical limit, because the clamp cannot be told apart from a typo and the success text echoes the value asked for. |
delta |
float | None |
None |
Incremental movement in degrees. A finite number whose magnitude is at most the motor's full travel, which no starting position could exceed. |
positions |
dict[str, float] | None |
None |
Dictionary of motor positions {motor_name: degrees}. Every value is held to the same domain as position, and the first that is not names the motor it came from. |
description |
str | None |
None |
Description for stored poses |
smooth |
bool |
True |
Interpolate towards the targets over steps * step_delay seconds instead of writing each goal position once. A boolean: it selects one of two trajectories, so a value that is only truthy or only falsy is refused rather than read as one of them - smooth=0 would drop the interpolation this defaults to, and smooth="false" would keep it. Read only by load_pose and move_multiple. |
steps |
int |
20 |
Number of increments for an interpolated move. A positive integer - it divides the travel and bounds the write loop. |
step_delay |
float |
0.05 |
Seconds between increments of an interpolated move. A positive finite number - this pause is what makes the move smooth, so 0 is refused; use smooth=False to go straight to the target. Together with steps it sets the trajectory duration (the default 20 x 0.05s = ~1s). |
Returns. Dict containing status and response content, or an error dict when an interpolation option or a joint target the requested action reads cannot be honored.
read_predicate_verdict¶
Read the authoritative deterministic predicate verdict for an episode.
strands_robots.tools.episode_judge
| Parameter | Type | Default | Description |
|---|---|---|---|
root |
str |
required | Dataset root directory (the directory containing meta/). |
episode |
int |
required | Episode index, a non-negative whole number. |
Returns. Structured result whose JSON payload is the episode's deterministic block (success / failure and, when present, steps / cumulative_reward / seed).
robot_mesh¶
Coordinate every robot, sim, and agent on the local Zenoh mesh.
Takes the agent's tool context (@tool(context=True)) - the seam it prompts an operator through.
strands_robots.tools.robot_mesh
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | One of peers / status / tell / send / rpc / broadcast / stop / emergency_stop / subscribe / unsubscribe / watch / inbox. rpc calls a device's NATIVE Device Connect function (e.g. the Reachy's nod / look / playMove) directly, bypassing the policy-action allowlist that tell / send enforce. Pass the function name in function and any kwargs as a JSON object in command. |
target |
str |
'' |
Peer id (for tell / send / stop / watch) or Zenoh topic pattern (for subscribe). |
instruction |
str |
'' |
Natural-language instruction for tell. |
command |
str |
'' |
JSON-encoded command body for send / broadcast. |
policy_provider |
str |
'mock' |
Policy provider tag forwarded with tell. |
policy_port |
int |
0 |
Optional policy port forwarded with tell. |
duration |
float |
30.0 |
Task duration (seconds) forwarded with tell. |
timeout |
float |
30.0 |
Response timeout for RPC actions (seconds). A positive finite number; read by tell / send / rpc / broadcast / stop and ignored by the rest. stop additionally caps it at 5s. Zero or negative would report {"status": "timeout"} without waiting at all, so an unusable value is refused rather than reported as a peer that did not answer. |
name |
str |
'' |
Optional subscription name for subscribe / inbox. |
limit |
int |
50 |
Max messages returned by inbox (default: 50). A positive integer; read by inbox only. |
function |
str |
'' |
Device-native function name for rpc (e.g. nod). |
Returns. A Strands tool response dict with status and a single text block. Examples:: robot_mesh(action="peers") robot_mesh(action="tell", target="so100_sim-a1b2", instruction="pick up the cube") robot_mesh(action="send", target="peer-b", command='{"action": "status"}') robot_mesh(action="emergency_stop") # raises a HITL interrupt; # runs only on operator approval
run_policy¶
Roll out a policy for n_episodes x n_steps with per-episode parquet boundaries.
strands_robots.tools.run_policy
| Parameter | Type | Default | Description |
|---|---|---|---|
simulation |
Any |
required | Live Simulation (or compatible) handle. Constructed by the orchestrator - pass through a Python partial / closure, not from agent text. LLMs cannot synthesize this argument, which is the point: the episode loop runs in deterministic Python. |
robot_name |
str | None |
None |
Robot to control. Forwarded to run_policy. Required when the simulation hosts more than one robot. |
policy_provider |
str |
'mock' |
Provider name passed to create_policy inside the engine ("mock" / "lerobot_local" / "groot" / "molmoact2" / ...). |
policy_config |
dict[str, Any] | None |
None |
Provider-specific kwargs forwarded verbatim. |
instruction |
str |
'' |
Natural-language instruction for the policy. |
n_episodes |
int |
1 |
Number of reset -> rollout episodes. MUST be a positive int. There is no "guess from duration" fallback. |
n_steps |
int |
60 |
Hard cap on control steps per episode. Forwarded to run_policy as n_steps. |
control_frequency |
float |
30.0 |
Target Hz for policy queries. Must be a finite number > 0; an unusable rate is reported before the rollout starts instead of aborting every episode mid-flight. When a recording is requested it must also EQUAL dataset_fps - see that parameter. |
action_horizon |
int |
8 |
Lower bound on actions consumed per policy call before re-querying; the effective interval is max(action_horizon, policy.execution_horizon), so a chunk-emitting policy always consumes its full chunk and a smaller value has no effect (see resolve_chunk_length). Must be a positive integer, reported before the rollout starts for the same reason. |
fast_mode |
bool |
True |
Skip real-time sleep between steps (default True for rollouts - wall-clock pacing slows headless eval). Must be a boolean; it selects a posture rather than scaling a quantity, so any other type is reported before the rollout starts rather than read by truthiness - a truthy "false" would otherwise run the episodes unpaced. |
dataset_root |
str | None |
None |
When set, the tool drives the full recording cycle: start_recording(root=dataset_root, ...) -> N rollouts with per-episode save_episode -> stop_recording -> parquet-truth read. When None the loop runs without recording (smoke-test mode). |
dataset_repo_id |
str |
'local/run_policy_rollout' |
Forwarded to start_recording. |
dataset_task |
str |
'' |
Task label forwarded to start_recording. |
dataset_fps |
int |
30 |
Dataset FPS forwarded to start_recording. Must be a positive whole number - reported by start_recording itself, which checks the rate before it touches the target directory, so an unusable value costs nothing. It must also EQUAL control_frequency whenever dataset_root is set: the recorder captures one frame per control step and never decimates, while LeRobot timestamps every frame from the declared rate, so a differing pair cannot be honored, only mislabelled. The disagreement is refused up front (strands_robots.simulation.recording.requested_rate_mismatch_reason) rather than by the per-episode rollout - which this tool reaches only after start_recording(overwrite=True) has replaced any dataset already at dataset_root with an empty one. Ignored entirely when dataset_root is None. |
dataset_cameras |
list[str] | None |
None |
Camera names to record into the dataset. When set, forwarded as start_recording(cameras=...) (supported by both the MuJoCo and Newton backends) to scope a policy-specific dataset to exactly the views the policy declares (e.g. ["camera1", "camera2", "camera3"]) and keep the implicit default free camera out of observation.images.*. When None (default) no cameras kwarg is forwarded at all, so every scene camera is recorded and the call stays backend-agnostic across the MuJoCo and Newton engines. |
seed |
int | None |
None |
Master RNG seed. Each episode derives a deterministic offset so rollouts are reproducible within a process. |
policy_kwargs |
dict[str, Any] | None |
None |
Optional per-call goal payload forwarded to every policy.get_actions call (the #300 goal keys). |
video |
dict[str, Any] | None |
None |
Optional rollout-video config forwarded to Simulation.run_policy (e.g. {"path": "/tmp/rollout.mp4", "fps": 30, "camera": "camera1", "width": 640, "height": 480}). path is required to enable recording; a falsy/absent path disables it. For n_episodes > 1 an _ep<i> suffix is inserted into the path stem so each episode writes its own MP4 instead of overwriting. The returned payload carries video_paths (the MP4s that landed on disk). |
stop_when |
dict[str, Any] | None |
None |
Optional semantic early-return clause forwarded to every per-episode Simulation.run_policy call: the episode ends as soon as the condition holds in the sim, instead of only at the n_steps budget - a per-episode success gate for collection loops. Same predicate DSL as a benchmark spec's success clause: a single call {"predicate": "grasped", "body": "cube", "gripper_prefix": "so100"} or an {"all": [...]} / {"any": [...]} group. Validated against the closed predicate registry up front (before any recording is started), so an unknown predicate name is rejected with the valid list while nothing has been set up yet. Each rollout's stopped_reason ('predicate' | 'budget' | 'cancelled' | 'error') is reported per episode, as is stop_when_true_at_reset: a clause the scene's initial state already satisfies is evaluated only AFTER an applied action, so it fires on the episode's first step whatever the policy commands - one recorded frame for that episode, tagged stopped_reason='predicate' and indistinguishable from an episode that reached the condition. Usually a threshold on the wrong side of the initial state (a body_above_z below where the object already rests). The payload aggregates episodes_stop_when_true_at_reset with stop_when_reset_warning; it is deliberately not a warnings entry, which would flip status to "error", because domain randomisation legitimately satisfies a clause on some draws. |
Returns. Standard {status, content} payload. On success the payload also carries:: { "n_episodes_requested": int, "n_episodes_actual": int, # parquet-truth, -1 if unread "n_frames_actual": int, # parquet-truth, -1 if unread "dataset_root": str | None, "recording_save_error": str | None, # None on a healthy run "warnings": [str, ...], # mismatch flags "episodes_stop_when_true_at_reset": int, "stop_when_reset_warning": str | None, "episodes": [ {"index": int, "status": "success" | "error", ...}, ... ], }
sample_frames¶
Sample evenly spaced frames from one episode for the judge to inspect.
strands_robots.tools.episode_judge
| Parameter | Type | Default | Description |
|---|---|---|---|
root |
str |
required | Dataset root directory (the directory containing meta/). |
episode |
int |
required | Episode index to sample, a non-negative whole number. |
n_frames |
int |
4 |
How many evenly spaced frames to sample, a positive count. Clamped to the episode length. |
include_images |
bool |
False |
When True, decode the camera frames at the sampled positions into PNG image blocks (requires the lerobot extra; a dataset recorded without cameras reports an error). Must be a boolean - a posture flag is checked, never read by truthiness. |
Returns. Structured result whose JSON payload carries episode, length, samples (frame_index / timestamp / state per sample), max_state_delta and rms_state_jerk (state units per second cubed when timestamps are present, per step cubed otherwise; null when the episode is shorter than four frames). When images are requested, one image block follows per camera per sampled position - position-major, cameras in sorted key order within each position (the same order load_episode reports camera_keys) - the leading text block states the block count and that grouping, and every image block is immediately preceded by a text block naming its camera and its frame_index, so a judge reading a run of n_frames x n_cameras images can say which view a per-view observation belongs to and join that view back onto the state row for the same frame in samples. The label is adjacent to its image because that is what binds: the grouping sentence alone is a rule the judge must apply, and a rule stated at a distance from the images does not survive the flat run (measured on a three-camera recording with one view fully blocked, naming the blind camera scored 22/40 from the grouping sentence alone, 17/40 from the full block map spelled out in one text block, and 40/40 from these per-block labels, against 30/30 on the same frames asked one at a time). Every camera is deliberately included rather than one canonical view: the same world motion can be legible in one view and below a judge's threshold in another (measured on a real two-camera recording, where a 185 mm slide read as 84 px of travel in one view and 22 px in the other), so sampling a single camera would drop verdicts.
serial_tool¶
Advanced serial communication tool for robot control and device communication.
Takes the agent's tool context (@tool(context=True)) - the seam it prompts an operator through.
strands_robots.tools.serial_tool
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | Action to perform |
port |
str | None |
None |
Serial port path (e.g., "/dev/ttyACM0", "COM3") |
baudrate |
int |
9600 |
Communication speed in baud; a positive integer (default: 9600) |
timeout |
float |
1.0 |
Read timeout in seconds; a finite number >= 0, where 0 is pyserial's non-blocking mode (return what is already buffered) |
data |
str | None |
None |
String data to send |
hex_data |
str | None |
None |
Hex string data to send (e.g., "FF FF 01 04 03 00 64 92") |
motor_id |
int | None |
None |
Motor ID for Feetech commands; an integer in [1, 254], of which 254 (0xfe) is the broadcast every servo receives. An action that reads a reply back accepts only a single servo, [1, 253] |
position |
int | None |
None |
Target position for STS/SMS-series motors; an integer in [0, 4095]. That full scale and the two-byte order this tool encodes into are both STS/SMS properties: the SCS series is 10-bit and reads the same two bytes in the opposite order, so an SCS-series servo is not addressed by this action at all |
velocity |
int | None |
None |
Target velocity for STS/SMS-series motors; an integer in [0, 32767]. Goal_Velocity is sign-magnitude on that series, so a magnitude reaching bit 15 commands the opposite direction instead of a faster move |
read_bytes |
int |
1024 |
Number of bytes to read; a positive integer |
Returns. Dict containing status and response content
train_policy¶
Post-tune (fine-tune) a robot policy on a recorded LeRobotDataset.
strands_robots.tools.train_policy
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
'train' |
One of: - "train" : validate + launch training (default). - "validate" : pure preflight only; report problems, launch nothing. - "status" : "RUNNING != learning" verdict for a job (needs job_id). - "export" : produce a loadable artifact from a checkpoint (needs output_dir; uses the run's last checkpoint). - "list" : list available training providers. |
provider |
str |
'lerobot_local' |
Training backend / policy family - "lerobot_local" (act, diffusion, smolvla, pi0, pi05, ...), "groot" (NVIDIA GR00T), "cosmos3" (NVIDIA Cosmos3), or "mock". Same name as the inference provider in create_policy. |
dataset_root |
str | None |
None |
Path to a LeRobotDataset v3 root (has meta/info.json) - exactly what Robot.stop_recording writes. Optional when dataset_repo_id is set (then it is the local cache root). |
dataset_repo_id |
str | None |
None |
Hugging Face Hub dataset id (org/name) to train from the Hub instead of a local root - required to streaming a large (50-500 GB) Hub dataset without downloading it in full. lerobot only. |
streaming |
bool |
False |
Stream frames instead of materializing the dataset (lerobot StreamingLeRobotDataset). With dataset_repo_id this streams Hub shards with bounded disk; with a local dataset_root it streams from disk with bounded RAM. lerobot only; ignored elsewhere. |
base_model |
str |
'' |
HF id or local checkpoint to post-tune from. For GR00T this is required (--base_model_path); ACT-from-scratch leaves it "". |
output_dir |
str | None |
None |
Where checkpoints + logs go. |
embodiment |
str | None |
None |
Embodiment tag - which state/action projector head the run trains. REQUIRED for GR00T, and read by any lerobot policy whose config declares embodiment_tag (lerobot's native GR00T port); refused for a lerobot policy that has no such field, since those take their state/action shape from the dataset features. |
steps |
int |
10000 |
Total optimizer steps. |
batch_size |
int |
32 |
Global batch size (summed across GPUs). |
learning_rate |
float | None |
None |
Optimizer learning rate. None (default) uses the backend's own default (the policy training preset for lerobot, GR00T's FinetuneConfig default, Cosmos's TOML default); an explicit value must be a positive finite number and is honored by every backend. 0 and inf are refused up front: the first trains for the whole run without updating a weight, the second writes a checkpoint of NaN, and no backend reports either. |
save_freq |
int |
1000 |
Checkpoint cadence in steps. |
num_gpus |
int |
1 |
GPUs on this node (>1 -> accelerate/torchrun multi-GPU). A positive integer; anything else is refused by preflight. |
num_nodes |
int |
1 |
Nodes (Cosmos HSDP / torchrun --nnodes). A positive integer; anything else is refused by preflight. |
resume |
bool |
False |
Resume from the latest checkpoint under output_dir. |
seed |
int | None |
None |
Master seed. |
method |
str |
'full' |
Tuning strategy - "full" | "lora" | "expert_only" | "frozen_backbone". lora and expert_only are mutually exclusive. |
lora_r |
int | None |
None |
LoRA adapter rank, read only when method="lora". A positive integer, or None to keep peft's default. It is the denominator of the lora_alpha / lora_r scaling, so anything else is refused by preflight. |
lora_alpha |
int | None |
None |
Numerator of the LoRA lora_alpha / lora_r scaling, read only when method="lora". A positive integer, or None to keep peft's default. Zero trains an adapter whose scaling is 0.0 and which therefore cannot change the model, so it is refused rather than run. |
lora_target_modules |
str | None |
None |
Comma-separated module names the LoRA adapters are attached to, read only when method="lora". Omit to keep the backend's default target set. |
tune |
dict[str, bool] | None |
None |
Fine-grained component toggles for GR00T ({"llm","visual","projector","diffusion"}), honoured by the groot provider and by lerobot_local with extra={"policy_type": "groot"}. A key naming no component (vision for visual) or a component the policy cannot freeze is refused by preflight, because an unforwarded toggle trains the config default and reports success. |
val_episodes |
int | None |
None |
Hold out the LAST N episodes for validation; the run logs an eval loss over them at the checkpoint cadence. A positive integer below the dataset's episode count, or None for no held-out set - the split is a fraction lerobot takes the ceiling of, so a fractional count would reserve a different number of episodes. The count is read from the dataset's local meta/info.json, so a Hub source (dataset_repo_id with no populated dataset_root) is refused with the two ways to get a split instead of being launched without one. |
augmentation |
dict[str, Any] | None |
None |
Backend-specific augmentation dict. |
fps |
int | None |
None |
Dataset control rate (when a backend needs it). |
extra |
dict[str, Any] | None |
None |
Backend-specific passthrough. lerobot: policy_type, job_name, any --key=value. GR00T: groot_root, modality_config_path. Cosmos: cosmos_root, sft_toml. |
job_id |
str | None |
None |
Job identifier for action="status". |
Returns. Canonical Strands result {status, content:[...]} (no sibling keys). For train/status/export the structured fields (job_id, checkpoint_dir, exported_model, metrics) are in a {"json": ...} block inside content, alongside a human-readable {"text": ...} block. Dependencies (per provider - the base [lerobot] extra is not always enough): - lerobot_local + ACT/diffusion: pip install 'strands-robots[lerobot]'. - lerobot_local + smolvla/pi0/pi05: add lerobot's [smolvla]/[pi] extra on top of strands-robots[lerobot] (which pins lerobot>=0.6.0). Those extras layer transformers>=5.4.0,<5.6.0 (plus num2words / scipy); do NOT pin transformers==5.3.0 - it conflicts with lerobot 0.6's transformers floor. - groot/cosmos3: install the upstream package into THIS interpreter (the trainer imports it and calls its library functions in-process - no subprocess). Point extra['groot_root']/GR00T_ROOT or extra['cosmos_root']/COSMOS_ROOT at the checkout for runtime config/recipe resolution. - torchcodec's .so must match the installed torch build exactly; a torch nightly load-fails a stable torchcodec (undefined symbol) and lerobot silently yields zero frames. See docs/training/overview.md.
use_lerobot¶
Universal LeRobot access - call any lerobot module, class, or function dynamically.
strands_robots.tools.use_lerobot
| Parameter | Type | Default | Description |
|---|---|---|---|
module |
str |
'discovery' |
Dotted path into lerobot (e.g. "cameras.opencv.OpenCVCamera", "datasets.lerobot_dataset.LeRobotDataset", "policies.factory"). Special values: "discovery" - explore modules + all registered configs. "registry" - list a single registry; pass its name as method (robots|teleoperators|cameras|policies). |
method |
str |
'list_modules' |
Method/function/attribute name to call or read. Special values: "list_modules" - discovery output (with module="discovery"). "describe" - inspect the object without calling it. |
parameters |
dict[str, Any] | None |
None |
Dict of kwargs to pass to the method. Omit for no-arg calls. |
label |
str |
'' |
Human-readable description of what this call does. |
Returns. Dict with status and content; content may include text + image blocks.
use_ros¶
Universal ROS 2 tool - in-process rclpy, dynamic types, no shelling out.
Takes the agent's tool context (@tool(context=True)) - the seam it prompts an operator through.
strands_robots.tools.use_ros
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | One of status, list_topics, list_nodes, list_services, list_actions, info, echo, publish, service_call, action_send_goal. |
topic |
str | None |
None |
Topic name (echo, publish, info). |
service |
str | None |
None |
Service name (service_call, info). |
action_name |
str | None |
None |
Action server name (action_send_goal), e.g. /navigate_to_pose. |
type |
str | None |
None |
Fully-qualified interface type, e.g. geometry_msgs/msg/Twist, turtlesim/srv/Spawn, or nav2_msgs/action/NavigateToPose. Auto-resolved for echo when omitted. |
fields |
dict[str, Any] | None |
None |
JSON field dict applied with set_message_fields (publish, service_call, action_send_goal). Booleans and nulls are preserved - the dict is passed straight to rclpy, never serialised through source. |
timeout |
float |
5.0 |
Seconds to wait for samples / a service / an action result. For action_send_goal this is the end-to-end budget (discovery + acceptance + execution); size it to the goal (e.g. 120 for a Nav2 navigation), and note the goal is cancelled when it expires. A positive finite number of seconds. |
count |
int |
1 |
Number of messages to echo or publish. A positive integer; it is consumed as a range() bound, so 0 publishes nothing and a float or a numeric string cannot be honored. |
rate |
float |
10.0 |
Publish rate in Hz. A positive finite number - the inter-message period is 1 / rate, so 0, a negative value, nan and inf all leave the burst unthrottled rather than paced. |
Returns. A Strands tool result dict {"status": ..., "content": [{"text": ...}]}.
use_rosbridge¶
Universal rosbridge tool - ROS over a WebSocket, no ROS install needed.
Takes the agent's tool context (@tool(context=True)) - the seam it prompts an operator through.
strands_robots.tools.use_rosbridge
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | One of status, list_topics, list_services, echo, publish, service_call. |
host |
str |
'localhost' |
rosbridge server hostname or IP. Held to the shared domain every dialled host in this package shares, then to this transport's own narrower allowlist. |
port |
int |
9090 |
rosbridge WebSocket port (default 9090). |
topic |
str | None |
None |
Topic name (echo, publish). Held to the same name rule as service. |
service |
str | None |
None |
Service name (service_call). Held to the same name rule as topic. |
type |
str | None |
None |
ROS1 two-segment interface type, e.g. geometry_msgs/Twist. Required for publish - a message cannot be built without it - and auto-resolved for echo when omitted. |
fields |
dict[str, Any] | None |
None |
JSON field dict (publish message / service_call request). |
timeout |
float |
5.0 |
Seconds for the WebSocket dial, sample collection, or a service call. A positive finite number of seconds; every action dials the bridge, so every action reads it. |
count |
int |
1 |
Messages to echo or publish. A positive integer; it is consumed as a range() bound, so 0 publishes nothing and a float or a numeric string cannot be honored. |
rate |
float |
10.0 |
Publish rate in Hz. A positive finite number - the inter-message period is 1 / rate, so 0, a negative value, nan and inf all leave the burst unthrottled rather than paced. |
Returns. A Strands tool result dict {"status": ..., "content": [{"text": ...}]}.
use_rtps¶
Pure-RTPS ROS 2 participant tool - no rclpy, all ROS 2 distros.
Takes the agent's tool context (@tool(context=True)) - the seam it prompts an operator through.
strands_robots.tools.use_rtps
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | One of status, types, advertise, publish, subscribe, echo. |
topic |
str | None |
None |
ROS 2 topic name, absolute (e.g. /turtle1/cmd_vel). |
type |
str | None |
None |
ROS 2 interface type in the IDL bundle (e.g. geometry_msgs/msg/Twist). List with action="types". |
fields |
dict[str, Any] | None |
None |
JSON field dict for publish; nested message fields are built recursively. Booleans and nulls are preserved (plain Python values). |
timeout |
float |
5.0 |
Seconds to wait for samples (echo). A positive finite number. |
count |
int |
1 |
Number of messages to publish or samples to echo. A positive integer; it is consumed as a range() bound, so 0 publishes nothing and a float or a numeric string cannot be honored. |
rate |
float |
10.0 |
Publish rate in Hz. A positive finite number - the inter-message period is 1 / rate, so 0, a negative value, nan and inf all leave the burst unthrottled rather than paced. |
Returns. A Strands tool result dict {"status": ..., "content": [{"text": ...}]}.
write_label¶
Write the judge's annotation for an episode into the label sidecar.
strands_robots.tools.episode_judge
| Parameter | Type | Default | Description |
|---|---|---|---|
root |
str |
required | Dataset root directory (the directory containing meta/). |
episode |
int |
required | Episode index to label, a non-negative whole number. |
quality |
str |
required | Quality grade, one of low / medium / high. Grades the execution visible in the recording (smoothness, directness, control), not the outcome - the deterministic verdict already carries success/failure, so a clean failure can be medium or high and a jerky or lucky success can be low. |
failure_mode |
str | None |
None |
Optional tag from the fixed taxonomy (jerky_motion, near_miss, camera_occlusion, wrong_but_lucky, drift, collision, incomplete, other). Legal on a successful episode too - near_miss and wrong_but_lucky are exactly the annotations that make a success worth excluding from training data. |
note |
str |
'' |
Short free-text observation backing the grade and tag. |
success_opinion |
bool | None |
None |
The judge's own success read, or omit to offer none. Disagreement with the deterministic verdict is recorded as a dispute annotation, never applied. |
judge_model |
str |
'' |
Identifier of the labeling model (or "human"), stored for provenance and calibration. |
Returns. Structured result whose JSON payload is the updated episode record (episode_index / deterministic / judge).
Unitree G1¶
The humanoid's DDS surface: locomotion FSM, arm actions, task control and every sensor read.
g1_arm_action, g1_arm_action_admits, g1_balance_stand, g1_battery, g1_decode_error_code, g1_fsm_admits, g1_get_state, g1_get_task_status, g1_imu, g1_joint_index, g1_joint_name, g1_joint_reference, g1_lidar_state, g1_lidar_summary, g1_list_arm_actions, g1_list_error_codes, g1_list_motion_gates, g1_mainboard, g1_move_velocity, g1_pressure, g1_release_arm, g1_run_policy, g1_safe_lie_to_stand, g1_safe_squat_to_stand, g1_safe_stand_to_squat, g1_send_action, g1_set_fsm, g1_set_stand_height, g1_set_swing_height, g1_shake_hand_loco, g1_start_task, g1_stop_move, g1_stop_task, g1_wave_hand_loco, use_unitree
g1_arm_action¶
Execute one built-in G1 arm gesture (clap, heart, shake hand, ...).
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
action |
str |
'' |
A gesture name like 'clap' or 'heart' - the full name-to-id map is on strands_robots.tools.g1.g1_arm_actions.g1_list_arm_actions. |
action_id |
int | None |
None |
The SDK's numeric id (like 17 or 20), an alternative to action. Pass one of the two. |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_arm_action_admits¶
Decide whether a given arm-action name or id is inside the SDK's admission set.
strands_robots.tools.g1.g1_arm_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
'' |
The arm-action name to test. Case-sensitive to match the SDK's own dict keys (the SDK does not lower-case its lookup, so a caller writing "Two-Hand Kiss" gets a key-not-found on the wire; this lookup mirrors that). Empty string means "no name supplied". |
action_id |
int | None |
None |
The arm-action id to test. Must be an int; bool is refused (True is int(1) but a dict-key typo of True for an action id is a caller mistake, not a valid gate query). |
Returns. A dict with status ("success" on any decidable answer, "error" on the both-supplied / neither-supplied ambiguity), a query sub-dict carrying whichever of action / action_id was supplied, an admitted boolean naming whether the SDK's ExecuteAction would admit the query, and (when admitted is True) the resolved action_name / action_id pair a future execute verb would forward to the SDK. On a not-admitted query the dict also carries refusal_code / refusal_text naming the rc=7402 refusal the SDK would return.
g1_balance_stand¶
Put the G1 into BalanceStand in the given balance mode.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
balance_mode |
int | None |
None |
Integer mode id; use_unitree's describe_operation documents the SDK side. |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_battery¶
Return the driver's cached rt/lf/bmsstate snapshot.
strands_robots.tools.g1.g1_battery
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a _snapshot(attr: str) method returning the cached sensor dict (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. The verb is duck-typed on _snapshot; any object with that method answering "_battery" and returning the cache dict shape the driver's _on_bms writes will satisfy it. |
Returns. A dict with status, a present flag naming whether the driver has a cached reading yet, and the four fields _on_bms writes: pct (SOC percentage, float or None), current (pack current as BmsState_.current reports it, float or None), cycle (integer cycle count or None) and t (the wall time the reading was decoded at, seconds since epoch, float or None). There is no charging flag: BmsState_ declares no charge field, so reporting one would be a guess with the shape of a reading. On a driver whose subscriber has not received a BMS message yet the returned dict carries present=False and every field None - the verb does not fabricate a reading the driver does not have.
g1_decode_error_code¶
Decode one SDK return code against the catalogued name.
strands_robots.tools.g1.g1_error_codes
| Parameter | Type | Default | Description |
|---|---|---|---|
code |
int |
required | The integer rc the SDK returned. Must be an int; bool is refused (True is int(1) but a passed-through boolean is a caller mistake, not a valid decode query). A negative value is admitted decidably as unknown rather than refused: the catalogue carries no negative codes, but _common.decode_code already renders any integer, so refusing one here would make this verb narrower than the renderer whose text it quotes. A transport-level -1 is the convention for an SDK call that raised instead of returning a rc; this verb reports it as known=False without inventing text for it. |
Returns. A dict with status ("success" on any decidable answer, "error" on the type-mistake refusal), a query sub-dict carrying the supplied code, a known boolean naming whether the code appears in the snapshot, and (when known is True) the decoded text from the catalogue. On an unknown code the dict carries the unknown marker under text so the returned envelope always names something - a caller composing an error message off this call does not have to branch on a missing key.
g1_fsm_admits¶
Decide whether a given FSM id is inside G1Driver's admission set.
strands_robots.tools.g1.g1_motion_gates
| Parameter | Type | Default | Description |
|---|---|---|---|
fsm_id |
int |
required | The FSM id to test. Must be an int; bool is refused (True is int(1) but a dict-key typo of True for an FSM id is a caller mistake, not a valid gate query). |
scope |
str |
'arm' |
Which admission set to test. "arm" (default) tests HANDSHAKE_FSMS; "loco" tests WALK_FSMS. |
Returns. A dict with status, the requested scope, the tested fsm_id, an admitted boolean naming whether the write path would open, the fsm_ids list the answer was computed against, and (when admitted is False) the refusal_code and refusal_text the driver would surface. An unknown scope or a non-int fsm_id carries status="error".
g1_get_state¶
Return the driver's status plus the arm / loco gate membership answers.
strands_robots.tools.g1.g1_state
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with an async get_status method returning the driver's status envelope (in practice a strands_robots.drivers.g1.G1Driver). The driver may be connected or not; get_status reports which, and every field it does not have yet comes back None rather than raising. Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. |
Returns. A dict with status, the driver's tool_name and connected flag, its last-observed fsm_id / mode_machine / battery_pct, the motion-switcher diagnostics (fsm_mode_name / fsm_refusal / motion_switcher_open_error), two decided admits_arm / admits_loco booleans, and the handshake_fsms / walk_fsms id sets the answers were computed against (sorted, as lists) so a caller can quote them in its own voice. An fsm_id of None reports both admit booleans as False - the gate cannot open on a read that never arrived.
g1_get_task_status¶
Return the driver's control-loop task snapshot.
strands_robots.tools.g1.g1_task_status
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a synchronous get_task_status method returning the driver's task envelope (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. The verb is duck-typed on get_task_status; any object with that method returning the envelope shape the driver writes will satisfy it. |
Returns. A dict with status (the envelope's own status value, so a driver method that ever refuses on this path surfaces the refusal verbatim - today it does not; the driver returns status="success" on both shapes), a present flag naming whether the driver has ever started a loop (False only on the just-connected "no task has been started" shape), the loop's running flag, and the eight snapshot fields the driver's _ControlLoop.snapshot writes: steps (integer count of published frames), refusals (a list of per-step refusal records the re-gate accumulated), elapsed_s (float seconds since the loop started, or since it finished if it has), the two budgets the loop was started with (duration_budget_s / n_steps_budget, either float / int or None when open-ended), exit_reason (one of the five self-terminating reasons named in the module docstring, or None while running), exit_detail (a per-reason free-text field the loop's exit branch writes), hz (the loop's target publish rate, from strands_robots.drivers.g1._CONTROL_LOOP_HZ), and the two fields the FSM refresher writes (fsm_refresh_hz / fsm_reads, naming who fills the FSM cache the re-gate reads). On the "no task has been started" shape present is False and every snapshot field is None except running (which is False) and reason (which quotes the driver's own text verbatim).
g1_imu¶
Return the driver's cached rt/lowstate IMU snapshot.
strands_robots.tools.g1.g1_imu
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a _snapshot(attr: str) method returning the cached sensor dict (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. The verb is duck-typed on _snapshot; any object with that method answering "_imu" and returning the cache dict shape the driver's _on_lowstate writes will satisfy it. |
Returns. A dict with status, a present flag naming whether the driver has a cached reading yet, and the five fields _on_lowstate writes: rpy (roll/pitch/yaw as a three-element list[float] in radians, or None), gyroscope (three-element list[float] in rad/s, or None), accelerometer (three-element list[float] in m/s², or None), quaternion (four-element list[float] as [w, x, y, z], or None) and t (the wall time the reading was decoded at, seconds since epoch, float or None). On a driver whose subscriber has not received a LowState message yet the returned dict carries present=False and every field None - the verb does not fabricate a reading the driver does not have.
g1_joint_index¶
Return the driver slot for a joint name.
strands_robots.tools.g1.g1_joints
| Parameter | Type | Default | Description |
|---|---|---|---|
name |
str |
required | A joint name in the driver's snake_case (canonical) or in PascalCase / camelCase (alias). |
Returns. A dict with status and the same record shape g1_joint_reference returns for a single slot. An unknown name carries status="error" and a message listing the driver's actual map so the caller sees the domain rather than a hint.
g1_joint_name¶
Return the driver name for a joint slot.
strands_robots.tools.g1.g1_joints
| Parameter | Type | Default | Description |
|---|---|---|---|
index |
int |
required | The 0-based joint slot the caller wants to name. |
Returns. A dict with status and the same record shape g1_joint_reference returns for a single slot. Out-of-range indices carry status="error".
g1_joint_reference¶
Return the joint-name / slot / gain table G1Driver writes against.
strands_robots.tools.g1.g1_joints
| Parameter | Type | Default | Description |
|---|---|---|---|
group |
str |
'' |
Optional group filter. One of left_leg, right_leg, waist, left_arm, right_arm. Empty returns every slot. |
Returns. A dict with status, a count of returned rows, and a joints list of records carrying index, name, group, kp and kd for each slot. On an unknown group name the returned dict carries status="error" and a message naming the valid groups as a resolvable domain.
g1_lidar_state¶
Return the driver's cached rt/utlidar/lidar_state snapshot.
strands_robots.tools.g1.g1_lidar_state
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a _snapshot(attr: str) method returning the cached sensor dict (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close -- see the module docstring's SDK-load-hygiene note. The verb is duck-typed on _snapshot; any object with that method answering "_lidar_state" and returning the cache dict shape the driver's _on_lidar_state writes will satisfy it. |
Returns. A dict with status, a present flag naming whether the driver has a cached reading yet, and the five fields _on_lidar_state writes: code (the MID-360's fault code as an integer, or None), code_text (the same code rendered through strands_robots.drivers.unitree._common.decode_code, or None), freq (the cloud frequency in Hz reported off the message's cloud_frequency field, float or None), sys_rotation_speed (the system rotation speed off the message's sys_rotation_speed field, float or None) and t (the wall time the reading was decoded at, seconds since epoch, float or None). On a driver whose subscriber has not received a state message yet the returned dict carries present=False and every field None -- the verb does not fabricate a reading the driver does not have.
g1_lidar_summary¶
Return the driver's cached lidar-cloud header summary.
strands_robots.tools.g1.g1_lidar_summary
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a _snapshot(attr: str) method returning the cached sensor dict (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. The verb is duck-typed on _snapshot; any object with that method answering "_lidar_summary" and returning the cache dict shape the driver's _on_lidar_cloud writes will satisfy it. |
Returns. A dict with status, a present flag naming whether the driver has a cached reading yet, and the six fields _on_lidar_cloud writes: count (the cloud's true point count as width * height, integer, or None), width (integer or None), height (integer or None), point_step (bytes per point, integer or None), row_step (bytes per row, integer or None) and t (the wall time the cloud was summarised at, seconds since epoch, float or None). On a driver whose subscriber has not received a PointCloud2 message yet the returned dict carries present=False and every field None - the verb does not fabricate a reading the driver does not have. count is the cloud's uncapped size on purpose (refs strands-labs/robots#2752): a MID-360 that drops from 24000 points to 3000 is reporting a fault, and clamping the number would hide it.
g1_list_arm_actions¶
Return the arm-action ids G1ArmActionClient.ExecuteAction admits.
strands_robots.tools.g1.g1_arm_actions
No parameters.
Returns. A dict with status, a count naming the number of actions, an action_map dict (name -> id) covering every entry the SDK's own action_map ships, a sorted action_ids list of the ids alone (useful for a caller comparing an integer input), a release_action_id field naming the id ExecuteAction uses to drop the arm-action hold, an arm_ready_fsm_ids list naming the FSM ids the arm-SDK gate admits on (from strands_robots.drivers.unitree._common.HANDSHAKE_FSMS, surfaced here because arm-action execution is arm-SDK-shaped and shares the same gate), and a refusals list carrying the three SDK-side refusal codes and their decoded text (7402 invalid id, 7401 arm is holding, 7400 topic is occupied) that a future execute verb's driver wrapper would surface. Every field is a snapshot of an SDK or driver constant; no dynamic decode runs here.
g1_list_error_codes¶
Return the SDK error codes the G1 locomotion / arm handlers surface.
strands_robots.tools.g1.g1_error_codes
No parameters.
Returns. A dict with status, a count naming the number of catalogued codes, an error_codes list of descriptors (one per code, sorted ascending) carrying code and text, and a bare codes list of just the integer codes for a caller who only needs the set. Every field is a snapshot of a module-level constant; no dynamic decode runs here. The catalogue mirrors what strands_robots.drivers.unitree._common.decode_code would render for the same numbers, so a caller reading a refusal text from any other verb reads the same sentence here.
g1_list_motion_gates¶
Return the FSM-id sets G1Driver._check_motion_gates admits on.
strands_robots.tools.g1.g1_motion_gates
| Parameter | Type | Default | Description |
|---|---|---|---|
scope |
str |
'' |
Optional scope filter. "arm" returns the FSM ids that admit arm-SDK-shaped writes (HANDSHAKE_FSMS); "loco" returns the narrower set locomotion-shaped writes need (WALK_FSMS, which excludes 500 because sitting accepts arm gestures but not walking). Empty returns both scopes so a caller can see the whole gate at once. |
Returns. A dict with status and a gates list of records, one per returned scope. Each record carries scope, an fsm_ids list (sorted ascending, integers only), and the refusal_code / refusal_text pair the driver's write path would surface when a caller writes with the live FSM outside the set. On an unknown scope name the returned dict carries status="error" and a message naming the valid scopes as a resolvable domain.
g1_mainboard¶
Return the driver's cached rt/mainboardstate snapshot.
strands_robots.tools.g1.g1_mainboard
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a _snapshot(attr: str) method returning the cached sensor dict (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close -- see the module docstring's SDK-load-hygiene note. The verb is duck-typed on _snapshot; any object with that method answering "_mainboard" and returning the cache dict shape the driver's _on_mainboard writes will satisfy it. |
Returns. A dict with status, a present flag naming whether the driver has a cached reading yet, and the five fields _on_mainboard writes: fan_state (a vector of integer fan flags as list[int] or None), temperature (a vector of board-thermistor readings as list[float] or None), value and state (the two remaining vectors MainBoardState_ declares, as list[float] / list[int] or None, under the vendor's own names because the IDL documents no semantics for them) and t (the wall time the reading was decoded at, seconds since epoch, float or None). On a driver whose subscriber has not received a MainBoardState_ message yet the returned dict carries present=False and every field None -- the verb does not fabricate a reading the driver does not have. A field the current firmware does not declare surfaces as None for that key alone (the driver's _on_mainboard reads through getattr with a default), so a partial reading is decidable rather than surfaced as an empty dict.
g1_move_velocity¶
Command the G1 to WALK at (vx, vy, vyaw) for duration seconds.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
vx |
float | None |
None |
Forward velocity, m/s (signed finite float). |
vy |
float | None |
None |
Lateral velocity, m/s (positive = strafe left). |
vyaw |
float | None |
None |
Rotation rate, rad/s (positive = counter-clockwise). |
duration |
float | None |
None |
Seconds to hold the triple (positive finite float). |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_pressure¶
Return the driver's cached rt/pressuresensorstate snapshot.
strands_robots.tools.g1.g1_pressure
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a _snapshot(attr: str) method returning the cached sensor dict (in practice a G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close -- see the module docstring's SDK-load-hygiene note. The verb is duck-typed on _snapshot; any object with that method answering "_pressure" and returning the cache dict shape the driver's _on_pressure writes will satisfy it. |
Returns. A dict with status, a present flag naming whether the driver has a cached reading yet, and the five fields _on_pressure writes: pressure (a per-sensor vector of raw pressure readings as list[float] or None), temperature (a per-sensor vector of Celsius readings as list[float] or None), lost (the packet-loss counter as int or None), reserve (the reserve scalar the IDL declares next to it as int or None), and t (the wall time the reading was decoded at, seconds since epoch, float or None). On a driver whose subscriber has not received a PressSensorState_ message yet the returned dict carries present=False and every field None -- the verb does not fabricate a reading the driver does not have. A field the current firmware does not declare surfaces as None for that key alone (the driver's _on_pressure reads through getattr with a default), so a partial reading is decidable rather than surfaced as an empty dict.
g1_release_arm¶
Force-release the G1 arm's holding action (ExecuteAction id 99).
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_run_policy¶
Start the driver's 500 Hz control loop against policy_object.
strands_robots.tools.g1.g1_run_policy
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a synchronous run_policy(policy_object, instruction=..., duration=..., n_steps=...) returning the driver's start envelope (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own strands_robots.drivers.unitree._common.ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. The verb is duck-typed on run_policy; any object with that method returning the envelope shape the driver writes will satisfy it. |
policy_object |
Any |
None |
An already-built policy - either a strands_robots.policies.Policy instance with a .step(obs) method or a bare callable that returns a joint-name-keyed action dict per step. The driver's own strands_robots.drivers.g1.G1Driver.run_policy refuses a None or non-callable / no-.step() object verbatim once its own path is reached; this verb refuses the same shape here before reaching the driver so the refusal envelope names policy_object and the remedy rather than surfacing the driver's own message through a call site the caller cannot map back to the parameter. |
instruction |
str |
'' |
A free-form conditioning string. The driver's strands_robots.drivers.g1.G1Driver.run_policy discards it (del instruction # policies own their own conditioning); a policy that reads instructions carries its own state and does not need the driver to route them. The parameter is retained on this verb for the shape send_action's wire frame and every language-driven manipulation demo already exposes; the driver's discard is documented and stable. |
duration |
float |
30.0 |
Wall-clock budget for the rollout in seconds. The driver's method validates this against strands_robots.utils.positive_finite_number_error (nan poisons every deadline comparison in the loop; inf collapses the exit test to always-false; a non-numeric string raises out of a method that must return an envelope). Defaults to 30.0 seconds; the loop exits with exit_reason="duration" when time.monotonic() - started_at >= duration. |
n_steps |
int | None |
None |
Optional step-count budget. None (the default) means "no step cap"; a positive integer caps the loop at that many steps and exits with exit_reason="n_steps" when self._steps >= self._n_steps. The driver's method validates this against strands_robots.utils.positive_count_error when not None (a bool silently caps at 1, a fractional applies a cap the caller never named, and 0 / negative exits instantly with exit_reason="n_steps" on a rollout that commanded nothing). |
Returns. The envelope G1Driver.run_policy returned. On the success path this is {"status": "success", "content": [{"json": {"tool_name": ..., "task_running": True, "duration": ..., "n_steps": ..., "hz": 500}}]}; on the driver's refusal path (duration / n_steps validation, gate flip, policy_object refused by the driver, a task already running) it is {"status": "error", "content": [{"text": "..."}]} with the driver's own reason inside. The verb does not reshape either shape - a future field the driver adds on the success path reaches a caller the moment the driver writes it, because this verb passes the envelope through.
g1_safe_lie_to_stand¶
Stand the G1 up from lying: Damp, wait preamble_s, Lie2StandUp.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
preamble_s |
float |
0.5 |
Seconds to hold Damp before the transition (positive finite float). |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_safe_squat_to_stand¶
Stand the G1 up from a squat: Damp, wait preamble_s, Squat2StandUp.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
preamble_s |
float |
0.5 |
Seconds to hold Damp before the transition (positive finite float). |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_safe_stand_to_squat¶
Lower the G1 into a squat: Damp, wait preamble_s, StandUp2Squat.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
preamble_s |
float |
0.5 |
Seconds to hold Damp before the transition (positive finite float). |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_send_action¶
Publish one LowCmd_ frame on rt/lowcmd for action.
strands_robots.tools.g1.g1_send_action
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a callable send_action(action, robot_name=...) returning the driver's write envelope (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own strands_robots.drivers.unitree._common.ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. The verb is duck-typed on send_action; any object with that method returning the envelope shape the driver writes will satisfy it. |
action |
dict[str, Any] | None |
None |
A joint-name-keyed dict. Values are either a target position in radians (the driver falls back to reference gains) or an inner dict carrying any subset of q / kp / kd / dq / tau; the driver's own strands_robots.drivers.g1._build_lowcmd_from_action refuses a missing q verbatim so a silently-zeroed target cannot make it onto the wire. A caller who passes an empty dict is refused here rather than on the driver: a wire frame that names no joint is a no-op that would still consume the arm-SDK gate's admission read, and the refusal string names action and the remedy so a caller reading the envelope can fix the call. |
Returns. The envelope G1Driver.send_action returned. On the success path this is {"status": "success", "content": [{"json": {"topic": "rt/lowcmd", "joints": [...], "fsm_id": ..., "mode_machine": ...}}]}; on the driver's refusal path (gate flip, publisher not initialised, action-dict validation, SDK missing on the write path, publish error) it is {"status": "error", "content": [{"text": "..."}]} with the driver's own reason inside. The verb does not reshape either shape - a future field the driver adds on the success path reaches a caller the moment the driver writes it, because this verb passes the envelope through.
g1_set_fsm¶
Request a G1 FSM transition and read back the settled state.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
fsm_id |
int | None |
None |
Integer id from the SDK's SetFsmId admission set - use_unitree's describe_operation documents it. |
wait |
float |
3.0 |
Seconds between SetFsmId and the fsm-after read (positive finite float). |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_set_stand_height¶
Set the G1's standing height.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
height |
float | None |
None |
Finite float in meters (typical range 0.0..~0.8; 0.0 = LOW / crouched, negative = HighStand fallback). |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_set_swing_height¶
Set the G1's walking leg-lift (swing) clearance.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
height |
float | None |
None |
Finite float in meters (neon-bundle-observed range 0.0..0.2; typical safe range 0.05..0.15). |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_shake_hand_loco¶
Dispatch the G1's built-in LocoClient.ShakeHand task.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
stage |
int | None |
None |
Integer stage id from the admitted set. |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_start_task¶
Start a provider-driven task on the driver's 500 Hz control loop.
strands_robots.tools.g1.g1_start_task
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a synchronous start_task(instruction, policy_port=..., policy_host=..., policy_provider=..., duration=..., **kwargs) returning the driver's envelope (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own strands_robots.drivers.unitree._common.ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. The verb is duck-typed on start_task; any object with that method returning the envelope shape the driver writes will satisfy it. |
instruction |
str |
'' |
A free-form conditioning string handed to the provider once the registry lands. The driver's strands_robots.drivers.g1.G1Driver.start_task discards it today (del instruction, ...) alongside every other provider-facing argument, because there is no provider to receive them; the parameter is retained on this verb for the shape every language-driven manipulation demo already exposes and for parity with send_action's wire frame. The driver's discard is documented and stable. |
policy_port |
int | None |
None |
TCP port a remote inference server listens on, passed through to the provider once the registry lands. None (the default) lets the provider pick its own default. Discarded on today's driver alongside instruction. |
policy_host |
str |
'localhost' |
Hostname of the remote inference server; "localhost" is the default the lerobot driver uses in the same shape. Passed through to the provider once the registry lands, discarded on today's driver. |
policy_provider |
str |
'groot' |
Provider name looked up in strands_robots.policies once the registry lands. "groot" is the neon reference stack's default and matches the driver's own signature default. The registry is the source of truth for the admission set; this verb does not gate the name on this side (see the module docstring's "does not refuse" note). |
duration |
float |
30.0 |
Wall-clock budget for the rollout in seconds. Handed to the same loop run_policy starts, so the deadline = started_at + duration shape and exit_reason="duration" exit apply once the provider registry lands. Defaults to 30.0 seconds; discarded on today's driver. |
Returns. The envelope G1Driver.start_task returned. On today's driver this is {"status": "error", "content": [{"text": "start_task: provider registry not wired yet; ... "}]} after the FSM/battery gate admits, or the gate's own refusal envelope if it did not. Once the provider registry lands the same call returns strands_robots.drivers.g1.G1Driver.run_policy's start envelope ({"status": "success", "content": [{"json": {...}}]}) verbatim, because the driver's start_task forwards to the same loop path. The verb does not reshape either shape - a future field the driver adds reaches a caller the moment the driver writes it.
g1_stop_move¶
Stop all G1 locomotion (zero velocity triple, FSM unchanged).
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
Returns. The driver's envelope, success or refusal, unreshaped.
g1_stop_task¶
Signal the driver's control loop to stop and report the join.
strands_robots.tools.g1.g1_stop_task
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | An object with a synchronous stop_task method returning the driver's stop envelope (in practice a strands_robots.drivers.g1.G1Driver). Typed typing.Any rather than as G1Driver to keep this module out of the import cycle the driver's own ensure_dds reach into this package would close - see the module docstring's SDK-load-hygiene note. The verb is duck-typed on stop_task; any object with that method returning the envelope shape the driver writes will satisfy it. |
Returns. A dict with status (the envelope's own status value, so the join-outlasted-budget shape surfaces its "error" verbatim rather than being flattened to a success), a present flag naming whether the driver returned a snapshot dict (True on both the joined and the timed-out shape, False on the "no task is running" text sentinel), the loop's stopped flag (True if the loop joined within budget, False if the join timed out, None on the "no task is running" shape), the running flag (True only on the timed-out shape where the loop is still writing frames), and the eight snapshot fields the driver's _ControlLoop.snapshot writes: steps, refusals, elapsed_s, duration_budget_s, n_steps_budget, exit_reason, exit_detail, hz, and the two FSM-refresher fields fsm_refresh_hz / fsm_reads. On the "no task is running" shape reason quotes the driver's own text verbatim and every snapshot field is None.
g1_wave_hand_loco¶
Dispatch the G1's built-in LocoClient.WaveHand task.
strands_robots.tools.g1.g1_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live G1Driver handle the orchestrator constructed. |
turn_flag |
bool | None |
None |
False = wave in place, True = wave and turn around. |
Returns. The driver's envelope, success or refusal, unreshaped.
use_unitree¶
Universal interface to every Unitree SDK2 client method.
Takes the agent's tool context (@tool(context=True)) - the seam it prompts an operator through.
strands_robots.tools.g1.use_unitree
| Parameter | Type | Default | Description |
|---|---|---|---|
service_name |
str |
required | One of {loco, arm, audio, motion_switcher, vui, robot_state} - or 'meta' for discovery operations. |
operation_name |
str |
required | PascalCase method name on the client class (e.g. 'SetFsmId', 'ExecuteAction', 'TtsMaker'), or one of {list_services, list_operations, describe_operation} when service_name='meta'. |
parameters |
dict[str, Any] | None |
None |
Kwargs to pass to the method. For meta ops, the lookup target (e.g. {'service_name': 'loco'}). |
label |
str |
'' |
Optional human-readable description, echoed in the response. |
network_interface |
str |
'eth0' |
DDS interface. Default 'eth0'. |
Returns. Dict with status/message plus service, operation, label, result, mutative and high_danger flags. On error: the message plus available_operations or the expected signature where useful. The mutative and high_danger flags are present on BOTH outcomes, because a call that failed is the one whose classification a caller most needs. An RPC that times out is not evidence the command never landed - a loco.SetVelocity answering RPC_CLIENT_API_TIMEOUT is consistent with a robot that is walking - and an absent flag cannot be told apart from False, so .get("high_danger") would read a failed ZeroTorque exactly like a failed GetFsmId.
Reachy Mini¶
The Mini's daemon surface: head and antenna gestures, emotions, sound and camera.
reachy_antennas, reachy_body_turn, reachy_camera, reachy_express, reachy_get_state, reachy_home, reachy_list_emotions, reachy_look, reachy_look_at, reachy_motors, reachy_play_sound, reachy_stop, reachy_volume, reachy_wake
reachy_antennas¶
Move just the two antennas (the Mini's 'ears'), in degrees.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
right |
float |
0.0 |
Right antenna angle, degrees (~[-90, 90]). |
left |
float |
0.0 |
Left antenna angle, degrees (~[-90, 90]). |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_body_turn¶
Rotate the Mini's body around the vertical axis, in degrees.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
yaw |
float |
0.0 |
Body yaw, degrees, envelope +/-160, and within 65 deg of the head's current yaw target. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_camera¶
Capture a frame from the Mini's head camera and save it to disk.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
save_path |
str |
'' |
Where to write the JPEG; empty means the driver's default. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_express¶
Play a named emotion or dance from the Mini's recorded-move library.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
emotion |
str |
'' |
The move's name, e.g. 'happy', 'curious', 'no'. |
library |
str |
'emotions' |
'emotions' (default) or 'dances'. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_get_state¶
Read the Mini's live state: joints, head pose, IMU, battery.
strands_robots.tools.reachy.reachy_reads
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_home¶
Return the Mini to the neutral pose: head centred, body forward, ears rest.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_list_emotions¶
List the recorded moves the Mini's daemon can play.
strands_robots.tools.reachy.reachy_reads
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
library |
str |
'emotions' |
'emotions' (default) or 'dances'. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_look¶
Move the Mini's head to a pose - the primary gesture verb.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
pitch |
float |
0.0 |
Head pitch, degrees (positive = up). |
roll |
float |
0.0 |
Head roll, degrees. |
yaw |
float |
0.0 |
Head yaw, degrees (positive = left). |
x |
float |
0.0 |
Head translation forward, millimetres (small, ~[-20, 20]). |
y |
float |
0.0 |
Head translation left, millimetres. |
z |
float |
0.0 |
Head translation up, millimetres. |
body_yaw |
float | None |
None |
Body rotation, degrees; None lets the daemon turn the body as far as the head yaw needs, and no further. |
antenna_left |
float | None |
None |
Left antenna angle, degrees; None leaves it alone. |
antenna_right |
float | None |
None |
Right antenna angle, degrees; None leaves it alone. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_look_at¶
Turn the Mini's head toward pixel (u, v) of an unmodified camera frame.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
u |
int | None |
None |
Pixel column in the camera frame, from the left. |
v |
int | None |
None |
Pixel row in the camera frame, from the top. |
frame_width |
int | None |
None |
Width of the unmodified frame the pixel came from. |
frame_height |
int | None |
None |
Height of that frame. |
duration |
float |
1.0 |
Seconds for the interpolated move. |
Returns. The driver's envelope, success or refusal, unreshaped. Success is the daemon accepting the move, not the head having arrived.
reachy_motors¶
Set the Mini's motor torque: 'enabled' holds pose, 'disabled' goes limp.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
mode |
str |
'' |
'enabled' or 'disabled'. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_play_sound¶
Play a sound file through the Mini's speaker.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
sound_file |
str |
'' |
Daemon-side path or asset name of the audio file. |
wobble |
bool |
False |
Bob the head in sync with the audio. This moves the head and stays on until driver.set_wobbling(False); off by default. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_stop¶
Halt any recorded move the daemon is playing.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_volume¶
Read or set the Mini's speaker volume, 0-100.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
level |
int | str | None |
None |
Target volume: an integer 0-100, or a word - silent, low, normal, loud, max, quieter, louder. Omit it to read the current level instead. |
allow_test_sound |
bool |
False |
Acknowledge the daemon's test sound. Required True for a write; ignored for a read. |
Returns. The driver's envelope, success or refusal, unreshaped.
reachy_wake¶
Wake the Mini up (init pose, ears up) or put it to sleep.
strands_robots.tools.reachy.reachy_actions
| Parameter | Type | Default | Description |
|---|---|---|---|
driver |
Any |
required | The live ReachyDriver handle the orchestrator constructed. |
sleep |
bool |
False |
True plays go-to-sleep instead of wake-up. Checked, not parsed - a truthy spelling of off is refused, never honoured. |
Returns. The driver's envelope, success or refusal, unreshaped.