Skip to content

feat(manip): restore reset, and expose cancel as a skill - #3872

Open
mustafab0 wants to merge 1 commit into
mb/grasp-04-wrist-camera-tffrom
mb/grasp-05-reset-and-cancel
Open

feat(manip): restore reset, and expose cancel as a skill#3872
mustafab0 wants to merge 1 commit into
mb/grasp-04-wrist-camera-tffrom
mb/grasp-05-reset-and-cancel

Conversation

@mustafab0

Copy link
Copy Markdown
Contributor

reset was removed in #3447 but FAULT stayed, and planning only runs from IDLE or COMPLETED, so a faulted module accepted nothing further. Both manipulator agent prompts still instruct the model to call reset after a failure, one of them describing it as available as a skill and an RPC, so an agent that faulted was told to call a tool that did not exist. test_state_transitions_during_execution calls it too.

cancel already stops the trajectory, bumps the planning epoch, drops the pending plan and dismisses its preview, so reset delegates to it and adds only the unconditional return to IDLE with the error cleared — that is the whole of the difference between the two verbs, and writing it that way keeps it that way. Resetting cancels an active motion rather than refusing one: telling a caller to cancel first is a dead end for anyone holding only the skill surface, where cancel was never exposed. It is now.

Fifth of nine in the xArm grasping re-landing stack.

reset was removed in #3447 but FAULT stayed, and planning only runs from IDLE or
COMPLETED, so a faulted module accepted nothing further. Both manipulator agent
prompts still instruct the model to call reset after a failure, one of them
describing it as available as a skill and an RPC, so an agent that faulted was
told to call a tool that did not exist. A Drake-gated test in
test_manipulation_module.py calls it too.

cancel already stops the trajectory, bumps the planning epoch, drops the pending
plan and dismisses its preview, so reset delegates to it and adds only the
unconditional return to IDLE with the error cleared. Resetting cancels an active
motion rather than refusing one: telling a caller to cancel first is a dead end
for anyone holding only the skill surface, where cancel was never exposed. It is
now.
@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.11111% with 5 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
dimos/manipulation/manipulation_skills.py 44.44% 5 Missing ⚠️
@@                       Coverage Diff                       @@
##           mb/grasp-04-wrist-camera-tf    #3872      +/-   ##
===============================================================
+ Coverage                        77.65%   77.72%   +0.06%     
===============================================================
  Files                             1324     1324              
  Lines                           125452   125488      +36     
  Branches                         10911    10912       +1     
===============================================================
+ Hits                             97422    97537     +115     
+ Misses                           24889    24865      -24     
+ Partials                          3141     3086      -55     
Flag Coverage Δ
OS-ubuntu-24.04-arm 74.33% <86.11%> (+<0.01%) ⬆️
OS-ubuntu-latest 74.87% <86.11%> (+<0.01%) ⬆️
Py-3.10 ?
Py-3.11 74.87% <86.11%> (?)
Py-3.12 74.87% <86.11%> (?)
Py-3.13 74.86% <86.11%> (+<0.01%) ⬆️
Py-3.14 74.87% <86.11%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
dimos/manipulation/manipulation_module.py 76.73% <100.00%> (+8.49%) ⬆️
dimos/manipulation/manipulation_spec.py 97.27% <ø> (ø)
dimos/manipulation/test_manipulation_unit.py 99.61% <100.00%> (+0.01%) ⬆️
dimos/manipulation/manipulation_skills.py 53.44% <44.44%> (+7.65%) ⬆️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@greptile-apps

greptile-apps Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change restores manipulation reset, exposes cancellation and reset as agent skills, and expands recovery coverage. Runtime checks reproduced two unsafe recovery behaviors: reset can permit a new trajectory after the previous stop was not confirmed, and the cancellation skill can report that same unconfirmed stop as successful. These paths should be corrected before merging.

Confidence Score: 3/5

Not safe to merge until uncertain cancellation outcomes remain faulted and are exposed as failures to callers.

Focused runtime harnesses exercised both uncertain-cancellation paths and observed redispatch after reset as well as a successful skill result while the module remained faulted.

