@agenticros/core 0.5.0

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.
Files changed (151) hide show
  1. package/LICENSE +192 -0
  2. package/README.md +88 -0
  3. package/dist/banner.d.ts +7 -0
  4. package/dist/banner.d.ts.map +1 -0
  5. package/dist/banner.js +25 -0
  6. package/dist/banner.js.map +1 -0
  7. package/dist/capabilities.d.ts +101 -0
  8. package/dist/capabilities.d.ts.map +1 -0
  9. package/dist/capabilities.js +240 -0
  10. package/dist/capabilities.js.map +1 -0
  11. package/dist/cmd-vel-twist.d.ts +9 -0
  12. package/dist/cmd-vel-twist.d.ts.map +1 -0
  13. package/dist/cmd-vel-twist.js +32 -0
  14. package/dist/cmd-vel-twist.js.map +1 -0
  15. package/dist/config.d.ts +1195 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +427 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/discovery.d.ts +113 -0
  20. package/dist/discovery.d.ts.map +1 -0
  21. package/dist/discovery.js +141 -0
  22. package/dist/discovery.js.map +1 -0
  23. package/dist/find-robots-for.d.ts +85 -0
  24. package/dist/find-robots-for.d.ts.map +1 -0
  25. package/dist/find-robots-for.js +120 -0
  26. package/dist/find-robots-for.js.map +1 -0
  27. package/dist/index.d.ts +32 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +20 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/memory/factory.d.ts +18 -0
  32. package/dist/memory/factory.d.ts.map +1 -0
  33. package/dist/memory/factory.js +51 -0
  34. package/dist/memory/factory.js.map +1 -0
  35. package/dist/memory/index.d.ts +3 -0
  36. package/dist/memory/index.d.ts.map +1 -0
  37. package/dist/memory/index.js +2 -0
  38. package/dist/memory/index.js.map +1 -0
  39. package/dist/memory/local/provider.d.ts +29 -0
  40. package/dist/memory/local/provider.d.ts.map +1 -0
  41. package/dist/memory/local/provider.js +202 -0
  42. package/dist/memory/local/provider.js.map +1 -0
  43. package/dist/memory/mem0/provider.d.ts +66 -0
  44. package/dist/memory/mem0/provider.d.ts.map +1 -0
  45. package/dist/memory/mem0/provider.js +310 -0
  46. package/dist/memory/mem0/provider.js.map +1 -0
  47. package/dist/memory/types.d.ts +91 -0
  48. package/dist/memory/types.d.ts.map +1 -0
  49. package/dist/memory/types.js +10 -0
  50. package/dist/memory/types.js.map +1 -0
  51. package/dist/mission-registry.d.ts +94 -0
  52. package/dist/mission-registry.d.ts.map +1 -0
  53. package/dist/mission-registry.js +123 -0
  54. package/dist/mission-registry.js.map +1 -0
  55. package/dist/mission-transcript-sink.d.ts +33 -0
  56. package/dist/mission-transcript-sink.d.ts.map +1 -0
  57. package/dist/mission-transcript-sink.js +76 -0
  58. package/dist/mission-transcript-sink.js.map +1 -0
  59. package/dist/mission.d.ts +281 -0
  60. package/dist/mission.d.ts.map +1 -0
  61. package/dist/mission.js +331 -0
  62. package/dist/mission.js.map +1 -0
  63. package/dist/planner/index.d.ts +84 -0
  64. package/dist/planner/index.d.ts.map +1 -0
  65. package/dist/planner/index.js +486 -0
  66. package/dist/planner/index.js.map +1 -0
  67. package/dist/robots.d.ts +133 -0
  68. package/dist/robots.d.ts.map +1 -0
  69. package/dist/robots.js +220 -0
  70. package/dist/robots.js.map +1 -0
  71. package/dist/topic-utils.d.ts +47 -0
  72. package/dist/topic-utils.d.ts.map +1 -0
  73. package/dist/topic-utils.js +136 -0
  74. package/dist/topic-utils.js.map +1 -0
  75. package/dist/transport/factory.d.ts +10 -0
  76. package/dist/transport/factory.d.ts.map +1 -0
  77. package/dist/transport/factory.js +40 -0
  78. package/dist/transport/factory.js.map +1 -0
  79. package/dist/transport/local/conversion.d.ts +30 -0
  80. package/dist/transport/local/conversion.d.ts.map +1 -0
  81. package/dist/transport/local/conversion.js +340 -0
  82. package/dist/transport/local/conversion.js.map +1 -0
  83. package/dist/transport/local/entities.d.ts +34 -0
  84. package/dist/transport/local/entities.d.ts.map +1 -0
  85. package/dist/transport/local/entities.js +108 -0
  86. package/dist/transport/local/entities.js.map +1 -0
  87. package/dist/transport/local/transport.d.ts +53 -0
  88. package/dist/transport/local/transport.d.ts.map +1 -0
  89. package/dist/transport/local/transport.js +344 -0
  90. package/dist/transport/local/transport.js.map +1 -0
  91. package/dist/transport/rosbridge/actions.d.ts +30 -0
  92. package/dist/transport/rosbridge/actions.d.ts.map +1 -0
  93. package/dist/transport/rosbridge/actions.js +61 -0
  94. package/dist/transport/rosbridge/actions.js.map +1 -0
  95. package/dist/transport/rosbridge/adapter.d.ts +29 -0
  96. package/dist/transport/rosbridge/adapter.d.ts.map +1 -0
  97. package/dist/transport/rosbridge/adapter.js +108 -0
  98. package/dist/transport/rosbridge/adapter.js.map +1 -0
  99. package/dist/transport/rosbridge/client.d.ts +55 -0
  100. package/dist/transport/rosbridge/client.d.ts.map +1 -0
  101. package/dist/transport/rosbridge/client.js +375 -0
  102. package/dist/transport/rosbridge/client.js.map +1 -0
  103. package/dist/transport/rosbridge/services.d.ts +14 -0
  104. package/dist/transport/rosbridge/services.d.ts.map +1 -0
  105. package/dist/transport/rosbridge/services.js +25 -0
  106. package/dist/transport/rosbridge/services.js.map +1 -0
  107. package/dist/transport/rosbridge/topics.d.ts +28 -0
  108. package/dist/transport/rosbridge/topics.d.ts.map +1 -0
  109. package/dist/transport/rosbridge/topics.js +59 -0
  110. package/dist/transport/rosbridge/topics.js.map +1 -0
  111. package/dist/transport/rosbridge/types.d.ts +87 -0
  112. package/dist/transport/rosbridge/types.d.ts.map +1 -0
  113. package/dist/transport/rosbridge/types.js +6 -0
  114. package/dist/transport/rosbridge/types.js.map +1 -0
  115. package/dist/transport/transport.d.ts +39 -0
  116. package/dist/transport/transport.d.ts.map +1 -0
  117. package/dist/transport/transport.js +2 -0
  118. package/dist/transport/transport.js.map +1 -0
  119. package/dist/transport/types.d.ts +100 -0
  120. package/dist/transport/types.d.ts.map +1 -0
  121. package/dist/transport/types.js +5 -0
  122. package/dist/transport/types.js.map +1 -0
  123. package/dist/transport/webrtc/signaling-client.d.ts +38 -0
  124. package/dist/transport/webrtc/signaling-client.d.ts.map +1 -0
  125. package/dist/transport/webrtc/signaling-client.js +161 -0
  126. package/dist/transport/webrtc/signaling-client.js.map +1 -0
  127. package/dist/transport/webrtc/signaling-types.d.ts +112 -0
  128. package/dist/transport/webrtc/signaling-types.d.ts.map +1 -0
  129. package/dist/transport/webrtc/signaling-types.js +8 -0
  130. package/dist/transport/webrtc/signaling-types.js.map +1 -0
  131. package/dist/transport/webrtc/transport.d.ts +67 -0
  132. package/dist/transport/webrtc/transport.d.ts.map +1 -0
  133. package/dist/transport/webrtc/transport.js +406 -0
  134. package/dist/transport/webrtc/transport.js.map +1 -0
  135. package/dist/transport/zenoh/adapter.d.ts +47 -0
  136. package/dist/transport/zenoh/adapter.d.ts.map +1 -0
  137. package/dist/transport/zenoh/adapter.js +296 -0
  138. package/dist/transport/zenoh/adapter.js.map +1 -0
  139. package/dist/transport/zenoh/cdr.d.ts +17 -0
  140. package/dist/transport/zenoh/cdr.d.ts.map +1 -0
  141. package/dist/transport/zenoh/cdr.js +170 -0
  142. package/dist/transport/zenoh/cdr.js.map +1 -0
  143. package/dist/transport/zenoh/keys.d.ts +21 -0
  144. package/dist/transport/zenoh/keys.d.ts.map +1 -0
  145. package/dist/transport/zenoh/keys.js +44 -0
  146. package/dist/transport/zenoh/keys.js.map +1 -0
  147. package/dist/transport-pool.d.ts +74 -0
  148. package/dist/transport-pool.d.ts.map +1 -0
  149. package/dist/transport-pool.js +135 -0
  150. package/dist/transport-pool.js.map +1 -0
  151. package/package.json +80 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js ADDED
@@ -0,0 +1,427 @@
1
+ import { z } from "zod";
2
+ const IceServerSchema = z.object({
3
+ urls: z.union([z.string(), z.array(z.string())]),
4
+ username: z.string().optional(),
5
+ credential: z.string().optional(),
6
+ });
7
+ // ─────────────────────────────────────────────────────────────────────────────
8
+ // Transport sub-schemas. Extracted so both the top-level config and the
9
+ // per-robot override in `robots[i].transport` can share them without
10
+ // drifting. The shapes mirror packages/core/src/transport/types.ts.
11
+ // ─────────────────────────────────────────────────────────────────────────────
12
+ const ZenohSettingsSchema = z.object({
13
+ /** WebSocket URL for zenoh-ts (zenoh-plugin-remote-api). Not tcp/ — use e.g. ws://localhost:10000 */
14
+ routerEndpoint: z.string().default("ws://localhost:10000"),
15
+ domainId: z.number().default(0),
16
+ /** "ros2dds" = zenoh-bridge-ros2dds key format (slashes kept). "rmw_zenoh" = rmw_zenoh key format (domain + %). */
17
+ keyFormat: z.enum(["ros2dds", "rmw_zenoh"]).default("ros2dds"),
18
+ /**
19
+ * Must match zenoh-bridge-ros2dds `plugins.ros2dds.namespace` when it is not the default "/".
20
+ * Example: bridge has `namespace: "/bot1"` → set `bridgeNamespace` to "/bot1" or "bot1".
21
+ * Omit or use "/" when the bridge uses the default (only the ROS topic path is the zenoh key).
22
+ */
23
+ bridgeNamespace: z.string().optional(),
24
+ });
25
+ const RosbridgeSettingsSchema = z.object({
26
+ url: z.string().default("ws://localhost:9090"),
27
+ reconnect: z.boolean().default(true),
28
+ reconnectInterval: z.number().default(3000),
29
+ });
30
+ const LocalSettingsSchema = z.object({
31
+ domainId: z.number().default(0),
32
+ });
33
+ const WebrtcSettingsSchema = z.object({
34
+ signalingUrl: z.string().default(""),
35
+ apiUrl: z.string().default(""),
36
+ robotId: z.string().default(""),
37
+ robotKey: z.string().default(""),
38
+ iceServers: z
39
+ .array(IceServerSchema)
40
+ .default([{ urls: "stun:stun.l.google.com:19302" }]),
41
+ });
42
+ /**
43
+ * Per-robot transport override sub-schemas (Phase 1.d-resolve).
44
+ *
45
+ * These intentionally MIRROR the top-level shapes but drop every
46
+ * `.default(...)`. Why: when `getTransportConfigForRobot` merges an
47
+ * override over the global config it does a per-field merge
48
+ * (`{ ...global, ...override }`). If the override schema applied
49
+ * defaults (e.g. `domainId: 0`), those defaults would silently clobber
50
+ * the global values whenever the user omitted them — making the
51
+ * "merge only the fields I actually wrote" contract impossible.
52
+ *
53
+ * Every field is optional here. Validation still rejects wrong types
54
+ * (e.g. `routerEndpoint: 42`), which is what we want.
55
+ */
56
+ const ZenohOverrideSettingsSchema = z.object({
57
+ routerEndpoint: z.string().optional(),
58
+ domainId: z.number().optional(),
59
+ keyFormat: z.enum(["ros2dds", "rmw_zenoh"]).optional(),
60
+ bridgeNamespace: z.string().optional(),
61
+ });
62
+ const RosbridgeOverrideSettingsSchema = z.object({
63
+ url: z.string().optional(),
64
+ reconnect: z.boolean().optional(),
65
+ reconnectInterval: z.number().optional(),
66
+ });
67
+ const LocalOverrideSettingsSchema = z.object({
68
+ domainId: z.number().optional(),
69
+ });
70
+ const WebrtcOverrideSettingsSchema = z.object({
71
+ signalingUrl: z.string().optional(),
72
+ apiUrl: z.string().optional(),
73
+ robotId: z.string().optional(),
74
+ robotKey: z.string().optional(),
75
+ iceServers: z.array(IceServerSchema).optional(),
76
+ });
77
+ /**
78
+ * Per-robot transport override schema (Phase 1.d-resolve).
79
+ *
80
+ * Discriminated union on `mode`, each variant `.strict()` so that a
81
+ * typo like `{ mode: "zenoh", local: {...} }` fails fast at parse time
82
+ * instead of being silently stripped. Sub-sections are optional —
83
+ * `{ mode: "zenoh" }` is a valid override that inherits everything
84
+ * from the top-level `config.zenoh`. A partial sub-section like
85
+ * `{ mode: "zenoh", zenoh: { routerEndpoint: "ws://field:10000" } }`
86
+ * is merged per-field over the global config — see the resolver.
87
+ *
88
+ * Why a discriminated union (vs the top-level shape of sibling fields):
89
+ * - Keeps the override self-contained at one JSON property
90
+ * - Matches TransportConfig's runtime discriminated union 1:1
91
+ * - Trivially validatable per-robot without leaking across siblings
92
+ */
93
+ const RobotTransportOverrideSchema = z.discriminatedUnion("mode", [
94
+ z
95
+ .object({
96
+ mode: z.literal("rosbridge"),
97
+ rosbridge: RosbridgeOverrideSettingsSchema.optional(),
98
+ })
99
+ .strict(),
100
+ z
101
+ .object({
102
+ mode: z.literal("local"),
103
+ local: LocalOverrideSettingsSchema.optional(),
104
+ })
105
+ .strict(),
106
+ z
107
+ .object({
108
+ mode: z.literal("zenoh"),
109
+ zenoh: ZenohOverrideSettingsSchema.optional(),
110
+ })
111
+ .strict(),
112
+ z
113
+ .object({
114
+ mode: z.literal("webrtc"),
115
+ webrtc: WebrtcOverrideSettingsSchema.optional(),
116
+ })
117
+ .strict(),
118
+ ]);
119
+ export const AgenticROSConfigSchema = z.object({
120
+ transport: z
121
+ .object({
122
+ /**
123
+ * Default is "local" — assumes the gateway is co-located with the robot
124
+ * (Mode A: DDS direct via rclnodejs, no router). Switch to "rosbridge",
125
+ * "zenoh", or "webrtc" when the gateway runs off-robot.
126
+ */
127
+ mode: z.enum(["rosbridge", "local", "webrtc", "zenoh"]).default("local"),
128
+ })
129
+ .default({}),
130
+ zenoh: ZenohSettingsSchema.default({}),
131
+ rosbridge: RosbridgeSettingsSchema.default({}),
132
+ local: LocalSettingsSchema.default({}),
133
+ webrtc: WebrtcSettingsSchema.default({}),
134
+ robot: z
135
+ .object({
136
+ name: z.string().default("Robot"),
137
+ namespace: z.string().default(""),
138
+ /** Camera topic for "what do you see?" (e.g. /camera/camera/color/image_raw/compressed). If set, used as default in ros2_camera_snapshot and in context. */
139
+ cameraTopic: z.string().default(""),
140
+ })
141
+ .default({}),
142
+ /**
143
+ * Phase 1.d multi-robot list. When non-empty, this is the source of
144
+ * truth for `ros2_list_robots` and (in a follow-up) the per-tool
145
+ * `robot_id` parameter. When empty, the legacy single-robot
146
+ * `config.robot` above is synthesised into a one-entry list at
147
+ * resolution time (see packages/core/src/robots.ts). Existing configs
148
+ * keep working unchanged; this field is opt-in.
149
+ *
150
+ * Mark one entry with `default: true` to make it the active robot
151
+ * even when it isn't the first in the list. Otherwise the first entry
152
+ * wins.
153
+ */
154
+ robots: z
155
+ .array(z.object({
156
+ /** Stable, human-readable identifier referenced by `robot_id` arguments. */
157
+ id: z.string(),
158
+ name: z.string().default("Robot"),
159
+ namespace: z.string().default(""),
160
+ cameraTopic: z.string().default(""),
161
+ default: z.boolean().optional(),
162
+ /**
163
+ * Phase 1.e robot kind ("amr" | "arm" | "drone" | "rover" | …).
164
+ *
165
+ * Free-form string so users can invent their own taxonomy, but the
166
+ * documented set is `amr` (autonomous mobile robot), `arm`,
167
+ * `drone`, and `rover`. Consumed by `ros2_find_robots_for(kind=…)`
168
+ * so an agent can ask "find me an AMR with a depth camera that
169
+ * can follow_person" and the platform filters the fleet.
170
+ *
171
+ * Defaults to "amr" (back-compat: every existing robot today is
172
+ * an AMR), so the field stays useful even when the user hasn't
173
+ * tagged their robots explicitly.
174
+ */
175
+ kind: z.string().default("amr"),
176
+ /**
177
+ * Phase 1.e sensor/hardware tags.
178
+ *
179
+ * Lets `ros2_find_robots_for` answer questions like "which
180
+ * robots have a depth camera" without subscribing to topics or
181
+ * inspecting the URDF. All flags default to false — set them
182
+ * explicitly per robot via the CLI (`--sensors=has_realsense`)
183
+ * or by hand-editing `~/.agenticros/config.json`.
184
+ *
185
+ * The list is intentionally short for Phase 1; expand it as we
186
+ * accumulate seed-catalog skills that depend on a specific
187
+ * hardware capability (lidar SLAM, arm grasping, etc.).
188
+ */
189
+ sensors: z
190
+ .object({
191
+ has_realsense: z.boolean().default(false),
192
+ has_lidar: z.boolean().default(false),
193
+ has_arm: z.boolean().default(false),
194
+ })
195
+ .default({}),
196
+ /**
197
+ * Phase 1.e optional per-robot capability allowlist.
198
+ *
199
+ * When set, restricts which capabilities `ros2_find_robots_for`
200
+ * considers this robot capable of. When unset (the common
201
+ * case), the robot inherits the gateway's global capability
202
+ * registry (the union of built-in verbs plus every loaded
203
+ * skill's capabilities). Useful in heterogeneous fleets where
204
+ * one robot has the arm skill loaded and another doesn't.
205
+ */
206
+ capabilities: z.array(z.string()).optional(),
207
+ /**
208
+ * Phase 1.d-resolve per-robot transport override.
209
+ *
210
+ * When set, this robot uses its own transport instead of the
211
+ * top-level `config.transport.*`. Useful when one host drives
212
+ * BOTH a local sim (mode: "local") AND a real robot reached via
213
+ * an off-robot bridge (mode: "zenoh" / "rosbridge") — each
214
+ * robot connects through the right path with no global config
215
+ * juggling.
216
+ *
217
+ * Sub-sections (`zenoh`, `rosbridge`, `local`, `webrtc`) are
218
+ * optional inside the override: omit them to inherit the global
219
+ * `config.<section>` defaults; set them to override only the
220
+ * fields you need (e.g. a different router endpoint).
221
+ *
222
+ * Consumed by `getTransportConfigForRobot(config, robotId)` in
223
+ * robots.ts. Adapters opt in to multi-transport pools — when
224
+ * the override is absent they keep using the single global
225
+ * transport, so existing single-robot deployments are
226
+ * unaffected.
227
+ */
228
+ transport: RobotTransportOverrideSchema.optional(),
229
+ }))
230
+ .default([]),
231
+ /** Phase 3 teleop web app: camera + twist controls. */
232
+ teleop: z
233
+ .object({
234
+ /** Default camera topic when only one source or as default selection. Falls back to robot.cameraTopic then RealSense default. */
235
+ cameraTopic: z.string().default(""),
236
+ /** Explicit list of camera sources for the selector; if empty, derived from listTopics() filtered by Image/CompressedImage. */
237
+ cameraTopics: z
238
+ .array(z.object({ topic: z.string(), label: z.string().optional() }))
239
+ .default([]),
240
+ /** cmd_vel topic override (default from robot namespace). */
241
+ cmdVelTopic: z.string().default(""),
242
+ /** Default linear speed (m/s) for teleop. */
243
+ speedDefault: z.coerce.number().min(0).max(2).default(0.3),
244
+ /** Camera poll interval in ms for the teleop page. */
245
+ cameraPollMs: z.number().min(50).max(2000).default(150),
246
+ })
247
+ .default({}),
248
+ safety: z
249
+ .object({
250
+ maxLinearVelocity: z.number().default(1.0),
251
+ maxAngularVelocity: z.number().default(1.5),
252
+ workspaceLimits: z
253
+ .object({
254
+ xMin: z.number().default(-10),
255
+ xMax: z.number().default(10),
256
+ yMin: z.number().default(-10),
257
+ yMax: z.number().default(10),
258
+ })
259
+ .default({}),
260
+ })
261
+ .default({}),
262
+ /**
263
+ * Optional in-plugin image describer.
264
+ *
265
+ * When the primary chat model is text-only (e.g. Ollama qwen2.5:7b),
266
+ * OpenClaw filters image content blocks out of tool results before the
267
+ * LLM ever sees them, so `ros2_camera_snapshot` cannot be described.
268
+ * Configuring an OpenAI-compatible chat completions endpoint here lets
269
+ * the plugin call a vision model itself and embed the description text
270
+ * directly in the snapshot tool result.
271
+ *
272
+ * Recommended Jetson setup: point at local Ollama with a VL model:
273
+ * url: "http://host.docker.internal:11434/v1/chat/completions"
274
+ * model: "qwen2.5vl:7b"
275
+ *
276
+ * If `enabled: false`, the snapshot result includes only the camera URL
277
+ * and the agent is on its own (suitable when the primary model is
278
+ * multimodal and OpenClaw does not need to filter images).
279
+ */
280
+ describer: z
281
+ .object({
282
+ enabled: z.boolean().default(false),
283
+ /** OpenAI-compat chat completions endpoint URL. */
284
+ url: z
285
+ .string()
286
+ // host.openshell.internal:11435 is the nemoclaw ollama-auth-proxy
287
+ // bound to the docker bridge — it's the ONLY way to reach the
288
+ // host's Ollama from a NemoClaw sandbox. Two reasons:
289
+ // 1. The default Ollama daemon binds 127.0.0.1:11434 on the
290
+ // host, which is not reachable from the bridge.
291
+ // 2. The built-in `local-inference` policy permits POST to
292
+ // host.openshell.internal:11435 (and 11434/8000) but the
293
+ // OPA proxy will refuse a forward to any other port.
294
+ // The auth-proxy requires `Authorization: Bearer <token>` from
295
+ // ~/.nemoclaw/ollama-proxy-token — set ``describer.apiKey``.
296
+ .default("http://host.openshell.internal:11435/v1/chat/completions"),
297
+ /** Optional Bearer token / API key for the endpoint. */
298
+ apiKey: z.string().optional(),
299
+ /** Vision model id (must accept OpenAI `image_url` content blocks). */
300
+ model: z.string().default("qwen2.5vl:7b"),
301
+ /** Prompt sent alongside the image. */
302
+ prompt: z
303
+ .string()
304
+ .default("Describe what is visible in this camera frame from a mobile robot. " +
305
+ "Focus on the physical scene: objects, materials, layout, colors, lighting, distances. " +
306
+ "Be concrete and specific. Do not speculate or add detail you cannot see."),
307
+ /** Max tokens for the description. */
308
+ maxTokens: z.number().int().min(50).max(2048).default(400),
309
+ /** Request timeout in ms. */
310
+ timeoutMs: z.number().int().min(1000).max(180000).default(60000),
311
+ /**
312
+ * Resize images larger than this max dimension before sending to the
313
+ * VL model. Reduces token usage and latency. Set to 0 to disable.
314
+ */
315
+ maxImageDimension: z.number().int().min(0).max(4096).default(896),
316
+ })
317
+ .default({}),
318
+ /**
319
+ * Optional cross-adapter semantic memory subsystem.
320
+ *
321
+ * When `enabled: true`, OpenClaw, Claude Code, and Gemini adapters all
322
+ * register four memory tools (memory_remember / memory_recall /
323
+ * memory_forget / memory_status) backed by a shared store. Default is
324
+ * off — zero new deps when disabled.
325
+ *
326
+ * See docs/memory.md for ready-to-paste recipes.
327
+ */
328
+ memory: z
329
+ .object({
330
+ /** Master switch. When false, adapters skip registering memory tools. */
331
+ enabled: z.boolean().default(false),
332
+ /** Which backend to use. "local" has no extra deps; "mem0" needs `pnpm add mem0ai`. */
333
+ backend: z.enum(["local", "mem0"]).default("local"),
334
+ /** Override the per-record namespace. Defaults to robot.namespace at call time. */
335
+ namespace: z.string().optional(),
336
+ local: z
337
+ .object({
338
+ /** JSON-on-disk store path. Supports leading "~/". */
339
+ storePath: z.string().default("~/.agenticros/memory.json"),
340
+ })
341
+ .default({}),
342
+ mem0: z
343
+ .object({
344
+ /**
345
+ * When true, mem0 runs its LLM-driven fact extraction on `add`.
346
+ * When false (default), content is stored as-is — predictable,
347
+ * no LLM call on write, agent stays in explicit control.
348
+ */
349
+ inferOnWrite: z.boolean().default(false),
350
+ /** SQLite history db path (mem0 historyDbPath). Supports leading "~/". */
351
+ historyDbPath: z
352
+ .string()
353
+ .default("~/.agenticros/memory-history.db"),
354
+ /**
355
+ * Embedder passed verbatim to `new Memory({ embedder })`.
356
+ * When omitted, the factory auto-detects: Ollama (if reachable)
357
+ * → OpenAI (if OPENAI_API_KEY set) → error.
358
+ */
359
+ embedder: z
360
+ .object({
361
+ provider: z.string(),
362
+ config: z.record(z.string(), z.unknown()),
363
+ })
364
+ .optional(),
365
+ /** Vector store passed verbatim to `new Memory({ vectorStore })`. */
366
+ vectorStore: z
367
+ .object({
368
+ provider: z.string(),
369
+ config: z.record(z.string(), z.unknown()),
370
+ })
371
+ .optional(),
372
+ /** LLM passed verbatim to `new Memory({ llm })`. Only used when inferOnWrite is true. */
373
+ llm: z
374
+ .object({
375
+ provider: z.string(),
376
+ config: z.record(z.string(), z.unknown()),
377
+ })
378
+ .optional(),
379
+ })
380
+ .default({}),
381
+ })
382
+ .default({}),
383
+ /** Per-skill config. Keys are skill ids (e.g. followme). Each skill validates its own slice. */
384
+ skills: z.record(z.string(), z.unknown()).default({}),
385
+ /** Directories to scan for skill packages (package.json with an `agenticros` block). Resolved at gateway start. */
386
+ skillPaths: z.array(z.string()).default([]),
387
+ /** Npm (or local) package names to load as skills. Resolved via require.resolve from plugin context. */
388
+ skillPackages: z.array(z.string()).default([]),
389
+ });
390
+ /**
391
+ * Parse and validate raw config against the schema.
392
+ * Returns a fully-defaulted, typed config object.
393
+ * Backward compat: if raw.followMe is set, it is merged into raw.skills.followme before parsing.
394
+ */
395
+ export function parseConfig(raw) {
396
+ const normalized = { ...raw };
397
+ const followMe = raw.followMe;
398
+ if (followMe !== undefined && followMe !== null && typeof followMe === "object") {
399
+ const skills = normalized.skills ?? {};
400
+ if (!(typeof skills === "object" && skills !== null && !Array.isArray(skills))) {
401
+ normalized.skills = { followme: followMe };
402
+ }
403
+ else if (!("followme" in skills)) {
404
+ normalized.skills = { ...skills, followme: followMe };
405
+ }
406
+ }
407
+ return AgenticROSConfigSchema.parse(normalized);
408
+ }
409
+ /**
410
+ * Build TransportConfig from full config for createTransport().
411
+ */
412
+ export function getTransportConfig(config) {
413
+ const mode = config.transport?.mode ?? "local";
414
+ switch (mode) {
415
+ case "rosbridge":
416
+ return { mode: "rosbridge", rosbridge: config.rosbridge ?? { url: "ws://localhost:9090" } };
417
+ case "local":
418
+ return { mode: "local", local: config.local };
419
+ case "webrtc":
420
+ return { mode: "webrtc", webrtc: config.webrtc ?? {} };
421
+ case "zenoh":
422
+ return { mode: "zenoh", zenoh: config.zenoh ?? {} };
423
+ default:
424
+ return { mode: "local", local: config.local ?? { domainId: 0 } };
425
+ }
426
+ }
427
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Multi-robot discovery — Phase 1.d "fleet awareness on the wire".
3
+ *
4
+ * Configuration tells the gateway what robots the user wants to talk to.
5
+ * The transport tells the gateway what's actually on the wire right now.
6
+ * Discovery is the bridge: scan published ROS2 topics, infer robot
7
+ * namespaces from `<ns>/cmd_vel` patterns, cross-reference against the
8
+ * configured robot list, and surface three categories:
9
+ *
10
+ * 1. configured_online — in config AND seen on the wire
11
+ * 2. configured_offline — in config but NOT seen on the wire
12
+ * 3. unknown_detected — on the wire but NOT in config
13
+ *
14
+ * The agent uses this to answer questions like "which robots can I talk
15
+ * to right now?" without forcing the user to hand-edit
16
+ * `~/.agenticros/config.json` every time a robot joins the network.
17
+ *
18
+ * Persistence is intentionally OUT of scope here: discovery is read-only.
19
+ * Writing newly-detected robots into the user's config is a separate
20
+ * UX decision handled by the CLI / OpenClaw config UI on top of this
21
+ * function.
22
+ *
23
+ * ## Detection signal
24
+ *
25
+ * `<ns>/cmd_vel` (the velocity command topic) is the canonical signal —
26
+ * a robot that can be driven publishes/subscribes there. Other topics
27
+ * like `<ns>/odom`, `<ns>/joint_states`, and `<ns>/camera/...` corroborate
28
+ * the same `<ns>`; we surface them as `topicCount` so consumers can
29
+ * gauge how "alive" the namespace looks.
30
+ *
31
+ * The unnamespaced `/cmd_vel` topic (default namespace, common in
32
+ * simulation) is detected as id="" — consumers can render it as
33
+ * "default robot" or similar.
34
+ *
35
+ * ## Namespace rewrite
36
+ *
37
+ * `ros2_publish` rewrites a UUID-shaped namespace like
38
+ * `3946b404-c33e-...` into `robot3946b404c33e...` (strip dashes,
39
+ * prefix with "robot") because most robot firmware expects the
40
+ * dashless form. Discovery applies the same rewrite when matching
41
+ * configured robots against detected namespaces, so a UUID-style
42
+ * config entry still matches the `/robot<no-dashes>/cmd_vel` topic
43
+ * the robot is actually publishing on.
44
+ */
45
+ import type { AgenticROSConfig } from "./config.js";
46
+ import type { ResolvedRobot } from "./robots.js";
47
+ import type { TopicInfo } from "./transport/types.js";
48
+ /** One robot inferred from the topic graph. */
49
+ export interface DetectedRobot {
50
+ /** The namespace segment, e.g. "robot3946b...". Empty string = default namespace. */
51
+ id: string;
52
+ /** The full cmd_vel topic name we saw — e.g. "/robot3946b.../cmd_vel". */
53
+ cmdVelTopic: string;
54
+ /**
55
+ * Total topics under `/<id>/`, INCLUDING the cmd_vel topic itself.
56
+ * A topicCount of 1 means the robot is "barely there" (just cmd_vel,
57
+ * no odom / joint_states / camera etc.); higher counts corroborate
58
+ * that the namespace is actually a live robot, not a stale advert.
59
+ * Always 0 for the unnamespaced default robot (id="").
60
+ */
61
+ topicCount: number;
62
+ /**
63
+ * The matching `robot.id` from `config.robots` (or the legacy fallback)
64
+ * when this detected namespace maps to a configured robot, otherwise
65
+ * `null`. Matching uses the same UUID→robot-no-dashes rewrite as the
66
+ * publish path.
67
+ */
68
+ configuredRobotId: string | null;
69
+ }
70
+ /** Result of a discovery pass. */
71
+ export interface RobotDiscoveryResult {
72
+ /** Every robot inferred from the topic graph, with config match annotations. */
73
+ detected: DetectedRobot[];
74
+ /** Configured robots that ARE present on the wire right now. */
75
+ configured_online: ResolvedRobot[];
76
+ /** Configured robots that are NOT present on the wire right now. */
77
+ configured_offline: ResolvedRobot[];
78
+ /** Detected robots that have no matching config entry — candidates to add. */
79
+ unknown_detected: DetectedRobot[];
80
+ /** Total topics scanned (echoed for diagnostics). */
81
+ total_topics: number;
82
+ }
83
+ /**
84
+ * Apply the same UUID→robot-no-dashes rewrite as `ros2_publish` uses
85
+ * when normalising a `/<ns>/cmd_vel` target.
86
+ *
87
+ * `""` stays `""` (default namespace). Namespaces that already start
88
+ * with "robot" are returned unchanged.
89
+ */
90
+ export declare function effectiveCmdVelNamespace(robotNamespace: string): string;
91
+ /**
92
+ * Find every robot-shaped namespace in a topic list.
93
+ *
94
+ * Detection rule: any `/<seg>/cmd_vel` topic implies a robot with
95
+ * namespace `<seg>`. The unnamespaced `/cmd_vel` topic registers the
96
+ * empty namespace (id=""). Topic count under each namespace is
97
+ * accumulated so consumers can rank by liveness.
98
+ *
99
+ * The returned `DetectedRobot.configuredRobotId` is always `null` here —
100
+ * call `discoverRobots()` (which wraps this function) to annotate with
101
+ * config matches.
102
+ */
103
+ export declare function detectRobotsFromTopics(topics: TopicInfo[]): DetectedRobot[];
104
+ /**
105
+ * Top-level discovery: detect robots on the wire, match against the
106
+ * configured robot list, and classify into online / offline / unknown.
107
+ *
108
+ * Pure function — feed it the topic list and the config, get a result
109
+ * back. No transport access here; adapters wrap this with a call to
110
+ * `transport.listTopics()`.
111
+ */
112
+ export declare function discoverRobots(topics: TopicInfo[], config: AgenticROSConfig): RobotDiscoveryResult;
113
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,qFAAqF;IACrF,EAAE,EAAE,MAAM,CAAC;IACX,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,kCAAkC;AAClC,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,gEAAgE;IAChE,iBAAiB,EAAE,aAAa,EAAE,CAAC;IACnC,oEAAoE;IACpE,kBAAkB,EAAE,aAAa,EAAE,CAAC;IACpC,8EAA8E;IAC9E,gBAAgB,EAAE,aAAa,EAAE,CAAC;IAClC,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,aAAa,EAAE,CAiC3E;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EAAE,EACnB,MAAM,EAAE,gBAAgB,GACvB,oBAAoB,CAiCtB"}