mu-agent-bridge 1.0.71 → 1.0.78

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 (195) hide show
  1. package/README.md +17 -10
  2. package/dist/src-ts/agent.js +35 -0
  3. package/dist/src-ts/channel-sessions.js +3 -2
  4. package/dist/src-ts/cli.js +67 -37
  5. package/dist/src-ts/control-server.js +12 -30
  6. package/dist/src-ts/core-updater.js +141 -33
  7. package/dist/src-ts/daemon-process.js +2 -1
  8. package/dist/src-ts/dsh-agent.js +31 -13
  9. package/dist/src-ts/http-agent.js +36 -0
  10. package/dist/src-ts/plugin-catalog.js +11 -2
  11. package/dist/src-ts/plugin-manager.js +351 -50
  12. package/dist/src-ts/plugins/abweb/index.js +1 -1
  13. package/dist/src-ts/plugins/abweb/public/app.js +73 -5
  14. package/dist/src-ts/plugins/abweb/public/index.html +15 -0
  15. package/dist/src-ts/plugins/abweb/public/style.css +4 -0
  16. package/dist/src-ts/plugins/aun/attachments.js +3 -21
  17. package/dist/src-ts/plugins/aun/index.js +155 -21
  18. package/dist/src-ts/plugins/aun/messages.js +4 -1
  19. package/dist/src-ts/plugins/aun/public/app.js +2 -1
  20. package/dist/src-ts/plugins/aun/public/index.html +1 -1
  21. package/dist/src-ts/plugins/cdp-draft.js +5 -2
  22. package/dist/src-ts/plugins/chatgpt/cdp-client.js +26 -12
  23. package/dist/src-ts/plugins/chatgpt/index.js +80 -19
  24. package/dist/src-ts/plugins/claude-cli/index.js +19 -2
  25. package/dist/src-ts/plugins/codex-cli/index.js +19 -2
  26. package/dist/src-ts/plugins/desktop-launch.js +44 -3
  27. package/dist/src-ts/plugins/doubao/cdp-client.js +234 -45
  28. package/dist/src-ts/plugins/doubao/index.js +152 -8
  29. package/dist/src-ts/plugins/doubao/native-task.js +134 -0
  30. package/dist/src-ts/plugins/dsh/cdp-client.js +334 -0
  31. package/dist/src-ts/plugins/dsh/index.js +172 -21
  32. package/dist/src-ts/plugins/dsh/session-history.js +31 -3
  33. package/dist/src-ts/plugins/feishu/index.js +1 -1
  34. package/dist/src-ts/plugins/local-cli/agent.js +74 -9
  35. package/dist/src-ts/plugins/personal-assistant/claude-cli-model.js +30 -0
  36. package/dist/src-ts/plugins/personal-assistant/coordination.js +57 -0
  37. package/dist/src-ts/plugins/personal-assistant/index.js +263 -0
  38. package/dist/src-ts/plugins/personal-assistant/model-client.js +181 -0
  39. package/dist/src-ts/plugins/personal-assistant/owner-context.js +56 -0
  40. package/dist/src-ts/plugins/personal-assistant/remote-ability.js +176 -0
  41. package/dist/src-ts/plugins/personal-assistant/session-memory.js +124 -0
  42. package/dist/src-ts/plugins/personal-assistant/tools.js +167 -0
  43. package/dist/src-ts/plugins/qwenwork/cdp-client.js +90 -18
  44. package/dist/src-ts/plugins/qwenwork/index.js +139 -24
  45. package/dist/src-ts/plugins/workbuddy/cdp-client.js +353 -82
  46. package/dist/src-ts/plugins/workbuddy/index.js +124 -41
  47. package/dist/src-ts/plugins/zcode/cdp-client.js +500 -0
  48. package/dist/src-ts/plugins/zcode/index.js +97 -0
  49. package/dist/src-ts/session-management.js +132 -14
  50. package/dist/src-ts/version-manager.js +6 -3
  51. package/dist/tests-ts/abweb-cli.test.js +10 -2
  52. package/dist/tests-ts/abweb-model-config.test.js +73 -0
  53. package/dist/tests-ts/agent.test.js +27 -0
  54. package/dist/tests-ts/aun-attachments.test.js +19 -17
  55. package/dist/tests-ts/aun-default-owner-page.test.js +2 -1
  56. package/dist/tests-ts/aun-messages.test.js +20 -0
  57. package/dist/tests-ts/aun-plugin.test.js +292 -19
  58. package/dist/tests-ts/bundled-package.test.js +12 -2
  59. package/dist/tests-ts/cdp-draft-recovery.test.js +182 -3
  60. package/dist/tests-ts/channel-sessions.test.js +27 -0
  61. package/dist/tests-ts/chatgpt-plugin.test.js +118 -0
  62. package/dist/tests-ts/control-server.test.js +56 -0
  63. package/dist/tests-ts/core-updater.test.js +215 -46
  64. package/dist/tests-ts/daemon-process.test.js +126 -1
  65. package/dist/tests-ts/desktop-launch.test.js +73 -0
  66. package/dist/tests-ts/doubao-native-task.test.js +237 -0
  67. package/dist/tests-ts/doubao-plugin.test.js +773 -12
  68. package/dist/tests-ts/dsh-agent.test.js +157 -8
  69. package/dist/tests-ts/dsh-cdp.test.js +148 -0
  70. package/dist/tests-ts/dsh-history.test.js +37 -0
  71. package/dist/tests-ts/feishu-plugin.test.js +1 -1
  72. package/dist/tests-ts/http-agent.test.js +18 -0
  73. package/dist/tests-ts/installer-assets.test.js +1 -1
  74. package/dist/tests-ts/local-cli.test.js +146 -1
  75. package/dist/tests-ts/model-provider-cancellation.test.js +152 -0
  76. package/dist/tests-ts/native-session-management.test.js +8 -7
  77. package/dist/tests-ts/personal-assistant-coordination.test.js +92 -0
  78. package/dist/tests-ts/personal-assistant-extensions.test.js +35 -0
  79. package/dist/tests-ts/personal-assistant-memory.test.js +117 -0
  80. package/dist/tests-ts/personal-assistant-owner-context.test.js +107 -0
  81. package/dist/tests-ts/personal-assistant-remote-ability.test.js +123 -0
  82. package/dist/tests-ts/personal-assistant.test.js +663 -0
  83. package/dist/tests-ts/platform-integration.test.js +183 -1
  84. package/dist/tests-ts/plugin-catalog.test.js +12 -2
  85. package/dist/tests-ts/plugin-manager.test.js +356 -4
  86. package/dist/tests-ts/plugin-upgrade-deadline.test.js +354 -0
  87. package/dist/tests-ts/publish-packages.test.js +42 -0
  88. package/dist/tests-ts/qwenwork-plugin.test.js +135 -1
  89. package/dist/tests-ts/qwenwork-reconnect.test.js +195 -0
  90. package/dist/tests-ts/qwenwork-sse.test.js +33 -0
  91. package/dist/tests-ts/session-access-defaults.test.js +112 -0
  92. package/dist/tests-ts/session-management.test.js +159 -4
  93. package/dist/tests-ts/version-manager.test.js +40 -0
  94. package/dist/tests-ts/workbuddy-cdp-recovery.test.js +311 -0
  95. package/dist/tests-ts/workbuddy-plugin.test.js +499 -4
  96. package/dist/tests-ts/zcode-cdp.test.js +894 -0
  97. package/dist/tests-ts/zcode-plugin.test.js +396 -0
  98. package/package.json +1 -1
  99. package/plugins/abweb/dist/src-ts/agent.js +35 -0
  100. package/plugins/abweb/dist/src-ts/plugins/abweb/index.js +1 -1
  101. package/plugins/abweb/dist/src-ts/plugins/abweb/public/app.js +73 -5
  102. package/plugins/abweb/dist/src-ts/plugins/abweb/public/app.ts +57 -5
  103. package/plugins/abweb/dist/src-ts/plugins/abweb/public/index.html +15 -0
  104. package/plugins/abweb/dist/src-ts/plugins/abweb/public/style.css +4 -0
  105. package/plugins/abweb/package.json +1 -1
  106. package/plugins/abweb/plugin.json +1 -1
  107. package/plugins/aun/config.schema.json +1 -1
  108. package/plugins/aun/dist/src-ts/agent.js +35 -0
  109. package/plugins/aun/dist/src-ts/plugins/aun/attachments.js +3 -21
  110. package/plugins/aun/dist/src-ts/plugins/aun/index.js +155 -21
  111. package/plugins/aun/dist/src-ts/plugins/aun/messages.js +4 -1
  112. package/plugins/aun/dist/src-ts/plugins/aun/public/app.js +2 -1
  113. package/plugins/aun/dist/src-ts/plugins/aun/public/index.html +1 -1
  114. package/plugins/aun/package.json +1 -1
  115. package/plugins/aun/plugin.json +1 -1
  116. package/plugins/chatgpt/dist/src-ts/agent.js +35 -0
  117. package/plugins/chatgpt/dist/src-ts/plugins/cdp-draft.js +5 -2
  118. package/plugins/chatgpt/dist/src-ts/plugins/chatgpt/cdp-client.js +26 -12
  119. package/plugins/chatgpt/dist/src-ts/plugins/chatgpt/index.js +80 -19
  120. package/plugins/chatgpt/dist/src-ts/plugins/desktop-launch.js +44 -3
  121. package/plugins/chatgpt/package.json +1 -1
  122. package/plugins/chatgpt/plugin.json +1 -1
  123. package/plugins/claude-cli/dist/src-ts/agent.js +35 -0
  124. package/plugins/claude-cli/dist/src-ts/plugins/claude-cli/index.js +19 -2
  125. package/plugins/claude-cli/dist/src-ts/plugins/local-cli/agent.js +74 -9
  126. package/plugins/claude-cli/package.json +1 -1
  127. package/plugins/claude-cli/plugin.json +3 -2
  128. package/plugins/codex-cli/dist/src-ts/agent.js +35 -0
  129. package/plugins/codex-cli/dist/src-ts/plugins/codex-cli/index.js +19 -2
  130. package/plugins/codex-cli/dist/src-ts/plugins/local-cli/agent.js +74 -9
  131. package/plugins/codex-cli/package.json +1 -1
  132. package/plugins/codex-cli/plugin.json +3 -2
  133. package/plugins/doubao/config.schema.json +2 -1
  134. package/plugins/doubao/dist/src-ts/agent.js +35 -0
  135. package/plugins/doubao/dist/src-ts/plugins/desktop-launch.js +44 -3
  136. package/plugins/doubao/dist/src-ts/plugins/doubao/cdp-client.js +234 -45
  137. package/plugins/doubao/dist/src-ts/plugins/doubao/index.js +152 -8
  138. package/plugins/doubao/dist/src-ts/plugins/doubao/native-task.js +134 -0
  139. package/plugins/doubao/package.json +1 -1
  140. package/plugins/doubao/plugin.json +3 -2
  141. package/plugins/dsh/config.schema.json +5 -2
  142. package/plugins/dsh/dist/src-ts/agent.js +35 -0
  143. package/plugins/dsh/dist/src-ts/dsh-agent.js +31 -13
  144. package/plugins/dsh/dist/src-ts/plugins/desktop-launch.js +44 -3
  145. package/plugins/dsh/dist/src-ts/plugins/dsh/cdp-client.js +334 -0
  146. package/plugins/dsh/dist/src-ts/plugins/dsh/index.js +172 -21
  147. package/plugins/dsh/dist/src-ts/plugins/dsh/session-history.js +31 -3
  148. package/plugins/dsh/package.json +1 -1
  149. package/plugins/dsh/plugin.json +3 -2
  150. package/plugins/feishu/dist/src-ts/agent.js +35 -0
  151. package/plugins/feishu/dist/src-ts/plugins/feishu/index.js +1 -1
  152. package/plugins/feishu/package.json +1 -1
  153. package/plugins/feishu/plugin.json +1 -1
  154. package/plugins/personal-assistant/config.schema.json +23 -0
  155. package/plugins/personal-assistant/dist/src-ts/agent.js +69 -0
  156. package/plugins/personal-assistant/dist/src-ts/attachments.js +62 -0
  157. package/plugins/personal-assistant/dist/src-ts/plugin.js +13 -0
  158. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/claude-cli-model.js +30 -0
  159. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/coordination.js +57 -0
  160. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/index.js +263 -0
  161. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/model-client.js +181 -0
  162. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/owner-context.js +56 -0
  163. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/remote-ability.js +176 -0
  164. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/session-memory.js +124 -0
  165. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/tools.js +167 -0
  166. package/plugins/personal-assistant/package.json +39 -0
  167. package/plugins/personal-assistant/plugin.json +15 -0
  168. package/plugins/qwenwork/dist/src-ts/agent.js +35 -0
  169. package/plugins/qwenwork/dist/src-ts/plugins/cdp-draft.js +5 -2
  170. package/plugins/qwenwork/dist/src-ts/plugins/desktop-launch.js +44 -3
  171. package/plugins/qwenwork/dist/src-ts/plugins/qwenwork/cdp-client.js +90 -18
  172. package/plugins/qwenwork/dist/src-ts/plugins/qwenwork/index.js +139 -24
  173. package/plugins/qwenwork/package.json +1 -1
  174. package/plugins/qwenwork/plugin.json +3 -2
  175. package/plugins/workbuddy/config.schema.json +1 -1
  176. package/plugins/workbuddy/dist/src-ts/agent.js +35 -0
  177. package/plugins/workbuddy/dist/src-ts/plugins/desktop-launch.js +44 -3
  178. package/plugins/workbuddy/dist/src-ts/plugins/workbuddy/cdp-client.js +353 -82
  179. package/plugins/workbuddy/dist/src-ts/plugins/workbuddy/index.js +124 -41
  180. package/plugins/workbuddy/package.json +1 -1
  181. package/plugins/workbuddy/plugin.json +3 -2
  182. package/plugins/zcode/config.schema.json +13 -0
  183. package/plugins/zcode/dist/src-ts/agent.js +69 -0
  184. package/plugins/zcode/dist/src-ts/attachments.js +62 -0
  185. package/plugins/zcode/dist/src-ts/plugin.js +13 -0
  186. package/plugins/zcode/dist/src-ts/plugins/desktop-launch.js +238 -0
  187. package/plugins/zcode/dist/src-ts/plugins/workbuddy/cdp-client.js +896 -0
  188. package/plugins/zcode/dist/src-ts/plugins/workbuddy/cli-client.js +39 -0
  189. package/plugins/zcode/dist/src-ts/plugins/workbuddy/desktop-launch.js +10 -0
  190. package/plugins/zcode/dist/src-ts/plugins/workbuddy/index.js +567 -0
  191. package/plugins/zcode/dist/src-ts/plugins/workbuddy/session-history.js +121 -0
  192. package/plugins/zcode/dist/src-ts/plugins/zcode/cdp-client.js +500 -0
  193. package/plugins/zcode/dist/src-ts/plugins/zcode/index.js +97 -0
  194. package/plugins/zcode/package.json +16 -0
  195. package/plugins/zcode/plugin.json +11 -0
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const strict_1 = __importDefault(require("node:assert/strict"));
7
+ const node_http_1 = require("node:http");
7
8
  const promises_1 = require("node:fs/promises");
