agenticros 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -0
- package/README.md +90 -4
- package/dist/commands/config.d.ts +20 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +179 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +33 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +232 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/down.d.ts +15 -0
- package/dist/commands/down.d.ts.map +1 -0
- package/dist/commands/down.js +91 -0
- package/dist/commands/down.js.map +1 -0
- package/dist/commands/init.d.ts +21 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +259 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +18 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +67 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/status.d.ts +12 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +56 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/up.d.ts +20 -0
- package/dist/commands/up.d.ts.map +1 -0
- package/dist/commands/up.js +70 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/menu.d.ts +9 -0
- package/dist/menu.d.ts.map +1 -0
- package/dist/menu.js +96 -0
- package/dist/menu.js.map +1 -0
- package/dist/runners/real-robot.d.ts +15 -0
- package/dist/runners/real-robot.d.ts.map +1 -0
- package/dist/runners/real-robot.js +46 -0
- package/dist/runners/real-robot.js.map +1 -0
- package/dist/runners/sim.d.ts +19 -0
- package/dist/runners/sim.d.ts.map +1 -0
- package/dist/runners/sim.js +53 -0
- package/dist/runners/sim.js.map +1 -0
- package/dist/util/env.d.ts +24 -0
- package/dist/util/env.d.ts.map +1 -0
- package/dist/util/env.js +53 -0
- package/dist/util/env.js.map +1 -0
- package/dist/util/logger.d.ts +24 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +62 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/paths.d.ts +57 -0
- package/dist/util/paths.d.ts.map +1 -0
- package/dist/util/paths.js +132 -0
- package/dist/util/paths.js.map +1 -0
- package/dist/util/pidfile.d.ts +16 -0
- package/dist/util/pidfile.d.ts.map +1 -0
- package/dist/util/pidfile.js +63 -0
- package/dist/util/pidfile.js.map +1 -0
- package/dist/util/state.d.ts +26 -0
- package/dist/util/state.d.ts.map +1 -0
- package/dist/util/state.js +55 -0
- package/dist/util/state.js.map +1 -0
- package/package.json +60 -1
- package/runtime/BUNDLE.json +11 -0
- package/runtime/LICENSE +192 -0
- package/runtime/README.md +273 -0
- package/runtime/docs/architecture.md +366 -0
- package/runtime/docs/cli.md +140 -0
- package/runtime/docs/memory.md +292 -0
- package/runtime/docs/robot-setup.md +347 -0
- package/runtime/package.json +28 -0
- package/runtime/packages/agenticros/agenticros-agenticros-0.0.1.tgz +0 -0
- package/runtime/packages/agenticros/openclaw.plugin.json +451 -0
- package/runtime/packages/agenticros/package.json +41 -0
- package/runtime/packages/agenticros/src/camera-snapshot-cache.ts +59 -0
- package/runtime/packages/agenticros/src/camera-snapshot-routes.ts +44 -0
- package/runtime/packages/agenticros/src/commands/estop.ts +41 -0
- package/runtime/packages/agenticros/src/commands/transport.ts +195 -0
- package/runtime/packages/agenticros/src/config-file.ts +136 -0
- package/runtime/packages/agenticros/src/config-page.ts +498 -0
- package/runtime/packages/agenticros/src/context/robot-context.ts +373 -0
- package/runtime/packages/agenticros/src/depth.ts +313 -0
- package/runtime/packages/agenticros/src/describer.ts +157 -0
- package/runtime/packages/agenticros/src/image-binary-trim.ts +16 -0
- package/runtime/packages/agenticros/src/index.ts +85 -0
- package/runtime/packages/agenticros/src/landing-page.ts +38 -0
- package/runtime/packages/agenticros/src/memory.ts +44 -0
- package/runtime/packages/agenticros/src/plugin-api.ts +173 -0
- package/runtime/packages/agenticros/src/plugin-image-base64.ts +69 -0
- package/runtime/packages/agenticros/src/preflight.ts +110 -0
- package/runtime/packages/agenticros/src/routes.ts +328 -0
- package/runtime/packages/agenticros/src/safety/validator.ts +43 -0
- package/runtime/packages/agenticros/src/service.ts +359 -0
- package/runtime/packages/agenticros/src/skill-api.ts +65 -0
- package/runtime/packages/agenticros/src/skill-loader.ts +146 -0
- package/runtime/packages/agenticros/src/teleop/page.ts +498 -0
- package/runtime/packages/agenticros/src/teleop/routes.ts +650 -0
- package/runtime/packages/agenticros/src/tools/index.ts +26 -0
- package/runtime/packages/agenticros/src/tools/ros2-action.ts +50 -0
- package/runtime/packages/agenticros/src/tools/ros2-camera.ts +221 -0
- package/runtime/packages/agenticros/src/tools/ros2-depth-distance.ts +58 -0
- package/runtime/packages/agenticros/src/tools/ros2-introspect.ts +62 -0
- package/runtime/packages/agenticros/src/tools/ros2-memory.ts +158 -0
- package/runtime/packages/agenticros/src/tools/ros2-param.ts +87 -0
- package/runtime/packages/agenticros/src/tools/ros2-publish.ts +52 -0
- package/runtime/packages/agenticros/src/tools/ros2-service.ts +46 -0
- package/runtime/packages/agenticros/src/tools/ros2-subscribe.ts +71 -0
- package/runtime/packages/agenticros/tsconfig.json +9 -0
- package/runtime/packages/agenticros-claude-code/README.md +260 -0
- package/runtime/packages/agenticros-claude-code/config.example.json +9 -0
- package/runtime/packages/agenticros-claude-code/dist/config.d.ts +8 -0
- package/runtime/packages/agenticros-claude-code/dist/config.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/config.js +93 -0
- package/runtime/packages/agenticros-claude-code/dist/config.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/depth.d.ts +20 -0
- package/runtime/packages/agenticros-claude-code/dist/depth.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/depth.js +126 -0
- package/runtime/packages/agenticros-claude-code/dist/depth.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.d.ts +6 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.js +36 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/coco-classes.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.d.ts +33 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.js +134 -0
- package/runtime/packages/agenticros-claude-code/dist/find-object/find-object.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.d.ts +43 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.js +73 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/controller.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.d.ts +58 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.js +251 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/detector.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.d.ts +61 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.js +268 -0
- package/runtime/packages/agenticros-claude-code/dist/follow-me/loop.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/index.d.ts +3 -0
- package/runtime/packages/agenticros-claude-code/dist/index.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/index.js +111 -0
- package/runtime/packages/agenticros-claude-code/dist/index.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/memory.d.ts +17 -0
- package/runtime/packages/agenticros-claude-code/dist/memory.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/memory.js +44 -0
- package/runtime/packages/agenticros-claude-code/dist/memory.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/safety.d.ts +10 -0
- package/runtime/packages/agenticros-claude-code/dist/safety.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/safety.js +34 -0
- package/runtime/packages/agenticros-claude-code/dist/safety.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.d.ts +36 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.js +777 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/transport.d.ts +17 -0
- package/runtime/packages/agenticros-claude-code/dist/transport.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/transport.js +46 -0
- package/runtime/packages/agenticros-claude-code/dist/transport.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.d.ts +42 -0
- package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.d.ts.map +1 -0
- package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.js +114 -0
- package/runtime/packages/agenticros-claude-code/dist/zero-shot/detector.js.map +1 -0
- package/runtime/packages/agenticros-claude-code/package.json +29 -0
- package/runtime/packages/agenticros-claude-code/src/config.ts +96 -0
- package/runtime/packages/agenticros-claude-code/src/depth.ts +173 -0
- package/runtime/packages/agenticros-claude-code/src/find-object/coco-classes.ts +38 -0
- package/runtime/packages/agenticros-claude-code/src/find-object/find-object.ts +190 -0
- package/runtime/packages/agenticros-claude-code/src/follow-me/controller.ts +109 -0
- package/runtime/packages/agenticros-claude-code/src/follow-me/depth-loop.ts +420 -0
- package/runtime/packages/agenticros-claude-code/src/follow-me/detector.ts +303 -0
- package/runtime/packages/agenticros-claude-code/src/follow-me/loop.ts +330 -0
- package/runtime/packages/agenticros-claude-code/src/index.ts +125 -0
- package/runtime/packages/agenticros-claude-code/src/memory.ts +51 -0
- package/runtime/packages/agenticros-claude-code/src/safety.ts +44 -0
- package/runtime/packages/agenticros-claude-code/src/tools.ts +891 -0
- package/runtime/packages/agenticros-claude-code/src/transport.ts +58 -0
- package/runtime/packages/agenticros-claude-code/src/zero-shot/detector.ts +169 -0
- package/runtime/packages/agenticros-claude-code/tsconfig.json +9 -0
- package/runtime/packages/agenticros-claude-code/yolo-debug.mjs +106 -0
- package/runtime/packages/agenticros-gemini/README.md +139 -0
- package/runtime/packages/agenticros-gemini/package.json +28 -0
- package/runtime/packages/agenticros-gemini/scripts/smoke-api.mjs +42 -0
- package/runtime/packages/agenticros-gemini/src/chat.ts +139 -0
- package/runtime/packages/agenticros-gemini/src/config.ts +92 -0
- package/runtime/packages/agenticros-gemini/src/depth.ts +173 -0
- package/runtime/packages/agenticros-gemini/src/index.ts +58 -0
- package/runtime/packages/agenticros-gemini/src/memory.ts +32 -0
- package/runtime/packages/agenticros-gemini/src/safety.ts +44 -0
- package/runtime/packages/agenticros-gemini/src/tools.ts +516 -0
- package/runtime/packages/agenticros-gemini/src/transport.ts +58 -0
- package/runtime/packages/agenticros-gemini/tsconfig.json +8 -0
- package/runtime/packages/core/package.json +47 -0
- package/runtime/packages/core/src/banner.ts +32 -0
- package/runtime/packages/core/src/cmd-vel-twist.ts +31 -0
- package/runtime/packages/core/src/config.ts +279 -0
- package/runtime/packages/core/src/index.ts +54 -0
- package/runtime/packages/core/src/memory/__tests__/factory.test.ts +70 -0
- package/runtime/packages/core/src/memory/__tests__/local-provider.test.ts +195 -0
- package/runtime/packages/core/src/memory/__tests__/mem0-provider.test.ts +192 -0
- package/runtime/packages/core/src/memory/__tests__/smart-defaults.test.ts +46 -0
- package/runtime/packages/core/src/memory/factory.ts +63 -0
- package/runtime/packages/core/src/memory/index.ts +10 -0
- package/runtime/packages/core/src/memory/local/provider.ts +229 -0
- package/runtime/packages/core/src/memory/mem0/provider.ts +379 -0
- package/runtime/packages/core/src/memory/types.ts +96 -0
- package/runtime/packages/core/src/topic-utils.ts +95 -0
- package/runtime/packages/core/src/transport/factory.ts +47 -0
- package/runtime/packages/core/src/transport/local/conversion.ts +333 -0
- package/runtime/packages/core/src/transport/local/entities.ts +129 -0
- package/runtime/packages/core/src/transport/local/transport.ts +406 -0
- package/runtime/packages/core/src/transport/rosbridge/actions.ts +81 -0
- package/runtime/packages/core/src/transport/rosbridge/adapter.ts +157 -0
- package/runtime/packages/core/src/transport/rosbridge/client.ts +438 -0
- package/runtime/packages/core/src/transport/rosbridge/services.ts +41 -0
- package/runtime/packages/core/src/transport/rosbridge/topics.ts +60 -0
- package/runtime/packages/core/src/transport/rosbridge/types.ts +118 -0
- package/runtime/packages/core/src/transport/transport.ts +77 -0
- package/runtime/packages/core/src/transport/types.ts +137 -0
- package/runtime/packages/core/src/transport/webrtc/signaling-client.ts +196 -0
- package/runtime/packages/core/src/transport/webrtc/signaling-types.ts +130 -0
- package/runtime/packages/core/src/transport/webrtc/transport.ts +516 -0
- package/runtime/packages/core/src/transport/zenoh/adapter.ts +357 -0
- package/runtime/packages/core/src/transport/zenoh/cdr.ts +183 -0
- package/runtime/packages/core/src/transport/zenoh/keys.ts +51 -0
- package/runtime/packages/core/tsconfig.json +9 -0
- package/runtime/packages/ros-camera/package.json +30 -0
- package/runtime/packages/ros-camera/src/index.ts +13 -0
- package/runtime/packages/ros-camera/src/snapshot.ts +372 -0
- package/runtime/packages/ros-camera/tsconfig.json +9 -0
- package/runtime/pnpm-lock.yaml +5260 -0
- package/runtime/pnpm-workspace.yaml +2 -0
- package/runtime/ros2_ws/src/agenticros_agent/agenticros_agent/__init__.py +0 -0
- package/runtime/ros2_ws/src/agenticros_agent/agenticros_agent/agent_node.py +561 -0
- package/runtime/ros2_ws/src/agenticros_agent/package.xml +25 -0
- package/runtime/ros2_ws/src/agenticros_agent/resource/agenticros_agent +0 -0
- package/runtime/ros2_ws/src/agenticros_agent/setup.cfg +4 -0
- package/runtime/ros2_ws/src/agenticros_agent/setup.py +25 -0
- package/runtime/ros2_ws/src/agenticros_bringup/README.md +128 -0
- package/runtime/ros2_ws/src/agenticros_bringup/agenticros_bringup/__init__.py +1 -0
- package/runtime/ros2_ws/src/agenticros_bringup/agenticros_bringup/cmd_vel_relay.py +33 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/cmd_vel_bridge.launch.py +58 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/gazebo_turtlebot3.launch.py +69 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/mode_a_gazebo.launch.py +55 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/mode_a_gazebo_rviz.launch.py +48 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/realsense_rosbridge.launch.py +154 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/rosbridge_gazebo.launch.py +54 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/rviz.launch.py +38 -0
- package/runtime/ros2_ws/src/agenticros_bringup/launch/turtlebot3_gazebo_rviz.launch.py +42 -0
- package/runtime/ros2_ws/src/agenticros_bringup/package.xml +24 -0
- package/runtime/ros2_ws/src/agenticros_bringup/resource/agenticros_bringup +0 -0
- package/runtime/ros2_ws/src/agenticros_bringup/rviz/turtlebot3_agenticros.rviz +174 -0
- package/runtime/ros2_ws/src/agenticros_bringup/setup.cfg +4 -0
- package/runtime/ros2_ws/src/agenticros_bringup/setup.py +28 -0
- package/runtime/ros2_ws/src/agenticros_discovery/agenticros_discovery/__init__.py +0 -0
- package/runtime/ros2_ws/src/agenticros_discovery/agenticros_discovery/discovery_node.py +172 -0
- package/runtime/ros2_ws/src/agenticros_discovery/package.xml +22 -0
- package/runtime/ros2_ws/src/agenticros_discovery/resource/agenticros_discovery +0 -0
- package/runtime/ros2_ws/src/agenticros_discovery/setup.cfg +5 -0
- package/runtime/ros2_ws/src/agenticros_discovery/setup.py +25 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/README.md +66 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/__init__.py +1 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/__main__.py +5 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/follow_me_node.py +278 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/follower_controller.py +631 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/agenticros_follow_me/person_tracker.py +635 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/package.xml +22 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/resource/agenticros_follow_me +0 -0
- package/runtime/ros2_ws/src/agenticros_follow_me/setup.py +25 -0
- package/runtime/ros2_ws/src/agenticros_msgs/CMakeLists.txt +26 -0
- package/runtime/ros2_ws/src/agenticros_msgs/msg/CapabilityManifest.msg +9 -0
- package/runtime/ros2_ws/src/agenticros_msgs/package.xml +22 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeGetStatus.srv +11 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeSetDistance.srv +4 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeSetTarget.srv +6 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeStart.srv +5 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/FollowMeStop.srv +3 -0
- package/runtime/ros2_ws/src/agenticros_msgs/srv/GetCapabilities.srv +5 -0
- package/runtime/ros2_ws/src/agenticros_sim/CMakeLists.txt +24 -0
- package/runtime/ros2_ws/src/agenticros_sim/README.md +120 -0
- package/runtime/ros2_ws/src/agenticros_sim/config/agenticros-sim.config.json +28 -0
- package/runtime/ros2_ws/src/agenticros_sim/config/amr_bridge.yaml +111 -0
- package/runtime/ros2_ws/src/agenticros_sim/config/amr_view.rviz +172 -0
- package/runtime/ros2_ws/src/agenticros_sim/env-hooks/gz_resource_path.dsv.in +3 -0
- package/runtime/ros2_ws/src/agenticros_sim/env-hooks/gz_resource_path.sh.in +7 -0
- package/runtime/ros2_ws/src/agenticros_sim/launch/sim_amr.launch.py +159 -0
- package/runtime/ros2_ws/src/agenticros_sim/models/agenticros_amr/model.config +17 -0
- package/runtime/ros2_ws/src/agenticros_sim/models/agenticros_amr/model.sdf +244 -0
- package/runtime/ros2_ws/src/agenticros_sim/package.xml +27 -0
- package/runtime/ros2_ws/src/agenticros_sim/worlds/agenticros_indoor.sdf +183 -0
- package/runtime/scripts/activate_workspace.sh +285 -0
- package/runtime/scripts/agenticros-describer.policy.yaml +96 -0
- package/runtime/scripts/agenticros-proxy.cjs +99 -0
- package/runtime/scripts/agenticros-rosbridge.policy.yaml +62 -0
- package/runtime/scripts/check-cli-tarball-size.mjs +42 -0
- package/runtime/scripts/configure_agenticros.sh +200 -0
- package/runtime/scripts/configure_for_sim.sh +64 -0
- package/runtime/scripts/fix-openclaw-control-ui-path.sh +20 -0
- package/runtime/scripts/install_cli.sh +94 -0
- package/runtime/scripts/install_rosbridge_from_source.sh +67 -0
- package/runtime/scripts/lib/agenticros-banner.sh +28 -0
- package/runtime/scripts/onboard_robot.sh +75 -0
- package/runtime/scripts/openai.policy.yaml +77 -0
- package/runtime/scripts/openclaw-dashboard-url.cjs +49 -0
- package/runtime/scripts/pack-runtime.mjs +245 -0
- package/runtime/scripts/run_demo_native.sh +43 -0
- package/runtime/scripts/run_nemoclaw_host_stack.sh +91 -0
- package/runtime/scripts/run_robot_rosbridge.sh +36 -0
- package/runtime/scripts/sandbox_rosbridge_relay.py +137 -0
- package/runtime/scripts/setup-openclaw-local.cjs +75 -0
- package/runtime/scripts/setup_gateway_plugin.sh +329 -0
- package/runtime/scripts/setup_robot.sh +113 -0
- package/runtime/scripts/setup_workspace.sh +484 -0
- package/runtime/scripts/sim/run_sim.sh +146 -0
- package/runtime/scripts/smoke_test_nemoclaw.sh +123 -0
- package/runtime/scripts/start_demo.sh +55 -0
- package/runtime/scripts/sync-skill-tools.mjs +335 -0
- package/runtime/scripts/test-follow-me-sim.mjs +135 -0
- package/runtime/scripts/test-mcp-e2e.mjs +184 -0
- package/runtime/scripts/test-rclnodejs.mts +129 -0
- package/runtime/scripts/use-openclaw-2026.2.26.sh +19 -0
- package/runtime/scripts/use-openclaw-2026.3.11.sh +19 -0
- package/runtime/scripts/zenoh-bridge-ros2dds-robot.json5 +30 -0
- package/runtime/scripts/zenohd-agenticros.json5 +11 -0
- package/runtime/scripts/zenohd-rosclaw.json5 +11 -0
- package/runtime/tsconfig.base.json +19 -0
- package/index.js +0 -6
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "agenticros",
|
|
3
|
+
"name": "AgenticROS",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"description": "ROS2 integration for AI agent platforms (OpenClaw adapter)",
|
|
6
|
+
"activation": {
|
|
7
|
+
"onStartup": true
|
|
8
|
+
},
|
|
9
|
+
"contracts": {
|
|
10
|
+
"tools": [
|
|
11
|
+
"ros2_publish",
|
|
12
|
+
"ros2_subscribe_once",
|
|
13
|
+
"ros2_service_call",
|
|
14
|
+
"ros2_action_goal",
|
|
15
|
+
"ros2_param_get",
|
|
16
|
+
"ros2_param_set",
|
|
17
|
+
"ros2_list_topics",
|
|
18
|
+
"ros2_camera_snapshot",
|
|
19
|
+
"ros2_depth_distance",
|
|
20
|
+
"memory_remember",
|
|
21
|
+
"memory_recall",
|
|
22
|
+
"memory_forget",
|
|
23
|
+
"memory_status",
|
|
24
|
+
"follow_robot",
|
|
25
|
+
"follow_me_see",
|
|
26
|
+
"ollama_status"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"configSchema": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"properties": {
|
|
33
|
+
"transport": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"properties": {
|
|
36
|
+
"mode": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"enum": [
|
|
39
|
+
"rosbridge",
|
|
40
|
+
"local",
|
|
41
|
+
"webrtc",
|
|
42
|
+
"zenoh"
|
|
43
|
+
],
|
|
44
|
+
"description": "Transport mode: local (Mode A, default — gateway co-located with the robot), rosbridge (Mode B, off-robot via WebSocket), webrtc (Mode C, cloud), or zenoh (Mode D)",
|
|
45
|
+
"default": "local"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"rosbridge": {
|
|
50
|
+
"type": "object",
|
|
51
|
+
"properties": {
|
|
52
|
+
"url": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"description": "Rosbridge WebSocket URL",
|
|
55
|
+
"default": "ws://localhost:9090"
|
|
56
|
+
},
|
|
57
|
+
"reconnect": {
|
|
58
|
+
"type": "boolean",
|
|
59
|
+
"description": "Auto-reconnect on disconnect",
|
|
60
|
+
"default": true
|
|
61
|
+
},
|
|
62
|
+
"reconnectInterval": {
|
|
63
|
+
"type": "number",
|
|
64
|
+
"description": "Reconnect interval in milliseconds",
|
|
65
|
+
"default": 3000
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"required": [
|
|
69
|
+
"url"
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"local": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"properties": {
|
|
75
|
+
"domainId": {
|
|
76
|
+
"type": "number",
|
|
77
|
+
"description": "ROS2 domain ID for local DDS communication",
|
|
78
|
+
"default": 0
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"zenoh": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"properties": {
|
|
85
|
+
"routerEndpoint": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"description": "Zenoh router endpoint (e.g. ws://localhost:10000 for zenoh-ts)",
|
|
88
|
+
"default": "tcp/localhost:7447"
|
|
89
|
+
},
|
|
90
|
+
"domainId": {
|
|
91
|
+
"type": "number",
|
|
92
|
+
"description": "ROS2 domain ID (matches rmw_zenoh)",
|
|
93
|
+
"default": 0
|
|
94
|
+
},
|
|
95
|
+
"keyFormat": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"enum": [
|
|
98
|
+
"ros2dds",
|
|
99
|
+
"rmw_zenoh"
|
|
100
|
+
],
|
|
101
|
+
"description": "Use ros2dds when using zenoh-bridge-ros2dds; use rmw_zenoh when robot uses Zenoh RMW directly",
|
|
102
|
+
"default": "ros2dds"
|
|
103
|
+
},
|
|
104
|
+
"bridgeNamespace": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"description": "Must match zenoh-bridge-ros2dds plugins.ros2dds.namespace when not default \"/\" (e.g. \"/bot1\"). Omit for default bridge namespace."
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"webrtc": {
|
|
111
|
+
"type": "object",
|
|
112
|
+
"properties": {
|
|
113
|
+
"signalingUrl": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"description": "WebSocket URL of the signaling server (e.g., wss://signal-host)"
|
|
116
|
+
},
|
|
117
|
+
"apiUrl": {
|
|
118
|
+
"type": "string",
|
|
119
|
+
"description": "REST API URL of the signaling server (e.g., https://signal-host)"
|
|
120
|
+
},
|
|
121
|
+
"robotId": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"description": "Target robot's ID on the signaling server"
|
|
124
|
+
},
|
|
125
|
+
"robotKey": {
|
|
126
|
+
"type": "string",
|
|
127
|
+
"description": "Robot key secret (validated by robot, not server)"
|
|
128
|
+
},
|
|
129
|
+
"iceServers": {
|
|
130
|
+
"type": "array",
|
|
131
|
+
"description": "STUN/TURN server configuration",
|
|
132
|
+
"items": {
|
|
133
|
+
"type": "object",
|
|
134
|
+
"properties": {
|
|
135
|
+
"urls": {
|
|
136
|
+
"description": "STUN/TURN server URL(s)"
|
|
137
|
+
},
|
|
138
|
+
"username": {
|
|
139
|
+
"type": "string"
|
|
140
|
+
},
|
|
141
|
+
"credential": {
|
|
142
|
+
"type": "string"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
"default": [
|
|
147
|
+
{
|
|
148
|
+
"urls": "stun:stun.l.google.com:19302"
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"robot": {
|
|
155
|
+
"type": "object",
|
|
156
|
+
"properties": {
|
|
157
|
+
"name": {
|
|
158
|
+
"type": "string",
|
|
159
|
+
"description": "Robot display name",
|
|
160
|
+
"default": "Robot"
|
|
161
|
+
},
|
|
162
|
+
"namespace": {
|
|
163
|
+
"type": "string",
|
|
164
|
+
"description": "ROS2 topic namespace so cmd_vel and other root-level topics are published to /<namespace>/<topic> (e.g. robot3946b404c33e4aa39a8d16deb1c5c593 → /robot3946.../cmd_vel). Required if the robot base subscribes to a namespaced cmd_vel.",
|
|
165
|
+
"default": ""
|
|
166
|
+
},
|
|
167
|
+
"cameraTopic": {
|
|
168
|
+
"type": "string",
|
|
169
|
+
"description": "Camera topic for what do you see and default for teleop",
|
|
170
|
+
"default": ""
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
"teleop": {
|
|
175
|
+
"type": "object",
|
|
176
|
+
"description": "Teleop web app: camera and twist controls",
|
|
177
|
+
"properties": {
|
|
178
|
+
"cameraTopic": {
|
|
179
|
+
"type": "string",
|
|
180
|
+
"default": ""
|
|
181
|
+
},
|
|
182
|
+
"cameraTopics": {
|
|
183
|
+
"type": "array",
|
|
184
|
+
"items": {
|
|
185
|
+
"type": "object",
|
|
186
|
+
"properties": {
|
|
187
|
+
"topic": {
|
|
188
|
+
"type": "string"
|
|
189
|
+
},
|
|
190
|
+
"label": {
|
|
191
|
+
"type": "string"
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"default": []
|
|
196
|
+
},
|
|
197
|
+
"cmdVelTopic": {
|
|
198
|
+
"type": "string",
|
|
199
|
+
"default": ""
|
|
200
|
+
},
|
|
201
|
+
"speedDefault": {
|
|
202
|
+
"type": "number",
|
|
203
|
+
"description": "Default linear speed (m/s) for teleop",
|
|
204
|
+
"default": 0.3,
|
|
205
|
+
"minimum": 0,
|
|
206
|
+
"maximum": 2
|
|
207
|
+
},
|
|
208
|
+
"cameraPollMs": {
|
|
209
|
+
"type": "number",
|
|
210
|
+
"default": 150,
|
|
211
|
+
"minimum": 50,
|
|
212
|
+
"maximum": 2000
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
"safety": {
|
|
217
|
+
"type": "object",
|
|
218
|
+
"properties": {
|
|
219
|
+
"maxLinearVelocity": {
|
|
220
|
+
"type": "number",
|
|
221
|
+
"description": "Maximum linear velocity (m/s)",
|
|
222
|
+
"default": 1
|
|
223
|
+
},
|
|
224
|
+
"maxAngularVelocity": {
|
|
225
|
+
"type": "number",
|
|
226
|
+
"description": "Maximum angular velocity (rad/s)",
|
|
227
|
+
"default": 1.5
|
|
228
|
+
},
|
|
229
|
+
"workspaceLimits": {
|
|
230
|
+
"type": "object",
|
|
231
|
+
"description": "Workspace boundary limits (meters)",
|
|
232
|
+
"properties": {
|
|
233
|
+
"xMin": {
|
|
234
|
+
"type": "number",
|
|
235
|
+
"default": -10
|
|
236
|
+
},
|
|
237
|
+
"xMax": {
|
|
238
|
+
"type": "number",
|
|
239
|
+
"default": 10
|
|
240
|
+
},
|
|
241
|
+
"yMin": {
|
|
242
|
+
"type": "number",
|
|
243
|
+
"default": -10
|
|
244
|
+
},
|
|
245
|
+
"yMax": {
|
|
246
|
+
"type": "number",
|
|
247
|
+
"default": 10
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"describer": {
|
|
254
|
+
"type": "object",
|
|
255
|
+
"description": "Optional in-plugin image describer. When enabled, ros2_camera_snapshot calls an OpenAI-compatible vision endpoint (typically local Ollama with a qwen2.5-VL model) and embeds the description text directly in the tool result. Required when the primary chat model is text-only (e.g. qwen2.5:7b for tool calling on Jetson) because OpenClaw filters image content blocks out of tool results for text-only models, leaving the agent unable to describe what the robot sees.",
|
|
256
|
+
"properties": {
|
|
257
|
+
"enabled": {
|
|
258
|
+
"type": "boolean",
|
|
259
|
+
"default": false,
|
|
260
|
+
"description": "Master switch for the describer."
|
|
261
|
+
},
|
|
262
|
+
"url": {
|
|
263
|
+
"type": "string",
|
|
264
|
+
"default": "http://host.openshell.internal:11435/v1/chat/completions",
|
|
265
|
+
"description": "OpenAI-compat chat completions endpoint URL (e.g. Ollama)."
|
|
266
|
+
},
|
|
267
|
+
"apiKey": {
|
|
268
|
+
"type": "string",
|
|
269
|
+
"description": "Optional Bearer token for the endpoint."
|
|
270
|
+
},
|
|
271
|
+
"model": {
|
|
272
|
+
"type": "string",
|
|
273
|
+
"default": "qwen2.5vl:7b",
|
|
274
|
+
"description": "Vision model id (must accept OpenAI image_url content blocks)."
|
|
275
|
+
},
|
|
276
|
+
"prompt": {
|
|
277
|
+
"type": "string",
|
|
278
|
+
"description": "Prompt sent alongside each image. A reasonable default is used when omitted."
|
|
279
|
+
},
|
|
280
|
+
"maxTokens": {
|
|
281
|
+
"type": "number",
|
|
282
|
+
"default": 400,
|
|
283
|
+
"minimum": 50,
|
|
284
|
+
"maximum": 2048,
|
|
285
|
+
"description": "Max tokens to generate for each description."
|
|
286
|
+
},
|
|
287
|
+
"timeoutMs": {
|
|
288
|
+
"type": "number",
|
|
289
|
+
"default": 60000,
|
|
290
|
+
"minimum": 1000,
|
|
291
|
+
"maximum": 180000,
|
|
292
|
+
"description": "HTTP request timeout in milliseconds."
|
|
293
|
+
},
|
|
294
|
+
"maxImageDimension": {
|
|
295
|
+
"type": "number",
|
|
296
|
+
"default": 896,
|
|
297
|
+
"minimum": 0,
|
|
298
|
+
"maximum": 4096,
|
|
299
|
+
"description": "Resize images larger than this max dimension before sending to the VL model. 0 disables resizing."
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
"memory": {
|
|
304
|
+
"type": "object",
|
|
305
|
+
"description": "Optional cross-adapter semantic memory. Off by default; see docs/memory.md.",
|
|
306
|
+
"properties": {
|
|
307
|
+
"enabled": {
|
|
308
|
+
"type": "boolean",
|
|
309
|
+
"default": false,
|
|
310
|
+
"description": "Master switch. When false, no memory tools are registered."
|
|
311
|
+
},
|
|
312
|
+
"backend": {
|
|
313
|
+
"type": "string",
|
|
314
|
+
"enum": ["local", "mem0"],
|
|
315
|
+
"default": "local",
|
|
316
|
+
"description": "local = JSON-on-disk, no deps; mem0 = semantic search via mem0ai (requires `pnpm add mem0ai`)."
|
|
317
|
+
},
|
|
318
|
+
"namespace": {
|
|
319
|
+
"type": "string",
|
|
320
|
+
"description": "Override per-record namespace. Defaults to robot.namespace at call time."
|
|
321
|
+
},
|
|
322
|
+
"local": {
|
|
323
|
+
"type": "object",
|
|
324
|
+
"properties": {
|
|
325
|
+
"storePath": {
|
|
326
|
+
"type": "string",
|
|
327
|
+
"default": "~/.agenticros/memory.json"
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
"mem0": {
|
|
332
|
+
"type": "object",
|
|
333
|
+
"properties": {
|
|
334
|
+
"inferOnWrite": {
|
|
335
|
+
"type": "boolean",
|
|
336
|
+
"default": false,
|
|
337
|
+
"description": "When true, mem0 LLM-extracts facts on add. Default false (raw store)."
|
|
338
|
+
},
|
|
339
|
+
"historyDbPath": {
|
|
340
|
+
"type": "string",
|
|
341
|
+
"default": "~/.agenticros/memory-history.db"
|
|
342
|
+
},
|
|
343
|
+
"embedder": {
|
|
344
|
+
"type": "object",
|
|
345
|
+
"description": "Optional. When omitted, factory auto-detects Ollama → OpenAI → error."
|
|
346
|
+
},
|
|
347
|
+
"vectorStore": {
|
|
348
|
+
"type": "object",
|
|
349
|
+
"description": "Optional. Passed to mem0 verbatim."
|
|
350
|
+
},
|
|
351
|
+
"llm": {
|
|
352
|
+
"type": "object",
|
|
353
|
+
"description": "Optional. Required only when inferOnWrite is true."
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
"skills": {
|
|
360
|
+
"type": "object",
|
|
361
|
+
"description": "Per-skill config. Keys are skill ids (e.g. followme). Each skill validates its own slice.",
|
|
362
|
+
"additionalProperties": true
|
|
363
|
+
},
|
|
364
|
+
"skillPaths": {
|
|
365
|
+
"type": "array",
|
|
366
|
+
"description": "Directories to scan for skill packages (package.json with agenticrosSkill: true).",
|
|
367
|
+
"items": {
|
|
368
|
+
"type": "string"
|
|
369
|
+
},
|
|
370
|
+
"default": []
|
|
371
|
+
},
|
|
372
|
+
"skillPackages": {
|
|
373
|
+
"type": "array",
|
|
374
|
+
"description": "Npm (or local) package names to load as skills (e.g. agenticros-skill-followme).",
|
|
375
|
+
"items": {
|
|
376
|
+
"type": "string"
|
|
377
|
+
},
|
|
378
|
+
"default": []
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
"uiHints": {
|
|
383
|
+
"transport.mode": {
|
|
384
|
+
"label": "Transport Mode",
|
|
385
|
+
"description": "How the plugin connects to ROS2: rosbridge (WebSocket), local (DDS), webrtc (P2P), or zenoh (Mode D)"
|
|
386
|
+
},
|
|
387
|
+
"zenoh.routerEndpoint": {
|
|
388
|
+
"label": "Zenoh Router Endpoint",
|
|
389
|
+
"placeholder": "ws://localhost:10000"
|
|
390
|
+
},
|
|
391
|
+
"zenoh.domainId": {
|
|
392
|
+
"label": "Zenoh Domain ID",
|
|
393
|
+
"advanced": true
|
|
394
|
+
},
|
|
395
|
+
"zenoh.bridgeNamespace": {
|
|
396
|
+
"label": "Zenoh bridge ROS namespace",
|
|
397
|
+
"description": "Same as ros2dds.namespace on the robot bridge when not \"/\"",
|
|
398
|
+
"advanced": true
|
|
399
|
+
},
|
|
400
|
+
"rosbridge.url": {
|
|
401
|
+
"label": "Rosbridge URL",
|
|
402
|
+
"placeholder": "ws://localhost:9090"
|
|
403
|
+
},
|
|
404
|
+
"robot.name": {
|
|
405
|
+
"label": "Robot Name",
|
|
406
|
+
"placeholder": "Robot"
|
|
407
|
+
},
|
|
408
|
+
"robot.namespace": {
|
|
409
|
+
"label": "ROS2 Robot Namespace",
|
|
410
|
+
"description": "ROS2 topic namespace; e.g. robot-uuid gives topics like /robot-uuid/cmd_vel",
|
|
411
|
+
"placeholder": ""
|
|
412
|
+
},
|
|
413
|
+
"safety.maxLinearVelocity": {
|
|
414
|
+
"label": "Max Linear Velocity (m/s)",
|
|
415
|
+
"advanced": true
|
|
416
|
+
},
|
|
417
|
+
"safety.maxAngularVelocity": {
|
|
418
|
+
"label": "Max Angular Velocity (rad/s)",
|
|
419
|
+
"advanced": true
|
|
420
|
+
},
|
|
421
|
+
"safety.workspaceLimits": {
|
|
422
|
+
"label": "Workspace Boundary Limits",
|
|
423
|
+
"advanced": true
|
|
424
|
+
},
|
|
425
|
+
"skills.followme.depthTopic": {
|
|
426
|
+
"label": "Follow Me — depth image topic",
|
|
427
|
+
"description": "sensor_msgs/Image depth topic for distance (e.g. RealSense depth)"
|
|
428
|
+
},
|
|
429
|
+
"skills.followme.rateHz": {
|
|
430
|
+
"label": "Follow Me — loop rate (Hz)",
|
|
431
|
+
"advanced": true
|
|
432
|
+
},
|
|
433
|
+
"skills.followme.invertLinearX": {
|
|
434
|
+
"label": "Follow Me — invert cmd_vel linear.x",
|
|
435
|
+
"description": "Flip forward/back if the base drives the wrong way",
|
|
436
|
+
"advanced": true
|
|
437
|
+
},
|
|
438
|
+
"skills.followme.logTickTiming": {
|
|
439
|
+
"label": "Follow Me — log tick timing",
|
|
440
|
+
"description": "Emit latency logs for depth / sectors / Ollama per tick",
|
|
441
|
+
"advanced": true
|
|
442
|
+
},
|
|
443
|
+
"skills.followme.criticalStopDistanceM": {
|
|
444
|
+
"label": "Follow Me — hard stop distance (m)"
|
|
445
|
+
},
|
|
446
|
+
"skills.followme.maxVelocityFraction": {
|
|
447
|
+
"label": "Follow Me — max speed fraction of Safety limits",
|
|
448
|
+
"description": "Caps linear/angular vs safety.maxLinearVelocity / maxAngularVelocity (e.g. 0.2 = 20%)"
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agenticros/openclaw",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "AgenticROS OpenClaw plugin — ROS2 tools, commands, and routes for the OpenClaw gateway",
|
|
6
|
+
"openclaw": {
|
|
7
|
+
"id": "agenticros",
|
|
8
|
+
"activation": {
|
|
9
|
+
"onStartup": true
|
|
10
|
+
},
|
|
11
|
+
"extensions": [
|
|
12
|
+
"./dist/index.js"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"typecheck": "tsc --noEmit"
|
|
18
|
+
},
|
|
19
|
+
"openclaw": {
|
|
20
|
+
"extensions": [
|
|
21
|
+
"./dist/index.js"
|
|
22
|
+
],
|
|
23
|
+
"compat": {
|
|
24
|
+
"pluginApi": ">=2026.3.24-beta.2"
|
|
25
|
+
},
|
|
26
|
+
"build": {
|
|
27
|
+
"openclawVersion": "2026.3.24-beta.2"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@agenticros/core": "workspace:*",
|
|
32
|
+
"@agenticros/ros-camera": "workspace:*",
|
|
33
|
+
"@sinclair/typebox": "^0.34.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^20.17.0",
|
|
37
|
+
"typescript": "^5.7.0"
|
|
38
|
+
},
|
|
39
|
+
"author": "PlaiPin",
|
|
40
|
+
"license": "Apache-2.0"
|
|
41
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
type Entry = { body: Buffer; mimeType: string; at: number };
|
|
4
|
+
|
|
5
|
+
const TTL_MS = 15 * 60 * 1000;
|
|
6
|
+
const MAX_ENTRIES = 64;
|
|
7
|
+
const MAX_BYTES = 12 * 1024 * 1024;
|
|
8
|
+
|
|
9
|
+
const cache = new Map<string, Entry>();
|
|
10
|
+
|
|
11
|
+
function prune(): void {
|
|
12
|
+
const now = Date.now();
|
|
13
|
+
for (const [k, v] of cache) {
|
|
14
|
+
if (now - v.at > TTL_MS) {
|
|
15
|
+
cache.delete(k);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
while (cache.size > MAX_ENTRIES) {
|
|
19
|
+
let oldestKey: string | undefined;
|
|
20
|
+
let oldestAt = Infinity;
|
|
21
|
+
for (const [k, v] of cache) {
|
|
22
|
+
if (v.at < oldestAt) {
|
|
23
|
+
oldestAt = v.at;
|
|
24
|
+
oldestKey = k;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (oldestKey) {
|
|
28
|
+
cache.delete(oldestKey);
|
|
29
|
+
} else {
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Store one frame for GET /camera/snapshot?id=… (chat UI same as teleop: raw bytes, not data URLs).
|
|
37
|
+
*/
|
|
38
|
+
export function storeCameraSnapshot(body: Buffer, mimeType: string): string {
|
|
39
|
+
prune();
|
|
40
|
+
if (body.length > MAX_BYTES) {
|
|
41
|
+
throw new Error(`Snapshot exceeds ${MAX_BYTES} bytes`);
|
|
42
|
+
}
|
|
43
|
+
const id = randomBytes(16).toString("hex");
|
|
44
|
+
cache.set(id, { body, mimeType: mimeType.trim() || "image/jpeg", at: Date.now() });
|
|
45
|
+
return id;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function getCameraSnapshot(id: string): Entry | undefined {
|
|
49
|
+
prune();
|
|
50
|
+
const e = cache.get(id);
|
|
51
|
+
if (!e) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
if (Date.now() - e.at > TTL_MS) {
|
|
55
|
+
cache.delete(id);
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return e;
|
|
59
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { OpenClawPluginApi, HttpRouteRequest, HttpRouteResponse } from "./plugin-api.js";
|
|
2
|
+
import { getCameraSnapshot } from "./camera-snapshot-cache.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Serves cached ros2_camera_snapshot bytes (JPEG/PNG) for chat markdown — avoids huge data: URLs.
|
|
6
|
+
*/
|
|
7
|
+
export function registerCameraSnapshotRoutes(api: OpenClawPluginApi): void {
|
|
8
|
+
const register = api.registerHttpRoute;
|
|
9
|
+
if (typeof register !== "function") {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const handler = (req: HttpRouteRequest, res: HttpRouteResponse) => {
|
|
14
|
+
const url = req.url ?? "";
|
|
15
|
+
const u = new URL(url, "http://localhost");
|
|
16
|
+
const id = u.searchParams.get("id")?.trim() ?? "";
|
|
17
|
+
if (!id || !/^[a-f0-9]{32}$/i.test(id)) {
|
|
18
|
+
res.statusCode = 400;
|
|
19
|
+
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
|
20
|
+
res.end("Missing or invalid id");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const entry = getCameraSnapshot(id);
|
|
24
|
+
if (!entry) {
|
|
25
|
+
res.statusCode = 404;
|
|
26
|
+
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
|
27
|
+
res.end("Snapshot not found or expired");
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
res.setHeader("Content-Type", entry.mimeType);
|
|
31
|
+
res.setHeader("Cache-Control", "no-store");
|
|
32
|
+
res.statusCode = 200;
|
|
33
|
+
res.end(entry.body);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const route = (opts: { path: string; method?: string; handler: typeof handler }) =>
|
|
37
|
+
register({ ...opts, requireAuth: false, auth: "plugin" });
|
|
38
|
+
|
|
39
|
+
for (const base of ["/agenticros", "/api/agenticros", "/plugins/agenticros"]) {
|
|
40
|
+
route({ path: `${base}/camera/snapshot`, method: "GET", handler });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
api.logger.info("AgenticROS: camera snapshot route registered (GET .../camera/snapshot?id=)");
|
|
44
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "../plugin-api.js";
|
|
2
|
+
import type { AgenticROSConfig } from "@agenticros/core";
|
|
3
|
+
import { getTransport } from "../service.js";
|
|
4
|
+
import { getCmdVelTopic } from "../teleop/routes.js";
|
|
5
|
+
|
|
6
|
+
const TWIST_TYPE = "geometry_msgs/msg/Twist";
|
|
7
|
+
const ZERO_TWIST = {
|
|
8
|
+
linear: { x: 0, y: 0, z: 0 },
|
|
9
|
+
angular: { x: 0, y: 0, z: 0 },
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Register the /estop command.
|
|
14
|
+
* This command bypasses the AI agent and immediately sends a zero-velocity
|
|
15
|
+
* command to stop the robot. Uses the same cmd_vel topic as teleop/skills
|
|
16
|
+
* (config.teleop.cmdVelTopic or robot namespace).
|
|
17
|
+
*/
|
|
18
|
+
export function registerEstopCommand(api: OpenClawPluginApi, config: AgenticROSConfig): void {
|
|
19
|
+
api.registerCommand({
|
|
20
|
+
name: "estop",
|
|
21
|
+
description: "Emergency stop — immediately halt the robot (bypasses AI)",
|
|
22
|
+
|
|
23
|
+
async handler(_ctx) {
|
|
24
|
+
try {
|
|
25
|
+
const transport = getTransport();
|
|
26
|
+
const topic = getCmdVelTopic(config);
|
|
27
|
+
|
|
28
|
+
// Send zero repeatedly so the base reliably stops
|
|
29
|
+
for (let i = 0; i < 5; i++) {
|
|
30
|
+
transport.publish({ topic, type: TWIST_TYPE, msg: ZERO_TWIST });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
api.logger.warn("ESTOP: Zero velocity command sent");
|
|
34
|
+
return { text: "Emergency stop activated. Robot halted." };
|
|
35
|
+
} catch (error) {
|
|
36
|
+
api.logger.error(`ESTOP FAILED: ${String(error)}`);
|
|
37
|
+
return { text: "Emergency stop failed — transport may be disconnected!" };
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|