> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cadenzalabs.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Actions

> The action library: names, lookups, specs, and NL parsing per robot.

Every robot has a fixed library of named base actions. These are the building
blocks for `ActionCall`, `Sim.run`, CLI [group actions](/cli/actions), and policy
outputs.

## How an action becomes motion

An `ActionSpec` is either **gait-based** (a continuous locomotion command run by
the gait engine) or **phase-based** (a timed sequence of joint targets with
per-joint PD gains and motor schedules). The simulator dispatches on
`spec.is_gait` / `spec.is_phase`.

```mermaid theme={null}
flowchart TD
    NAME["action name<br/>'walk_forward'"] --> SPEC[ActionSpec]
    SPEC -->|is_gait| GAIT["GaitAction<br/>cmd_vx · cmd_yaw · step_height"]
    SPEC -->|is_phase| PHASES["ActionPhase[]<br/>JointTarget + MotorSchedule"]
    GAIT --> ENG[Gait engine]
    PHASES --> INTERP[Per-joint interpolation]
    ENG --> CTRL[joint targets → MuJoCo]
    INTERP --> CTRL
```

## Look up actions

```python theme={null}
import cadenza_lab as cadenza

cadenza.list_actions("go1")          # -> list[str] of action names
spec = cadenza.get_action("go1", "walk_forward")   # -> ActionSpec
lib  = cadenza.get_library("go1")    # -> ActionLibrary
```

```python theme={null}
list_actions(robot) -> list[str]
get_action(robot, name) -> ActionSpec
get_library(robot) -> ActionLibrary
```

## `ActionLibrary`

```python theme={null}
lib = cadenza.get_library("g1")
lib.robot              # "g1"
lib.list_actions()     # action names
lib.get("walk_forward")    # -> ActionSpec
lib.describe()         # human-readable summary of the library
```

## `ActionSpec`

The full description of one action. Key fields:

| Field                                                  | Description                                          |
| ------------------------------------------------------ | ---------------------------------------------------- |
| `name`, `description`, `robot`                         | Identity.                                            |
| `phases`                                               | Tuple of `ActionPhase` for phase-based actions.      |
| `gait`                                                 | A `GaitAction` for gait-based actions (else `None`). |
| `distance_m`, `rotation_rad`, `duration_s`, `speed_ms` | Action defaults.                                     |
| `max_pitch_rad`, `max_roll_rad`                        | Abort thresholds. Exceed them and the action fails.  |
| `hip_range`, `thigh_range`, `knee_range`               | Joint limits used by `clamp_joints`.                 |

```python theme={null}
spec = cadenza.get_action("go1", "walk_forward")
spec.is_gait          # True
spec.is_phase         # False
spec.total_duration() # seconds

jump = cadenza.get_action("go1", "jump")
jump.is_phase         # True
[p.name for p in jump.phases]   # ['crouch', 'hold_crouch', 'launch', ...]
```

Supporting dataclasses: `GaitAction` (gait command), `ActionPhase` (one timed
phase), `JointTarget` (12/16-DOF targets + `kp`/`kd`), and `MotorSchedule`
(per-joint velocity/torque caps and delays).

## Action catalog

<Tabs>
  <Tab title="go1 (quadruped, 21)">
    ```text theme={null}
    stand            stand_up         sit              lie_down
    jump             walk_forward     walk_backward    trot_forward
    crawl_forward    turn_left        turn_right       precision_turn_left
    precision_turn_right             climb_step        side_step_left
    side_step_right  pace_forward     bound_forward    rear_up
    shake_hand       rear_kick
    ```
  </Tab>

  <Tab title="g1 (humanoid, 20)">
    ```text theme={null}
    stand            stand_up         sit              lie_down
    crouch           deep_crouch      lift_left_hand   lift_right_hand
    walk_forward     walk_backward    trot_forward     crawl_forward
    turn_left        turn_right       side_step_left   side_step_right
    jump             shake_hand       rear_kick        rear_up
    ```
  </Tab>

  <Tab title="arm (6-axis, 6)">
    ```text theme={null}
    home             move_to          open_gripper
    close_gripper    pick             place
    ```
  </Tab>
</Tabs>

<Note>
  The arm's library is **Cartesian**, not gait/phase: `move_to`, `pick`, and
  `place` take an `(x, y, z)` target instead of a `GaitAction` or `ActionPhase`
  schedule, and `cadenza.get_library("arm")` returns an `ArmActionLibrary` (it
  duck-types `list_actions` / `get` / `describe`). See the
  [Arm controller](/sdk/robots#arm-6-axis-manipulator).
</Note>

<Note>
  Action availability is per-robot, so always confirm with
  `cadenza.list_actions(robot)` rather than assuming a name exists on both robots.
</Note>

## Parameterize with `ActionCall`

Wrap an action name with parameters to execute it (see
[Gym adapter](/sdk/gym-adapter#actioncall)):

```python theme={null}
from cadenza_lab import ActionCall

ActionCall("walk_forward", distance_m=1.0)
ActionCall("turn_left", rotation_rad=1.57)
ActionCall("trot_forward", distance_m=2.0, speed=1.2)
```

## Natural-language parsing

`CommandParser` turns a natural-language command into a `list[ActionCall]`, the
same parser the one-liner `cadenza.run(...)` and the CLI's scripted driver use.

<Warning>
  The parser lives at `cadenza.parser` (the real module), not `cadenza_lab.parser`.
  Import it as shown below.
</Warning>

```python theme={null}
from cadenza.parser import CommandParser

calls = CommandParser("go1").parse("walk forward 2 meters then turn left")
# [ActionCall(walk_forward, 2.0m), ActionCall(turn_left)]
```

## Demo: explore the library

```python theme={null}
"""demo_actions.py: inspect the action library (headless, no viewer)."""
import cadenza_lab as cadenza
from cadenza.parser import CommandParser

for robot in ("go1", "g1"):
    names = cadenza.list_actions(robot)
    print(f"\n{robot}: {len(names)} actions")
    for name in names:
        spec = cadenza.get_action(robot, name)
        kind = "gait " if spec.is_gait else "phase"
        print(f"  {kind}  {name:<22} {spec.description}")

# Natural language → actions
calls = CommandParser("go1").parse("trot forward 3 meters then turn right then sit")
print("\nparsed:", [c.action_name for c in calls])
```

```bash theme={null}
python demo_actions.py
```
