fix(robot): repair /api/ai/commands + port back vision-tag stripping#2
Merged
Merged
Conversation
- dashboard: get_plugin("ConversationPlugin") → "conversation" so
POST /api/ai/commands resolves the conversation plugin instead of
always returning 503.
- conversation_plugin_slv: add _execute_robot_command dispatcher. The SLV
plugin had the _cmd_* handlers but not the dispatch method the dashboard
calls, so the endpoint 500'd on AttributeError. Validated on-device:
status + dance now return 200 and the robot physically moves.
- llm / edge_llm: port back streaming [Faces: ...] vision-tag stripping
that was hot-patched on the device but never committed (would be lost on
image rebuild). Adds _StreamingBracketStripper, _VISION_TAG_RE,
_RESPONSE_STRIP_RE and prompt guards; the two files are interdependent
via _extract_emotion and land together.
- tests: add TestStreamingBracketStripper covering split tags, unclosed
bracket, trailing-space suppression, and non-tag brackets.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ng lint CI (and any checkout without the ../seeed-local-voice sibling) failed at `uv sync` because tool.uv.sources pointed at an editable local path that only exists on the device. Point it at the vendored torch-free wheel (deploy/jetson/reachy/vendor/openvoicestream_agent-0.1.0-py3-none-any.whl) so the project resolves on CI, fresh clones, and image builds; regenerate uv.lock accordingly. With sync working, ruff now runs and surfaced 4 pre-existing F401 unused imports (proof_engine_e2e.py, e2e_slv_plugin_local.py) — removed. Verified locally: `uv sync --extra dev` succeeds, `ruff check .` clean, `pytest tests/` → 550 passed, 58 skipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Triggered while validating robot movement on the deployed Jetson (
reachy-claw:slv-v6). Found two real bugs in the REST control path plus device-only work that had never been committed back.Bug 1 —
/api/ai/commandsalways 503dashboard_plugin.pylooked upget_plugin("ConversationPlugin"), but the plugin registers as"conversation"(strict name match inapp.get_plugin). The endpoint never resolved the plugin. One-char fix.Bug 2 — endpoint 500 on the SLV deployment (only surfaced via on-device test)
This deployment uses the standalone
conversation_plugin_slv.ConversationPlugin, which has the_cmd_*handlers but not the_execute_robot_commanddispatcher the dashboard calls →AttributeError→ 500. Added the dispatcher (exposing the 7 handlers the SLV plugin actually implements). Codex's static review missed this because it only inspected the legacy plugin; it was caught by real-device testing.Port-back — streaming
[Faces: ...]vision-tag strippingedge_llm.py/llm.pyhad been hot-patched directly on the device (newer thanmaster) to strip[Faces: ...]vision-context tags from the streamed LLM output so they don't leak into TTS. Never committed → would be lost on image rebuild. Ported back as a unit (the two files are interdependent via_extract_emotion). Adds_StreamingBracketStripper,_VISION_TAG_RE,_RESPONSE_STRIP_RE, and prompt guards.Validation
reachy-claw:POST /api/ai/commands {command: reachy_status}→{"status":"success","state":"idle","robot_connected":true}POST /api/ai/commands {command: reachy_dance, args:{dance_name:"celebrate"}}→{"status":"success","dance":"celebrate","steps":6}and the robot physically danced.TestStreamingBracketStripper(8 cases: split[emotion]/[Faces:...], unclosed[, trailing-space suppression, non-tag brackets, passthrough) — verified green against the real code inside the container (local Mac env can't resolve deps).Follow-up (not in this PR)
The Jetson is currently running the hot-patched files (backups at
*.bak-apifix). After merge, thereachy-claw:slv-v6image must be rebuilt and redeployed for the fixes to persist across container recreation.🤖 Generated with Claude Code