Files Needing Attention: dimos/manipulation/manipulation_module.py must preserve the fault for uncertain cancellation, and dimos/manipulation/manipulation_skills.py must propagate uncertain cancellation as a non-success result.

T-Rex T-Rex Logs

What T-Rex did

  • Published a finding-comment proof for a posted P1 finding and documented the focused uncertain-cancellation reset harness and its execution log.
  • Published a second finding-comment proof for a posted P1 finding and recorded the focused uncertain cancellation skill runtime harness plus the underlying module and cancellation-skill outputs for the uncertain coordinator response.
  • Published a third finding-comment proof for a posted P1 finding with no additional artifacts.
  • Validated the contract behavior by observing cancel status transitions, reset, and dispatch state changes, ending with exit code 0 and an accepted dispatch.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. General comment

    P1 reset admits a new trajectory after an uncertain cancellation

    • Bug
      • A coordinator cancellation outcome explicitly indicating that the trajectory may still be moving is changed from FAULT to IDLE by reset(), so the state gate admits a new plan and execute() dispatches it.
    • Cause
      • dimos/manipulation/manipulation_module.py:459-462 ignores the status returned by cancel() except for its message and unconditionally writes IDLE and clears the error. This overwrites the UNCERTAIN-to-FAULT projection at lines 1314-1325; _begin_group_planning() accepts IDLE at lines 501-518.
    • Fix
      • Do not transition to IDLE or clear the error when cancel() returns ExecutionStatus.UNCERTAIN; retain FAULT and reject new planning/dispatch until the coordinator can establish a deterministic stopped or terminal trajectory state.

    T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "feat(manip): restore reset, and expose c..." | Re-trigger Greptile

Comment on lines +459 to +462
cancelled = self.cancel().status is not ExecutionStatus.NO_EXECUTION
with self._lock:
self._state = ManipulationState.IDLE
self._error_message = ""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Reset admits overlapping motion

reset() invokes cancel() but unconditionally clears the error and restores IDLE, including when cancellation returned UNCERTAIN. That outcome means the coordinator could not confirm that the active trajectory stopped. Restoring IDLE reopens the planning gate, allowing a new trajectory to be dispatched while the earlier one may still be moving. Preserve FAULT and reject planning until a deterministic stopped or terminal result is available.

Artifacts

Focused uncertain-cancellation reset harness

  • This executable harness injects a coordinator UNCERTAIN cancellation and asserts the resulting reset, planning admission, and new-dispatch behavior, with the takeaway that it exercises the exact claimed safety path.

Observed uncertain-cancellation reset execution

  • This captured command output records UNCERTAIN cancellation followed by IDLE reset, PLANNING admission, and ACCEPTED redispatch with exit code 0, with the takeaway that the defect is confirmed at runtime.

View artifacts

T-Rex Ran code and verified through T-Rex

Comment on lines +93 to +96
@skill
def cancel(self) -> SkillResult[ManipulationSkillError]:
"""Stop the active motion or planning attempt, leaving the arm where it is."""
return SkillResult.ok(self.manipulation.cancel().message or "Cancelled")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Cancellation skill masks uncertain stops

The module transitions to FAULT when the coordinator returns UNCERTAIN, but this skill always returns SkillResult.ok. An agent branching on the skill result can therefore continue as though the arm stopped even though the stop was not confirmed and the module requires recovery. Return a failed or explicitly uncertain skill result for UNCERTAIN and other faulted cancellation outcomes.

Artifacts

Focused uncertain cancellation skill runtime harness

  • Authored harness that creates an executing manipulation module, makes the coordinator return UNCERTAIN, and exercises both the module and skill paths; it provides the reproducible defect trigger.

Underlying module cancellation output for an uncertain coordinator response

  • Executed module-level cancellation capture showing `ExecutionStatus.UNCERTAIN` and module state `FAULT`; it establishes the authoritative unsafe cancellation state before the skill wrapper.

Cancellation skill output for the same uncertain coordinator response

  • Executed skill-level cancellation capture showing `skill_success=True` with no error code while the underlying module remains in `FAULT`; it confirms the unsafe success translation.

View artifacts

T-Rex Ran code and verified through T-Rex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant