aws-runtime-bridge 1.9.50 → 1.9.51

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.
@@ -1 +1 @@
1
- {"version":3,"file":"AcodeSdkAdapter.d.ts","sourceRoot":"","sources":["../../src/adapter/AcodeSdkAdapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AcodeSdkAdapter.d.ts","sourceRoot":"","sources":["../../src/adapter/AcodeSdkAdapter.ts"],"names":[],"mappings":"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"}
@@ -1801,13 +1801,27 @@ export class AcodeSdkAdapter extends EventEmitter {
1801
1801
  currentEntry.watchdogLastDataFlowTime = now;
1802
1802
  return;
1803
1803
  }
1804
- // thinking/tool_using 状态下检查超时
1805
- if (status !== "thinking" && status !== "tool_using") {
1804
+ // 看门狗只在 thinking 状态工作:检测 ai_request 发出后 provider 流挂死。
1805
+ // tool_using 状态下完全不触发看门狗——每个工具都有自己的超时机制:
1806
+ // - MCP 普通工具:60s(DEFAULT_MCP_TOOL_CALL_TIMEOUT_MS)
1807
+ // - 内置文件工具/Bash:fallbackTimeoutMs / 自带 timeout_ms
1808
+ // - ask_user_question:question_request 事件取消看门狗,依赖用户回答
1809
+ // - await_sub_agents:无超时,依赖子 agent 自己的 runtime 看门狗
1810
+ // 若在 tool_using 触发看门狗,abort() 即使能中断工具,也会打断 agent 正在进行的
1811
+ // 合法长时间操作(如等待子 agent 完成),违反"看门狗不应影响 agent 动作"原则。
1812
+ // 同时重置计时基准,避免 tool_using 期间累积时间带到下一次 thinking 误触发。
1813
+ if (status === "tool_using") {
1814
+ currentEntry.watchdogLastDataFlowTime = now;
1815
+ currentEntry.watchdogSubmitStartTime = now;
1816
+ return;
1817
+ }
1818
+ // 其他非 thinking 状态(compacting/error 等)不计时
1819
+ if (status !== "thinking") {
1806
1820
  return;
1807
1821
  }
1808
1822
  const submitElapsed = now - (currentEntry.watchdogSubmitStartTime || now);
1809
1823
  const dataFlowElapsed = now - (currentEntry.watchdogLastDataFlowTime || now);
1810
- // 数据流超时(40s 无流式数据)— submit 超时(120s)更短,优先触发
1824
+ // 数据流超时(40s 无流式数据)— thinking 状态触发,比 submit 超时(120s)更短,优先触发
1811
1825
  if (dataFlowElapsed >= ACODE_DATA_FLOW_STREAM_WATCHDOG_MS) {
1812
1826
  console.warn(`[ACode] CRITICAL: Data flow watchdog triggered after ${Math.round(dataFlowElapsed / 1000)}s ` +
1813
1827
  `(source: ${source}, session: ${sessionId}, status: ${status}). ` +
@@ -9,12 +9,14 @@
9
9
  * - CREATE:检查文件是否存在,准备删除
10
10
  * - UPDATE:读取 diff patch,读取当前文件内容,在内存中应用反向 patch 验证是否成功
11
11
  * - DELETE:读取删除前的完整内容,准备重建
12
- * 2. 原子执行:预检全部通过后,批量写入文件系统;任一预检失败则直接返回错误,
13
- * 由调用方决定是否使用快照进行完整覆盖。
12
+ * 2. 原子执行:预检全部通过后,批量写入文件系统;任一预检失败则返回 previewFailed=true,
13
+ * 由调用方(前端)弹出"跳过不通过项 / 文件全量覆盖"二选一对话框。
14
+ * skipFailed=true 时仅执行通过项(partial);否则不写盘。
14
15
  *
15
16
  * 反向操作映射:
16
17
  * CREATE → DELETE(删除创建的文件)
17
- * UPDATE → 应用反向 diff patch(精确撤销修改的部分,保留用户后续改动)
18
+ * UPDATE → 应用反向 diff patch(精确撤销修改的部分,保留用户后续改动);
19
+ * 若补丁无法精确应用(上下文不匹配=冲突),报为预检失败,不静默整文件覆盖
18
20
  * DELETE → 重新创建被删除的文件(根据 cacheKey 从 bridge 本地缓存读取)
19
21
  */
20
22
  export declare const fileDiffRollbackRouter: import("express-serve-static-core").Router;
@@ -31,6 +33,13 @@ export interface ReverseOperation {
31
33
  export interface DiffRollbackRequest {
32
34
  workspacePath: string;
33
35
  operations: ReverseOperation[];
36
+ /**
37
+ * 预检部分失败时的处理策略。
38
+ * - 缺省/ false:任一预检失败则直接返回 previewFailed,不写盘(由调用方决定后续动作)。
39
+ * - true:仅执行通过预检的操作(preview.plan 中的项),跳过失败项,
40
+ * 返回 partial:true,让调用方可以"跳过不通过项"而非整工作区快照覆盖。
41
+ */
42
+ skipFailed?: boolean;
34
43
  }
35
44
  /** 单条操作的执行状态 */
36
45
  export interface OperationDetail {
@@ -50,6 +59,11 @@ export interface DiffRollbackResult {
50
59
  errors: string[];
51
60
  /** 当 ok=false 且未执行写盘时为 true */
52
61
  previewFailed?: boolean;
62
+ /**
63
+ * 部分执行标志:skipFailed=true 且仅有部分操作通过预检时,
64
+ * 已对通过项执行写盘、跳过失败项,返回 partial:true。
65
+ */
66
+ partial?: boolean;
53
67
  /** 每条操作的详细状态 */
54
68
  details: OperationDetail[];
55
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file-diff-rollback.d.ts","sourceRoot":"","sources":["../../src/routes/file-diff-rollback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,eAAO,MAAM,sBAAsB,4CAAW,CAAC;AAE/C,MAAM,WAAW,gBAAgB;IAC/B,aAAa;IACb,iBAAiB,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAClD,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,gBAAgB;AAChB,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa;IACb,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC/E,gBAAgB;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB;IAChB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
1
+ {"version":3,"file":"file-diff-rollback.d.ts","sourceRoot":"","sources":["../../src/routes/file-diff-rollback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAWH,eAAO,MAAM,sBAAsB,4CAAW,CAAC;AAE/C,MAAM,WAAW,gBAAgB;IAC/B,aAAa;IACb,iBAAiB,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAClD,mBAAmB;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,gBAAgB;AAChB,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa;IACb,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC/E,gBAAgB;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB;IAChB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B"}
@@ -9,12 +9,14 @@
9
9
  * - CREATE:检查文件是否存在,准备删除
10
10
  * - UPDATE:读取 diff patch,读取当前文件内容,在内存中应用反向 patch 验证是否成功
11
11
  * - DELETE:读取删除前的完整内容,准备重建
12
- * 2. 原子执行:预检全部通过后,批量写入文件系统;任一预检失败则直接返回错误,
13
- * 由调用方决定是否使用快照进行完整覆盖。
12
+ * 2. 原子执行:预检全部通过后,批量写入文件系统;任一预检失败则返回 previewFailed=true,
13
+ * 由调用方(前端)弹出"跳过不通过项 / 文件全量覆盖"二选一对话框。
14
+ * skipFailed=true 时仅执行通过项(partial);否则不写盘。
14
15
  *
15
16
  * 反向操作映射:
16
17
  * CREATE → DELETE(删除创建的文件)
17
- * UPDATE → 应用反向 diff patch(精确撤销修改的部分,保留用户后续改动)
18
+ * UPDATE → 应用反向 diff patch(精确撤销修改的部分,保留用户后续改动);
19
+ * 若补丁无法精确应用(上下文不匹配=冲突),报为预检失败,不静默整文件覆盖
18
20
  * DELETE → 重新创建被删除的文件(根据 cacheKey 从 bridge 本地缓存读取)
19
21
  */
20
22
  import { promises as fs } from 'node:fs';
@@ -93,40 +95,42 @@ async function previewRollback(workspacePath, operations) {
93
95
  details.push({ relativePath, originalOperation: 'UPDATE', status: 'preview_failed', reason });
94
96
  break;
95
97
  }
96
- // 尝试用 diff patch 精确回滚
98
+ // 尝试用 diff patch 精确回滚。
99
+ // 关键设计:applyPatch 失败时不再静默回退到 beforeContent(那会丢弃用户/其他任务
100
+ // 对该文件的所有改动),而是报为 preview_failed,让前端弹出
101
+ // "跳过不通过项 / 文件全量覆盖" 二选一对话框。
97
102
  const patch = await readDiffFromCache(normalizedWorkspace, op.cacheKey);
103
+ if (patch === null) {
104
+ const reason = `本地缓存中找不到 diff 补丁 (cacheKey=${op.cacheKey}),无法精确回滚`;
105
+ errors.push(`UPDATE rollback failed: ${reason} for ${relativePath}`);
106
+ details.push({ relativePath, originalOperation: 'UPDATE', status: 'preview_failed', reason });
107
+ break;
108
+ }
98
109
  let rollbackContent = null;
99
- let rollbackMethod = 'beforeContent 兜底';
100
- if (patch !== null) {
101
- try {
102
- const parsed = Diff.parsePatch(patch);
103
- const reversed = Diff.reversePatch(parsed);
104
- const result = Diff.applyPatch(currentContent, reversed);
105
- if (result !== false) {
106
- rollbackContent = result;
107
- rollbackMethod = '反向 diff 补丁';
108
- }
109
- else {
110
- log.warn(`Diff patch failed for ${relativePath}, falling back to beforeContent`);
111
- }
112
- }
113
- catch (err) {
114
- log.warn(`Diff patch error for ${relativePath}: ${err.message}, falling back to beforeContent`);
110
+ try {
111
+ const parsed = Diff.parsePatch(patch);
112
+ const reversed = Diff.reversePatch(parsed);
113
+ const result = Diff.applyPatch(currentContent, reversed);
114
+ if (result !== false) {
115
+ rollbackContent = result;
115
116
  }
116
- }
117
- // diff patch 失败时,用 beforeContent 兜底
118
- if (rollbackContent === null) {
119
- const beforeContent = await readBeforeContentFromCache(normalizedWorkspace, op.cacheKey);
120
- if (beforeContent === null) {
121
- const reason = `diff 补丁应用失败且本地缓存中找不到 beforeContent (cacheKey=${op.cacheKey})`;
117
+ else {
118
+ // 反向 diff 补丁无法精确应用(上下文不匹配),
119
+ // 说明文件已被其他任务或用户修改了 AI 改动的同一区域,存在冲突。
120
+ const reason = `反向 diff 补丁无法精确应用:文件当前内容与 AI 变更后的预期上下文不匹配,可能已被其他任务或用户修改了相同区域,存在冲突`;
122
121
  errors.push(`UPDATE rollback failed: ${reason} for ${relativePath}`);
123
122
  details.push({ relativePath, originalOperation: 'UPDATE', status: 'preview_failed', reason });
124
123
  break;
125
124
  }
126
- rollbackContent = beforeContent;
125
+ }
126
+ catch (err) {
127
+ const reason = `反向 diff 补丁应用异常: ${err.message}`;
128
+ errors.push(`UPDATE rollback failed: ${reason} for ${relativePath}`);
129
+ details.push({ relativePath, originalOperation: 'UPDATE', status: 'preview_failed', reason });
130
+ break;
127
131
  }
128
132
  plan.push({ type: 'WRITE', fullPath, relativePath, originalOperation: 'UPDATE', content: rollbackContent });
129
- details.push({ relativePath, originalOperation: 'UPDATE', status: 'preview_passed', action: rollbackMethod });
133
+ details.push({ relativePath, originalOperation: 'UPDATE', status: 'preview_passed', action: '应用反向 diff 补丁' });
130
134
  // 更新内存状态:文件内容已回滚
131
135
  fileContentMap.set(relativePath, rollbackContent);
132
136
  break;
@@ -243,7 +247,7 @@ fileDiffRollbackRouter.post('/file-diff-rollback/preview', validateToken, async
243
247
  * 无论成功失败,都返回每条操作的详细状态。
244
248
  */
245
249
  fileDiffRollbackRouter.post('/file-diff-rollback/execute', validateToken, async (req, res) => {
246
- const { workspacePath, operations } = req.body;
250
+ const { workspacePath, operations, skipFailed } = req.body;
247
251
  if (!workspacePath || !Array.isArray(operations)) {
248
252
  res.status(400).json({ error: 'workspacePath and operations (array) are required' });
249
253
  return;
@@ -251,6 +255,25 @@ fileDiffRollbackRouter.post('/file-diff-rollback/execute', validateToken, async
251
255
  // ── 第一步:内存预检 ──
252
256
  const preview = await previewRollback(workspacePath, operations);
253
257
  if (!preview.ok) {
258
+ // 策略:仅执行通过预检的项(跳过失败项)。
259
+ // preview.plan 只装通过项,且链式预演中失败项不会污染 fileContentMap,
260
+ // 因此通过项预计算出的目标内容天然保留了失败项的改动 —— 直接执行 plan 即等价于"跳过不通过项"。
261
+ if (skipFailed && preview.plan.length > 0) {
262
+ const execResult = await executePlan(preview.plan, preview.details);
263
+ const failedCount = preview.details.filter((d) => d.status === 'preview_failed').length;
264
+ log.warn(`Diff rollback partial execute: passed=${execResult.restored}, skippedFailed=${failedCount}, ioSkipped=${execResult.skipped}`);
265
+ const result = {
266
+ ok: execResult.errors.length === 0,
267
+ restored: execResult.restored,
268
+ skipped: execResult.skipped + failedCount,
269
+ errors: execResult.errors,
270
+ previewFailed: false,
271
+ partial: true,
272
+ details: execResult.details,
273
+ };
274
+ res.json(result);
275
+ return;
276
+ }
254
277
  const result = {
255
278
  ok: false,
256
279
  restored: 0,
@@ -40,6 +40,20 @@ export declare class ACodeRuntime extends EventEmitter {
40
40
  private submitQueue;
41
41
  private activeTurn;
42
42
  private abortRequested;
43
+ /**
44
+ * 当前正在 await_sub_agents 工具中阻塞等待的子 agent subId 集合。
45
+ *
46
+ * 用于让 abort()/stop() 能中断 awaitSubAgents 的阻塞:
47
+ * - awaitSubAgents 调用前把 subIds 加入此 set,finally 中移除
48
+ * - abort()/stop() 时对此 set 中每个 subId 调用 manager.abort(subId)
49
+ * - manager.abort 会 settle completionPromise(resolve with error)
50
+ * - 从而让 await completionPromise 解除阻塞,execute() 正常返回,
51
+ * executeSubmit 不再永久 pending,submitQueue 链恢复,后续 submit 可执行。
52
+ *
53
+ * 没有此机制时:abort() 只能中断 fetch 流,对 await completionPromise 无效,
54
+ * 导致 executeSubmit 永久阻塞 → submitQueue 死锁 → 后续 sendMessage 全部排队 → agent 无反应。
55
+ */
56
+ private pendingAwaitedSubIds;
43
57
  private sessionCompleteEmitted;
44
58
  private contextVersion;
45
59
  private readonly stopWaiters;
@@ -174,6 +188,28 @@ export declare class ACodeRuntime extends EventEmitter {
174
188
  * 在 abort()/stop() 中调用,确保用户点停止或会话终止时 execute 不会永久阻塞。
175
189
  */
176
190
  private rejectAllQuestionWaiters;
191
+ /**
192
+ * 取消当前正在 await_sub_agents 工具中阻塞等待的子 agent。
193
+ *
194
+ * 核心作用:让 abort()/stop() 能解除 awaitSubAgents 的阻塞,避免 submitQueue 死锁。
195
+ *
196
+ * 工作原理:
197
+ * 1. 遍历 pendingAwaitedSubIds(awaitSubAgents 工具执行期间记录的 subIds)
198
+ * 2. 对每个 subId 调用 manager.abort(subId)
199
+ * 3. manager.abort 会 settle completionPromise(resolve with error="aborted")
200
+ * 4. awaitSubAgents 中 await completionPromise 解除阻塞,execute() 正常返回
201
+ * 5. executeSubmit 完成,submit() Promise resolve,submitQueue 链恢复
202
+ * 6. 后续 sendMessage / auto-poll 的 submit 能正常排队执行
203
+ *
204
+ * 场景:看门狗触发 abort() 或用户点击停止时,agent 正卡在 await_sub_agents
205
+ * 等待子 agent 完成。若不取消子 agent,completionPromise 永不 settle,
206
+ * executeSubmit 永久 pending,submitQueue 死锁,agent 彻底无反应。
207
+ *
208
+ * 注意:此方法 fire-and-forget,不 await manager.abort 完成。
209
+ * manager.abort 内部会同步 settle completionPromise(通过 completionResolve),
210
+ * 解除 awaitSubAgents 阻塞无需等待 abort I/O 完成。
211
+ */
212
+ private cancelPendingAwaitedSubAgents;
177
213
  /** 终止 ACode 会话并发出 session_complete。 */
178
214
  stop(): Promise<void>;
179
215
  private resolveCommandDirs;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -1018,6 +1018,20 @@ export class ACodeRuntime extends EventEmitter {
1018
1018
  this.submitQueue = Promise.resolve();
1019
1019
  this.activeTurn = false;
1020
1020
  this.abortRequested = false;
1021
+ /**
1022
+ * 当前正在 await_sub_agents 工具中阻塞等待的子 agent subId 集合。
1023
+ *
1024
+ * 用于让 abort()/stop() 能中断 awaitSubAgents 的阻塞:
1025
+ * - awaitSubAgents 调用前把 subIds 加入此 set,finally 中移除
1026
+ * - abort()/stop() 时对此 set 中每个 subId 调用 manager.abort(subId)
1027
+ * - manager.abort 会 settle completionPromise(resolve with error)
1028
+ * - 从而让 await completionPromise 解除阻塞,execute() 正常返回,
1029
+ * executeSubmit 不再永久 pending,submitQueue 链恢复,后续 submit 可执行。
1030
+ *
1031
+ * 没有此机制时:abort() 只能中断 fetch 流,对 await completionPromise 无效,
1032
+ * 导致 executeSubmit 永久阻塞 → submitQueue 死锁 → 后续 sendMessage 全部排队 → agent 无反应。
1033
+ */
1034
+ this.pendingAwaitedSubIds = new Set();
1021
1035
  this.sessionCompleteEmitted = false;
1022
1036
  this.contextVersion = 0;
1023
1037
  this.stopWaiters = new Set();
@@ -1704,6 +1718,15 @@ export class ACodeRuntime extends EventEmitter {
1704
1718
  this.abortController = null;
1705
1719
  // ask_user_question 等待用户回答期间被 abort,需 reject 所有 waiter
1706
1720
  this.rejectAllQuestionWaiters("aborted");
1721
+ // ★ 取消正在 await_sub_agents 中阻塞等待的子 agent,让 completionPromise settle,
1722
+ // 解除 execute() 阻塞,避免 submitQueue 永久死锁导致 agent 无反应。
1723
+ this.cancelPendingAwaitedSubAgents();
1724
+ // ★ 触发 stopWaiters,中断正在执行的 MCP 工具调用(callTool)。
1725
+ // MCP callTool 不监听 abortController.signal,只通过 stopWaiter.promise 被中断。
1726
+ // 若不触发,MCP 工具超过 120s 后看门狗触发 abort,但 callTool 仍 pending,
1727
+ // executeSubmit 永久阻塞 → submitQueue 死锁 → agent 无反应。
1728
+ // stopWaiters 是一次性的(触发后清空),不影响后续轮次的新 stopWaiter。
1729
+ this.notifyRuntimeStop();
1707
1730
  }
1708
1731
  /**
1709
1732
  * 构造 ask_user_question 工具的依赖注入。
@@ -1811,7 +1834,26 @@ export class ACodeRuntime extends EventEmitter {
1811
1834
  };
1812
1835
  },
1813
1836
  // 阻塞等待指定子 agent 数组完成
1814
- awaitSubAgents: (subIds, timeoutMs) => manager.awaitCompletion(subIds, timeoutMs),
1837
+ // ★ 记录正在等待的 subIds pendingAwaitedSubIds,让 abort()/stop() 能中断此阻塞:
1838
+ // manager.abort(subId) 会 settle completionPromise,使 await completionPromise 解除阻塞,
1839
+ // execute() 正常返回,executeSubmit 不再永久 pending,submitQueue 链恢复。
1840
+ awaitSubAgents: async (subIds, timeoutMs) => {
1841
+ // 记录当前等待的 subIds(用于 abort/stop 时中断)
1842
+ const tracking = new Set();
1843
+ for (const id of subIds) {
1844
+ this.pendingAwaitedSubIds.add(id);
1845
+ tracking.add(id);
1846
+ }
1847
+ try {
1848
+ return await manager.awaitCompletion(subIds, timeoutMs);
1849
+ }
1850
+ finally {
1851
+ // 清理跟踪记录(无论成功/失败/中断都需清理)
1852
+ for (const id of tracking) {
1853
+ this.pendingAwaitedSubIds.delete(id);
1854
+ }
1855
+ }
1856
+ },
1815
1857
  // 终止某子 agent
1816
1858
  abortSubAgent: (subId) => manager.abort(subId),
1817
1859
  };
@@ -1846,6 +1888,42 @@ export class ACodeRuntime extends EventEmitter {
1846
1888
  }
1847
1889
  this.questionWaiters.clear();
1848
1890
  }
1891
+ /**
1892
+ * 取消当前正在 await_sub_agents 工具中阻塞等待的子 agent。
1893
+ *
1894
+ * 核心作用:让 abort()/stop() 能解除 awaitSubAgents 的阻塞,避免 submitQueue 死锁。
1895
+ *
1896
+ * 工作原理:
1897
+ * 1. 遍历 pendingAwaitedSubIds(awaitSubAgents 工具执行期间记录的 subIds)
1898
+ * 2. 对每个 subId 调用 manager.abort(subId)
1899
+ * 3. manager.abort 会 settle completionPromise(resolve with error="aborted")
1900
+ * 4. awaitSubAgents 中 await completionPromise 解除阻塞,execute() 正常返回
1901
+ * 5. executeSubmit 完成,submit() Promise resolve,submitQueue 链恢复
1902
+ * 6. 后续 sendMessage / auto-poll 的 submit 能正常排队执行
1903
+ *
1904
+ * 场景:看门狗触发 abort() 或用户点击停止时,agent 正卡在 await_sub_agents
1905
+ * 等待子 agent 完成。若不取消子 agent,completionPromise 永不 settle,
1906
+ * executeSubmit 永久 pending,submitQueue 死锁,agent 彻底无反应。
1907
+ *
1908
+ * 注意:此方法 fire-and-forget,不 await manager.abort 完成。
1909
+ * manager.abort 内部会同步 settle completionPromise(通过 completionResolve),
1910
+ * 解除 awaitSubAgents 阻塞无需等待 abort I/O 完成。
1911
+ */
1912
+ cancelPendingAwaitedSubAgents() {
1913
+ if (this.pendingAwaitedSubIds.size === 0)
1914
+ return;
1915
+ const manager = this.config.subAgentManager;
1916
+ if (!manager)
1917
+ return;
1918
+ const subIds = Array.from(this.pendingAwaitedSubIds);
1919
+ runtimeDebugLog(`[ACodeRuntime] ⛔ Cancelling ${subIds.length} pending awaited sub-agent(s): ${subIds.join(", ")}`);
1920
+ // fire-and-forget:manager.abort 内部同步 settle completionPromise 即可解除阻塞
1921
+ for (const subId of subIds) {
1922
+ void manager.abort(subId).catch((err) => {
1923
+ runtimeDebugLog(`[ACodeRuntime] ⚠️ manager.abort(${subId}) threw: ${err instanceof Error ? err.message : String(err)}`);
1924
+ });
1925
+ }
1926
+ }
1849
1927
  /** 终止 ACode 会话并发出 session_complete。 */
1850
1928
  async stop() {
1851
1929
  if (this.state.terminated) {
@@ -1858,6 +1936,9 @@ export class ACodeRuntime extends EventEmitter {
1858
1936
  this.abortController = null;
1859
1937
  // ask_user_question 等待用户回答期间被 stop,需 reject 所有 waiter
1860
1938
  this.rejectAllQuestionWaiters("session terminated");
1939
+ // ★ 取消正在 await_sub_agents 中阻塞等待的子 agent,让 completionPromise settle,
1940
+ // 解除 execute() 阻塞,避免 submitQueue 永久死锁。
1941
+ this.cancelPendingAwaitedSubAgents();
1861
1942
  await runBestEffort("ACode active turn shutdown", this.submitQueue, (message) => {
1862
1943
  this.emitAcodeEvent("error", { message });
1863
1944
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws-runtime-bridge",
3
- "version": "1.9.50",
3
+ "version": "1.9.51",
4
4
  "description": "AgentsWorkStudio runtime bridge service for machine-level agent runtime integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",