@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.
Files changed (153) hide show
  1. package/README.md +39 -22
  2. package/dist/capture/index.d.ts +1 -1
  3. package/dist/capture/index.d.ts.map +1 -1
  4. package/dist/capture/index.js +27 -7
  5. package/dist/capture/index.js.map +1 -1
  6. package/dist/client/connector.d.ts +29 -0
  7. package/dist/client/connector.d.ts.map +1 -0
  8. package/dist/client/connector.js +218 -0
  9. package/dist/client/connector.js.map +1 -0
  10. package/dist/client/hub.d.ts +61 -0
  11. package/dist/client/hub.d.ts.map +1 -0
  12. package/dist/client/hub.js +170 -0
  13. package/dist/client/hub.js.map +1 -0
  14. package/dist/client/skill-sync.d.ts +36 -0
  15. package/dist/client/skill-sync.d.ts.map +1 -0
  16. package/dist/client/skill-sync.js +226 -0
  17. package/dist/client/skill-sync.js.map +1 -0
  18. package/dist/config.d.ts +2 -1
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +72 -3
  21. package/dist/config.js.map +1 -1
  22. package/dist/embedding/index.d.ts +4 -2
  23. package/dist/embedding/index.d.ts.map +1 -1
  24. package/dist/embedding/index.js +17 -1
  25. package/dist/embedding/index.js.map +1 -1
  26. package/dist/hub/auth.d.ts +19 -0
  27. package/dist/hub/auth.d.ts.map +1 -0
  28. package/dist/hub/auth.js +70 -0
  29. package/dist/hub/auth.js.map +1 -0
  30. package/dist/hub/server.d.ts +41 -0
  31. package/dist/hub/server.d.ts.map +1 -0
  32. package/dist/hub/server.js +767 -0
  33. package/dist/hub/server.js.map +1 -0
  34. package/dist/hub/user-manager.d.ts +31 -0
  35. package/dist/hub/user-manager.d.ts.map +1 -0
  36. package/dist/hub/user-manager.js +129 -0
  37. package/dist/hub/user-manager.js.map +1 -0
  38. package/dist/index.d.ts +2 -0
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +8 -4
  41. package/dist/index.js.map +1 -1
  42. package/dist/ingest/providers/index.d.ts +10 -2
  43. package/dist/ingest/providers/index.d.ts.map +1 -1
  44. package/dist/ingest/providers/index.js +209 -43
  45. package/dist/ingest/providers/index.js.map +1 -1
  46. package/dist/ingest/providers/openai.d.ts +1 -0
  47. package/dist/ingest/providers/openai.d.ts.map +1 -1
  48. package/dist/ingest/providers/openai.js +1 -0
  49. package/dist/ingest/providers/openai.js.map +1 -1
  50. package/dist/ingest/task-processor.js +1 -1
  51. package/dist/ingest/task-processor.js.map +1 -1
  52. package/dist/openclaw-api.d.ts +53 -0
  53. package/dist/openclaw-api.d.ts.map +1 -0
  54. package/dist/openclaw-api.js +189 -0
  55. package/dist/openclaw-api.js.map +1 -0
  56. package/dist/recall/engine.js +1 -1
  57. package/dist/recall/engine.js.map +1 -1
  58. package/dist/shared/llm-call.d.ts +4 -2
  59. package/dist/shared/llm-call.d.ts.map +1 -1
  60. package/dist/shared/llm-call.js +20 -81
  61. package/dist/shared/llm-call.js.map +1 -1
  62. package/dist/sharing/types.contract.d.ts +2 -0
  63. package/dist/sharing/types.contract.d.ts.map +1 -0
  64. package/dist/sharing/types.contract.js +3 -0
  65. package/dist/sharing/types.contract.js.map +1 -0
  66. package/dist/sharing/types.d.ts +80 -0
  67. package/dist/sharing/types.d.ts.map +1 -0
  68. package/dist/sharing/types.js +3 -0
  69. package/dist/sharing/types.js.map +1 -0
  70. package/dist/skill/evaluator.d.ts.map +1 -1
  71. package/dist/skill/evaluator.js +2 -2
  72. package/dist/skill/evaluator.js.map +1 -1
  73. package/dist/skill/evolver.d.ts +0 -2
  74. package/dist/skill/evolver.d.ts.map +1 -1
  75. package/dist/skill/evolver.js +0 -3
  76. package/dist/skill/evolver.js.map +1 -1
  77. package/dist/skill/generator.d.ts.map +1 -1
  78. package/dist/skill/generator.js +4 -4
  79. package/dist/skill/generator.js.map +1 -1
  80. package/dist/skill/upgrader.js +1 -1
  81. package/dist/skill/upgrader.js.map +1 -1
  82. package/dist/skill/validator.js +1 -1
  83. package/dist/skill/validator.js.map +1 -1
  84. package/dist/storage/ensure-binding.d.ts.map +1 -1
  85. package/dist/storage/ensure-binding.js +3 -1
  86. package/dist/storage/ensure-binding.js.map +1 -1
  87. package/dist/storage/sqlite.d.ts +329 -1
  88. package/dist/storage/sqlite.d.ts.map +1 -1
  89. package/dist/storage/sqlite.js +909 -4
  90. package/dist/storage/sqlite.js.map +1 -1
  91. package/dist/telemetry.d.ts +5 -12
  92. package/dist/telemetry.d.ts.map +1 -1
  93. package/dist/telemetry.js +38 -135
  94. package/dist/telemetry.js.map +1 -1
  95. package/dist/tools/index.d.ts +1 -0
  96. package/dist/tools/index.d.ts.map +1 -1
  97. package/dist/tools/index.js +3 -1
  98. package/dist/tools/index.js.map +1 -1
  99. package/dist/tools/memory-search.d.ts +5 -2
  100. package/dist/tools/memory-search.d.ts.map +1 -1
  101. package/dist/tools/memory-search.js +50 -7
  102. package/dist/tools/memory-search.js.map +1 -1
  103. package/dist/tools/network-memory-detail.d.ts +4 -0
  104. package/dist/tools/network-memory-detail.d.ts.map +1 -0
  105. package/dist/tools/network-memory-detail.js +34 -0
  106. package/dist/tools/network-memory-detail.js.map +1 -0
  107. package/dist/types.d.ts +49 -2
  108. package/dist/types.d.ts.map +1 -1
  109. package/dist/types.js.map +1 -1
  110. package/dist/viewer/html.d.ts.map +1 -1
  111. package/dist/viewer/html.js +3965 -459
  112. package/dist/viewer/html.js.map +1 -1
  113. package/dist/viewer/server.d.ts +51 -0
  114. package/dist/viewer/server.d.ts.map +1 -1
  115. package/dist/viewer/server.js +1564 -23
  116. package/dist/viewer/server.js.map +1 -1
  117. package/index.ts +769 -67
  118. package/openclaw.plugin.json +2 -1
  119. package/package.json +4 -3
  120. package/scripts/postinstall.cjs +283 -46
  121. package/skill/memos-memory-guide/SKILL.md +82 -20
  122. package/src/capture/index.ts +27 -7
  123. package/src/client/connector.ts +212 -0
  124. package/src/client/hub.ts +207 -0
  125. package/src/client/skill-sync.ts +216 -0
  126. package/src/config.ts +94 -3
  127. package/src/embedding/index.ts +21 -1
  128. package/src/hub/auth.ts +78 -0
  129. package/src/hub/server.ts +754 -0
  130. package/src/hub/user-manager.ts +143 -0
  131. package/src/index.ts +13 -5
  132. package/src/ingest/providers/index.ts +246 -46
  133. package/src/ingest/providers/openai.ts +1 -1
  134. package/src/ingest/task-processor.ts +1 -1
  135. package/src/openclaw-api.ts +287 -0
  136. package/src/recall/engine.ts +1 -1
  137. package/src/shared/llm-call.ts +23 -95
  138. package/src/sharing/types.contract.ts +40 -0
  139. package/src/sharing/types.ts +102 -0
  140. package/src/skill/evaluator.ts +3 -2
  141. package/src/skill/evolver.ts +0 -5
  142. package/src/skill/generator.ts +6 -4
  143. package/src/skill/upgrader.ts +1 -1
  144. package/src/skill/validator.ts +1 -1
  145. package/src/storage/ensure-binding.ts +3 -1
  146. package/src/storage/sqlite.ts +1159 -4
  147. package/src/telemetry.ts +39 -152
  148. package/src/tools/index.ts +1 -0
  149. package/src/tools/memory-search.ts +58 -8
  150. package/src/tools/network-memory-detail.ts +34 -0
  151. package/src/types.ts +44 -2
  152. package/src/viewer/html.ts +3965 -459
  153. 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 Aliyun ARMS RUM.
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 ARMS_ENDPOINT =
22
- "https://proj-xtrace-e218d9316b328f196a3c640cc7ca84-cn-hangzhou.cn-hangzhou.log.aliyuncs.com" +
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
- this.flushTimer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
72
- if (this.flushTimer.unref) this.flushTimer.unref();
73
- this.log.debug("Telemetry initialized (ARMS)");
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
- const resp = await fetch(ARMS_ENDPOINT, {
198
- method: "POST",
199
- headers: { "Content-Type": "text/plain" },
200
- body: JSON.stringify(payload),
201
- signal: AbortSignal.timeout(SEND_TIMEOUT_MS),
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
- this.log.debug(`Telemetry flush: ${batch.length} events → ${resp.status}`);
204
- } catch (err) {
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: "created" | "upgraded"): void {
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.flushTimer) {
276
- clearInterval(this.flushTimer);
277
- this.flushTimer = null;
162
+ if (this.client) {
163
+ try {
164
+ await this.client.shutdown();
165
+ } catch {}
278
166
  }
279
- await this.flush();
280
167
  }
281
168
  }
@@ -1,3 +1,4 @@
1
1
  export { createMemorySearchTool } from "./memory-search";
2
2
  export { createMemoryTimelineTool } from "./memory-timeline";
3
3
  export { createMemoryGetTool } from "./memory-get";
4
+ export { createNetworkMemoryDetailTool } from "./network-memory-detail";
@@ -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
- export function createMemorySearchTool(engine: RecallEngine): ToolDefinition {
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
- const result = await engine.search({
34
- query: (input.query as string) ?? "",
35
- maxResults: input.maxResults as number | undefined,
36
- minScore: input.minScore as number | undefined,
37
- ownerFilter: resolveOwnerFilter(input.owner),
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
- return result;
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 {