refactor(atomic-actions): generalize runtime endpoints - #488
Conversation
Make endpoint bindings, timed command frames, transports, routing, safe holds, and profile lowering controller-agnostic. Preserve joint trajectories as optional feedback artifacts and add staged, same-address invocation revision semantics for mobile and whole-body safety.
Greptile SummaryThe PR replaces arm/tool-shaped atomic-action routing with typed generic endpoint targets, command frames, transports, and target-scoped lifecycle handling.
Confidence Score: 4/5This PR should not merge until mixed-transport frame dispatch prevents or safely handles partial execution when one addressed transport rejects. The new router can activate an earlier transport before discovering that a later transport rejected the same synchronized frame, leaving an observable partial physical action before cancel-and-hold recovery begins. Files Needing Attention: embodichain/lab/sim/atomic_actions/transports.py, embodichain/lab/sim/atomic_actions/runner.py
|
| Filename | Overview |
|---|---|
| embodichain/lab/sim/atomic_actions/transports.py | Adds exact-ID transport routing and acknowledgement aggregation, but sequential mixed-transport sends can partially execute before an aggregate rejection. |
| embodichain/lab/sim/atomic_actions/runner.py | Adds staged revisions and target-scoped safe stops; failure handling occurs only after transport dispatch returns. |
| embodichain/lab/sim/atomic_actions/execution.py | Converts session output to endpoint command frames and adds destination continuity, target holding, and feedback-mode handling. |
| embodichain/lab/sim/atomic_actions/runtime_commands.py | Defines validated immutable endpoint payloads, frames, and timed command sequences. |
| embodichain/lab/sim/atomic_actions/core.py | Lowers joint trajectories into endpoint commands and authorizes emitted destinations against engine-owned bindings. |
| embodichain/lab/sim/atomic_actions/bindings.py | Replaces role mappings with generic endpoint bindings and immutable typed runtime targets. |
| embodichain/lab/sim/atomic_actions/sim_adapter.py | Implements the built-in joint-position transport, including inactive-row position holds and zero velocities. |
| embodichain/lab/sim/skills/profiles.py | Generalizes profile resolution to produce endpoint bindings and typed runtime targets. |
Sequence Diagram
sequenceDiagram
participant Session as ExecutionSession
participant Runner as ExecutionRunner
participant Router as EndpointCommandRouter
participant A as Transport A
participant B as Transport B
Session->>Runner: synchronized RuntimeCommandFrame
Runner->>Router: send(frame)
Router->>A: send(subframe A)
A-->>Router: accepted
Router->>B: send(subframe B)
B-->>Router: rejected
Router-->>Runner: aggregate rejection
Runner->>Router: cancel(all targets)
Runner->>Router: hold(all targets)
Prompt To Fix All With AI
### Issue 1
embodichain/lab/sim/atomic_actions/transports.py:246-264
**Partial multi-transport frame execution**
When a frame addresses multiple transports and a later transport rejects, times out, or raises, the router has already dispatched the frame to earlier transports, causing one controller to begin moving before the runner initiates cancel-and-hold recovery.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "refactor(atomic-actions): generalize run..." | Re-trigger Greptile
| acknowledgements: list[tuple[str, CommandAcknowledgement]] = [] | ||
| for transport_id, commands in grouped.items(): | ||
| subframe = RuntimeCommandFrame( | ||
| commands=tuple(commands), | ||
| active_mask=frame.active_mask, | ||
| env_ids=frame.env_ids, | ||
| hold_duration=frame.hold_duration, | ||
| ) | ||
| transport = self._transports[transport_id] | ||
| acknowledgement = self._invoke_transport( | ||
| transport_id, | ||
| "send", | ||
| lambda transport=transport, subframe=subframe: transport.send( | ||
| subframe, | ||
| timeout=normalized_timeout, | ||
| ), | ||
| ) | ||
| acknowledgements.append((transport_id, acknowledgement)) | ||
| return self._aggregate_acknowledgements("send", acknowledgements) |
There was a problem hiding this comment.
Partial multi-transport frame execution
When a frame addresses multiple transports and a later transport rejects, times out, or raises, the router has already dispatched the frame to earlier transports, causing one controller to begin moving before the runner initiates cancel-and-hold recovery.
Prompt To Fix With AI
This is a comment left during a code review.
Path: embodichain/lab/sim/atomic_actions/transports.py
Line: 246-264
Comment:
**Partial multi-transport frame execution**
When a frame addresses multiple transports and a later transport rejects, times out, or raises, the router has already dispatched the frame to earlier transports, causing one controller to begin moving before the runner initiates cancel-and-hold recovery.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.There was a problem hiding this comment.
Pull request overview
Refactors the atomic-actions runtime to execute transport-neutral endpoint command frames end-to-end (bindings → planning → session → runner → transport router), removing the temporary arm/tool-shaped binding seam and making runtime targets/payloads first-class.
Changes:
- Replaces role-based
ActionBindingusage with engine-owned endpoint bindings viaSkillBindingContract+engine.bind_control_parts(...). - Introduces/threads transport-neutral runtime command carriers (
RuntimeCommandFrame,TimedCommandSequence) through planning and execution, including safe-stop behavior via endpoint targets. - Updates built-in primitives, tests, tutorials, benchmarks, and docs to the new binding + runtime command model.
Reviewed changes
Copilot reviewed 69 out of 69 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/sim/planners/test_curobo_planner.py | Updates planner tests to use engine.bind_control_parts() bindings. |
| tests/sim/atomic_actions/test_sim_adapter.py | Adapts sim adapter tests to endpoint command frames/targets and transport semantics. |
| tests/sim/atomic_actions/test_runtime_commands.py | Adds value-object tests for transport-neutral runtime commands. |
| tests/sim/atomic_actions/test_runner.py | Updates runner tests for endpoint frames, target-scoped hold/cancel, and revision staging. |
| tests/sim/atomic_actions/test_motion_strategy_e2e.py | Adjusts e2e assertions to use per-plan joint trajectory + command sequence. |
| tests/sim/atomic_actions/test_engine.py | Updates engine tests for direct endpoint binding and joint-trajectory-only compilation. |
| tests/sim/atomic_actions/test_curobo_motion_strategy_e2e.py | Updates curobo e2e to new binding and plan output structure. |
| tests/sim/atomic_actions/test_control.py | Migrates command override and binding resolution tests to endpoint-scoped overrides. |
| scripts/tutorials/atomic_action/press.py | Migrates tutorial to bind_control_parts() and per-skill bindings. |
| scripts/tutorials/atomic_action/place.py | Migrates tutorial to bind_control_parts() and endpoint mappings. |
| scripts/tutorials/atomic_action/pickup.py | Migrates tutorial invocation binding to endpoint binding helper. |
| scripts/tutorials/atomic_action/moving_target_recovery.py | Updates recovery tutorial to new binding API. |
| scripts/tutorials/atomic_action/move_joints.py | Updates tutorial to endpoint binding helper for joint motion. |
| scripts/tutorials/atomic_action/move_held_object.py | Updates tutorial to per-skill endpoint bindings. |
| scripts/tutorials/atomic_action/move_end_effector.py | Updates tutorial to endpoint binding helper. |
| scripts/tutorials/atomic_action/hand_over.py | Updates tutorial to endpoint bindings for source/destination slots. |
| scripts/tutorials/atomic_action/dynamic_obstacle_recovery.py | Switches EEF path computation from trajectory to command sequence; updates binding. |
| scripts/tutorials/atomic_action/coordinated_placement.py | Updates coordinated placement tutorial to new bindings and trajectory retrieval. |
| scripts/tutorials/atomic_action/coordinated_pickment.py | Updates coordinated pickment tutorial to new endpoint binding. |
| scripts/tutorials/atomic_action/assemble.py | Updates assemble tutorial to per-skill endpoint bindings. |
| scripts/benchmark/atomic_action/press_benchmark.py | Migrates benchmark to endpoint bindings per invocation sequence. |
| scripts/benchmark/atomic_action/place_benchmark.py | Migrates benchmark to endpoint binding helper. |
| scripts/benchmark/atomic_action/pickup_benchmark.py | Migrates benchmark to endpoint binding helper. |
| scripts/benchmark/atomic_action/move_joints_benchmark.py | Updates benchmark helpers to accept engine and build endpoint binding once. |
| scripts/benchmark/atomic_action/move_held_object_benchmark.py | Migrates benchmark to endpoint bindings for each skill. |
| scripts/benchmark/atomic_action/move_end_effector_benchmark.py | Migrates benchmark to endpoint binding helper. |
| examples/sim/planners/curobo_planner.py | Updates example to bind endpoints via engine helper. |
| embodichain/lab/sim/skills/profiles.py | Refactors profile endpoint resolution to produce typed runtime targets and binding endpoints. |
| embodichain/lab/sim/atomic_actions/sim_adapter.py | Implements joint-position endpoint transport behavior over RuntimeCommandFrame. |
| embodichain/lab/sim/atomic_actions/runtime.py | Reworks planning services to build/validate endpoint bindings and apply endpoint-scoped overrides. |
| embodichain/lab/sim/atomic_actions/runner.py | Updates runner to dispatch endpoint frames, target-scoped hold/cancel, and staged revision install. |
| embodichain/lab/sim/atomic_actions/requirements.py | Removes ActionBindingRoute lowering seam from endpoint requirements/contracts. |
| embodichain/lab/sim/atomic_actions/primitives/press.py | Migrates primitive to endpoint binding accessors/targets. |
| embodichain/lab/sim/atomic_actions/primitives/place.py | Migrates primitive to endpoint binding accessors/targets. |
| embodichain/lab/sim/atomic_actions/primitives/pick_up.py | Migrates primitive to endpoint binding accessors/targets and target-based DOF handling. |
| embodichain/lab/sim/atomic_actions/primitives/move_joints.py | Migrates primitive to endpoint binding accessors/targets. |
| embodichain/lab/sim/atomic_actions/primitives/move_held_object.py | Migrates primitive to endpoint binding accessors/targets. |
| embodichain/lab/sim/atomic_actions/primitives/move_end_effector.py | Migrates primitive to endpoint binding accessors/targets. |
| embodichain/lab/sim/atomic_actions/primitives/hand_over.py | Migrates primitive to endpoint binding accessors/targets for source/destination. |
| embodichain/lab/sim/atomic_actions/primitives/coordinated_placement.py | Migrates primitive to endpoint binding accessors/targets for placing/support. |
| embodichain/lab/sim/atomic_actions/primitives/coordinated_pickment.py | Migrates primitive to endpoint binding accessors/targets for left/right roles. |
| embodichain/lab/sim/atomic_actions/plans.py | Makes ActionPlan.commands authoritative (command sequences), adds feedback mode + optional joint trajectory retention. |
| embodichain/lab/sim/atomic_actions/invocation.py | Updates resolved request binding type and snapshots engine-owned endpoint bindings. |
| embodichain/lab/sim/atomic_actions/engine.py | Adds bind_control_parts() and constrains compile() to joint-trajectory-backed plans. |
| embodichain/lab/sim/atomic_actions/control.py | Reworks invocation command overrides to be endpoint-scoped and flattenable. |
| embodichain/lab/sim/atomic_actions/init.py | Updates public exports to new endpoint binding/command/transport types. |
| embodichain_tasks/embodichain_tasks/tableware/stack_blocks_two.py | Migrates task planning to per-skill endpoint bindings. |
| embodichain_tasks/embodichain_tasks/tableware/blocks_ranking_rgb.py | Migrates task planning to per-skill endpoint bindings. |
| embodichain_tasks/embodichain_tasks/multi_segments/cube_pick_place.py | Migrates multi-segment planning to per-skill endpoint bindings. |
| docs/source/tutorial/atomic_actions.rst | Updates tutorial docs for new binding contract, router usage, and revised runtime carriers. |
| docs/source/overview/sim/atomic_actions/robot_skill_profiles.md | Updates profile docs to remove lowering routes and describe typed runtime targets/bindings. |
| docs/source/api_reference/embodichain/embodichain.lab.sim.atomic_actions.rst | Updates API reference exports for new endpoint runtime types and router/transport. |
| docs/design/declarative_expert_program_plan.md | Updates design doc to reflect PR2C runtime endpoint model and artifacts. |
| agent_context/MAP.yaml | Updates agent context index keywords for new runtime endpoint types. |
| .agents/skills/add-atomic-action/SKILL.md | Updates scaffolding guidance to the new endpoint binding + runtime command model. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if not isinstance(invocation, ActionInvocation): | ||
| raise TypeError("invocation must be an ActionInvocation.") | ||
| if self._status is not RunnerStatus.RUNNING: | ||
| raise RuntimeError("Only a running execution runner can be revised.") | ||
| prepared = self._session._prepare_revision(invocation) |
Description
Stack
feat/atomic-action-pr2b-robot-skill-profileMake generic profile endpoints executable end to end. Bindings are keyed by semantic slots and endpoint IDs; typed runtime targets and payloads flow through command frames, routers, transports, acknowledgements, cancellation, and transport-owned safe holds.
This intentionally removes the temporary arm/tool-shaped routing seam. Joint-position, full-body, and custom endpoint tests all use the same authorization and lifecycle contracts.
Refs #471
Refs #474
Type of change
Screenshots
Not applicable.
Validation
tests/sim/atomic_actions/test_runtime_commands.py,test_transports.py, andtest_endpoint_runtime_e2e.pyChecklist