agenticros 0.3.4 → 0.3.5
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/README.md +18 -3
- package/dist/util/skill-manifest.d.ts.map +1 -1
- package/dist/util/skill-manifest.js +22 -1
- package/dist/util/skill-manifest.js.map +1 -1
- package/package.json +1 -1
- package/runtime/BUNDLE.json +1 -1
- package/runtime/README.md +31 -6
- package/runtime/docs/cli.md +1 -1
- package/runtime/docs/robot-setup.md +1 -1
- package/runtime/packages/agenticros/openclaw.plugin.json +147 -1
- package/runtime/packages/agenticros/src/__tests__/capabilities-plugin.test.ts +2 -0
- package/runtime/packages/agenticros/src/routes.ts +4 -3
- package/runtime/packages/agenticros/src/tools/index.ts +6 -5
- package/runtime/packages/agenticros/src/tools/mission-pause.ts +49 -0
- package/runtime/packages/agenticros/src/tools/mission-resume.ts +41 -0
- package/runtime/packages/agenticros/src/tools/ros2-mission.ts +33 -84
- package/runtime/packages/agenticros-claude-code/README.md +2 -0
- package/runtime/packages/agenticros-claude-code/dist/tools.d.ts.map +1 -1
- package/runtime/packages/agenticros-claude-code/dist/tools.js +130 -111
- package/runtime/packages/agenticros-claude-code/dist/tools.js.map +1 -1
- package/runtime/packages/agenticros-claude-code/src/tools.ts +140 -99
- package/runtime/packages/agenticros-gemini/package.json +2 -0
- package/runtime/packages/agenticros-gemini/src/find-object/coco-classes.ts +38 -0
- package/runtime/packages/agenticros-gemini/src/find-object/find-object.ts +191 -0
- package/runtime/packages/agenticros-gemini/src/follow-me/controller.ts +109 -0
- package/runtime/packages/agenticros-gemini/src/follow-me/depth-loop.ts +452 -0
- package/runtime/packages/agenticros-gemini/src/follow-me/detector.ts +303 -0
- package/runtime/packages/agenticros-gemini/src/follow-me/loop.ts +359 -0
- package/runtime/packages/agenticros-gemini/src/tools.ts +351 -90
- package/runtime/packages/core/README.md +1 -1
- package/runtime/packages/core/package.json +1 -1
- package/runtime/packages/core/src/__tests__/config-persistence.test.ts +26 -0
- package/runtime/packages/core/src/__tests__/external-capability.test.ts +72 -0
- package/runtime/packages/core/src/__tests__/heartbeat-fleet.test.ts +152 -0
- package/runtime/packages/core/src/__tests__/mission-bindings.test.ts +101 -0
- package/runtime/packages/core/src/__tests__/mission-pause.test.ts +104 -0
- package/runtime/packages/core/src/capabilities.ts +38 -3
- package/runtime/packages/core/src/capability-schema.ts +58 -0
- package/runtime/packages/core/src/config.ts +20 -0
- package/runtime/packages/core/src/discovery.ts +21 -3
- package/runtime/packages/core/src/external-capability.ts +219 -0
- package/runtime/packages/core/src/fleet-config.ts +91 -0
- package/runtime/packages/core/src/heartbeat.ts +167 -0
- package/runtime/packages/core/src/index.ts +55 -0
- package/runtime/packages/core/src/mission-bindings.ts +189 -0
- package/runtime/packages/core/src/mission-registry.ts +31 -3
- package/runtime/packages/core/src/mission.ts +64 -7
- package/runtime/packages/core/src/robots.ts +6 -2
- package/runtime/packages/core/src/transport/rosbridge/client.ts +7 -0
- package/runtime/pnpm-lock.yaml +6 -0
- package/templates/skills/camera/package.json +1 -1
- package/templates/skills/depth/package.json +1 -1
- package/templates/skills/robot/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
> agentic AI for ROS-powered robots
|
|
4
4
|
|
|
5
5
|
`agenticros` is the unified command-line tool for AgenticROS — bring up a real
|
|
6
|
-
robot or a simulated one, drive it from Claude Code, OpenAI Codex, Hermes Agent, or OpenClaw
|
|
6
|
+
robot or a simulated one, drive it from Claude Code, OpenAI Codex, Hermes Agent, or OpenClaw
|
|
7
|
+
(with **local Ollama VLMs** or cloud models),
|
|
7
8
|
and keep your workspace healthy from a single binary.
|
|
8
9
|
|
|
9
10
|
```bash
|
|
10
11
|
# Brand new machine: one command end-to-end
|
|
11
|
-
npx agenticros init # workspace + plugin + MCP clients + API key + doctor
|
|
12
|
+
npx agenticros init # workspace + plugin + MCP clients + optional API key + doctor
|
|
12
13
|
agenticros # interactive menu
|
|
13
14
|
agenticros mcp setup # register AgenticROS MCP for Codex, Hermes, and Claude
|
|
14
15
|
agenticros up real # bring up the real-robot stack
|
|
@@ -31,6 +32,20 @@ npm tarball bundles those scripts plus the ROS 2 source packages and the
|
|
|
31
32
|
pre-built MCP server, so `npx agenticros init` works on a fresh machine with
|
|
32
33
|
no `git clone` step.
|
|
33
34
|
|
|
35
|
+
## Local VLM (Ollama)
|
|
36
|
+
|
|
37
|
+
Run **without cloud LLM API keys** by pointing OpenClaw or Hermes at Ollama:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
ollama pull qwen3-vl:8b-instruct # or qwen3-vl:2b on smaller hardware
|
|
41
|
+
npx agenticros init # skip OpenAI key when prompted
|
|
42
|
+
# Point OpenClaw primary model at Ollama (see docs/local-vlm.md)
|
|
43
|
+
agenticros up sim-amr
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
OpenClaw: web chat, teleop, messaging, skills. Hermes: terminal + Ollama. Full guide:
|
|
47
|
+
**[docs/local-vlm.md](../../docs/local-vlm.md)** (model picks, multimodal catalog patch, describer, Follow Me).
|
|
48
|
+
|
|
34
49
|
## Install
|
|
35
50
|
|
|
36
51
|
Three ways, listed easiest first:
|
|
@@ -81,7 +96,7 @@ walks through:
|
|
|
81
96
|
3. ROS 2 workspace build (`colcon build --symlink-install`)
|
|
82
97
|
4. OpenClaw plugin install (`scripts/setup_gateway_plugin.sh`)
|
|
83
98
|
5. Robot config (namespace, transport mode, sample `~/.agenticros/config.json`)
|
|
84
|
-
6. OpenAI API key (
|
|
99
|
+
6. OpenAI API key (optional — skip when using local Ollama; see [docs/local-vlm.md](../../docs/local-vlm.md))
|
|
85
100
|
7. Codex MCP config (optional — `~/.codex/config.toml` and project `.codex/config.toml`)
|
|
86
101
|
8. Hermes MCP config (optional — `~/.hermes/config.yaml`)
|
|
87
102
|
9. Final `agenticros doctor` summary
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-manifest.d.ts","sourceRoot":"","sources":["../../src/util/skill-manifest.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"skill-manifest.d.ts","sourceRoot":"","sources":["../../src/util/skill-manifest.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAoFhE;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAI/D;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,GACV;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASzC"}
|
|
@@ -39,7 +39,7 @@ export function validateManifest(raw) {
|
|
|
39
39
|
}
|
|
40
40
|
const coreDep = m.dependencies?.["@agenticros/core"];
|
|
41
41
|
if (coreDep?.startsWith("file:")) {
|
|
42
|
-
warnings.push("`@agenticros/core` is declared as a `file:` path. Publish a version from npm (e.g. `^0.
|
|
42
|
+
warnings.push("`@agenticros/core` is declared as a `file:` path. Publish a version from npm (e.g. `^0.6.0`) before others can install your skill.");
|
|
43
43
|
}
|
|
44
44
|
if (!block.description && !m.description) {
|
|
45
45
|
warnings.push("Add a one-sentence `description` (top-level or in `agenticros`).");
|
|
@@ -47,6 +47,27 @@ export function validateManifest(raw) {
|
|
|
47
47
|
if (!block.capabilities || block.capabilities.length === 0) {
|
|
48
48
|
warnings.push("Declare at least one capability in `agenticros.capabilities` so the agent planner can reason about your skill.");
|
|
49
49
|
}
|
|
50
|
+
else {
|
|
51
|
+
for (const cap of block.capabilities) {
|
|
52
|
+
if (!cap || typeof cap !== "object" || typeof cap.id !== "string") {
|
|
53
|
+
warnings.push("Each capability must be an object with a string `id`.");
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const c = cap;
|
|
57
|
+
if (!c.verb || typeof c.verb !== "string") {
|
|
58
|
+
warnings.push(`Capability "${c.id}" should declare a string \`verb\`.`);
|
|
59
|
+
}
|
|
60
|
+
const impl = c.implementation;
|
|
61
|
+
if (impl && typeof impl === "object" && impl.kind === "external_ros_node") {
|
|
62
|
+
if (!impl.action && !impl.service && !impl.topic) {
|
|
63
|
+
warnings.push(`Capability "${c.id}" external_ros_node should set action, service, or topic.`);
|
|
64
|
+
}
|
|
65
|
+
if ((impl.action || impl.service || impl.topic) && !impl.msg_type) {
|
|
66
|
+
warnings.push(`Capability "${c.id}" external_ros_node should set msg_type for action/service/topic dispatch.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
50
71
|
if (!block.screenshots || block.screenshots.length === 0) {
|
|
51
72
|
warnings.push("Add at least one entry to `agenticros.screenshots` so the marketplace card has a preview image.");
|
|
52
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-manifest.js","sourceRoot":"","sources":["../../src/util/skill-manifest.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"skill-manifest.js","sourceRoot":"","sources":["../../src/util/skill-manifest.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/runtime/BUNDLE.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"packedAt": "2026-07-
|
|
2
|
+
"packedAt": "2026-07-09T19:39:11.659Z",
|
|
3
3
|
"repo": "https://github.com/PlaiPin/agenticros",
|
|
4
4
|
"note": "This directory is a snapshot of the agenticros monorepo source. `agenticros init` will copy it to ~/agenticros and run pnpm install + colcon build there.",
|
|
5
5
|
"layout": {
|
package/runtime/README.md
CHANGED
|
@@ -33,6 +33,29 @@ With AgenticROS, your robot can describe what it sees, follow intent ("go check
|
|
|
33
33
|
|
|
34
34
|
AgenticROS is built so that new adapters (LangGraph, OpenAI, local models, voice stacks, etc.) can be added without touching the ROS 2 layer. The core transport and tool contract are platform-agnostic; adapters are thin shims that surface those tools to each agent runtime.
|
|
35
35
|
|
|
36
|
+
## Local VLM (Ollama) — no cloud API required
|
|
37
|
+
|
|
38
|
+
Control your robot with a **local vision-language model** instead of OpenAI or other cloud APIs. AgenticROS robot tools work the same; you point **OpenClaw** or **Hermes** at Ollama on your machine.
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
ollama pull qwen3-vl:8b-instruct # recommended: chat + tools + camera vision
|
|
42
|
+
# or: ollama pull qwen3-vl:2b # smaller hardware
|
|
43
|
+
|
|
44
|
+
npx agenticros init # skip the OpenAI key step when prompted
|
|
45
|
+
# Configure OpenClaw to use Ollama as primary model (see guide below)
|
|
46
|
+
agenticros up sim-amr # or: agenticros up real
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Then chat in OpenClaw web UI or Hermes: *"List ROS topics"*, *"drive forward slowly"*, *"what do you see?"*
|
|
50
|
+
|
|
51
|
+
| Path | Best for |
|
|
52
|
+
|------|----------|
|
|
53
|
+
| **OpenClaw + Ollama** | Web chat, teleop, messaging channels, skills |
|
|
54
|
+
| **Hermes + Ollama** | Terminal agent with any Ollama model |
|
|
55
|
+
| **NemoClaw + Ollama** | Sandboxed Jetson / edge (see [docs/nemoclaw.md](docs/nemoclaw.md)) |
|
|
56
|
+
|
|
57
|
+
**Full setup, model picks, multimodal catalog patches, describer, Follow Me VLM, and troubleshooting:** **[docs/local-vlm.md](docs/local-vlm.md)**
|
|
58
|
+
|
|
36
59
|
## Architecture
|
|
37
60
|
|
|
38
61
|

|
|
@@ -103,6 +126,8 @@ On the ROS side, every robot publishes a 1 Hz heartbeat on `<ns>/agenticros/robo
|
|
|
103
126
|
|
|
104
127
|
`mission_cancel({ mission_id })` flips an in-process cancellation token; the runner stops at the next step boundary and marks remaining steps `cancelled`. When the [shared memory backend](#memory-optional) is on, every step is also written to `mission:<id>` in long-term memory, tagged with `step:<status>` and `capability:<id>`. A different agent — different process, different vendor — can `memory_recall` later and reconstruct exactly what happened, so two agents can collaborate on or hand off a mission.
|
|
105
128
|
|
|
129
|
+
**How-to:** step-by-step fleet setup, declarative plans, NL goals, cancel, and handoff — **[docs/missions.md](docs/missions.md)**. Runnable walkthrough: **[examples/find-and-approach/README.md](examples/find-and-approach/README.md)**.
|
|
130
|
+
|
|
106
131
|
Full architecture + design trade-offs: **[docs/strategy-ai-agents-plus-ros.md](docs/strategy-ai-agents-plus-ros.md)**.
|
|
107
132
|
|
|
108
133
|
## Repository layout
|
|
@@ -112,7 +137,7 @@ Full architecture + design trade-offs: **[docs/strategy-ai-agents-plus-ros.md](d
|
|
|
112
137
|
- `**packages/agenticros-claude-code**` — MCP server for Claude Code + Claude desktop / Dispatch (tools only; no config UI).
|
|
113
138
|
- `**packages/agenticros-gemini**` — Gemini CLI (function calling; no MCP).
|
|
114
139
|
- `**ros2_ws/**` — ROS2 workspace: `agenticros_msgs`, `agenticros_bringup` (Gazebo + RViz + rosbridge launches), `agenticros_discovery`, `agenticros_agent`, `agenticros_follow_me`.
|
|
115
|
-
- `**docs/**` — Architecture, skills, robot setup, Zenoh, teleop.
|
|
140
|
+
- `**docs/**` — Architecture, skills, robot setup, Zenoh, teleop, **[local VLM / Ollama](docs/local-vlm.md)**.
|
|
116
141
|
- `**scripts/**` — Workspace setup, gateway plugin config, run demos.
|
|
117
142
|
- `**docker/**` — Docker Compose and Dockerfiles for ROS2 + plugin images.
|
|
118
143
|
- `**examples/**` — Example projects.
|
|
@@ -138,7 +163,7 @@ The first run launches the interactive menu:
|
|
|
138
163
|
? What would you like to do?
|
|
139
164
|
Launch with real robot
|
|
140
165
|
❯ Launch with simulation
|
|
141
|
-
First-time setup (workspace + OpenClaw plugin + Codex MCP + API key)
|
|
166
|
+
First-time setup (workspace + OpenClaw plugin + Codex MCP + optional API key)
|
|
142
167
|
Manage skills (2 registered, 0 available, 0 broken)
|
|
143
168
|
Stop everything
|
|
144
169
|
Doctor (health check)
|
|
@@ -146,8 +171,8 @@ The first run launches the interactive menu:
|
|
|
146
171
|
Tail logs
|
|
147
172
|
```
|
|
148
173
|
|
|
149
|
-
Pick **First-time setup** once (workspace + OpenClaw plugin + optional Codex MCP + API key, all
|
|
150
|
-
idempotent)
|
|
174
|
+
Pick **First-time setup** once (workspace + OpenClaw plugin + optional Codex MCP + optional API key, all
|
|
175
|
+
idempotent). **Using local Ollama instead of OpenAI?** Skip the API key step — see **[Local VLM (Ollama)](#local-vlm-ollama--no-cloud-api-required)**. Then choose how you want to run:
|
|
151
176
|
|
|
152
177
|
| You want to … | Pick |
|
|
153
178
|
|---|---|
|
|
@@ -163,7 +188,7 @@ so **Stop everything** cleanly tears the demo down.
|
|
|
163
188
|
Prefer scripted invocations? Every menu item maps to a direct command:
|
|
164
189
|
|
|
165
190
|
```bash
|
|
166
|
-
npx agenticros init # one-time workspace + plugin + Codex/Hermes MCP + API key
|
|
191
|
+
npx agenticros init # one-time workspace + plugin + Codex/Hermes MCP (+ optional API key)
|
|
167
192
|
agenticros codex setup # register AgenticROS MCP for OpenAI Codex CLI
|
|
168
193
|
agenticros codex doctor # validate ~/.codex/config.toml
|
|
169
194
|
agenticros hermes setup # register AgenticROS MCP for Hermes Agent
|
|
@@ -212,7 +237,7 @@ needing token auth: run `node scripts/agenticros-proxy.cjs 18790` and open
|
|
|
212
237
|
See **[docs/openclaw-releases-and-plugin-routes.md](docs/openclaw-releases-and-plugin-routes.md)**
|
|
213
238
|
and **[docs/teleop.md](docs/teleop.md)**.
|
|
214
239
|
|
|
215
|
-
See **`docs/`** for robot setup, skills, teleop, simulation internals, and Docker.
|
|
240
|
+
See **`docs/`** for robot setup, **[missions](docs/missions.md)**, skills, teleop, simulation internals, and Docker.
|
|
216
241
|
|
|
217
242
|
## RViz2 and Gazebo (TurtleBot3 + rosbridge)
|
|
218
243
|
|
package/runtime/docs/cli.md
CHANGED
|
@@ -64,7 +64,7 @@ skipped (with a checkmark) when already done:
|
|
|
64
64
|
3. ROS 2 workspace build (`colcon build --symlink-install`)
|
|
65
65
|
4. OpenClaw plugin install (via `scripts/setup_gateway_plugin.sh`)
|
|
66
66
|
5. Robot config (writes `~/.agenticros/config.json`)
|
|
67
|
-
6. OpenAI API key (
|
|
67
|
+
6. OpenAI API key (optional — skip when using local Ollama; see [local-vlm.md](local-vlm.md))
|
|
68
68
|
7. MCP client config (optional — `agenticros mcp setup` for Codex, Hermes, and Claude)
|
|
69
69
|
8. Final `agenticros doctor` summary
|
|
70
70
|
|
|
@@ -296,7 +296,7 @@ The message comes from **OpenAI's API limits**, not from AgenticROS. The gateway
|
|
|
296
296
|
1. **Confirm it's OpenAI** — Check gateway logs:
|
|
297
297
|
`journalctl --user -u openclaw-gateway.service -n 100 --no-pager | grep -i "429\|rate\|limit\|error"`
|
|
298
298
|
2. **Check your OpenAI account** — [Usage](https://platform.openai.com/usage), [API keys](https://platform.openai.com/api-keys). Free/low tiers have strict RPM/TPM and can stay limited for a while.
|
|
299
|
-
3. **What helps** — Wait (RPM/TPM reset in minutes; daily limits at UTC midnight). Or in OpenClaw switch to a model with higher limits if available.
|
|
299
|
+
3. **What helps** — Wait (RPM/TPM reset in minutes; daily limits at UTC midnight). Or switch OpenClaw to a **local Ollama VLM** — see [local-vlm.md](local-vlm.md). Or in OpenClaw switch to a model with higher limits if available.
|
|
300
300
|
4. **AgenticROS** — We only trim context/tool output to use fewer tokens; we can't remove OpenAI's limits.
|
|
301
301
|
|
|
302
302
|
### 404 errors when installing rosbridge_suite
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"ros2_find_robots_for",
|
|
22
22
|
"run_mission",
|
|
23
23
|
"mission_cancel",
|
|
24
|
+
"mission_pause",
|
|
25
|
+
"mission_resume",
|
|
24
26
|
"ros2_camera_snapshot",
|
|
25
27
|
"ros2_depth_distance",
|
|
26
28
|
"memory_remember",
|
|
@@ -30,7 +32,8 @@
|
|
|
30
32
|
"follow_robot",
|
|
31
33
|
"follow_me_see",
|
|
32
34
|
"ollama_status",
|
|
33
|
-
"find_object"
|
|
35
|
+
"find_object",
|
|
36
|
+
"scan_surroundings"
|
|
34
37
|
]
|
|
35
38
|
},
|
|
36
39
|
"configSchema": {
|
|
@@ -178,6 +181,149 @@
|
|
|
178
181
|
}
|
|
179
182
|
}
|
|
180
183
|
},
|
|
184
|
+
"robots": {
|
|
185
|
+
"type": "array",
|
|
186
|
+
"description": "Multi-robot fleet list. When non-empty, used by ros2_list_robots and per-tool robot_id. When empty, the legacy config.robot entry is used. Manage via `agenticros robots` CLI.",
|
|
187
|
+
"default": [],
|
|
188
|
+
"items": {
|
|
189
|
+
"type": "object",
|
|
190
|
+
"required": [
|
|
191
|
+
"id"
|
|
192
|
+
],
|
|
193
|
+
"properties": {
|
|
194
|
+
"id": {
|
|
195
|
+
"type": "string",
|
|
196
|
+
"description": "Stable identifier referenced by robot_id tool arguments"
|
|
197
|
+
},
|
|
198
|
+
"name": {
|
|
199
|
+
"type": "string",
|
|
200
|
+
"default": "Robot"
|
|
201
|
+
},
|
|
202
|
+
"namespace": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"default": ""
|
|
205
|
+
},
|
|
206
|
+
"cameraTopic": {
|
|
207
|
+
"type": "string",
|
|
208
|
+
"default": ""
|
|
209
|
+
},
|
|
210
|
+
"default": {
|
|
211
|
+
"type": "boolean",
|
|
212
|
+
"description": "When true, this robot is active even if not first in the list"
|
|
213
|
+
},
|
|
214
|
+
"kind": {
|
|
215
|
+
"type": "string",
|
|
216
|
+
"description": "Robot kind for ros2_find_robots_for (e.g. amr, arm, drone, rover)",
|
|
217
|
+
"default": "amr"
|
|
218
|
+
},
|
|
219
|
+
"sensors": {
|
|
220
|
+
"type": "object",
|
|
221
|
+
"properties": {
|
|
222
|
+
"has_realsense": {
|
|
223
|
+
"type": "boolean",
|
|
224
|
+
"default": false
|
|
225
|
+
},
|
|
226
|
+
"has_lidar": {
|
|
227
|
+
"type": "boolean",
|
|
228
|
+
"default": false
|
|
229
|
+
},
|
|
230
|
+
"has_arm": {
|
|
231
|
+
"type": "boolean",
|
|
232
|
+
"default": false
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"capabilities": {
|
|
237
|
+
"type": "array",
|
|
238
|
+
"description": "Optional per-robot capability allowlist for ros2_find_robots_for",
|
|
239
|
+
"items": {
|
|
240
|
+
"type": "string"
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"transport": {
|
|
244
|
+
"type": "object",
|
|
245
|
+
"description": "Per-robot transport override (inherits global transport when omitted)",
|
|
246
|
+
"properties": {
|
|
247
|
+
"mode": {
|
|
248
|
+
"type": "string",
|
|
249
|
+
"enum": [
|
|
250
|
+
"rosbridge",
|
|
251
|
+
"local",
|
|
252
|
+
"webrtc",
|
|
253
|
+
"zenoh"
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
"zenoh": {
|
|
257
|
+
"type": "object",
|
|
258
|
+
"properties": {
|
|
259
|
+
"routerEndpoint": {
|
|
260
|
+
"type": "string"
|
|
261
|
+
},
|
|
262
|
+
"domainId": {
|
|
263
|
+
"type": "number"
|
|
264
|
+
},
|
|
265
|
+
"keyFormat": {
|
|
266
|
+
"type": "string",
|
|
267
|
+
"enum": [
|
|
268
|
+
"ros2dds",
|
|
269
|
+
"rmw_zenoh"
|
|
270
|
+
]
|
|
271
|
+
},
|
|
272
|
+
"bridgeNamespace": {
|
|
273
|
+
"type": "string"
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"rosbridge": {
|
|
278
|
+
"type": "object",
|
|
279
|
+
"properties": {
|
|
280
|
+
"url": {
|
|
281
|
+
"type": "string"
|
|
282
|
+
},
|
|
283
|
+
"reconnect": {
|
|
284
|
+
"type": "boolean"
|
|
285
|
+
},
|
|
286
|
+
"reconnectInterval": {
|
|
287
|
+
"type": "number"
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"local": {
|
|
292
|
+
"type": "object",
|
|
293
|
+
"properties": {
|
|
294
|
+
"domainId": {
|
|
295
|
+
"type": "number"
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
"webrtc": {
|
|
300
|
+
"type": "object",
|
|
301
|
+
"properties": {
|
|
302
|
+
"signalingUrl": {
|
|
303
|
+
"type": "string"
|
|
304
|
+
},
|
|
305
|
+
"apiUrl": {
|
|
306
|
+
"type": "string"
|
|
307
|
+
},
|
|
308
|
+
"robotId": {
|
|
309
|
+
"type": "string"
|
|
310
|
+
},
|
|
311
|
+
"robotKey": {
|
|
312
|
+
"type": "string"
|
|
313
|
+
},
|
|
314
|
+
"iceServers": {
|
|
315
|
+
"type": "array",
|
|
316
|
+
"items": {
|
|
317
|
+
"type": "object"
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
},
|
|
181
327
|
"teleop": {
|
|
182
328
|
"type": "object",
|
|
183
329
|
"description": "Teleop web app: camera and twist controls",
|
|
@@ -131,6 +131,8 @@ test("plugin: register() is synchronous and produces the base 15-tool surface",
|
|
|
131
131
|
"run_mission",
|
|
132
132
|
// Phase 1.f — cancel an in-flight mission by id.
|
|
133
133
|
"mission_cancel",
|
|
134
|
+
"mission_pause",
|
|
135
|
+
"mission_resume",
|
|
134
136
|
];
|
|
135
137
|
for (const name of expected) {
|
|
136
138
|
assert.ok(toolNames.includes(name), `Expected base tool ${name} in registered set`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { OpenClawPluginApi, HttpRouteHandler, HttpRouteResponse } from "./plugin-api.js";
|
|
2
2
|
import type { AgenticROSConfig } from "@agenticros/core";
|
|
3
|
-
import { parseConfig } from "@agenticros/core";
|
|
3
|
+
import { parseConfig, prepareConfigForPersistence } from "@agenticros/core";
|
|
4
4
|
import {
|
|
5
5
|
readOpenClawConfig,
|
|
6
6
|
writeAgenticROSConfig,
|
|
@@ -172,8 +172,9 @@ export function registerRoutes(api: OpenClawPluginApi, config: AgenticROSConfig)
|
|
|
172
172
|
api.logger.warn("AgenticROS config read failed: " + readMsg);
|
|
173
173
|
return { success: false, error: readMsg, statusCode: 500 };
|
|
174
174
|
}
|
|
175
|
+
let combined: Record<string, unknown>;
|
|
175
176
|
try {
|
|
176
|
-
|
|
177
|
+
combined =
|
|
177
178
|
existingAgenticROS && typeof existingAgenticROS === "object"
|
|
178
179
|
? mergeIncomingAgenticROSConfig(existingAgenticROS, body)
|
|
179
180
|
: body;
|
|
@@ -192,7 +193,7 @@ export function registerRoutes(api: OpenClawPluginApi, config: AgenticROSConfig)
|
|
|
192
193
|
merged.webrtc.robotKey = existingKey;
|
|
193
194
|
}
|
|
194
195
|
try {
|
|
195
|
-
writeAgenticROSConfig(merged
|
|
196
|
+
writeAgenticROSConfig(prepareConfigForPersistence(merged, combined));
|
|
196
197
|
} catch (err) {
|
|
197
198
|
const msg = err instanceof ConfigFileError ? err.message : (err instanceof Error ? err.message : "Failed to write config");
|
|
198
199
|
api.logger.warn("AgenticROS config write failed: " + msg);
|
|
@@ -14,6 +14,8 @@ import { registerDiscoverRobotsTool } from "./ros2-discover.js";
|
|
|
14
14
|
import { registerFindRobotsForTool } from "./ros2-find-robots-for.js";
|
|
15
15
|
import { registerMissionTool, type ToolRegistry } from "./ros2-mission.js";
|
|
16
16
|
import { registerMissionCancelTool } from "./mission-cancel.js";
|
|
17
|
+
import { registerMissionPauseTool } from "./mission-pause.js";
|
|
18
|
+
import { registerMissionResumeTool } from "./mission-resume.js";
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* Wrap the OpenClaw API so every registerTool() call is also recorded in
|
|
@@ -21,11 +23,8 @@ import { registerMissionCancelTool } from "./mission-cancel.js";
|
|
|
21
23
|
* dispatch sub-tool calls by name (e.g. capability "drive_base" routes
|
|
22
24
|
* to the registered "ros2_publish" tool's execute()).
|
|
23
25
|
*
|
|
24
|
-
*
|
|
25
|
-
* `
|
|
26
|
-
* v1: today the mission runner only supports the eight intrinsic
|
|
27
|
-
* capability bindings declared in ros2-mission.ts. Phase 1.d will
|
|
28
|
-
* extend this to capture skill-declared tools as well.
|
|
26
|
+
* Skill tools registered via `api.registerTool` are captured too, so
|
|
27
|
+
* `buildMissionBindings` can resolve `ros2_<capability_id>` when present.
|
|
29
28
|
*/
|
|
30
29
|
function wrapApiWithToolCapture(api: OpenClawPluginApi): {
|
|
31
30
|
wrappedApi: OpenClawPluginApi;
|
|
@@ -63,4 +62,6 @@ export function registerTools(api: OpenClawPluginApi, config: AgenticROSConfig):
|
|
|
63
62
|
registerFindRobotsForTool(wrappedApi, config);
|
|
64
63
|
registerMissionTool(wrappedApi, config, registry);
|
|
65
64
|
registerMissionCancelTool(wrappedApi);
|
|
65
|
+
registerMissionPauseTool(wrappedApi);
|
|
66
|
+
registerMissionResumeTool(wrappedApi);
|
|
66
67
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: mission_pause — pause a running mission at the next step boundary.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Type } from "@sinclair/typebox";
|
|
6
|
+
import type { OpenClawPluginApi } from "../plugin-api.js";
|
|
7
|
+
import { getMissionRegistry } from "../mission-registry.js";
|
|
8
|
+
|
|
9
|
+
export function registerMissionPauseTool(api: OpenClawPluginApi): void {
|
|
10
|
+
api.registerTool({
|
|
11
|
+
name: "mission_pause",
|
|
12
|
+
label: "Pause Mission",
|
|
13
|
+
description:
|
|
14
|
+
"Pause a mission that's currently running in this OpenClaw plugin process. " +
|
|
15
|
+
"Pass the mission_id returned by run_mission. The runner waits at the next step " +
|
|
16
|
+
"boundary until mission_resume (or mission_cancel). Idempotent if already paused.",
|
|
17
|
+
parameters: Type.Object({
|
|
18
|
+
mission_id: Type.String({
|
|
19
|
+
description: "The mission_id echoed by run_mission. Required.",
|
|
20
|
+
}),
|
|
21
|
+
reason: Type.Optional(
|
|
22
|
+
Type.String({
|
|
23
|
+
description: "Optional free-text reason — surfaced in the paused transcript entry.",
|
|
24
|
+
}),
|
|
25
|
+
),
|
|
26
|
+
}),
|
|
27
|
+
|
|
28
|
+
async execute(_toolCallId, params) {
|
|
29
|
+
const missionId = typeof params["mission_id"] === "string" ? (params["mission_id"] as string).trim() : "";
|
|
30
|
+
if (!missionId) {
|
|
31
|
+
const text = "mission_pause requires 'mission_id' (a non-empty string returned by run_mission).";
|
|
32
|
+
return { content: [{ type: "text", text }], details: { success: false, error: text } };
|
|
33
|
+
}
|
|
34
|
+
const reason = typeof params["reason"] === "string" ? (params["reason"] as string) : undefined;
|
|
35
|
+
const outcome = getMissionRegistry().pause(missionId, reason);
|
|
36
|
+
const details = {
|
|
37
|
+
success: true,
|
|
38
|
+
mission_id: missionId,
|
|
39
|
+
found: outcome.found,
|
|
40
|
+
already_paused: outcome.alreadyPaused,
|
|
41
|
+
reason: reason ?? null,
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
content: [{ type: "text", text: JSON.stringify(details) }],
|
|
45
|
+
details,
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool: mission_resume — resume a paused mission.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Type } from "@sinclair/typebox";
|
|
6
|
+
import type { OpenClawPluginApi } from "../plugin-api.js";
|
|
7
|
+
import { getMissionRegistry } from "../mission-registry.js";
|
|
8
|
+
|
|
9
|
+
export function registerMissionResumeTool(api: OpenClawPluginApi): void {
|
|
10
|
+
api.registerTool({
|
|
11
|
+
name: "mission_resume",
|
|
12
|
+
label: "Resume Mission",
|
|
13
|
+
description:
|
|
14
|
+
"Resume a mission previously paused with mission_pause. Pass the mission_id " +
|
|
15
|
+
"returned by run_mission. Idempotent if the mission is not paused.",
|
|
16
|
+
parameters: Type.Object({
|
|
17
|
+
mission_id: Type.String({
|
|
18
|
+
description: "The mission_id echoed by run_mission. Required.",
|
|
19
|
+
}),
|
|
20
|
+
}),
|
|
21
|
+
|
|
22
|
+
async execute(_toolCallId, params) {
|
|
23
|
+
const missionId = typeof params["mission_id"] === "string" ? (params["mission_id"] as string).trim() : "";
|
|
24
|
+
if (!missionId) {
|
|
25
|
+
const text = "mission_resume requires 'mission_id' (a non-empty string returned by run_mission).";
|
|
26
|
+
return { content: [{ type: "text", text }], details: { success: false, error: text } };
|
|
27
|
+
}
|
|
28
|
+
const outcome = getMissionRegistry().resume(missionId);
|
|
29
|
+
const details = {
|
|
30
|
+
success: true,
|
|
31
|
+
mission_id: missionId,
|
|
32
|
+
found: outcome.found,
|
|
33
|
+
was_paused: outcome.wasPaused,
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
content: [{ type: "text", text: JSON.stringify(details) }],
|
|
37
|
+
details,
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
}
|