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.
- package/README.md +12 -8
- package/dist/src-ts/cli.js +67 -37
- package/dist/src-ts/control-server.js +7 -28
- package/dist/src-ts/core-updater.js +141 -33
- package/dist/src-ts/daemon-process.js +2 -1
- package/dist/src-ts/dsh-agent.js +7 -2
- package/dist/src-ts/http-agent.js +36 -0
- package/dist/src-ts/plugin-manager.js +185 -58
- package/dist/src-ts/plugins/abweb/index.js +1 -1
- package/dist/src-ts/plugins/abweb/public/app.js +8 -6
- package/dist/src-ts/plugins/abweb/public/index.html +3 -3
- package/dist/src-ts/plugins/aun/attachments.js +3 -21
- package/dist/src-ts/plugins/aun/index.js +89 -11
- package/dist/src-ts/plugins/aun/messages.js +1 -1
- package/dist/src-ts/plugins/aun/public/app.js +2 -1
- package/dist/src-ts/plugins/aun/public/index.html +1 -1
- package/dist/src-ts/plugins/cdp-draft.js +5 -2
- package/dist/src-ts/plugins/chatgpt/index.js +3 -2
- package/dist/src-ts/plugins/claude-cli/index.js +1 -1
- package/dist/src-ts/plugins/desktop-launch.js +44 -3
- package/dist/src-ts/plugins/doubao/cdp-client.js +231 -45
- package/dist/src-ts/plugins/doubao/index.js +119 -7
- package/dist/src-ts/plugins/doubao/native-task.js +134 -0
- package/dist/src-ts/plugins/dsh/cdp-client.js +334 -0
- package/dist/src-ts/plugins/dsh/index.js +102 -23
- package/dist/src-ts/plugins/dsh/session-history.js +31 -3
- package/dist/src-ts/plugins/feishu/index.js +1 -1
- package/dist/src-ts/plugins/personal-assistant/index.js +29 -8
- package/dist/src-ts/plugins/personal-assistant/model-client.js +20 -6
- package/dist/src-ts/plugins/personal-assistant/session-memory.js +124 -0
- package/dist/src-ts/plugins/personal-assistant/tools.js +4 -3
- package/dist/src-ts/plugins/qwenwork/cdp-client.js +43 -7
- package/dist/src-ts/plugins/qwenwork/index.js +52 -18
- package/dist/src-ts/plugins/workbuddy/cdp-client.js +349 -83
- package/dist/src-ts/plugins/workbuddy/index.js +24 -12
- package/dist/src-ts/plugins/zcode/cdp-client.js +500 -0
- package/dist/src-ts/plugins/zcode/index.js +97 -0
- package/dist/src-ts/session-management.js +27 -8
- package/dist/src-ts/version-manager.js +6 -3
- package/dist/tests-ts/abweb-model-config.test.js +44 -41
- package/dist/tests-ts/aun-attachments.test.js +19 -17
- package/dist/tests-ts/aun-default-owner-page.test.js +2 -1
- package/dist/tests-ts/aun-messages.test.js +14 -0
- package/dist/tests-ts/aun-plugin.test.js +207 -19
- package/dist/tests-ts/bundled-package.test.js +1 -1
- package/dist/tests-ts/cdp-draft-recovery.test.js +182 -3
- package/dist/tests-ts/chatgpt-plugin.test.js +19 -0
- package/dist/tests-ts/control-server.test.js +20 -0
- package/dist/tests-ts/core-updater.test.js +215 -46
- package/dist/tests-ts/daemon-process.test.js +126 -1
- package/dist/tests-ts/desktop-launch.test.js +73 -0
- package/dist/tests-ts/doubao-native-task.test.js +237 -0
- package/dist/tests-ts/doubao-plugin.test.js +688 -19
- package/dist/tests-ts/dsh-agent.test.js +91 -19
- package/dist/tests-ts/dsh-cdp.test.js +148 -0
- package/dist/tests-ts/dsh-history.test.js +37 -0
- package/dist/tests-ts/feishu-plugin.test.js +1 -1
- package/dist/tests-ts/http-agent.test.js +18 -0
- package/dist/tests-ts/local-cli.test.js +29 -2
- package/dist/tests-ts/model-provider-cancellation.test.js +2 -0
- package/dist/tests-ts/native-session-management.test.js +8 -7
- package/dist/tests-ts/personal-assistant-coordination.test.js +16 -0
- package/dist/tests-ts/personal-assistant-extensions.test.js +7 -1
- package/dist/tests-ts/personal-assistant-memory.test.js +117 -0
- package/dist/tests-ts/personal-assistant.test.js +277 -3
- package/dist/tests-ts/platform-integration.test.js +60 -1
- package/dist/tests-ts/plugin-manager.test.js +78 -6
- package/dist/tests-ts/plugin-upgrade-deadline.test.js +354 -0
- package/dist/tests-ts/publish-packages.test.js +1 -1
- package/dist/tests-ts/qwenwork-plugin.test.js +30 -0
- package/dist/tests-ts/qwenwork-reconnect.test.js +195 -0
- package/dist/tests-ts/qwenwork-sse.test.js +33 -0
- package/dist/tests-ts/session-access-defaults.test.js +112 -0
- package/dist/tests-ts/session-management.test.js +8 -8
- package/dist/tests-ts/version-manager.test.js +40 -0
- package/dist/tests-ts/workbuddy-cdp-recovery.test.js +311 -0
- package/dist/tests-ts/workbuddy-plugin.test.js +356 -13
- package/dist/tests-ts/zcode-cdp.test.js +894 -0
- package/dist/tests-ts/zcode-plugin.test.js +396 -0
- package/package.json +1 -1
- package/plugins/abweb/dist/src-ts/plugins/abweb/index.js +1 -1
- package/plugins/abweb/dist/src-ts/plugins/abweb/public/app.js +8 -6
- package/plugins/abweb/dist/src-ts/plugins/abweb/public/app.ts +7 -5
- package/plugins/abweb/dist/src-ts/plugins/abweb/public/index.html +3 -3
- package/plugins/abweb/package.json +1 -1
- package/plugins/abweb/plugin.json +1 -1
- package/plugins/aun/config.schema.json +1 -1
- package/plugins/aun/dist/src-ts/plugins/aun/attachments.js +3 -21
- package/plugins/aun/dist/src-ts/plugins/aun/index.js +89 -11
- package/plugins/aun/dist/src-ts/plugins/aun/messages.js +1 -1
- package/plugins/aun/dist/src-ts/plugins/aun/public/app.js +2 -1
- package/plugins/aun/dist/src-ts/plugins/aun/public/index.html +1 -1
- package/plugins/aun/package.json +1 -1
- package/plugins/aun/plugin.json +1 -1
- package/plugins/chatgpt/dist/src-ts/plugins/cdp-draft.js +5 -2
- package/plugins/chatgpt/dist/src-ts/plugins/chatgpt/index.js +3 -2
- package/plugins/chatgpt/dist/src-ts/plugins/desktop-launch.js +44 -3
- package/plugins/claude-cli/dist/src-ts/plugins/claude-cli/index.js +1 -1
- package/plugins/claude-cli/package.json +1 -1
- package/plugins/claude-cli/plugin.json +1 -1
- package/plugins/doubao/config.schema.json +2 -1
- package/plugins/doubao/dist/src-ts/plugins/desktop-launch.js +44 -3
- package/plugins/doubao/dist/src-ts/plugins/doubao/cdp-client.js +231 -45
- package/plugins/doubao/dist/src-ts/plugins/doubao/index.js +119 -7
- package/plugins/doubao/dist/src-ts/plugins/doubao/native-task.js +134 -0
- package/plugins/doubao/package.json +1 -1
- package/plugins/doubao/plugin.json +1 -1
- package/plugins/dsh/config.schema.json +5 -2
- package/plugins/dsh/dist/src-ts/dsh-agent.js +7 -2
- package/plugins/dsh/dist/src-ts/plugins/desktop-launch.js +44 -3
- package/plugins/dsh/dist/src-ts/plugins/dsh/cdp-client.js +334 -0
- package/plugins/dsh/dist/src-ts/plugins/dsh/index.js +102 -23
- package/plugins/dsh/dist/src-ts/plugins/dsh/session-history.js +31 -3
- package/plugins/dsh/package.json +1 -1
- package/plugins/dsh/plugin.json +1 -1
- package/plugins/feishu/dist/src-ts/plugins/feishu/index.js +1 -1
- package/plugins/feishu/package.json +1 -1
- package/plugins/feishu/plugin.json +1 -1
- package/plugins/personal-assistant/config.schema.json +3 -2
- package/plugins/personal-assistant/dist/src-ts/attachments.js +62 -0
- package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/index.js +29 -8
- package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/model-client.js +20 -6
- package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/session-memory.js +124 -0
- package/plugins/personal-assistant/dist/src-ts/plugins/personal-assistant/tools.js +4 -3
- package/plugins/personal-assistant/package.json +2 -2
- package/plugins/personal-assistant/plugin.json +1 -1
- package/plugins/qwenwork/dist/src-ts/plugins/cdp-draft.js +5 -2
- package/plugins/qwenwork/dist/src-ts/plugins/desktop-launch.js +44 -3
- package/plugins/qwenwork/dist/src-ts/plugins/qwenwork/cdp-client.js +43 -7
- package/plugins/qwenwork/dist/src-ts/plugins/qwenwork/index.js +52 -18
- package/plugins/qwenwork/package.json +1 -1
- package/plugins/qwenwork/plugin.json +1 -1
- package/plugins/workbuddy/config.schema.json +1 -1
- package/plugins/workbuddy/dist/src-ts/plugins/desktop-launch.js +44 -3
- package/plugins/workbuddy/dist/src-ts/plugins/workbuddy/cdp-client.js +349 -83
- package/plugins/workbuddy/dist/src-ts/plugins/workbuddy/index.js +24 -12
- package/plugins/workbuddy/package.json +1 -1
- package/plugins/workbuddy/plugin.json +1 -1
- package/plugins/zcode/config.schema.json +13 -0
- package/plugins/zcode/dist/src-ts/agent.js +69 -0
- package/plugins/zcode/dist/src-ts/attachments.js +62 -0
- package/plugins/zcode/dist/src-ts/plugin.js +13 -0
- package/plugins/zcode/dist/src-ts/plugins/desktop-launch.js +238 -0
- package/plugins/zcode/dist/src-ts/plugins/workbuddy/cdp-client.js +896 -0
- package/plugins/zcode/dist/src-ts/plugins/workbuddy/cli-client.js +39 -0
- package/plugins/zcode/dist/src-ts/plugins/workbuddy/desktop-launch.js +10 -0
- package/plugins/zcode/dist/src-ts/plugins/workbuddy/index.js +567 -0
- package/plugins/zcode/dist/src-ts/plugins/workbuddy/session-history.js +121 -0
- package/plugins/zcode/dist/src-ts/plugins/zcode/cdp-client.js +500 -0
- package/plugins/zcode/dist/src-ts/plugins/zcode/index.js +97 -0
- package/plugins/zcode/package.json +16 -0
- package/plugins/zcode/plugin.json +11 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DoubaoPlugin = exports.doubaoManifest = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
4
5
|
const promises_1 = require("node:fs/promises");
|
|
5
6
|
const node_path_1 = require("node:path");
|
|
6
7
|
const agent_1 = require("../../agent");
|
|
@@ -11,7 +12,7 @@ const desktop_launch_1 = require("../desktop-launch");
|
|
|
11
12
|
const node_os_1 = require("node:os");
|
|
12
13
|
exports.doubaoManifest = {
|
|
13
14
|
id: "doubao",
|
|
14
|
-
version: "1.0.
|
|
15
|
+
version: "1.0.35",
|
|
15
16
|
displayName: "豆包",
|
|
16
17
|
entry: "dist/index.js",
|
|
17
18
|
apiVersion: "1",
|
|
@@ -19,6 +20,95 @@ exports.doubaoManifest = {
|
|
|
19
20
|
capabilities: ["chat", "health", "model-provider"],
|
|
20
21
|
configSchema: "config.schema.json",
|
|
21
22
|
};
|
|
23
|
+
const doubaoLoginEntries = [
|
|
24
|
+
"Local State",
|
|
25
|
+
"saman_app_state",
|
|
26
|
+
"saman_shell_db_storage",
|
|
27
|
+
"saman_shell_persistent_storage_v1",
|
|
28
|
+
"Default/Network",
|
|
29
|
+
"Default/Local Storage",
|
|
30
|
+
"Default/IndexedDB",
|
|
31
|
+
"Default/Session Storage",
|
|
32
|
+
"Default/WebStorage",
|
|
33
|
+
"Default/DoubaoStorage",
|
|
34
|
+
"Default/Preferences",
|
|
35
|
+
"Default/Secure Preferences",
|
|
36
|
+
"Default/Remote_State",
|
|
37
|
+
"Default/Remote_State_Aha_Chromium",
|
|
38
|
+
];
|
|
39
|
+
function runRobocopy(args) {
|
|
40
|
+
return new Promise((resolve, reject) => (0, node_child_process_1.execFile)("robocopy.exe", args, { windowsHide: true }, error => {
|
|
41
|
+
if (!error)
|
|
42
|
+
return resolve();
|
|
43
|
+
const rawCode = error.code;
|
|
44
|
+
const code = typeof rawCode === "number" ? rawCode : Number(rawCode);
|
|
45
|
+
if (Number.isFinite(code) && code <= 7)
|
|
46
|
+
resolve();
|
|
47
|
+
else
|
|
48
|
+
reject(error);
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
async function copyWithWindowsBackup(from, staged) {
|
|
52
|
+
const sourceInfo = await (0, promises_1.stat)(from);
|
|
53
|
+
const robocopyTarget = `${staged}.robocopy`;
|
|
54
|
+
await (0, promises_1.rm)(robocopyTarget, { recursive: true, force: true });
|
|
55
|
+
await (0, promises_1.mkdir)(robocopyTarget, { recursive: true });
|
|
56
|
+
const args = [
|
|
57
|
+
sourceInfo.isDirectory() ? from : (0, node_path_1.dirname)(from),
|
|
58
|
+
robocopyTarget,
|
|
59
|
+
sourceInfo.isDirectory() ? "*" : (0, node_path_1.basename)(from),
|
|
60
|
+
...(sourceInfo.isDirectory() ? ["/E"] : []),
|
|
61
|
+
"/B", "/COPY:DAT", "/DCOPY:DAT", "/R:0", "/W:0", "/NFL", "/NDL", "/NJH", "/NJS", "/NP", "/XF", "LOCK", "LOG", "LOG.old", "lockfile",
|
|
62
|
+
];
|
|
63
|
+
try {
|
|
64
|
+
await runRobocopy(args);
|
|
65
|
+
const copied = sourceInfo.isDirectory() ? robocopyTarget : (0, node_path_1.join)(robocopyTarget, (0, node_path_1.basename)(from));
|
|
66
|
+
await (0, promises_1.rm)(staged, { recursive: true, force: true });
|
|
67
|
+
await (0, promises_1.rename)(copied, staged);
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
await (0, promises_1.rm)(robocopyTarget, { recursive: true, force: true }).catch(() => undefined);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function copyDoubaoLoginState(target) {
|
|
74
|
+
const source = (0, node_path_1.join)(process.env.LOCALAPPDATA ?? (0, node_path_1.join)((0, node_os_1.homedir)(), "AppData", "Local"), "Doubao", "User Data");
|
|
75
|
+
await (0, promises_1.mkdir)(target, { recursive: true });
|
|
76
|
+
for (const entry of doubaoLoginEntries) {
|
|
77
|
+
const from = (0, node_path_1.join)(source, entry);
|
|
78
|
+
const to = (0, node_path_1.join)(target, entry);
|
|
79
|
+
const staged = `${to}.mab-copy`;
|
|
80
|
+
try {
|
|
81
|
+
await (0, promises_1.rm)(staged, { recursive: true, force: true });
|
|
82
|
+
await (0, promises_1.mkdir)((0, node_path_1.dirname)(staged), { recursive: true });
|
|
83
|
+
try {
|
|
84
|
+
await (0, promises_1.cp)(from, staged, {
|
|
85
|
+
recursive: true,
|
|
86
|
+
force: true,
|
|
87
|
+
filter: value => !new Set(["LOCK", "LOG", "LOG.old", "lockfile"]).has(value.split(/[\\/]/).at(-1) ?? ""),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (error.code !== "EBUSY")
|
|
92
|
+
throw error;
|
|
93
|
+
try {
|
|
94
|
+
await copyWithWindowsBackup(from, staged);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
await (0, promises_1.rm)(staged, { recursive: true, force: true }).catch(() => undefined);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
await (0, promises_1.rm)(to, { recursive: true, force: true });
|
|
102
|
+
await (0, promises_1.rename)(staged, to);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
await (0, promises_1.rm)(staged, { recursive: true, force: true }).catch(() => undefined);
|
|
106
|
+
const code = error.code;
|
|
107
|
+
if (code !== "ENOENT" && code !== "EBUSY")
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
22
112
|
class DoubaoPlugin {
|
|
23
113
|
injectedClient;
|
|
24
114
|
manifest = exports.doubaoManifest;
|
|
@@ -63,7 +153,14 @@ class DoubaoPlugin {
|
|
|
63
153
|
conversationId: typeof context.config.conversationId === "string" ? context.config.conversationId : undefined,
|
|
64
154
|
botId: typeof context.config.botId === "string" ? context.config.botId : undefined,
|
|
65
155
|
pluginList: Array.isArray(context.config.pluginList) ? context.config.pluginList.filter((value) => typeof value === "string") : undefined,
|
|
156
|
+
mode: context.config.mode === "chat" ? "chat" : "local-computer",
|
|
66
157
|
timeoutMs: typeof context.config.timeoutMs === "number" ? context.config.timeoutMs : undefined,
|
|
158
|
+
logger: { warn: message => context.logger?.warn?.(message) },
|
|
159
|
+
recoverCdp: async () => {
|
|
160
|
+
if (!this.reconnect)
|
|
161
|
+
throw new Error("豆包插件尚未配置 CDP 恢复流程");
|
|
162
|
+
await this.reconnect();
|
|
163
|
+
},
|
|
67
164
|
});
|
|
68
165
|
this.sessionHistory = new session_history_1.DoubaoSessionHistoryProvider({
|
|
69
166
|
scope: `doubao:${(0, plugin_1.resolveRuntimePort)(context.config, context.runtime, "doubao", "DOUBAO_CDP_PORT", 9227)}`,
|
|
@@ -76,17 +173,30 @@ class DoubaoPlugin {
|
|
|
76
173
|
}
|
|
77
174
|
catch (first) {
|
|
78
175
|
if (context.config.autoStart !== false && !this.injectedClient && process.platform === "win32") {
|
|
176
|
+
if (!(0, agent_1.errorDetails)(first).includes("ECONNREFUSED"))
|
|
177
|
+
throw first;
|
|
79
178
|
const executable = await (0, desktop_launch_1.findWindowsExecutable)("Doubao.exe", typeof context.config.executablePath === "string" ? context.config.executablePath : undefined);
|
|
80
179
|
if (!executable)
|
|
81
180
|
throw new Error("未找到 Doubao.exe,请配置 executablePath");
|
|
82
181
|
const port = (0, plugin_1.resolveRuntimePort)(context.config, context.runtime, "doubao", "DOUBAO_CDP_PORT", 9227);
|
|
83
182
|
context.logger?.warn?.(`正在恢复豆包:${executable},等待 CDP ${port}`);
|
|
84
183
|
try {
|
|
85
|
-
|
|
184
|
+
// 只重启桥接持有的进程;人工实例占用默认目录时使用下方独立目录。
|
|
185
|
+
await (0, desktop_launch_1.restartOwnedAndWait)(this.ownedProcess, executable, [`--remote-debugging-port=${port}`], undefined, () => this.client.connect(), typeof context.config.startupTimeoutMs === "number" ? context.config.startupTimeoutMs : 30_000, child => { this.ownedProcess = child; });
|
|
86
186
|
return;
|
|
87
187
|
}
|
|
88
188
|
catch (error) {
|
|
89
189
|
first = new Error(`已启动豆包,但 CDP ${port} 未就绪:${error instanceof Error ? error.message : String(error)}`);
|
|
190
|
+
const profile = (0, node_path_1.join)(this.dataDir ?? (0, node_path_1.join)((0, node_os_1.homedir)(), ".agent-bridge", "doubao"), "desktop-profile");
|
|
191
|
+
try {
|
|
192
|
+
await copyDoubaoLoginState(profile);
|
|
193
|
+
context.logger?.warn?.(`默认豆包用户目录不可用,改用登录状态副本:${profile}`);
|
|
194
|
+
await (0, desktop_launch_1.restartOwnedAndWait)(this.ownedProcess, executable, [`--remote-debugging-port=${port}`], profile, () => this.client.connect(), typeof context.config.startupTimeoutMs === "number" ? context.config.startupTimeoutMs : 30_000, child => { this.ownedProcess = child; });
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
catch (fallbackError) {
|
|
198
|
+
first = new Error(`已启动豆包,但 CDP ${port} 未就绪:${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
|
|
199
|
+
}
|
|
90
200
|
}
|
|
91
201
|
}
|
|
92
202
|
throw first;
|
|
@@ -106,13 +216,14 @@ class DoubaoPlugin {
|
|
|
106
216
|
throw error;
|
|
107
217
|
}
|
|
108
218
|
}
|
|
109
|
-
async deactivate() {
|
|
219
|
+
async deactivate(_reason = "stop", options) {
|
|
110
220
|
await this.queue;
|
|
111
221
|
this.disposer?.();
|
|
112
222
|
this.disposer = undefined;
|
|
113
223
|
this.reconnect = undefined;
|
|
114
224
|
await this.client?.close();
|
|
115
|
-
|
|
225
|
+
if (!options?.preserveDesktop)
|
|
226
|
+
await (0, desktop_launch_1.terminateOwnedProcess)(this.ownedProcess).catch(() => undefined);
|
|
116
227
|
this.ownedProcess = undefined;
|
|
117
228
|
this.client = undefined;
|
|
118
229
|
this.state = "stopped";
|
|
@@ -142,7 +253,7 @@ class DoubaoPlugin {
|
|
|
142
253
|
if (this.state !== "ready" || !this.client)
|
|
143
254
|
throw new Error("豆包插件未就绪");
|
|
144
255
|
if (!this.client.connected())
|
|
145
|
-
await this.reconnect
|
|
256
|
+
await this.reconnect();
|
|
146
257
|
}
|
|
147
258
|
async handle(request) {
|
|
148
259
|
return this.enqueue(async () => {
|
|
@@ -169,9 +280,10 @@ class DoubaoPlugin {
|
|
|
169
280
|
const run = this.enqueue(async () => {
|
|
170
281
|
request.signal.throwIfAborted();
|
|
171
282
|
stage = "连接豆包模型(connect)";
|
|
283
|
+
await this.ensureConnected();
|
|
172
284
|
const client = this.client;
|
|
173
|
-
if (
|
|
174
|
-
throw new Error("
|
|
285
|
+
if (!client?.complete)
|
|
286
|
+
throw new Error("豆包客户端不支持模型调用");
|
|
175
287
|
stage = "等待豆包模型生成(generate)";
|
|
176
288
|
// 空服务端标识会原子创建独立会话,无需切换用户桌面页面。
|
|
177
289
|
const response = await client.complete(request.prompt, request.signal, undefined, this.bindings.get(request.sessionId) ?? "");
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.nativeTaskScript = void 0;
|
|
4
|
+
// shortcut: 依赖桌面端原生模块导出,豆包升级接口后需重新校验;接口缺失时拒绝发送。
|
|
5
|
+
exports.nativeTaskScript = String.raw `(body, readTexts, readArtifacts, getRequestUrl) => {
|
|
6
|
+
window.__mab_doubao_controller?.abort();
|
|
7
|
+
const controller = new AbortController();
|
|
8
|
+
window.__mab_doubao_controller = controller;
|
|
9
|
+
window.__mab_doubao_read_artifacts = undefined;
|
|
10
|
+
window.__mab_doubao_request_id = body.option.unique_key;
|
|
11
|
+
let progressSequence = 0;
|
|
12
|
+
window.__mab_doubao_progress = { requestId: body.option.unique_key, sequence: progressSequence };
|
|
13
|
+
window.__mab_doubao_result = null;
|
|
14
|
+
const finish = result => {
|
|
15
|
+
if (window.__mab_doubao_controller === controller) window.__mab_doubao_result = JSON.stringify(result);
|
|
16
|
+
};
|
|
17
|
+
(async () => {
|
|
18
|
+
window.__mab_doubao_request_url = getRequestUrl().href;
|
|
19
|
+
const chunks = window['@flow-web/desktop:stable'];
|
|
20
|
+
if (!Array.isArray(chunks)) throw Error('豆包本地电脑原生接口不可用,请检查桌面端版本');
|
|
21
|
+
let requireNative;
|
|
22
|
+
chunks.push([['mab_task_' + body.option.unique_key], {}, value => { requireNative = value; }]);
|
|
23
|
+
const factories = new Map(chunks.flatMap(chunk => Object.entries(chunk[1] || {})));
|
|
24
|
+
const load = (marker, extra = '') => {
|
|
25
|
+
for (const [id, factory] of factories) if (String(factory).includes(marker) && String(factory).includes(extra)) return requireNative(id);
|
|
26
|
+
throw Error('豆包本地电脑接口缺失:' + marker);
|
|
27
|
+
};
|
|
28
|
+
const named = name => load(name + ':()=>')[name];
|
|
29
|
+
const only = (module, predicate) => {
|
|
30
|
+
const matches = Object.values(module).filter(value => typeof value === 'function' && predicate(value));
|
|
31
|
+
if (matches.length !== 1) throw Error('豆包本地电脑原生接口不兼容');
|
|
32
|
+
return matches[0];
|
|
33
|
+
};
|
|
34
|
+
const environment = await named('sandboxEnvironmentController').query();
|
|
35
|
+
if (!environment.isReady || !environment.environmentId) throw Error('豆包本地电脑环境未就绪,请在当前桌面登录态中检查本地电脑功能');
|
|
36
|
+
const getStore = only(load('chat-ioc-manager: cannot bind empty store'), value => String(value).includes('it is async store'));
|
|
37
|
+
const state = getStore('chatInputStore').getState();
|
|
38
|
+
const agentMode = named('AgentMode').MOA;
|
|
39
|
+
const mode = state.modeSelectConfigs?.menu_item_list?.find(item => Number(item.agent_mode) === agentMode);
|
|
40
|
+
if (!mode) throw Error('当前豆包登录态未提供任务模式,不能使用本地电脑');
|
|
41
|
+
const modeId = state.modeSelectConfigsV2?.mode_list?.item_list?.find(item => Number(item.agent_mode) === agentMode)?.mode_id || mode.default_mode;
|
|
42
|
+
if (!modeId) throw Error('豆包本地电脑任务模式标识缺失');
|
|
43
|
+
const getAuthorization = only(load('new WeakMap', 'sandboxAuthType:'), value => value.length === 0);
|
|
44
|
+
const authorization = getAuthorization();
|
|
45
|
+
if (!authorization || typeof authorization.sandboxAuthType !== 'number') throw Error('无法读取豆包本地电脑授权设置');
|
|
46
|
+
const getService = only(load('chat-ioc-manager: cannot bind empty service'), value => value.constructor.name === 'AsyncFunction');
|
|
47
|
+
const service = await getService('chatIMService');
|
|
48
|
+
const messageService = await service?.getMessageService();
|
|
49
|
+
if (!messageService?.sendMessage) throw Error('豆包本地电脑消息服务未就绪');
|
|
50
|
+
const scope = body.client_meta.conversation_id || body.client_meta.local_conversation_id;
|
|
51
|
+
const taskApi = load('buildGeneralAgentCompletionTaskParam:()=>');
|
|
52
|
+
const clientOption = await taskApi.buildGeneralAgentCompletionTaskParam(scope);
|
|
53
|
+
if (!clientOption.sandbox_id || !clientOption.workspace) throw Error('豆包本地电脑工作区或运行环境不可用');
|
|
54
|
+
const workspace = clientOption.workspace;
|
|
55
|
+
const runtimeType = taskApi.GeneralAgentRuntimeType.LocalPC;
|
|
56
|
+
const modify = only(load('general_agent_conversation_modify_params'), value => value.constructor.name === 'AsyncFunction');
|
|
57
|
+
const changes = await modify({ completionTaskParam: clientOption, messageConversationId: scope, primaryWorkspace: clientOption.workspace, runtimeType, sandboxAuthType: authorization.sandboxAuthType });
|
|
58
|
+
const general = { ...changes, runtime_type: runtimeType, server_do_compare: true, client_option: {
|
|
59
|
+
...clientOption, sandbox_id: undefined, sandbox_env_id: clientOption.sandbox_id,
|
|
60
|
+
shared_folder_path: [clientOption.workspace], sandbox_auth_type: authorization.sandboxAuthType,
|
|
61
|
+
} };
|
|
62
|
+
const connector = await named('getFeishuConnectorEnabledForConversation')(scope);
|
|
63
|
+
const connectorInfo = only(load('connector_info_list', 'wrapped:!0'), value => {
|
|
64
|
+
const source = String(value); return source.includes('connector_id:') && source.includes('switch:') && source.includes('connector_vendor:');
|
|
65
|
+
});
|
|
66
|
+
const extra = {
|
|
67
|
+
agent_mode: String(agentMode), use_deep_think: String(mode.menu_type ?? mode.item_id), mode_id: String(modeId),
|
|
68
|
+
model_item_key: mode.model_item_key, model_extra_params: JSON.stringify(mode.model_extra_params || {}),
|
|
69
|
+
reasoning_effort: String(mode.reasoning_effort_config?.default_level ?? body.option.model_config.reasoning_effort),
|
|
70
|
+
general_task_param: JSON.stringify(general), mention_plugin_list: body.option.aggregate_params.mention_plugin_list,
|
|
71
|
+
...(connector ? { connector_info_list: JSON.stringify([connectorInfo(connector.enabled, connector.id)]) } : {}),
|
|
72
|
+
...(!body.client_meta.conversation_id ? {
|
|
73
|
+
conversation_init_option: JSON.stringify({ need_ack_conversation: true }),
|
|
74
|
+
conversation_init_ext: JSON.stringify({ mode_id: String(modeId), agent_task_param: JSON.stringify(changes.agent_task_param) }),
|
|
75
|
+
} : {}),
|
|
76
|
+
};
|
|
77
|
+
const create = named('createSendMessage');
|
|
78
|
+
const messages = body.messages.map(item => create({ conversationContext: {
|
|
79
|
+
conversation_id: body.client_meta.conversation_id || undefined,
|
|
80
|
+
local_conversation_id: body.client_meta.conversation_id ? undefined : scope, bot_id: body.client_meta.bot_id,
|
|
81
|
+
}, message: { content_blocks_v2: item.content_block, unique_id: item.local_message_id, ext: extra } }));
|
|
82
|
+
controller.signal.throwIfAborted();
|
|
83
|
+
const handle = messageService.sendMessage({ messages, sessionId: body.option.unique_key, session: { reportParams: { is_local_computer_on: 1 } }, sendMode: 'normal' });
|
|
84
|
+
controller.signal.addEventListener('abort', () => { Promise.resolve().then(() => handle.cancel()).catch(() => {}); }, { once: true });
|
|
85
|
+
const localIds = new Set(body.messages.map(item => item.local_message_id)), replies = new Map();
|
|
86
|
+
const questionIds = new Set(), messageIds = new Set();
|
|
87
|
+
let expectVideo = false, conversationId = body.client_meta.conversation_id;
|
|
88
|
+
const collect = message => {
|
|
89
|
+
const statuses = Object.values(message.final_status || {});
|
|
90
|
+
if (statuses.some(status => ['Broken', 'CancelError', 'Cancelled', 'Canceled'].includes(status))) throw Error('豆包本地电脑任务已中止');
|
|
91
|
+
if (message.error_details?.has_error || statuses.some(status => ['Error', 'PanicError', 'ExpectError'].includes(status))) throw Error(message.error_details?.error_msg || '豆包本地电脑任务执行失败');
|
|
92
|
+
if (message.ext?.has_video_gen === '1' || message.ext?.has_video_gen === 1) expectVideo = true;
|
|
93
|
+
if (message.message_id) {
|
|
94
|
+
messageIds.add(message.message_id);
|
|
95
|
+
replies.set(message.message_id, message.content_blocks_v2 || message.content_blocks || message.content_block || []);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
for await (const message of handle.subscribe()) {
|
|
99
|
+
if (window.__mab_doubao_controller === controller) window.__mab_doubao_progress = { requestId: body.option.unique_key, sequence: ++progressSequence };
|
|
100
|
+
if (message.conversation_id) conversationId = message.conversation_id;
|
|
101
|
+
if (localIds.has(message.local_message_id) || localIds.has(message.unique_id)) {
|
|
102
|
+
if (message.error_details?.has_error) throw Error('豆包本地电脑任务发送失败');
|
|
103
|
+
if (message.message_id) questionIds.add(message.message_id);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
if (message.reply_id) questionIds.add(message.reply_id);
|
|
107
|
+
collect(message);
|
|
108
|
+
}
|
|
109
|
+
const mediaSnapshot = () => {
|
|
110
|
+
const media = readArtifacts([...replies.values()], workspace);
|
|
111
|
+
return { ...media, pending: media.pending || (expectVideo && !media.artifacts.some(item => item.kind === 'video')) };
|
|
112
|
+
};
|
|
113
|
+
// 异步媒体按本轮引用读取原生消息列表,不依赖人工当前打开的会话。
|
|
114
|
+
if (window.__mab_doubao_controller !== controller) throw Error('豆包本地电脑原任务上下文已变化');
|
|
115
|
+
window.__mab_doubao_read_artifacts = async requestId => {
|
|
116
|
+
if (requestId !== body.option.unique_key || window.__mab_doubao_controller !== controller) throw Error('豆包本地电脑原任务上下文已变化');
|
|
117
|
+
controller.signal.throwIfAborted();
|
|
118
|
+
if (typeof messageService.fetchAndUpdateMessageList !== 'function') throw Error('豆包本地电脑异步产物读取接口不可用');
|
|
119
|
+
const page = await messageService.fetchAndUpdateMessageList({ conversationId, options: { limit: 50 } });
|
|
120
|
+
for (const message of page?.messages || []) {
|
|
121
|
+
if (message.conversation_id !== conversationId) continue;
|
|
122
|
+
const reference = message.ext?.reference_info;
|
|
123
|
+
const match = typeof reference === 'string' ? reference.match(/"referenced_message_id"\s*:\s*(?:"([^"\n]+)"|(\d+))/) : null;
|
|
124
|
+
const referenceId = match?.[1] || match?.[2];
|
|
125
|
+
if (messageIds.has(message.message_id) || questionIds.has(message.reply_id) || questionIds.has(referenceId)) collect(message);
|
|
126
|
+
}
|
|
127
|
+
return mediaSnapshot();
|
|
128
|
+
};
|
|
129
|
+
const media = mediaSnapshot();
|
|
130
|
+
const reply = readTexts([...replies.values()].map(blocks => blocks.filter(block => !block.parent_id && block.control_info?.is_visible !== false))).join('\n').trim();
|
|
131
|
+
if (!reply && !media.artifacts.length && !media.pending) throw Error('豆包本地电脑任务未返回结果');
|
|
132
|
+
finish({ ok: true, reply, conversationId, ...media, requestId: body.option.unique_key, questionIds: [...questionIds], messageIds: [...messageIds] });
|
|
133
|
+
})().catch(error => { finish({ failed: true, requestId: body.option.unique_key, reason: error?.message || String(error) }); });
|
|
134
|
+
}`;
|