@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/config.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as path from "path";
2
- import { DEFAULTS, type MemosLocalConfig, type PluginContext, type Logger } from "./types";
2
+ import { DEFAULTS, type MemosLocalConfig, type PluginContext, type Logger, type EmbeddingConfig, type SummarizerConfig } from "./types";
3
+ import { OpenClawAPIClient, type HostModelsConfig } from "./openclaw-api";
3
4
 
4
5
  const ENV_RE = /\$\{([A-Z_][A-Z0-9_]*)\}/g;
5
6
 
@@ -20,6 +21,24 @@ function deepResolveEnv<T>(obj: T): T {
20
21
  return obj;
21
22
  }
22
23
 
24
+ function resolveProviderFallback<T extends { provider?: string; capabilities?: unknown }>(
25
+ config: T | undefined,
26
+ fallbackProvider: T["provider"],
27
+ enabled: boolean,
28
+ ): T | undefined {
29
+ if (!config) {
30
+ return enabled
31
+ ? ({ provider: fallbackProvider } as T)
32
+ : undefined;
33
+ }
34
+
35
+ if (config.provider == null && enabled) {
36
+ return { ...config, provider: fallbackProvider };
37
+ }
38
+
39
+ return config;
40
+ }
41
+
23
42
  export function resolveConfig(raw: Partial<MemosLocalConfig> | undefined, stateDir: string): MemosLocalConfig {
24
43
  const cfg = deepResolveEnv(raw ?? {});
25
44
 
@@ -27,6 +46,11 @@ export function resolveConfig(raw: Partial<MemosLocalConfig> | undefined, stateD
27
46
  const telemetryEnabled =
28
47
  cfg.telemetry?.enabled ??
29
48
  (telemetryEnvVar === "false" || telemetryEnvVar === "0" ? false : true);
49
+ const sharingCapabilities = {
50
+ hostEmbedding: cfg.sharing?.capabilities?.hostEmbedding ?? false,
51
+ hostCompletion: cfg.sharing?.capabilities?.hostCompletion ?? false,
52
+ hostSkill: cfg.sharing?.capabilities?.hostSkill ?? false,
53
+ };
30
54
 
31
55
  return {
32
56
  ...cfg,
@@ -51,7 +75,64 @@ export function resolveConfig(raw: Partial<MemosLocalConfig> | undefined, stateD
51
75
  },
52
76
  telemetry: {
53
77
  enabled: telemetryEnabled,
78
+ posthogApiKey: cfg.telemetry?.posthogApiKey ?? process.env.POSTHOG_API_KEY ?? "",
79
+ posthogHost: cfg.telemetry?.posthogHost ?? process.env.POSTHOG_HOST ?? "",
54
80
  },
81
+ summarizer: (() => {
82
+ const summarizerConfig = resolveProviderFallback<SummarizerConfig>(
83
+ cfg.summarizer,
84
+ "openclaw",
85
+ sharingCapabilities.hostCompletion,
86
+ );
87
+ return summarizerConfig
88
+ ? {
89
+ ...summarizerConfig,
90
+ capabilities: sharingCapabilities,
91
+ }
92
+ : undefined;
93
+ })(),
94
+ embedding: (() => {
95
+ const embeddingConfig = resolveProviderFallback<EmbeddingConfig>(
96
+ cfg.embedding,
97
+ "openclaw",
98
+ sharingCapabilities.hostEmbedding,
99
+ );
100
+ return embeddingConfig
101
+ ? {
102
+ ...embeddingConfig,
103
+ capabilities: sharingCapabilities,
104
+ }
105
+ : undefined;
106
+ })(),
107
+ skillEvolution: cfg.skillEvolution ? {
108
+ ...cfg.skillEvolution,
109
+ summarizer: (() => {
110
+ const skSumCfg = resolveProviderFallback<SummarizerConfig>(
111
+ cfg.skillEvolution!.summarizer as SummarizerConfig | undefined,
112
+ "openclaw",
113
+ sharingCapabilities.hostSkill,
114
+ );
115
+ return skSumCfg
116
+ ? { ...skSumCfg, capabilities: sharingCapabilities }
117
+ : undefined;
118
+ })(),
119
+ } : undefined,
120
+ sharing: (() => {
121
+ const role = cfg.sharing?.role ?? "client";
122
+ const enabled = cfg.sharing?.enabled ?? false;
123
+ const hub = role === "hub" ? {
124
+ port: cfg.sharing?.hub?.port ?? 18800,
125
+ teamName: cfg.sharing?.hub?.teamName ?? "",
126
+ teamToken: cfg.sharing?.hub?.teamToken ?? "",
127
+ } : { port: 18800, teamName: "", teamToken: "" };
128
+ const client = role === "client" ? {
129
+ hubAddress: cfg.sharing?.client?.hubAddress ?? "",
130
+ userToken: cfg.sharing?.client?.userToken ?? "",
131
+ teamToken: cfg.sharing?.client?.teamToken ?? "",
132
+ pendingUserId: cfg.sharing?.client?.pendingUserId ?? "",
133
+ } : { hubAddress: "", userToken: "", teamToken: "", pendingUserId: "" };
134
+ return { enabled, role, hub, client, capabilities: sharingCapabilities };
135
+ })(),
55
136
  };
56
137
  }
57
138
 
@@ -60,6 +141,7 @@ export function buildContext(
60
141
  workspaceDir: string,
61
142
  rawConfig: Partial<MemosLocalConfig> | undefined,
62
143
  log?: Logger,
144
+ hostModels?: HostModelsConfig,
63
145
  ): PluginContext {
64
146
  const defaultLog: Logger = {
65
147
  debug: (...args) => console.debug("[memos-local]", ...args),
@@ -68,10 +150,19 @@ export function buildContext(
68
150
  error: (...args) => console.error("[memos-local]", ...args),
69
151
  };
70
152
 
153
+ const logger = log ?? defaultLog;
154
+ const config = resolveConfig(rawConfig, stateDir);
155
+
156
+ // Create OpenClawAPI instance if host capabilities are enabled
157
+ const openclawAPI = (config.sharing?.capabilities?.hostEmbedding || config.sharing?.capabilities?.hostCompletion || config.sharing?.capabilities?.hostSkill)
158
+ ? new OpenClawAPIClient(logger, hostModels)
159
+ : undefined;
160
+
71
161
  return {
72
162
  stateDir,
73
163
  workspaceDir,
74
- config: resolveConfig(rawConfig, stateDir),
75
- log: log ?? defaultLog,
164
+ config,
165
+ log: logger,
166
+ openclawAPI,
76
167
  };
77
168
  }
@@ -1,4 +1,4 @@
1
- import type { EmbeddingConfig, Logger } from "../types";
1
+ import type { EmbeddingConfig, Logger, OpenClawAPI } from "../types";
2
2
  import { embedOpenAI } from "./providers/openai";
3
3
  import { embedGemini } from "./providers/gemini";
4
4
  import { embedCohere, embedCohereQuery } from "./providers/cohere";
@@ -11,9 +11,13 @@ export class Embedder {
11
11
  constructor(
12
12
  private cfg: EmbeddingConfig | undefined,
13
13
  private log: Logger,
14
+ private openclawAPI?: OpenClawAPI,
14
15
  ) {}
15
16
 
16
17
  get provider(): string {
18
+ if (this.cfg?.provider === "openclaw" && this.cfg.capabilities?.hostEmbedding !== true) {
19
+ return "local";
20
+ }
17
21
  return this.cfg?.provider ?? "local";
18
22
  }
19
23
 
@@ -81,4 +85,20 @@ export class Embedder {
81
85
  throw err;
82
86
  }
83
87
  }
88
+
89
+ private async embedOpenClaw(texts: string[]): Promise<number[][]> {
90
+ if (!this.openclawAPI) {
91
+ throw new Error(
92
+ "OpenClaw API not available. Ensure sharing.capabilities.hostEmbedding is enabled in config."
93
+ );
94
+ }
95
+
96
+ this.log.debug(`Calling OpenClaw embed API for ${texts.length} texts`);
97
+ const response = await this.openclawAPI.embed({
98
+ texts,
99
+ model: this.cfg?.model,
100
+ });
101
+
102
+ return response.embeddings;
103
+ }
84
104
  }
@@ -0,0 +1,78 @@
1
+ import { createHmac, randomBytes, timingSafeEqual } from "crypto";
2
+ import type { UserRole, UserStatus } from "../sharing/types";
3
+
4
+ type UserTokenPayload = {
5
+ userId: string;
6
+ username: string;
7
+ role: UserRole;
8
+ status: UserStatus;
9
+ exp: number;
10
+ };
11
+
12
+ function base64url(input: Buffer | string): string {
13
+ return Buffer.from(input)
14
+ .toString("base64")
15
+ .replace(/\+/g, "-")
16
+ .replace(/\//g, "_")
17
+ .replace(/=+$/g, "");
18
+ }
19
+
20
+ function unbase64url(input: string): Buffer {
21
+ const padded = input.replace(/-/g, "+").replace(/_/g, "/") + "===".slice((input.length + 3) % 4);
22
+ return Buffer.from(padded, "base64");
23
+ }
24
+
25
+ function sign(value: string, secret: string): string {
26
+ return base64url(createHmac("sha256", secret).update(value).digest());
27
+ }
28
+
29
+ export function createTeamToken(secret: string): string {
30
+ const nonce = base64url(randomBytes(12));
31
+ const body = `team.${nonce}`;
32
+ return `${body}.${sign(body, secret)}`;
33
+ }
34
+
35
+ export function verifyTeamToken(token: string, secret: string): boolean {
36
+ const idx = token.lastIndexOf(".");
37
+ if (idx <= 0) return false;
38
+ const body = token.slice(0, idx);
39
+ const sig = token.slice(idx + 1);
40
+ const expected = sign(body, secret);
41
+ try {
42
+ return timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
43
+ } catch {
44
+ return false;
45
+ }
46
+ }
47
+
48
+ export function issueUserToken(
49
+ payload: { userId: string; username: string; role: UserRole; status: UserStatus },
50
+ secret: string,
51
+ ttlMs = 24 * 60 * 60 * 1000,
52
+ ): string {
53
+ const full: UserTokenPayload = { ...payload, exp: Date.now() + ttlMs };
54
+ const body = base64url(JSON.stringify(full));
55
+ return `${body}.${sign(body, secret)}`;
56
+ }
57
+
58
+ export function verifyUserToken(token: string, secret: string): Omit<UserTokenPayload, "exp"> | null {
59
+ const idx = token.lastIndexOf(".");
60
+ if (idx <= 0) return null;
61
+ const body = token.slice(0, idx);
62
+ const sig = token.slice(idx + 1);
63
+ const expected = sign(body, secret);
64
+
65
+ try {
66
+ if (!timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) return null;
67
+ const parsed = JSON.parse(unbase64url(body).toString("utf8")) as UserTokenPayload;
68
+ if (parsed.exp < Date.now()) return null;
69
+ return {
70
+ userId: parsed.userId,
71
+ username: parsed.username,
72
+ role: parsed.role,
73
+ status: parsed.status,
74
+ };
75
+ } catch {
76
+ return null;
77
+ }
78
+ }