@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.
- package/LICENSE +192 -0
- package/README.md +88 -0
- package/dist/banner.d.ts +7 -0
- package/dist/banner.d.ts.map +1 -0
- package/dist/banner.js +25 -0
- package/dist/banner.js.map +1 -0
- package/dist/capabilities.d.ts +101 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +240 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/cmd-vel-twist.d.ts +9 -0
- package/dist/cmd-vel-twist.d.ts.map +1 -0
- package/dist/cmd-vel-twist.js +32 -0
- package/dist/cmd-vel-twist.js.map +1 -0
- package/dist/config.d.ts +1195 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +427 -0
- package/dist/config.js.map +1 -0
- package/dist/discovery.d.ts +113 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +141 -0
- package/dist/discovery.js.map +1 -0
- package/dist/find-robots-for.d.ts +85 -0
- package/dist/find-robots-for.d.ts.map +1 -0
- package/dist/find-robots-for.js +120 -0
- package/dist/find-robots-for.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/memory/factory.d.ts +18 -0
- package/dist/memory/factory.d.ts.map +1 -0
- package/dist/memory/factory.js +51 -0
- package/dist/memory/factory.js.map +1 -0
- package/dist/memory/index.d.ts +3 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +2 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/local/provider.d.ts +29 -0
- package/dist/memory/local/provider.d.ts.map +1 -0
- package/dist/memory/local/provider.js +202 -0
- package/dist/memory/local/provider.js.map +1 -0
- package/dist/memory/mem0/provider.d.ts +66 -0
- package/dist/memory/mem0/provider.d.ts.map +1 -0
- package/dist/memory/mem0/provider.js +310 -0
- package/dist/memory/mem0/provider.js.map +1 -0
- package/dist/memory/types.d.ts +91 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +10 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/mission-registry.d.ts +94 -0
- package/dist/mission-registry.d.ts.map +1 -0
- package/dist/mission-registry.js +123 -0
- package/dist/mission-registry.js.map +1 -0
- package/dist/mission-transcript-sink.d.ts +33 -0
- package/dist/mission-transcript-sink.d.ts.map +1 -0
- package/dist/mission-transcript-sink.js +76 -0
- package/dist/mission-transcript-sink.js.map +1 -0
- package/dist/mission.d.ts +281 -0
- package/dist/mission.d.ts.map +1 -0
- package/dist/mission.js +331 -0
- package/dist/mission.js.map +1 -0
- package/dist/planner/index.d.ts +84 -0
- package/dist/planner/index.d.ts.map +1 -0
- package/dist/planner/index.js +486 -0
- package/dist/planner/index.js.map +1 -0
- package/dist/robots.d.ts +133 -0
- package/dist/robots.d.ts.map +1 -0
- package/dist/robots.js +220 -0
- package/dist/robots.js.map +1 -0
- package/dist/topic-utils.d.ts +47 -0
- package/dist/topic-utils.d.ts.map +1 -0
- package/dist/topic-utils.js +136 -0
- package/dist/topic-utils.js.map +1 -0
- package/dist/transport/factory.d.ts +10 -0
- package/dist/transport/factory.d.ts.map +1 -0
- package/dist/transport/factory.js +40 -0
- package/dist/transport/factory.js.map +1 -0
- package/dist/transport/local/conversion.d.ts +30 -0
- package/dist/transport/local/conversion.d.ts.map +1 -0
- package/dist/transport/local/conversion.js +340 -0
- package/dist/transport/local/conversion.js.map +1 -0
- package/dist/transport/local/entities.d.ts +34 -0
- package/dist/transport/local/entities.d.ts.map +1 -0
- package/dist/transport/local/entities.js +108 -0
- package/dist/transport/local/entities.js.map +1 -0
- package/dist/transport/local/transport.d.ts +53 -0
- package/dist/transport/local/transport.d.ts.map +1 -0
- package/dist/transport/local/transport.js +344 -0
- package/dist/transport/local/transport.js.map +1 -0
- package/dist/transport/rosbridge/actions.d.ts +30 -0
- package/dist/transport/rosbridge/actions.d.ts.map +1 -0
- package/dist/transport/rosbridge/actions.js +61 -0
- package/dist/transport/rosbridge/actions.js.map +1 -0
- package/dist/transport/rosbridge/adapter.d.ts +29 -0
- package/dist/transport/rosbridge/adapter.d.ts.map +1 -0
- package/dist/transport/rosbridge/adapter.js +108 -0
- package/dist/transport/rosbridge/adapter.js.map +1 -0
- package/dist/transport/rosbridge/client.d.ts +55 -0
- package/dist/transport/rosbridge/client.d.ts.map +1 -0
- package/dist/transport/rosbridge/client.js +375 -0
- package/dist/transport/rosbridge/client.js.map +1 -0
- package/dist/transport/rosbridge/services.d.ts +14 -0
- package/dist/transport/rosbridge/services.d.ts.map +1 -0
- package/dist/transport/rosbridge/services.js +25 -0
- package/dist/transport/rosbridge/services.js.map +1 -0
- package/dist/transport/rosbridge/topics.d.ts +28 -0
- package/dist/transport/rosbridge/topics.d.ts.map +1 -0
- package/dist/transport/rosbridge/topics.js +59 -0
- package/dist/transport/rosbridge/topics.js.map +1 -0
- package/dist/transport/rosbridge/types.d.ts +87 -0
- package/dist/transport/rosbridge/types.d.ts.map +1 -0
- package/dist/transport/rosbridge/types.js +6 -0
- package/dist/transport/rosbridge/types.js.map +1 -0
- package/dist/transport/transport.d.ts +39 -0
- package/dist/transport/transport.d.ts.map +1 -0
- package/dist/transport/transport.js +2 -0
- package/dist/transport/transport.js.map +1 -0
- package/dist/transport/types.d.ts +100 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +5 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/transport/webrtc/signaling-client.d.ts +38 -0
- package/dist/transport/webrtc/signaling-client.d.ts.map +1 -0
- package/dist/transport/webrtc/signaling-client.js +161 -0
- package/dist/transport/webrtc/signaling-client.js.map +1 -0
- package/dist/transport/webrtc/signaling-types.d.ts +112 -0
- package/dist/transport/webrtc/signaling-types.d.ts.map +1 -0
- package/dist/transport/webrtc/signaling-types.js +8 -0
- package/dist/transport/webrtc/signaling-types.js.map +1 -0
- package/dist/transport/webrtc/transport.d.ts +67 -0
- package/dist/transport/webrtc/transport.d.ts.map +1 -0
- package/dist/transport/webrtc/transport.js +406 -0
- package/dist/transport/webrtc/transport.js.map +1 -0
- package/dist/transport/zenoh/adapter.d.ts +47 -0
- package/dist/transport/zenoh/adapter.d.ts.map +1 -0
- package/dist/transport/zenoh/adapter.js +296 -0
- package/dist/transport/zenoh/adapter.js.map +1 -0
- package/dist/transport/zenoh/cdr.d.ts +17 -0
- package/dist/transport/zenoh/cdr.d.ts.map +1 -0
- package/dist/transport/zenoh/cdr.js +170 -0
- package/dist/transport/zenoh/cdr.js.map +1 -0
- package/dist/transport/zenoh/keys.d.ts +21 -0
- package/dist/transport/zenoh/keys.d.ts.map +1 -0
- package/dist/transport/zenoh/keys.js +44 -0
- package/dist/transport/zenoh/keys.js.map +1 -0
- package/dist/transport-pool.d.ts +74 -0
- package/dist/transport-pool.d.ts.map +1 -0
- package/dist/transport-pool.js +135 -0
- package/dist/transport-pool.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,141 @@
|
|
|
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 { listRobots } from "./robots.js";
|
|
46
|
+
/**
|
|
47
|
+
* Apply the same UUID→robot-no-dashes rewrite as `ros2_publish` uses
|
|
48
|
+
* when normalising a `/<ns>/cmd_vel` target.
|
|
49
|
+
*
|
|
50
|
+
* `""` stays `""` (default namespace). Namespaces that already start
|
|
51
|
+
* with "robot" are returned unchanged.
|
|
52
|
+
*/
|
|
53
|
+
export function effectiveCmdVelNamespace(robotNamespace) {
|
|
54
|
+
const ns = robotNamespace.trim();
|
|
55
|
+
if (ns === "")
|
|
56
|
+
return "";
|
|
57
|
+
if (ns.toLowerCase().startsWith("robot"))
|
|
58
|
+
return ns;
|
|
59
|
+
return `robot${ns.replace(/-/g, "")}`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Find every robot-shaped namespace in a topic list.
|
|
63
|
+
*
|
|
64
|
+
* Detection rule: any `/<seg>/cmd_vel` topic implies a robot with
|
|
65
|
+
* namespace `<seg>`. The unnamespaced `/cmd_vel` topic registers the
|
|
66
|
+
* empty namespace (id=""). Topic count under each namespace is
|
|
67
|
+
* accumulated so consumers can rank by liveness.
|
|
68
|
+
*
|
|
69
|
+
* The returned `DetectedRobot.configuredRobotId` is always `null` here —
|
|
70
|
+
* call `discoverRobots()` (which wraps this function) to annotate with
|
|
71
|
+
* config matches.
|
|
72
|
+
*/
|
|
73
|
+
export function detectRobotsFromTopics(topics) {
|
|
74
|
+
const byNs = new Map();
|
|
75
|
+
for (const t of topics) {
|
|
76
|
+
// Match /<seg>/cmd_vel exactly — sub-namespaces would imply a more
|
|
77
|
+
// complex robot graph than this v1 wants to handle.
|
|
78
|
+
const m = t.name.match(/^\/([^/]+)\/cmd_vel$/);
|
|
79
|
+
if (m) {
|
|
80
|
+
const ns = m[1];
|
|
81
|
+
if (!byNs.has(ns))
|
|
82
|
+
byNs.set(ns, { cmdVelTopic: t.name, topicCount: 0 });
|
|
83
|
+
}
|
|
84
|
+
else if (t.name === "/cmd_vel" && !byNs.has("")) {
|
|
85
|
+
byNs.set("", { cmdVelTopic: "/cmd_vel", topicCount: 0 });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Count topics under each detected namespace. Empty-namespace robots
|
|
89
|
+
// (default) intentionally don't accumulate counts — every topic in
|
|
90
|
+
// the system would otherwise "belong" to them, which is misleading.
|
|
91
|
+
for (const t of topics) {
|
|
92
|
+
for (const [ns, info] of byNs) {
|
|
93
|
+
if (ns === "")
|
|
94
|
+
continue;
|
|
95
|
+
if (t.name.startsWith(`/${ns}/`)) {
|
|
96
|
+
info.topicCount += 1;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return Array.from(byNs.entries()).map(([id, info]) => ({
|
|
101
|
+
id,
|
|
102
|
+
cmdVelTopic: info.cmdVelTopic,
|
|
103
|
+
topicCount: info.topicCount,
|
|
104
|
+
configuredRobotId: null,
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Top-level discovery: detect robots on the wire, match against the
|
|
109
|
+
* configured robot list, and classify into online / offline / unknown.
|
|
110
|
+
*
|
|
111
|
+
* Pure function — feed it the topic list and the config, get a result
|
|
112
|
+
* back. No transport access here; adapters wrap this with a call to
|
|
113
|
+
* `transport.listTopics()`.
|
|
114
|
+
*/
|
|
115
|
+
export function discoverRobots(topics, config) {
|
|
116
|
+
const detected = detectRobotsFromTopics(topics);
|
|
117
|
+
const configured = listRobots(config);
|
|
118
|
+
// Map effective-namespace → configured robot for O(1) lookup.
|
|
119
|
+
const effToCfg = new Map();
|
|
120
|
+
for (const r of configured) {
|
|
121
|
+
effToCfg.set(effectiveCmdVelNamespace(r.namespace), r);
|
|
122
|
+
}
|
|
123
|
+
const annotated = detected.map((d) => {
|
|
124
|
+
const cfg = effToCfg.get(d.id);
|
|
125
|
+
return cfg
|
|
126
|
+
? { ...d, configuredRobotId: cfg.id }
|
|
127
|
+
: { ...d, configuredRobotId: null };
|
|
128
|
+
});
|
|
129
|
+
const detectedIds = new Set(annotated.map((d) => d.id));
|
|
130
|
+
const configured_online = configured.filter((r) => detectedIds.has(effectiveCmdVelNamespace(r.namespace)));
|
|
131
|
+
const configured_offline = configured.filter((r) => !detectedIds.has(effectiveCmdVelNamespace(r.namespace)));
|
|
132
|
+
const unknown_detected = annotated.filter((d) => d.configuredRobotId === null);
|
|
133
|
+
return {
|
|
134
|
+
detected: annotated,
|
|
135
|
+
configured_online,
|
|
136
|
+
configured_offline,
|
|
137
|
+
unknown_detected,
|
|
138
|
+
total_topics: topics.length,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `findRobotsFor` — Phase 1.e capability-aware robot filter.
|
|
3
|
+
*
|
|
4
|
+
* Given a (capability?, kind?, online?) query, returns the configured
|
|
5
|
+
* robots that match, ranked best-first. This is the resolver behind the
|
|
6
|
+
* `ros2_find_robots_for` MCP tool — adapters call it from `tools.ts`
|
|
7
|
+
* with the live online-set computed from a topic scan (or `undefined`
|
|
8
|
+
* when `online` isn't being filtered, so we don't pay for the scan).
|
|
9
|
+
*
|
|
10
|
+
* Filter semantics:
|
|
11
|
+
* - `capability` — keep robots whose per-robot allowlist
|
|
12
|
+
* (`config.robots[i].capabilities`) includes the verb, OR (when no
|
|
13
|
+
* allowlist is set) whose gateway's global capability registry
|
|
14
|
+
* includes it. The global path is the common case — every robot
|
|
15
|
+
* today exposes the same builtin + skill-declared capabilities. The
|
|
16
|
+
* per-robot allowlist exists for heterogeneous fleets where (e.g.)
|
|
17
|
+
* only one robot has the `arm_skill` loaded.
|
|
18
|
+
* - `kind` — exact match on `robot.kind` (case-insensitive). Use
|
|
19
|
+
* "amr" / "arm" / "drone" / "rover" by convention but any string is
|
|
20
|
+
* accepted by the schema.
|
|
21
|
+
* - `online` — `true` keeps only robots whose id is in `onlineIds`;
|
|
22
|
+
* `false` keeps only robots NOT in `onlineIds`; `undefined` skips
|
|
23
|
+
* this filter entirely. The adapter is responsible for populating
|
|
24
|
+
* `onlineIds` from the live topic graph (typically via
|
|
25
|
+
* `discoverRobots()`) before calling this — core doesn't touch the
|
|
26
|
+
* transport.
|
|
27
|
+
*
|
|
28
|
+
* Ranking (highest score first):
|
|
29
|
+
* +2 online (when query.online is true)
|
|
30
|
+
* +1 per-robot capabilities allowlist included the requested verb
|
|
31
|
+
* (an explicit "I support this" beats a global-registry inference)
|
|
32
|
+
* +0 default tier
|
|
33
|
+
*
|
|
34
|
+
* Ties broken by config declaration order (stable).
|
|
35
|
+
*
|
|
36
|
+
* Why not a full LLM-style scoring function? Phase 1.e's goal is
|
|
37
|
+
* deterministic and explainable — an agent calling `find_robots_for`
|
|
38
|
+
* wants a list it can plan against, not a relevance heuristic. The
|
|
39
|
+
* +1/+2 deltas are enough to surface a perfect match above an
|
|
40
|
+
* inherited one without inventing fuzzy matching.
|
|
41
|
+
*/
|
|
42
|
+
import type { AgenticROSConfig } from "./config.js";
|
|
43
|
+
import { type ResolvedRobot } from "./robots.js";
|
|
44
|
+
/** Query input to `findRobotsFor`. All fields optional → returns every robot. */
|
|
45
|
+
export interface FindRobotsForQuery {
|
|
46
|
+
/** Capability id (e.g. `follow_person`, `find_object`). Case-sensitive — match the registry. */
|
|
47
|
+
capability?: string;
|
|
48
|
+
/** Robot kind (e.g. `amr`, `arm`, `drone`). Case-insensitive. */
|
|
49
|
+
kind?: string;
|
|
50
|
+
/** When set, restrict to online (true) or offline (false) robots. */
|
|
51
|
+
online?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/** One entry in the find-robots-for result. */
|
|
54
|
+
export interface FindRobotsForMatch {
|
|
55
|
+
robot: ResolvedRobot;
|
|
56
|
+
/** True when the capability filter was satisfied by an explicit per-robot allowlist. */
|
|
57
|
+
matched_capability_explicitly: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* True when this robot is in the caller-supplied online set, false when
|
|
60
|
+
* not, and `null` when the caller didn't provide an online set at all
|
|
61
|
+
* (so we can't say either way).
|
|
62
|
+
*/
|
|
63
|
+
online: boolean | null;
|
|
64
|
+
/** Sort key — higher = better match. See module header for the formula. */
|
|
65
|
+
score: number;
|
|
66
|
+
}
|
|
67
|
+
/** Result envelope. */
|
|
68
|
+
export interface FindRobotsForResult {
|
|
69
|
+
query: FindRobotsForQuery;
|
|
70
|
+
total: number;
|
|
71
|
+
/** Best-matching robots first. */
|
|
72
|
+
robots: FindRobotsForMatch[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Run the filter+rank against the configured fleet.
|
|
76
|
+
*
|
|
77
|
+
* `onlineIds` is optional. When omitted AND `query.online` is set, this
|
|
78
|
+
* throws — the adapter MUST resolve the live set before calling this so
|
|
79
|
+
* the core stays transport-agnostic.
|
|
80
|
+
*
|
|
81
|
+
* The match list is stable across calls with the same input (no
|
|
82
|
+
* non-determinism, no time-of-day effects).
|
|
83
|
+
*/
|
|
84
|
+
export declare function findRobotsFor(config: AgenticROSConfig, query: FindRobotsForQuery, onlineIds?: ReadonlySet<string>): FindRobotsForResult;
|
|
85
|
+
//# sourceMappingURL=find-robots-for.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-robots-for.d.ts","sourceRoot":"","sources":["../src/find-robots-for.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7D,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,aAAa,CAAC;IACrB,wFAAwF;IACxF,6BAA6B,EAAE,OAAO,CAAC;IACvC;;;;OAIG;IACH,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;CACf;AAED,uBAAuB;AACvB,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,kBAAkB,EACzB,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAC9B,mBAAmB,CAsErB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `findRobotsFor` — Phase 1.e capability-aware robot filter.
|
|
3
|
+
*
|
|
4
|
+
* Given a (capability?, kind?, online?) query, returns the configured
|
|
5
|
+
* robots that match, ranked best-first. This is the resolver behind the
|
|
6
|
+
* `ros2_find_robots_for` MCP tool — adapters call it from `tools.ts`
|
|
7
|
+
* with the live online-set computed from a topic scan (or `undefined`
|
|
8
|
+
* when `online` isn't being filtered, so we don't pay for the scan).
|
|
9
|
+
*
|
|
10
|
+
* Filter semantics:
|
|
11
|
+
* - `capability` — keep robots whose per-robot allowlist
|
|
12
|
+
* (`config.robots[i].capabilities`) includes the verb, OR (when no
|
|
13
|
+
* allowlist is set) whose gateway's global capability registry
|
|
14
|
+
* includes it. The global path is the common case — every robot
|
|
15
|
+
* today exposes the same builtin + skill-declared capabilities. The
|
|
16
|
+
* per-robot allowlist exists for heterogeneous fleets where (e.g.)
|
|
17
|
+
* only one robot has the `arm_skill` loaded.
|
|
18
|
+
* - `kind` — exact match on `robot.kind` (case-insensitive). Use
|
|
19
|
+
* "amr" / "arm" / "drone" / "rover" by convention but any string is
|
|
20
|
+
* accepted by the schema.
|
|
21
|
+
* - `online` — `true` keeps only robots whose id is in `onlineIds`;
|
|
22
|
+
* `false` keeps only robots NOT in `onlineIds`; `undefined` skips
|
|
23
|
+
* this filter entirely. The adapter is responsible for populating
|
|
24
|
+
* `onlineIds` from the live topic graph (typically via
|
|
25
|
+
* `discoverRobots()`) before calling this — core doesn't touch the
|
|
26
|
+
* transport.
|
|
27
|
+
*
|
|
28
|
+
* Ranking (highest score first):
|
|
29
|
+
* +2 online (when query.online is true)
|
|
30
|
+
* +1 per-robot capabilities allowlist included the requested verb
|
|
31
|
+
* (an explicit "I support this" beats a global-registry inference)
|
|
32
|
+
* +0 default tier
|
|
33
|
+
*
|
|
34
|
+
* Ties broken by config declaration order (stable).
|
|
35
|
+
*
|
|
36
|
+
* Why not a full LLM-style scoring function? Phase 1.e's goal is
|
|
37
|
+
* deterministic and explainable — an agent calling `find_robots_for`
|
|
38
|
+
* wants a list it can plan against, not a relevance heuristic. The
|
|
39
|
+
* +1/+2 deltas are enough to surface a perfect match above an
|
|
40
|
+
* inherited one without inventing fuzzy matching.
|
|
41
|
+
*/
|
|
42
|
+
import { listAllCapabilities } from "./capabilities.js";
|
|
43
|
+
import { listRobots } from "./robots.js";
|
|
44
|
+
/**
|
|
45
|
+
* Run the filter+rank against the configured fleet.
|
|
46
|
+
*
|
|
47
|
+
* `onlineIds` is optional. When omitted AND `query.online` is set, this
|
|
48
|
+
* throws — the adapter MUST resolve the live set before calling this so
|
|
49
|
+
* the core stays transport-agnostic.
|
|
50
|
+
*
|
|
51
|
+
* The match list is stable across calls with the same input (no
|
|
52
|
+
* non-determinism, no time-of-day effects).
|
|
53
|
+
*/
|
|
54
|
+
export function findRobotsFor(config, query, onlineIds) {
|
|
55
|
+
if (query.online !== undefined && onlineIds === undefined) {
|
|
56
|
+
throw new Error("findRobotsFor: query.online was set but onlineIds was not provided. " +
|
|
57
|
+
"Call discoverRobots() first and pass configured_online ids.");
|
|
58
|
+
}
|
|
59
|
+
// Resolve the global capability registry once — used as the fallback
|
|
60
|
+
// when a robot doesn't declare its own per-robot allowlist.
|
|
61
|
+
const globalCapIds = new Set(listAllCapabilities(config).map((c) => c.id));
|
|
62
|
+
const wantedKind = query.kind?.trim().toLowerCase();
|
|
63
|
+
const wantedCap = query.capability?.trim();
|
|
64
|
+
const fleet = listRobots(config);
|
|
65
|
+
const matches = [];
|
|
66
|
+
for (const robot of fleet) {
|
|
67
|
+
// kind filter
|
|
68
|
+
if (wantedKind && robot.kind.toLowerCase() !== wantedKind)
|
|
69
|
+
continue;
|
|
70
|
+
// capability filter
|
|
71
|
+
let matchedExplicitly = false;
|
|
72
|
+
if (wantedCap) {
|
|
73
|
+
const allowlist = robot.capabilities;
|
|
74
|
+
if (allowlist) {
|
|
75
|
+
if (!allowlist.includes(wantedCap))
|
|
76
|
+
continue;
|
|
77
|
+
matchedExplicitly = true;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// No per-robot allowlist → fall back to the gateway-wide
|
|
81
|
+
// registry. This is the common case today.
|
|
82
|
+
if (!globalCapIds.has(wantedCap))
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// online filter
|
|
87
|
+
let isOnline = null;
|
|
88
|
+
if (onlineIds) {
|
|
89
|
+
isOnline = onlineIds.has(robot.id);
|
|
90
|
+
if (query.online === true && !isOnline)
|
|
91
|
+
continue;
|
|
92
|
+
if (query.online === false && isOnline)
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
let score = 0;
|
|
96
|
+
if (matchedExplicitly)
|
|
97
|
+
score += 1;
|
|
98
|
+
if (query.online === true && isOnline)
|
|
99
|
+
score += 2;
|
|
100
|
+
// Reward online robots even when the user didn't filter for it —
|
|
101
|
+
// an agent picking a robot for an action almost always wants the
|
|
102
|
+
// one currently reachable.
|
|
103
|
+
if (query.online === undefined && isOnline === true)
|
|
104
|
+
score += 1;
|
|
105
|
+
matches.push({ robot, matched_capability_explicitly: matchedExplicitly, online: isOnline, score });
|
|
106
|
+
}
|
|
107
|
+
// Stable sort: higher score first, tie-broken by original config
|
|
108
|
+
// order (which is what listRobots() returned).
|
|
109
|
+
matches.sort((a, b) => b.score - a.score);
|
|
110
|
+
return {
|
|
111
|
+
query: {
|
|
112
|
+
...(wantedCap ? { capability: wantedCap } : {}),
|
|
113
|
+
...(wantedKind ? { kind: wantedKind } : {}),
|
|
114
|
+
...(query.online !== undefined ? { online: query.online } : {}),
|
|
115
|
+
},
|
|
116
|
+
total: matches.length,
|
|
117
|
+
robots: matches,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=find-robots-for.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-robots-for.js","sourceRoot":"","sources":["../src/find-robots-for.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAGH,OAAO,EAAE,mBAAmB,EAAmB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,UAAU,EAAsB,MAAM,aAAa,CAAC;AAmC7D;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAwB,EACxB,KAAyB,EACzB,SAA+B;IAE/B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,sEAAsE;YACpE,6DAA6D,CAChE,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,4DAA4D;IAC5D,MAAM,YAAY,GAAwB,IAAI,GAAG,CAC/C,mBAAmB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAa,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACzD,CAAC;IAEF,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACpD,MAAM,SAAS,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;IAE3C,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,OAAO,GAAyB,EAAE,CAAC;IAEzC,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,cAAc;QACd,IAAI,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,UAAU;YAAE,SAAS;QAEpE,oBAAoB;QACpB,IAAI,iBAAiB,GAAG,KAAK,CAAC;QAC9B,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC;YACrC,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;oBAAE,SAAS;gBAC7C,iBAAiB,GAAG,IAAI,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,yDAAyD;gBACzD,2CAA2C;gBAC3C,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC;oBAAE,SAAS;YAC7C,CAAC;QACH,CAAC;QAED,gBAAgB;QAChB,IAAI,QAAQ,GAAmB,IAAI,CAAC;QACpC,IAAI,SAAS,EAAE,CAAC;YACd,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACnC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACjD,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,IAAI,QAAQ;gBAAE,SAAS;QACnD,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,iBAAiB;YAAE,KAAK,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,QAAQ;YAAE,KAAK,IAAI,CAAC,CAAC;QAClD,iEAAiE;QACjE,iEAAiE;QACjE,2BAA2B;QAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI;YAAE,KAAK,IAAI,CAAC,CAAC;QAEhE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACrG,CAAC;IAED,iEAAiE;IACjE,+CAA+C;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE1C,OAAO;QACL,KAAK,EAAE;YACL,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE;QACD,KAAK,EAAE,OAAO,CAAC,MAAM;QACrB,MAAM,EAAE,OAAO;KAChB,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agenticros/core — Platform-agnostic ROS2 transport, config, and utilities.
|
|
3
|
+
*/
|
|
4
|
+
export type { AgenticROSConfig, RobotTransportOverride } from "./config.js";
|
|
5
|
+
export { AgenticROSConfigSchema, parseConfig, getTransportConfig, } from "./config.js";
|
|
6
|
+
export { createTransport } from "./transport/factory.js";
|
|
7
|
+
export type { RosTransport } from "./transport/transport.js";
|
|
8
|
+
export type { ConnectionStatus, ConnectionHandler, Subscription, PublishOptions, AdvertiseOptions, SubscribeOptions, ServiceCallOptions, ServiceCallResult, ActionGoalOptions, ActionResult, TopicInfo, ServiceInfo, ActionInfo, MessageHandler, TransportConfig, } from "./transport/types.js";
|
|
9
|
+
export { toNamespacedTopic, toNamespacedTopicFull, toTeleopCameraTopicShort, resolveCameraSubscribeTopic, } from "./topic-utils.js";
|
|
10
|
+
export { applyCmdVelTwistSignConvention } from "./cmd-vel-twist.js";
|
|
11
|
+
export { isCdrTypeSupported } from "./transport/zenoh/cdr.js";
|
|
12
|
+
export { renderAgenticROSBanner, agenticROSBannerLines, type AgenticROSBannerOptions, } from "./banner.js";
|
|
13
|
+
export { createMemory, resolveMemoryNamespace } from "./memory/index.js";
|
|
14
|
+
export type { MemoryProvider, MemoryRecord, MemoryStatus, RememberInput, RecallInput, ForgetInput, } from "./memory/index.js";
|
|
15
|
+
export { BUILTIN_CAPABILITIES, readSkillCapabilities, listAllCapabilities, } from "./capabilities.js";
|
|
16
|
+
export type { Capability, CapabilityField, CapabilityImplementation, CapabilitySource, } from "./capabilities.js";
|
|
17
|
+
export { runMission } from "./mission.js";
|
|
18
|
+
export type { Mission, MissionStep, MissionResult, MissionStepResult, MissionToolDispatcher, CapabilityToolBinding, CapabilityToolBindings, MissionCancellationToken, MissionTranscriptEntry, MissionTranscriptSink, RunMissionOptions, } from "./mission.js";
|
|
19
|
+
export { MissionRegistry, generateMissionId, missionTranscriptNamespace, } from "./mission-registry.js";
|
|
20
|
+
export type { MissionRegistryEntry } from "./mission-registry.js";
|
|
21
|
+
export { createMemoryTranscriptSink } from "./mission-transcript-sink.js";
|
|
22
|
+
export { compileGoalToMission } from "./planner/index.js";
|
|
23
|
+
export type { PlannerResult, PlannerCandidate } from "./planner/index.js";
|
|
24
|
+
export { listRobots, resolveRobot, resolveRobotFromArgs, getActiveRobotId, getTransportConfigForRobot, hasRobotTransportOverride, } from "./robots.js";
|
|
25
|
+
export type { ResolvedRobot, RobotSensors } from "./robots.js";
|
|
26
|
+
export { detectRobotsFromTopics, discoverRobots, effectiveCmdVelNamespace, } from "./discovery.js";
|
|
27
|
+
export type { DetectedRobot, RobotDiscoveryResult } from "./discovery.js";
|
|
28
|
+
export { findRobotsFor } from "./find-robots-for.js";
|
|
29
|
+
export type { FindRobotsForQuery, FindRobotsForMatch, FindRobotsForResult, } from "./find-robots-for.js";
|
|
30
|
+
export { TransportPool, TRANSPORT_POOL_GLOBAL_KEY } from "./transport-pool.js";
|
|
31
|
+
export type { TransportFactory } from "./transport-pool.js";
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EACL,sBAAsB,EACtB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,WAAW,EACX,UAAU,EACV,cAAc,EACd,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACzE,YAAY,EACV,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,UAAU,EACV,eAAe,EACf,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EACV,OAAO,EACP,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE1E,OAAO,EACL,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @agenticros/core — Platform-agnostic ROS2 transport, config, and utilities.
|
|
3
|
+
*/
|
|
4
|
+
export { AgenticROSConfigSchema, parseConfig, getTransportConfig, } from "./config.js";
|
|
5
|
+
export { createTransport } from "./transport/factory.js";
|
|
6
|
+
export { toNamespacedTopic, toNamespacedTopicFull, toTeleopCameraTopicShort, resolveCameraSubscribeTopic, } from "./topic-utils.js";
|
|
7
|
+
export { applyCmdVelTwistSignConvention } from "./cmd-vel-twist.js";
|
|
8
|
+
export { isCdrTypeSupported } from "./transport/zenoh/cdr.js";
|
|
9
|
+
export { renderAgenticROSBanner, agenticROSBannerLines, } from "./banner.js";
|
|
10
|
+
export { createMemory, resolveMemoryNamespace } from "./memory/index.js";
|
|
11
|
+
export { BUILTIN_CAPABILITIES, readSkillCapabilities, listAllCapabilities, } from "./capabilities.js";
|
|
12
|
+
export { runMission } from "./mission.js";
|
|
13
|
+
export { MissionRegistry, generateMissionId, missionTranscriptNamespace, } from "./mission-registry.js";
|
|
14
|
+
export { createMemoryTranscriptSink } from "./mission-transcript-sink.js";
|
|
15
|
+
export { compileGoalToMission } from "./planner/index.js";
|
|
16
|
+
export { listRobots, resolveRobot, resolveRobotFromArgs, getActiveRobotId, getTransportConfigForRobot, hasRobotTransportOverride, } from "./robots.js";
|
|
17
|
+
export { detectRobotsFromTopics, discoverRobots, effectiveCmdVelNamespace, } from "./discovery.js";
|
|
18
|
+
export { findRobotsFor } from "./find-robots-for.js";
|
|
19
|
+
export { TransportPool, TRANSPORT_POOL_GLOBAL_KEY } from "./transport-pool.js";
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,sBAAsB,EACtB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAoBzD,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GAEtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAUzE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAe1C,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EACL,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAOrD,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgenticROSConfig } from "../config.js";
|
|
2
|
+
import type { MemoryProvider } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Build a MemoryProvider from full config.
|
|
5
|
+
*
|
|
6
|
+
* Returns `null` when memory is disabled (`config.memory.enabled === false`),
|
|
7
|
+
* so adapters can short-circuit registering memory tools.
|
|
8
|
+
*
|
|
9
|
+
* The mem0 backend is loaded via dynamic import — `mem0ai` is an optional peer
|
|
10
|
+
* dependency. Users on `backend: "local"` never load it.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createMemory(config: AgenticROSConfig): Promise<MemoryProvider | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve the effective namespace used by memory tools.
|
|
15
|
+
* Argument > config.memory.namespace > config.robot.namespace.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveMemoryNamespace(config: AgenticROSConfig, argNamespace?: string): string;
|
|
18
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/memory/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA8BhC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,gBAAgB,EACxB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CASR"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a MemoryProvider from full config.
|
|
3
|
+
*
|
|
4
|
+
* Returns `null` when memory is disabled (`config.memory.enabled === false`),
|
|
5
|
+
* so adapters can short-circuit registering memory tools.
|
|
6
|
+
*
|
|
7
|
+
* The mem0 backend is loaded via dynamic import — `mem0ai` is an optional peer
|
|
8
|
+
* dependency. Users on `backend: "local"` never load it.
|
|
9
|
+
*/
|
|
10
|
+
export async function createMemory(config) {
|
|
11
|
+
if (!config.memory?.enabled)
|
|
12
|
+
return null;
|
|
13
|
+
const backend = config.memory.backend;
|
|
14
|
+
switch (backend) {
|
|
15
|
+
case "local": {
|
|
16
|
+
const { LocalMemoryProvider } = await import("./local/provider.js");
|
|
17
|
+
return new LocalMemoryProvider({
|
|
18
|
+
storePath: config.memory.local.storePath,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
case "mem0": {
|
|
22
|
+
const { createMem0Provider } = await import("./mem0/provider.js");
|
|
23
|
+
return await createMem0Provider({
|
|
24
|
+
config: {
|
|
25
|
+
inferOnWrite: config.memory.mem0.inferOnWrite,
|
|
26
|
+
historyDbPath: config.memory.mem0.historyDbPath,
|
|
27
|
+
embedder: config.memory.mem0.embedder,
|
|
28
|
+
vectorStore: config.memory.mem0.vectorStore,
|
|
29
|
+
llm: config.memory.mem0.llm,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
default: {
|
|
34
|
+
const _exhaustive = backend;
|
|
35
|
+
throw new Error(`Unknown memory backend: ${String(_exhaustive)}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the effective namespace used by memory tools.
|
|
41
|
+
* Argument > config.memory.namespace > config.robot.namespace.
|
|
42
|
+
*/
|
|
43
|
+
export function resolveMemoryNamespace(config, argNamespace) {
|
|
44
|
+
return ((argNamespace && argNamespace.trim().length > 0 ? argNamespace : undefined) ??
|
|
45
|
+
(config.memory?.namespace && config.memory.namespace.trim().length > 0
|
|
46
|
+
? config.memory.namespace
|
|
47
|
+
: undefined) ??
|
|
48
|
+
config.robot?.namespace ??
|
|
49
|
+
"");
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/memory/factory.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAwB;IAExB,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IACtC,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,EAAE,mBAAmB,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;YACpE,OAAO,IAAI,mBAAmB,CAAC;gBAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS;aACzC,CAAC,CAAC;QACL,CAAC;QAED,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAClE,OAAO,MAAM,kBAAkB,CAAC;gBAC9B,MAAM,EAAE;oBACN,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY;oBAC7C,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa;oBAC/C,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ;oBACrC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW;oBAC3C,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG;iBAC5B;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,WAAW,GAAU,OAAO,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAwB,EACxB,YAAqB;IAErB,OAAO,CACL,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3E,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YACpE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS;YACzB,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,CAAC,KAAK,EAAE,SAAS;QACvB,EAAE,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ForgetInput, MemoryProvider, MemoryRecord, MemoryStatus, RecallInput, RememberInput } from "../types.js";
|
|
2
|
+
interface LocalConfig {
|
|
3
|
+
storePath: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Tiny JSON-on-disk memory backend. No new deps.
|
|
7
|
+
*
|
|
8
|
+
* Recall ranks by token-overlap score (tf-style) with a small recency bonus
|
|
9
|
+
* so two equally-relevant memories are returned newest-first. This is
|
|
10
|
+
* intentionally dumb — users who want true semantic search opt into mem0.
|
|
11
|
+
*/
|
|
12
|
+
export declare class LocalMemoryProvider implements MemoryProvider {
|
|
13
|
+
readonly backend: "local";
|
|
14
|
+
private readonly storePath;
|
|
15
|
+
private records;
|
|
16
|
+
private writeChain;
|
|
17
|
+
constructor(config: LocalConfig);
|
|
18
|
+
remember(input: RememberInput): Promise<MemoryRecord>;
|
|
19
|
+
recall(input: RecallInput): Promise<MemoryRecord[]>;
|
|
20
|
+
forget(input: ForgetInput): Promise<{
|
|
21
|
+
removed: number;
|
|
22
|
+
}>;
|
|
23
|
+
status(namespace: string): Promise<MemoryStatus>;
|
|
24
|
+
recent(namespace: string, limit?: number): Promise<MemoryRecord[]>;
|
|
25
|
+
private load;
|
|
26
|
+
private persist;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/memory/local/provider.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,EACd,MAAM,aAAa,CAAC;AAErB,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAOD;;;;;;GAMG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IACxD,QAAQ,CAAC,OAAO,EAAG,OAAO,CAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,UAAU,CAAoC;gBAE1C,MAAM,EAAE,WAAW;IAIzB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAgBrD,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAyBnD,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IA6BxD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAgBhD,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;YAUrD,IAAI;YAyBJ,OAAO;CAatB"}
|