@memtensor/memos-local-openclaw-plugin 1.0.4-beta.6 → 1.0.4-beta.7
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 +39 -22
- package/dist/capture/index.d.ts +1 -1
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +27 -7
- package/dist/capture/index.js.map +1 -1
- package/dist/client/connector.d.ts +29 -0
- package/dist/client/connector.d.ts.map +1 -0
- package/dist/client/connector.js +218 -0
- package/dist/client/connector.js.map +1 -0
- package/dist/client/hub.d.ts +61 -0
- package/dist/client/hub.d.ts.map +1 -0
- package/dist/client/hub.js +170 -0
- package/dist/client/hub.js.map +1 -0
- package/dist/client/skill-sync.d.ts +36 -0
- package/dist/client/skill-sync.d.ts.map +1 -0
- package/dist/client/skill-sync.js +226 -0
- package/dist/client/skill-sync.js.map +1 -0
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +72 -3
- package/dist/config.js.map +1 -1
- package/dist/embedding/index.d.ts +4 -2
- package/dist/embedding/index.d.ts.map +1 -1
- package/dist/embedding/index.js +17 -1
- package/dist/embedding/index.js.map +1 -1
- package/dist/hub/auth.d.ts +19 -0
- package/dist/hub/auth.d.ts.map +1 -0
- package/dist/hub/auth.js +70 -0
- package/dist/hub/auth.js.map +1 -0
- package/dist/hub/server.d.ts +41 -0
- package/dist/hub/server.d.ts.map +1 -0
- package/dist/hub/server.js +767 -0
- package/dist/hub/server.js.map +1 -0
- package/dist/hub/user-manager.d.ts +31 -0
- package/dist/hub/user-manager.d.ts.map +1 -0
- package/dist/hub/user-manager.js +129 -0
- package/dist/hub/user-manager.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/dist/ingest/providers/index.d.ts +10 -2
- package/dist/ingest/providers/index.d.ts.map +1 -1
- package/dist/ingest/providers/index.js +209 -43
- package/dist/ingest/providers/index.js.map +1 -1
- package/dist/ingest/providers/openai.d.ts +1 -0
- package/dist/ingest/providers/openai.d.ts.map +1 -1
- package/dist/ingest/providers/openai.js +1 -0
- package/dist/ingest/providers/openai.js.map +1 -1
- package/dist/ingest/task-processor.js +1 -1
- package/dist/ingest/task-processor.js.map +1 -1
- package/dist/openclaw-api.d.ts +53 -0
- package/dist/openclaw-api.d.ts.map +1 -0
- package/dist/openclaw-api.js +189 -0
- package/dist/openclaw-api.js.map +1 -0
- package/dist/recall/engine.js +1 -1
- package/dist/recall/engine.js.map +1 -1
- package/dist/shared/llm-call.d.ts +4 -2
- package/dist/shared/llm-call.d.ts.map +1 -1
- package/dist/shared/llm-call.js +20 -81
- package/dist/shared/llm-call.js.map +1 -1
- package/dist/sharing/types.contract.d.ts +2 -0
- package/dist/sharing/types.contract.d.ts.map +1 -0
- package/dist/sharing/types.contract.js +3 -0
- package/dist/sharing/types.contract.js.map +1 -0
- package/dist/sharing/types.d.ts +80 -0
- package/dist/sharing/types.d.ts.map +1 -0
- package/dist/sharing/types.js +3 -0
- package/dist/sharing/types.js.map +1 -0
- package/dist/skill/evaluator.d.ts.map +1 -1
- package/dist/skill/evaluator.js +2 -2
- package/dist/skill/evaluator.js.map +1 -1
- package/dist/skill/evolver.d.ts +0 -2
- package/dist/skill/evolver.d.ts.map +1 -1
- package/dist/skill/evolver.js +0 -3
- package/dist/skill/evolver.js.map +1 -1
- package/dist/skill/generator.d.ts.map +1 -1
- package/dist/skill/generator.js +4 -4
- package/dist/skill/generator.js.map +1 -1
- package/dist/skill/upgrader.js +1 -1
- package/dist/skill/upgrader.js.map +1 -1
- package/dist/skill/validator.js +1 -1
- package/dist/skill/validator.js.map +1 -1
- package/dist/storage/ensure-binding.d.ts.map +1 -1
- package/dist/storage/ensure-binding.js +3 -1
- package/dist/storage/ensure-binding.js.map +1 -1
- package/dist/storage/sqlite.d.ts +329 -1
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +909 -4
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/telemetry.d.ts +5 -12
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +38 -135
- package/dist/telemetry.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/memory-search.d.ts +5 -2
- package/dist/tools/memory-search.d.ts.map +1 -1
- package/dist/tools/memory-search.js +50 -7
- package/dist/tools/memory-search.js.map +1 -1
- package/dist/tools/network-memory-detail.d.ts +4 -0
- package/dist/tools/network-memory-detail.d.ts.map +1 -0
- package/dist/tools/network-memory-detail.js +34 -0
- package/dist/tools/network-memory-detail.js.map +1 -0
- package/dist/types.d.ts +49 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/viewer/html.d.ts.map +1 -1
- package/dist/viewer/html.js +3965 -459
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +51 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +1564 -23
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +769 -67
- package/openclaw.plugin.json +2 -1
- package/package.json +4 -3
- package/scripts/postinstall.cjs +283 -46
- package/skill/memos-memory-guide/SKILL.md +82 -20
- package/src/capture/index.ts +27 -7
- package/src/client/connector.ts +212 -0
- package/src/client/hub.ts +207 -0
- package/src/client/skill-sync.ts +216 -0
- package/src/config.ts +94 -3
- package/src/embedding/index.ts +21 -1
- package/src/hub/auth.ts +78 -0
- package/src/hub/server.ts +754 -0
- package/src/hub/user-manager.ts +143 -0
- package/src/index.ts +13 -5
- package/src/ingest/providers/index.ts +246 -46
- package/src/ingest/providers/openai.ts +1 -1
- package/src/ingest/task-processor.ts +1 -1
- package/src/openclaw-api.ts +287 -0
- package/src/recall/engine.ts +1 -1
- package/src/shared/llm-call.ts +23 -95
- package/src/sharing/types.contract.ts +40 -0
- package/src/sharing/types.ts +102 -0
- package/src/skill/evaluator.ts +3 -2
- package/src/skill/evolver.ts +0 -5
- package/src/skill/generator.ts +6 -4
- package/src/skill/upgrader.ts +1 -1
- package/src/skill/validator.ts +1 -1
- package/src/storage/ensure-binding.ts +3 -1
- package/src/storage/sqlite.ts +1159 -4
- package/src/telemetry.ts +39 -152
- package/src/tools/index.ts +1 -0
- package/src/tools/memory-search.ts +58 -8
- package/src/tools/network-memory-detail.ts +34 -0
- package/src/types.ts +44 -2
- package/src/viewer/html.ts +3965 -459
- package/src/viewer/server.ts +1452 -25
package/src/telemetry.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Telemetry module — anonymous usage analytics via
|
|
2
|
+
* Telemetry module — anonymous usage analytics via PostHog.
|
|
3
3
|
*
|
|
4
4
|
* Privacy-first design:
|
|
5
5
|
* - Enabled by default with anonymous data only; opt-out via TELEMETRY_ENABLED=false
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - Only sends aggregate counts, tool names, latencies, and version info
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { PostHog } from "posthog-node";
|
|
11
12
|
import * as fs from "fs";
|
|
12
13
|
import * as path from "path";
|
|
13
14
|
import * as os from "os";
|
|
@@ -16,61 +17,45 @@ import type { Logger } from "./types";
|
|
|
16
17
|
|
|
17
18
|
export interface TelemetryConfig {
|
|
18
19
|
enabled?: boolean;
|
|
20
|
+
posthogApiKey?: string;
|
|
21
|
+
posthogHost?: string;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
"/rum/web/v2" +
|
|
24
|
-
"?workspace=default-cms-1026429231103299-cn-hangzhou" +
|
|
25
|
-
"&service_id=a3u72ukxmr@066657d42a13a9a9f337f";
|
|
26
|
-
|
|
27
|
-
const ARMS_PID = "a3u72ukxmr@066657d42a13a9a9f337f";
|
|
28
|
-
const ARMS_ENV = "prod";
|
|
29
|
-
|
|
30
|
-
const FLUSH_AT = 10;
|
|
31
|
-
const FLUSH_INTERVAL_MS = 30_000;
|
|
32
|
-
const SEND_TIMEOUT_MS = 30_000;
|
|
33
|
-
const SESSION_TTL_MS = 30 * 60_000; // 30 min inactivity → new session
|
|
34
|
-
interface ArmsEvent {
|
|
35
|
-
event_type: "custom";
|
|
36
|
-
type: string;
|
|
37
|
-
name: string;
|
|
38
|
-
group: string;
|
|
39
|
-
value: number;
|
|
40
|
-
properties: Record<string, string | number | boolean>;
|
|
41
|
-
timestamp: number;
|
|
42
|
-
event_id: string;
|
|
43
|
-
times: number;
|
|
44
|
-
}
|
|
24
|
+
const DEFAULT_POSTHOG_API_KEY = "phc_7lae6UC5jyImDefX6uub7zCxWyswCGNoBifCKqjvDrI";
|
|
25
|
+
const DEFAULT_POSTHOG_HOST = "https://eu.i.posthog.com";
|
|
45
26
|
|
|
46
27
|
export class Telemetry {
|
|
28
|
+
private client: PostHog | null = null;
|
|
47
29
|
private distinctId: string;
|
|
48
30
|
private enabled: boolean;
|
|
49
31
|
private pluginVersion: string;
|
|
50
32
|
private log: Logger;
|
|
51
33
|
private dailyPingSent = false;
|
|
52
34
|
private dailyPingDate = "";
|
|
53
|
-
private buffer: ArmsEvent[] = [];
|
|
54
|
-
private flushTimer: ReturnType<typeof setInterval> | null = null;
|
|
55
|
-
private sessionId: string;
|
|
56
|
-
private firstSeenDate: string;
|
|
57
35
|
|
|
58
36
|
constructor(config: TelemetryConfig, stateDir: string, pluginVersion: string, log: Logger) {
|
|
59
37
|
this.log = log;
|
|
60
38
|
this.pluginVersion = pluginVersion;
|
|
61
39
|
this.enabled = config.enabled !== false;
|
|
62
40
|
this.distinctId = this.loadOrCreateAnonymousId(stateDir);
|
|
63
|
-
this.firstSeenDate = this.loadOrCreateFirstSeen(stateDir);
|
|
64
|
-
this.sessionId = this.loadOrCreateSessionId(stateDir);
|
|
65
41
|
|
|
66
42
|
if (!this.enabled) {
|
|
67
43
|
this.log.debug("Telemetry disabled (opt-out via TELEMETRY_ENABLED=false)");
|
|
68
44
|
return;
|
|
69
45
|
}
|
|
70
46
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
47
|
+
const apiKey = config.posthogApiKey || DEFAULT_POSTHOG_API_KEY;
|
|
48
|
+
try {
|
|
49
|
+
this.client = new PostHog(apiKey, {
|
|
50
|
+
host: config.posthogHost || DEFAULT_POSTHOG_HOST,
|
|
51
|
+
flushAt: 10,
|
|
52
|
+
flushInterval: 30_000,
|
|
53
|
+
});
|
|
54
|
+
this.log.debug("Telemetry initialized (PostHog)");
|
|
55
|
+
} catch (err) {
|
|
56
|
+
this.log.warn(`Telemetry init failed: ${err}`);
|
|
57
|
+
this.enabled = false;
|
|
58
|
+
}
|
|
74
59
|
}
|
|
75
60
|
|
|
76
61
|
private loadOrCreateAnonymousId(stateDir: string): string {
|
|
@@ -96,113 +81,24 @@ export class Telemetry {
|
|
|
96
81
|
return newId;
|
|
97
82
|
}
|
|
98
83
|
|
|
99
|
-
private loadOrCreateSessionId(stateDir: string): string {
|
|
100
|
-
const filePath = path.join(stateDir, "memos-local", ".session");
|
|
101
|
-
try {
|
|
102
|
-
const raw = fs.readFileSync(filePath, "utf-8").trim();
|
|
103
|
-
const sep = raw.indexOf("|");
|
|
104
|
-
if (sep > 0) {
|
|
105
|
-
const ts = parseInt(raw.slice(0, sep), 10);
|
|
106
|
-
const id = raw.slice(sep + 1);
|
|
107
|
-
if (id.length > 10 && Date.now() - ts < SESSION_TTL_MS) {
|
|
108
|
-
this.touchSession(filePath, id);
|
|
109
|
-
return id;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
} catch {}
|
|
113
|
-
const newId = uuidv4();
|
|
114
|
-
this.touchSession(filePath, newId);
|
|
115
|
-
return newId;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private touchSession(filePath: string, id: string): void {
|
|
119
|
-
try {
|
|
120
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
121
|
-
fs.writeFileSync(filePath, `${Date.now()}|${id}`, "utf-8");
|
|
122
|
-
} catch {}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
private loadOrCreateFirstSeen(stateDir: string): string {
|
|
126
|
-
const filePath = path.join(stateDir, "memos-local", ".first-seen");
|
|
127
|
-
try {
|
|
128
|
-
const existing = fs.readFileSync(filePath, "utf-8").trim();
|
|
129
|
-
if (existing.length === 10) return existing;
|
|
130
|
-
} catch {}
|
|
131
|
-
const today = new Date().toISOString().slice(0, 10);
|
|
132
|
-
try {
|
|
133
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
134
|
-
fs.writeFileSync(filePath, today, "utf-8");
|
|
135
|
-
} catch {}
|
|
136
|
-
return today;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
84
|
private capture(event: string, properties?: Record<string, unknown>): void {
|
|
140
|
-
if (!this.enabled) return;
|
|
141
|
-
|
|
142
|
-
const safeProps: Record<string, string | number | boolean> = {
|
|
143
|
-
plugin_version: this.pluginVersion,
|
|
144
|
-
os: os.platform(),
|
|
145
|
-
os_version: os.release(),
|
|
146
|
-
node_version: process.version,
|
|
147
|
-
arch: os.arch(),
|
|
148
|
-
};
|
|
149
|
-
if (properties) {
|
|
150
|
-
for (const [k, v] of Object.entries(properties)) {
|
|
151
|
-
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
|
|
152
|
-
safeProps[k] = v;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
this.buffer.push({
|
|
158
|
-
event_type: "custom",
|
|
159
|
-
type: "memos_plugin",
|
|
160
|
-
name: event,
|
|
161
|
-
group: "memos_local",
|
|
162
|
-
value: 1,
|
|
163
|
-
properties: safeProps,
|
|
164
|
-
timestamp: Date.now(),
|
|
165
|
-
event_id: uuidv4(),
|
|
166
|
-
times: 1,
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
if (this.buffer.length >= FLUSH_AT) {
|
|
170
|
-
this.flush();
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
private buildPayload(events: ArmsEvent[]): Record<string, unknown> {
|
|
175
|
-
return {
|
|
176
|
-
app: {
|
|
177
|
-
id: ARMS_PID,
|
|
178
|
-
env: ARMS_ENV,
|
|
179
|
-
version: this.pluginVersion,
|
|
180
|
-
type: "node",
|
|
181
|
-
},
|
|
182
|
-
user: { id: this.distinctId },
|
|
183
|
-
session: { id: this.sessionId },
|
|
184
|
-
net: {},
|
|
185
|
-
view: { id: "plugin", name: "memos-local-openclaw" },
|
|
186
|
-
events,
|
|
187
|
-
_v: "1.0.0",
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
private async flush(): Promise<void> {
|
|
192
|
-
if (this.buffer.length === 0) return;
|
|
193
|
-
const batch = this.buffer.splice(0);
|
|
194
|
-
const payload = this.buildPayload(batch);
|
|
85
|
+
if (!this.enabled || !this.client) return;
|
|
195
86
|
|
|
196
87
|
try {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
88
|
+
this.client.capture({
|
|
89
|
+
distinctId: this.distinctId,
|
|
90
|
+
event,
|
|
91
|
+
properties: {
|
|
92
|
+
plugin_version: this.pluginVersion,
|
|
93
|
+
os: os.platform(),
|
|
94
|
+
os_version: os.release(),
|
|
95
|
+
node_version: process.version,
|
|
96
|
+
arch: os.arch(),
|
|
97
|
+
...properties,
|
|
98
|
+
},
|
|
202
99
|
});
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
this.log.debug(`Telemetry flush failed: ${err}`);
|
|
100
|
+
} catch {
|
|
101
|
+
// best-effort, never throw
|
|
206
102
|
}
|
|
207
103
|
}
|
|
208
104
|
|
|
@@ -235,7 +131,7 @@ export class Telemetry {
|
|
|
235
131
|
});
|
|
236
132
|
}
|
|
237
133
|
|
|
238
|
-
trackSkillEvolved(skillName: string, upgradeType:
|
|
134
|
+
trackSkillEvolved(skillName: string, upgradeType: string): void {
|
|
239
135
|
this.capture("skill_evolved", {
|
|
240
136
|
skill_name: skillName,
|
|
241
137
|
upgrade_type: upgradeType,
|
|
@@ -254,28 +150,19 @@ export class Telemetry {
|
|
|
254
150
|
});
|
|
255
151
|
}
|
|
256
152
|
|
|
257
|
-
trackError(source: string, errorType: string): void {
|
|
258
|
-
this.capture("plugin_error", {
|
|
259
|
-
error_source: source,
|
|
260
|
-
error_type: errorType,
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
|
|
264
153
|
private maybeSendDailyPing(): void {
|
|
265
154
|
const today = new Date().toISOString().slice(0, 10);
|
|
266
155
|
if (this.dailyPingSent && this.dailyPingDate === today) return;
|
|
267
156
|
this.dailyPingSent = true;
|
|
268
157
|
this.dailyPingDate = today;
|
|
269
|
-
this.capture("daily_active"
|
|
270
|
-
first_seen_date: this.firstSeenDate,
|
|
271
|
-
});
|
|
158
|
+
this.capture("daily_active");
|
|
272
159
|
}
|
|
273
160
|
|
|
274
161
|
async shutdown(): Promise<void> {
|
|
275
|
-
if (this.
|
|
276
|
-
|
|
277
|
-
|
|
162
|
+
if (this.client) {
|
|
163
|
+
try {
|
|
164
|
+
await this.client.shutdown();
|
|
165
|
+
} catch {}
|
|
278
166
|
}
|
|
279
|
-
await this.flush();
|
|
280
167
|
}
|
|
281
168
|
}
|
package/src/tools/index.ts
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
|
+
import { hubSearchMemories } from "../client/hub";
|
|
2
|
+
import type { HubScope, HubSearchResult } from "../sharing/types";
|
|
1
3
|
import type { RecallEngine } from "../recall/engine";
|
|
2
|
-
import type { ToolDefinition } from "../types";
|
|
4
|
+
import type { PluginContext, ToolDefinition } from "../types";
|
|
5
|
+
import type { SqliteStore } from "../storage/sqlite";
|
|
3
6
|
|
|
4
7
|
function resolveOwnerFilter(owner: unknown): string[] {
|
|
5
8
|
const resolvedOwner = typeof owner === "string" && owner.trim().length > 0 ? owner : "agent:main";
|
|
6
9
|
return resolvedOwner === "public" ? ["public"] : [resolvedOwner, "public"];
|
|
7
10
|
}
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
function resolveScope(scope: unknown): HubScope {
|
|
13
|
+
return scope === "group" || scope === "all" ? scope : "local";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function emptyHubResult(scope: HubScope): HubSearchResult {
|
|
17
|
+
return {
|
|
18
|
+
hits: [],
|
|
19
|
+
meta: {
|
|
20
|
+
totalCandidates: 0,
|
|
21
|
+
searchedGroups: [],
|
|
22
|
+
includedPublic: scope === "all",
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function createMemorySearchTool(engine: RecallEngine, store?: SqliteStore, ctx?: PluginContext, sharedState?: { lastSearchTime: number }): ToolDefinition {
|
|
10
28
|
return {
|
|
11
29
|
name: "memory_search",
|
|
12
30
|
description:
|
|
@@ -27,16 +45,48 @@ export function createMemorySearchTool(engine: RecallEngine): ToolDefinition {
|
|
|
27
45
|
type: "number",
|
|
28
46
|
description: "Minimum relevance score threshold 0-1 (default 0.45, floor 0.35).",
|
|
29
47
|
},
|
|
48
|
+
scope: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "Search scope: local (default), group, or all. Group/all return split local and hub sections.",
|
|
51
|
+
},
|
|
52
|
+
hubAddress: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "Optional hub address override for group/all search, integration tests, or manual routing.",
|
|
55
|
+
},
|
|
56
|
+
userToken: {
|
|
57
|
+
type: "string",
|
|
58
|
+
description: "Optional hub bearer token override for group/all search or integration tests.",
|
|
59
|
+
},
|
|
30
60
|
},
|
|
31
61
|
},
|
|
32
62
|
handler: async (input) => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
63
|
+
if (sharedState) sharedState.lastSearchTime = Date.now();
|
|
64
|
+
const query = (input.query as string) ?? "";
|
|
65
|
+
const maxResults = input.maxResults as number | undefined;
|
|
66
|
+
const minScore = input.minScore as number | undefined;
|
|
67
|
+
const ownerFilter = resolveOwnerFilter(input.owner);
|
|
68
|
+
const scope = resolveScope(input.scope);
|
|
69
|
+
|
|
70
|
+
const localSearch = engine.search({
|
|
71
|
+
query,
|
|
72
|
+
maxResults,
|
|
73
|
+
minScore,
|
|
74
|
+
ownerFilter,
|
|
38
75
|
});
|
|
39
|
-
|
|
76
|
+
|
|
77
|
+
if (scope === "local" || !store || !ctx) {
|
|
78
|
+
return localSearch;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const [local, hub] = await Promise.all([
|
|
82
|
+
localSearch,
|
|
83
|
+
hubSearchMemories(store, ctx, { query, maxResults, scope, hubAddress: input.hubAddress as string | undefined, userToken: input.userToken as string | undefined }).catch((err) => {
|
|
84
|
+
ctx.log.warn(`Hub search failed, using local-only results: ${err}`);
|
|
85
|
+
return emptyHubResult(scope);
|
|
86
|
+
}),
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
return { local, hub };
|
|
40
90
|
},
|
|
41
91
|
};
|
|
42
92
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { hubGetMemoryDetail } from "../client/hub";
|
|
2
|
+
import type { PluginContext, ToolDefinition } from "../types";
|
|
3
|
+
import type { SqliteStore } from "../storage/sqlite";
|
|
4
|
+
|
|
5
|
+
export function createNetworkMemoryDetailTool(store: SqliteStore, ctx: PluginContext): ToolDefinition {
|
|
6
|
+
return {
|
|
7
|
+
name: "network_memory_detail",
|
|
8
|
+
description:
|
|
9
|
+
"Fetch the full detail for one Hub search hit using its remoteHitId. Use this after memory_search(scope=group|all) when you need the full shared content.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
remoteHitId: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "The remoteHitId returned by memory_search hub results.",
|
|
16
|
+
},
|
|
17
|
+
hubAddress: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "Optional hub address override for integration tests or manual routing.",
|
|
20
|
+
},
|
|
21
|
+
userToken: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Optional hub bearer token override for integration tests.",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
required: ["remoteHitId"],
|
|
27
|
+
},
|
|
28
|
+
handler: async (input) => hubGetMemoryDetail(store, ctx, {
|
|
29
|
+
remoteHitId: String(input.remoteHitId ?? ""),
|
|
30
|
+
hubAddress: input.hubAddress as string | undefined,
|
|
31
|
+
userToken: input.userToken as string | undefined,
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -150,7 +150,8 @@ export type SummaryProvider =
|
|
|
150
150
|
| "bailian"
|
|
151
151
|
| "cohere"
|
|
152
152
|
| "mistral"
|
|
153
|
-
| "voyage"
|
|
153
|
+
| "voyage"
|
|
154
|
+
| "openclaw";
|
|
154
155
|
|
|
155
156
|
export type EmbeddingProvider =
|
|
156
157
|
| "openai"
|
|
@@ -160,7 +161,8 @@ export type EmbeddingProvider =
|
|
|
160
161
|
| "cohere"
|
|
161
162
|
| "mistral"
|
|
162
163
|
| "voyage"
|
|
163
|
-
| "local"
|
|
164
|
+
| "local"
|
|
165
|
+
| "openclaw";
|
|
164
166
|
|
|
165
167
|
export interface ProviderConfig {
|
|
166
168
|
provider: string;
|
|
@@ -170,6 +172,7 @@ export interface ProviderConfig {
|
|
|
170
172
|
headers?: Record<string, string>;
|
|
171
173
|
timeoutMs?: number;
|
|
172
174
|
temperature?: number;
|
|
175
|
+
capabilities?: SharingCapabilities;
|
|
173
176
|
}
|
|
174
177
|
|
|
175
178
|
export interface SummarizerConfig extends ProviderConfig {
|
|
@@ -246,11 +249,43 @@ export interface SkillEvolutionConfig {
|
|
|
246
249
|
minConfidence?: number;
|
|
247
250
|
maxSkillLines?: number;
|
|
248
251
|
autoInstall?: boolean;
|
|
252
|
+
/** Optional independent LLM config for skill evaluation/validation. Falls back to main summarizer if not set. */
|
|
249
253
|
summarizer?: SummarizerConfig;
|
|
250
254
|
}
|
|
251
255
|
|
|
252
256
|
export interface TelemetryConfig {
|
|
253
257
|
enabled?: boolean;
|
|
258
|
+
posthogApiKey?: string;
|
|
259
|
+
posthogHost?: string;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export type SharingRole = "hub" | "client";
|
|
263
|
+
|
|
264
|
+
export interface SharingCapabilities {
|
|
265
|
+
hostEmbedding?: boolean;
|
|
266
|
+
hostCompletion?: boolean;
|
|
267
|
+
hostSkill?: boolean;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface HubModeConfig {
|
|
271
|
+
port?: number;
|
|
272
|
+
teamName?: string;
|
|
273
|
+
teamToken?: string;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface ClientModeConfig {
|
|
277
|
+
hubAddress?: string;
|
|
278
|
+
userToken?: string;
|
|
279
|
+
teamToken?: string;
|
|
280
|
+
pendingUserId?: string;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export interface SharingConfig {
|
|
284
|
+
enabled?: boolean;
|
|
285
|
+
role?: SharingRole;
|
|
286
|
+
hub?: HubModeConfig;
|
|
287
|
+
client?: ClientModeConfig;
|
|
288
|
+
capabilities?: SharingCapabilities;
|
|
254
289
|
}
|
|
255
290
|
|
|
256
291
|
export interface MemosLocalConfig {
|
|
@@ -278,6 +313,7 @@ export interface MemosLocalConfig {
|
|
|
278
313
|
};
|
|
279
314
|
skillEvolution?: SkillEvolutionConfig;
|
|
280
315
|
telemetry?: TelemetryConfig;
|
|
316
|
+
sharing?: SharingConfig;
|
|
281
317
|
}
|
|
282
318
|
|
|
283
319
|
// ─── Defaults ───
|
|
@@ -318,6 +354,12 @@ export interface PluginContext {
|
|
|
318
354
|
workspaceDir: string;
|
|
319
355
|
config: MemosLocalConfig;
|
|
320
356
|
log: Logger;
|
|
357
|
+
openclawAPI?: OpenClawAPI;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export interface OpenClawAPI {
|
|
361
|
+
embed(request: { texts: string[]; model?: string }): Promise<{ embeddings: number[][]; dimensions: number }>;
|
|
362
|
+
complete(request: { prompt: string; maxTokens?: number; temperature?: number; model?: string }): Promise<{ text: string }>;
|
|
321
363
|
}
|
|
322
364
|
|
|
323
365
|
export interface Logger {
|