aws-runtime-bridge 1.9.55 → 1.9.57

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 (29) hide show
  1. package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -1
  2. package/dist/adapter/AcodeSdkAdapter.js +41 -10
  3. package/dist/routes/sub-agents.js +1 -1
  4. package/dist/routes/terminal.d.ts +17 -0
  5. package/dist/routes/terminal.d.ts.map +1 -1
  6. package/dist/routes/terminal.js +131 -7
  7. package/dist/services/agent-event-store.d.ts +1 -0
  8. package/dist/services/agent-event-store.d.ts.map +1 -1
  9. package/dist/services/agent-event-store.js +23 -10
  10. package/dist/services/session-output.d.ts +1 -1
  11. package/dist/services/session-output.d.ts.map +1 -1
  12. package/dist/services/session-output.js +57 -16
  13. package/package/acode/dist/sub-agent-manager.d.ts.map +1 -1
  14. package/package/acode/dist/sub-agent-manager.js +9 -0
  15. package/package/acode/dist/sub-agent-types.d.ts +1 -1
  16. package/package/acode/dist/sub-agent-types.d.ts.map +1 -1
  17. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +6 -0
  18. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
  19. package/package/aws-client-agent-mcp/dist/mcp-server.js +69 -7
  20. package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
  21. package/package/aws-client-agent-mcp/dist/mcp-server.test.js +84 -0
  22. package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
  23. package/package/aws-client-agent-mcp/dist/memory-store.d.ts.map +1 -1
  24. package/package/aws-client-agent-mcp/dist/memory-store.js +21 -8
  25. package/package/aws-client-agent-mcp/dist/memory-store.js.map +1 -1
  26. package/package/aws-client-agent-mcp/dist/memory-tools.d.ts.map +1 -1
  27. package/package/aws-client-agent-mcp/dist/memory-tools.js +18 -2
  28. package/package/aws-client-agent-mcp/dist/memory-tools.js.map +1 -1
  29. package/package.json +2 -1
@@ -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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"}
@@ -48,6 +48,17 @@ const ACODE_WATCHDOG_POLL_INTERVAL_MS = 5_000;
48
48
  // 触发 recoverTurnFailure 强制恢复。覆盖 provider requestTimeoutMs 配置不当或流挂死等场景。
49
49
  // 仅在 thinking/tool_using 状态下累计计时,waiting_input 状态下不计时(agent 正在有意等待)。
50
50
  const ACODE_DATA_FLOW_STREAM_WATCHDOG_MS = 40_000;
51
+ /**
52
+ * tool_using 慢超时兜底(毫秒)。
53
+ * ★ 修复 BUG:原实现 tool_using 状态完全无超时保护——
54
+ * - ask_user_question 依赖 question_request 事件取消看门狗,但事件丢失时永久卡死
55
+ * - await_sub_agents 依赖子 agent 自己的 runtime 看门狗,子 agent 崩溃不通知时永久卡死
56
+ * - 工具内部 hang(如 bash 等待 stdin、MCP 工具死锁)无兜底
57
+ * 设 5min 兜底:远大于正常工具耗时(MCP 60s / Bash 默认 30s / 文件操作通常 < 5s),
58
+ * 仅在工具确实彻底 hang 时触发恢复。每次 tool_use_start 会重置 watchdogLastDataFlowTime,
59
+ * 连续多个工具串接不会累积超时。
60
+ */
61
+ const ACODE_TOOL_USING_SLOW_TIMEOUT_MS = 5 * 60_000;
51
62
  const ACODE_AUTO_POLL_DELAY_MS = 250;
52
63
  // Backoff used when a polling-driven turn fails (e.g., 60s MCP tool timeout,
53
64
  // model 5xx, provider unreachable). Larger than ACODE_AUTO_POLL_DELAY_MS to
