aws-runtime-bridge 1.9.10 → 1.9.21

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 (132) hide show
  1. package/dist/adapter/AcodeSdkAdapter.d.ts +40 -0
  2. package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -1
  3. package/dist/adapter/AcodeSdkAdapter.js +376 -10
  4. package/dist/adapter/AcodeSdkAdapter.test.js +155 -8
  5. package/dist/adapter/ClaudeSdkAdapter.d.ts.map +1 -1
  6. package/dist/adapter/ClaudeSdkAdapter.js +17 -1
  7. package/dist/adapter/CodexSdkAdapter.d.ts.map +1 -1
  8. package/dist/adapter/CodexSdkAdapter.js +15 -1
  9. package/dist/adapter/OpencodeSdkAdapter.d.ts.map +1 -1
  10. package/dist/adapter/OpencodeSdkAdapter.js +56 -4
  11. package/dist/adapter/instance-ai-config-resolver.d.ts +49 -0
  12. package/dist/adapter/instance-ai-config-resolver.d.ts.map +1 -0
  13. package/dist/adapter/instance-ai-config-resolver.js +46 -0
  14. package/dist/adapter/types.d.ts +29 -2
  15. package/dist/adapter/types.d.ts.map +1 -1
  16. package/dist/index.js +5 -1
  17. package/dist/routes/dashboard.d.ts.map +1 -1
  18. package/dist/routes/dashboard.js +749 -15
  19. package/dist/routes/events.d.ts +7 -0
  20. package/dist/routes/events.d.ts.map +1 -0
  21. package/dist/routes/events.js +22 -0
  22. package/dist/routes/file-browser.d.ts +1 -1
  23. package/dist/routes/file-browser.d.ts.map +1 -1
  24. package/dist/routes/file-browser.js +25 -9
  25. package/dist/routes/file-snapshot.d.ts +10 -0
  26. package/dist/routes/file-snapshot.d.ts.map +1 -0
  27. package/dist/routes/file-snapshot.js +156 -0
  28. package/dist/routes/git.d.ts +10 -0
  29. package/dist/routes/git.d.ts.map +1 -1
  30. package/dist/routes/git.js +405 -2
  31. package/dist/routes/git.test.js +39 -2
  32. package/dist/routes/instance.js +3 -1
  33. package/dist/routes/memory.d.ts +3 -0
  34. package/dist/routes/memory.d.ts.map +1 -1
  35. package/dist/routes/memory.js +3 -0
  36. package/dist/routes/terminal.d.ts +17 -3
  37. package/dist/routes/terminal.d.ts.map +1 -1
  38. package/dist/routes/terminal.js +464 -47
  39. package/dist/routes/terminal.test.js +37 -9
  40. package/dist/services/agent-event-store.d.ts +60 -0
  41. package/dist/services/agent-event-store.d.ts.map +1 -0
  42. package/dist/services/agent-event-store.js +68 -0
  43. package/dist/services/event-delta-pusher.d.ts +40 -0
  44. package/dist/services/event-delta-pusher.d.ts.map +1 -0
  45. package/dist/services/event-delta-pusher.js +95 -0
  46. package/dist/services/fileSnapshotStore.d.ts +96 -0
  47. package/dist/services/fileSnapshotStore.d.ts.map +1 -0
  48. package/dist/services/fileSnapshotStore.js +500 -0
  49. package/dist/services/instance-ai-config-service.d.ts +49 -0
  50. package/dist/services/instance-ai-config-service.d.ts.map +1 -0
  51. package/dist/services/instance-ai-config-service.js +174 -0
  52. package/dist/services/panel-auth.d.ts +8 -0
  53. package/dist/services/panel-auth.d.ts.map +1 -1
  54. package/dist/services/panel-auth.js +8 -0
  55. package/dist/services/ring-buffer.d.ts +67 -0
  56. package/dist/services/ring-buffer.d.ts.map +1 -0
  57. package/dist/services/ring-buffer.js +103 -0
  58. package/dist/services/session-output.d.ts +49 -3
  59. package/dist/services/session-output.d.ts.map +1 -1
  60. package/dist/services/session-output.js +115 -2
  61. package/dist/utils/instance-ai-config-debug-logger.d.ts +37 -0
  62. package/dist/utils/instance-ai-config-debug-logger.d.ts.map +1 -0
  63. package/dist/utils/instance-ai-config-debug-logger.js +63 -0
  64. package/dist/utils/logger.d.ts +18 -0
  65. package/dist/utils/logger.d.ts.map +1 -1
  66. package/dist/utils/logger.js +48 -4
  67. package/package/acode/dist/built-in-file-tools.d.ts +1 -1
  68. package/package/acode/dist/built-in-file-tools.d.ts.map +1 -1
  69. package/package/acode/dist/built-in-file-tools.js +5 -3
  70. package/package/acode/dist/builtins/commandArtifacts.d.ts +8 -1
  71. package/package/acode/dist/builtins/commandArtifacts.d.ts.map +1 -1
  72. package/package/acode/dist/builtins/commandArtifacts.js +24 -4
  73. package/package/acode/dist/builtins/shellCommandResult.d.ts +1 -0
  74. package/package/acode/dist/builtins/shellCommandResult.d.ts.map +1 -1
  75. package/package/acode/dist/builtins/shellCommandResult.js +3 -3
  76. package/package/acode/dist/builtins/shellCommandRunner.d.ts +1 -0
  77. package/package/acode/dist/builtins/shellCommandRunner.d.ts.map +1 -1
  78. package/package/acode/dist/builtins/shellCommandRunner.js +1 -0
  79. package/package/acode/dist/builtins/shellOutputDecoder.d.ts +25 -2
  80. package/package/acode/dist/builtins/shellOutputDecoder.d.ts.map +1 -1
  81. package/package/acode/dist/builtins/shellOutputDecoder.js +69 -5
  82. package/package/acode/dist/cli.js +2 -0
  83. package/package/acode/dist/runtime.d.ts.map +1 -1
  84. package/package/acode/dist/runtime.js +156 -5
  85. package/package/acode/dist/types.d.ts +1 -0
  86. package/package/acode/dist/types.d.ts.map +1 -1
  87. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +10 -3
  88. package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +1 -1
  89. package/package/aws-client-agent-mcp/dist/agent-client.js +33 -11
  90. package/package/aws-client-agent-mcp/dist/agent-client.js.map +1 -1
  91. package/package/aws-client-agent-mcp/dist/context-manager.d.ts +136 -0
  92. package/package/aws-client-agent-mcp/dist/context-manager.d.ts.map +1 -0
  93. package/package/aws-client-agent-mcp/dist/context-manager.js +473 -0
  94. package/package/aws-client-agent-mcp/dist/context-manager.js.map +1 -0
  95. package/package/aws-client-agent-mcp/dist/context-manager.test.d.ts +6 -0
  96. package/package/aws-client-agent-mcp/dist/context-manager.test.d.ts.map +1 -0
  97. package/package/aws-client-agent-mcp/dist/context-manager.test.js +307 -0
  98. package/package/aws-client-agent-mcp/dist/context-manager.test.js.map +1 -0
  99. package/package/aws-client-agent-mcp/dist/http-client.d.ts +11 -0
  100. package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +1 -1
  101. package/package/aws-client-agent-mcp/dist/http-client.js +67 -0
  102. package/package/aws-client-agent-mcp/dist/http-client.js.map +1 -1
  103. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +166 -10
  104. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
  105. package/package/aws-client-agent-mcp/dist/mcp-server.js +933 -41
  106. package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
  107. package/package/aws-client-agent-mcp/dist/mcp-server.test.js +150 -130
  108. package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
  109. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +15 -1
  110. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +1 -1
  111. package/package/aws-client-agent-mcp/dist/mcp-tools.js +62 -2
  112. package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +1 -1
  113. package/package/aws-client-agent-mcp/dist/memory-store.d.ts +58 -1
  114. package/package/aws-client-agent-mcp/dist/memory-store.d.ts.map +1 -1
  115. package/package/aws-client-agent-mcp/dist/memory-store.js +246 -15
  116. package/package/aws-client-agent-mcp/dist/memory-store.js.map +1 -1
  117. package/package/aws-client-agent-mcp/dist/memory-tools.d.ts +8 -0
  118. package/package/aws-client-agent-mcp/dist/memory-tools.d.ts.map +1 -1
  119. package/package/aws-client-agent-mcp/dist/memory-tools.js +106 -2
  120. package/package/aws-client-agent-mcp/dist/memory-tools.js.map +1 -1
  121. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +7 -1
  122. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts.map +1 -1
  123. package/package/aws-client-agent-mcp/dist/server-memory-store.js +18 -0
  124. package/package/aws-client-agent-mcp/dist/server-memory-store.js.map +1 -1
  125. package/package/aws-client-agent-mcp/dist/types.d.ts +103 -2
  126. package/package/aws-client-agent-mcp/dist/types.d.ts.map +1 -1
  127. package/package/aws-client-agent-mcp/dist/types.js.map +1 -1
  128. package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +27 -2
  129. package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +1 -1
  130. package/package/aws-client-agent-mcp/dist/websocket-client.js +123 -5
  131. package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -1
  132. package/package.json +1 -1
