mu-agent-bridge 1.0.73 → 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 (152) hide show
  1. package/README.md +12 -8
  2. package/dist/src-ts/cli.js +67 -37
  3. package/dist/src-ts/control-server.js +7 -28
  4. package/dist/src-ts/core-updater.js +141 -33
  5. package/dist/src-ts/daemon-process.js +2 -1
  6. package/dist/src-ts/dsh-agent.js +7 -2
  7. package/dist/src-ts/http-agent.js +36 -0
  8. package/dist/src-ts/plugin-manager.js +185 -58
  9. package/dist/src-ts/plugins/abweb/index.js +1 -1
  10. package/dist/src-ts/plugins/abweb/public/app.js +8 -6
  11. package/dist/src-ts/plugins/abweb/public/index.html +3 -3
  12. package/dist/src-ts/plugins/aun/attachments.js +3 -21
  13. package/dist/src-ts/plugins/aun/index.js +89 -11
  14. package/dist/src-ts/plugins/aun/messages.js +1 -1
  15. package/dist/src-ts/plugins/aun/public/app.js +2 -1
  16. package/dist/src-ts/plugins/aun/public/index.html +1 -1
  17. package/dist/src-ts/plugins/cdp-draft.js +5 -2
  18. package/dist/src-ts/plugins/chatgpt/index.js +3 -2
  19. package/dist/src-ts/plugins/claude-cli/index.js +1 -1
  20. package/dist/src-ts/plugins/desktop-launch.js +44 -3
  21. package/dist/src-ts/plugins/doubao/cdp-client.js +231 -45
  22. package/dist/src-ts/plugins/doubao/index.js +119 -7
  23. package/dist/src-ts/plugins/doubao/native-task.js +134 -0
  24. package/dist/src-ts/plugins/dsh/cdp-client.js +334 -0
  25. package/dist/src-ts/plugins/dsh/index.js +102 -23
  26. package/dist/src-ts/plugins/dsh/session-history.js +31 -3
  27. package/dist/src-ts/plugins/feishu/index.js +1 -1
  28. package/dist/src-ts/plugins/personal-assistant/index.js +29 -8
  29. package/dist/src-ts/plugins/personal-assistant/model-client.js +20 -6
  30. package/dist/src-ts/plugins/personal-assistant/session-memory.js +124 -0
  31. package/dist/src-ts/plugins/personal-assistant/tools.js +4 -3
  32. package/dist/src-ts/plugins/qwenwork/cdp-client.js +43 -7
  33. package/dist/src-ts/plugins/qwenwork/index.js +52 -18
  34. package/dist/src-ts/plugins/workbuddy/cdp-client.js +349 -83
  35. package/dist/src-ts/plugins/workbuddy/index.js +24 -12
  36. package/dist/src-ts/plugins/zcode/cdp-client.js +500 -0
  37. package/dist/src-ts/plugins/zcode/index.js +97 -0
  38. package/dist/src-ts/session-management.js +27 -8
  39. package/dist/src-ts/version-manager.js +6 -3
  40. package/dist/tests-ts/abweb-model-config.test.js +44 -41
  41. package/dist/tests-ts/aun-attachments.test.js +19 -17
  42. package/dist/tests-ts/aun-default-owner-page.test.js +2 -1
  43. package/dist/tests-ts/aun-messages.test.js +14 -0
  44. package/dist/tests-ts/aun-plugin.test.js +207 -19
  45. package/dist/tests-ts/bundled-package.test.js +1 -1
  46. package/dist/tests-ts/cdp-draft-recovery.test.js +182 -3
  47. package/dist/tests-ts/chatgpt-plugin.test.js +19 -0
  48. package/dist/tests-ts/control-server.test.js +20 -0
  49. package/dist/tests-ts/core-updater.test.js +215 -46
  50. package/dist/tests-ts/daemon-process.test.js +126 -1
  51. package/dist/tests-ts/desktop-launch.test.js +73 -0
  52. package/dist/tests-ts/doubao-native-task.test.js +237 -0
  53. package/dist/tests-ts/doubao-plugin.test.js +688 -19
  54. package/dist/tests-ts/dsh-agent.test.js +91 -19
  55. package/dist/tests-ts/dsh-cdp.test.js +148 -0
  56. package/dist/tests-ts/dsh-history.test.js +37 -0
  57. package/dist/tests-ts/feishu-plugin.test.js +1 -1
  58. package/dist/tests-ts/http-agent.test.js +18 -0
  59. package/dist/tests-ts/local-cli.test.js +29 -2
  60. package/dist/tests-ts/model-provider-cancellation.test.js +2 -0
  61. package/dist/tests-ts/native-session-management.test.js +8 -7
  62. package/dist/tests-ts/personal-assistant-coordination.test.js +16 -0
  63. package/dist/tests-ts/personal-assistant-extensions.test.js +7 -1
  64. package/dist/tests-ts/personal-assistant-memory.test.js +117 -0
  65. package/dist/tests-ts/personal-assistant.test.js +277 -3
  66. package/dist/tests-ts/platform-integration.test.js +60 -1
  67. package/dist/tests-ts/plugin-manager.test.js +78 -6
  68. package/dist/tests-ts/plugin-upgrade-deadline.test.js +354 -0
  69. package/dist/tests-ts/publish-packages.test.js +1 -1
  70. package/dist/tests-ts/qwenwork-plugin.test.js +30 -0
  71. package/dist/tests-ts/qwenwork-reconnect.test.js +195 -0
  72. package/dist/tests-ts/qwenwork-sse.test.js +33 -0
  73. package/dist/tests-ts/session-access-defaults.test.js +112 -0
  74. package/dist/tests-ts/session-management.test.js +8 -8
  75. package/dist/tests-ts/version-manager.test.js +40 -0
  76. package/dist/tests-ts/workbuddy-cdp-recovery.test.js +311 -0
  77. package/dist/tests-ts/workbuddy-plugin.test.js +356 -13
  78. package/dist/tests-ts/zcode-cdp.test.js +894 -0
  79. package/dist/tests-ts/zcode-plugin.test.js +396 -0
  80. package/package.json +1 -1
  81. package/plugins/abweb/dist/src-ts/plugins/abweb/index.js +1 -1
  82. package/plugins/abweb/dist/src-ts/plugins/abweb/public/app.js +8 -6
  83. package/plugins/abweb/dist/src-ts/plugins/abweb/public/app.ts +7 -5
  84. package/plugins/abweb/dist/src-ts/plugins/abweb/public/index.html +3 -3
  85. package/plugins/abweb/package.json +1 -1
  86. package/plugins/abweb/plugin.json +1 -1
  87. package/plugins/aun/config.schema.json +1 -1
  88. package/plugins/aun/dist/src-ts/plugins/aun/attachments.js +3 -21
  89. package/plugins/aun/dist/src-ts/plugins/aun/index.js +89 -11
  90. package/plugins/aun/dist/src-ts/plugins/aun/messages.js +1 -1
  91. package/plugins/aun/dist/src-ts/plugins/aun/public/app.js +2 -1
  92. package/plugins/aun/dist/src-ts/plugins/aun/public/index.html +1 -1
  93. package/plugins/aun/package.json +1 -1
  94. package/plugins/aun/plugin.json +1 -1
  95. package/plugins/chatgpt/dist/src-ts/plugins/cdp-draft.js +5 -2
  96. package/plugins/chatgpt/dist/src-ts/plugins/chatgpt/index.js +3 -2
  97. package/plugins/chatgpt/dist/src-ts/plugins/desktop-launch.js +44 -3
  98. package/plugins/claude-cli/dist/src-ts/plugins/claude-cli/index.js +1 -1
  99. package/plugins/claude-cli/package.json +1 -1
  100. package/plugins/claude-cli/plugin.json +1 -1
  101. package/plugins/doubao/config.schema.json +2 -1
  102. package/plugins/doubao/dist/src-ts/plugins/desktop-launch.js +44 -3
  103. package/plugins/doubao/dist/src-ts/plugins/doubao/cdp-client.js +231 -45
  104. package/plugins/doubao/dist/src-ts/plugins/doubao/index.js +119 -7
  105. package/plugins/doubao/dist/src-ts/plugins/doubao/native-task.js +134 -0
  106. package/plugins/doubao/package.json +1 -1
  107. package/plugins/doubao/plugin.json +1 -1
  108. package/plugins/dsh/config.schema.json +5 -2
  109. package/plugins/dsh/dist/src-ts/dsh-agent.js +7 -2
  110. package/plugins/dsh/dist/src-ts/plugins/desktop-launch.js +44 -3
  111. package/plugins/dsh/dist/src-ts/plugins/dsh/cdp-client.js +334 -0
  112. package/plugins/dsh/dist/src-ts/plugins/dsh/index.js +102 -23
  113. package/plugins/dsh/dist/src-ts/plugins/dsh/session-history.js +31 -3
  114. package/plugins/dsh/package.json +1 -1
  115. package/plugins/dsh/plugin.json +1 -1
  116. package/plugins/feishu/dist/src-ts/plugins/feishu/index.js +1 -1
  117. package/plugins/feishu/package.json +1 -1
  118. package/plugins/feishu/plugin.json +1 -1
  119. package/plugins/personal-assistant/config.schema.json +3 -2
  120. package/plugins/personal-assistant/dist/src-ts/attachments.js +62 -0
  121. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/index.js +29 -8
  122. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/model-client.js +20 -6
  123. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/session-memory.js +124 -0
  124. package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/tools.js +4 -3
  125. package/plugins/personal-assistant/package.json +2 -2
  126. package/plugins/personal-assistant/plugin.json +1 -1
  127. package/plugins/qwenwork/dist/src-ts/plugins/cdp-draft.js +5 -2
  128. package/plugins/qwenwork/dist/src-ts/plugins/desktop-launch.js +44 -3
  129. package/plugins/qwenwork/dist/src-ts/plugins/qwenwork/cdp-client.js +43 -7
  130. package/plugins/qwenwork/dist/src-ts/plugins/qwenwork/index.js +52 -18
  131. package/plugins/qwenwork/package.json +1 -1
  132. package/plugins/qwenwork/plugin.json +1 -1
  133. package/plugins/workbuddy/config.schema.json +1 -1
  134. package/plugins/workbuddy/dist/src-ts/plugins/desktop-launch.js +44 -3
  135. package/plugins/workbuddy/dist/src-ts/plugins/workbuddy/cdp-client.js +349 -83
  136. package/plugins/workbuddy/dist/src-ts/plugins/workbuddy/index.js +24 -12
  137. package/plugins/workbuddy/package.json +1 -1
  138. package/plugins/workbuddy/plugin.json +1 -1
  139. package/plugins/zcode/config.schema.json +13 -0
  140. package/plugins/zcode/dist/src-ts/agent.js +69 -0
  141. package/plugins/zcode/dist/src-ts/attachments.js +62 -0
  142. package/plugins/zcode/dist/src-ts/plugin.js +13 -0
  143. package/plugins/zcode/dist/src-ts/plugins/desktop-launch.js +238 -0
  144. package/plugins/zcode/dist/src-ts/plugins/workbuddy/cdp-client.js +896 -0
  145. package/plugins/zcode/dist/src-ts/plugins/workbuddy/cli-client.js +39 -0
  146. package/plugins/zcode/dist/src-ts/plugins/workbuddy/desktop-launch.js +10 -0
  147. package/plugins/zcode/dist/src-ts/plugins/workbuddy/index.js +567 -0
  148. package/plugins/zcode/dist/src-ts/plugins/workbuddy/session-history.js +121 -0
  149. package/plugins/zcode/dist/src-ts/plugins/zcode/cdp-client.js +500 -0
  150. package/plugins/zcode/dist/src-ts/plugins/zcode/index.js +97 -0
  151. package/plugins/zcode/package.json +16 -0
  152. package/plugins/zcode/plugin.json +11 -0
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = __importDefault(require("node:test"));
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const node_vm_1 = require("node:vm");
9
+ const cdp_client_1 = require("../src-ts/plugins/doubao/cdp-client");
10
+ function nativePage(options = {}) {
11
+ const sent = [];
12
+ const modules = {
13
+ enums: { AgentMode: { MOA: 17, Chat: 21 } },
14
+ environment: { sandboxEnvironmentController: { query: async () => ({ isReady: options.ready !== false, environmentId: "native-env" }) } },
15
+ task: { GeneralAgentRuntimeType: { LocalPC: 27 }, buildGeneralAgentCompletionTaskParam: async (chatId) => ({ sandbox_id: "native-env", workspace: `workspace:${chatId}`, client_env_id: "native-client" }) },
16
+ store: { get: function get() { /* it is async store */ return { getState: () => ({ modeSelectConfigs: { menu_item_list: options.mode === false ? [] : [{ agent_mode: 17, menu_type: 9, model_item_key: "native-model", default_mode: "native-mode" }] } }) }; } },
17
+ auth: { snapshot: () => options.authorization === false ? undefined : ({ mode: "ask-risky", sandboxAuthType: 41 }) },
18
+ modify: { build: async (value) => ({ agent_task_param: { runtime_type: value.runtimeType, workspace: value.completionTaskParam.workspace, sandbox_auth_type: value.sandboxAuthType }, need_modify_conversation: true }) },
19
+ connector: { getFeishuConnectorEnabledForConversation: async () => ({ enabled: true, id: "native-lark" }) },
20
+ connectorInfo: { build: function build(enabled, id) { return { connector_id: id, switch: enabled ? 2 : 1, connector_vendor: 2 }; } },
21
+ message: { createSendMessage: (value) => ({ ...value.message, ...value.conversationContext, local_message_id: value.message.unique_id }) },
22
+ service: { get: async function get() {
23
+ return { getMessageService: async () => ({ sendMessage(value) {
24
+ sent.push(value);
25
+ return { cancel() { }, subscribe: () => options.messages ? options.messages(value) : (async function* () {
26
+ yield { ...value.messages[0], message_id: "question", conversation_id: "real-conversation" };
27
+ yield { message_id: "answer", conversation_id: "real-conversation", reply_id: "question", content_blocks_v2: [{ content: { text_block: { text: "命令已执行" } } }], ...(options.failure ? { error_details: { has_error: true, error_msg: "执行失败" } } : {}) };
28
+ })() };
29
+ }, fetchAndUpdateMessageList: async (request) => {
30
+ strict_1.default.equal(typeof request.conversationId, "string");
31
+ strict_1.default.equal(request.options.limit, 50);
32
+ return { messages: options.historyMessages || [] };
33
+ } }) };
34
+ } },
35
+ };
36
+ const markers = {
37
+ enums: "AgentMode:()=>", environment: "sandboxEnvironmentController:()=>", task: "buildGeneralAgentCompletionTaskParam:()=>", store: "chat-ioc-manager: cannot bind empty store", auth: "new WeakMap sandboxAuthType:", modify: "general_agent_conversation_modify_params", connector: "getFeishuConnectorEnabledForConversation:()=>", connectorInfo: "connector_info_list connector_vendor wrapped:!0", message: "createSendMessage:()=>", service: "chat-ioc-manager: cannot bind empty service",
38
+ };
39
+ const factories = Object.fromEntries(Object.keys(modules).map(id => {
40
+ const factory = () => { };
41
+ factory.toString = () => markers[id];
42
+ return [id, factory];
43
+ }));
44
+ const chunks = [[[], factories]];
45
+ chunks.push = (chunk) => { chunk[2]((id) => modules[id]); return 1; };
46
+ const window = { "@flow-web/desktop:stable": chunks };
47
+ return { sent, window };
48
+ }
49
+ (0, node_test_1.default)("豆包客户端默认使用本地电脑,纯聊天需要显式选择", () => {
50
+ strict_1.default.equal(new cdp_client_1.DoubaoCdpClient().options.mode, "local-computer");
51
+ strict_1.default.equal(new cdp_client_1.DoubaoCdpClient({ mode: "chat" }).options.mode, "chat");
52
+ });
53
+ (0, node_test_1.default)("豆包本地电脑生成图片持续输出时可跨过三分钟等待并返回图片附件", async (t) => {
54
+ t.mock.timers.enable({ apis: ["setTimeout", "Date"] });
55
+ const imageUrl = "https://p1-flow-imagex-sign.byteimg.com/long-image.png";
56
+ const png = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jL1sAAAAASUVORK5CYII=", "base64");
57
+ const page = nativePage({ messages: async function* (value) {
58
+ yield { ...value.messages[0], message_id: "question", conversation_id: "123" };
59
+ for (let i = 1; i <= 4; i++) {
60
+ await new Promise(resolve => setTimeout(resolve, 60_000));
61
+ yield { message_id: "answer", conversation_id: "123", content_blocks_v2: [{ content: { text_block: { text: `正在生成第 ${i} 步` } } }] };
62
+ }
63
+ yield { message_id: "answer", conversation_id: "123", content_blocks_v2: [
64
+ { content: { text_block: { text: "图片已生成" } } },
65
+ { block_type: 10084, is_finish: true, content: { rich_media_layout_block: { media: [{ type: 6, creation: { type: 1, image: { status: 2, image_ori: { url: imageUrl } } } }] } } },
66
+ ] };
67
+ } });
68
+ const client = new cdp_client_1.DoubaoCdpClient({ fetchImpl: async (input) => {
69
+ strict_1.default.equal(String(input), imageUrl);
70
+ return new Response(png, { headers: { "content-type": "image/png" } });
71
+ } });
72
+ client.connect = async () => { };
73
+ client.evaluate = async (expression) => (0, node_vm_1.runInNewContext)(expression, { window: page.window, Map, Set, JSON, Date, Error, AbortController, URL, performance: { getEntriesByType: () => [] }, navigator: { userAgent: "" } });
74
+ const running = client.complete("生成图片", undefined, undefined, "");
75
+ void running.catch(() => undefined);
76
+ for (let i = 0; i < 242; i++) {
77
+ await new Promise(setImmediate);
78
+ t.mock.timers.tick(1_000);
79
+ }
80
+ const result = await running;
81
+ strict_1.default.equal(result.text, "图片已生成");
82
+ strict_1.default.equal(result.images.length, 1);
83
+ strict_1.default.deepEqual(Buffer.from(result.images[0].data), png);
84
+ strict_1.default.equal(page.sent.length, 1, "持续等待不能重新提交生成任务");
85
+ });
86
+ function start(page, conversationId) {
87
+ (0, node_vm_1.runInNewContext)((0, cdp_client_1.buildLocalComputerInjection)((0, cdp_client_1.requestBody)("请执行命令", conversationId, "bot", ["feishu"], [], "local-computer")), { window: page.window, Map, Set, JSON, Date, Error, AbortController, URL, performance: { getEntriesByType: () => [] }, navigator: { userAgent: "" } });
88
+ }
89
+ async function execute(page, conversationId = "peer-conversation") {
90
+ start(page, conversationId);
91
+ for (let i = 0; i < 100 && !page.window.__mab_doubao_result; i++)
92
+ await new Promise(resolve => setImmediate(resolve));
93
+ strict_1.default.ok(page.window.__mab_doubao_result, "原生任务必须结束并返回结果");
94
+ return JSON.parse(page.window.__mab_doubao_result);
95
+ }
96
+ (0, node_test_1.default)("豆包本地电脑请求使用原生模式、工作区、授权和伙伴,并通过原生发送链返回结果", async () => {
97
+ const page = nativePage();
98
+ const result = await execute(page);
99
+ strict_1.default.equal(result.ok, true);
100
+ strict_1.default.equal(result.reply, "命令已执行");
101
+ strict_1.default.equal(result.conversationId, "real-conversation");
102
+ strict_1.default.equal(page.window.__mab_doubao_progress.requestId, result.requestId);
103
+ strict_1.default.equal(page.window.__mab_doubao_progress.sequence, 2);
104
+ strict_1.default.equal(new URL(page.window.__mab_doubao_request_url).origin, "https://www.doubao.com");
105
+ strict_1.default.equal(page.window.__mab_doubao_controller.signal.aborted, false);
106
+ strict_1.default.equal(page.sent.length, 1);
107
+ const message = page.sent[0].messages[0];
108
+ strict_1.default.equal(message.conversation_id, "peer-conversation");
109
+ strict_1.default.equal(message.ext.agent_mode, "17");
110
+ strict_1.default.equal(message.ext.use_deep_think, "9");
111
+ const general = JSON.parse(message.ext.general_task_param);
112
+ strict_1.default.equal(general.runtime_type, 27);
113
+ strict_1.default.equal(general.client_option.workspace, "workspace:peer-conversation");
114
+ strict_1.default.equal(general.client_option.sandbox_env_id, "native-env");
115
+ strict_1.default.equal(general.client_option.sandbox_auth_type, 41);
116
+ strict_1.default.equal(general.agent_task_param.workspace, "workspace:peer-conversation");
117
+ strict_1.default.equal(JSON.parse(message.ext.connector_info_list)[0].connector_id, "native-lark");
118
+ strict_1.default.deepEqual(JSON.parse(message.ext.mention_plugin_list), ["feishu"]);
119
+ });
120
+ (0, node_test_1.default)("豆包未开通任务模式、环境未就绪或缺少授权时拒绝发送,不能降为纯聊天", async () => {
121
+ for (const options of [{ ready: false }, { mode: false }, { authorization: false }]) {
122
+ const page = nativePage(options);
123
+ const result = await execute(page);
124
+ strict_1.default.equal(result.failed, true);
125
+ strict_1.default.equal(page.sent.length, 0);
126
+ strict_1.default.match(result.reason, /本地电脑|任务模式|授权/);
127
+ }
128
+ });
129
+ (0, node_test_1.default)("豆包新会话沿用独立临时会话标识,初始化本地电脑参数", async () => {
130
+ const page = nativePage();
131
+ const result = await execute(page, "");
132
+ strict_1.default.equal(result.ok, true);
133
+ const message = page.sent[0].messages[0];
134
+ strict_1.default.equal(message.conversation_id, undefined);
135
+ strict_1.default.match(message.local_conversation_id, /^local_/);
136
+ strict_1.default.ok(JSON.parse(message.ext.conversation_init_ext).agent_task_param);
137
+ });
138
+ (0, node_test_1.default)("豆包原生发送失败必须报错,不能将收到的中间文字当作成功", async () => {
139
+ const page = nativePage({ failure: true });
140
+ strict_1.default.equal((await execute(page)).failed, true);
141
+ });
142
+ (0, node_test_1.default)("豆包本地电脑中止终态不能伪装成成功", async () => {
143
+ const page = nativePage({ messages: async function* () {
144
+ yield { message_id: "answer", conversation_id: "broken", content_blocks_v2: [{ content: { text_block: { text: "只完成第一步" } } }], final_status: { session: "Broken" } };
145
+ } });
146
+ const result = await execute(page, "broken");
147
+ strict_1.default.equal(result.failed, true);
148
+ strict_1.default.match(result.reason, /中止/);
149
+ });
150
+ (0, node_test_1.default)("豆包本地电脑等待工具返回的异步视频并通过原生消息列表读取", async () => {
151
+ const page = nativePage({
152
+ messages: async function* (value) {
153
+ yield { ...value.messages[0], message_id: "question", conversation_id: "video-conversation" };
154
+ yield { message_id: "answer", conversation_id: "video-conversation", content_blocks_v2: [{ content: { text_block: { text: "已提交视频" } } }], ext: { has_video_gen: "1" } };
155
+ },
156
+ historyMessages: [{ message_id: "video-message", conversation_id: "video-conversation", reply_id: "question", content_blocks_v2: [{ block_type: 2074, is_finish: true, content: { creation_block: { creations: [{ video: { status: 3, vid: "async-video" } }] } } }] }],
157
+ });
158
+ const result = await execute(page);
159
+ strict_1.default.equal(result.pending, true);
160
+ const media = await page.window.__mab_doubao_read_artifacts(page.window.__mab_doubao_request_id);
161
+ strict_1.default.equal(media.pending, false);
162
+ strict_1.default.equal(media.artifacts[0].vid, "async-video");
163
+ });
164
+ (0, node_test_1.default)("豆包本地电脑旧请求晚结束时不覆盖其他 peer 的正文与会话", async () => {
165
+ let release;
166
+ const gate = new Promise(resolve => { release = resolve; });
167
+ const page = nativePage({ messages: async function* (value) {
168
+ const id = value.messages[0].conversation_id;
169
+ if (id === "first")
170
+ await gate;
171
+ yield { message_id: id, conversation_id: id, content_blocks_v2: [{ content: { text_block: { text: id } } }] };
172
+ } });
173
+ start(page, "first");
174
+ for (let i = 0; i < 100 && page.sent.length === 0; i++)
175
+ await new Promise(resolve => setImmediate(resolve));
176
+ strict_1.default.equal((await execute(page, "second")).reply, "second");
177
+ release();
178
+ await new Promise(resolve => setImmediate(resolve));
179
+ strict_1.default.equal(JSON.parse(page.window.__mab_doubao_result).reply, "second");
180
+ strict_1.default.equal(JSON.parse(page.window.__mab_doubao_result).conversationId, "second");
181
+ });
182
+ (0, node_test_1.default)("豆包旧请求迟到时不能覆盖新请求的异步产物读取器", async () => {
183
+ let release;
184
+ const gate = new Promise(resolve => { release = resolve; });
185
+ const page = nativePage({
186
+ messages: async function* (value) {
187
+ const id = value.messages[0].conversation_id;
188
+ if (id === "first")
189
+ await gate;
190
+ yield { message_id: id, conversation_id: id, reply_id: "question-" + id, content_blocks_v2: [{ content: { text_block: { text: "已提交" } } }], ext: { has_video_gen: "1" } };
191
+ },
192
+ historyMessages: [{ message_id: "second-video", conversation_id: "second", reply_id: "question-second", content_blocks_v2: [{ block_type: 2074, is_finish: true, content: { creation_block: { creations: [{ video: { status: 3, vid: "second-video" } }] } } }] }],
193
+ });
194
+ start(page, "first");
195
+ for (let i = 0; i < 100 && page.sent.length === 0; i++)
196
+ await new Promise(resolve => setImmediate(resolve));
197
+ start(page, "second");
198
+ for (let i = 0; i < 100 && !page.window.__mab_doubao_result; i++)
199
+ await new Promise(resolve => setImmediate(resolve));
200
+ release();
201
+ await new Promise(resolve => setImmediate(resolve));
202
+ const media = await page.window.__mab_doubao_read_artifacts(page.window.__mab_doubao_request_id);
203
+ strict_1.default.equal(media.artifacts[0].vid, "second-video");
204
+ });
205
+ (0, node_test_1.default)("豆包默认客户端通过原生发送链解析文件 URI、视频 VID 和图片", async () => {
206
+ const png = Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jL1sAAAAASUVORK5CYII=", "base64");
207
+ const video = Buffer.from([0, 0, 0, 12, 102, 116, 121, 112, 0, 0, 0, 0]);
208
+ const imageUrl = "https://p1-flow-imagex-sign.byteimg.com/image.png";
209
+ const videoUrl = "https://v1-vdl.doubao.com/video.mp4";
210
+ const fileUrl = "https://p1-flow-sign.byteimg.com/file.txt";
211
+ const page = nativePage({ messages: async function* () {
212
+ yield { message_id: "answer", conversation_id: "media-conversation", content_blocks_v2: [
213
+ { block_type: 2074, is_finish: true, content: { creation_block: { creations: [
214
+ { image: { status: 2, image_ori: { url: imageUrl } } }, { video: { status: 3, vid: "native-video" } },
215
+ ] } } },
216
+ { block_type: 10020, is_finish: true, content: { file_block: { name: "结果.txt", uri: "native-file" } } },
217
+ ] };
218
+ } });
219
+ const urls = [];
220
+ const context = { window: page.window, Map, Set, JSON, Date, Error, AbortController, URL, performance: { getEntriesByType: () => [] }, navigator: { userAgent: "" }, fetch: async (url, options) => {
221
+ strict_1.default.equal(options.signal.aborted, false);
222
+ urls.push(new URL(url).pathname);
223
+ return new Response(JSON.stringify({ code: 0, data: url.includes("get_play_info") ? { play_infos: [{ main: videoUrl }] } : { file_urls: [{ uri: "native-file", main_url: fileUrl }] } }));
224
+ } };
225
+ const client = new cdp_client_1.DoubaoCdpClient({ timeoutMs: 5000, fetchImpl: async (input) => {
226
+ const url = String(input);
227
+ return new Response(url === imageUrl ? png : url === videoUrl ? video : Buffer.from("文件内容"), { headers: { "content-type": url === imageUrl ? "image/png" : url === videoUrl ? "video/mp4" : "text/plain" } });
228
+ } });
229
+ client.connect = async () => { };
230
+ client.evaluate = async (expression) => (0, node_vm_1.runInNewContext)(expression, context);
231
+ const result = await client.complete("生成产物", undefined, undefined, "");
232
+ strict_1.default.equal(result.sessionId, "media-conversation");
233
+ strict_1.default.equal(result.attachments.length, 3);
234
+ strict_1.default.equal(result.images.length, 1);
235
+ strict_1.default.equal(result.attachments[2].filename, "结果.txt");
236
+ strict_1.default.deepEqual(urls, ["/samantha/video/get_play_info", "/alice/message/get_file_url"]);
237
+ });