@@ -1150,6 +1161,8 @@ export class AcodeSdkAdapter extends EventEmitter {
1150
1161
  const actionInput = toolInput ? JSON.stringify(toolInput, null, 2) : undefined;
1151
1162
  const eventData = {
1152
1163
  toolName: actionDetail,
1164
+ // ★ 保存原始工具名(如 "acode__await_sub_agents"),供看门狗豁免判断使用
1165
+ rawToolName: toolName,
1153
1166
  actionType: actionInfo.actionType,
1154
1167
  actionLabel: actionInfo.actionLabel,
1155
1168
  actionDetail,
@@ -1801,17 +1814,35 @@ export class AcodeSdkAdapter extends EventEmitter {
1801
1814
  currentEntry.watchdogLastDataFlowTime = now;
1802
1815
  return;
1803
1816
  }
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 误触发。
1817
+ // ★ tool_using 慢超时兜底:原实现完全无超时,工具 hang 时永久卡死。
1818
+ // 现加 5min 慢超时,仅当工具确实彻底 hang(无 tool_use_end、无状态切换)时触发恢复。
1819
+ // - 正常工具调用:tool_use_end 会切换状态为 thinking/waiting_input,重置计时
1820
+ // - 多工具串接:每个 tool_use_start 重置 watchdogLastDataFlowTime,不累积
1821
+ // - ask_user_question:question_request 事件切到 waiting_input,自动重置
1822
+ // 恢复方式与 thinking 一致:abort + recoverTurnFailure(补发 tool_use_end)。
1813
1823
  if (status === "tool_using") {
1814
- currentEntry.watchdogLastDataFlowTime = now;
1824
+ const toolUsingElapsed = now - (currentEntry.watchdogLastDataFlowTime || now);
1825
+ if (toolUsingElapsed >= ACODE_TOOL_USING_SLOW_TIMEOUT_MS) {
1826
+ // ★ 豁免 await_sub_agents:父 agent 阻塞等待子 agent 完成,
1827
+ // 多个子 agent 串行执行总时长可能远超 5min(每个子 agent 自带看门狗)。
1828
+ // 对其触发 abort 会中断所有正在跑的子 agent,造成不可恢复的混乱。
1829
+ // 仅记录告警 + 重置计时,让等待继续。子 agent 卡死时由各自的看门狗处理。
1830
+ const rawToolName = String(currentEntry.pendingToolEventData?.rawToolName ?? "");
1831
+ if (rawToolName.endsWith("await_sub_agents")) {
1832
+ console.warn(`[ACode] tool_using elapsed ${Math.round(toolUsingElapsed / 1000)}s but await_sub_agents ` +
1833
+ `is running (session: ${sessionId}, tool: ${rawToolName}), skipping recovery ` +
1834
+ `(sub-agents have their own watchdogs)`);
1835
+ currentEntry.watchdogSubmitStartTime = now;
1836
+ currentEntry.watchdogLastDataFlowTime = now;
1837
+ return;
1838
+ }
1839
+ console.warn(`[ACode] CRITICAL: tool_using slow timeout triggered after ${Math.round(toolUsingElapsed / 1000)}s ` +
1840
+ `(source: ${source}, session: ${sessionId}). ` +
1841
+ `Tool execution likely hung. Forcing recovery via recoverTurnFailure.`);
1842
+ this.executeWatchdogRecovery(sessionId, currentEntry, source, "tool_using_slow", toolUsingElapsed);
1843
+ return;
1844
+ }
1845
+ // 未超时则重置 submit 计时(避免 tool_using 期间累积到下一次 thinking 误触发 submit_timeout)
1815
1846
  currentEntry.watchdogSubmitStartTime = now;
1816
1847
  return;
1817
1848
  }
@@ -185,7 +185,7 @@ subAgentsRouter.get("/sub-agents/:agentId/:subId", validateToken, async (req, re
185
185
  });
186
186
  /**
187
187
  * GET /runtime/sub-agents/:agentId/:subId/events
188
- * SSE 实时事件流(sub-agent 运行期间推送 spawned/running/tool_start/delta/tool_end/completed/failed/cancelled)。
188
+ * SSE 实时事件流(sub-agent 运行期间推送 spawned/running/tool_start/delta/tool_end/progress/completed/failed/cancelled)。
189
189
  *
190
190
  * 客户端关闭连接时自动取消订阅。
191
191
  */
@@ -160,6 +160,23 @@ export declare function resolveRuntimeStatusFromProviderEvent(event: ProviderEve
160
160
  status: string;
161
161
  actionInfo?: RuntimeStatusActionInfo;
162
162
  } | undefined;
163
+ /**
164
+ * 带超时 + 重试的 sendOutput 包装器。
165
+ * ★ 修复 BUG:原 raceSendOutput 超时后仅放行队列,不取消底层请求,
166
+ * 导致顺序错乱 + 切断合法重试。新方案:
167
+ * 1. AbortController 在超时时真正取消底层 axios 请求(防止迟到请求污染顺序)
168
+ * 2. 超时或 sendOutput 抛出非 abort 错误后重试(最多 2 次,1s/2s 退避),
169
+ * 覆盖瞬时网络问题 / 服务端 5xx / axios 超时等
170
+ * 3. 服务端按 (agentId, sessionId, seq) 幂等去重,即使超时的请求最终到达也不会重复
171
+ * 4. 所有重试失败后 resolve(不 reject),放行队列下一条
172
+ * 5. 成功路径必须 clearTimeout,否则 30s 后 timeout promise reject 无人 await,
173
+ * 触发 unhandledRejection 导致进程崩溃
174
+ *
175
+ * @param factory - 接收 AbortSignal,返回 sendOutput Promise(每次重试创建新请求)
176
+ * @param timeoutMs - 单次请求超时
177
+ * @param maxRetries - 最大重试次数(不含首次)
178
+ */
179
+ export declare function raceSendOutputWithRetry(factory: (signal: AbortSignal) => Promise<void>, timeoutMs?: number, maxRetries?: number): Promise<void>;
163
180
  export declare function resolveSdkProviderId(command?: string): string;
164
181
  export {};
165
182
  //# sourceMappingURL=terminal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"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"}
@@ -613,9 +613,14 @@ function appendCommandOutput(entry, output) {
613
613
  return;
614
614
  }
615
615
  entry.seq += 1;
616
+ // ★ sendOutput 对非 abort 错误会 rethrow(供 raceSendOutputWithRetry 重试),
617
+ // 此处 fire-and-forget 调用必须 .catch 避免 unhandledRejection。
618
+ // 命令输出丢失可接受(本地 buffer 已在 finally 记录),不重试。
616
619
  void sendOutput(entry.agentId, output, entry.sessionId, entry.seq, undefined, {
617
620
  runtimeAccessToken: entry.runtimeAccessToken,
618
621
  schedulerBaseUrl: entry.schedulerBaseUrl,
622
+ }).catch(() => {
623
+ // sendOutput 内部已 logger.warn,此处静默即可
619
624
  });
620
625
  }
621
626
  /**
@@ -1314,12 +1319,84 @@ const sdkOutputQueueBySession = new Map();
1314
1319
  // ★ 根因:runtime.ts 同步连续发射 start/detect 等事件,多个 void sendStatus 并发执行 HTTP POST,
1315
1320
  // 部分 HTTP 请求因竞争/超时/Java 后端 FOR UPDATE 锁等待而失败,事件永久丢失(本地 buffer 不重推)。
1316
1321
  const compactionStatusChainBySession = new Map();
1322
+ /**
1323
+ * ★ 修复 BUG:idle 类工具(poll_message)状态变更的串行重试队列。
1324
+ * poll_message 的 tool_use_start/tool_use_end 切换 status 至关重要,
1325
+ * 若 sendStatus HTTP 失败,前端 base.runtimeStatus 会卡在上一个状态,
1326
+ * 导致"实际在 poll_message 阻塞但显示思考中"的假象。
1327
+ * 串行化 + 2 次重试确保关键状态变更最终到达,仍失败则前端兜底恢复显示。
1328
+ */
1329
+ const idleStatusChainBySession = new Map();
1317
1330
  /** 小 chunk 积攒缓存:sessionId:sourceEventType → { buffer, seq, timer, sourceEventType, entry },不足 20 字符时积攒最多 500ms 再推送 */
1318
1331
  const sdkOutputSmallChunkAccumulators = new Map();
1319
1332
  /** 小 chunk 积攒阈值:字符数少于此值的 output 事件积攒发送 */
1320
1333
  const SMALL_CHUNK_CHAR_THRESHOLD = 20;
1321
1334
  /** 小 chunk 最大积攒时间(毫秒) */
1322
1335
  const SMALL_CHUNK_MAX_ACCUMULATE_MS = 500;
1336
+ /**
1337
+ * 串行队列单条 sendOutput 的最大允许时长(毫秒)。
1338
+ * ★ 修复 BUG(原 raceSendOutput):
1339
+ * 1. 超时后不取消底层请求 → 顺序错乱(超时的 A 在 B 之后到达服务端)
1340
+ * 2. 20s 超时切断 sendOutput 内部合法的 401 重试链路(15s×2=30s)
1341
+ * 新方案:AbortController 真正取消底层请求 + 超时重试 + 服务端 (agentId,sessionId,seq) 幂等。
1342
+ * timeout 取 30s 覆盖 sendOutput 内部 401 重试链路(15s + 15s)。
1343
+ */
1344
+ const SEND_OUTPUT_QUEUE_TIMEOUT_MS = 30_000;
1345
+ /**
1346
+ * 带超时 + 重试的 sendOutput 包装器。
1347
+ * ★ 修复 BUG:原 raceSendOutput 超时后仅放行队列,不取消底层请求,
1348
+ * 导致顺序错乱 + 切断合法重试。新方案:
1349
+ * 1. AbortController 在超时时真正取消底层 axios 请求(防止迟到请求污染顺序)
1350
+ * 2. 超时或 sendOutput 抛出非 abort 错误后重试(最多 2 次,1s/2s 退避),
1351
+ * 覆盖瞬时网络问题 / 服务端 5xx / axios 超时等
1352
+ * 3. 服务端按 (agentId, sessionId, seq) 幂等去重,即使超时的请求最终到达也不会重复
1353
+ * 4. 所有重试失败后 resolve(不 reject),放行队列下一条
1354
+ * 5. 成功路径必须 clearTimeout,否则 30s 后 timeout promise reject 无人 await,
1355
+ * 触发 unhandledRejection 导致进程崩溃
1356
+ *
1357
+ * @param factory - 接收 AbortSignal,返回 sendOutput Promise(每次重试创建新请求)
1358
+ * @param timeoutMs - 单次请求超时
1359
+ * @param maxRetries - 最大重试次数(不含首次)
1360
+ */
1361
+ export async function raceSendOutputWithRetry(factory, timeoutMs = SEND_OUTPUT_QUEUE_TIMEOUT_MS, maxRetries = 2) {
1362
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
1363
+ const controller = new AbortController();
1364
+ let timer;
1365
+ try {
1366
+ // 创建请求 promise,预 attach catch 避免 abort 导致 unhandled rejection
1367
+ const requestPromise = factory(controller.signal);
1368
+ requestPromise.catch(() => { });
1369
+ await Promise.race([
1370
+ requestPromise,
1371
+ new Promise((_, reject) => {
1372
+ timer = setTimeout(() => {
1373
+ controller.abort();
1374
+ reject(new Error(`sendOutput timeout after ${timeoutMs}ms`));
1375
+ }, timeoutMs);
1376
+ }),
1377
+ ]);
1378
+ // ★ 成功路径必须清除 timer:否则 30s 后 timer 触发 reject,
1379
+ // 该 timeout promise 无人 await,会触发 unhandledRejection 导致进程崩溃。
1380
+ if (timer)
1381
+ clearTimeout(timer);
1382
+ return; // 成功
1383
+ }
1384
+ catch (err) {
1385
+ if (timer)
1386
+ clearTimeout(timer);
1387
+ const errMsg = err instanceof Error ? err.message : String(err);
1388
+ if (attempt < maxRetries) {
1389
+ const backoff = 1000 * (attempt + 1);
1390
+ log.warn(`sendOutput attempt ${attempt + 1}/${maxRetries + 1} failed (${errMsg}), ` +
1391
+ `retrying in ${backoff}ms...`);
1392
+ await new Promise((r) => setTimeout(r, backoff));
1393
+ continue;
1394
+ }
1395
+ log.warn(`sendOutput failed after ${maxRetries + 1} attempts (${errMsg}), ` +
1396
+ `giving up to unblock serial queue`);
1397
+ }
1398
+ }
1399
+ }
1323
1400
  function flushSmallChunkAccumulator(sessionId, sourceEventType) {
1324
1401
  const key = sourceEventType
1325
1402
  ? `${sessionId}:${sourceEventType}`
@@ -1333,11 +1410,16 @@ function flushSmallChunkAccumulator(sessionId, sourceEventType) {
1333
1410
  }
1334
1411
  else {
1335
1412
  // 刷新该 sessionId 下的所有 accumulator(可能有多种 sourceEventType)
1413
+ // ★ 先收集匹配 key 再逐个 flush,避免递归调用在迭代中 delete 同一 Map(虽然 JS 规范安全,但代码坏味道)。
1414
+ const keysToFlush = [];
1336
1415
  for (const [k, v] of sdkOutputSmallChunkAccumulators) {
1337
1416
  if (k.startsWith(sessionId + ":") && v.buffer) {
1338
- flushSmallChunkAccumulator(sessionId, v.sourceEventType);
1417
+ keysToFlush.push(v.sourceEventType);
1339
1418
  }
1340
1419
  }
1420
+ for (const sourceType of keysToFlush) {
1421
+ flushSmallChunkAccumulator(sessionId, sourceType);
1422
+ }
1341
1423
  return;
1342
1424
  }
1343
1425
  if (!acc || !acc.buffer)
@@ -1359,7 +1441,7 @@ function flushSmallChunkAccumulator(sessionId, sourceEventType) {
1359
1441
  schedulerBaseUrl: entry.schedulerBaseUrl,
1360
1442
  };
1361
1443
  const prev = sdkOutputQueueBySession.get(sessionId) ?? Promise.resolve();
1362
- const next = prev.then(() => sendOutput(entry.agentId, output, sessionId, seq, metadata, authOptions), () => sendOutput(entry.agentId, output, sessionId, seq, metadata, authOptions));
1444
+ const next = prev.then(() => raceSendOutputWithRetry((signal) => sendOutput(entry.agentId, output, sessionId, seq, metadata, authOptions, signal)), () => raceSendOutputWithRetry((signal) => sendOutput(entry.agentId, output, sessionId, seq, metadata, authOptions, signal)));
1363
1445
  sdkOutputQueueBySession.set(sessionId, next);
1364
1446
  void next.finally(() => {
1365
1447
  if (sdkOutputQueueBySession.get(sessionId) === next) {
@@ -1409,7 +1491,7 @@ function enqueueSdkOutputEvent(event, entry) {
1409
1491
  // 大 chunk 直接发送(先刷新可能存在的积攒缓存)
1410
1492
  flushSmallChunkAccumulator(event.sessionId);
1411
1493
  const prev = sdkOutputQueueBySession.get(event.sessionId) ?? Promise.resolve();
1412
- const next = prev.then(() => sendOutput(entry.agentId, output, event.sessionId, seq, metadata, authOptions), () => sendOutput(entry.agentId, output, event.sessionId, seq, metadata, authOptions));
1494
+ const next = prev.then(() => raceSendOutputWithRetry((signal) => sendOutput(entry.agentId, output, event.sessionId, seq, metadata, authOptions, signal)), () => raceSendOutputWithRetry((signal) => sendOutput(entry.agentId, output, event.sessionId, seq, metadata, authOptions, signal)));
1413
1495
  sdkOutputQueueBySession.set(event.sessionId, next);
1414
1496
  // 队列空闲时自动清理,避免内存泄漏
1415
1497
  void next.finally(() => {
@@ -1490,6 +1572,12 @@ function wireSdkAdapterEvents(adapter, definition) {
1490
1572
  adapter.on("status-change", (sessionId, status, actionInfo) => {
1491
1573
  const entry = sdkSessions.get(sessionId);
1492
1574
  if (entry) {
1575
+ // ★ 状态切换时主动 flush 小 chunk accumulator:
1576
+ // 原实现只在收到大 chunk 时 flush,状态切换(如 thinking → tool_using)会
1577
+ // 让 < 20 字符的思考内容残留在 accumulator 中,直到下次同类型 chunk 到达才被
1578
+ // 一起发出,导致时间线顺序错乱(思考内容显示在工具调用之后)。
1579
+ // 现在每次状态切换都先 flush 该 session 下所有 accumulator,保证顺序正确。
1580
+ flushSmallChunkAccumulator(sessionId);
1493
1581
  // ★ 活跃状态定期刷新:防止长时间 LLM 调用期间服务端 WebSocket 空闲超时导致 LOST
1494
1582
  if (status === "thinking" || status === "tool_using" || status === "compacting") {
1495
1583
  startStatusRefresh(sessionId);
@@ -1581,10 +1669,46 @@ function wireSdkAdapterEvents(adapter, definition) {
1581
1669
  // 不传 restoredActionInfo,避免 dashboard 创建第二个"调用MCP"时间线条目。
1582
1670
  // tool_use_start 的 status-change 已创建了一个条目,这里只需纯状态变更。
1583
1671
  const skipRestoredActionInfo = shouldPreservePrevAction && !runtimeState.actionInfo?.actionType;
1584
- void sendStatus(entry.agentId, sessionId, runtimeState.status, skipRestoredActionInfo ? undefined : restoredActionInfo, resolveStatusChangeUsage(runtimeState.actionInfo), {
1585
- runtimeAccessToken: entry.runtimeAccessToken,
1586
- schedulerBaseUrl: entry.schedulerBaseUrl,
1587
- });
1672
+ // 修复 BUG:idle 类工具(poll_message)的关键状态切换走串行重试队列,
1673
+ // 避免 sendStatus HTTP 失败导致前端 base.runtimeStatus 卡在上一个状态。
1674
+ // 场景:poll_message 返回 → tool_use_end → status="thinking" →
1675
+ // agent 立即调用下一个 poll_message → tool_use_start → status="waiting_input" →
1676
+ // 若 sendStatus 失败,前端 base.runtimeStatus 卡在 thinking,但实际 agent 已在 poll_message 阻塞。
1677
+ // 重试 2 次(1s/2s 退避),仍失败则前端兜底(findRecentPollingBlockEvent)恢复显示。
1678
+ const isIdleToolStatusChange = restoredActionInfo?.actionType === "idle" ||
1679
+ (entry.currentRuntimeActionType === "idle" && shouldPreservePrevAction);
1680
+ if (isIdleToolStatusChange) {
1681
+ const prev = idleStatusChainBySession.get(sessionId) ?? Promise.resolve();
1682
+ const next = prev.then(async () => {
1683
+ const maxRetries = 2;
1684
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
1685
+ const response = await sendStatus(entry.agentId, sessionId, runtimeState.status, skipRestoredActionInfo ? undefined : restoredActionInfo, resolveStatusChangeUsage(runtimeState.actionInfo), {
1686
+ runtimeAccessToken: entry.runtimeAccessToken,
1687
+ schedulerBaseUrl: entry.schedulerBaseUrl,
1688
+ });
1689
+ if (response !== undefined)
1690
+ return;
1691
+ if (attempt < maxRetries) {
1692
+ await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));
1693
+ }
1694
+ }
1695
+ log.warn(`[${definition.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`);
1696
+ }).catch((err) => {
1697
+ log.warn(`[${definition.displayName}] idle status chain error:`, err);
1698
+ });
1699
+ idleStatusChainBySession.set(sessionId, next);
1700
+ next.finally(() => {
1701
+ if (idleStatusChainBySession.get(sessionId) === next) {
1702
+ idleStatusChainBySession.delete(sessionId);
1703
+ }
1704
+ });
1705
+ }
1706
+ else {
1707
+ void sendStatus(entry.agentId, sessionId, runtimeState.status, skipRestoredActionInfo ? undefined : restoredActionInfo, resolveStatusChangeUsage(runtimeState.actionInfo), {
1708
+ runtimeAccessToken: entry.runtimeAccessToken,
1709
+ schedulerBaseUrl: entry.schedulerBaseUrl,
1710
+ });
1711
+ }
1588
1712
  }
1589
1713
  // ★ 修复时序竞争:session 稳定到 waiting_input 时,若缓存了 runtime_capabilities
1590
1714
  // 但尚未被清除(说明第一次发送可能因 runtime_session_id 未及时更新而被服务端丢弃),
@@ -47,6 +47,7 @@ declare class AgentEventStore {
47
47
  * 追加一条 output 事件到指定 agent 的缓冲区。
48
48
  * 若最后一条也是 output 且来自同一 session + sourceEventType,
49
49
  * 则在 10s 窗口内合并内容。
50
+ * ★ 修复 BUG:合并到 8000 上限后开新条目,而不是无脑截断头部丢内容。
50
51
  * @returns 被合并或新创建的条目
51
52
  */
52
53
  appendOrMergeOutput(agentId: string, payload: BridgeEventPayload): RingBufferEntry<BridgeEventPayload>;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-event-store.d.ts","sourceRoot":"","sources":["../../src/services/agent-event-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,cAAc,CAAC;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAQD;;;;GAIG;AACH,cAAM,eAAe;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAE9D,OAAO,CAAC,YAAY;IASpB;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,eAAe,CAAC,kBAAkB,CAAC;IAIzF;;;;;OAKG;IACH,mBAAmB,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,kBAAkB,GAC1B,eAAe,CAAC,kBAAkB,CAAC;IA6BtC;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAG9B;AAED,WAAW;AACX,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
1
+ {"version":3,"file":"agent-event-store.d.ts","sourceRoot":"","sources":["../../src/services/agent-event-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,cAAc,CAAC;IACrE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAgBD;;;;GAIG;AACH,cAAM,eAAe;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAE9D,OAAO,CAAC,YAAY;IASpB;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,eAAe,CAAC,kBAAkB,CAAC;IAIzF;;;;;;OAMG;IACH,mBAAmB,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,kBAAkB,GAC1B,eAAe,CAAC,kBAAkB,CAAC;IAgCtC;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAG9B;AAED,WAAW;AACX,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
@@ -6,6 +6,14 @@
6
6
  */
7
7
  import { RingBuffer } from "./ring-buffer.js";
8
8
  const PER_AGENT_BUFFER_CAPACITY = 500;
9
+ /**
10
+ * 单条 output 事件合并后的字符上限。
11
+ * ★ 必须与 session-output.ts 的 MAX_SINGLE_OUTPUT_CHARS 保持一致:
12
+ * session-output.ts 在 finally 块按此值截断单条 output,
13
+ * 本文件按此值判断合并后是否超限。两处不一致会导致合并后仍被截断或反之。
14
+ * 修改时必须同步两处。
15
+ */
16
+ const MAX_OUTPUT_MERGE_CHARS = 8000;
9
17
  /**
10
18
  * per-agent 事件存储。
11
19
  * 每条 append/appendOrMergeOutput 调用会写入对应 agent 的环状缓冲区,
@@ -34,26 +42,31 @@ class AgentEventStore {
34
42
  * 追加一条 output 事件到指定 agent 的缓冲区。
35
43
  * 若最后一条也是 output 且来自同一 session + sourceEventType,
36
44
  * 则在 10s 窗口内合并内容。
45
+ * ★ 修复 BUG:合并到 8000 上限后开新条目,而不是无脑截断头部丢内容。
37
46
  * @returns 被合并或新创建的条目
38
47
  */
39
48
  appendOrMergeOutput(agentId, payload) {
40
49
  return this.ensureBuffer(agentId).appendOrMerge(payload, (lastEntry) => {
41
50
  const last = lastEntry.data;
42
- return (last.category === "output" &&
43
- last.sessionId === payload.sessionId &&
44
- last.sourceEventType === payload.sourceEventType &&
45
- Date.now() - lastEntry.timestamp <= 10_000);
51
+ if (last.category !== "output" ||
52
+ last.sessionId !== payload.sessionId ||
53
+ last.sourceEventType !== payload.sourceEventType ||
54
+ Date.now() - lastEntry.timestamp > 10_000) {
55
+ return false;
56
+ }
57
+ // 预估合并后长度,超上限则开新条目,避免截断丢内容
58
+ const existingLen = (last.output || "").length;
59
+ const newLen = (payload.output || "").length;
60
+ return existingLen + newLen <= MAX_OUTPUT_MERGE_CHARS;
46
61
  }, (lastData, newData) => {
47
62
  const existingOutput = lastData.output || "";
48
63
  const newOutput = newData.output || "";
49
- const merged = existingOutput.includes(newOutput)
50
- ? existingOutput
51
- : `${existingOutput}${newOutput}`;
64
+ if (existingOutput.includes(newOutput)) {
65
+ return lastData;
66
+ }
52
67
  return {
53
68
  ...lastData,
54
- output: merged.length > 8000
55
- ? `${merged.slice(0, 8000)}...(truncated)`
56
- : merged,
69
+ output: `${existingOutput}${newOutput}`,
57
70
  };
58
71
  });
59
72
  }
@@ -103,7 +103,7 @@ export declare function sendStatus(agentId: string, sessionId: string | null, st
103
103
  * @param sessionId - 会话 ID
104
104
  * @param seq - 序列号
105
105
  */
106
- export declare function sendOutput(agentId: string, output: string, sessionId: string, seq: number, metadata?: RuntimeOutputMetadata, authOptions?: RuntimeCallbackAuthOptions): Promise<void>;
106
+ export declare function sendOutput(agentId: string, output: string, sessionId: string, seq: number, metadata?: RuntimeOutputMetadata, authOptions?: RuntimeCallbackAuthOptions, signal?: AbortSignal): Promise<void>;
107
107
  /**
108
108
  * 发送 AskUserQuestion 事件到调度器。
109
109
  *
@@ -1 +1 @@
1
- {"version":3,"file":"session-output.d.ts","sourceRoot":"","sources":["../../src/services/session-output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-output.d.ts","sourceRoot":"","sources":["../../src/services/session-output.ts"],"names":[],"mappings":"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"}
@@ -69,12 +69,23 @@ async function tryRefreshRuntimeToken(serverBaseUrl) {
69
69
  tokenRefreshPromise = null;
70
70
  }
71
71
  }
72
- /** 单条 output 事件的文本长度上限(需求 4.1.3 #1),超过则截断。 */
72
+ /**
73
+ * 单条 output 事件的文本长度上限(需求 4.1.3 #1),超过则截断。
74
+ * ★ 必须与 agent-event-store.ts 的 MAX_OUTPUT_MERGE_CHARS 保持一致,修改时必须同步两处。
75
+ */
73
76
  const MAX_SINGLE_OUTPUT_CHARS = 8000;
74
77
  /** 单个会话待发送输出上限,避免调度器不可达时内存无限增长。 */
75
78
  const MAX_PENDING_OUTPUT_CHARS = 64 * 1024;
76
79
  /** 单次回调最大发送量,避免一次 POST 携带过大的终端噪声。 */
77
80
  const MAX_OUTPUT_FLUSH_CHARS = 32 * 1024;
81
+ /**
82
+ * sendOutput HTTP POST 超时(毫秒)。
83
+ * ★ 修复 BUG:原实现未设置 timeout,TCP keep-alive 失效或对端半挂时永久阻塞,
84
+ * 导致 per-session 串行队列(sdkOutputQueueBySession)后续所有 chunk 全部排队等待,
85
+ * 思考与实时输出在该 session 上全部断流。
86
+ * 取 15s 与 sendStatus 一致,足够覆盖正常网络延迟,避免长尾挂起。
87
+ */
88
+ const OUTPUT_CALLBACK_TIMEOUT_MS = 15_000;
78
89
  /** 活跃会话存储 */
79
90
  export const sessions = new Map();
80
91
  /**
@@ -232,7 +243,7 @@ export async function sendStatus(agentId, sessionId, status, actionInfo, usage,
232
243
  * @param sessionId - 会话 ID
233
244
  * @param seq - 序列号
234
245
  */
235
- export async function sendOutput(agentId, output, sessionId, seq, metadata, authOptions) {
246
+ export async function sendOutput(agentId, output, sessionId, seq, metadata, authOptions, signal) {
236
247
  const callbackBaseUrl = resolveRuntimeCallbackBaseUrl(authOptions);
237
248
  try {
238
249
  const headers = runtimeAuthHeaders(authOptions, callbackBaseUrl);
@@ -244,20 +255,37 @@ export async function sendOutput(agentId, output, sessionId, seq, metadata, auth
244
255
  });
245
256
  return;
246
257
  }
247
- await axios.post(`${callbackBaseUrl}/api/runtime/callback/output`, { agentId, output, sessionId, seq, ...metadata }, { headers });
258
+ // 仅在 signal 存在时传入,避免无 signal 调用改变 axios config 形状影响测试断言
259
+ const axiosConfig = {
260
+ headers,
261
+ timeout: OUTPUT_CALLBACK_TIMEOUT_MS,
262
+ };
263
+ if (signal)
264
+ axiosConfig.signal = signal;
265
+ await axios.post(`${callbackBaseUrl}/api/runtime/callback/output`, { agentId, output, sessionId, seq, ...metadata }, axiosConfig);
248
266
  }
249
267
  catch (error) {
268
+ // ★ 被 AbortController 取消的请求直接抛出,不触发 401 重试(重试由 raceSendOutputWithRetry 负责)
269
+ if (signal?.aborted || error?.name === "AbortError" || error?.code === "ERR_CANCELED") {
270
+ throw error;
271
+ }
250
272
  if (getAxiosStatusCode(error) === 401) {
251
273
  const refreshed = await tryRefreshRuntimeToken(callbackBaseUrl);
252
274
  if (refreshed) {
253
275
  const retryHeaders = runtimeAuthHeaders(authOptions, callbackBaseUrl);
254
276
  if (retryHeaders) {
255
277
  try {
256
- await axios.post(`${callbackBaseUrl}/api/runtime/callback/output`, { agentId, output, sessionId, seq, ...metadata }, { headers: retryHeaders });
278
+ const retryConfig = {
279
+ headers: retryHeaders,
280
+ timeout: OUTPUT_CALLBACK_TIMEOUT_MS,
281
+ };
282
+ if (signal)
283
+ retryConfig.signal = signal;
284
+ await axios.post(`${callbackBaseUrl}/api/runtime/callback/output`, { agentId, output, sessionId, seq, ...metadata }, retryConfig);
257
285
  return;
258
286
  }
259
287
  catch {
260
- // retry also failed
288
+ // retry also failed — 落入下面的 rethrow,由 raceSendOutputWithRetry 重试
261
289
  }
262
290
  }
263
291
  }
@@ -267,12 +295,18 @@ export async function sendOutput(agentId, output, sessionId, seq, metadata, auth
267
295
  sessionId,
268
296
  error,
269
297
  });
298
+ // ★ 非 abort、非 401(或 401 refresh/retry 失败)错误必须 rethrow,
299
+ // 让 raceSendOutputWithRetry 统一重试,覆盖瞬时网络问题 / 服务端 5xx / axios 超时等。
300
+ // 401 错误也 rethrow:外层重试时 tryRefreshRuntimeToken 会从缓存返回已刷新的 token,
301
+ // retry 可能成功;若 refresh 真失败,外层重试 2 次后放弃,本地 buffer 已在 finally 记录。
302
+ throw error;
270
303
  }
271
304
  finally {
272
305
  // 不论 server 回调成功或失败,都在桥接侧本地记录输出事件
273
306
  // 需求 4.1.3 #1:截断超长 output,确保单条事件体积可控
307
+ // ★ 修复 BUG:原实现截断头部,长输出尾部丢失。改为保留尾部(用户更关心最新内容)。
274
308
  const truncatedOutput = output.length > MAX_SINGLE_OUTPUT_CHARS
275
- ? `${output.slice(0, MAX_SINGLE_OUTPUT_CHARS)}...(truncated)`
309
+ ? `...(truncated)\n${output.slice(-MAX_SINGLE_OUTPUT_CHARS)}`
276
310
  : output;
277
311
  const eventPayload = {
278
312
  category: "output",
@@ -285,24 +319,31 @@ export async function sendOutput(agentId, output, sessionId, seq, metadata, auth
285
319
  logCategory: metadata?.logCategory,
286
320
  };
287
321
  // output 事件合并写入:同 session + 同 sourceEventType + 10s 窗口内追加到同一条
322
+ // ★ 修复 BUG:原实现合并到 8000 上限后无脑截断头部,导致后续同窗口 chunk 持续丢失。
323
+ // 新策略:若合并后会超限,condition 返回 false 让调用方开新条目,
324
+ // 避免长输出尾部持续被丢弃。截断时保留尾部(用户更关心最新内容)。
288
325
  bridgeEventBuffer.appendOrMerge(eventPayload, (lastEntry) => {
289
326
  const last = lastEntry.data;
290
- return (last.category === "output" &&
291
- last.sessionId === sessionId &&
292
- last.sourceEventType === metadata?.sourceEventType &&
293
- Date.now() - lastEntry.timestamp <= 10_000);
327
+ if (last.category !== "output" ||
328
+ last.sessionId !== sessionId ||
329
+ last.sourceEventType !== metadata?.sourceEventType ||
330
+ Date.now() - lastEntry.timestamp > 10_000) {
331
+ return false;
332
+ }
333
+ // 预估合并后长度,超上限则开新条目,避免截断丢内容
334
+ const existingLen = (last.output || "").length;
335
+ const newLen = (eventPayload.output || "").length;
336
+ return existingLen + newLen <= MAX_SINGLE_OUTPUT_CHARS;
294
337
  }, (lastData, newData) => {
295
338
  // 内容去重:如果新内容已包含在已合并内容中,跳过拼接防止重复
296
339
  const existingOutput = lastData.output || "";
297
340
  const newOutput = newData.output || "";
298
- const merged = existingOutput.includes(newOutput)
299
- ? existingOutput
300
- : `${existingOutput}${newOutput}`;
341
+ if (existingOutput.includes(newOutput)) {
342
+ return lastData;
343
+ }
301
344
  return {
302
345
  ...lastData,
303
- output: merged.length > MAX_SINGLE_OUTPUT_CHARS
304
- ? `${merged.slice(0, MAX_SINGLE_OUTPUT_CHARS)}...(truncated)`
305
- : merged,
346
+ output: `${existingOutput}${newOutput}`,
306
347
  };
307
348
  });
308
349
  // 同步写入 per-agent 事件存储(同样合并)并调度差量推送
@@ -1 +1 @@
1
- {"version":3,"file":"sub-agent-manager.d.ts","sourceRoot":"","sources":["../src/sub-agent-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sub-agent-manager.d.ts","sourceRoot":"","sources":["../src/sub-agent-manager.ts"],"names":[],"mappings":"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"}