@@ -4,6 +4,7 @@ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
4
4
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
5
5
  import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
6
6
  import { createBuiltInFileTools, } from "./built-in-file-tools.js";
7
+ import { cleanupAcodeCmdDist } from "./builtins/commandArtifacts.js";
7
8
  import { loadAcodeCommands } from "./commands/commandLoader.js";
8
9
  import { ACodeCommandRegistry } from "./commands/commandRegistry.js";
9
10
  import { loadAcodeConfig, loadAcodeSkills } from "./config.js";
@@ -891,9 +892,16 @@ export class ACodeRuntime extends EventEmitter {
891
892
  const acodeConfig = await loadAcodeConfig(this.config.configPath);
892
893
  const skills = await loadAcodeSkills(this.config.skillsDir);
893
894
  const provider = resolveProviderConfig(this.config, acodeConfig);
895
+ // [DEBUG] ACode Runtime 最终解析的 provider 配置(写入 stdout,bridge 会捕获)
896
+ console.log(`[ACodeRuntime] ★★★ DEBUG ★★★ resolveProviderConfig 结果: config.model=${this.config.model ?? "(undefined)"}, ` +
897
+ `resolvedModel=${provider.model}, baseURL=${provider.baseURL ?? "(none)"}, apiKey=${provider.apiKey ? "[set]" : "(none)"}, ` +
898
+ `configPath=${this.config.configPath ?? "(none)"}`);
894
899
  const permissions = resolvePermissionConfig(this.config, acodeConfig);
895
900
  const mcpConnections = await this.connectMcpServers(acodeConfig.mcpServers ?? {}, provider.mcpToolTimeoutMs);
896
- const builtInTools = createBuiltInFileTools(this.config.workingDirectory);
901
+ const agentId = this.config.agentId || "unknown";
902
+ // 重启时清理旧 spillover 输出
903
+ void cleanupAcodeCmdDist(agentId);
904
+ const builtInTools = createBuiltInFileTools(this.config.workingDirectory, agentId);
897
905
  const exposedTools = [
898
906
  ...builtInTools,
899
907
  ...mcpConnections.flatMap((connection) => connection.tools),
@@ -1002,29 +1010,48 @@ export class ACodeRuntime extends EventEmitter {
1002
1010
  return contextVersion !== this.contextVersion;
1003
1011
  }
1004
1012
  async executeSubmit(message, contextVersion) {
1013
+ const turnStartTime = Date.now();
1014
+ console.log(`[ACodeRuntime] ══════════════════════════════════════════`);
1015
+ console.log(`[ACodeRuntime] ▶️ executeSubmit STARTED`);
1016
+ console.log(`[ACodeRuntime] Message: ${message.slice(0, 100)}${message.length > 100 ? '...' : ''}`);
1017
+ console.log(`[ACodeRuntime] 🔢 Context version: ${contextVersion}`);
1018
+ console.log(`[ACodeRuntime] ═══════════════════════════════════════════`);
1005
1019
  if (!this.state.started || this.state.terminated) {
1020
+ console.error(`[ACodeRuntime] ❌ Runtime not active (started: ${this.state.started}, terminated: ${this.state.terminated})`);
1006
1021
  throw new Error("ACode runtime is not active");
1007
1022
  }
1008
1023
  this.activeTurn = true;
1009
1024
  this.abortRequested = false;
1010
1025
  const originalPrompt = message.trim();
1026
+ let turnCompleted = false;
1011
1027
  try {
1028
+ console.log(`[ACodeRuntime] 🔍 Dispatching UserPromptSubmit hook...`);
1029
+ const promptHookStartTime = Date.now();
1012
1030
  const promptHookResults = await this.hookBus.dispatch("UserPromptSubmit", { prompt: originalPrompt });
1031
+ const promptHookDuration = Date.now() - promptHookStartTime;
1032
+ console.log(`[ACodeRuntime] ✅ UserPromptSubmit hook completed in ${promptHookDuration}ms, ` +
1033
+ `results: ${promptHookResults.length}`);
1013
1034
  if (this.isTurnSuperseded(contextVersion)) {
1035
+ console.log(`[ACodeRuntime] ⚠️ Turn superseded after hook, aborting`);
1014
1036
  return;
1015
1037
  }
1016
1038
  const promptDeny = findDeniedHookResult(promptHookResults);
1017
1039
  if (promptDeny) {
1040
+ console.error(`[ACodeRuntime] ❌ Prompt denied by hook: ${promptDeny.message}`);
1018
1041
  this.emitAcodeEvent("error", {
1019
1042
  message: promptDeny.message || "ACode prompt was denied by hook",
1020
1043
  });
1021
1044
  this.emitAcodeEvent("turn_complete", { failed: true });
1045
+ turnCompleted = true;
1046
+ console.log(`[ACodeRuntime] 📤 Emitted turn_complete (failed=true) due to hook deny`);
1022
1047
  return;
1023
1048
  }
1049
+ console.log(`[ACodeRuntime] 🔍 Expanding command if any...`);
1024
1050
  const expandedCommand = this.state.commandRegistry.expand(originalPrompt);
1025
1051
  const trimmed = expandedCommand?.prompt.trim() || originalPrompt;
1026
1052
  const commandAllowedTools = expandedCommand?.command.allowedTools;
1027
1053
  if (expandedCommand) {
1054
+ console.log(`[ACodeRuntime] 📋 Slash command detected: ${expandedCommand.command.name}`);
1028
1055
  this.emitAcodeEvent("command_status", {
1029
1056
  action: "slash_command",
1030
1057
  command: expandedCommand.command.name,
@@ -1033,29 +1060,47 @@ export class ACodeRuntime extends EventEmitter {
1033
1060
  });
1034
1061
  }
1035
1062
  if (!this.state.provider.baseURL || !this.state.provider.apiKey) {
1063
+ console.log(`[ACodeRuntime] ⚠️ No provider configured, using fallback response`);
1036
1064
  const text = createFallbackResponse(trimmed, this.state);
1037
1065
  this.emitAcodeEvent("assistant_delta", { text });
1038
1066
  this.emitAcodeEvent("turn_complete", {
1039
1067
  usage: { inputTokens: trimmed.length, outputTokens: text.length },
1040
1068
  });
1069
+ turnCompleted = true;
1070
+ console.log(`[ACodeRuntime] 📤 Emitted turn_complete (fallback mode)`);
1041
1071
  return;
1042
1072
  }
1073
+ console.log(`[ACodeRuntime] 📎 Parsing attachment message...`);
1043
1074
  const parsedContent = parseAttachmentMessage(trimmed);
1044
1075
  if (parsedContent.hasImages && !this.state.provider.supportsImageInput) {
1076
+ console.error(`[ACodeRuntime] ❌ Image input not supported by current provider`);
1045
1077
  throw new Error("ACode provider/model is not configured for image input. Enable provider.default.models[model].modalities.input including 'image' or options.supportsImageInput=true.");
1046
1078
  }
1079
+ console.log(`[ACodeRuntime] 🖼️ Materializing image content if any...`);
1047
1080
  const userContent = await materializeImageContent(parsedContent.content);
1048
1081
  if (this.isTurnSuperseded(contextVersion)) {
1082
+ console.log(`[ACodeRuntime] ️ Turn superseded after materializing content, aborting`);
1049
1083
  return;
1050
1084
  }
1085
+ console.log(`[ACodeRuntime] 💬 Adding user message to conversation`);
1051
1086
  this.state.conversation.push({ role: "user", content: userContent });
1087
+ console.log(`[ACodeRuntime] Conversation size: ${this.state.conversation.length} messages`);
1088
+ console.log(`[ACodeRuntime] Starting runModelTurn...`);
1089
+ const modelTurnStartTime = Date.now();
1052
1090
  const result = await this.runModelTurn(commandAllowedTools, contextVersion);
1091
+ const modelTurnDuration = Date.now() - modelTurnStartTime;
1092
+ console.log(`[ACodeRuntime] ✅ runModelTurn completed in ${modelTurnDuration}ms`);
1093
+ console.log(`[ACodeRuntime] 📝 Result: text=${result.text ? result.text.slice(0, 80) + (result.text.length > 80 ? '...' : '') : '(empty)'}, ` +
1094
+ `finishReason=${result.finishReason || '(none)'}`);
1053
1095
  if (this.isTurnSuperseded(contextVersion)) {
1096
+ console.log(`[ACodeRuntime] ️ Turn superseded after runModelTurn, aborting`);
1054
1097
  return;
1055
1098
  }
1056
1099
  if (result.text && !this.state.provider.stream) {
1100
+ console.log(`[ACodeRuntime] 📤 Emitting assistant_delta (non-streaming mode)`);
1057
1101
  this.emitAcodeEvent("assistant_delta", { text: result.text });
1058
1102
  }
1103
+ console.log(`[ACodeRuntime] 📤 Emitting turn_complete...`);
1059
1104
  this.emitAcodeEvent("turn_complete", {
1060
1105
  usage: result.usage ?? {
1061
1106
  inputTokens: trimmed.length,
@@ -1064,23 +1109,52 @@ export class ACodeRuntime extends EventEmitter {
1064
1109
  ...(result.responseBody ? { responseBody: result.responseBody } : {}),
1065
1110
  ...(result.finishReason ? { finishReason: result.finishReason } : {}),
1066
1111
  });
1112
+ turnCompleted = true;
1113
+ const totalDuration = Date.now() - turnStartTime;
1114
+ console.log(`[ACodeRuntime] ═══════════════════════════════════════════`);
1115
+ console.log(`[ACodeRuntime] ✅ executeSubmit COMPLETED in ${totalDuration}ms`);
1116
+ console.log(`[ACodeRuntime] ══════════════════════════════════════════`);
1067
1117
  }
1068
1118
  catch (error) {
1119
+ const errorDuration = Date.now() - turnStartTime;
1120
+ console.error(`[ACodeRuntime] ❌ executeSubmit FAILED after ${errorDuration}ms:`, error instanceof Error ? error.message : String(error));
1121
+ console.error(`[ACodeRuntime] 🔍 Error stack:`, error instanceof Error ? error.stack : '(no stack)');
1069
1122
  if (this.isTurnSuperseded(contextVersion)) {
1123
+ console.log(`[ACodeRuntime] ️ Turn superseded in error handler, skipping recovery`);
1070
1124
  return;
1071
1125
  }
1072
1126
  if (this.abortRequested) {
1127
+ console.log(`[ACodeRuntime] ⚠️ Abort requested, emitting aborted turn_complete`);
1073
1128
  this.emitAcodeEvent("turn_complete", { aborted: true });
1129
+ turnCompleted = true;
1074
1130
  return;
1075
1131
  }
1132
+ console.log(`[ACodeRuntime] Emitting error and failed turn_complete...`);
1076
1133
  this.emitAcodeEvent("error", {
1077
1134
  message: error instanceof Error ? error.message : String(error),
1078
1135
  });
1079
1136
  this.emitAcodeEvent("turn_complete", { failed: true });
1137
+ turnCompleted = true;
1080
1138
  }
1081
1139
  finally {
1140
+ const finallyDuration = Date.now() - turnStartTime;
1141
+ console.log(`[ACodeRuntime] 🔚 executeSubmit finally block entered after ${finallyDuration}ms`);
1142
+ console.log(`[ACodeRuntime] 🔍 turnCompleted=${turnCompleted}, activeTurn=${this.activeTurn}, ` +
1143
+ `abortRequested=${this.abortRequested}`);
1082
1144
  this.activeTurn = false;
1083
1145
  this.abortRequested = false;
1146
+ // 关键修复:如果异常路径没有发射 turn_complete,强制发射一个
1147
+ // 这确保 adapter 层的 recoverResolvedTurnWithoutTerminalEvent 能够正确触发
1148
+ if (!turnCompleted && !this.isTurnSuperseded(contextVersion)) {
1149
+ console.error(`[ACodeRuntime] 🚨 CRITICAL: executeSubmit finally block reached without turn_complete event!`);
1150
+ console.error(`[ACodeRuntime] 🚨 This indicates a code path that should have emitted turn_complete but didn't.`);
1151
+ console.error(`[ACodeRuntime] Forcing failed turn_complete to prevent state stuck.`);
1152
+ this.emitAcodeEvent("error", {
1153
+ message: "ACode turn completed without proper completion event (internal error)",
1154
+ });
1155
+ this.emitAcodeEvent("turn_complete", { failed: true });
1156
+ console.log(`[ACodeRuntime] Emergency turn_complete (failed=true) emitted`);
1157
+ }
1084
1158
  }
1085
1159
  }
1086
1160
  /** 中止当前轮次;由执行轮次统一发出一个终态事件,避免 aborted/failed 双终态。 */
@@ -1127,15 +1201,29 @@ export class ACodeRuntime extends EventEmitter {
1127
1201
  let finalUsage;
1128
1202
  let finalResponseBody;
1129
1203
  let finalFinishReason;
1130
- for (let step = 0; step < 5; step += 1) {
1204
+ // 日志:开始 runModelTurn
1205
+ console.log(`[ACodeRuntime] ▶️ runModelTurn started (contextVersion: ${contextVersion})`);
1206
+ // 移除5次限制,添加安全上限防止真正的无限循环
1207
+ const SAFETY_LIMIT = 50; // 安全上限,正常情况下不会达到
1208
+ for (let step = 0; step < SAFETY_LIMIT; step += 1) {
1209
+ // 详细日志:记录每次迭代
1210
+ console.log(`[ACodeRuntime] 🔄 Iteration ${step + 1} starting...`);
1131
1211
  if (this.isTurnSuperseded(contextVersion)) {
1212
+ console.log(`[ACodeRuntime] ⚠️ Turn superseded at iteration ${step + 1}, aborting`);
1132
1213
  return { text: "" };
1133
1214
  }
1215
+ const requestStartTime = Date.now();
1134
1216
  const response = await this.requestChatCompletion(commandAllowedTools);
1217
+ const requestDuration = Date.now() - requestStartTime;
1218
+ // 日志:AI请求完成
1219
+ console.log(`[ACodeRuntime] 🤖 AI request completed in ${requestDuration}ms, ` +
1220
+ `choices: ${response.choices?.length || 0}`);
1135
1221
  if (this.isTurnSuperseded(contextVersion)) {
1222
+ console.log(`[ACodeRuntime] ⚠️ Turn superseded after AI response at iteration ${step + 1}`);
1136
1223
  return { text: "" };
1137
1224
  }
1138
1225
  if (this.state.terminated) {
1226
+ console.log(`[ACodeRuntime] Runtime terminated at iteration ${step + 1}`);
1139
1227
  throw new Error("ACode runtime was stopped during the active turn");
1140
1228
  }
1141
1229
  const choice = response.choices?.[0];
@@ -1149,6 +1237,11 @@ export class ACodeRuntime extends EventEmitter {
1149
1237
  const toolCalls = Array.isArray(message?.tool_calls)
1150
1238
  ? message.tool_calls
1151
1239
  : [];
1240
+ // 日志:AI响应详情
1241
+ console.log(`[ACodeRuntime] AI response: ` +
1242
+ `content=${content ? content.slice(0, 100) + (content.length > 100 ? '...' : '') : '(empty)'}, ` +
1243
+ `toolCalls=${toolCalls.length}, ` +
1244
+ `finishReason=${finalFinishReason || '(none)'}`);
1152
1245
  if (response.usage) {
1153
1246
  const rtInputTokens = response.usage.prompt_tokens ?? response.usage.input_tokens;
1154
1247
  const rtOutputTokens = response.usage.completion_tokens ?? response.usage.output_tokens;
@@ -1158,6 +1251,7 @@ export class ACodeRuntime extends EventEmitter {
1158
1251
  inputTokens: rtInputTokens,
1159
1252
  outputTokens: rtOutputTokens,
1160
1253
  };
1254
+ console.log(`[ACodeRuntime] 💰 Token usage: input=${rtInputTokens}, output=${rtOutputTokens}`);
1161
1255
  }
1162
1256
  }
1163
1257
  this.state.conversation.push({
@@ -1167,8 +1261,10 @@ export class ACodeRuntime extends EventEmitter {
1167
1261
  });
1168
1262
  if (content) {
1169
1263
  finalText = content;
1264
+ console.log(`[ACodeRuntime] ✨ Captured assistant text: ${content.slice(0, 80)}...`);
1170
1265
  }
1171
1266
  if (toolCalls.length === 0) {
1267
+ console.log(`[ACodeRuntime] ✅ No tool calls at iteration ${step + 1}, completing turn`);
1172
1268
  return {
1173
1269
  text: finalText,
1174
1270
  usage: finalUsage,
@@ -1176,16 +1272,29 @@ export class ACodeRuntime extends EventEmitter {
1176
1272
  finishReason: finalFinishReason,
1177
1273
  };
1178
1274
  }
1275
+ // 日志:即将执行工具调用
1276
+ const toolNames = toolCalls.map(tc => tc.function.name).join(", ");
1277
+ console.log(`[ACodeRuntime] 🔧 Executing ${toolCalls.length} tool(s) at iteration ${step + 1}: ${toolNames}`);
1278
+ const toolStart = Date.now();
1179
1279
  await this.handleToolCalls(toolCalls, commandAllowedTools, contextVersion);
1280
+ const toolDuration = Date.now() - toolStart;
1281
+ // 日志:工具执行完成
1282
+ console.log(`[ACodeRuntime] ⚙️ Tool execution completed in ${toolDuration}ms at iteration ${step + 1}`);
1180
1283
  if (this.isTurnSuperseded(contextVersion)) {
1284
+ console.log(`[ACodeRuntime] ⚠️ Turn superseded after tool execution at iteration ${step + 1}`);
1181
1285
  return { text: "" };
1182
1286
  }
1287
+ // 日志:准备下一次迭代
1288
+ console.log(`[ACodeRuntime] 🔄 Preparing iteration ${step + 2}...`);
1183
1289
  }
1290
+ // 达到安全上限(理论上不应该发生)
1291
+ console.error(`[ACodeRuntime] 🚨 CRITICAL: Reached safety limit of ${SAFETY_LIMIT} iterations! ` +
1292
+ `This indicates a potential infinite loop. Forcing turn completion.`);
1184
1293
  return {
1185
- text: finalText || "ACode 已达到本轮 MCP 工具调用上限。",
1294
+ text: finalText || `ACode 已达到安全迭代上限(${SAFETY_LIMIT}次),强制结束本轮对话。`,
1186
1295
  usage: finalUsage,
1187
1296
  responseBody: finalResponseBody,
1188
- finishReason: finalFinishReason,
1297
+ finishReason: finalFinishReason || "safety_iteration_limit_reached",
1189
1298
  };
1190
1299
  }
1191
1300
  async requestChatCompletion(commandAllowedTools) {
@@ -1219,6 +1328,8 @@ export class ACodeRuntime extends EventEmitter {
1219
1328
  const redactedRequestHeaders = redactRequestHeaders(requestHeaders);
1220
1329
  const emitAiRequest = (body) => {
1221
1330
  const requestBody = JSON.stringify(body, null, 2);
1331
+ // [DEBUG] ACode Runtime 实际发送的模型名称
1332
+ console.log(`[ACodeRuntime] ★★★ DEBUG ★★★ emitAiRequest: 发送请求 model=${provider.model}, endpoint=${requestUrl}, messageCount=${this.state.conversation.length}`);
1222
1333
  this.emitAcodeEvent("ai_request", {
1223
1334
  model: provider.model,
1224
1335
  endpoint: requestUrl,
@@ -1264,7 +1375,15 @@ export class ACodeRuntime extends EventEmitter {
1264
1375
  timedOut = true;
1265
1376
  requestAbortController.abort();
1266
1377
  }));
1267
- return isRecord(payload) ? payload : {};
1378
+ // 容错处理: 如果网关返回的不是有效对象,记录警告并返回空响应
1379
+ // 避免 Agent 永久卡在 thinking/tool_using 状态
1380
+ if (!isRecord(payload)) {
1381
+ this.emitAcodeEvent("warning", {
1382
+ message: `ACode provider returned invalid response format (expected object, got ${typeof payload}); treating as empty response`,
1383
+ });
1384
+ return {};
1385
+ }
1386
+ return payload;
1268
1387
  })(), 0, "ACode provider request");
1269
1388
  }
1270
1389
  catch (error) {
@@ -1380,12 +1499,18 @@ export class ACodeRuntime extends EventEmitter {
1380
1499
  };
1381
1500
  }
1382
1501
  async handleToolCalls(toolCalls, commandAllowedTools, contextVersion = this.contextVersion) {
1502
+ console.log(`[ACodeRuntime] handleToolCalls started with ${toolCalls.length} tool(s)`);
1383
1503
  for (const toolCall of toolCalls) {
1384
1504
  if (this.isTurnSuperseded(contextVersion)) {
1505
+ console.log(`[ACodeRuntime] ️ Turn superseded, skipping remaining tools`);
1385
1506
  return;
1386
1507
  }
1508
+ const toolName = toolCall.function.name;
1509
+ console.log(`[ACodeRuntime] 🔍 Looking up tool: ${toolName}`);
1387
1510
  const tool = this.state.exposedTools.find((item) => item.exposedName === toolCall.function.name);
1388
1511
  if (!tool) {
1512
+ console.error(`[ACodeRuntime] ❌ Tool not found: ${toolCall.function.name}, ` +
1513
+ `available tools: ${this.state.exposedTools.map(t => t.exposedName).join(", ")}`);
1389
1514
  this.state.conversation.push({
1390
1515
  role: "tool",
1391
1516
  tool_call_id: toolCall.id,
@@ -1393,9 +1518,11 @@ export class ACodeRuntime extends EventEmitter {
1393
1518
  });
1394
1519
  continue;
1395
1520
  }
1521
+ console.log(`[ACodeRuntime] Found tool: ${tool.toolName} (kind: ${tool.kind}, source: ${tool.kind === 'mcp' ? tool.serverName : 'builtin'})`);
1396
1522
  try {
1397
1523
  if (tool.kind === "builtin") {
1398
1524
  const toolArguments = coerceArguments(toolCall.function.arguments);
1525
+ console.log(`[ACodeRuntime] Built-in tool arguments: ${JSON.stringify(toolArguments).slice(0, 200)}`);
1399
1526
  assertToolPermission(tool, this.state.permissions, commandAllowedTools);
1400
1527
  const preResults = await this.hookBus.dispatch("PreToolUse", {
1401
1528
  source: "builtin",
@@ -1408,9 +1535,11 @@ export class ACodeRuntime extends EventEmitter {
1408
1535
  }
1409
1536
  const denied = findDeniedHookResult(preResults);
1410
1537
  if (denied) {
1538
+ console.error(`[ACodeRuntime] ❌ Tool denied by hook: ${tool.exposedName}: ${denied.message}`);
1411
1539
  throw new Error(denied.message ||
1412
1540
  `ACode tool denied by hook: ${tool.exposedName}`);
1413
1541
  }
1542
+ console.log(`[ACodeRuntime] Emitting mcp_status call_tool for ${tool.exposedName}`);
1414
1543
  this.emitAcodeEvent("mcp_status", {
1415
1544
  action: "call_tool",
1416
1545
  server: "builtin",
@@ -1420,6 +1549,8 @@ export class ACodeRuntime extends EventEmitter {
1420
1549
  arguments: toolArguments,
1421
1550
  argumentsPreview: summarizeToolArguments(toolArguments),
1422
1551
  });
1552
+ const toolStart = Date.now();
1553
+ console.log(`[ACodeRuntime] ▶️ Executing built-in tool: ${tool.exposedName}`);
1423
1554
  const result = await withTimeout(tool.execute(toolArguments, {
1424
1555
  onOutput: (outputEvent) => {
1425
1556
  this.emitAcodeEvent("command_output", {
@@ -1438,6 +1569,8 @@ export class ACodeRuntime extends EventEmitter {
1438
1569
  });
1439
1570
  },
1440
1571
  }), getBuiltInToolTimeoutMs(tool, toolArguments, this.state.provider.mcpToolTimeoutMs), `ACode built-in tool ${tool.toolName}`);
1572
+ const toolDuration = Date.now() - toolStart;
1573
+ console.log(`[ACodeRuntime] ✅ Built-in tool ${tool.exposedName} completed in ${toolDuration}ms`);
1441
1574
  if (this.isTurnSuperseded(contextVersion)) {
1442
1575
  return;
1443
1576
  }
@@ -1451,6 +1584,8 @@ export class ACodeRuntime extends EventEmitter {
1451
1584
  return;
1452
1585
  }
1453
1586
  const resultText = toToolResultText(result);
1587
+ console.log(`[ACodeRuntime] 📤 Emitting mcp_status tool_result for ${tool.exposedName}, ` +
1588
+ `result length: ${resultText.length} chars`);
1454
1589
  this.emitAcodeEvent("mcp_status", {
1455
1590
  action: "tool_result",
1456
1591
  server: "builtin",
@@ -1465,8 +1600,11 @@ export class ACodeRuntime extends EventEmitter {
1465
1600
  await this.appendSyntheticMultimodalUserMessage(resultText, contextVersion);
1466
1601
  continue;
1467
1602
  }
1603
+ // MCP工具处理
1468
1604
  const connection = this.state.mcpConnections.find((item) => item.serverName === tool.serverName);
1469
1605
  if (!connection) {
1606
+ console.error(`[ACodeRuntime] ❌ MCP server not connected: ${tool.serverName}, ` +
1607
+ `connected servers: ${this.state.mcpConnections.map(c => c.serverName).join(", ")}`);
1470
1608
  this.state.conversation.push({
1471
1609
  role: "tool",
1472
1610
  tool_call_id: toolCall.id,
@@ -1475,6 +1613,7 @@ export class ACodeRuntime extends EventEmitter {
1475
1613
  continue;
1476
1614
  }
1477
1615
  const toolArguments = coerceArguments(toolCall.function.arguments);
1616
+ console.log(`[ACodeRuntime] MCP tool arguments: ${JSON.stringify(toolArguments).slice(0, 200)}`);
1478
1617
  assertToolPermission(tool, this.state.permissions, commandAllowedTools);
1479
1618
  const preResults = await this.hookBus.dispatch("PreToolUse", {
1480
1619
  source: "mcp",
@@ -1488,8 +1627,10 @@ export class ACodeRuntime extends EventEmitter {
1488
1627
  }
1489
1628
  const denied = findDeniedHookResult(preResults);
1490
1629
  if (denied) {
1630
+ console.error(`[ACodeRuntime] ❌ MCP tool denied by hook: ${tool.exposedName}: ${denied.message}`);
1491
1631
  throw new Error(denied.message || `ACode tool denied by hook: ${tool.exposedName}`);
1492
1632
  }
1633
+ console.log(`[ACodeRuntime] 📤 Emitting mcp_status call_tool for MCP ${tool.exposedName}`);
1493
1634
  this.emitAcodeEvent("mcp_status", {
1494
1635
  action: "call_tool",
1495
1636
  server: tool.serverName,
@@ -1503,7 +1644,12 @@ export class ACodeRuntime extends EventEmitter {
1503
1644
  const toolTimeoutMs = isPollingTool
1504
1645
  ? this.state.provider.mcpPollingToolTimeoutMs
1505
1646
  : this.state.provider.mcpToolTimeoutMs;
1647
+ const toolStart = Date.now();
1648
+ console.log(`[ACodeRuntime] ▶️ Executing MCP tool: ${tool.exposedName} ` +
1649
+ `(timeout: ${toolTimeoutMs}ms, polling: ${isPollingTool})`);
1506
1650
  const result = await this.callMcpToolWithTimeout(connection, tool, toolArguments, toolTimeoutMs, isPollingTool);
1651
+ const toolDuration = Date.now() - toolStart;
1652
+ console.log(`[ACodeRuntime] ✅ MCP tool ${tool.exposedName} completed in ${toolDuration}ms`);
1507
1653
  if (this.isTurnSuperseded(contextVersion)) {
1508
1654
  return;
1509
1655
  }
@@ -1518,6 +1664,8 @@ export class ACodeRuntime extends EventEmitter {
1518
1664
  return;
1519
1665
  }
1520
1666
  const resultText = toToolResultText(result);
1667
+ console.log(`[ACodeRuntime] 📤 Emitting mcp_status tool_result for MCP ${tool.exposedName}, ` +
1668
+ `result length: ${resultText.length} chars`);
1521
1669
  this.emitAcodeEvent("mcp_status", {
1522
1670
  action: "tool_result",
1523
1671
  server: tool.serverName,
@@ -1532,15 +1680,18 @@ export class ACodeRuntime extends EventEmitter {
1532
1680
  await this.appendSyntheticMultimodalUserMessage(resultText, contextVersion);
1533
1681
  }
1534
1682
  catch (error) {
1683
+ console.error(`[ACodeRuntime] ❌ Tool execution failed: ${toolCall.function.name}`, error instanceof Error ? error.message : String(error));
1535
1684
  if (this.isTurnSuperseded(contextVersion)) {
1536
1685
  return;
1537
1686
  }
1538
1687
  if (this.abortRequested || this.state.terminated) {
1688
+ console.log(`[ACodeRuntime] ⚠️ Rethrowing error due to abort/termination`);
1539
1689
  throw error instanceof Error ? error : new Error(String(error));
1540
1690
  }
1541
1691
  this.appendToolFailureResult(toolCall, tool, error);
1542
1692
  }
1543
1693
  }
1694
+ console.log(`[ACodeRuntime] handleToolCalls completed for all ${toolCalls.length} tool(s)`);
1544
1695
  }
1545
1696
  async callMcpToolWithTimeout(connection, tool, toolArguments, timeoutMs, retrySdkTimeout) {
1546
1697
  const sdkTimeout = timeoutMs > 0 ? timeoutMs : MCP_SDK_MAX_SAFE_TIMEOUT_MS;
@@ -87,6 +87,7 @@ export type ACodeHookHandler = (event: ACodeHookEvent) => ACodeHookResult | unde
87
87
  export interface ACodeRuntimeConfig {
88
88
  sessionId: string;
89
89
  workingDirectory: string;
90
+ agentId?: string;
90
91
  configPath?: string;
91
92
  skillsDir?: string;
92
93
  initialPrompt?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,7 @@ export declare class AgentClient {
20
20
  private profileHandler;
21
21
  private pollTimer;
22
22
  private statusReporter;
23
+ private newCharacterHandler;
23
24
  /**
24
25
  * Profile 缓存
25
26
  * 用于处理 PROFILE_INFO 消息在 profileHandler 设置之前到达的情况
@@ -107,13 +108,15 @@ export declare class AgentClient {
107
108
  */
108
109
  fetchUnreadMessages(options?: FetchUnreadMessagesOptions): Promise<UnreadMessagesResult>;
109
110
  /**
110
- * 拉取服务端私信并对 poll_message 长轮询临时失败做恢复。
111
- * 主流程:正常调用 HTTP MCP tool -> 仅当服务端阻塞 poll_message 返回 503 或客户端硬超时时转为空结果,让本地轮询退避后继续等待。
111
+ * 拉取服务端私信并对 poll_message 长轮询做容错处理。
112
+ * 主流程:针对 poll_message 使用 callToolOnce(单次长阻塞,无重试干扰);
113
+ * 非 poll_message 工具走 callTool(标准带重试逻辑)。
114
+ * callToolOnce 超时后转为空结果,让 hydrateUnreadMessagesUntilAvailable 继续等待。
112
115
  */
113
116
  private fetchDirectMessagesWithRecovery;
114
117
  /**
115
118
  * 判断是否为 poll_message 长轮询的可恢复失败。
116
- * 主流程:只匹配明确的 MCP tool HTTP 503 或客户端超时,避免吞掉业务工具错误或认证错误。
119
+ * 主流程:只匹配明确的 HTTP 503 或客户端硬超时,避免吞掉业务工具错误或认证错误。
117
120
  */
118
121
  private isRecoverableLongPollError;
119
122
  /**
@@ -186,6 +189,10 @@ export declare class AgentClient {
186
189
  private processMessage;
187
190
  private ensureRegistered;
188
191
  private delay;
192
+ /**
193
+ * 注册新角色回调:当 registerAsNewAgent 返回 isExisting === false 时触发。
194
+ */
195
+ onNewCharacter(handler: () => void): void;
189
196
  getState(): {
190
197
  agentId: string | null;
191
198
  displayName: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-client.d.ts","sourceRoot":"","sources":["../src/agent-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-client.d.ts","sourceRoot":"","sources":["../src/agent-client.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ export class AgentClient {
23
23
  profileHandler = null;
24
24
  pollTimer = null;
25
25
  statusReporter = null;
26
+ newCharacterHandler = null;
26
27
  /**
27
28
  * Profile 缓存
28
29
  * 用于处理 PROFILE_INFO 消息在 profileHandler 设置之前到达的情况
@@ -150,6 +151,10 @@ export class AgentClient {
150
151
  logger.info("[AgentClient] WebSocket 连接已建立,Agent 现在已上线");
151
152
  // 初始化状态报告器
152
153
  this.initializeStatusReporter();
154
+ // 触发新角色回调
155
+ if (result.isExisting === false && this.newCharacterHandler) {
156
+ this.newCharacterHandler();
157
+ }
153
158
  return result;
154
159
  }
155
160
  /**
@@ -389,24 +394,30 @@ export class AgentClient {
389
394
  };
390
395
  }
391
396
  /**
392
- * 拉取服务端私信并对 poll_message 长轮询临时失败做恢复。
393
- * 主流程:正常调用 HTTP MCP tool -> 仅当服务端阻塞 poll_message 返回 503 或客户端硬超时时转为空结果,让本地轮询退避后继续等待。
397
+ * 拉取服务端私信并对 poll_message 长轮询做容错处理。
398
+ * 主流程:针对 poll_message 使用 callToolOnce(单次长阻塞,无重试干扰);
399
+ * 非 poll_message 工具走 callTool(标准带重试逻辑)。
400
+ * callToolOnce 超时后转为空结果,让 hydrateUnreadMessagesUntilAvailable 继续等待。
394
401
  */
395
402
  async fetchDirectMessagesWithRecovery(toolName, args) {
396
- try {
397
- return await this.httpClient.callTool(toolName, args);
398
- }
399
- catch (error) {
400
- if (toolName === "poll_message" && this.isRecoverableLongPollError(error)) {
401
- logger.warn("[AgentClient] 服务端 poll_message 长轮询临时不可用,按空结果退避后继续等待:", error);
402
- return { messages: [] };
403
+ if (toolName === "poll_message") {
404
+ try {
405
+ return await this.httpClient.callToolOnce(toolName, args);
406
+ }
407
+ catch (error) {
408
+ if (this.isRecoverableLongPollError(error)) {
409
+ logger.warn("[AgentClient] poll_message 单次长轮询超时,按空结果退避后继续等待:", error);
410
+ return { messages: [] };
411
+ }
412
+ throw error;
403
413
  }
404
- throw error;
405
414
  }
415
+ // 非 poll_message 工具走标准带重试路径
416
+ return await this.httpClient.callTool(toolName, args);
406
417
  }
407
418
  /**
408
419
  * 判断是否为 poll_message 长轮询的可恢复失败。
409
- * 主流程:只匹配明确的 MCP tool HTTP 503 或客户端超时,避免吞掉业务工具错误或认证错误。
420
+ * 主流程:只匹配明确的 HTTP 503 或客户端硬超时,避免吞掉业务工具错误或认证错误。
410
421
  */
411
422
  isRecoverableLongPollError(error) {
412
423
  if (!(error instanceof Error)) {
@@ -623,6 +634,11 @@ export class AgentClient {
623
634
  this.projectName = profile.projectName;
624
635
  logger.info(`[AgentClient] 更新所属项目: ${this.projectName}`);
625
636
  }
637
+ // 同步角色名,确保写入永久记忆的目录与服务端存储的 roleName 一致
638
+ if (profile.roleName && profile.roleName !== this.agentConfig.roleName) {
639
+ logger.info(`[AgentClient] 同步角色名: "${this.agentConfig.roleName || "(空)"}" -> "${profile.roleName}"`);
640
+ this.agentConfig.roleName = profile.roleName;
641
+ }
626
642
  if (this.profileHandler) {
627
643
  // profileHandler 已设置,直接调用
628
644
  this.profileHandler(profile);
@@ -671,6 +687,12 @@ export class AgentClient {
671
687
  this.pollTimer = setTimeout(resolve, ms);
672
688
  });
673
689
  }
690
+ /**
691
+ * 注册新角色回调:当 registerAsNewAgent 返回 isExisting === false 时触发。
692
+ */
693
+ onNewCharacter(handler) {
694
+ this.newCharacterHandler = handler;
695
+ }
674
696
  getState() {
675
697
  return {
676
698
  agentId: this.agentId,