8
9
  const node_os_1 = require("node:os");
9
10
  const node_path_1 = require("node:path");
@@ -17,7 +18,7 @@ const qwenwork_1 = require("../src-ts/plugins/qwenwork");
17
18
  const state = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "agent-bridge-platform-"));
18
19
  const manager = new plugin_manager_1.PluginManager({ pluginsDir: (0, node_path_1.resolve)(process.cwd(), "plugins"), stateDir: state });
19
20
  const records = await manager.discover();
20
- strict_1.default.deepEqual(records.map((record) => record.id).sort(), ["abweb", "aun", "chatgpt", "claude-cli", "codex-cli", "doubao", "dsh", "feishu", "qwenwork", "workbuddy"]);
21
+ strict_1.default.deepEqual(records.map((record) => record.id).sort(), ["abweb", "aun", "chatgpt", "claude-cli", "codex-cli", "doubao", "dsh", "feishu", "personal-assistant", "qwenwork", "workbuddy", "zcode"]);
21
22
  strict_1.default.equal(records.find((record) => record.id === "aun")?.type, "channel");
22
23
  const server = new control_server_1.ControlServer({ manager, host: "127.0.0.1", port: 0 });
23
24
  const address = await server.start();
@@ -48,6 +49,187 @@ const qwenwork_1 = require("../src-ts/plugins/qwenwork");
48
49
  await (0, promises_1.rm)(state, { recursive: true, force: true });
