@memtensor/memos-local-openclaw-plugin 1.0.4-beta.6 → 1.0.4-beta.8

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 (143) hide show
  1. package/README.md +38 -21
  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 +29 -3
  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 +231 -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 +70 -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 +48 -0
  31. package/dist/hub/server.d.ts.map +1 -0
  32. package/dist/hub/server.js +922 -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 +203 -6
  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 -1
  59. package/dist/shared/llm-call.d.ts.map +1 -1
  60. package/dist/shared/llm-call.js +14 -1
  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/generator.d.ts.map +1 -1
  74. package/dist/skill/generator.js +4 -4
  75. package/dist/skill/generator.js.map +1 -1
  76. package/dist/skill/upgrader.js +1 -1
  77. package/dist/skill/upgrader.js.map +1 -1
  78. package/dist/skill/validator.js +1 -1
  79. package/dist/skill/validator.js.map +1 -1
  80. package/dist/storage/ensure-binding.d.ts.map +1 -1
  81. package/dist/storage/ensure-binding.js +3 -1
  82. package/dist/storage/ensure-binding.js.map +1 -1
  83. package/dist/storage/sqlite.d.ts +332 -1
  84. package/dist/storage/sqlite.d.ts.map +1 -1
  85. package/dist/storage/sqlite.js +913 -4
  86. package/dist/storage/sqlite.js.map +1 -1
  87. package/dist/tools/index.d.ts +1 -0
  88. package/dist/tools/index.d.ts.map +1 -1
  89. package/dist/tools/index.js +3 -1
  90. package/dist/tools/index.js.map +1 -1
  91. package/dist/tools/memory-search.d.ts +5 -2
  92. package/dist/tools/memory-search.d.ts.map +1 -1
  93. package/dist/tools/memory-search.js +50 -7
  94. package/dist/tools/memory-search.js.map +1 -1
  95. package/dist/tools/network-memory-detail.d.ts +4 -0
  96. package/dist/tools/network-memory-detail.d.ts.map +1 -0
  97. package/dist/tools/network-memory-detail.js +34 -0
  98. package/dist/tools/network-memory-detail.js.map +1 -0
  99. package/dist/types.d.ts +48 -2
  100. package/dist/types.d.ts.map +1 -1
  101. package/dist/types.js.map +1 -1
  102. package/dist/viewer/html.d.ts.map +1 -1
  103. package/dist/viewer/html.js +4299 -511
  104. package/dist/viewer/html.js.map +1 -1
  105. package/dist/viewer/server.d.ts +65 -0
  106. package/dist/viewer/server.d.ts.map +1 -1
  107. package/dist/viewer/server.js +1844 -90
  108. package/dist/viewer/server.js.map +1 -1
  109. package/index.ts +767 -41
  110. package/openclaw.plugin.json +3 -2
  111. package/package.json +3 -3
  112. package/scripts/postinstall.cjs +282 -45
  113. package/skill/memos-memory-guide/SKILL.md +82 -20
  114. package/src/capture/index.ts +30 -2
  115. package/src/client/connector.ts +225 -0
  116. package/src/client/hub.ts +207 -0
  117. package/src/client/skill-sync.ts +216 -0
  118. package/src/config.ts +92 -3
  119. package/src/embedding/index.ts +21 -1
  120. package/src/hub/auth.ts +78 -0
  121. package/src/hub/server.ts +906 -0
  122. package/src/hub/user-manager.ts +143 -0
  123. package/src/index.ts +13 -5
  124. package/src/ingest/providers/index.ts +240 -6
  125. package/src/ingest/providers/openai.ts +1 -1
  126. package/src/ingest/task-processor.ts +1 -1
  127. package/src/openclaw-api.ts +287 -0
  128. package/src/recall/engine.ts +1 -1
  129. package/src/shared/llm-call.ts +18 -2
  130. package/src/sharing/types.contract.ts +40 -0
  131. package/src/sharing/types.ts +102 -0
  132. package/src/skill/evaluator.ts +3 -2
  133. package/src/skill/generator.ts +6 -4
  134. package/src/skill/upgrader.ts +1 -1
  135. package/src/skill/validator.ts +1 -1
  136. package/src/storage/ensure-binding.ts +3 -1
  137. package/src/storage/sqlite.ts +1164 -4
  138. package/src/tools/index.ts +1 -0
  139. package/src/tools/memory-search.ts +58 -8
  140. package/src/tools/network-memory-detail.ts +34 -0
  141. package/src/types.ts +43 -2
  142. package/src/viewer/html.ts +4299 -511
  143. package/src/viewer/server.ts +1688 -73
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,
@@ -52,6 +76,61 @@ export function resolveConfig(raw: Partial<MemosLocalConfig> | undefined, stateD
52
76
  telemetry: {
53
77
  enabled: telemetryEnabled,
54
78
  },
79
+ summarizer: (() => {
80
+ const summarizerConfig = resolveProviderFallback<SummarizerConfig>(
81
+ cfg.summarizer,
82
+ "openclaw",
83
+ sharingCapabilities.hostCompletion,
84
+ );
85
+ return summarizerConfig
86
+ ? {
87
+ ...summarizerConfig,
88
+ capabilities: sharingCapabilities,
89
+ }
90
+ : undefined;
91
+ })(),
92
+ embedding: (() => {
93
+ const embeddingConfig = resolveProviderFallback<EmbeddingConfig>(
94
+ cfg.embedding,
95
+ "openclaw",
96
+ sharingCapabilities.hostEmbedding,
97
+ );
98
+ return embeddingConfig
99
+ ? {
100
+ ...embeddingConfig,
101
+ capabilities: sharingCapabilities,
102
+ }
103
+ : undefined;
104
+ })(),
105
+ skillEvolution: cfg.skillEvolution ? {
106
+ ...cfg.skillEvolution,
107
+ summarizer: (() => {
108
+ const skSumCfg = resolveProviderFallback<SummarizerConfig>(
109
+ cfg.skillEvolution!.summarizer as SummarizerConfig | undefined,
110
+ "openclaw",
111
+ sharingCapabilities.hostSkill,
112
+ );
113
+ return skSumCfg
114
+ ? { ...skSumCfg, capabilities: sharingCapabilities }
115
+ : undefined;
116
+ })(),
117
+ } : undefined,
118
+ sharing: (() => {
119
+ const role = cfg.sharing?.role ?? "client";
120
+ const enabled = cfg.sharing?.enabled ?? false;
121
+ const hub = role === "hub" ? {
122
+ port: cfg.sharing?.hub?.port ?? 18800,
123
+ teamName: cfg.sharing?.hub?.teamName ?? "",
124
+ teamToken: cfg.sharing?.hub?.teamToken ?? "",
125
+ } : { port: 18800, teamName: "", teamToken: "" };
126
+ const client = role === "client" ? {
127
+ hubAddress: cfg.sharing?.client?.hubAddress ?? "",
128
+ userToken: cfg.sharing?.client?.userToken ?? "",
129
+ teamToken: cfg.sharing?.client?.teamToken ?? "",
130
+ pendingUserId: cfg.sharing?.client?.pendingUserId ?? "",
131
+ } : { hubAddress: "", userToken: "", teamToken: "", pendingUserId: "" };
132
+ return { enabled, role, hub, client, capabilities: sharingCapabilities };
133
+ })(),
55
134
  };
