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,498 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the AgenticROS config page HTML.
|
|
3
|
+
* Page fetches config.json (relative), renders an editable form, and on Save POSTs to config/save. Served under /plugins/agenticros/ or /api/agenticros/.
|
|
4
|
+
*/
|
|
5
|
+
export function getConfigPageHtml(): string {
|
|
6
|
+
return `<!DOCTYPE html>
|
|
7
|
+
<html lang="en">
|
|
8
|
+
<head>
|
|
9
|
+
<meta charset="UTF-8" />
|
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
11
|
+
<title>AgenticROS Config</title>
|
|
12
|
+
<style>
|
|
13
|
+
* { box-sizing: border-box; }
|
|
14
|
+
body { font-family: system-ui, sans-serif; margin: 12px; background: #1a1a1a; color: #e0e0e0; max-width: 720px; }
|
|
15
|
+
h1 { font-size: 1.5rem; margin: 0 0 8px 0; }
|
|
16
|
+
a { color: #0c9; text-decoration: none; }
|
|
17
|
+
a:hover { text-decoration: underline; }
|
|
18
|
+
.banner { border-radius: 8px; padding: 12px; margin-bottom: 16px; font-size: 0.9rem; }
|
|
19
|
+
.banner.success { background: #1e3a1e; color: #9f9; border: 1px solid #2a5a2a; }
|
|
20
|
+
.banner.error { background: #3a1e1e; color: #f99; border: 1px solid #5a2a2a; }
|
|
21
|
+
.banner.saving { background: #2a2a2a; color: #ccc; border: 1px solid #555; }
|
|
22
|
+
.banner.hidden { display: none; }
|
|
23
|
+
section { margin-bottom: 24px; }
|
|
24
|
+
section h2 { font-size: 1.1rem; margin: 0 0 8px 0; color: #ccc; }
|
|
25
|
+
label { display: block; margin-bottom: 4px; font-size: 0.9rem; color: #aaa; }
|
|
26
|
+
input[type="text"], input[type="number"], input[type="url"], select { width: 100%; max-width: 400px; padding: 6px 8px; background: #252525; border: 1px solid #444; border-radius: 4px; color: #e0e0e0; font-size: 0.9rem; }
|
|
27
|
+
input[type="checkbox"] { margin-right: 8px; }
|
|
28
|
+
.field { margin-bottom: 12px; }
|
|
29
|
+
.field-hint { font-size: 0.8rem; color: #666; margin-top: 2px; }
|
|
30
|
+
button { background: #0c9; color: #111; border: none; padding: 8px 16px; border-radius: 6px; font-weight: 600; cursor: pointer; font-size: 0.9rem; }
|
|
31
|
+
button:hover { background: #0db; }
|
|
32
|
+
button:disabled { opacity: 0.6; cursor: not-allowed; }
|
|
33
|
+
.readonly { color: #888; font-size: 0.9rem; }
|
|
34
|
+
</style>
|
|
35
|
+
</head>
|
|
36
|
+
<body>
|
|
37
|
+
<h1>AgenticROS Config</h1>
|
|
38
|
+
<p><a href="/plugins/agenticros/">Back to AgenticROS</a></p>
|
|
39
|
+
<div id="banner" class="banner hidden"></div>
|
|
40
|
+
<form id="config-form">
|
|
41
|
+
<section>
|
|
42
|
+
<h2>Transport / Mode</h2>
|
|
43
|
+
<div class="field">
|
|
44
|
+
<label for="transport.mode">Mode</label>
|
|
45
|
+
<select id="transport.mode" name="transport.mode">
|
|
46
|
+
<option value="local">Mode A – Local (same machine as the robot, default)</option>
|
|
47
|
+
<option value="rosbridge">Mode B – Rosbridge (local network)</option>
|
|
48
|
+
<option value="webrtc">Mode C – WebRTC (cloud/remote)</option>
|
|
49
|
+
<option value="zenoh">Mode D – Zenoh</option>
|
|
50
|
+
</select>
|
|
51
|
+
</div>
|
|
52
|
+
</section>
|
|
53
|
+
<section>
|
|
54
|
+
<h2>Robot</h2>
|
|
55
|
+
<div class="field"><label for="robot.name">Name</label><input type="text" id="robot.name" name="robot.name" /></div>
|
|
56
|
+
<div class="field"><label for="robot.namespace">Namespace</label><input type="text" id="robot.namespace" name="robot.namespace" placeholder="e.g. robot-uuid" /></div>
|
|
57
|
+
<div class="field"><label for="robot.cameraTopic">Camera topic</label><input type="text" id="robot.cameraTopic" name="robot.cameraTopic" placeholder="/camera/.../compressed" /></div>
|
|
58
|
+
</section>
|
|
59
|
+
<section id="section-local">
|
|
60
|
+
<h2>Local (Mode A)</h2>
|
|
61
|
+
<div class="field"><label for="local.domainId">Domain ID</label><input type="number" id="local.domainId" name="local.domainId" min="0" /></div>
|
|
62
|
+
</section>
|
|
63
|
+
<section id="section-rosbridge" style="display:none">
|
|
64
|
+
<h2>Rosbridge (Mode B)</h2>
|
|
65
|
+
<div class="field"><label for="rosbridge.url">URL</label><input type="url" id="rosbridge.url" name="rosbridge.url" placeholder="ws://localhost:9090" /></div>
|
|
66
|
+
<div class="field"><label><input type="checkbox" id="rosbridge.reconnect" name="rosbridge.reconnect" /> Reconnect</label></div>
|
|
67
|
+
<div class="field"><label for="rosbridge.reconnectInterval">Reconnect interval (ms)</label><input type="number" id="rosbridge.reconnectInterval" name="rosbridge.reconnectInterval" min="500" step="500" /></div>
|
|
68
|
+
</section>
|
|
69
|
+
<section id="section-zenoh" style="display:none">
|
|
70
|
+
<h2>Zenoh (Mode D)</h2>
|
|
71
|
+
<div class="field"><label for="zenoh.routerEndpoint">Router endpoint</label><input type="text" id="zenoh.routerEndpoint" name="zenoh.routerEndpoint" placeholder="ws://localhost:10000" /></div>
|
|
72
|
+
<div class="field"><label for="zenoh.domainId">Domain ID</label><input type="number" id="zenoh.domainId" name="zenoh.domainId" min="0" /></div>
|
|
73
|
+
<div class="field"><label for="zenoh.keyFormat">Key format</label><select id="zenoh.keyFormat" name="zenoh.keyFormat"><option value="ros2dds">ros2dds</option><option value="rmw_zenoh">rmw_zenoh</option></select></div>
|
|
74
|
+
</section>
|
|
75
|
+
<section id="section-webrtc" style="display:none">
|
|
76
|
+
<h2>WebRTC (Mode C)</h2>
|
|
77
|
+
<div class="field"><label for="webrtc.signalingUrl">Signaling URL</label><input type="url" id="webrtc.signalingUrl" name="webrtc.signalingUrl" /></div>
|
|
78
|
+
<div class="field"><label for="webrtc.apiUrl">API URL</label><input type="url" id="webrtc.apiUrl" name="webrtc.apiUrl" /></div>
|
|
79
|
+
<div class="field"><label for="webrtc.robotId">Robot ID</label><input type="text" id="webrtc.robotId" name="webrtc.robotId" /></div>
|
|
80
|
+
<div class="field"><span class="readonly">robotKey: (set in OpenClaw config only; not editable here)</span></div>
|
|
81
|
+
</section>
|
|
82
|
+
<section>
|
|
83
|
+
<h2>Teleop</h2>
|
|
84
|
+
<div class="field"><label for="teleop.cameraTopic">Camera topic</label><input type="text" id="teleop.cameraTopic" name="teleop.cameraTopic" /></div>
|
|
85
|
+
<div class="field"><label for="teleop.cmdVelTopic">cmd_vel topic</label><input type="text" id="teleop.cmdVelTopic" name="teleop.cmdVelTopic" /></div>
|
|
86
|
+
<div class="field"><label for="teleop.speedDefault">Speed default (m/s)</label><input type="number" id="teleop.speedDefault" name="teleop.speedDefault" min="0" max="2" step="0.1" /></div>
|
|
87
|
+
<div class="field"><label for="teleop.cameraPollMs">Camera poll (ms)</label><input type="number" id="teleop.cameraPollMs" name="teleop.cameraPollMs" min="50" max="2000" step="50" /></div>
|
|
88
|
+
</section>
|
|
89
|
+
<section>
|
|
90
|
+
<h2>Safety</h2>
|
|
91
|
+
<div class="field"><label for="safety.maxLinearVelocity">Max linear velocity</label><input type="number" id="safety.maxLinearVelocity" name="safety.maxLinearVelocity" min="0" step="0.1" /></div>
|
|
92
|
+
<div class="field"><label for="safety.maxAngularVelocity">Max angular velocity</label><input type="number" id="safety.maxAngularVelocity" name="safety.maxAngularVelocity" min="0" step="0.1" /></div>
|
|
93
|
+
</section>
|
|
94
|
+
<section>
|
|
95
|
+
<h2>Memory</h2>
|
|
96
|
+
<p class="field-hint">Optional cross-adapter semantic memory. Shared across OpenClaw, Claude Code, and Gemini when they target the same robot namespace. Off by default. <a href="https://github.com/" target="_blank">See docs/memory.md.</a></p>
|
|
97
|
+
<div class="field">
|
|
98
|
+
<label>Backend</label>
|
|
99
|
+
<label style="display:inline-block;margin-right:14px;font-size:0.9rem;color:#e0e0e0"><input type="radio" name="memory.backendChoice" value="off" /> Off</label>
|
|
100
|
+
<label style="display:inline-block;margin-right:14px;font-size:0.9rem;color:#e0e0e0"><input type="radio" name="memory.backendChoice" value="local" /> Local (no deps, dumb keyword)</label>
|
|
101
|
+
<label style="display:inline-block;font-size:0.9rem;color:#e0e0e0"><input type="radio" name="memory.backendChoice" value="mem0" /> Mem0 (semantic, requires <code>pnpm add mem0ai</code>)</label>
|
|
102
|
+
</div>
|
|
103
|
+
<div id="section-memory-mem0" style="display:none">
|
|
104
|
+
<div class="field"><label><input type="checkbox" id="memory.mem0.inferOnWrite" name="memory.mem0.inferOnWrite" /> Use LLM-driven fact extraction on write (slower, costs tokens)</label></div>
|
|
105
|
+
<div class="field"><label for="memory.mem0.historyDbPath">History DB path</label><input type="text" id="memory.mem0.historyDbPath" name="memory.mem0.historyDbPath" placeholder="~/.agenticros/memory-history.db" /></div>
|
|
106
|
+
<p class="field-hint">Embedder, vector store, and llm overrides require editing <code>~/.openclaw/openclaw.json</code> directly. When unset, the factory auto-detects Ollama (if reachable) then OpenAI (if OPENAI_API_KEY set).</p>
|
|
107
|
+
</div>
|
|
108
|
+
<div id="section-memory-local" style="display:none">
|
|
109
|
+
<div class="field"><label for="memory.local.storePath">Store path</label><input type="text" id="memory.local.storePath" name="memory.local.storePath" placeholder="~/.agenticros/memory.json" /></div>
|
|
110
|
+
</div>
|
|
111
|
+
<div class="field" id="memory-actions" style="display:none">
|
|
112
|
+
<button type="button" id="memory-test-btn">Test</button>
|
|
113
|
+
<button type="button" id="memory-clear-btn" style="background:#a33;color:#fff;margin-left:8px">Clear all in namespace</button>
|
|
114
|
+
<span id="memory-test-status" style="margin-left:10px;color:#aaa;font-size:0.85rem"></span>
|
|
115
|
+
</div>
|
|
116
|
+
<pre id="memory-test-output" style="display:none;background:#252525;padding:8px;border:1px solid #444;border-radius:4px;font-size:0.8rem;color:#9c9;max-width:520px;white-space:pre-wrap;word-break:break-all"></pre>
|
|
117
|
+
</section>
|
|
118
|
+
<section>
|
|
119
|
+
<h2>Skills</h2>
|
|
120
|
+
<div class="field">
|
|
121
|
+
<label for="skillPackages">Skill packages (comma-separated)</label>
|
|
122
|
+
<input type="text" id="skillPackages" name="skillPackages" placeholder="e.g. agenticros-skill-followme" />
|
|
123
|
+
<div class="field-hint">Npm package names to load as skills. Restart gateway after change.</div>
|
|
124
|
+
</div>
|
|
125
|
+
<div class="field">
|
|
126
|
+
<label for="skillPaths">Skill paths (comma-separated)</label>
|
|
127
|
+
<input type="text" id="skillPaths" name="skillPaths" placeholder="e.g. /path/to/skills" />
|
|
128
|
+
<div class="field-hint">Directories to scan for skill packages (package.json with agenticrosSkill: true).</div>
|
|
129
|
+
</div>
|
|
130
|
+
</section>
|
|
131
|
+
<section>
|
|
132
|
+
<h2>Follow Me (<code>skills.followme</code>)</h2>
|
|
133
|
+
<p class="field-hint">Per-skill settings for the Follow Me / follow_robot behavior. Stored under <code>plugins.entries.agenticros.config.skills.followme</code> in OpenClaw JSON.</p>
|
|
134
|
+
<div class="field"><label><input type="checkbox" id="skills.followme.useOllama" name="skills.followme.useOllama" /> Use Ollama VLM for steering (requires camera topic)</label></div>
|
|
135
|
+
<div class="field"><label for="skills.followme.ollamaUrl">Ollama URL</label><input type="url" id="skills.followme.ollamaUrl" name="skills.followme.ollamaUrl" placeholder="http://localhost:11434" /></div>
|
|
136
|
+
<div class="field"><label for="skills.followme.vlmModel">VLM model</label><input type="text" id="skills.followme.vlmModel" name="skills.followme.vlmModel" placeholder="qwen3-vl:2b" /></div>
|
|
137
|
+
<div class="field"><label for="skills.followme.cameraTopic">Camera topic (for Ollama)</label><input type="text" id="skills.followme.cameraTopic" name="skills.followme.cameraTopic" placeholder="/camera/image_raw/compressed" /></div>
|
|
138
|
+
<div class="field">
|
|
139
|
+
<label for="skills.followme.cameraMessageType">Camera message type</label>
|
|
140
|
+
<select id="skills.followme.cameraMessageType" name="skills.followme.cameraMessageType">
|
|
141
|
+
<option value="CompressedImage">CompressedImage</option>
|
|
142
|
+
<option value="Image">Image</option>
|
|
143
|
+
</select>
|
|
144
|
+
</div>
|
|
145
|
+
<div class="field"><label for="skills.followme.depthTopic">Depth image topic</label><input type="text" id="skills.followme.depthTopic" name="skills.followme.depthTopic" placeholder="/camera/camera/depth/image_rect_raw" /></div>
|
|
146
|
+
<div class="field"><label for="skills.followme.cmdVelTopic">cmd_vel override</label><input type="text" id="skills.followme.cmdVelTopic" name="skills.followme.cmdVelTopic" placeholder="(optional; else teleop / namespace)" /></div>
|
|
147
|
+
<div class="field"><label for="skills.followme.targetDistance">Target distance (m)</label><input type="number" id="skills.followme.targetDistance" name="skills.followme.targetDistance" min="0.25" max="5" step="0.05" /></div>
|
|
148
|
+
<div class="field"><label for="skills.followme.rateHz">Loop rate (Hz)</label><input type="number" id="skills.followme.rateHz" name="skills.followme.rateHz" min="1" max="15" step="1" /></div>
|
|
149
|
+
<div class="field"><label for="skills.followme.minLinearVelocity">Min linear speed (m/s)</label><input type="number" id="skills.followme.minLinearVelocity" name="skills.followme.minLinearVelocity" min="0.05" max="2" step="0.05" /></div>
|
|
150
|
+
<div class="field"><label><input type="checkbox" id="skills.followme.invertLinearX" name="skills.followme.invertLinearX" /> Invert cmd_vel linear.x (forward/back)</label></div>
|
|
151
|
+
<div class="field"><label><input type="checkbox" id="skills.followme.logTickTiming" name="skills.followme.logTickTiming" /> Log tick timing (latency debug)</label></div>
|
|
152
|
+
<div class="field"><label for="skills.followme.criticalStopDistanceM">Hard stop distance (m)</label><input type="number" id="skills.followme.criticalStopDistanceM" name="skills.followme.criticalStopDistanceM" min="0.1" max="2" step="0.05" /></div>
|
|
153
|
+
<div class="field"><label for="skills.followme.maxVelocityFraction">Max speed fraction (of Safety caps)</label><input type="number" id="skills.followme.maxVelocityFraction" name="skills.followme.maxVelocityFraction" min="0.05" max="1" step="0.05" /></div>
|
|
154
|
+
<div class="field"><label for="skills.followme.visionCallbackUrl">Vision callback URL</label><input type="url" id="skills.followme.visionCallbackUrl" name="skills.followme.visionCallbackUrl" placeholder="(optional)" /></div>
|
|
155
|
+
<div class="field"><label><input type="checkbox" id="skills.followme.useDepthSectors" name="skills.followme.useDepthSectors" /> Use depth sectors for turning (when not using Ollama)</label></div>
|
|
156
|
+
<div class="field"><label for="skills.followme.searchAngularVelocity">Search angular velocity (rad/s)</label><input type="number" id="skills.followme.searchAngularVelocity" name="skills.followme.searchAngularVelocity" min="0.05" max="1.5" step="0.05" /></div>
|
|
157
|
+
<div class="field"><label for="skills.followme.searchTicksBeforeSwitch">Search ticks before direction switch</label><input type="number" id="skills.followme.searchTicksBeforeSwitch" name="skills.followme.searchTicksBeforeSwitch" min="1" max="120" step="1" /></div>
|
|
158
|
+
</section>
|
|
159
|
+
<p><button type="button" id="save-btn">Save config</button><span id="save-status"></span></p>
|
|
160
|
+
</form>
|
|
161
|
+
<script src="config.js"></script>
|
|
162
|
+
</body>
|
|
163
|
+
</html>`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Returns the config page script (served as config.js so it runs under CSP). */
|
|
167
|
+
export function getConfigPageScript(): string {
|
|
168
|
+
return CONFIG_PAGE_SCRIPT;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const CONFIG_PAGE_SCRIPT = `(function() {
|
|
172
|
+
var form = document.getElementById('config-form');
|
|
173
|
+
var banner = document.getElementById('banner');
|
|
174
|
+
var saveBtn = document.getElementById('save-btn');
|
|
175
|
+
var saveStatus = document.getElementById('save-status');
|
|
176
|
+
if (!form || !banner || !saveBtn) {
|
|
177
|
+
if (banner) { banner.className = 'banner error'; banner.textContent = 'Config form or save button not found.'; }
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
function setSaveStatus(msg, isError) {
|
|
181
|
+
if (saveStatus) {
|
|
182
|
+
saveStatus.textContent = msg;
|
|
183
|
+
saveStatus.style.color = isError ? '#f99' : (msg.indexOf('Saved') !== -1 ? '#9f9' : '#aaa');
|
|
184
|
+
saveStatus.style.marginLeft = '10px';
|
|
185
|
+
}
|
|
186
|
+
if (saveBtn && msg) saveBtn.textContent = msg.indexOf('Saving') !== -1 ? 'Saving…' : 'Save config';
|
|
187
|
+
}
|
|
188
|
+
var NUM_FIELDS = ['rosbridge.reconnectInterval','zenoh.domainId','local.domainId','teleop.speedDefault','teleop.cameraPollMs','safety.maxLinearVelocity','safety.maxAngularVelocity','skills.followme.targetDistance','skills.followme.rateHz','skills.followme.minLinearVelocity','skills.followme.criticalStopDistanceM','skills.followme.maxVelocityFraction','skills.followme.searchAngularVelocity','skills.followme.searchTicksBeforeSwitch'];
|
|
189
|
+
var BOOL_FIELDS = ['rosbridge.reconnect','memory.mem0.inferOnWrite','skills.followme.useOllama','skills.followme.invertLinearX','skills.followme.logTickTiming','skills.followme.useDepthSectors'];
|
|
190
|
+
function setByPath(obj, path, value) {
|
|
191
|
+
var parts = path.split('.');
|
|
192
|
+
var cur = obj;
|
|
193
|
+
for (var i = 0; i < parts.length - 1; i++) {
|
|
194
|
+
var p = parts[i];
|
|
195
|
+
if (!cur[p] || typeof cur[p] !== 'object') cur[p] = {};
|
|
196
|
+
cur = cur[p];
|
|
197
|
+
}
|
|
198
|
+
cur[parts[parts.length - 1]] = value;
|
|
199
|
+
}
|
|
200
|
+
function getByPath(obj, path) {
|
|
201
|
+
var parts = path.split('.');
|
|
202
|
+
var cur = obj;
|
|
203
|
+
for (var i = 0; i < parts.length; i++) {
|
|
204
|
+
if (cur == null) return undefined;
|
|
205
|
+
cur = cur[parts[i]];
|
|
206
|
+
}
|
|
207
|
+
return cur;
|
|
208
|
+
}
|
|
209
|
+
function showBanner(className, text) {
|
|
210
|
+
banner.className = 'banner ' + className;
|
|
211
|
+
banner.textContent = text;
|
|
212
|
+
banner.classList.remove('hidden');
|
|
213
|
+
}
|
|
214
|
+
function hideBanner() {
|
|
215
|
+
banner.classList.add('hidden');
|
|
216
|
+
}
|
|
217
|
+
function getFormElement(name) {
|
|
218
|
+
var el = form.elements[name];
|
|
219
|
+
if (!el && typeof CSS !== 'undefined' && CSS.escape) {
|
|
220
|
+
try { el = form.querySelector('#' + CSS.escape(name)); } catch (_) {}
|
|
221
|
+
}
|
|
222
|
+
if (!el) try { el = document.getElementById(name); } catch (_) {}
|
|
223
|
+
return el || null;
|
|
224
|
+
}
|
|
225
|
+
function setFieldValue(name, value) {
|
|
226
|
+
var el = getFormElement(name);
|
|
227
|
+
if (!el) return;
|
|
228
|
+
if (el.type === 'checkbox') {
|
|
229
|
+
el.checked = !!value;
|
|
230
|
+
} else if (value !== undefined && value !== null) {
|
|
231
|
+
el.value = value;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function getFieldValue(name) {
|
|
235
|
+
var el = getFormElement(name);
|
|
236
|
+
if (!el) return undefined;
|
|
237
|
+
if (el.type === 'checkbox') return el.checked;
|
|
238
|
+
if (BOOL_FIELDS.indexOf(name) !== -1) return el.checked;
|
|
239
|
+
if (NUM_FIELDS.indexOf(name) !== -1) {
|
|
240
|
+
var n = Number(el.value);
|
|
241
|
+
return isNaN(n) ? undefined : n;
|
|
242
|
+
}
|
|
243
|
+
return el.value;
|
|
244
|
+
}
|
|
245
|
+
function toArray(val) {
|
|
246
|
+
if (Array.isArray(val)) return val;
|
|
247
|
+
if (typeof val === 'string') return val.split(',').map(function(s) { return s.trim(); }).filter(Boolean);
|
|
248
|
+
return [];
|
|
249
|
+
}
|
|
250
|
+
function getMemoryBackendChoice() {
|
|
251
|
+
var radios = document.getElementsByName('memory.backendChoice');
|
|
252
|
+
for (var i = 0; i < radios.length; i++) {
|
|
253
|
+
if (radios[i].checked) return radios[i].value;
|
|
254
|
+
}
|
|
255
|
+
return 'off';
|
|
256
|
+
}
|
|
257
|
+
function setMemoryBackendChoice(choice) {
|
|
258
|
+
var radios = document.getElementsByName('memory.backendChoice');
|
|
259
|
+
for (var i = 0; i < radios.length; i++) {
|
|
260
|
+
radios[i].checked = (radios[i].value === choice);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function updateMemoryVisibility() {
|
|
264
|
+
var choice = getMemoryBackendChoice();
|
|
265
|
+
var localSec = document.getElementById('section-memory-local');
|
|
266
|
+
var mem0Sec = document.getElementById('section-memory-mem0');
|
|
267
|
+
var actions = document.getElementById('memory-actions');
|
|
268
|
+
if (localSec) localSec.style.display = choice === 'local' ? 'block' : 'none';
|
|
269
|
+
if (mem0Sec) mem0Sec.style.display = choice === 'mem0' ? 'block' : 'none';
|
|
270
|
+
if (actions) actions.style.display = choice === 'off' ? 'none' : 'block';
|
|
271
|
+
}
|
|
272
|
+
function payloadFromForm() {
|
|
273
|
+
var payload = { transport: {}, robot: {}, rosbridge: {}, zenoh: {}, local: {}, webrtc: {}, teleop: {}, safety: {}, memory: { local: {}, mem0: {} }, skillPackages: [], skillPaths: [], skills: {} };
|
|
274
|
+
var names = ['transport.mode','robot.name','robot.namespace','robot.cameraTopic','rosbridge.url','rosbridge.reconnect','rosbridge.reconnectInterval','zenoh.routerEndpoint','zenoh.domainId','zenoh.keyFormat','local.domainId','webrtc.signalingUrl','webrtc.apiUrl','webrtc.robotId','teleop.cameraTopic','teleop.cmdVelTopic','teleop.speedDefault','teleop.cameraPollMs','safety.maxLinearVelocity','safety.maxAngularVelocity','memory.local.storePath','memory.mem0.inferOnWrite','memory.mem0.historyDbPath','skills.followme.useOllama','skills.followme.ollamaUrl','skills.followme.vlmModel','skills.followme.cameraTopic','skills.followme.cameraMessageType','skills.followme.depthTopic','skills.followme.cmdVelTopic','skills.followme.targetDistance','skills.followme.rateHz','skills.followme.minLinearVelocity','skills.followme.invertLinearX','skills.followme.logTickTiming','skills.followme.criticalStopDistanceM','skills.followme.maxVelocityFraction','skills.followme.visionCallbackUrl','skills.followme.useDepthSectors','skills.followme.searchAngularVelocity','skills.followme.searchTicksBeforeSwitch'];
|
|
275
|
+
for (var i = 0; i < names.length; i++) {
|
|
276
|
+
var v = getFieldValue(names[i]);
|
|
277
|
+
if (v !== undefined) setByPath(payload, names[i], v);
|
|
278
|
+
}
|
|
279
|
+
var memChoice = getMemoryBackendChoice();
|
|
280
|
+
payload.memory.enabled = (memChoice !== 'off');
|
|
281
|
+
if (memChoice !== 'off') payload.memory.backend = memChoice;
|
|
282
|
+
payload.skillPackages = toArray(getFieldValue('skillPackages'));
|
|
283
|
+
payload.skillPaths = toArray(getFieldValue('skillPaths'));
|
|
284
|
+
return payload;
|
|
285
|
+
}
|
|
286
|
+
function populateForm(c) {
|
|
287
|
+
var names = ['transport.mode','robot.name','robot.namespace','robot.cameraTopic','rosbridge.url','rosbridge.reconnect','rosbridge.reconnectInterval','zenoh.routerEndpoint','zenoh.domainId','zenoh.keyFormat','local.domainId','webrtc.signalingUrl','webrtc.apiUrl','webrtc.robotId','teleop.cameraTopic','teleop.cmdVelTopic','teleop.speedDefault','teleop.cameraPollMs','safety.maxLinearVelocity','safety.maxAngularVelocity','memory.local.storePath','memory.mem0.inferOnWrite','memory.mem0.historyDbPath','skills.followme.useOllama','skills.followme.ollamaUrl','skills.followme.vlmModel','skills.followme.cameraTopic','skills.followme.cameraMessageType','skills.followme.depthTopic','skills.followme.cmdVelTopic','skills.followme.targetDistance','skills.followme.rateHz','skills.followme.minLinearVelocity','skills.followme.invertLinearX','skills.followme.logTickTiming','skills.followme.criticalStopDistanceM','skills.followme.maxVelocityFraction','skills.followme.visionCallbackUrl','skills.followme.useDepthSectors','skills.followme.searchAngularVelocity','skills.followme.searchTicksBeforeSwitch'];
|
|
288
|
+
for (var i = 0; i < names.length; i++) {
|
|
289
|
+
var v = getByPath(c, names[i]);
|
|
290
|
+
setFieldValue(names[i], v);
|
|
291
|
+
}
|
|
292
|
+
var memEnabled = !!getByPath(c, 'memory.enabled');
|
|
293
|
+
var memBackend = getByPath(c, 'memory.backend') || 'local';
|
|
294
|
+
setMemoryBackendChoice(memEnabled ? memBackend : 'off');
|
|
295
|
+
updateMemoryVisibility();
|
|
296
|
+
setFieldValue('skillPackages', Array.isArray(c.skillPackages) ? c.skillPackages.join(', ') : (c.skillPackages || ''));
|
|
297
|
+
setFieldValue('skillPaths', Array.isArray(c.skillPaths) ? c.skillPaths.join(', ') : (c.skillPaths || ''));
|
|
298
|
+
if (getByPath(c, 'skills.followme.useDepthSectors') === undefined) {
|
|
299
|
+
var udsEl = getFormElement('skills.followme.useDepthSectors');
|
|
300
|
+
if (udsEl && udsEl.type === 'checkbox') udsEl.checked = true;
|
|
301
|
+
}
|
|
302
|
+
var mode = (c.transport && c.transport.mode) || 'local';
|
|
303
|
+
document.getElementById('section-rosbridge').style.display = mode === 'rosbridge' ? 'block' : 'none';
|
|
304
|
+
document.getElementById('section-zenoh').style.display = mode === 'zenoh' ? 'block' : 'none';
|
|
305
|
+
document.getElementById('section-local').style.display = mode === 'local' ? 'block' : 'none';
|
|
306
|
+
document.getElementById('section-webrtc').style.display = mode === 'webrtc' ? 'block' : 'none';
|
|
307
|
+
}
|
|
308
|
+
document.getElementById('transport.mode').addEventListener('change', function() {
|
|
309
|
+
var mode = this.value;
|
|
310
|
+
document.getElementById('section-rosbridge').style.display = mode === 'rosbridge' ? 'block' : 'none';
|
|
311
|
+
document.getElementById('section-zenoh').style.display = mode === 'zenoh' ? 'block' : 'none';
|
|
312
|
+
document.getElementById('section-local').style.display = mode === 'local' ? 'block' : 'none';
|
|
313
|
+
document.getElementById('section-webrtc').style.display = mode === 'webrtc' ? 'block' : 'none';
|
|
314
|
+
});
|
|
315
|
+
function doSave(method, payload) {
|
|
316
|
+
payload = payload || payloadFromForm();
|
|
317
|
+
if (method === 'GET') {
|
|
318
|
+
var json = JSON.stringify(payload);
|
|
319
|
+
var base64 = btoa(unescape(encodeURIComponent(json))).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');
|
|
320
|
+
if (base64.length > 1800) {
|
|
321
|
+
return Promise.resolve({ status: 413, data: { success: false, error: 'Config too large for GET. Edit ~/.openclaw/openclaw.json manually.' } });
|
|
322
|
+
}
|
|
323
|
+
return fetch('config/save?payload=' + encodeURIComponent(base64), { method: 'GET' })
|
|
324
|
+
.then(function(r) { return r.text().then(function(text) {
|
|
325
|
+
var data;
|
|
326
|
+
try { data = text ? JSON.parse(text) : {}; } catch (_) {
|
|
327
|
+
return { status: r.status, data: { success: false, error: (text || '').slice(0, 200) } };
|
|
328
|
+
}
|
|
329
|
+
return { status: r.status, data: data };
|
|
330
|
+
}); });
|
|
331
|
+
}
|
|
332
|
+
return fetch('config/save', {
|
|
333
|
+
method: method,
|
|
334
|
+
headers: { 'Content-Type': 'application/json' },
|
|
335
|
+
body: JSON.stringify(payload)
|
|
336
|
+
}).then(function(r) { return r.text().then(function(text) {
|
|
337
|
+
var data;
|
|
338
|
+
try { data = text ? JSON.parse(text) : {}; } catch (_) {
|
|
339
|
+
if (r.ok) {
|
|
340
|
+
var msg = (text && text.trim().indexOf('<!') === 0)
|
|
341
|
+
? 'Server returned a page instead of JSON. Edit ~/.openclaw/openclaw.json (plugins.entries.agenticros.config) and restart the gateway.'
|
|
342
|
+
: 'Server returned non-JSON (status 200).';
|
|
343
|
+
return { status: r.status, data: { success: false, error: msg } };
|
|
344
|
+
}
|
|
345
|
+
var errText = (text && text.trim().indexOf('<!') === 0) ? 'Server returned an error page.' : (text || 'No response body').slice(0, 300);
|
|
346
|
+
if (r.status === 401) errText = 'Unauthorized. Use the proxy (node scripts/agenticros-proxy.cjs 18790) and open the config page from there.';
|
|
347
|
+
if (r.status === 405) errText = 'Method not allowed. Will try PUT then GET.';
|
|
348
|
+
return { status: r.status, data: { success: false, error: errText } };
|
|
349
|
+
}
|
|
350
|
+
return { status: r.status, data: data };
|
|
351
|
+
}); });
|
|
352
|
+
}
|
|
353
|
+
function handleSaveResult(_, retryGet) {
|
|
354
|
+
var status = _.status;
|
|
355
|
+
var res = _.data || {};
|
|
356
|
+
if (res.success) {
|
|
357
|
+
showBanner('success', res.message + (res.configPath ? ' Saved to: ' + res.configPath : ''));
|
|
358
|
+
setSaveStatus('Saved. Restart gateway for changes.', false);
|
|
359
|
+
return Promise.resolve();
|
|
360
|
+
}
|
|
361
|
+
if (status === 405 && retryGet !== false) {
|
|
362
|
+
setSaveStatus('Trying PUT…', false);
|
|
363
|
+
return doSave('PUT').then(function(p) {
|
|
364
|
+
if (p.status === 200 && p.data && p.data.success) {
|
|
365
|
+
showBanner('success', p.data.message + (p.data.configPath ? ' Saved to: ' + p.data.configPath : ''));
|
|
366
|
+
setSaveStatus('Saved. Restart gateway for changes.', false);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
if (p.status === 405) {
|
|
370
|
+
setSaveStatus('Trying GET…', false);
|
|
371
|
+
return doSave('GET').then(function(g) {
|
|
372
|
+
if (g.status === 200 && g.data && g.data.success) {
|
|
373
|
+
showBanner('success', g.data.message + (g.data.configPath ? ' Saved to: ' + g.data.configPath : ''));
|
|
374
|
+
setSaveStatus('Saved. Restart gateway for changes.', false);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
var err = g.data && g.data.error ? g.data.error : 'Save failed (GET).';
|
|
378
|
+
showBanner('error', err);
|
|
379
|
+
setSaveStatus(err.slice(0, 80), true);
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
var putErr = p.data && p.data.error ? p.data.error : 'Save failed (PUT).';
|
|
383
|
+
showBanner('error', putErr);
|
|
384
|
+
setSaveStatus(putErr.slice(0, 80), true);
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
var errMsg = res.error || ('Save failed (status ' + status + ').');
|
|
388
|
+
if (status >= 400) errMsg = (status + ' ' + (status === 400 ? 'Bad Request' : status === 503 ? 'Service Unavailable' : status === 413 ? 'Payload too large' : 'Error') + ': ') + (res.error || errMsg);
|
|
389
|
+
showBanner('error', errMsg);
|
|
390
|
+
setSaveStatus(errMsg.slice(0, 80), true);
|
|
391
|
+
return Promise.resolve();
|
|
392
|
+
}
|
|
393
|
+
function runSave() {
|
|
394
|
+
hideBanner();
|
|
395
|
+
setSaveStatus('Saving…', false);
|
|
396
|
+
saveBtn.textContent = 'Saving…';
|
|
397
|
+
saveBtn.disabled = true;
|
|
398
|
+
doSave('POST')
|
|
399
|
+
.then(function(r) { return handleSaveResult(r); })
|
|
400
|
+
.catch(function(err) {
|
|
401
|
+
var msg = 'Request failed: ' + (err.message || String(err));
|
|
402
|
+
showBanner('error', msg);
|
|
403
|
+
setSaveStatus(msg.slice(0, 80), true);
|
|
404
|
+
})
|
|
405
|
+
.then(function() {
|
|
406
|
+
saveBtn.disabled = false;
|
|
407
|
+
if (saveBtn.textContent === 'Saving…') saveBtn.textContent = 'Save config';
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
window.agenticrosSave = runSave;
|
|
411
|
+
saveBtn.addEventListener('click', runSave);
|
|
412
|
+
form.addEventListener('submit', function(e) { e.preventDefault(); if (window.agenticrosSave) window.agenticrosSave(); });
|
|
413
|
+
var memoryRadios = document.getElementsByName('memory.backendChoice');
|
|
414
|
+
for (var ri = 0; ri < memoryRadios.length; ri++) {
|
|
415
|
+
memoryRadios[ri].addEventListener('change', updateMemoryVisibility);
|
|
416
|
+
}
|
|
417
|
+
var memoryTestBtn = document.getElementById('memory-test-btn');
|
|
418
|
+
var memoryClearBtn = document.getElementById('memory-clear-btn');
|
|
419
|
+
var memoryTestStatus = document.getElementById('memory-test-status');
|
|
420
|
+
var memoryTestOutput = document.getElementById('memory-test-output');
|
|
421
|
+
function setMemoryTestStatus(text, isErr) {
|
|
422
|
+
if (memoryTestStatus) {
|
|
423
|
+
memoryTestStatus.textContent = text;
|
|
424
|
+
memoryTestStatus.style.color = isErr ? '#f99' : '#aaa';
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function showMemoryTestOutput(text) {
|
|
428
|
+
if (memoryTestOutput) {
|
|
429
|
+
memoryTestOutput.textContent = text;
|
|
430
|
+
memoryTestOutput.style.display = 'block';
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (memoryTestBtn) {
|
|
434
|
+
memoryTestBtn.addEventListener('click', function() {
|
|
435
|
+
setMemoryTestStatus('Testing...', false);
|
|
436
|
+
if (memoryTestOutput) memoryTestOutput.style.display = 'none';
|
|
437
|
+
fetch('memory/status')
|
|
438
|
+
.then(function(r) { return r.text().then(function(t) { return { status: r.status, text: t }; }); })
|
|
439
|
+
.then(function(p) {
|
|
440
|
+
try {
|
|
441
|
+
var data = JSON.parse(p.text);
|
|
442
|
+
if (data && data.success === false) {
|
|
443
|
+
setMemoryTestStatus('Error', true);
|
|
444
|
+
showMemoryTestOutput(JSON.stringify(data, null, 2));
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
setMemoryTestStatus(
|
|
448
|
+
data.enabled
|
|
449
|
+
? 'OK — ' + data.backend + ', ' + (data.recordCount || 0) + ' records'
|
|
450
|
+
: 'Disabled',
|
|
451
|
+
false,
|
|
452
|
+
);
|
|
453
|
+
showMemoryTestOutput(JSON.stringify(data, null, 2));
|
|
454
|
+
} catch (_) {
|
|
455
|
+
setMemoryTestStatus('Bad response (status ' + p.status + ')', true);
|
|
456
|
+
showMemoryTestOutput(p.text);
|
|
457
|
+
}
|
|
458
|
+
})
|
|
459
|
+
.catch(function(err) {
|
|
460
|
+
setMemoryTestStatus('Request failed', true);
|
|
461
|
+
showMemoryTestOutput(String(err && err.message ? err.message : err));
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
if (memoryClearBtn) {
|
|
466
|
+
memoryClearBtn.addEventListener('click', function() {
|
|
467
|
+
if (!window.confirm('Delete every memory in the current namespace? This cannot be undone.')) return;
|
|
468
|
+
setMemoryTestStatus('Clearing...', false);
|
|
469
|
+
fetch('memory/clear', { method: 'POST' })
|
|
470
|
+
.then(function(r) { return r.text().then(function(t) { return { status: r.status, text: t }; }); })
|
|
471
|
+
.then(function(p) {
|
|
472
|
+
try {
|
|
473
|
+
var data = JSON.parse(p.text);
|
|
474
|
+
if (data && data.success) {
|
|
475
|
+
setMemoryTestStatus('Cleared ' + (data.removed || 0) + ' records', false);
|
|
476
|
+
showMemoryTestOutput(JSON.stringify(data, null, 2));
|
|
477
|
+
} else {
|
|
478
|
+
setMemoryTestStatus('Error', true);
|
|
479
|
+
showMemoryTestOutput(p.text);
|
|
480
|
+
}
|
|
481
|
+
} catch (_) {
|
|
482
|
+
setMemoryTestStatus('Bad response (status ' + p.status + ')', true);
|
|
483
|
+
showMemoryTestOutput(p.text);
|
|
484
|
+
}
|
|
485
|
+
})
|
|
486
|
+
.catch(function(err) {
|
|
487
|
+
setMemoryTestStatus('Request failed', true);
|
|
488
|
+
showMemoryTestOutput(String(err && err.message ? err.message : err));
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
fetch('config.json')
|
|
493
|
+
.then(function(r) { return r.json(); })
|
|
494
|
+
.then(function(c) { populateForm(c); })
|
|
495
|
+
.catch(function(e) {
|
|
496
|
+
showBanner('error', 'Failed to load config: ' + (e.message || 'Unknown error'));
|
|
497
|
+
});
|
|
498
|
+
})();`;
|