49
50
  }
50
51
  });
52
+ (0, node_test_1.default)("AUN 可信入口可调用个人助理和目标 Agent,HTTP relay 不继承管理身份", async () => {
53
+ const state = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "agent-bridge-assistant-integration-"));
54
+ const pluginsDir = (0, node_path_1.join)(state, "plugins");
55
+ const fakeAunDir = (0, node_path_1.join)(pluginsDir, "aun");
56
+ const targetDir = (0, node_path_1.join)(pluginsDir, "target-agent");
57
+ await (0, promises_1.mkdir)(pluginsDir, { recursive: true });
58
+ await (0, promises_1.cp)((0, node_path_1.join)(process.cwd(), "plugins", "personal-assistant"), (0, node_path_1.join)(pluginsDir, "personal-assistant"), { recursive: true });
59
+ await (0, promises_1.symlink)((0, node_path_1.resolve)(process.cwd(), "node_modules"), (0, node_path_1.join)(state, "node_modules"), "dir");
60
+ await (0, promises_1.mkdir)(fakeAunDir, { recursive: true });
61
+ await (0, promises_1.mkdir)(targetDir, { recursive: true });
62
+ await (0, promises_1.writeFile)((0, node_path_1.join)(fakeAunDir, "plugin.json"), JSON.stringify({ id: "aun", version: "1.0.0", type: "channel", displayName: "假 AUN", entry: "index.js", apiVersion: "1", capabilities: ["channel"] }));
63
+ await (0, promises_1.writeFile)((0, node_path_1.join)(fakeAunDir, "index.js"), `module.exports = class {
64
+ aunManagement = { list: async () => ({ aids: ["assistant.agentid.cn", "target.agentid.cn"], bindings: { "assistant.agentid.cn": "personal-assistant", "target.agentid.cn": "target-agent" } }), create: async () => ({}), bind: async () => ({}) };
65
+ identity = { list: async () => ({ evolcore: [], muAgentBridge: [] }), create: async () => ({}), bind: async () => {} };
66
+ async activate(context) { this.ingress = context.ingress; }
67
+ async deactivate() {}
68
+ async health() { return { status: "ready", details: { bindings: { "assistant.agentid.cn": "personal-assistant", "target.agentid.cn": "target-agent" } } }; }
69
+ async publish(message) { return this.ingress.publish(message); }
70
+ async handle() { throw new Error("不支持"); }
71
+ }`);
72
+ await (0, promises_1.writeFile)((0, node_path_1.join)(targetDir, "plugin.json"), JSON.stringify({ id: "target-agent", version: "1.0.0", type: "agent", displayName: "目标 Agent", entry: "index.js", apiVersion: "1", capabilities: ["chat"] }));
73
+ await (0, promises_1.writeFile)((0, node_path_1.join)(targetDir, "index.js"), `module.exports = class {
74
+ manifest = { id: "target-agent", version: "1.0.0", type: "agent", displayName: "目标 Agent", entry: "index.js", apiVersion: "1", process: "in-process", capabilities: ["chat"] };
75
+ async activate() {}
76
+ async deactivate() {}
77
+ async health() { return { status: "ready" }; }
78
+ async handle(request) { return { text: "目标已处理:" + request.task }; }
79
+ }`);
80
+ const modelRequests = [];
81
+ const modelServer = (0, node_http_1.createServer)(async (request, response) => {
82
+ let body = "";
83
+ for await (const chunk of request)
84
+ body += chunk;
85
+ const payload = JSON.parse(body);
86
+ modelRequests.push(payload);
87
+ const reply = modelRequests.length === 1
88
+ ? { choices: [{ message: { role: "assistant", content: null, tool_calls: [{ id: "list-call", type: "function", function: { name: "agents_list", arguments: "{}" } }] } }] }
89
+ : modelRequests.length === 2
90
+ ? { choices: [{ message: { role: "assistant", content: null, tool_calls: [{ id: "target-call", type: "function", function: { name: "agents_call", arguments: JSON.stringify({ id: "target-agent", task: "完成独立任务" }) } }] } }] }
91
+ : { choices: [{ message: { role: "assistant", content: "目标 Agent 已完成独立任务。" } }] };
92
+ response.writeHead(200, { "content-type": "application/json" });
93
+ response.end(JSON.stringify(reply));
94
+ });
95
+ await new Promise((resolve) => modelServer.listen(0, "127.0.0.1", resolve));
96
+ const modelAddress = modelServer.address();
97
+ strict_1.default.ok(modelAddress && typeof modelAddress !== "string");
98
+ const stateDir = (0, node_path_1.join)(state, "state");
99
+ await (0, promises_1.mkdir)((0, node_path_1.join)(stateDir, "personal-assistant"), { recursive: true });
100
+ await (0, promises_1.writeFile)((0, node_path_1.join)(stateDir, "personal-assistant", "config.json"), JSON.stringify({
101
+ endpoint: `http://127.0.0.1:${modelAddress.port}/v1/chat/completions`,
102
+ model: "offline-test",
103
+ apiKey: "offline-secret",
104
+ allowedPeers: ["owner.agentid.cn"],
105
+ allowedAgents: ["target-agent"],
106
+ }));
107
+ const manager = new plugin_manager_1.PluginManager({ pluginsDir, stateDir });
108
+ await manager.discover();
109
+ const replies = [];
110
+ try {
111
+ await manager.start("target-agent");
112
+ await manager.start("personal-assistant");
113
+ await manager.start("aun");
114
+ const control = new control_server_1.ControlServer({ manager, host: "127.0.0.1", port: 0 });
115
+ const controlAddress = await control.start();
116
+ try {
117
+ const bind = await fetch(`http://${controlAddress.host}:${controlAddress.port}/api/plugins/personal-assistant/aid`, {
118
+ method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify({ aid: "assistant.agentid.cn" }),
119
+ });
120
+ strict_1.default.equal(bind.status, 200);
121
+ strict_1.default.equal((await manager.config("personal-assistant")).aid, undefined);
122
+ const unbind = await fetch(`http://${controlAddress.host}:${controlAddress.port}/api/plugins/personal-assistant/aid`, {
123
+ method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify({ aid: "" }),
124
+ });
125
+ strict_1.default.equal(unbind.status, 400);
126
+ strict_1.default.match((await unbind.json()).error, /指定.*AID/);
127
+ strict_1.default.equal((await manager.config("personal-assistant")).aid, undefined);
128
+ const rebind = await fetch(`http://${controlAddress.host}:${controlAddress.port}/api/plugins/personal-assistant/aid`, {
129
+ method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify({ aid: "assistant.agentid.cn" }),
130
+ });
131
+ strict_1.default.equal(rebind.status, 200);
132
+ }
133
+ finally {
134
+ await control.stop();
135
+ }
136
+ const channel = manager.get("aun")?.instance;
137
+ await channel.publish({ channel: "aun", peerId: "owner.agentid.cn", threadId: "thread-1", agentPlugin: "personal-assistant", text: "请调用目标 Agent", reply: async (text) => { replies.push({ peerId: "owner.agentid.cn", threadId: "thread-1", text }); } });
138
+ strict_1.default.equal(replies.length, 1);
139
+ strict_1.default.deepEqual(replies[0], { peerId: "owner.agentid.cn", threadId: "thread-1", text: "目标 Agent 已完成独立任务。" });
140
+ strict_1.default.match(modelRequests[1].messages.at(-1)?.content ?? "", /target\.agentid\.cn/);
141
+ strict_1.default.match(modelRequests[2].messages.at(-1)?.content ?? "", /目标已处理:完成独立任务/);
142
+ await channel.publish({ channel: "aun", peerId: "intruder.agentid.cn", threadId: "thread-2", agentPlugin: "personal-assistant", text: "查询管理能力", reply: async (text) => { replies.push({ peerId: "intruder.agentid.cn", threadId: "thread-2", text }); } });
143
+ strict_1.default.equal(modelRequests.length, 3);
144
+ strict_1.default.match(replies[1].text, /授权的 AUN/);
145
+ await manager.saveConfig("personal-assistant", { allowedPeers: ["*"] });
146
+ await manager.reload("personal-assistant");
147
+ strict_1.default.equal((await manager.health("personal-assistant")).status, "ready");
148
+ await channel.publish({ channel: "aun", peerId: "another.agentid.cn", threadId: "thread-3", agentPlugin: "personal-assistant", text: "/assistant agent call target-agent 通配任务", reply: async (text) => { replies.push({ peerId: "another.agentid.cn", threadId: "thread-3", text }); } });
149
+ strict_1.default.equal(replies[2].text, "目标已处理:通配任务");
150
+ const server = new control_server_1.ControlServer({ manager, host: "127.0.0.1", port: 0 });
151
+ const address = await server.start();
152
+ try {
153
+ const response = await fetch(`http://${address.host}:${address.port}/api/agents/personal-assistant/v1/chat/completions`, {
154
+ method: "POST", headers: { "content-type": "application/json", "x-evolcore-peer": "owner.agentid.cn", "x-evolcore-session": "forged" },
155
+ body: JSON.stringify({ messages: [{ role: "user", content: "查询管理能力" }] }),
156
+ });
157
+ strict_1.default.equal(response.status, 200);
158
+ const result = await response.json();
159
+ strict_1.default.match(result.choices[0].message.content, /授权的 AUN/);
160
+ strict_1.default.equal(modelRequests.length, 3);
161
+ }
162
+ finally {
163
+ await server.stop();
164
+ }
165
+ }
166
+ finally {
167
+ for (const id of ["aun", "personal-assistant", "target-agent"])
168
+ if (manager.get(id)?.record.status === "ready")
169
+ await manager.stop(id);
170
+ await new Promise((resolve) => modelServer.close(() => resolve()));
171
+ await (0, promises_1.rm)(state, { recursive: true, force: true });
172
+ }
173
+ });
174
+ (0, node_test_1.default)("个人助理默认白名单允许任意 AUN Peer 调用所有 Agent,显式限制优先", async () => {
175
+ const root = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "mab-assistant-defaults-"));
176
+ const pluginsDir = (0, node_path_1.join)(root, "plugins");
177
+ const stateDir = (0, node_path_1.join)(root, "state");
178
+ const desktops = ["workbuddy", "qwenwork", "doubao", "dsh", "chatgpt"];
179
+ const manager = new plugin_manager_1.PluginManager({ pluginsDir, stateDir });
180
+ try {
181
+ await (0, promises_1.mkdir)(pluginsDir, { recursive: true });
182
+ await (0, promises_1.cp)((0, node_path_1.join)(process.cwd(), "plugins", "personal-assistant"), (0, node_path_1.join)(pluginsDir, "personal-assistant"), { recursive: true });
183
+ await (0, promises_1.symlink)((0, node_path_1.resolve)(process.cwd(), "node_modules"), (0, node_path_1.join)(root, "node_modules"), "dir");
184
+ const addPlugin = async (id) => {
185
+ const dir = (0, node_path_1.join)(pluginsDir, id);
186
+ await (0, promises_1.mkdir)(dir);
187
+ await (0, promises_1.writeFile)((0, node_path_1.join)(dir, "plugin.json"), JSON.stringify({ id, version: "1.0.0", type: id === "aun" ? "channel" : "agent", entry: "index.js", apiVersion: "1", capabilities: id === "aun" ? ["channel"] : ["chat"] }));
188
+ await (0, promises_1.writeFile)((0, node_path_1.join)(dir, "index.js"), "module.exports=class{async activate(c){this.ingress=c.ingress}async deactivate(){}async health(){return {status:'ready'}}async handle(r){return {text:'目标已处理:'+r.task}}async publish(m){return this.ingress.publish(m)}};");
189
+ };
190
+ for (const id of [...desktops, "codex-cli", "aun"])
191
+ await addPlugin(id);
192
+ await manager.discover();
193
+ strict_1.default.deepEqual((await manager.config("personal-assistant")).allowedPeers, []);
194
+ strict_1.default.deepEqual((await manager.config("personal-assistant")).allowedAgents, []);
195
+ await manager.start("personal-assistant");
196
+ strict_1.default.equal((await manager.health("personal-assistant")).status, "ready");
197
+ for (const id of [...desktops, "codex-cli"]) {
198
+ await manager.saveConfig(id, { executablePath: process.execPath });
199
+ await manager.start(id);
200
+ }
201
+ await manager.start("aun");
202
+ const channel = manager.get("aun").instance;
203
+ const send = async (peerId, id) => {
204
+ let reply = "";
205
+ await channel.publish({ channel: "aun", peerId, agentPlugin: "personal-assistant", text: `/assistant agent call ${id} 默认测试`, reply: async (text) => { reply = text; } });
206
+ return reply;
207
+ };
208
+ for (const id of desktops)
209
+ strict_1.default.equal(await send(`${id}.agentid.cn`, id), "目标已处理:默认测试");
210
+ strict_1.default.equal(await send("any.agentid.cn", "codex-cli"), "目标已处理:默认测试");
211
+ await addPlugin("new-agent");
212
+ await manager.discover();
213
+ await manager.start("new-agent");
214
+ strict_1.default.equal(await send("newpeer.agentid.cn", "new-agent"), "目标已处理:默认测试");
215
+ await manager.saveConfig("personal-assistant", { allowedPeers: ["owner.agentid.cn"], allowedAgents: ["workbuddy"] });
216
+ strict_1.default.match(await send("any.agentid.cn", "workbuddy"), /授权的 AUN/);
217
+ strict_1.default.equal(await send("owner.agentid.cn", "workbuddy"), "目标已处理:默认测试");
218
+ strict_1.default.match(await send("owner.agentid.cn", "dsh"), /白名单/);
219
+ await manager.saveConfig("personal-assistant", { allowedPeers: [], allowedAgents: [] });
220
+ strict_1.default.equal(await send("owner.agentid.cn", "workbuddy"), "目标已处理:默认测试");
221
+ strict_1.default.equal(await send("new-peer.agentid.cn", "dsh"), "目标已处理:默认测试");
222
+ strict_1.default.deepEqual((await manager.config("personal-assistant")).allowedPeers, []);
223
+ strict_1.default.deepEqual((await manager.config("personal-assistant")).allowedAgents, []);
224
+ }
225
+ finally {
226
+ for (const record of manager.list())
227
+ if (manager.get(record.id)?.instance)
228
+ await manager.stop(record.id);
229
+ await manager.logs.flush();
230
+ await (0, promises_1.rm)(root, { recursive: true, force: true });
231
+ }
232
+ });
51
233
  (0, node_test_1.default)("model manifests keep the platform defaults and explicit doubao degraded adapter", async () => {
52
234
  strict_1.default.equal(qwenwork_1.qwenworkManifest.defaults.cdpPort, 9228);
53
235
  strict_1.default.equal(qwenwork_1.qwenworkManifest.defaults.httpPort, 17893);
@@ -18,11 +18,21 @@ const plugin_manifest_1 = require("../src-ts/plugin-manifest");
18
18
  const name = decodeURIComponent(url.split("/").pop());
19
19
  return { "dist-tags": { latest: name === "agent-bridge-workbuddy" ? "1.2.0" : "1.0.0" }, versions: { [name === "agent-bridge-workbuddy" ? "1.2.0" : "1.0.0"]: { agentBridge: name === "agent-bridge-fake" ? undefined : { plugin: "./plugin.json", type: name === "agent-bridge-aun" ? "channel" : "agent" } } } };
20
20
  };
21
- strict_1.default.deepEqual((await (0, plugin_catalog_1.searchPluginCatalog)("", get)).map(({ name, type }) => [name, type]), [
22
- ["agent-bridge-workbuddy", "agent"], ["agent-bridge-aun", "channel"],
21
+ strict_1.default.deepEqual((await (0, plugin_catalog_1.searchPluginCatalog)("", get)).map(({ name, id, type }) => [name, id, type]), [
22
+ ["agent-bridge-workbuddy", "workbuddy", "agent"], ["agent-bridge-aun", "aun", "channel"],
23
23
  ]);
24
24
  strict_1.default.deepEqual((await (0, plugin_catalog_1.searchPluginCatalog)("aun", get)).map(({ name }) => name), ["agent-bridge-aun"]);
25
25
  });
26
+ (0, node_test_1.default)("远程目录优先返回显式插件 ID 并过滤无效声明", async () => {
27
+ const declarations = new Map([["agent-bridge-pa", "personal-assistant"], ["agent-bridge-empty", ""], ["agent-bridge-null", null], ["agent-bridge-number", 12], ["agent-bridge-invalid", "../pa"]]);
28
+ const get = async (url) => {
29
+ if (url.includes("/-/v1/search"))
30
+ return { objects: [...declarations.keys()].map(name => ({ package: { name } })) };
31
+ const name = decodeURIComponent(url.split("/").pop());
32
+ return { "dist-tags": { latest: "1.0.0" }, versions: { "1.0.0": { agentBridge: { id: declarations.get(name), plugin: "./plugin.json", type: "agent" } } } };
33
+ };
34
+ strict_1.default.deepEqual(await (0, plugin_catalog_1.searchPluginCatalog)("", get), [{ name: "agent-bridge-pa", id: "personal-assistant", version: "1.0.0", description: "", type: "agent" }]);
35
+ });
26
36
  (0, node_test_1.default)("插件清单类型从能力兼容识别,冲突类型拒绝", () => {
27
37
  const base = { id: "sample", version: "1.0.0", entry: "index.js", apiVersion: "1", capabilities: ["chat"] };
28
38
  strict_1.default.equal((0, plugin_manifest_1.validateManifest)(base).type, "agent");