56
135
  }
57
136
 
@@ -60,6 +139,7 @@ export function buildContext(
60
139
  workspaceDir: string,
61
140
  rawConfig: Partial<MemosLocalConfig> | undefined,
62
141
  log?: Logger,
142
+ hostModels?: HostModelsConfig,
63
143
  ): PluginContext {
64
144
  const defaultLog: Logger = {
65
145
  debug: (...args) => console.debug("[memos-local]", ...args),
@@ -68,10 +148,19 @@ export function buildContext(
68
148
  error: (...args) => console.error("[memos-local]", ...args),
69
149
  };
70
150
 
151
+ const logger = log ?? defaultLog;
152
+ const config = resolveConfig(rawConfig, stateDir);
153
+
154
+ // Create OpenClawAPI instance if host capabilities are enabled
155
+ const openclawAPI = (config.sharing?.capabilities?.hostEmbedding || config.sharing?.capabilities?.hostCompletion || config.sharing?.capabilities?.hostSkill)
156
+ ? new OpenClawAPIClient(logger, hostModels)
157
+ : undefined;
158
+
71
159
  return {
72
160
  stateDir,
73
161
  workspaceDir,
74
- config: resolveConfig(rawConfig, stateDir),
75
- log: log ?? defaultLog,
162
+ config,
163
+ log: logger,
164
+ openclawAPI,
76
165
  };
77
166
  }
@@ -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
+ }