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
@@ -16,7 +16,7 @@ const KNOWN_EVENTS = new Set([
16
16
  "agent-preset/selected", "agent/inbox/spliced", "approval/asked", "approval/decided", "approval/policy", "assistant/attempt", "assistant/message",
17
17
  "command/done", "command/run", "compaction/end", "compaction/prune", "compaction/start", "compaction/summary", "deliverables/presented",
18
18
  "developer/message", "feedback/message-delete", "feedback/message-put", "feedback/record", "goal/change", "hook/invoked", "hook/result",
19
- "image/offload", "llm/retry", "llm/retry-started", "model/selection", "permission/preset", "plan/mode", "request/context", "request/header",
19
+ "image/offload", "job/registered", "job/settled", "llm/retry", "llm/retry-started", "model/selection", "permission/preset", "plan/mode", "request/context", "request/header",
20
20
  "sandbox/mode", "schedule/change", "session-log-deepseek/delivery-accepted", "session/end-seed", "session/title", "session/title-llm-request",
21
21
  "step/end", "step/start", "subagent/catalog", "subagent/descriptor", "subagent/model-selection-policy", "system/message", "team/member",
22
22
  "team/message/delivered", "team/message/queued", "team/task", "todo/write", "tool-workflow/agent-end", "tool-workflow/agent-start",
@@ -134,6 +134,21 @@ class DshSessionHistoryProvider {
134
134
  readAt: new Date().toISOString(),
135
135
  };
136
136
  }
137
+ async readDeliveryState(sessionId) {
138
+ if (typeof sessionId !== "string" || !sessionId.trim() || sessionId.length > 512)
139
+ throw new Error("DSH 会话标识无效");
140
+ const root = await this.realRoot();
141
+ if (typeof root !== "string")
142
+ throw new Error(root.reason);
143
+ const discovered = await this.discover(root);
144
+ const entry = discovered.entries.find(item => item.id === sessionId);
145
+ if (!entry)
146
+ throw new Error("DSH 会话尚无可读取的持久化日志");
147
+ const parsed = await this.readEntry(root, entry);
148
+ if (!parsed.complete || !parsed.cwd)
149
+ throw new Error(parsed.reasons.join(";") || "DSH 会话工作目录无法验证");
150
+ return { cwd: parsed.cwd, sequence: parsed.sequence, presented: parsed.presented };
151
+ }
137
152
  async realRoot() {
138
153
  try {
139
154
  const resolved = await (0, promises_1.realpath)(this.root);
@@ -251,7 +266,7 @@ class DshSessionHistoryProvider {
251
266
  }
252
267
  async readEntry(root, entry) {
253
268
  const reasons = [];
254
- const fail = (reason) => ({ session: { id: entry.id, title: entry.id }, turns: [], complete: false, reasons: [...new Set([...reasons, reason])] });
269
+ const fail = (reason) => ({ session: { id: entry.id, title: entry.id }, turns: [], complete: false, reasons: [...new Set([...reasons, reason])], sequence: -1, presented: [] });
255
270
  try {
256
271
  if (!await this.inside(root, entry.path))
257
272
  return fail("DSH 会话日志路径越界或为符号链接");
@@ -285,7 +300,9 @@ class DshSessionHistoryProvider {
285
300
  if (header.type !== "session" || header.version !== 4 || header.id !== entry.id || !validTime(header.createdAt) || typeof header.isSeeded !== "boolean" || !Number.isSafeInteger(header.delegationDepth) || header.delegationDepth < 0)
286
301
  return fail("DSH 会话头格式或身份无法验证");
287
302
  const turns = [];
303
+ const presented = [];
288
304
  let complete = true;
305
+ let sequence = -1;
289
306
  for (let index = 1; index < rows.length; index++) {
290
307
  let event;
291
308
  try {
@@ -296,11 +313,22 @@ class DshSessionHistoryProvider {
296
313
  }
297
314
  if (!event || event.seq !== index - 1 || typeof event.type !== "string" || !validTime(event.time) || typeof event.data !== "object" || event.data === null)
298
315
  return fail("DSH 会话事件序号、时间或结构无法验证");
316
+ sequence = event.seq;
299
317
  if (!KNOWN_EVENTS.has(event.type) && event.ignorable !== true) {
300
318
  complete = false;
301
319
  reasons.push(`存在未知且不可安全忽略的 DSH 事件:${event.type}`);
302
320
  continue;
303
321
  }
322
+ if (event.type === "deliverables/presented") {
323
+ const files = event.data.files;
324
+ if (!Array.isArray(files) || files.some((file) => !file || typeof file.path !== "string" || !file.path.trim())) {
325
+ complete = false;
326
+ reasons.push("DSH present 事件缺少有效文件路径");
327
+ continue;
328
+ }
329
+ presented.push({ sequence, paths: files.map((file) => file.path) });
330
+ continue;
331
+ }
304
332
  if (event.type !== "user/message" && event.type !== "assistant/message")
305
333
  continue;
306
334
  const declaredRole = event.type === "user/message" ? event.data.role : event.data.message?.role;
@@ -335,7 +363,7 @@ class DshSessionHistoryProvider {
335
363
  if (message)
336
364
  turns.push({ id: `${entry.id}:${event.seq}`, role: event.type === "user/message" ? "user" : "assistant", text: message, time: new Date(event.time).toISOString() });
337
365
  }
338
- return { session: { id: entry.id, title: entry.id, updatedAt: new Date(before.mtimeMs).toISOString() }, turns, complete, reasons: [...new Set(reasons)] };
366
+ return { session: { id: entry.id, title: entry.id, updatedAt: new Date(before.mtimeMs).toISOString() }, turns, complete, reasons: [...new Set(reasons)], ...(typeof header.cwd === "string" ? { cwd: header.cwd } : {}), sequence, presented };
339
367
  }
340
368
  catch (error) {
341
369
  return fail(error instanceof Error && /maximum output length|larger than/.test(error.message) ? "DSH 解压日志超过读取上限" : "DSH 会话日志无法按官方 v4 格式完整解析");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-bridge-dsh",
3
- "version": "1.0.11",
3
+ "version": "1.0.15",
4
4
  "description": "agent-bridge 的 DeepSeek Harness 插件,支持后台定时自动升级验证。",
5
5
  "keywords": [
6
6
  "mu-agent-bridge-plugin",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh",
3
- "version": "1.0.11",
3
+ "version": "1.0.15",
4
4
  "type": "agent",
5
5
  "displayName": "DeepSeek Harness",
6
6
  "entry": "dist/src-ts/plugins/dsh/index.js",
@@ -8,7 +8,8 @@
8
8
  "process": "in-process",
9
9
  "capabilities": [
10
10
  "chat",
11
- "health"
11
+ "health",
12
+ "model-provider"
12
13
  ],
13
14
  "configSchema": "config.schema.json"
14
15
  }
@@ -1,7 +1,42 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AgentOperationError = exports.AgentError = void 0;
4
+ exports.abortable = abortable;
4
5
  exports.errorDetails = errorDetails;
6
+ async function abortable(promise, signal) {
7
+ if (!signal)
8
+ return promise;
9
+ if (signal.aborted) {
10
+ // promise 已在调用方启动,先观察其拒绝,避免预取消时产生未处理拒绝。
11
+ void promise.catch(() => undefined);
12
+ signal.throwIfAborted();
13
+ }
14
+ return new Promise((resolve, reject) => {
15
+ let settled = false;
16
+ const cleanup = () => signal.removeEventListener("abort", abort);
17
+ const abort = () => {
18
+ if (settled)
19
+ return;
20
+ settled = true;
21
+ cleanup();
22
+ reject(signal.reason);
23
+ };
24
+ signal.addEventListener("abort", abort, { once: true });
25
+ promise.then((value) => {
26
+ if (settled)
27
+ return;
28
+ settled = true;
29
+ cleanup();
30
+ resolve(value);
31
+ }, (error) => {
32
+ if (settled)
33
+ return;
34
+ settled = true;
35
+ cleanup();
36
+ reject(error);
37
+ });
38
+ });
39
+ }
5
40
  class AgentError extends Error {
6
41
  constructor(message, options) {
7
42
  super(message, options);
@@ -5,7 +5,7 @@ const promises_1 = require("node:fs/promises");
5
5
  const node_path_1 = require("node:path");
6
6
  const qrcode_1 = require("qrcode");
7
7
  const client_1 = require("./client");
8
- const manifest = { id: "feishu", version: "1.0.7", type: "channel", displayName: "飞书通道", entry: "dist/src-ts/plugins/feishu/index.js", apiVersion: "1", process: "in-process", capabilities: ["channel", "channel.bot.setup", "channel.receive", "channel.send", "health", "cli"], configSchema: "config.schema.json", managementPage: "/abweb/channels/feishu" };
8
+ const manifest = { id: "feishu", version: "1.0.8", type: "channel", displayName: "飞书通道", entry: "dist/src-ts/plugins/feishu/index.js", apiVersion: "1", process: "in-process", capabilities: ["channel", "channel.bot.setup", "channel.receive", "channel.send", "health", "cli"], configSchema: "config.schema.json", managementPage: "/abweb/channels/feishu" };
9
9
  const newSessionCommand = /^\/new(?:[ \t]+[^\r\n]+)?$/;
10
10
  const commands = [
11
11
  { name: "status", summary: "查看飞书通道状态", usage: "mab feishu status" },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-bridge-feishu",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "agent-bridge 的飞书通道插件。",
5
5
  "keywords": [
6
6
  "mu-agent-bridge-plugin",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "feishu",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "type": "channel",
5
5
  "displayName": "飞书通道",
6
6
  "entry": "dist/src-ts/plugins/feishu/index.js",
@@ -0,0 +1,23 @@
1
+ {
2
+ "type": "object",
3
+ "default": { "allowedPeers": [], "allowedAgents": [] },
4
+ "properties": {
5
+ "modelProvider": { "type": "string", "enum": ["openai", "claude-cli", "plugin"], "default": "openai", "description": "模型来源;plugin 使用已安装插件的当前模型" },
6
+ "modelPlugin": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,63}$", "description": "模型来源插件 ID" },
7
+ "endpoint": { "type": "string", "minLength": 1, "maxLength": 2048, "pattern": "^https?://[^\\s]+/chat/completions$", "description": "OpenAI 兼容 chat/completions 完整地址" },
8
+ "aid": { "type": "string", "maxLength": 256, "pattern": "^(?:[A-Za-z0-9][A-Za-z0-9._-]+)?$", "description": "绑定到个人助理的 AUN AID,由核心在绑定时维护;空字符串表示解绑" },
9
+ "model": { "type": "string", "minLength": 1, "maxLength": 256, "description": "模型名称" },
10
+ "apiKey": { "type": "string", "minLength": 1, "maxLength": 4096, "secret": true, "writeOnly": true, "description": "模型服务密钥,仅保存在本机配置中" },
11
+ "allowedPeers": { "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^(?:\\*|[A-Za-z0-9][A-Za-z0-9._-]{2,255})$" }, "default": [], "description": "留空接受所有 AUN Peer;填写具体 AID 后限制来源" },
12
+ "allowedAgents": { "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^(?:\\*|[a-z0-9][a-z0-9-]{0,63})$" }, "default": [], "description": "留空允许调用所有已安装且就绪的普通 Agent;填写具体插件 ID 后限制目标" },
13
+ "timeoutMs": { "type": "integer", "minimum": 1000, "maximum": 120000, "default": 120000, "description": "单次模型请求最长时间(毫秒)" },
14
+ "ecPath": { "type": "string", "minLength": 1, "maxLength": 2048, "description": "EvolCore ec 命令路径,默认使用 PATH 中的 ec" },
15
+ "selfAid": { "type": "string", "maxLength": 256, "pattern": "^(?:[A-Za-z0-9][A-Za-z0-9._-]+)?$", "description": "个人助理自身的 AUN AID;未配置时关闭 Ability 和协调能力" },
16
+ "abilityProviders": { "type": "array", "uniqueItems": true, "items": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{2,255}$" }, "default": [], "description": "允许读取与调用只读 Ability 的 Provider AID 白名单" },
17
+ "ownerAid": { "type": "string", "maxLength": 256, "pattern": "^(?:[A-Za-z0-9][A-Za-z0-9._-]+)?$", "description": "Owner 共享上下文的固定来源 AID" },
18
+ "ownerContextPath": { "type": "string", "maxLength": 2048, "pattern": "^/[^\\\\]*$", "description": "Owner AUN FS 中固定的规范绝对路径" },
19
+ "ownerContextTtlMs": { "type": "integer", "minimum": 1000, "maximum": 300000, "default": 60000, "description": "Owner 共享上下文缓存有效期(毫秒)" }
20
+ },
21
+ "required": ["allowedPeers", "allowedAgents"],
22
+ "additionalProperties": false
23
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentOperationError = exports.AgentError = void 0;
4
+ exports.abortable = abortable;
5
+ exports.errorDetails = errorDetails;
6
+ async function abortable(promise, signal) {
7
+ if (!signal)
8
+ return promise;
9
+ if (signal.aborted) {
10
+ // promise 已在调用方启动,先观察其拒绝,避免预取消时产生未处理拒绝。
11
+ void promise.catch(() => undefined);
12
+ signal.throwIfAborted();
13
+ }
14
+ return new Promise((resolve, reject) => {
15
+ let settled = false;
16
+ const cleanup = () => signal.removeEventListener("abort", abort);
17
+ const abort = () => {
18
+ if (settled)
19
+ return;
20
+ settled = true;
21
+ cleanup();
22
+ reject(signal.reason);
23
+ };
24
+ signal.addEventListener("abort", abort, { once: true });
25
+ promise.then((value) => {
26
+ if (settled)
27
+ return;
28
+ settled = true;
29
+ cleanup();
30
+ resolve(value);
31
+ }, (error) => {
32
+ if (settled)
33
+ return;
34
+ settled = true;
35
+ cleanup();
36
+ reject(error);
37
+ });
38
+ });
39
+ }
40
+ class AgentError extends Error {
41
+ constructor(message, options) {
42
+ super(message, options);
43
+ this.name = "AgentError";
44
+ }
45
+ }
46
+ exports.AgentError = AgentError;
47
+ /** 保留底层错误码,避免只留下 fetch failed 或超时这类表层提示。 */
48
+ function errorDetails(error) {
49
+ const parts = [];
50
+ const seen = new Set();
51
+ for (let current = error; current && !seen.has(current) && seen.size < 5;) {
52
+ seen.add(current);
53
+ const value = current;
54
+ const message = typeof value.message === "string" ? value.message : String(current);
55
+ parts.push(`${message}${value.code ? `(${String(value.code)})` : ""}`);
56
+ current = value.cause;
57
+ }
58
+ return parts.join(";原因:") || String(error);
59
+ }
60
+ class AgentOperationError extends AgentError {
61
+ code;
62
+ stage;
63
+ constructor(code, stage, cause) {
64
+ super(`${code}:${stage}失败:${errorDetails(cause)}`, { cause });
65
+ this.code = code;
66
+ this.stage = stage;
67
+ }
68
+ }
69
+ exports.AgentOperationError = AgentOperationError;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_TOTAL_ATTACHMENT_BYTES = exports.MAX_ATTACHMENTS = exports.MAX_ATTACHMENT_BYTES = void 0;
4
+ exports.detectImageContentType = detectImageContentType;
5
+ exports.attachmentFilename = attachmentFilename;
6
+ exports.validateAttachment = validateAttachment;
7
+ exports.validateAttachments = validateAttachments;
8
+ exports.asAttachments = asAttachments;
9
+ exports.MAX_ATTACHMENT_BYTES = 32 * 1024 * 1024;
10
+ exports.MAX_ATTACHMENTS = 8;
11
+ exports.MAX_TOTAL_ATTACHMENT_BYTES = 64 * 1024 * 1024;
12
+ function detectImageContentType(data) {
13
+ if (data.length >= 8 && data.slice(0, 8).every((value, index) => value === [137, 80, 78, 71, 13, 10, 26, 10][index]))
14
+ return "image/png";
15
+ if (data.length >= 3 && data[0] === 0xff && data[1] === 0xd8 && data[2] === 0xff)
16
+ return "image/jpeg";
17
+ if (data.length >= 12 && String.fromCharCode(...data.slice(0, 4)) === "RIFF" && String.fromCharCode(...data.slice(8, 12)) === "WEBP")
18
+ return "image/webp";
19
+ return undefined;
20
+ }
21
+ function attachmentFilename(filename) {
22
+ if (typeof filename !== "string" || /[\u0000-\u001f\u007f]/.test(filename))
23
+ throw new Error("附件文件名无效");
24
+ const name = filename.split(/[\\/]/).pop() ?? "";
25
+ if (!name.trim() || name === "." || name === "..")
26
+ throw new Error("附件文件名无效");
27
+ return name;
28
+ }
29
+ function validateAttachment(item) {
30
+ if (!item || !(item.data instanceof Uint8Array) || item.data.byteLength === 0)
31
+ throw new Error("附件内容不能为空");
32
+ if (item.data.byteLength > exports.MAX_ATTACHMENT_BYTES)
33
+ throw new Error("单个附件不能超过 32 MiB");
34
+ attachmentFilename(item.filename);
35
+ if (item.kind !== "image" && item.kind !== "file")
36
+ throw new Error("附件类型无效");
37
+ if (typeof item.contentType !== "string" || !/^[A-Za-z0-9!#$&^_.+-]+\/[A-Za-z0-9!#$&^_.+-]+$/.test(item.contentType))
38
+ throw new Error("附件 MIME 类型无效");
39
+ if (item.kind === "image") {
40
+ const detected = detectImageContentType(item.data);
41
+ if (!detected || detected !== item.contentType.toLowerCase())
42
+ throw new Error("图片内容与 MIME 类型不一致");
43
+ }
44
+ }
45
+ function validateAttachments(items) {
46
+ if (!items)
47
+ return;
48
+ if (!Array.isArray(items))
49
+ throw new Error("附件列表无效");
50
+ if (items.length > exports.MAX_ATTACHMENTS)
51
+ throw new Error("单条消息最多包含 8 个附件");
52
+ let total = 0;
53
+ for (const item of items) {
54
+ validateAttachment(item);
55
+ total += item.data.byteLength;
56
+ }
57
+ if (total > exports.MAX_TOTAL_ATTACHMENT_BYTES)
58
+ throw new Error("单条消息附件总大小不能超过 64 MiB");
59
+ }
60
+ function asAttachments(images) {
61
+ return (images ?? []).map((image) => ({ ...image, kind: "image" }));
62
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveRuntimePort = resolveRuntimePort;
4
+ function resolveRuntimePort(config, runtime, pluginId, envName, fallback) {
5
+ const injected = runtime?.ports?.[pluginId];
6
+ if (typeof injected === "number" && Number.isInteger(injected) && injected > 0)
7
+ return injected;
8
+ const configured = config.cdpPort;
9
+ if (typeof configured === "number" && Number.isInteger(configured) && configured > 0)
10
+ return configured;
11
+ const environment = Number(process.env[envName] ?? "");
12
+ return Number.isInteger(environment) && environment > 0 ? environment : fallback;
13
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.responseSchema = void 0;
4
+ exports.claudeCliCompletion = claudeCliCompletion;
5
+ const tools_1 = require("./tools");
6
+ exports.responseSchema = {
7
+ type: "object", additionalProperties: false, required: ["role", "content", "tool_calls"],
8
+ properties: {
9
+ role: { type: "string", enum: ["assistant"] },
10
+ content: { type: ["string", "null"], maxLength: 32_000 },
11
+ tool_calls: { type: "array", maxItems: 8, items: {
12
+ type: "object", additionalProperties: false, required: ["id", "type", "function"],
13
+ properties: {
14
+ id: { type: "string", minLength: 1, maxLength: 128 }, type: { type: "string", enum: ["function"] },
15
+ function: { type: "object", additionalProperties: false, required: ["name", "arguments"], properties: {
16
+ name: { type: "string", enum: [...tools_1.TOOL_NAMES] }, arguments: { type: "string", maxLength: 64_000 },
17
+ } },
18
+ },
19
+ } },
20
+ },
21
+ };
22
+ function claudeCliCompletion(callPlugin, timeoutMs) {
23
+ return async (messages, signal) => {
24
+ const response = await callPlugin("claude-cli", {
25
+ task: JSON.stringify({ instructions: "你是个人助理的模型推理器。按照 messages 中的系统要求处理最后一条用户消息;tools 仅描述宿主提供的管理工具。需要查询或执行任务时返回 tool_calls,待工具结果返回后再回答;不要编造结果。每次调用使用不同 id。最终回答时 tool_calls 为空数组。仅返回 Schema 规定的 JSON。", messages, tools: (0, tools_1.toolDefinitions)() }),
26
+ modelResponseSchema: exports.responseSchema, timeoutMs, signal,
27
+ });
28
+ return response.text;
29
+ };
30
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCoordinator = createCoordinator;
4
+ const node_child_process_1 = require("node:child_process");
5
+ const node_util_1 = require("node:util");
6
+ const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
7
+ const isAid = (value) => typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._-]{2,255}$/.test(value);
8
+ const isAgentId = (value) => typeof value === "string" && /^[a-z0-9][a-z0-9-]{0,63}$/.test(value);
9
+ const isThreadId = (value) => typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/.test(value);
10
+ function createCoordinator(options) {
11
+ if (!isAid(options.selfAid))
12
+ throw new Error("selfAid 无效");
13
+ const allowed = new Map();
14
+ for (const agent of options.allowedAgents) {
15
+ if (!isAgentId(agent.id) || !Array.isArray(agent.aids) || agent.aids.some((aid) => !isAid(aid)))
16
+ throw new Error("Agent 白名单无效");
17
+ allowed.set(agent.id, new Set(agent.aids));
18
+ }
19
+ const run = options.execFile ?? (async (file, args) => execFileAsync(file, args, { timeout: 30_000, maxBuffer: 1024 * 1024, encoding: "utf8", windowsHide: true }));
20
+ const command = async (args) => {
21
+ const { stdout } = await run(options.ecPath ?? "ec", args);
22
+ let value;
23
+ try {
24
+ value = JSON.parse(stdout);
25
+ }
26
+ catch {
27
+ throw new Error("EvolCore 返回了无效 JSON");
28
+ }
29
+ if (!value || typeof value !== "object" || Array.isArray(value) || value.ok === false)
30
+ throw new Error("EvolCore 命令失败");
31
+ return value;
32
+ };
33
+ return {
34
+ async dispatch({ agentId, aid, task }) {
35
+ if (!isAgentId(agentId) || !isAid(aid) || !allowed.get(agentId)?.has(aid))
36
+ throw new Error("目标 Agent/AID 不在白名单中");
37
+ if (typeof task !== "string" || !task.trim() || task.length > 20_000)
38
+ throw new Error("任务长度无效");
39
+ const thread = await command(["thread", "create", aid, "--name", `个人助理派活-${agentId}`, "--format", "json"]);
40
+ const threadId = thread.thread_id ?? thread.threadId ?? thread.id;
41
+ if (!isThreadId(threadId))
42
+ throw new Error("EvolCore 未返回有效 threadId");
43
+ await command(["msg", "send", options.selfAid, aid, "--text", task, "--thread", threadId, "--return", "required", "--format", "json"]);
44
+ return { status: "pending", agentId, aid, threadId };
45
+ },
46
+ async getStatus({ aid, threadId }) {
47
+ if (!isAid(aid))
48
+ throw new Error("AID 无效");
49
+ if (!isThreadId(threadId))
50
+ throw new Error("threadId 无效");
51
+ const history = await command(["thread", "history", threadId, "--format", "json"]);
52
+ const state = history.status ?? history.state;
53
+ const status = state === "completed" || state === "failed" || state === "cancelled" ? state : "pending";
54
+ return { status, aid, threadId, history };
55
+ },
56
+ };
57
+ }