mu-agent-bridge 1.0.17 → 1.0.18

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.
@@ -110,9 +110,27 @@ class ControlServer {
110
110
  if (method === "POST" && url.pathname === "/api/update") {
111
111
  this.options.manager.log("info", "已请求后台升级,准备重启 daemon", undefined, "后台升级");
112
112
  if (process.platform === "win32") {
113
- const script = "$ErrorActionPreference='Continue'; Start-Sleep -Seconds 2; schtasks.exe /End /TN mab | Out-Null; npm.cmd install -g mu-agent-bridge@latest --no-fund --no-audit; schtasks.exe /Run /TN mab | Out-Null";
114
- const child = (0, node_child_process_1.spawn)("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script], { detached: true, stdio: "ignore", windowsHide: true });
115
- child.unref();
113
+ const logFile = `${process.env.APPDATA ?? process.cwd()}\\agent-bridge\\state\\core-update.log`;
114
+ const script = [
115
+ "$ErrorActionPreference='Continue'",
116
+ `$log = '${logFile.replace(/'/g, "''")}'`,
117
+ "$dir = Split-Path -Parent $log",
118
+ "New-Item -ItemType Directory -Force $dir | Out-Null",
119
+ "function Write-UpdateLog($text) { \"$(Get-Date -Format o) $text\" | Out-File -FilePath $log -Append -Encoding utf8 }",
120
+ "Start-Sleep -Seconds 3",
121
+ "Write-UpdateLog '停止旧 daemon'",
122
+ "schtasks.exe /End /TN mab 2>&1 | ForEach-Object { Write-UpdateLog $_ }",
123
+ "Start-Sleep -Seconds 2",
124
+ "Write-UpdateLog '开始安装 mu-agent-bridge@latest'",
125
+ "npm.cmd install -g mu-agent-bridge@latest --no-fund --no-audit 2>&1 | ForEach-Object { Write-UpdateLog $_ }",
126
+ "Write-UpdateLog '重新启动 mab 计划任务'",
127
+ "schtasks.exe /Run /TN mab 2>&1 | ForEach-Object { Write-UpdateLog $_ }",
128
+ "Write-UpdateLog '后台升级脚本结束'",
129
+ ].join('; ');
130
+ setTimeout(() => {
131
+ const child = (0, node_child_process_1.spawn)("powershell.exe", ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script], { detached: true, stdio: "ignore", windowsHide: true });
132
+ child.unref();
133
+ }, 1500).unref();
116
134
  }
117
135
  else {
118
136
  return this.json(res, 501, { error: "当前平台未配置后台升级器" });
@@ -5,6 +5,7 @@ const node_child_process_1 = require("node:child_process");
5
5
  exports.editorSelector = '[data-codex-composer="true"][contenteditable="true"]';
6
6
  exports.turnSelector = '[data-chatgpt-conversation-turn="true"]';
7
7
  exports.userBubbleSelector = "[data-user-message-bubble]";
8
+ const assistantMessageSelector = '[data-markdown-text-style="assistant-message"]';
8
9
  const turnIdAttribute = "data-chatgpt-conversation-turn-id";
9
10
  const contentUnitSelector = "[data-content-search-unit-key]";
10
11
  const sendButtonSelector = 'button[aria-label="Send"], button[aria-label="发送"]';
@@ -88,7 +89,8 @@ class ChatgptCdpClient {
88
89
  if (!response.ok)
89
90
  throw new Error(`ChatGPT CDP /json HTTP ${response.status}`);
90
91
  const targets = await response.json();
91
- const page = targets.find((target) => target.type === "page" && /chatgpt|codex/i.test(`${target.title} ${target.url}`));
92
+ const page = targets.find((target) => target.type === "page" && (/chatgpt|codex/i.test(`${target.title} ${target.url}`)
93
+ || target.url === "app://-/index.html"));
92
94
  if (page?.webSocketDebuggerUrl)
93
95
  return page;
94
96
  last = new Error(`未找到 ChatGPT/Codex 页面 target(端口 ${this.port})`);
@@ -111,6 +113,7 @@ class ChatgptCdpClient {
111
113
  await this.waitFor(`Boolean(document.querySelector(${JSON.stringify(exports.editorSelector)}))`, "ChatGPT 桌面端输入框未就绪");
112
114
  const beforeTurnsJson = await this.evaluate(`JSON.stringify([...document.querySelectorAll(${JSON.stringify(exports.turnSelector)})].map(turn => ({ id: turn.getAttribute(${JSON.stringify(turnIdAttribute)}), users: turn.querySelectorAll(${JSON.stringify(exports.userBubbleSelector)}).length })))`);
113
115
  const beforeTurns = JSON.parse(String(beforeTurnsJson || "[]"));
116
+ const beforeAssistantCount = Number(await this.evaluate(`document.querySelectorAll(${JSON.stringify(assistantMessageSelector)}).length`));
114
117
  const ready = await this.evaluate(`(() => {
115
118
  const editor = document.querySelector(${JSON.stringify(exports.editorSelector)});
116
119
  if (!editor || editor.innerText.trim()) return false;
@@ -164,7 +167,13 @@ class ChatgptCdpClient {
164
167
  const fresh = oldIndex < 0 || index >= before.length || users.length > (old?.users ?? 0);
165
168
  return fresh && users.item(users.length - 1)?.innerText.trim() === ${JSON.stringify(text.trim())};
166
169
  });
167
- if (!turn) return JSON.stringify({ reply: "", active: false });
170
+ if (!turn) {
171
+ const assistants = [...document.querySelectorAll(${JSON.stringify(assistantMessageSelector)})];
172
+ const fallback = assistants.length > ${beforeAssistantCount}
173
+ ? assistants.at(-1)?.innerText.trim() ?? ""
174
+ : "";
175
+ return JSON.stringify({ reply: fallback, active: Boolean(document.querySelector(${JSON.stringify(stopButtonSelector)})) });
176
+ }
168
177
  const user = turn.querySelectorAll(${JSON.stringify(exports.userBubbleSelector)}).item(turn.querySelectorAll(${JSON.stringify(exports.userBubbleSelector)}).length - 1);
169
178
  const unit = user?.closest(${JSON.stringify(contentUnitSelector)});
170
179
  const units = [...turn.querySelectorAll(${JSON.stringify(contentUnitSelector)})];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mu-agent-bridge",
3
- "version": "1.0.17",
3
+ "version": "1.0.18",
4
4
  "description": "将 AUN Agent 连接到本地桌面 AI 客户端的插件平台。",
5
5
  "main": "dist/src-ts/cli.js",
6
6
  "bin": {
@@ -88,7 +88,8 @@ class ChatgptCdpClient {
88
88
  if (!response.ok)
89
89
  throw new Error(`ChatGPT CDP /json HTTP ${response.status}`);
90
90
  const targets = await response.json();
91
- const page = targets.find((target) => target.type === "page" && /chatgpt|codex/i.test(`${target.title} ${target.url}`));
91
+ const page = targets.find((target) => target.type === "page" && (/chatgpt|codex/i.test(`${target.title} ${target.url}`)
92
+ || target.url === "app://-/index.html"));
92
93
  if (page?.webSocketDebuggerUrl)
93
94
  return page;
94
95
  last = new Error(`未找到 ChatGPT/Codex 页面 target(端口 ${this.port})`);
@@ -164,7 +165,11 @@ class ChatgptCdpClient {
164
165
  const fresh = oldIndex < 0 || index >= before.length || users.length > (old?.users ?? 0);
165
166
  return fresh && users.item(users.length - 1)?.innerText.trim() === ${JSON.stringify(text.trim())};
166
167
  });
167
- if (!turn) return JSON.stringify({ reply: "", active: false });
168
+ if (!turn) {
169
+ const fallback = [...document.querySelectorAll('[data-message-author-role="assistant"]')]
170
+ .map(item => item.innerText.trim()).filter(Boolean).at(-1) ?? "";
171
+ return JSON.stringify({ reply: fallback, active: Boolean(document.querySelector(${JSON.stringify(stopButtonSelector)})) });
172
+ }
168
173
  const user = turn.querySelectorAll(${JSON.stringify(exports.userBubbleSelector)}).item(turn.querySelectorAll(${JSON.stringify(exports.userBubbleSelector)}).length - 1);
169
174
  const unit = user?.closest(${JSON.stringify(contentUnitSelector)});
170
175
  const units = [...turn.querySelectorAll(${JSON.stringify(contentUnitSelector)})];