mu-agent-bridge 1.0.26 → 1.0.28
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/dist/src-ts/plugin-manager.js +12 -6
- package/dist/src-ts/plugins/aun/index.js +1 -1
- package/dist/tests-ts/bundled-package.test.js +3 -1
- package/dist/tests-ts/plugin-manager.test.js +38 -0
- package/package.json +1 -1
- package/plugins/abweb/package.json +32 -0
- package/plugins/aun/dist/src-ts/plugins/aun/index.js +1 -1
- package/plugins/aun/package.json +35 -0
- package/plugins/aun/plugin.json +1 -1
- package/plugins/chatgpt/package.json +1 -0
- package/plugins/doubao/package.json +32 -0
- package/plugins/dsh/package.json +32 -0
- package/plugins/feishu/package.json +31 -0
- package/plugins/qwenwork/package.json +32 -0
- package/plugins/workbuddy/package.json +32 -0
|
@@ -115,8 +115,8 @@ class PluginManager {
|
|
|
115
115
|
async discover() {
|
|
116
116
|
await this.loadPluginTrust();
|
|
117
117
|
await (0, promises_1.mkdir)(this.root, { recursive: true });
|
|
118
|
-
await this.discoverNpmPackages();
|
|
119
118
|
await this.discoverManagedPackages();
|
|
119
|
+
await this.discoverNpmPackages();
|
|
120
120
|
for (const id of await (0, promises_1.readdir)(this.root, { withFileTypes: true })) {
|
|
121
121
|
if (!id.isDirectory())
|
|
122
122
|
continue;
|
|
@@ -145,7 +145,7 @@ class PluginManager {
|
|
|
145
145
|
const root = (0, node_path_1.resolve)(this.options.stateDir, "npm");
|
|
146
146
|
const path = (0, node_path_1.resolve)(record.path);
|
|
147
147
|
const managed = path.startsWith(`${root}${node_path_1.sep}`);
|
|
148
|
-
const packageName =
|
|
148
|
+
const packageName = record.packageName;
|
|
149
149
|
return { packageName: packageName && /^agent-bridge-[a-z0-9-]+$/.test(packageName) ? packageName : undefined, managed, version: record.version };
|
|
150
150
|
}
|
|
151
151
|
async checkPackageUpdates() {
|
|
@@ -165,12 +165,13 @@ class PluginManager {
|
|
|
165
165
|
const loaded = this.plugins.get(id);
|
|
166
166
|
if (!loaded)
|
|
167
167
|
throw new agent_1.AgentError(`unknown plugin: ${id}`);
|
|
168
|
-
if (
|
|
169
|
-
throw new agent_1.AgentError("
|
|
168
|
+
if (loaded.record.packageName !== packageName)
|
|
169
|
+
throw new agent_1.AgentError("插件未声明对应的 npm 包,不能通过 npm 升级");
|
|
170
170
|
const prefix = (0, node_path_1.join)(this.options.stateDir, "npm", packageName);
|
|
171
171
|
const cached = await this.cachedPackage(packageName, version);
|
|
172
172
|
const staging = cached ?? (0, node_path_1.join)(this.options.stateDir, "npm", `.staging-${packageName}-${Date.now()}`);
|
|
173
173
|
const backup = `${prefix}.backup-${Date.now()}`;
|
|
174
|
+
const hadPrefix = await this.existsDir(prefix);
|
|
174
175
|
let stopped = false;
|
|
175
176
|
this.log("info", `开始升级插件:${id}`, { packageName, version }, "插件升级");
|
|
176
177
|
await (0, promises_1.mkdir)(staging, { recursive: true });
|
|
@@ -192,7 +193,8 @@ class PluginManager {
|
|
|
192
193
|
this.validateCandidate(manifest, meta.agentBridge);
|
|
193
194
|
await this.stop(id, "reload");
|
|
194
195
|
stopped = true;
|
|
195
|
-
|
|
196
|
+
if (hadPrefix)
|
|
197
|
+
await (0, promises_1.rename)(prefix, backup);
|
|
196
198
|
await (0, promises_1.rename)(staging, prefix);
|
|
197
199
|
this.plugins.delete(id);
|
|
198
200
|
await this.discoverManagedPackages();
|
|
@@ -209,10 +211,14 @@ class PluginManager {
|
|
|
209
211
|
await (0, promises_1.rm)(prefix, { recursive: true, force: true });
|
|
210
212
|
await (0, promises_1.rename)(backup, prefix);
|
|
211
213
|
}
|
|
214
|
+
else if (stopped && !hadPrefix)
|
|
215
|
+
await (0, promises_1.rm)(prefix, { recursive: true, force: true });
|
|
212
216
|
if (stopped) {
|
|
213
217
|
this.plugins.delete(id);
|
|
218
|
+
loaded.instance = undefined;
|
|
219
|
+
loaded.record.status = "discovered";
|
|
220
|
+
this.plugins.set(id, loaded);
|
|
214
221
|
try {
|
|
215
|
-
await this.discoverManagedPackages();
|
|
216
222
|
await this.start(id);
|
|
217
223
|
}
|
|
218
224
|
catch { /* 回滚后仍无法启动时保留原错误 */ }
|
|
@@ -10,7 +10,7 @@ const node_url_1 = require("node:url");
|
|
|
10
10
|
const messages_1 = require("./messages");
|
|
11
11
|
const evolcore_1 = require("./evolcore");
|
|
12
12
|
const manifest = {
|
|
13
|
-
id: "aun", version: "1.0.
|
|
13
|
+
id: "aun", version: "1.0.15", type: "channel", displayName: "AUN 通道",
|
|
14
14
|
entry: "dist/src-ts/plugins/aun/index.js", apiVersion: "1", process: "in-process",
|
|
15
15
|
capabilities: ["channel", "channel.identity.create", "channel.receive", "channel.send", "health"],
|
|
16
16
|
configSchema: "config.schema.json",
|
|
@@ -30,6 +30,8 @@ const ids = ["abweb", "aun", "chatgpt", "doubao", "dsh", "feishu", "qwenwork", "
|
|
|
30
30
|
strict_1.default.deepEqual(manifest, packageManifest);
|
|
31
31
|
await (0, promises_1.access)((0, node_path_1.join)(directory, "config.schema.json"));
|
|
32
32
|
await (0, promises_1.access)((0, node_path_1.join)(directory, manifest.entry));
|
|
33
|
-
|
|
33
|
+
const meta = JSON.parse(await (0, promises_1.readFile)((0, node_path_1.join)(directory, "package.json"), "utf8"));
|
|
34
|
+
strict_1.default.equal(meta.name, `agent-bridge-${id}`);
|
|
35
|
+
strict_1.default.equal(meta.version, packageManifest.version);
|
|
34
36
|
}
|
|
35
37
|
});
|
|
@@ -44,6 +44,44 @@ const node_test_1 = __importDefault(require("node:test"));
|
|
|
44
44
|
const plugin_manager_1 = require("../src-ts/plugin-manager");
|
|
45
45
|
const version_manager_1 = require("../src-ts/version-manager");
|
|
46
46
|
const channel_sessions_1 = require("../src-ts/channel-sessions");
|
|
47
|
+
(0, node_test_1.default)("随包插件检查独立 npm 更新,升级后重启仍选新副本,失败恢复内置版本", async () => {
|
|
48
|
+
const root = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "mab-bundled-update-"));
|
|
49
|
+
const stateDir = (0, node_path_1.join)(root, "state");
|
|
50
|
+
const pluginsDir = (0, node_path_1.join)(root, "plugins");
|
|
51
|
+
const packageName = "agent-bridge-demo";
|
|
52
|
+
const writePlugin = async (dir, version, failed = false) => {
|
|
53
|
+
await (0, promises_1.mkdir)(dir, { recursive: true });
|
|
54
|
+
await (0, promises_1.writeFile)((0, node_path_1.join)(dir, "package.json"), JSON.stringify({ name: packageName, version, agentBridge: { plugin: "./plugin.json" } }));
|
|
55
|
+
await (0, promises_1.writeFile)((0, node_path_1.join)(dir, "plugin.json"), JSON.stringify({ id: "demo", version, entry: "index.js", apiVersion: "1", capabilities: [] }));
|
|
56
|
+
await (0, promises_1.writeFile)((0, node_path_1.join)(dir, "index.js"), `module.exports = { activate: async()=>{${failed ? 'throw new Error("升级测试失败")' : ''}}, deactivate: async()=>{}, health: async()=>({status:"ready"}) };`);
|
|
57
|
+
};
|
|
58
|
+
try {
|
|
59
|
+
await writePlugin((0, node_path_1.join)(pluginsDir, "demo"), "1.0.0");
|
|
60
|
+
const versions = new version_manager_1.VersionManager({ stateDir, npm: async () => JSON.stringify({ version: "1.0.1" }) });
|
|
61
|
+
const options = { pluginsDir, stateDir, versions, publisherResolver: async () => "m2lihui" };
|
|
62
|
+
const manager = new plugin_manager_1.PluginManager(options);
|
|
63
|
+
await manager.discover();
|
|
64
|
+
await manager.start("demo");
|
|
65
|
+
strict_1.default.equal((await manager.checkPackageUpdates()).find((item) => item.packageName === packageName)?.state, "update-available");
|
|
66
|
+
strict_1.default.equal(manager.list()[0].autoUpdate, true);
|
|
67
|
+
const downloaded = (0, node_path_1.join)(root, "downloaded");
|
|
68
|
+
await writePlugin((0, node_path_1.join)(downloaded, "node_modules", packageName), "1.0.1", true);
|
|
69
|
+
manager.downloadPackage = async () => downloaded;
|
|
70
|
+
await strict_1.default.rejects(manager.upgradePackage("demo", packageName, "1.0.1"), /升级测试失败/);
|
|
71
|
+
strict_1.default.equal(manager.list()[0].version, "1.0.0");
|
|
72
|
+
strict_1.default.equal(manager.list()[0].status, "ready");
|
|
73
|
+
await writePlugin((0, node_path_1.join)(downloaded, "node_modules", packageName), "1.0.1");
|
|
74
|
+
strict_1.default.equal((await manager.upgradePackage("demo", packageName, "1.0.1")).version, "1.0.1");
|
|
75
|
+
await manager.stop("demo");
|
|
76
|
+
const restarted = new plugin_manager_1.PluginManager(options);
|
|
77
|
+
await restarted.discover();
|
|
78
|
+
strict_1.default.equal(restarted.list()[0].version, "1.0.1");
|
|
79
|
+
strict_1.default.equal(restarted.packageInfo("demo").managed, true);
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
await (0, promises_1.rm)(root, { recursive: true, force: true });
|
|
83
|
+
}
|
|
84
|
+
});
|
|
47
85
|
(0, node_test_1.default)("通道会话隔离、续接和重启恢复", async () => {
|
|
48
86
|
const root = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "mab-sessions-"));
|
|
49
87
|
try {
|
package/package.json
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-bridge-abweb",
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"description": "agent-bridge 的网页管理插件。",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mu-agent-bridge-plugin",
|
|
7
|
+
"mu-agent-bridge-management"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://codeup.aliyun.com/6808da56fb3da14b899afd54/agent_bridge.git",
|
|
12
|
+
"directory": "packages/abweb"
|
|
13
|
+
},
|
|
14
|
+
"main": "dist/src-ts/plugins/abweb/index.js",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"plugin.json",
|
|
18
|
+
"config.schema.json",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"agentBridge": {
|
|
22
|
+
"plugin": "./plugin.json",
|
|
23
|
+
"type": "management"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"registry": "https://registry.npmjs.org"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -10,7 +10,7 @@ const node_url_1 = require("node:url");
|
|
|
10
10
|
const messages_1 = require("./messages");
|
|
11
11
|
const evolcore_1 = require("./evolcore");
|
|
12
12
|
const manifest = {
|
|
13
|
-
id: "aun", version: "1.0.
|
|
13
|
+
id: "aun", version: "1.0.15", type: "channel", displayName: "AUN 通道",
|
|
14
14
|
entry: "dist/src-ts/plugins/aun/index.js", apiVersion: "1", process: "in-process",
|
|
15
15
|
capabilities: ["channel", "channel.identity.create", "channel.receive", "channel.send", "health"],
|
|
16
16
|
configSchema: "config.schema.json",
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-bridge-aun",
|
|
3
|
+
"version": "1.0.15",
|
|
4
|
+
"description": "mu-agent-bridge 的 AUN 通道插件。",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mu-agent-bridge-plugin",
|
|
7
|
+
"mu-agent-bridge-channel"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://codeup.aliyun.com/6808da56fb3da14b899afd54/agent_bridge.git",
|
|
12
|
+
"directory": "packages/aun"
|
|
13
|
+
},
|
|
14
|
+
"main": "dist/src-ts/plugins/aun/index.js",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"plugin.json",
|
|
18
|
+
"config.schema.json",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"agentBridge": {
|
|
22
|
+
"plugin": "./plugin.json",
|
|
23
|
+
"type": "channel"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"registry": "https://registry.npmjs.org"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22.16.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@agentunion/fastaun": "0.5.18"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/plugins/aun/plugin.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"agent-bridge-chatgpt","version":"1.0.1","description":"agent-bridge 的 ChatGPT Codex CDP 插件。","keywords":["mu-agent-bridge-plugin","mu-agent-bridge-agent"],"main":"dist/src-ts/plugins/chatgpt/index.js","files":["dist/","plugin.json","config.schema.json","README.md"],"agentBridge":{"plugin":"./plugin.json","type":"agent"},"engines":{"node":">=22"}}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-bridge-doubao",
|
|
3
|
+
"version": "1.0.5",
|
|
4
|
+
"description": "agent-bridge 的豆包插件。",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mu-agent-bridge-plugin",
|
|
7
|
+
"mu-agent-bridge-agent"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://codeup.aliyun.com/6808da56fb3da14b899afd54/agent_bridge.git",
|
|
12
|
+
"directory": "packages/doubao"
|
|
13
|
+
},
|
|
14
|
+
"main": "dist/src-ts/plugins/doubao/index.js",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"plugin.json",
|
|
18
|
+
"config.schema.json",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"agentBridge": {
|
|
22
|
+
"plugin": "./plugin.json",
|
|
23
|
+
"type": "agent"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"registry": "https://registry.npmjs.org"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-bridge-dsh",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "agent-bridge 的 DeepSeek Harness 插件,支持后台定时自动升级验证。",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mu-agent-bridge-plugin",
|
|
7
|
+
"mu-agent-bridge-agent"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://codeup.aliyun.com/6808da56fb3da14b899afd54/agent_bridge.git",
|
|
12
|
+
"directory": "packages/dsh"
|
|
13
|
+
},
|
|
14
|
+
"main": "dist/src-ts/plugins/dsh/index.js",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"plugin.json",
|
|
18
|
+
"config.schema.json",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"agentBridge": {
|
|
22
|
+
"plugin": "./plugin.json",
|
|
23
|
+
"type": "agent"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"registry": "https://registry.npmjs.org"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-bridge-feishu",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "agent-bridge 的飞书通道插件。",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mu-agent-bridge-plugin",
|
|
7
|
+
"mu-agent-bridge-channel"
|
|
8
|
+
],
|
|
9
|
+
"main": "dist/src-ts/plugins/feishu/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/",
|
|
12
|
+
"plugin.json",
|
|
13
|
+
"config.schema.json",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"agentBridge": {
|
|
17
|
+
"plugin": "./plugin.json",
|
|
18
|
+
"type": "channel"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=22"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"qrcode": "^1.5.4",
|
|
25
|
+
"@larksuiteoapi/node-sdk": "1.74.0"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public",
|
|
29
|
+
"registry": "https://registry.npmjs.org"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-bridge-qwenwork",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "agent-bridge 的千问办公插件。",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mu-agent-bridge-plugin",
|
|
7
|
+
"mu-agent-bridge-agent"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://codeup.aliyun.com/6808da56fb3da14b899afd54/agent_bridge.git",
|
|
12
|
+
"directory": "packages/qwenwork"
|
|
13
|
+
},
|
|
14
|
+
"main": "dist/src-ts/plugins/qwenwork/index.js",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"plugin.json",
|
|
18
|
+
"config.schema.json",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"agentBridge": {
|
|
22
|
+
"plugin": "./plugin.json",
|
|
23
|
+
"type": "agent"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"registry": "https://registry.npmjs.org"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-bridge-workbuddy",
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"description": "agent-bridge 的 CodeBuddy CLI 插件。",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mu-agent-bridge-plugin",
|
|
7
|
+
"mu-agent-bridge-agent"
|
|
8
|
+
],
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://codeup.aliyun.com/6808da56fb3da14b899afd54/agent_bridge.git",
|
|
12
|
+
"directory": "packages/workbuddy"
|
|
13
|
+
},
|
|
14
|
+
"main": "dist/src-ts/plugins/workbuddy/index.js",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"plugin.json",
|
|
18
|
+
"config.schema.json",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"agentBridge": {
|
|
22
|
+
"plugin": "./plugin.json",
|
|
23
|
+
"type": "agent"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"registry": "https://registry.npmjs.org"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=22"
|
|
31
|
+
}
|
|
32
|
+
}
|