@memtensor/memos-cloud-openclaw-plugin 0.1.14 → 0.1.15
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/LICENSE +201 -201
- package/README.md +316 -316
- package/README_ZH.md +321 -321
- package/clawdbot.plugin.json +6 -1
- package/index.js +18 -17
- package/lib/arms-reporter.js +116 -116
- package/lib/check-update.js +187 -187
- package/lib/config-resolution-schema.js +50 -50
- package/lib/config-ui/app.css +920 -920
- package/lib/config-ui/app.js +1290 -1290
- package/lib/config-ui/index.html +112 -112
- package/lib/memos-cloud-api.js +848 -848
- package/moltbot.plugin.json +6 -1
- package/openclaw.plugin.json +6 -1
- package/package.json +46 -46
- package/scripts/sync-version.js +45 -45
- package/test/direct-session-user-id.test.mjs +94 -94
- package/test/query-strip.test.mjs +381 -381
package/moltbot.plugin.json
CHANGED
|
@@ -2,9 +2,14 @@
|
|
|
2
2
|
"id": "memos-cloud-openclaw-plugin",
|
|
3
3
|
"name": "MemOS Cloud OpenClaw Plugin",
|
|
4
4
|
"description": "MemOS Cloud recall + add memory via lifecycle hooks",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.15",
|
|
6
6
|
"kind": "lifecycle",
|
|
7
7
|
"main": "./index.js",
|
|
8
|
+
"activation": {
|
|
9
|
+
"onCapabilities": [
|
|
10
|
+
"hook"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
8
13
|
"configSchema": {
|
|
9
14
|
"type": "object",
|
|
10
15
|
"properties": {
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,9 +2,14 @@
|
|
|
2
2
|
"id": "memos-cloud-openclaw-plugin",
|
|
3
3
|
"name": "MemOS Cloud OpenClaw Plugin",
|
|
4
4
|
"description": "MemOS Cloud recall + add memory via lifecycle hooks",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.15",
|
|
6
6
|
"kind": "lifecycle",
|
|
7
7
|
"main": "./index.js",
|
|
8
|
+
"activation": {
|
|
9
|
+
"onCapabilities": [
|
|
10
|
+
"hook"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
8
13
|
"configSchema": {
|
|
9
14
|
"type": "object",
|
|
10
15
|
"properties": {
|
package/package.json
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@memtensor/memos-cloud-openclaw-plugin",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "OpenClaw lifecycle plugin for MemOS Cloud (add + recall memory)",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"sync-version": "node scripts/sync-version.js",
|
|
7
|
-
"version": "npm run sync-version && git add openclaw.plugin.json moltbot.plugin.json clawdbot.plugin.json",
|
|
8
|
-
"publish-beta": "npm publish --tag beta",
|
|
9
|
-
"publish-beta-patch": "npm version prepatch --preid=beta && npm publish --tag beta",
|
|
10
|
-
"publish-latest": "npm version $(node -p \"require('./package.json').version.split('-')[0]\") && npm publish",
|
|
11
|
-
"publish-latest-patch": "npm version patch && npm publish"
|
|
12
|
-
},
|
|
13
|
-
"keywords": [
|
|
14
|
-
"memos",
|
|
15
|
-
"memos-cloud",
|
|
16
|
-
"openclaw",
|
|
17
|
-
"plugin",
|
|
18
|
-
"memory"
|
|
19
|
-
],
|
|
20
|
-
"homepage": "https://github.com/MemTensor/MemOS-Cloud-OpenClaw-Plugin#readme",
|
|
21
|
-
"bugs": {
|
|
22
|
-
"url": "https://github.com/MemTensor/MemOS-Cloud-OpenClaw-Plugin/issues"
|
|
23
|
-
},
|
|
24
|
-
"repository": {
|
|
25
|
-
"type": "git",
|
|
26
|
-
"url": "git+https://github.com/MemTensor/MemOS-Cloud-OpenClaw-Plugin.git"
|
|
27
|
-
},
|
|
28
|
-
"type": "module",
|
|
29
|
-
"author": "MemTensor",
|
|
30
|
-
"license": "MIT",
|
|
31
|
-
"openclaw": {
|
|
32
|
-
"extensions": [
|
|
33
|
-
"./index.js"
|
|
34
|
-
]
|
|
35
|
-
},
|
|
36
|
-
"clawdbot": {
|
|
37
|
-
"extensions": [
|
|
38
|
-
"./index.js"
|
|
39
|
-
]
|
|
40
|
-
},
|
|
41
|
-
"moltbot": {
|
|
42
|
-
"extensions": [
|
|
43
|
-
"./index.js"
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@memtensor/memos-cloud-openclaw-plugin",
|
|
3
|
+
"version": "0.1.15",
|
|
4
|
+
"description": "OpenClaw lifecycle plugin for MemOS Cloud (add + recall memory)",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"sync-version": "node scripts/sync-version.js",
|
|
7
|
+
"version": "npm run sync-version && git add openclaw.plugin.json moltbot.plugin.json clawdbot.plugin.json",
|
|
8
|
+
"publish-beta": "npm publish --tag beta",
|
|
9
|
+
"publish-beta-patch": "npm version prepatch --preid=beta && npm publish --tag beta",
|
|
10
|
+
"publish-latest": "npm version $(node -p \"require('./package.json').version.split('-')[0]\") && npm publish",
|
|
11
|
+
"publish-latest-patch": "npm version patch && npm publish"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"memos",
|
|
15
|
+
"memos-cloud",
|
|
16
|
+
"openclaw",
|
|
17
|
+
"plugin",
|
|
18
|
+
"memory"
|
|
19
|
+
],
|
|
20
|
+
"homepage": "https://github.com/MemTensor/MemOS-Cloud-OpenClaw-Plugin#readme",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/MemTensor/MemOS-Cloud-OpenClaw-Plugin/issues"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/MemTensor/MemOS-Cloud-OpenClaw-Plugin.git"
|
|
27
|
+
},
|
|
28
|
+
"type": "module",
|
|
29
|
+
"author": "MemTensor",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"openclaw": {
|
|
32
|
+
"extensions": [
|
|
33
|
+
"./index.js"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"clawdbot": {
|
|
37
|
+
"extensions": [
|
|
38
|
+
"./index.js"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"moltbot": {
|
|
42
|
+
"extensions": [
|
|
43
|
+
"./index.js"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
package/scripts/sync-version.js
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
|
|
5
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
-
const __dirname = path.dirname(__filename);
|
|
7
|
-
|
|
8
|
-
// Read the updated package.json to get the new version
|
|
9
|
-
const packageJsonPath = path.resolve(__dirname, '../package.json');
|
|
10
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
11
|
-
const newVersion = packageJson.version;
|
|
12
|
-
|
|
13
|
-
console.log(`Syncing version to ${newVersion}...`);
|
|
14
|
-
|
|
15
|
-
const filesToUpdate = [
|
|
16
|
-
'openclaw.plugin.json',
|
|
17
|
-
'moltbot.plugin.json',
|
|
18
|
-
'clawdbot.plugin.json'
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
filesToUpdate.forEach(fileName => {
|
|
22
|
-
const filePath = path.resolve(__dirname, '..', fileName);
|
|
23
|
-
|
|
24
|
-
if (fs.existsSync(filePath)) {
|
|
25
|
-
try {
|
|
26
|
-
const content = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
27
|
-
|
|
28
|
-
if (content.version !== newVersion) {
|
|
29
|
-
content.version = newVersion;
|
|
30
|
-
// Write back with 2 spaces indentation and a newline at the end
|
|
31
|
-
fs.writeFileSync(filePath, JSON.stringify(content, null, 2) + '\n', 'utf8');
|
|
32
|
-
console.log(`Updated ${fileName} to version ${newVersion}`);
|
|
33
|
-
} else {
|
|
34
|
-
console.log(`${fileName} is already at version ${newVersion}`);
|
|
35
|
-
}
|
|
36
|
-
} catch (error) {
|
|
37
|
-
console.error(`Error updating ${fileName}:`, error.message);
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
} else {
|
|
41
|
-
console.warn(`Warning: ${fileName} not found, skipping.`);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
console.log('Version sync complete.');
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
|
|
8
|
+
// Read the updated package.json to get the new version
|
|
9
|
+
const packageJsonPath = path.resolve(__dirname, '../package.json');
|
|
10
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
11
|
+
const newVersion = packageJson.version;
|
|
12
|
+
|
|
13
|
+
console.log(`Syncing version to ${newVersion}...`);
|
|
14
|
+
|
|
15
|
+
const filesToUpdate = [
|
|
16
|
+
'openclaw.plugin.json',
|
|
17
|
+
'moltbot.plugin.json',
|
|
18
|
+
'clawdbot.plugin.json'
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
filesToUpdate.forEach(fileName => {
|
|
22
|
+
const filePath = path.resolve(__dirname, '..', fileName);
|
|
23
|
+
|
|
24
|
+
if (fs.existsSync(filePath)) {
|
|
25
|
+
try {
|
|
26
|
+
const content = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
27
|
+
|
|
28
|
+
if (content.version !== newVersion) {
|
|
29
|
+
content.version = newVersion;
|
|
30
|
+
// Write back with 2 spaces indentation and a newline at the end
|
|
31
|
+
fs.writeFileSync(filePath, JSON.stringify(content, null, 2) + '\n', 'utf8');
|
|
32
|
+
console.log(`Updated ${fileName} to version ${newVersion}`);
|
|
33
|
+
} else {
|
|
34
|
+
console.log(`${fileName} is already at version ${newVersion}`);
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error(`Error updating ${fileName}:`, error.message);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
console.warn(`Warning: ${fileName} not found, skipping.`);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
console.log('Version sync complete.');
|
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
import test from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
|
|
4
|
-
import { buildConfig } from "../lib/memos-cloud-api.js";
|
|
5
|
-
import {
|
|
6
|
-
buildAddMessagePayload,
|
|
7
|
-
buildSearchPayload,
|
|
8
|
-
extractDirectSessionUserId,
|
|
9
|
-
resolveMemosUserId,
|
|
10
|
-
} from "../index.js";
|
|
11
|
-
|
|
12
|
-
test("buildConfig keeps useDirectSessionUserId disabled by default", () => {
|
|
13
|
-
const previous = process.env.MEMOS_USE_DIRECT_SESSION_USER_ID;
|
|
14
|
-
delete process.env.MEMOS_USE_DIRECT_SESSION_USER_ID;
|
|
15
|
-
try {
|
|
16
|
-
const cfg = buildConfig({});
|
|
17
|
-
assert.equal(cfg.useDirectSessionUserId, false);
|
|
18
|
-
} finally {
|
|
19
|
-
if (previous === undefined) {
|
|
20
|
-
delete process.env.MEMOS_USE_DIRECT_SESSION_USER_ID;
|
|
21
|
-
} else {
|
|
22
|
-
process.env.MEMOS_USE_DIRECT_SESSION_USER_ID = previous;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test("extractDirectSessionUserId returns the id for direct session keys", () => {
|
|
28
|
-
assert.equal(
|
|
29
|
-
extractDirectSessionUserId("agent:main:discord:direct:1160853368999247882"),
|
|
30
|
-
"1160853368999247882",
|
|
31
|
-
);
|
|
32
|
-
assert.equal(extractDirectSessionUserId("agent:main:telegram:direct:8361983702"), "8361983702");
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test("extractDirectSessionUserId ignores non-direct session keys", () => {
|
|
36
|
-
assert.equal(extractDirectSessionUserId("agent:main:discord:channel:1482035270651220051"), "");
|
|
37
|
-
assert.equal(extractDirectSessionUserId(""), "");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test("resolveMemosUserId falls back to configured userId when switch is off", () => {
|
|
41
|
-
const cfg = { userId: "openclaw-user", useDirectSessionUserId: false };
|
|
42
|
-
const ctx = { sessionKey: "agent:main:discord:direct:1160853368999247882" };
|
|
43
|
-
assert.equal(resolveMemosUserId(cfg, ctx), "openclaw-user");
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test("resolveMemosUserId uses direct id when switch is on", () => {
|
|
47
|
-
const cfg = { userId: "openclaw-user", useDirectSessionUserId: true };
|
|
48
|
-
const ctx = { sessionKey: "agent:main:discord:direct:1160853368999247882" };
|
|
49
|
-
assert.equal(resolveMemosUserId(cfg, ctx), "1160853368999247882");
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test("buildSearchPayload uses direct session id as user_id for private chats", () => {
|
|
53
|
-
const cfg = {
|
|
54
|
-
userId: "openclaw-user",
|
|
55
|
-
useDirectSessionUserId: true,
|
|
56
|
-
queryPrefix: "",
|
|
57
|
-
maxQueryChars: 0,
|
|
58
|
-
recallGlobal: true,
|
|
59
|
-
knowledgebaseIds: [],
|
|
60
|
-
memoryLimitNumber: 6,
|
|
61
|
-
includePreference: true,
|
|
62
|
-
preferenceLimitNumber: 6,
|
|
63
|
-
includeToolMemory: false,
|
|
64
|
-
toolMemoryLimitNumber: 0,
|
|
65
|
-
relativity: 0.45,
|
|
66
|
-
multiAgentMode: false,
|
|
67
|
-
};
|
|
68
|
-
const ctx = { sessionKey: "agent:main:discord:direct:1160853368999247882" };
|
|
69
|
-
|
|
70
|
-
const payload = buildSearchPayload(cfg, "你好", ctx);
|
|
71
|
-
assert.equal(payload.user_id, "1160853368999247882");
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test("buildAddMessagePayload keeps configured userId for non-direct chats", () => {
|
|
75
|
-
const cfg = {
|
|
76
|
-
userId: "openclaw-user",
|
|
77
|
-
useDirectSessionUserId: true,
|
|
78
|
-
multiAgentMode: false,
|
|
79
|
-
appId: "",
|
|
80
|
-
tags: [],
|
|
81
|
-
info: {},
|
|
82
|
-
allowPublic: false,
|
|
83
|
-
allowKnowledgebaseIds: [],
|
|
84
|
-
asyncMode: true,
|
|
85
|
-
conversationId: "",
|
|
86
|
-
conversationIdPrefix: "",
|
|
87
|
-
conversationIdSuffix: "",
|
|
88
|
-
conversationSuffixMode: "none",
|
|
89
|
-
};
|
|
90
|
-
const ctx = { sessionKey: "agent:main:discord:channel:1482035270651220051" };
|
|
91
|
-
|
|
92
|
-
const payload = buildAddMessagePayload(cfg, [{ role: "user", content: "hi" }], ctx);
|
|
93
|
-
assert.equal(payload.user_id, "openclaw-user");
|
|
94
|
-
});
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import { buildConfig } from "../lib/memos-cloud-api.js";
|
|
5
|
+
import {
|
|
6
|
+
buildAddMessagePayload,
|
|
7
|
+
buildSearchPayload,
|
|
8
|
+
extractDirectSessionUserId,
|
|
9
|
+
resolveMemosUserId,
|
|
10
|
+
} from "../index.js";
|
|
11
|
+
|
|
12
|
+
test("buildConfig keeps useDirectSessionUserId disabled by default", () => {
|
|
13
|
+
const previous = process.env.MEMOS_USE_DIRECT_SESSION_USER_ID;
|
|
14
|
+
delete process.env.MEMOS_USE_DIRECT_SESSION_USER_ID;
|
|
15
|
+
try {
|
|
16
|
+
const cfg = buildConfig({});
|
|
17
|
+
assert.equal(cfg.useDirectSessionUserId, false);
|
|
18
|
+
} finally {
|
|
19
|
+
if (previous === undefined) {
|
|
20
|
+
delete process.env.MEMOS_USE_DIRECT_SESSION_USER_ID;
|
|
21
|
+
} else {
|
|
22
|
+
process.env.MEMOS_USE_DIRECT_SESSION_USER_ID = previous;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("extractDirectSessionUserId returns the id for direct session keys", () => {
|
|
28
|
+
assert.equal(
|
|
29
|
+
extractDirectSessionUserId("agent:main:discord:direct:1160853368999247882"),
|
|
30
|
+
"1160853368999247882",
|
|
31
|
+
);
|
|
32
|
+
assert.equal(extractDirectSessionUserId("agent:main:telegram:direct:8361983702"), "8361983702");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("extractDirectSessionUserId ignores non-direct session keys", () => {
|
|
36
|
+
assert.equal(extractDirectSessionUserId("agent:main:discord:channel:1482035270651220051"), "");
|
|
37
|
+
assert.equal(extractDirectSessionUserId(""), "");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("resolveMemosUserId falls back to configured userId when switch is off", () => {
|
|
41
|
+
const cfg = { userId: "openclaw-user", useDirectSessionUserId: false };
|
|
42
|
+
const ctx = { sessionKey: "agent:main:discord:direct:1160853368999247882" };
|
|
43
|
+
assert.equal(resolveMemosUserId(cfg, ctx), "openclaw-user");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("resolveMemosUserId uses direct id when switch is on", () => {
|
|
47
|
+
const cfg = { userId: "openclaw-user", useDirectSessionUserId: true };
|
|
48
|
+
const ctx = { sessionKey: "agent:main:discord:direct:1160853368999247882" };
|
|
49
|
+
assert.equal(resolveMemosUserId(cfg, ctx), "1160853368999247882");
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("buildSearchPayload uses direct session id as user_id for private chats", () => {
|
|
53
|
+
const cfg = {
|
|
54
|
+
userId: "openclaw-user",
|
|
55
|
+
useDirectSessionUserId: true,
|
|
56
|
+
queryPrefix: "",
|
|
57
|
+
maxQueryChars: 0,
|
|
58
|
+
recallGlobal: true,
|
|
59
|
+
knowledgebaseIds: [],
|
|
60
|
+
memoryLimitNumber: 6,
|
|
61
|
+
includePreference: true,
|
|
62
|
+
preferenceLimitNumber: 6,
|
|
63
|
+
includeToolMemory: false,
|
|
64
|
+
toolMemoryLimitNumber: 0,
|
|
65
|
+
relativity: 0.45,
|
|
66
|
+
multiAgentMode: false,
|
|
67
|
+
};
|
|
68
|
+
const ctx = { sessionKey: "agent:main:discord:direct:1160853368999247882" };
|
|
69
|
+
|
|
70
|
+
const payload = buildSearchPayload(cfg, "你好", ctx);
|
|
71
|
+
assert.equal(payload.user_id, "1160853368999247882");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("buildAddMessagePayload keeps configured userId for non-direct chats", () => {
|
|
75
|
+
const cfg = {
|
|
76
|
+
userId: "openclaw-user",
|
|
77
|
+
useDirectSessionUserId: true,
|
|
78
|
+
multiAgentMode: false,
|
|
79
|
+
appId: "",
|
|
80
|
+
tags: [],
|
|
81
|
+
info: {},
|
|
82
|
+
allowPublic: false,
|
|
83
|
+
allowKnowledgebaseIds: [],
|
|
84
|
+
asyncMode: true,
|
|
85
|
+
conversationId: "",
|
|
86
|
+
conversationIdPrefix: "",
|
|
87
|
+
conversationIdSuffix: "",
|
|
88
|
+
conversationSuffixMode: "none",
|
|
89
|
+
};
|
|
90
|
+
const ctx = { sessionKey: "agent:main:discord:channel:1482035270651220051" };
|
|
91
|
+
|
|
92
|
+
const payload = buildAddMessagePayload(cfg, [{ role: "user", content: "hi" }], ctx);
|
|
93
|
+
assert.equal(payload.user_id, "openclaw-user");
|
|
94
|
+
});
|