@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.
- package/README.md +38 -21
- package/dist/capture/index.d.ts +1 -1
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/index.js +29 -3
- 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 +231 -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 +70 -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 +48 -0
- package/dist/hub/server.d.ts.map +1 -0
- package/dist/hub/server.js +922 -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 +203 -6
- 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 -1
- package/dist/shared/llm-call.d.ts.map +1 -1
- package/dist/shared/llm-call.js +14 -1
- 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/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 +332 -1
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +913 -4
- package/dist/storage/sqlite.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 +48 -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 +4299 -511
- package/dist/viewer/html.js.map +1 -1
- package/dist/viewer/server.d.ts +65 -0
- package/dist/viewer/server.d.ts.map +1 -1
- package/dist/viewer/server.js +1844 -90
- package/dist/viewer/server.js.map +1 -1
- package/index.ts +767 -41
- package/openclaw.plugin.json +3 -2
- package/package.json +3 -3
- package/scripts/postinstall.cjs +282 -45
- package/skill/memos-memory-guide/SKILL.md +82 -20
- package/src/capture/index.ts +30 -2
- package/src/client/connector.ts +225 -0
- package/src/client/hub.ts +207 -0
- package/src/client/skill-sync.ts +216 -0
- package/src/config.ts +92 -3
- package/src/embedding/index.ts +21 -1
- package/src/hub/auth.ts +78 -0
- package/src/hub/server.ts +906 -0
- package/src/hub/user-manager.ts +143 -0
- package/src/index.ts +13 -5
- package/src/ingest/providers/index.ts +240 -6
- 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 +18 -2
- 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/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 +1164 -4
- 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 +43 -2
- package/src/viewer/html.ts +4299 -511
- 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
|
|
75
|
-
log:
|
|
162
|
+
config,
|
|
163
|
+
log: logger,
|
|
164
|
+
openclawAPI,
|
|
76
165
|
};
|
|
77
166
|
}
|
package/src/embedding/index.ts
CHANGED
|
@@ -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
|
}
|
package/src/hub/auth.ts
ADDED
|
@@ -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
|
+
}
|