aws-runtime-bridge 1.9.169 → 1.9.171

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 (92) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/adapter/AcodeSdkAdapter.d.ts +46 -0
  3. package/dist/adapter/AcodeSdkAdapter.js +4 -4
  4. package/dist/adapter/ClaudeSdkAdapter.js +2 -2
  5. package/dist/adapter/types.d.ts +7 -0
  6. package/dist/config.d.ts +6 -0
  7. package/dist/config.js +2 -2
  8. package/dist/index.js +1 -1
  9. package/dist/routes/agent-state.d.ts +2 -0
  10. package/dist/routes/agent-state.js +2 -0
  11. package/dist/routes/capabilities.js +1 -1
  12. package/dist/routes/debug-mount.d.ts +2 -0
  13. package/dist/routes/debug-mount.js +2 -0
  14. package/dist/routes/mcp.js +1 -1
  15. package/dist/routes/plugins.js +1 -1
  16. package/dist/routes/skills.js +1 -1
  17. package/dist/routes/terminal.js +24 -34
  18. package/dist/services/acode-bg-manager.d.ts +2 -0
  19. package/dist/services/agent-capability-sync.js +1 -1
  20. package/dist/services/agent-startup-memory.d.ts +11 -0
  21. package/dist/services/agent-startup-memory.js +8 -0
  22. package/dist/services/debug-mount.d.ts +122 -0
  23. package/dist/services/debug-mount.js +2 -0
  24. package/dist/services/desktop-mcp-manager.js +1 -1
  25. package/dist/services/instance-ai-config-service.js +1 -1
  26. package/dist/services/instance-features.d.ts +4 -0
  27. package/dist/services/instance-features.js +1 -1
  28. package/dist/services/instance-init-service.js +1 -1
  29. package/dist/services/log-retention.d.ts +37 -0
  30. package/dist/services/log-retention.js +2 -0
  31. package/dist/services/mcp-deploy.d.ts +31 -0
  32. package/dist/services/mcp-deploy.js +4 -3
  33. package/dist/services/mcp-env-injector.d.ts +24 -0
  34. package/dist/services/mcp-env-injector.js +1 -1
  35. package/dist/services/mcp-package.d.ts +35 -0
  36. package/dist/services/mcp-package.js +2 -0
  37. package/dist/services/mcp-probe-client.d.ts +25 -0
  38. package/dist/services/mcp-probe-client.js +2 -0
  39. package/dist/services/panel-env.d.ts +5 -0
  40. package/dist/services/panel-env.js +1 -1
  41. package/dist/services/plugin-deployment.d.ts +36 -0
  42. package/dist/services/plugin-deployment.js +3 -0
  43. package/dist/services/plugin-event-buffer.js +2 -1
  44. package/dist/services/plugin-fs.d.ts +5 -0
  45. package/dist/services/plugin-fs.js +2 -0
  46. package/dist/services/plugin-handler-adapter.d.ts +7 -0
  47. package/dist/services/plugin-handler-adapter.js +3 -0
  48. package/dist/services/plugin-listener-runner.d.ts +18 -0
  49. package/dist/services/plugin-listener-runner.js +8 -0
  50. package/dist/services/plugin-loader.d.ts +32 -0
  51. package/dist/services/plugin-loader.js +2 -0
  52. package/dist/services/plugin-manager.d.ts +17 -136
  53. package/dist/services/plugin-manager.js +4 -15
  54. package/dist/services/plugin-manifest.d.ts +83 -0
  55. package/dist/services/plugin-manifest.js +2 -0
  56. package/dist/services/plugin-runtime.d.ts +67 -0
  57. package/dist/services/plugin-runtime.js +1 -0
  58. package/dist/services/request-invalid-dump.d.ts +21 -0
  59. package/dist/services/request-invalid-dump.js +2 -0
  60. package/dist/services/skill-manager.d.ts +15 -0
  61. package/dist/services/skill-manager.js +3 -2
  62. package/dist/types.d.ts +6 -0
  63. package/dist/utils/lifecycle-log.d.ts +2 -0
  64. package/dist/utils/lifecycle-log.js +2 -2
  65. package/dist/utils/mcp-utils.js +1 -1
  66. package/package/acode/dist/compaction.d.ts +35 -1
  67. package/package/acode/dist/compaction.js +6 -6
  68. package/package/acode/dist/image-utils.js +1 -1
  69. package/package/acode/dist/plugin-types.d.ts +6 -27
  70. package/package/acode/dist/runtime.d.ts +37 -0
  71. package/package/acode/dist/runtime.js +31 -30
  72. package/package/acode/dist/tool-group-manager.d.ts +10 -0
  73. package/package/acode/dist/tool-group-manager.js +5 -10
  74. package/package/acode/dist/types.d.ts +2 -0
  75. package/package/aws-client-agent-mcp/dist/ability-market-tools.d.ts +18 -0
  76. package/package/aws-client-agent-mcp/dist/ability-market-tools.js +2 -0
  77. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +15 -4
  78. package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
  79. package/package/aws-client-agent-mcp/dist/http-client.d.ts +2 -0
  80. package/package/aws-client-agent-mcp/dist/http-client.js +1 -1
  81. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +0 -7
  82. package/package/aws-client-agent-mcp/dist/mcp-server.js +12 -12
  83. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +5 -0
  84. package/package/aws-client-agent-mcp/dist/mcp-tools.js +34 -20
  85. package/package/aws-client-agent-mcp/dist/memory-store.d.ts +1 -1
  86. package/package/aws-client-agent-mcp/dist/memory-store.js +2 -2
  87. package/package/aws-client-agent-mcp/dist/memory-tools.js +7 -7
  88. package/package/aws-client-agent-mcp/dist/status-reporter.js +1 -1
  89. package/package/aws-client-agent-mcp/dist/tool-groups.js +2 -2
  90. package/package/aws-client-agent-mcp/dist/types.d.ts +15 -22
  91. package/package.json +3 -2
  92. package/dist/services/builtin-commands/create-plugin.md +0 -44
package/CHANGELOG.md CHANGED
@@ -5,6 +5,77 @@ files 白名单),供调度中心「查看本次更新内容」弹窗按 `##
5
5
  展示。发布新版本时须在仓库中先写好 `## v<version>` 段(prepack-guard 校验缺段
6
6
  即阻断发布);Bridge 自更新成功后的运行时追加仅作为包内缺段时的兜底。
7
7
 
8
+ ## v1.9.171
9
+
10
+ _发布日期:2026-10-20_
11
+
12
+ ### 消息协作、邮箱别名、同事观察与日志治理
13
+
14
+ - 消息中心:发送改为乐观上屏(本地「发送中」→ 服务端 `sent`),网络/5xx/429
15
+ 自动退避重试 3 次,失败气泡保留并支持「重试 / 编辑」;WS 回显按发送者+正文+
16
+ 时间窗认领本地待发气泡;私信/群聊发送携带客户端幂等键,服务端按
17
+ `(sender, clientMessageId)` 去重,HTTP 响应丢失后的自动重试不会产生重复消息。
18
+ - 群聊支持 @所有人(后端展开为房间/项目实际成员,提及记录与未读口径一致)、
19
+ 结构化引用提醒(回表校验被引用消息作者,拒绝客户端伪造 `senderId`),并补充
20
+ 引用提醒系统通知。
21
+ - 新增角色实例邮箱「人类只读查看」(收件箱 / 已发送 / 详情,不改变 IMAP 已读
22
+ 状态)与邮箱别名设置;别名更新改为「先建新远端映射、再删旧映射」,任一步失败
23
+ 不会让旧别名提前失效,失败时补偿恢复远端状态。
24
+ - 同事协作:`get_colleague` 增加在线状态、当前动作、工作区路径与邮箱概要;
25
+ 新增 `list_colleague_events` 分页查看同事行为时间线(摘要视图,剥离工具输入/
26
+ 结果原文),由 `collaboration.agentObserve` 能力开关控制(默认收纳)。
27
+ - ACode 收口:AI 配置 / MCP 模板 / 终端 CLI 仅保留 ACode,移除 ClaudeCode、
28
+ Codex、OpenCode 的配置入口与文案。
29
+ - 修复:`RuntimeBridgeService` / `RuntimeGlobalSettingsService` 保存 MCP 时补回
30
+ `instantiate` / `packageUrl` / `packageSha256` 字段,避免包型 MCP 初始化丢失。
31
+ - 修复:清空角色实例邮箱别名改为显式 `SET address_alias = NULL`(MyBatis-Plus
32
+ `updateById` 会忽略 null 字段);恢复心跳超时后的 Agent 异常离线告警。
33
+ - bridge 日志治理:新增统一日志保留策略(lifecycle、MCP 子进程、AI 配置调试
34
+ 日志,最长保留 7 天),启动即清理 + 每 6h 周期清理,面板下发值夹取到 1..7 天;
35
+ Java Debug 日志清理同步收敛为最长 7 天。
36
+ - bridge 启动记忆加载抽为独立服务并复用;provider 请求体非法(确定性 4xx)时
37
+ 落盘完整对话上下文快照(去重 + 保留最近 20 份),便于事后复现工具调用配对问题。
38
+ - dashboard 接入标签页未读标题 / PWA 应用角标;页面隐藏时按私信、群聊 @、系统
39
+ 通知弹桌面通知(同会话 4s 合并、点击跳转会话),权限申请放在个人菜单。
40
+
41
+ > **验证**:bridge `npm run typecheck` 与 `npm test` 通过
42
+ > (120 files、1724 passed、2 skipped);Java `mvn -q test` 通过;
43
+ > dashboard `npm run lint`、`npm run type-check` 与 99 个 `test:*` 脚本
44
+ > 全部通过。
45
+
46
+ ## v1.9.170
47
+
48
+ _发布日期:2026-10-17_
49
+
50
+ ### 能力市场与插件运行时落地,并发一致性与调试挂载修复
51
+
52
+ - 新增能力市场:Java 侧 `AbilityMarketService` / `AbilityMarketController` 提供
53
+ 模板上架、安装、卸载与“我的能力”清单,安装态以 `RuntimeGlobalSettings`
54
+ 全局设置持久化;bridge 侧配套能力市场工具与 MCP 包探测、部署链路
55
+ (`mcp-package.ts`、`mcp-probe-client.ts`、`ability-market-tools.ts`)。
56
+ - bridge 插件体系重构为 manifest / loader / runtime / listener-runner 分层,
57
+ 统一插件清单校验、持久化目录部署与监听器生命周期,并补充插件开发指南与
58
+ 插件系统设计文档。
59
+ - dashboard 新增能力市场管理页与安装弹窗(含环境变量占位符校验)、Agent 状态
60
+ 重置与上下文压缩弹窗,会话操作菜单抽取为 `chat-message-actions`。
61
+ - 新增调试挂载(debug-mount)能力:会话建立时按需挂载调试资源,会话销毁
62
+ (含 SDK 会话清理各出口)统一调用 `clearDebugMounts`,避免残留。
63
+ - 修复:`AbilityMarketService` 安装 / 卸载回滚快照在同一写锁内捕获,消除并发
64
+ 写下的回滚竞态;`mcp-deploy` 增加名称合法性校验(拒绝 `.`、`..` 与非 basename)
65
+ 并改用原子 rename 交换,清单 `fileName` 以实际下载文件名为准。
66
+ - 修复:插件部署仅在全部候选迁移成功时才清理旧 `shared/` 目录,legacy
67
+ `zipFile` 经 `sanitizeArchiveFileName` 收敛,重命名失败不再误删目标目录;
68
+ 插件处理器在启用 shell 且命令含 `{{...}}` 插值时改为 fail-closed 拒绝执行。
69
+ - 修复:`package/acode` 运行时 `removeMcpServer` 同步清理 stderr 缓冲;手动
70
+ compact 优先级高于自动 `shouldCompact`,避免手动压缩计划被丢弃。
71
+
72
+ > **验证**:bridge `tsc --noEmit` 与 `vitest run` 通过(1687 passed;仅
73
+ > `src/browser/page-listener-nav.smoke.test.ts` 偶发 hook 超时,重跑通过,该目录
74
+ > 未改动);`package/acode` `tsc --noEmit`、`runtime.test.ts` 与 `compaction.test.ts`
75
+ > 通过;Java `mvn compile` 通过,`AbilityMarketServiceTest`(31)、
76
+ > `RuntimeBridgeServiceTest`(79)通过;dashboard `npm run lint`、`npm run type-check`
77
+ > 以及 i18n / ability-market / dialogQueue 相关测试通过。
78
+
8
79
  ## v1.9.169
9
80
 
10
81
  _发布日期:2026-10-12_
@@ -17,6 +17,13 @@ type ACodeRuntimeInstance = {
17
17
  }): Promise<void>;
18
18
  abort(): Promise<void>;
19
19
  resetContext?(): Promise<void>;
20
+
21
+ compactContext?(plan?: {
22
+ pruneCategories?: string[];
23
+ summarize?: boolean;
24
+ }): unknown;
25
+
26
+ getCompactionPreview?(): unknown;
20
27
  stop(): Promise<void>;
21
28
 
22
29
  exportConversation?(): unknown[];
@@ -37,11 +44,27 @@ type ACodeRuntimeInstance = {
37
44
 
38
45
  requestMcpToolsRefresh?(serverName?: string): void;
39
46
 
47
+ addMcpServer?(name: string, spec: Record<string, unknown>): Promise<{
48
+ ok: boolean;
49
+ tools: number;
50
+ toolNames?: string[];
51
+ error?: string;
52
+ }>;
53
+
54
+ removeMcpServer?(name: string): Promise<{
55
+ ok: boolean;
56
+ removed: boolean;
57
+ }>;
58
+
59
+ getMcpServerStderr?(name: string, tail?: number): string[];
60
+
40
61
  setToolPermissionPolicy?(policy: unknown): void;
41
62
 
42
63
  submitToolPermissionDecision?(requestId: string, allowed: boolean): boolean;
43
64
 
44
65
  addPluginCommands?(commands: unknown[]): void;
66
+
67
+ syncPluginGroups?(): Promise<void>;
45
68
  };
46
69
  type ACodeRuntimeConstructor = new (config: {
47
70
  sessionId: string;
@@ -133,6 +156,13 @@ export declare class AcodeSdkAdapter extends EventEmitter implements BaseProvide
133
156
  sendQuestionAnswer(sessionId: string, answers: Record<string, string>): Promise<void>;
134
157
  abortCurrentTurn(sessionId: string): Promise<void>;
135
158
  resetContext(sessionId: string): Promise<void>;
159
+
160
+ compactContext(sessionId: string, plan?: {
161
+ pruneCategories?: string[];
162
+ summarize?: boolean;
163
+ }): unknown;
164
+
165
+ getCompactionPreview(sessionId: string): unknown;
136
166
  terminateSession(sessionId: string): Promise<void>;
137
167
  getConversation(sessionId: string): ConversationMessage[];
138
168
 
@@ -160,6 +190,22 @@ export declare class AcodeSdkAdapter extends EventEmitter implements BaseProvide
160
190
 
161
191
  private syncMcpToolsForAgent;
162
192
 
193
+ debugMountMcpServer(agentId: string, name: string, spec: Record<string, unknown>): Promise<{
194
+ ok: boolean;
195
+ mounted: boolean;
196
+ sessions: number;
197
+ tools: number;
198
+ toolNames?: string[];
199
+ error?: string;
200
+ }>;
201
+
202
+ debugUnmountMcpServer(agentId: string, name: string): Promise<{
203
+ ok: boolean;
204
+ sessions: number;
205
+ }>;
206
+
207
+ getMcpServerStderr(agentId: string, name: string, tail?: number): string[];
208
+
163
209
  private shouldInjectCapabilityTools;
164
210
 
165
211
  private resolveCapabilityToolPrefix;
@@ -1,7 +1,7 @@
1
- import{EventEmitter as nt}from"node:events";import rt from"node:fs/promises";import H from"node:path";import{fileURLToPath as lt,pathToFileURL as ut}from"node:url";import{isMcpGroupKey as dt}from"@agentswork/acode";import{v4 as L}from"uuid";import{getBridgeInstancePluginsDir as ct,getBridgeInstanceSkillsDir as pt,getBridgeTemplateConfigFile as M,getBridgeTemplateSkillsDir as mt}from"../config.js";import{getReleasedAcodeEntryPath as ft}from"../services/acode-package.js";import{syncAgentSkillFarm as K}from"../services/agent-capability-sync.js";import{agentPtyManager as gt}from"../services/agent-pty-manager.js";import{getBrowserTools as v,closeBrowserSession as ht,registerListenerWakeHook as Tt,unregisterListenerWakeHook as j}from"../services/browser-session-manager.js";import{getDesktopTools as R,getDesktopToolsIfReady as At}from"../services/desktop-mcp-manager.js";import{redactForLog as G}from"../services/instance-ai-config-service.js";import{BROWSER_FEATURE_KEY as x,DESKTOP_FEATURE_KEY as w,getAgentToolPermissions as yt,getFeatureState as U,isFeatureEnabled as St,resolveAgentToolPermissions as bt,resolveGroupFeatureKey as _t}from"../services/instance-features.js";import{pluginManager as I}from"../services/plugin-manager.js";import{buildRuntimeResourcesSnapshot as Ct}from"../services/runtime-resources-snapshot.js";import{subAgentManager as kt}from"../services/sub-agent-manager-instance.js";import{recordAgentFileChange as Pt}from"../services/workspaceTaskChangeWatcher.js";import{getInstanceAiConfigDebugLogger as F}from"../utils/instance-ai-config-debug-logger.js";import{recordLifecycleEvent as k}from"../utils/lifecycle-log.js";import{isMessagePollingIdleCommand as q,isPollMessageToolDescriptor as wt}from"./acode-tool-names.js";import{IdlePollLoop as $t}from"./idle-poll-loop.js";import{resolveAcodeProviderConfig as Et}from"./instance-ai-config-resolver.js";import{MESSAGE_POLLING_IDLE_PROMPT as z}from"./prompts.js";import{getCanonicalMcpDetail as J,getToolActionInfo as Lt}from"./types.js";const xt=process.env.ACODE_COMPACTION_DEBUG==="1";function r(...l){xt&&console.log(...l)}const It=process.env.ACODE_TOKEN_DEBUG==="1";function P(...l){It&&console.log("[TokenDebug][Adapter]",...l)}const Dt=z,Ot=5e3;function $(l,t){const e=process.env[l];if(e===void 0||e.trim()==="")return t;const o=Number(e.trim());return Number.isFinite(o)&&o>=0?Math.floor(o):t}const Q=$("ACODE_DATA_FLOW_WATCHDOG_MS",12e4),Rt=5*6e4,Mt=$("ACODE_STUCK_AUTOPOLL_TIMEOUT_MS",5*6e4),Y=$("ACODE_LIVENESS_POLL_INTERVAL_MS",15e3),B=$("ACODE_LIVENESS_STALL_TIMEOUT_MS",10*6e4),vt=250,Ut=1e3,Ft=$("ACODE_DEFERRED_IDLE_REARM_MS",3e3),V=[2e3,3e3,1e4,4e4],X=4e3;function Z(l){const t=String(l||"").trim();if(t)return t.length>X?`${t.slice(0,X)}\u2026(truncated)`:t}function qt(l){const t=l.toLowerCase();return/tool[_ ]?call/.test(t)||t.includes("invalid_request")?!0:/(?:failed:\s*|http[\s/]*|status[\s:="']*|code[\s:="']*)(400|401|403|404|422)(?!\d)/.test(t)}const N={[x]:"browser_",[w]:"desktop_"};function Bt(l){if(!l||typeof l!="object")return;const t=l,e=typeof t.exposedName=="string"&&t.exposedName||typeof t.toolName=="string"&&t.toolName||typeof t.name=="string"&&t.name||"";if(!e)return;const o=typeof t.execute=="function"?t.execute:void 0;return{name:e,...typeof t.description=="string"?{description:t.description}:{},...t.inputSchema!==void 0?{inputSchema:t.inputSchema}:{},definition:t,...o?{execute:o}:{}}}const tt=$("ACODE_SUBMIT_TIMEOUT_MS",12e4),et=3e3,Nt=z;function Wt(){return H.resolve(ft())}function Ht(l){return ut(H.resolve(l)).href}const ot=128e3,E={"claude-4":{contextLimit:2e5,maxOutput:8192},"claude-sonnet-4":{contextLimit:2e5,maxOutput:8192},"claude-3-5-sonnet":{contextLimit:2e5,maxOutput:8192},"claude-3-opus":{contextLimit:2e5,maxOutput:8192},"claude-3-haiku":{contextLimit:2e5,maxOutput:8192},"claude-2":{contextLimit:1e5,maxOutput:4096},"gpt-4o":{contextLimit:128e3,maxOutput:16384},"gpt-4-turbo":{contextLimit:128e3,maxOutput:4096},"gpt-4":{contextLimit:8192,maxOutput:4096},"gpt-3.5-turbo":{contextLimit:16384,maxOutput:4096},o1:{contextLimit:2e5,maxOutput:1e5},"o3-mini":{contextLimit:2e5,maxOutput:1e5},"gemini-2.0-flash":{contextLimit:1048576,maxOutput:8192},"gemini-2.5-pro":{contextLimit:1048576,maxOutput:8192},"gemini-1.5-pro":{contextLimit:2097152,maxOutput:8192},"gemini-1.5-flash":{contextLimit:1048576,maxOutput:8192},deepseek:{contextLimit:64e3,maxOutput:8192},"deepseek-chat":{contextLimit:64e3,maxOutput:8192},"deepseek-reasoner":{contextLimit:64e3,maxOutput:8192},"qwen-max":{contextLimit:32e3,maxOutput:8192},"qwen-plus":{contextLimit:128e3,maxOutput:8192},"qwen-turbo":{contextLimit:1e6,maxOutput:8192},"glm-4":{contextLimit:128e3,maxOutput:4096},"yi-":{contextLimit:2e5,maxOutput:4096},"llama-3":{contextLimit:8192,maxOutput:4096},"llama-2":{contextLimit:4096,maxOutput:4096},mistral:{contextLimit:32e3,maxOutput:4096},mixtral:{contextLimit:32e3,maxOutput:4096},codestral:{contextLimit:256e3,maxOutput:8192},grok:{contextLimit:131072,maxOutput:4096},"nova-":{contextLimit:2e5,maxOutput:8192}};function Kt(l){if(!l)return ot;const t=l.toLowerCase().trim(),e=E[t];if(e)return e.contextLimit;const o=Object.keys(E).filter(a=>t.startsWith(a)).sort((a,i)=>i.length-a.length),s=o[0]!==void 0?E[o[0]]:void 0;return s?s.contextLimit:ot}const st=4096;function jt(l){if(!l)return st;const t=l.toLowerCase().trim(),e=E[t];if(e)return e.maxOutput;const o=Object.keys(E).filter(a=>t.startsWith(a)).sort((a,i)=>i.length-a.length),s=o[0]!==void 0?E[o[0]]:void 0;return s?s.maxOutput:st}function it(l){if(!l||typeof l!="object")return;const t=l,e=y(t.inputTokens,t.input_tokens,t.promptTokens,t.prompt_tokens),o=y(t.outputTokens,t.output_tokens,t.completionTokens,t.completion_tokens);if(e===0&&o===0)return;let s=y(t.cacheHitTokens,t.promptCacheHitTokens,t.prompt_cache_hit_tokens),a=y(t.cacheMissTokens,t.promptCacheMissTokens,t.prompt_cache_miss_tokens),i=t.cacheHitTokens!==void 0||t.cacheMissTokens!==void 0||t.promptCacheHitTokens!==void 0||t.promptCacheMissTokens!==void 0||t.prompt_cache_hit_tokens!==void 0||t.prompt_cache_miss_tokens!==void 0;if(s===0&&a===0){const n=y(t.cache_read_input_tokens),c=y(t.cache_creation_input_tokens);if(n>0||c>0){const f=t.input_tokens!==void 0&&Number.isFinite(Number(t.input_tokens))&&Number(t.input_tokens)>=0?y(t.input_tokens):Math.max(0,e-n-c);s=n,a=c+f,i=!0}else s=y(t.cache_hit_tokens),a=y(t.cache_miss_tokens),i=i||t.cache_hit_tokens!==void 0||t.cache_miss_tokens!==void 0}if(s===0&&a===0){const n=y(t.prompt_tokens_details?.cached_tokens);n>0&&(s=n,a=e>n?e-n:0,i=!0)}return{inputTokens:e,outputTokens:o,...i?{cacheHitTokens:s,cacheMissTokens:a}:{},...i?{hasCache:!0}:{}}}function y(...l){for(const t of l){const e=Number(t);if(Number.isFinite(e)&&e>0)return e}return 0}function Gt(l){return l==="stderr"||l==="mixed"?l:"stdout"}function D(l){const t=Number(l);return Number.isFinite(t)?t:0}function W(l){if(l==null)return;const t=Number(l);return Number.isFinite(t)?t:void 0}function zt(l){if(!l||typeof l!="object"||Array.isArray(l))return;const t={};for(const[e,o]of Object.entries(l))typeof o=="string"&&(t[e]=o);return Object.keys(t).length>0?t:void 0}function Jt(l){return l.failed===!0}function at(l,t,e){if(!l)return e?`${t}/${e}`:t;const o=`${t}__`;return l.startsWith(o)?J(`${t}__${l.slice(o.length)}`):J(l.replace("/","__"))}function Qt(l){return l==="read_file"||l==="edit_file"||l==="write_file"||l==="bash"}function Yt(l){const t=Vt(l);return t?[t.directMessages,t.groupMessages,t.messages].some(e=>Array.isArray(e)&&e.length>0):typeof l=="string"&&l.trim().length>0}function Vt(l){if(l&&typeof l=="object"&&!Array.isArray(l))return l;if(!(typeof l!="string"||!l.trim()))try{const t=JSON.parse(l);return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}catch{return}}class ke extends nt{constructor(){super(),this.providerId="acode",this.displayName="ACode",this.sessions=new Map,this.expandedBuiltInCapabilities=new Map,this.builtInCapabilityToolCache=new Map,this.listenerWakeHooks=new Map,I.setOnPluginsChanged(t=>{this.syncPluginCommands(t)})}async syncPluginCommands(t){try{const e=await I.getPluginCommands(t);for(const o of this.sessions.values())o.config.agentId===t&&o.runtime.addPluginCommands?.(e)}catch(e){r(`[acode-adapter] syncPluginCommands failed for agent ${t}:`,e.message)}}async startSession(t,e){const o=e.mcpConfigPath||M(),{resolved:s,configContextLimit:a,supportsImage:i}=await this.resolveAcodeProvider(e,o),n=s.model,c=a??Kt(n),u=jt(n),f={sessionId:t,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0,contextLimit:c,maxOutput:u,cacheHitTokens:0,cacheMissTokens:0}};this.sessions.set(t,{adapterSession:f,config:e,runtime:await this.createRuntime(t,n,e,s,i),autoPollActive:!1,retryAttempt:0,retryActive:!1,retryEpoch:0}),this.emit("status-change",t,"starting");const d=this.sessions.get(t);if(!d)throw new Error("ACode session was not initialized");this.startLivenessWatchdog(t,d);const p=()=>{const m=this.sessions.get(t);m&&(m.autoPollDelayMs=void 0,this.getIdlePollLoop(m).start())};this.listenerWakeHooks.set(t,p),Tt(e.agentId,p);try{if(await d.runtime.start(),console.log(`[HIBERNATE-REPLAY] startSession: agentId=${e.agentId??"?"} resumeTranscript=${Array.isArray(d.config.resumeTranscript)?`${d.config.resumeTranscript.length}\u6761`:"\u65E0"} importTranscript\u652F\u6301=${typeof d.runtime.importTranscript=="function"}`),f.status="waiting_input",this.emit("status-change",t,"waiting_input",{usage:d.adapterSession.totalUsage}),d.config.resumeTranscript&&d.runtime.importTranscript)try{const m=await d.runtime.importTranscript(d.config.resumeTranscript);console.log(`[HIBERNATE-REPLAY] importTranscript \u5B8C\u6210: agentId=${e.agentId??"?"} \u91CD\u653E=${m}\u6761 conversation=${d.runtime.exportConversation?.().length??"?"}\u6761`),m>0&&d.adapterSession.messages.push({id:L(),sessionId:t,role:"assistant",content:`[\u4F11\u7720\u6062\u590D] \u5DF2\u91CD\u653E\u4F11\u7720\u524D\u7684 ${m} \u6761\u5BF9\u8BDD\u8BB0\u5F55\uFF0C\u4E0A\u4E0B\u6587\u5DF2\u63A5\u7EED\u3002`,timestamp:new Date().toISOString()})}catch(m){console.error(`[HIBERNATE-REPLAY] importTranscript \u5931\u8D25\uFF08\u964D\u7EA7\u4E3A\u6458\u8981\u901A\u9053\uFF09: agentId=${e.agentId??"?"}`,m instanceof Error?m.stack:m)}e.initialPrompt?.trim()?this.startInitialPromptTurn(t,e.initialPrompt):this.armIdleLoopOrAutoPoll(t)}catch(m){f.status="error",this.emitRuntimeErrorEvent(t,m),this.emit("status-change",t,"error");const T=this.sessions.get(t);throw T?.capabilitiesFallbackTimer&&clearTimeout(T.capabilitiesFallbackTimer),T&&this.stopLivenessWatchdog(T),this.sessions.delete(t),j(e.agentId,this.listenerWakeHooks.get(t)),this.listenerWakeHooks.delete(t),m}}async sendMessage(t,e){const o=Date.now();r("[ACode] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),r("[ACode] \u25B6\uFE0F sendMessage STARTED"),r(`[ACode] Session: ${t}`),r(`[ACode] Message: ${e.slice(0,100)}${e.length>100?"...":""}`),r("[ACode] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");const s=this.requireSession(t),a=s.adapterSession.status;r(`[ACode] Previous status: ${a}`),this.cancelScheduledAutoPoll(s),s.failedTurnRecoveryScheduled=!1,s.idlePollLoop?.stop(),s.idleListeningIntentionallyStopped=!1,this.cancelRequestRetry(s),s.retryAttempt=0,s.retryCircuitBroken=!1,s.retryEpoch+=1,s.turnModelRequestSucceeded=!1;const i={id:L(),sessionId:t,role:"user",content:e,timestamp:new Date().toISOString()};s.adapterSession.messages.push(i),this.emit("conversation-message",t,i),r(`[ACode] Changing status: ${a} \u2192 thinking`),s.adapterSession.status="thinking",this.emit("status-change",t,"thinking"),s.autoPollObservedAssistantText=!1,s.autoPollObservedAnyTool=!1,s.autoPollObservedPollingTool=!1,s.lastSubmittedPrompt=e,s.retryEpoch+=1,s.turnModelRequestSucceeded=!1,this.startSubmitTimeoutDetection(t,s,"sendMessage");try{r("[ACode] \u25B6\uFE0F Calling runtime.submit()...");const n=Date.now();await s.runtime.submit(e);const c=Date.now()-n;this.cancelSubmitTimeoutDetection(s),r(`[ACode] \u2705 runtime.submit() completed in ${c}ms`),r(`[ACode] Current status after submit: ${s.adapterSession.status}`),r("[ACode] \u25B6\uFE0F Calling recoverResolvedTurnWithoutTerminalEvent()..."),this.recoverResolvedTurnWithoutTerminalEvent(t),r(`[ACode] Status after recovery: ${s.adapterSession.status}`);const u=Date.now()-o;r("[ACode] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),r(`[ACode] \u2705 sendMessage COMPLETED in ${u}ms`),r("[ACode] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")}catch(n){const c=Date.now()-o;console.error(`[ACode] \u274C sendMessage FAILED after ${c}ms:`,n instanceof Error?n.message:String(n)),this.cancelSubmitTimeoutDetection(s),r("[ACode] \u25B6\uFE0F sendMessage failed, scheduling request retry..."),this.emitRuntimeErrorEvent(t,n),this.scheduleRequestRetry(t,"sendMessage"),r(`[ACode] Status after failure: ${s.adapterSession.status}`)}}async sendConfirmation(t,e){}submitToolPermissionDecision(t,e,o){const s=this.sessions.get(t);if(!s)return!1;s.pendingToolAuthRequests?.delete(e);const a=s.runtime.submitToolPermissionDecision?.(e,o)??!1;return a&&this.startSubmitTimeoutDetection(t,s,"submitToolPermissionDecision"),a}getPendingToolAuthRequests(t){const e=this.sessions.get(t);return e?.pendingToolAuthRequests?Array.from(e.pendingToolAuthRequests.entries()).map(([o,s])=>({requestId:o,capability:s.capability,detail:s.detail,requestedAt:s.requestedAt})):[]}async sendQuestionAnswer(t,e){const o=this.sessions.get(t);if(!o)return;const s=o.pendingQuestionToolCallId;if(!s){r(`[AcodeSdkAdapter] sendQuestionAnswer: no pending question for session ${t}`);return}o.pendingQuestionToolCallId=void 0,o.pendingQuestions=void 0,o.runtime.submitQuestionAnswer&&o.runtime.submitQuestionAnswer(s,e),this.startSubmitTimeoutDetection(t,o,"sendQuestionAnswer")}async abortCurrentTurn(t){await this.requireSession(t).runtime.abort()}async resetContext(t){const e=this.requireSession(t);if(this.cancelScheduledAutoPoll(e),e.failedTurnRecoveryScheduled=!1,e.autoPollActive=!1,e.autoPollObservedPollingTool=!1,e.autoPollObservedAssistantText=!1,e.autoPollObservedAnyTool=!1,e.stopAutoPollAfterCurrentTurn=!1,e.idleListeningIntentionallyStopped=!1,e.idlePollLoop?.stop(),!e.runtime.resetContext)throw new Error("ACode runtime does not support context reset");await e.runtime.resetContext(),e.adapterSession.messages=[];const o=e.adapterSession.totalUsage;if(e.adapterSession.totalUsage={inputTokens:0,outputTokens:0,contextLimit:o.contextLimit,maxOutput:o.maxOutput,inputLimit:o.inputLimit,compactionThreshold:o.compactionThreshold,cacheHitTokens:o.cacheHitTokens,cacheMissTokens:o.cacheMissTokens},e.adapterSession.status="waiting_input",this.emit("status-change",t,"waiting_input",{usage:e.adapterSession.totalUsage}),e.config.initialPrompt?.trim()){this.startInitialPromptTurn(t,e.config.initialPrompt);return}this.armIdleLoopOrAutoPoll(t)}async terminateSession(t){const e=this.sessions.get(t);if(!e)return;this.cancelScheduledAutoPoll(e),e.failedTurnRecoveryScheduled=!1,e.idlePollLoop?.stop(),this.stopLivenessWatchdog(e),this.cancelRequestRetry(e),e.capabilitiesFallbackTimer&&(clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=void 0),await e.runtime.stop();const o=e.config.agentId;o&&(j(o,this.listenerWakeHooks.get(t)),ht(o)),this.listenerWakeHooks.delete(t),e.adapterSession.status="terminated",this.sessions.delete(t),o&&![...this.sessions.values()].some(s=>s.config.agentId===o)&&(this.expandedBuiltInCapabilities.delete(o),this.builtInCapabilityToolCache.delete(o)),this.emit("status-change",t,"terminated")}getConversation(t){return this.sessions.get(t)?.adapterSession.messages??[]}exportRawTranscript(t){const e=this.sessions.get(t);if(e?.runtime.exportConversation)try{const o=e.runtime.exportConversation();return Array.isArray(o)?o:void 0}catch{return}}async importRawTranscript(t,e){const o=this.sessions.get(t);return!o?.runtime.importTranscript||!Array.isArray(e)?0:o.runtime.importTranscript(e)}hasSession(t){return this.sessions.has(t)}getProviderSessionId(t){return this.sessions.has(t)?t:void 0}getSessionStatus(t){return this.sessions.get(t)?.adapterSession.status}getTotalUsage(t){const e=this.sessions.get(t)?.adapterSession.totalUsage;if(e)return{inputTokens:e.inputTokens,outputTokens:e.outputTokens}}notifyForceMessage(t){const e=this.sessions.get(t);return e?.runtime?.notifyForceMessage?(e.autoPollDelayMs=void 0,e.runtime.notifyForceMessage(),!0):!1}getCapabilities(t){return this.sessions.get(t)?.lastCombinedCapabilities}async resolveAgentAiInfo(t){try{const e=[...this.sessions.values()].find(i=>i.config.agentId===t);if(!e)return;const o=e.config.mcpConfigPath||M(),{resolved:s,supportsImage:a}=await this.resolveAcodeProvider(e.config,o);return s?.model?{model:s.model,supportsImage:a===!0,...s.baseURL?{baseURL:s.baseURL}:{},...s.apiKey?{apiKey:s.apiKey}:{}}:void 0}catch{return}}resolveAgentSkillsDir(t){if(t){try{const e=K(t);if(e)return e}catch(e){r(`[acode-adapter] skill farm sync failed for agent ${t}:`,e.message)}return pt(t)}return mt()}async applyAgentFeatures(t){if(!t)return;const e=this.shouldInjectCapabilityTools(t,w),o=this.shouldInjectCapabilityTools(t,x);for(const[a,i]of this.sessions){if(i.config.agentId!==t)continue;const n=i.runtime,c=e,u=o;try{if(c){const f=await R(t,await this.resolveAgentAiInfo(t)),d=n.addBuiltInTools?.(f)??0;d>0&&r(`[acode-adapter] session ${a}: ${d} desktop tools hot-added for agent ${t}`)}else{const f=n.removeBuiltInToolsByPrefix?.("desktop_")??0;f>0&&r(`[acode-adapter] session ${a}: ${f} desktop tools hot-removed for agent ${t}`)}}catch(f){r(`[acode-adapter] session ${a}: desktop feature hot-sync failed for agent ${t}:`,f.message)}if(u)try{const f=await v(t,i.config.scopeKey,typeof i.config.browserAllowPrivate=="boolean"?{allowPrivate:i.config.browserAllowPrivate}:void 0),d=n.addBuiltInTools?.(f)??0;d>0&&r(`[acode-adapter] session ${a}: ${d} browser tools hot-added for agent ${t}`)}catch(f){r(`[acode-adapter] session ${a}: browser feature hot-sync failed for agent ${t}:`,f.message)}else{const f=n.removeBuiltInToolsByPrefix?.("browser_")??0;f>0&&r(`[acode-adapter] session ${a}: ${f} browser tools hot-removed for agent ${t}`)}}this.syncMcpToolsForAgent(t);try{K(t)}catch(a){r(`[acode-adapter] skill farm hot-sync failed for agent ${t}:`,a.message)}try{await I.applyCapabilities(t)}catch(a){r(`[acode-adapter] plugin capability hot-sync failed for agent ${t}:`,a.message)}const s=bt(t);for(const[a,i]of this.sessions)if(i.config.agentId===t)try{i.runtime.setToolPermissionPolicy?.(s)}catch(n){r(`[acode-adapter] session ${a}: tool permission policy hot-sync failed for agent ${t}:`,n.message)}}syncMcpToolsForAgent(t){if(t){for(const[e,o]of this.sessions)if(o.config.agentId===t)try{o.runtime.requestMcpToolsRefresh?.()}catch(s){r(`[acode-adapter] session ${e}: mcp tools refresh failed for agent ${t}:`,s.message)}}}shouldInjectCapabilityTools(t,e){return t?U(t,e)==="expanded":!0}resolveCapabilityToolPrefix(t){return N[String(t??"").trim()]}async loadCapabilityToolsForSession(t,e,o){const s=t===x?await v(e,o.config.scopeKey,typeof o.config.browserAllowPrivate=="boolean"?{allowPrivate:o.config.browserAllowPrivate}:void 0):await R(e,await this.resolveAgentAiInfo(e)),a=[];for(const i of s){const n=Bt(i);n&&a.push(n)}return a}async setBuiltInCapabilityTools(t,e,o){const s=String(t??"").trim(),a=this.resolveCapabilityToolPrefix(e);if(!s||!a)return{sessions:0,tools:0};const i=[...this.sessions.entries()].filter(([,u])=>u.config.agentId===s);if(i.length===0)return{sessions:0,tools:0};if(o==="collapse"){let u=0;for(const[f,d]of i){const p=d.runtime.removeBuiltInToolsByPrefix?.(a)??0;u+=p,p>0&&r(`[acode-adapter] session ${f}: ${p} ${e} tools removed on collapse (agent ${s})`)}return this.expandedBuiltInCapabilities.get(s)?.delete(e),this.builtInCapabilityToolCache.get(s)?.delete(e),r(`[acode-adapter] capability collapse: agent=${s} capability=${e} sessions=${i.length} removedTools=${u}`),{sessions:i.length,tools:u}}const n=new Map;for(const[u,f]of i){let d;try{d=await this.loadCapabilityToolsForSession(e,s,f)}catch(p){throw r(`[acode-adapter] session ${u}: capability ${e} tool load failed for agent ${s}:`,p.message),p}for(const p of d)n.has(p.name)||n.set(p.name,p)}const c=this.expandedBuiltInCapabilities.get(s)??new Set;return c.add(e),this.expandedBuiltInCapabilities.set(s,c),this.builtInCapabilityToolCache.set(s,n),r(`[acode-adapter] capability expand: agent=${s} capability=${e} sessions=${i.length} tools=${n.size} (manifests only, no session tool injection)`),{sessions:i.length,tools:n.size,manifests:[...n.values()].map(u=>({name:u.name,...u.description!==void 0?{description:u.description}:{},...u.inputSchema!==void 0?{inputSchema:u.inputSchema}:{}}))}}async callBuiltInCapabilityTool(t,e,o,s){const a=String(t??"").trim(),i=this.resolveCapabilityToolPrefix(e);if(!i)return{ok:!1,error:`\u672A\u77E5\u80FD\u529B\u300C${String(e)}\u300D\uFF1A\u4EC5\u652F\u6301 browser / desktop`};const n=String(o??"").trim();if(!n)return{ok:!1,error:"\u5DE5\u5177\u540D\u7F3A\u5931"};if(!n.startsWith(i))return{ok:!1,error:`\u5DE5\u5177\u300C${n}\u300D\u4E0D\u5C5E\u4E8E\u80FD\u529B\u300C${e}\u300D`};if(a&&U(a,e)==="disabled")return{ok:!1,error:`\u80FD\u529B\u300C${e}\u300D\u5DF2\u7981\u7528\uFF0C\u65E0\u6CD5\u8C03\u5EA6\u8BE5\u5DE5\u5177`};if(!(this.expandedBuiltInCapabilities.get(a)?.has(e)??!1))return{ok:!1,error:`\u80FD\u529B\u300C${e}\u300D\u5C1A\u672A\u5C55\u5F00\uFF0C\u8BF7\u5148\u8C03\u7528 expand_tools \u5C55\u5F00\u540E\u518D\u8C03\u5EA6\u8BE5\u5DE5\u5177`};const u=this.builtInCapabilityToolCache.get(a)?.get(n);return u?typeof u.execute!="function"?{ok:!1,error:`\u5DE5\u5177\u300C${n}\u300D\u4E0D\u53EF\u8C03\u5EA6\uFF08\u7F3A\u5C11 execute \u5B9E\u73B0\uFF09`}:{ok:!0,result:await u.execute.call(u.definition,s??{})}:{ok:!1,error:`\u5DE5\u5177\u300C${n}\u300D\u65E0\u7F13\u5B58\u5B9A\u4E49\uFF0C\u8BF7\u91CD\u65B0\u8C03\u7528 expand_tools \u5237\u65B0`}}getPendingQuestion(t){const e=this.sessions.get(t);if(e?.pendingQuestionToolCallId)return{toolCallId:e.pendingQuestionToolCallId,questions:e.pendingQuestions??[]}}cleanup(){for(const t of this.sessions.keys())this.terminateSession(t)}setIdleCommands(t,e){const o=this.sessions.get(t);if(o){if(o.idleCommands=e,this.cancelScheduledAutoPoll(o),e.idleInputCommand&&q(e.idleInputCommand)){this.getIdlePollLoop(o).start();return}o.adapterSession.status==="waiting_input"&&(e.idleInputCommand||e.nonInputCommand)&&this.getIdlePollLoop(o).start()}}setRuntimeConstructorForTest(t){this.runtimeConstructor=t}async loadAcodeProviderSection(t){try{const e=await rt.readFile(t,"utf-8"),o=JSON.parse(e),a=o.provider?.default,i=a?.options,n=y(o.contextLimit),c={},u={},f=a?.models;if(f&&typeof f=="object"){for(const[d,p]of Object.entries(f))if(p&&typeof p=="object"){const m=y(p.contextLimit);m>0&&(c[d.trim()]=m);const T=p.modalities?.input,g=Array.isArray(T)&&T.includes("image")||p.supportsImageInput===!0;u[d.trim()]=g===!0}}return{...a?.model?{model:a.model}:{},...i?.baseURL||i?.baseUrl?{baseURL:i?.baseURL||i?.baseUrl}:{},...i?.apiKey?{apiKey:i.apiKey}:{},...n>0?{contextLimit:n}:{},...Object.keys(c).length>0?{modelContextLimits:c}:{},...Object.keys(u).length>0?{modelImageSupport:u}:{}}}catch(e){const o=e instanceof Error?e.message:String(e);return F().log({level:"warn",category:"load",message:`loadAcodeProviderSection failed: ${t}: ${o}`,source:"bridge"}),{}}}async resolveAcodeProvider(t,e){const o=typeof t.model=="string"&&t.model.trim()?t.model.trim():void 0,s=F();s.log({level:"info",category:"resolve",message:"resolveAcodeProvider \u8F93\u5165",source:"bridge",details:{configModel:t.model??null,configInstanceAiConfig:t.instanceAiConfig?G(t.instanceAiConfig):null,configPath:e}});const a={...t.instanceAiConfig?.model?{model:t.instanceAiConfig.model}:{},...t.instanceAiConfig?.baseURL?{baseURL:t.instanceAiConfig.baseURL}:{},...t.instanceAiConfig?.apiKey?{apiKey:t.instanceAiConfig.apiKey}:{},...t.instanceAiConfig?.effort?{effort:t.instanceAiConfig.effort}:{},...o?{model:o}:{}},i=await this.loadAcodeProviderSection(e);let n=i.contextLimit;if(!n&&i.modelContextLimits){const u=o||t.instanceAiConfig?.model||i.model;u&&i.modelContextLimits[u]&&(n=i.modelContextLimits[u])}const c=Et(a,i,"acode-default");return s.log({level:"info",category:"resolve",message:"resolveAcodeProvider \u89E3\u6790\u7ED3\u679C",source:"bridge",details:{instanceConfig:G(a),globalConfigModel:i?.model??null,resolvedModel:c.model,resolvedBaseURL:c.baseURL??null,resolvedApiKey:c.apiKey?"[set]":null,configContextLimit:n,resolvedSource:c.source}}),{resolved:c,configPath:e,perSessionModel:o,configContextLimit:n,supportsImage:i.modelImageSupport?.[c.model]===!0}}async createRuntime(t,e,o,s,a){const i=await this.loadRuntimeConstructor(),n=o.mcpConfigPath||M();let c=[];try{c=await v(o.agentId,o.scopeKey,typeof o.browserAllowPrivate=="boolean"?{allowPrivate:o.browserAllowPrivate}:void 0)}catch(p){r(`[acode-adapter] browser tools injection skipped for agent ${o.agentId}:`,p.message)}let u=[];if(this.shouldInjectCapabilityTools(o.agentId??"",x)&&(u=c),o.agentId&&this.shouldInjectCapabilityTools(o.agentId,w))try{const p=s?.model?{model:s.model,supportsImage:a===!0,...s.baseURL?{baseURL:s.baseURL}:{},...s.apiKey?{apiKey:s.apiKey}:{}}:void 0,m=await R(o.agentId,p);m.length>0&&(u=[...u,...m])}catch(p){r(`[acode-adapter] desktop tools injection skipped for agent ${o.agentId}:`,p.message)}const f=new i({sessionId:t,agentId:o.agentId,workingDirectory:o.workingDirectory,configPath:n,skillsDir:this.resolveAgentSkillsDir(o.agentId),pluginsDir:o.agentId?ct(o.agentId):void 0,model:e,systemPrompt:typeof o.systemPrompt=="string"?o.systemPrompt:void 0,globalPrompt:typeof o.globalPrompt=="string"?o.globalPrompt:void 0,rolePrompt:typeof o.rolePrompt=="string"?o.rolePrompt:void 0,memory:typeof o.memory=="string"?o.memory:void 0,resumeContext:typeof o.resumeContext=="string"?o.resumeContext:void 0,env:o.envOverrides,subAgentManager:kt,terminalManager:gt,capabilityState:p=>dt(p)?"collapsed":U(o.agentId??"",_t(p)),capabilityToolRelay:o.agentId?{handlesGroup:p=>this.resolveCapabilityToolPrefix(p)!==void 0,handlesTool:p=>Object.values(N).some(m=>p.startsWith(m)),expand:async p=>(await this.setBuiltInCapabilityTools(o.agentId??"",p,"expand")).manifests??[],collapse:async p=>{await this.setBuiltInCapabilityTools(o.agentId??"",p,"collapse")},call:async(p,m)=>{const T=p.startsWith(N[w]??"desktop_")?w:x;return this.callBuiltInCapabilityTool(o.agentId??"",T,p,m)}}:void 0,pluginBridge:o.agentId?I.forAgent(o.agentId):void 0,runtimeResourcesProvider:o.agentId?()=>Ct(o.agentId):void 0,commandDirs:[lt(new URL("../services/builtin-commands/",import.meta.url))],...o.subAgentModel?{subAgentModel:o.subAgentModel}:{},...o.subAgentEffort?{subAgentEffort:o.subAgentEffort}:{},...o.instanceAiConfig?.effort?{effort:o.instanceAiConfig.effort}:{},onFileChange:p=>Pt({...p,agentId:o.agentId,workspacePath:o.workingDirectory}),extraBuiltInTools:u,...o.agentId?{toolPermissionPolicy:yt(o.agentId)??void 0}:{},subAgentSuiteTools:c,subAgentSuiteToolProvider:this.buildSubAgentSuiteToolProvider(o.agentId)});return F().log({level:"info",category:"resolve",message:"ACode provider resolved",source:"bridge",sessionId:t,details:{resolvedModel:e,perInstanceModel:o.instanceAiConfig?.model||null,perInstanceBaseURL:o.instanceAiConfig?.baseURL?"[set]":null,perInstanceApiKey:o.instanceAiConfig?.apiKey?"[set]":null,configPath:n}}),f.on("event",p=>this.forwardAcodeEvent(p)),f}buildSubAgentSuiteToolProvider(t){return async e=>{if(!t)return[];if(!St(t,w))return[];if(e.length===0)return At();if(!e.some(a=>{const i=a.trim().replace(/[.*]+$/,"");return i==="desktop"||i.startsWith("desktop.")}))return[];const s=await this.resolveAgentAiInfo(t);return R(t,s)}}async loadRuntimeConstructor(){if(this.runtimeConstructor)return this.runtimeConstructor;const t=Wt(),e=await import(Ht(t));if(!e.ACodeRuntime)throw new Error(`ACode runtime export not found: ${t}`);return this.runtimeConstructor=e.ACodeRuntime,this.runtimeConstructor}requireSession(t){const e=this.sessions.get(t);if(!e)throw new Error("ACode session not found");return e}startInitialPromptTurn(t,e){const o=this.sessions.get(t);o&&(o.adapterSession.status="thinking",this.emit("status-change",t,"thinking"),o.autoPollObservedAssistantText=!1,o.autoPollObservedAnyTool=!1,o.autoPollObservedPollingTool=!1,o.lastSubmittedPrompt=e,o.retryEpoch+=1,o.turnModelRequestSucceeded=!1,this.startSubmitTimeoutDetection(t,o,"startInitialPromptTurn"),o.runtime.submit(e).then(()=>{this.cancelSubmitTimeoutDetection(o),this.recoverResolvedTurnWithoutTerminalEvent(t)}).catch(s=>{const a=this.sessions.get(t);a&&(this.cancelSubmitTimeoutDetection(a),a.lastErrorText=s instanceof Error?s.message:String(s),this.emitRuntimeErrorEvent(t,s),this.scheduleRequestRetry(t,"startInitialPromptTurn"))}))}forwardAcodeEvent(t){const e=this.sessions.get(t.sessionId);if(e){if(e.lastAcodeEventAt=Date.now(),e.autoPollActive&&(e.autoPollLastActivityAt=Date.now()),t.type==="assistant_delta"){const o=typeof t.data.text=="string"?t.data.text:"";e.turnModelRequestSucceeded=!0,e.turnModelRequestSucceededEpoch=e.retryEpoch,e.autoPollObservedAssistantText=!0,e.adapterSession.messages.push({id:L(),sessionId:t.sessionId,role:"assistant",content:o,timestamp:t.timestamp}),this.resetDataFlowWatchdog(t.sessionId,e),this.emitProviderEvent(t,"text_delta",{text:o});return}if(t.type==="thinking_delta"){const o=typeof t.data.text=="string"?t.data.text:"";e.turnModelRequestSucceeded=!0,e.turnModelRequestSucceededEpoch=e.retryEpoch,this.resetDataFlowWatchdog(t.sessionId,e),this.emitProviderEvent(t,"thinking",{text:o});return}if(t.type==="command_output"){this.emitProviderEvent(t,"command_output",{text:typeof t.data.text=="string"?t.data.text:"",stream:Gt(t.data.stream),sequence:typeof t.data.sequence=="number"?t.data.sequence:void 0,cwd:typeof t.data.cwd=="string"?t.data.cwd:void 0,commandLineCount:typeof t.data.commandLineCount=="number"?t.data.commandLineCount:void 0,commandFilePath:typeof t.data.commandFilePath=="string"?t.data.commandFilePath:void 0});return}if(t.type==="background_command_completed"){this.emitProviderEvent(t,"background_command_completed",t.data);return}if(t.type==="ai_request"){const o=t.data.lastUsage,s=y(o?.inputTokens),a=y(o?.outputTokens),i=y(o?.cacheHitTokens),n=y(o?.cacheMissTokens),c=!!(o&&(s>0||a>0));let u;c&&(s>0&&(e.adapterSession.totalUsage.inputTokens=s),a>0&&(e.adapterSession.totalUsage.outputTokens=a),(o?.cacheHitTokens!==void 0||o?.cacheMissTokens!==void 0)&&(e.adapterSession.totalUsage.cacheHitTokens=i,e.adapterSession.totalUsage.cacheMissTokens=n),u={...e.adapterSession.totalUsage},P(`ai_request lastUsage applied: ${JSON.stringify(o)} -> totalUsage=${JSON.stringify(e.adapterSession.totalUsage)}`)),e.adapterSession.status==="compacting"&&(e.adapterSession.status="thinking"),e.adapterSession.status==="waiting_input"&&(e.adapterSession.status="thinking");const d={actionType:"ai_request",actionLabel:"AI\u8BF7\u6C42",actionDetail:this.formatAiRequestActionDetail(t.data)};u&&(d.usage=u),P(`ai_request handled: estimatedContextTokens=${t.data.estimatedContextTokens??"n/a"} totalUsage=${JSON.stringify(e.adapterSession.totalUsage)} displayUsage=${JSON.stringify(u??null)}`),this.emit("status-change",t.sessionId,e.adapterSession.status,d),this.startDataFlowWatchdog(t.sessionId,e),e.adapterSession.status==="thinking"&&e.watchdogSubmitStartTime&&(e.watchdogSubmitStartTime=Date.now()),this.emitProviderEvent(t,"ai_request",{model:typeof t.data.model=="string"?t.data.model:void 0,endpoint:typeof t.data.endpoint=="string"?t.data.endpoint:void 0,requestMethod:typeof t.data.requestMethod=="string"?t.data.requestMethod:void 0,requestUrl:typeof t.data.requestUrl=="string"?t.data.requestUrl:void 0,requestHeaders:zt(t.data.requestHeaders),stream:typeof t.data.stream=="boolean"?t.data.stream:void 0,messageCount:typeof t.data.messageCount=="number"?t.data.messageCount:void 0,toolCount:typeof t.data.toolCount=="number"?t.data.toolCount:void 0,lastUserMessagePreview:typeof t.data.lastUserMessagePreview=="string"?t.data.lastUserMessagePreview:void 0});return}if(t.type==="iteration_usage"){const o=it(t.data);o&&(e.adapterSession.totalUsage.inputTokens=o.inputTokens,e.adapterSession.totalUsage.outputTokens=o.outputTokens,o.hasCache&&(e.adapterSession.totalUsage.cacheHitTokens=o.cacheHitTokens,e.adapterSession.totalUsage.cacheMissTokens=o.cacheMissTokens),P(`iteration_usage applied: raw=${JSON.stringify(t.data)} -> totalUsage=${JSON.stringify(e.adapterSession.totalUsage)}`),this.emit("status-change",t.sessionId,e.adapterSession.status,{usage:{...e.adapterSession.totalUsage}}));return}if(t.type==="turn_complete"){const o=it(t.data.usage);if(o){const a=e.adapterSession.totalUsage.inputTokens,i=a>0&&o.inputTokens<Math.floor(a*.2)&&!o.hasCache;P(`turn_complete usage: raw=${JSON.stringify(t.data.usage)} parsed=${JSON.stringify(o)} currentInput=${a} threshold20pct=${Math.floor(a*.2)} isFallbackUsage=${i}`),i?o.outputTokens>0&&(e.adapterSession.totalUsage.outputTokens=o.outputTokens):(e.adapterSession.totalUsage.inputTokens=o.inputTokens,e.adapterSession.totalUsage.outputTokens=o.outputTokens),o.hasCache&&(e.adapterSession.totalUsage.cacheHitTokens=o.cacheHitTokens,e.adapterSession.totalUsage.cacheMissTokens=o.cacheMissTokens,r(`[ACode] \u{1F4B0} Cache usage (overwrite from runtime cumulative): hit=${e.adapterSession.totalUsage.cacheHitTokens}, miss=${e.adapterSession.totalUsage.cacheMissTokens} (turn delta: hit=${o.cacheHitTokens??0}, miss=${o.cacheMissTokens??0})`)),P(`totalUsage after turn_complete: ${JSON.stringify(e.adapterSession.totalUsage)}`)}else P(`turn_complete has NO parseable usage: raw=${JSON.stringify(t.data.usage)} failed=${t.data.failed===!0} aborted=${t.data.aborted===!0}`);const s=e.adapterSession.status;if(r(`[ACode] turn_complete event received (session: ${t.sessionId}), previous status: ${s}, failed: ${t.data.failed===!0}, aborted: ${t.data.aborted===!0}`),Jt(t.data)){r(`[ACode] Scheduling retry from failed turn_complete (session: ${t.sessionId})`),this.cancelDataFlowWatchdog(e),this.recoverTurnFailure(t.sessionId,e);return}if(t.data.aborted===!0&&(e.autoPollActive||e.retryActive||e.retryTimer)){r(`[ACode] Scheduling retry from aborted turn_complete (session: ${t.sessionId})`),this.cancelDataFlowWatchdog(e),this.recoverTurnFailure(t.sessionId,e);return}if(this.cancelDataFlowWatchdog(e),this.emitProviderEvent(t,"turn_complete",{usage:e.adapterSession.totalUsage,responseBody:typeof t.data.responseBody=="string"?t.data.responseBody:void 0,finishReason:typeof t.data.finishReason=="string"?t.data.finishReason:void 0}),e.adapterSession.status="waiting_input",k("turn_complete_to_waiting_input",{sessionId:t.sessionId,autoPollActive:!!e.autoPollActive,observedAnyTool:!!e.autoPollObservedAnyTool,observedPollingTool:!!e.autoPollObservedPollingTool,observedAssistantText:!!e.autoPollObservedAssistantText}),this.emit("status-change",t.sessionId,"waiting_input",{usage:e.adapterSession.totalUsage}),P(`status-change emitted (waiting_input after turn_complete): usage=${JSON.stringify(e.adapterSession.totalUsage)}`),r(`[ACode] Status changed to waiting_input after turn_complete (session: ${t.sessionId})`),e.autoPollActive&&e.autoPollObservedAssistantText&&!e.autoPollObservedPollingTool&&!e.autoPollObservedAnyTool){e.stopAutoPollAfterCurrentTurn=!0,e.idleListeningIntentionallyStopped=!0,console.warn(`[${this.displayName}] Auto-poll turn produced assistant text without calling any tool; stopping auto-poll rearm for session ${t.sessionId}`);return}if(!e.autoPollActive&&e.autoPollObservedAnyTool&&!e.autoPollObservedPollingTool){r(`[ACode] User-message turn called work tools; deferring idle rearm (no immediate dispatch) for this turn (session: ${t.sessionId})`),this.scheduleDeferredIdleRearm(t.sessionId);return}this.armIdleLoopOrAutoPoll(t.sessionId);return}if(t.type==="session_complete"){this.cancelDataFlowWatchdog(e),this.cancelScheduledAutoPoll(e),e.failedTurnRecoveryScheduled=!1,e.idlePollLoop?.stop(),e.adapterSession.status="completed",this.emitProviderEvent(t,"session_complete",{exitCode:Number(t.data.exitCode)||0}),this.emit("status-change",t.sessionId,"completed");return}if(t.type==="question_request"){this.cancelDataFlowWatchdog(e),this.cancelSubmitTimeoutDetection(e);const o=typeof t.data.toolCallId=="string"?t.data.toolCallId:"",s=Array.isArray(t.data.questions)?t.data.questions:[];o&&(e.pendingQuestionToolCallId=o,e.pendingQuestions=s),this.emit("ask-user-question",{sessionId:t.sessionId,toolCallId:o||void 0,questions:s});return}if(t.type==="tool_permission_request"){this.cancelDataFlowWatchdog(e),this.cancelSubmitTimeoutDetection(e);const o=typeof t.data.requestId=="string"?t.data.requestId:"";o&&(e.pendingToolAuthRequests||(e.pendingToolAuthRequests=new Map),e.pendingToolAuthRequests.set(o,{capability:String(t.data.capability||""),detail:{path:t.data.path,command:t.data.command,cwd:t.data.cwd,operation:t.data.operation},requestedAt:Date.now()})),this.emit("tool-permission-request",{sessionId:t.sessionId,requestId:o,capability:String(t.data.capability||""),agentId:e.config.agentId,detail:{path:t.data.path,command:t.data.command,cwd:t.data.cwd,operation:t.data.operation}});return}if(t.type==="error"){if(t.data.nonFatal){this.resetDataFlowWatchdog(t.sessionId,e),this.emitProviderEvent(t,"error",{text:String(t.data.message||"ACode runtime error")});return}this.cancelDataFlowWatchdog(e),e.adapterSession.status="error",e.lastErrorText=String(t.data.message||""),this.emitProviderEvent(t,"error",{text:String(t.data.message||"ACode runtime error")}),this.emit("status-change",t.sessionId,"error"),e.autoPollActive||this.recoverTurnFailure(t.sessionId,e);return}if(t.type==="mcp_status"){if(!t.data.action&&Array.isArray(t.data.tools)){const g=t.data.tools;g.some(A=>wt(A))||console.warn(`[${this.displayName}] ACode runtime is not exposing a poll_message tool. The LLM cannot call poll_message. Please configure an MCP server that provides poll_message (e.g. aws-mcp) in the dashboard panel for this runtime.`);const S=Array.isArray(t.data.servers)?t.data.servers:[],b=g.map(A=>({name:String(A.name??""),source:String(A.source??""),description:String(A.description??"")})).filter(A=>A.name),C={kind:"mcp",mcpServers:S,mcpTools:b};e.cachedMcpCapabilities=C,e.lastMcpCapabilities=C,e.lastCombinedCapabilities={kind:"combined",mcpServers:S,mcpTools:b,skills:e.lastCombinedCapabilities?.skills??[],skillsDir:e.lastCombinedCapabilities?.skillsDir,skillGroups:e.lastCombinedCapabilities?.skillGroups??[]},r(`[cap-diag] MCP capabilities cached: ${S.length} servers, ${b.length} tools`,{sessionId:t.sessionId,servers:S,toolNames:b.map(A=>A.name)}),e.capabilitiesFallbackTimer&&clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=setTimeout(()=>{const A=e.cachedMcpCapabilities;if(!A)return;const _={...A,skills:[],skillGroups:[]};this.emitProviderEvent(t,"runtime_capabilities",{capabilities:_,actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:JSON.stringify(_)}),r(`[cap-diag] MCP capabilities emitted via fallback (skill_status not received within ${et}ms)`,{sessionId:t.sessionId,mcpServers:A.mcpServers,mcpToolsCount:A.mcpTools?.length??0}),e.cachedMcpCapabilities=void 0,e.capabilitiesFallbackTimer=void 0},et);return}const o=String(t.data.action??"");if(o==="tool_batch_start"){const g=typeof t.data.batchId=="string"?t.data.batchId:void 0;if(!g){r(`[ACode] \u{1F9E9} tool_batch_start without batchId, ignored (session=${t.sessionId})`);return}const h=typeof t.data.toolCount=="number"?t.data.toolCount:0,S=Array.isArray(t.data.toolNames)?t.data.toolNames.map(b=>String(b??"")).filter(Boolean):[];r(`[ACode] \u{1F9E9} tool_batch_start: batch=${g.slice(0,20)}\u2026, tools=${h}`),this.emitProviderEvent(t,"tool_batch_start",{batchId:g,batchToolCount:h,batchToolNames:S,actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionDetail:S.length>0?S.join(", "):void 0,actionId:g});return}if(o==="tool_batch_metrics"){const g=typeof t.data.batchId=="string"?t.data.batchId:void 0;if(!g){r(`[ACode] \u26A1 tool_batch_metrics without batchId, ignored (session=${t.sessionId})`);return}const h={toolCount:D(t.data.toolCount),parallelism:D(t.data.parallelism),speedup:D(t.data.speedup),wallClockMs:D(t.data.wallClockMs),totalWaitMs:W(t.data.totalWaitMs),contentionCount:D(t.data.contentionCount),failureCount:W(t.data.failureCount),maxConcurrentObserved:W(t.data.maxConcurrentObserved)};r(`[ACode] \u26A1 tool_batch_metrics: batch=${g.slice(0,20)}\u2026, speedup=${h.speedup}x parallelism=${h.parallelism}x wall=${h.wallClockMs}ms contentions=${h.contentionCount} failures=${h.failureCount??"-"}`),this.emitProviderEvent(t,"tool_batch_metrics",{batchId:g,batchMetrics:h,actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionId:g});return}if(o!=="call_tool"&&o!=="tool_result"){r(`[ACode] \u{1F4AC} mcp_status status report ignored (action=${o||"none"}, server=${typeof t.data.server=="string"?t.data.server:"?"}, session=${t.sessionId})`);return}r(`[ACode] \u{1F4E1} mcp_status event: action=${o}, server=${typeof t.data.server=="string"?t.data.server:"?"}, tool=${typeof t.data.tool=="string"?t.data.tool:"?"}, toolUseId=${typeof t.data.toolUseId=="string"?t.data.toolUseId.slice(0,16)+"\u2026":"none"}, failed=${t.data.failed===!0}, session=${t.sessionId}, status=${e.adapterSession.status}`);const s=typeof t.data.server=="string"?t.data.server:"mcp",a=typeof t.data.tool=="string"?t.data.tool:"",i=s&&a?`${s}__${a}`:a||s,n=t.data.arguments&&typeof t.data.arguments=="object"&&!Array.isArray(t.data.arguments)?t.data.arguments:void 0,c=Lt(i,n);e.autoPollObservedAnyTool=!0,c.actionType==="idle"&&(e.autoPollObservedPollingTool=!0);const u=Qt(c.actionType)?c.actionDetail||at(void 0,s,a):at(c.actionDetail,s,a),f=typeof t.data.toolUseId=="string"?t.data.toolUseId:void 0,d=n?JSON.stringify(n,null,2):void 0,p=typeof t.data.batchId=="string"?t.data.batchId:void 0,m={toolName:u,rawToolName:i,actionType:c.actionType,actionLabel:c.actionLabel,actionDetail:u,...d?{actionInput:d}:{},...n?{toolInput:n}:{},...f?{toolUseId:f,actionId:f}:{},...p?{batchId:p,parentId:p}:{},metadata:{mcpServer:s}};if(t.data.action==="tool_result"){this.emitProviderEvent(t,"tool_use_end",{...m,toolResult:typeof t.data.result=="string"?t.data.result:JSON.stringify(t.data.result??"")}),e.adapterSession.messages.push({id:L(),sessionId:t.sessionId,role:"tool_result",content:typeof t.data.result=="string"?t.data.result:JSON.stringify(t.data.result??""),timestamp:t.timestamp,toolName:i,toolUseId:f,isError:t.data.failed===!0});const g=c.actionType==="idle"&&!Yt(t.data.result)?"waiting_input":"thinking";e.adapterSession.status=g,c.actionType==="idle"&&(e.idleToolActiveAt=void 0),k("tool_use_end",{sessionId:t.sessionId,actionType:c.actionType,tool:i,nextStatus:g,idleToolActiveAtAfter:e.idleToolActiveAt??null}),this.cancelDataFlowWatchdog(e),e.pendingToolEventData=void 0;const h=c.actionType==="idle";this.emit("status-change",t.sessionId,g,h||g==="thinking"?void 0:m);return}const T=c.actionType==="idle"?"waiting_input":"tool_using";e.adapterSession.status=T,c.actionType==="idle"&&(e.idleToolActiveAt=Date.now()),T==="tool_using"&&(this.resetDataFlowWatchdog(t.sessionId,e),e.pendingToolEventData={...m}),e.adapterSession.messages.push({id:L(),sessionId:t.sessionId,role:"tool_use",content:d??"",timestamp:t.timestamp,toolName:i,toolInput:n,toolUseId:f}),this.emitProviderEvent(t,"tool_use_start",m),this.emit("status-change",t.sessionId,T,m);return}if(t.type==="skill_status"){const s=(Array.isArray(t.data.skills)?t.data.skills:[]).map(d=>({name:String(d.name??""),description:typeof d.description=="string"?d.description:void 0,directory:typeof d.directory=="string"?d.directory:void 0})).filter(d=>d.name),a=typeof t.data.skillsDir=="string"?t.data.skillsDir:void 0,n=(Array.isArray(t.data.skillGroups)?t.data.skillGroups:[]).map(d=>{const p=Array.isArray(d.skills)?d.skills:[];return{dir:typeof d.dir=="string"?d.dir:"",exists:d.exists===!0,skills:p.map(m=>({name:String(m.name??""),description:typeof m.description=="string"?m.description:void 0,directory:typeof m.directory=="string"?m.directory:void 0})).filter(m=>m.name)}}).filter(d=>d.dir),c=e.cachedMcpCapabilities??e.lastMcpCapabilities,u=e.cachedMcpCapabilities!==void 0,f={kind:"combined",mcpServers:c?.mcpServers??[],mcpTools:c?.mcpTools??[],skills:s,skillsDir:a,skillGroups:n};this.emitProviderEvent(t,"runtime_capabilities",{capabilities:f,actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:JSON.stringify(f)}),e.lastCombinedCapabilities=f,r(`[cap-diag] Combined capabilities emitted ${u?"(startup merge)":"(runtime refresh)"}: ${(c?.mcpTools??[]).length} MCP tools, ${s.length} skills`,{sessionId:t.sessionId,mcpServers:c?.mcpServers??[],skillsDir:a}),e.capabilitiesFallbackTimer&&(clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=void 0),e.cachedMcpCapabilities=void 0;return}if(t.type==="startup_phase"){r(`[ACode] \u{1F680} startup_phase swallowed: ${String(t.data.phase??"unknown")}`,{sessionId:t.sessionId});return}if(t.type==="command_status"){if(t.data.action==="commands_loaded"){r(`[ACode] \u{1F4CB} command_status commands_loaded swallowed: ${typeof t.data.installedCommandCount=="number"?t.data.installedCommandCount:"?"} commands`,{sessionId:t.sessionId});return}this.emitProviderEvent(t,"thinking",{text:JSON.stringify(t.data)});return}if(t.type==="session_started"){const o=y(t.data.contextLimit)||void 0,s=y(t.data.maxOutput)||void 0,a=y(t.data.inputLimit)||void 0,i=y(t.data.compactionThreshold)||void 0;let n=!1;o!==void 0&&(e.adapterSession.totalUsage.contextLimit=o,n=!0),s!==void 0&&(e.adapterSession.totalUsage.maxOutput=s,n=!0),a!==void 0&&(e.adapterSession.totalUsage.inputLimit=a,n=!0),i!==void 0&&(e.adapterSession.totalUsage.compactionThreshold=i,n=!0),n&&this.emit("status-change",t.sessionId,e.adapterSession.status,{usage:e.adapterSession.totalUsage});return}if(t.type==="exit_plan_mode"){e.adapterSession.status="waiting_input";const o=typeof t.data.plan=="string"?t.data.plan:void 0;this.emitProviderEvent(t,"exit_plan_mode",{toolInput:t.data.toolInput&&typeof t.data.toolInput=="object"?t.data.toolInput:void 0,text:o||"\u9000\u51FA\u8BA1\u5212\u6A21\u5F0F"}),this.emit("status-change",t.sessionId,"waiting_input",{actionLabel:"\u5BA1\u6279\u8BA1\u5212",actionDetail:o||"\u7B49\u5F85\u7528\u6237\u5BA1\u6279\u9000\u51FA\u8BA1\u5212\u6A21\u5F0F"});return}if(t.type==="context_compaction"){const o=t.data,s=o.action,a=s==="start",i=s==="end",n=s==="phase",c=o.parentId,u=o.compactionId;if(o.trigger==="hibernation_replay"){const T=typeof o.replayedMessageCount=="number"?o.replayedMessageCount:void 0,g=o.estimatedTokens;typeof g=="number"&&g>0&&(e.adapterSession.totalUsage.inputTokens=g);const h={actionType:"context_compaction",actionLabel:"\u4F11\u7720\u6062\u590D",actionDetail:T?`\u5DF2\u91CD\u653E\u4F11\u7720\u524D\u7684 ${T} \u6761\u5BF9\u8BDD\u8BB0\u5F55\uFF0C\u4E0A\u4E0B\u6587\u5DF2\u63A5\u7EED`:"\u5DF2\u91CD\u653E\u4F11\u7720\u524D\u7684\u5BF9\u8BDD\u8BB0\u5F55\uFF0C\u4E0A\u4E0B\u6587\u5DF2\u63A5\u7EED",...u?{actionId:u}:{},...g?{usage:{...e.adapterSession.totalUsage,inputTokens:g}}:{}};this.emitProviderEvent(t,"context_compaction",h),this.emit("status-change",t.sessionId,e.adapterSession.status,h);return}let d,p;if(a){const T=String(o.sizeKB??o.sizeBeforeKB??"?"),g=String(o.messageCount??o.messageCountBefore??"?"),h=o.estimatedTokens,S=o.actualInputTokens?`input=${o.actualInputTokens}`:"",b=o.actualOutputTokens?`output=${o.actualOutputTokens}`:"",C=o.trigger;d="\u4E0A\u4E0B\u6587\u538B\u7F29\u5F00\u59CB";const A=C==="provider_overflow_error"?"\u6A21\u578B\u8FD4\u56DE\u4E0A\u4E0B\u6587\u8D85\u9650\u4FE1\u53F7":C==="finish_reason_context_overflow"?"\u54CD\u5E94\u4E2D\u7684\u8D85\u9650\u6807\u8BB0":C==="request_body_byte_limit"?"\u8BF7\u6C42\u4F53\u5B57\u8282\u4E0A\u9650":C,_=A?`, \u89E6\u53D1: ${A}`:"";h!==void 0?p=`\u538B\u7F29\u524D: ~${h} tokens, \u6D88\u606F: ${g}\u6761`+(S?`, \u5B9E\u9645 tokens: ${S} ${b}`:"")+_:p=`\u538B\u7F29\u524D: ${T}KB, \u6D88\u606F: ${g}\u6761`+(S?`, \u5B9E\u9645 tokens: ${S} ${b}`:"")+_}else if(n){const T=String(o.phase??""),g=String(o.phaseLabel??"\u538B\u7F29\u9636\u6BB5"),h=String(o.phaseDetail??"");T==="detect"?(d="\u5F00\u59CB\u89E6\u53D1\u54CD\u5E94\u5F0F\u538B\u7F29",p=h||"\u68C0\u6D4B\u5230\u4E0A\u4E0B\u6587\u8D85\u9650\uFF0C\u5373\u5C06\u5F00\u59CB\u538B\u7F29..."):(d=g,p=h)}else{const T=o.tokensBefore,g=o.tokensAfter,h=o.freedTokens,S=String(o.sizeBeforeKB??"?"),b=String(o.sizeAfterKB??"?"),C=String(o.freedKB??"?"),A=String(o.strategy??"?"),_=Number(o.prunedToolMessages??0),O=Number(o.summarizedMessages??0);d="\u538B\u7F29\u5B8C\u6210",T!==void 0&&g!==void 0?p=`\u91CA\u653E: ${h??T-g} tokens, ${T} tokens \u2192 ${g} tokens, \u7B56\u7565: ${A}`+(_?`, \u88C1\u526A\u5DE5\u5177: ${_}\u6761`:"")+(O?`, \u6458\u8981\u5316: ${O}\u6761`:""):p=`\u91CA\u653E: ${C}KB, ${S}KB \u2192 ${b}KB, \u7B56\u7565: ${A}`+(_?`, \u88C1\u526A\u5DE5\u5177: ${_}\u6761`:"")+(O?`, \u6458\u8981\u5316: ${O}\u6761`:"")}a&&(e.adapterSession.status="compacting");const m={actionType:"context_compaction",actionLabel:d,actionDetail:p};if(a&&u)m.actionId=u;else if((n||i)&&u)if(m.parentId=u,n){const T=String(o.phase??"unknown");m.actionId=`${u}-phase-${T}`}else m.actionId=`${u}-end`;n&&c&&!m.parentId&&(m.parentId=c),i&&(e.adapterSession.totalUsage.inputTokens=y(o.tokensAfter),e.adapterSession.totalUsage.outputTokens=0,e.config.agentId&&I.markAgentCompacted(e.config.agentId),m.usage={...e.adapterSession.totalUsage}),this.emitProviderEvent(t,"context_compaction",m),this.emit("status-change",t.sessionId,"compacting",m);return}this.emitProviderEvent(t,"thinking",{text:JSON.stringify(t.data)})}}emitProviderEvent(t,e,o){this.emit("event",{type:e,sessionId:t.sessionId,timestamp:t.timestamp,data:o})}armIdleLoopOrAutoPoll(t){const e=this.sessions.get(t);if(!(!e||this.isTerminalStatus(e.adapterSession.status))){if(e.autoPollTimer&&(clearTimeout(e.autoPollTimer),e.autoPollTimer=void 0),this.cancelRequestRetry(e),e.retryAttempt=0,e.idleCommands?.idleInputCommand){this.getIdlePollLoop(e).start();return}this.scheduleAutoPoll(t)}}scheduleDeferredIdleRearm(t){const e=this.sessions.get(t);!e||e.autoPollActive||e.autoPollTimer||this.isTerminalStatus(e.adapterSession.status)||this.scheduleAutoPoll(t,Ft)}getIdlePollLoop(t){if(t.idlePollLoop)return t.idlePollLoop;const e=t.adapterSession.sessionId;return t.idlePollLoop=new $t({getStatus:()=>this.sessions.get(e)?.adapterSession.status,getCommand:()=>this.sessions.get(e)?.idleCommands?.idleInputCommand,isPollingCommand:o=>q(o),preDispatchHook:()=>null,dispatchPollingPrompt:(o,s)=>this.submitAutoPollPrompt(e,s?o:Nt,{keepWaitingStatus:!0}),dispatchRegularIdleCommand:o=>this.submitAutoPollPrompt(e,o)}),t.idlePollLoop}submitAutoPollPrompt(t,e,o){const s=this.sessions.get(t);if(!s||this.isTerminalStatus(s.adapterSession.status))return;const a=(s.autoPollToken??0)+1;s.autoPollToken=a,s.autoPollActive=!0,s.autoPollObservedPollingTool=!1,s.autoPollObservedAssistantText=!1,s.autoPollObservedAnyTool=!1,s.stopAutoPollAfterCurrentTurn=!1,s.idleListeningIntentionallyStopped=!1,s.autoPollQueuedAt=Date.now(),s.autoPollLastActivityAt=Date.now(),s.idleToolActiveAt=void 0,s.lastSubmittedPrompt=e,s.retryEpoch+=1,s.turnModelRequestSucceeded=!1,o?.keepWaitingStatus||(s.adapterSession.status="thinking",this.emit("status-change",t,"thinking")),this.startSubmitTimeoutDetection(t,s,"submitAutoPollPrompt"),s.runtime.submit(e).catch(i=>{this.emitRuntimeErrorEvent(t,i),this.scheduleRequestRetry(t,"submitAutoPollPrompt")}).finally(()=>{const i=this.sessions.get(t);if(i){if(i.autoPollToken!==a){r(`[ACode] submitAutoPollPrompt.finally: token mismatch (my=${a}, current=${i.autoPollToken}), skipping cleanup \u2014 newer turn has taken over`);return}if(this.cancelSubmitTimeoutDetection(i),i.autoPollActive=!1,i.failedTurnRecoveryScheduled||i.autoPollTimer){i.failedTurnRecoveryScheduled=!1;return}if(i.stopAutoPollAfterCurrentTurn){i.stopAutoPollAfterCurrentTurn=!1,i.autoPollObservedPollingTool=!1,i.autoPollObservedAssistantText=!1,i.autoPollObservedAnyTool=!1;return}if(i.adapterSession.status==="error"){this.recoverTurnFailure(t,i);return}if(i.adapterSession.status==="thinking"||i.adapterSession.status==="tool_using"){this.recoverResolvedTurnWithoutTerminalEvent(t);return}i.adapterSession.status==="waiting_input"&&this.armIdleLoopOrAutoPoll(t)}})}scheduleAutoPoll(t,e){const o=this.sessions.get(t);if(!o||o.autoPollActive||o.autoPollTimer||this.isTerminalStatus(o.adapterSession.status))return;const s=e??o.autoPollDelayMs??vt;e===void 0&&(o.autoPollDelayMs=Math.min(s*2,Ut)),o.autoPollTimer=setTimeout(()=>{const a=this.sessions.get(t);!a||a.autoPollActive||this.isTerminalStatus(a.adapterSession.status)||(a.autoPollTimer=void 0,this.submitAutoPollPrompt(t,Dt,{keepWaitingStatus:!0}))},s)}cancelScheduledAutoPoll(t){t.autoPollDelayMs=void 0,t.autoPollTimer&&(clearTimeout(t.autoPollTimer),t.autoPollTimer=void 0)}scheduleRequestRetry(t,e){const o=this.sessions.get(t);if(!o||this.isTerminalStatus(o.adapterSession.status))return;if(o.retryCircuitBroken){r(`[ACode] scheduleRequestRetry(${e}): retry terminated by non-retryable error, suppress further auto-retry`);return}if(o.retryActive||o.retryTimer)return;if(!o.lastSubmittedPrompt){o.adapterSession.status="error",this.emit("status-change",t,"error");return}if(o.turnModelRequestSucceeded&&o.turnModelRequestSucceededEpoch===o.retryEpoch&&(o.turnModelRequestSucceeded=!1,o.retryAttempt=0),o.lastErrorText&&qt(o.lastErrorText)){r(`[ACode] scheduleRequestRetry(${e}): non-retryable provider error, giving up retry: ${o.lastErrorText.slice(0,200)}`),this.cancelRequestRetry(o),o.retryAttempt=0,o.retryCircuitBroken=!0,o.adapterSession.status="error",this.emit("status-change",t,"error",{actionType:"retry_aborted",actionLabel:"\u8BF7\u6C42\u65E0\u6548",actionDetail:"Provider \u8FD4\u56DE 4xx \u8BF7\u6C42\u9519\u8BEF\uFF08\u539F\u6837\u91CD\u8BD5\u5FC5\u7136\u5931\u8D25\uFF09\uFF0C\u5DF2\u505C\u6B62\u81EA\u52A8\u91CD\u8BD5\uFF0C\u8BF7\u68C0\u67E5\u6E20\u9053\u914D\u7F6E\u6216\u91CD\u542F\u4F1A\u8BDD\u3002",actionError:Z(o.lastErrorText)});return}o.retryAttempt+=1,o.retryActive=!0,this.cancelScheduledAutoPoll(o),o.idlePollLoop?.stop();const s=V[Math.min(o.retryAttempt-1,V.length-1)];o.adapterSession.status="error",this.emit("status-change",t,"error",{actionType:"retry",actionLabel:"\u91CD\u8BD5\u4E2D",actionDetail:`\u7B2C${o.retryAttempt}\u6B21 \xB7 ${Math.round(s/1e3)}s\u540E`,actionError:Z(o.lastErrorText)}),r(`[ACode] scheduleRequestRetry(${e}): attempt=${o.retryAttempt} delay=${s}ms`),o.retryTimer=setTimeout(()=>{o.retryTimer=void 0,this.retryFailedRequest(t,e)},s)}retryFailedRequest(t,e){const o=this.sessions.get(t);if(!o)return;if(o.retryTimer=void 0,this.isTerminalStatus(o.adapterSession.status)||!o.lastSubmittedPrompt){o.retryActive=!1;return}o.retryActive=!1;const s=o.lastSubmittedPrompt;r(`[ACode] retryFailedRequest(${e}): attempt=${o.retryAttempt} re-submitting...`),o.retryEpoch+=1,o.turnModelRequestSucceeded=!1,o.autoPollObservedAssistantText=!1,o.autoPollObservedAnyTool=!1,o.autoPollObservedPollingTool=!1,o.adapterSession.status="thinking",this.emit("status-change",t,"thinking",{usage:o.adapterSession.totalUsage}),this.startSubmitTimeoutDetection(t,o,"retryFailedRequest"),o.runtime.submit(s,{resume:!0}).then(()=>{const a=this.sessions.get(t);!a||a.retryTimer||(this.cancelSubmitTimeoutDetection(a),a.retryAttempt=0,a.retryActive=!1,a.retryCircuitBroken=!1,this.recoverResolvedTurnWithoutTerminalEvent(t))}).catch(a=>{const i=this.sessions.get(t);i&&(this.cancelSubmitTimeoutDetection(i),i.lastErrorText=a instanceof Error?a.message:String(a),this.emitRuntimeErrorEvent(t,a),this.scheduleRequestRetry(t,`retry#${i.retryAttempt+1}`))})}cancelRequestRetry(t){t.retryTimer&&(clearTimeout(t.retryTimer),t.retryTimer=void 0),t.retryActive=!1}isTerminalStatus(t){return t==="completed"||t==="terminated"}emitRuntimeErrorEvent(t,e){const o=new Date().toISOString();this.emit("event",{type:"error",sessionId:t,timestamp:o,data:{text:e instanceof Error?e.message:String(e)}})}estimateOutputTokensFromMessages(t){const e=t.filter(o=>o.role==="assistant").map(o=>o.content).join("");return Math.max(0,Math.round(e.length/4))}recoverTurnFailure(t,e){if(this.isTerminalStatus(e.adapterSession.status))return;if(e.idleToolActiveAt=void 0,e.pendingToolAuthRequests?.size&&e.pendingToolAuthRequests.clear(),e.adapterSession.status==="tool_using"&&e.pendingToolEventData){const s=e.pendingToolEventData;r(`[ACode] recoverTurnFailure: \u8865\u53D1 tool_use_end (tool: ${s.toolName??"unknown"}) \u5173\u95ED\u65F6\u95F4\u7EBF\u6761\u76EE\uFF0C\u907F\u514D\u6C38\u4E45\u5361\u5728\u5DE5\u5177\u6267\u884C\u72B6\u6001`),this.emit("event",{type:"tool_use_end",sessionId:t,timestamp:new Date().toISOString(),data:{...s,toolResult:"[aborted] \u5DE5\u5177\u6267\u884C\u88AB\u6570\u636E\u6D41\u770B\u95E8\u72D7\u4E2D\u65AD"}}),e.pendingToolEventData=void 0}const o=this.estimateOutputTokensFromMessages(e.adapterSession.messages);if(o>0){const s=e.adapterSession.totalUsage.outputTokens;e.adapterSession.totalUsage.outputTokens=o,r(`[ACode] recoverTurnFailure: \u4F30\u7B97\u8986\u76D6 output tokens ${s} -> ${o} (totalUsage now: input=${e.adapterSession.totalUsage.inputTokens}, output=${e.adapterSession.totalUsage.outputTokens})`)}this.cancelScheduledAutoPoll(e),this.scheduleRequestRetry(t,"recoverTurnFailure")}recoverResolvedTurnWithoutTerminalEvent(t){r(`[ACode] \u25B6\uFE0F recoverResolvedTurnWithoutTerminalEvent called for session ${t}`);const e=this.sessions.get(t);if(!e||this.isTerminalStatus(e.adapterSession.status)){r(`[ACode] Skipping recovery: entry=${!!e}, isTerminal=${e?this.isTerminalStatus(e.adapterSession.status):"N/A"}`);return}if(r(`[ACode] Current status: ${e.adapterSession.status}`),e.adapterSession.status!=="thinking"&&e.adapterSession.status!=="tool_using"){r(`[ACode] Skipping recovery: status is ${e.adapterSession.status} (not thinking/tool_using)`);return}console.warn(`[ACode] \u26A0\uFE0F Detected stuck state: ${e.adapterSession.status} after submit resolved! Recovering to waiting_input. If runtime.submit() is still pending (e.g., built-in tool execution not interruptible by abort()), the submitQueue is deadlocked and subsequent auto-poll/user submits will never execute.`),r("[ACode] Recovering to waiting_input..."),e.adapterSession.status="waiting_input";const o=e.idleCommands?.idleInputCommand,a=!!(o&&q(o))?{actionType:"idle",actionLabel:"\u76D1\u542C\u6D88\u606F",actionDetail:"aws-mcp/poll_message"}:void 0;if(this.emit("status-change",t,"waiting_input",a),r(`[ACode] \u2705 Recovery complete, status now: ${e.adapterSession.status}`),r("[ACode] \u25B6\uFE0F Arming idle loop or auto-poll..."),!e.autoPollActive&&e.autoPollObservedAnyTool&&!e.autoPollObservedPollingTool){r(`[ACode] User-message turn called work tools; deferring idle rearm in recoverResolvedTurnWithoutTerminalEvent (session: ${t})`),this.scheduleDeferredIdleRearm(t);return}this.armIdleLoopOrAutoPoll(t),r("[ACode] \u2705 Idle loop armed, recovery process complete")}startSubmitTimeoutDetection(t,e,o){this.cancelSubmitTimeoutDetection(e),e.watchdogSubmitStartTime=Date.now(),e.watchdogLastDataFlowTime=Date.now(),k("turn_watchdog_arm",{sessionId:t,source:o,status:e.adapterSession.status,autoPollActive:!!e.autoPollActive,idleToolActiveAt:e.idleToolActiveAt??null}),e.watchdogTimer=setInterval(()=>{const s=this.sessions.get(t);if(!s){this.cancelSubmitTimeoutDetection(e);return}const a=s.adapterSession.status,i=Date.now();if(a==="waiting_input"){if(s.autoPollActive&&s.autoPollLastActivityAt&&!this.hasActiveBlockingToolCall(s)&&i-s.autoPollLastActivityAt>=Mt){console.warn(`[ACode] CRITICAL: stuck auto-poll detected after ${Math.round((i-s.autoPollLastActivityAt)/1e3)}s (source: ${o}, session: ${t}): submit queued but no runtime events and no active poll_message tool. Forcing recovery (runtime force-settle will unblock submitQueue).`),this.executeWatchdogRecovery(t,s,o,"stuck_autopoll",i-s.autoPollLastActivityAt);return}s.watchdogSubmitStartTime=i,s.watchdogLastDataFlowTime=i;return}if(a==="tool_using"){const u=i-(s.watchdogLastDataFlowTime||i);if(u>=Rt){const f=String(s.pendingToolEventData?.rawToolName??"");if((s.pendingToolAuthRequests?.size??0)>0){const d=s.pendingToolAuthRequests?.size??0;console.warn(`[ACode] tool_using elapsed ${Math.round(u/1e3)}s but ${d} tool permission request(s) awaiting user decision (session: ${t}), skipping recovery`),s.watchdogSubmitStartTime=i,s.watchdogLastDataFlowTime=i;return}if(f.endsWith("await_complete")){console.warn(`[ACode] tool_using elapsed ${Math.round(u/1e3)}s but await_complete is running (session: ${t}, tool: ${f}), skipping recovery (sub-agents have their own watchdogs, bg commands have timeout limits)`),s.watchdogSubmitStartTime=i,s.watchdogLastDataFlowTime=i;return}if(console.warn(`[ACode] CRITICAL: tool_using slow timeout triggered after ${Math.round(u/1e3)}s (source: ${o}, session: ${t}). Tool execution likely hung. Forcing recovery via recoverTurnFailure.`),s.runtime.detachCurrentToolExecution?.()){console.warn(`[ACode] tool_using slow (${Math.round(u/1e3)}s): detached tool ${f} to background (session: ${t}); waiting for the real tool_result to continue the turn`),s.watchdogSubmitStartTime=i,s.watchdogLastDataFlowTime=i;return}this.executeWatchdogRecovery(t,s,o,"tool_using_slow",u);return}s.watchdogSubmitStartTime=i;return}if(a!=="thinking")return;const n=i-(s.watchdogSubmitStartTime||i),c=i-(s.watchdogLastDataFlowTime||i);if(Q>0&&c>=Q){console.warn(`[ACode] CRITICAL: Data flow watchdog triggered after ${Math.round(c/1e3)}s (source: ${o}, session: ${t}, status: ${a}). No stream data received. Forcing recovery via recoverTurnFailure.`),this.executeWatchdogRecovery(t,s,o,"data_flow",c);return}if(tt>0&&n>=tt){console.warn(`[ACode] CRITICAL: submit timeout detected after ${Math.round(n/1e3)}s (source: ${o}, session: ${t}, status: ${a}). Forcing recovery to prevent permanent state stuck.`),this.executeWatchdogRecovery(t,s,o,"submit_timeout",n);return}},Ot)}executeWatchdogRecovery(t,e,o,s,a){k("turn_watchdog_trigger",{sessionId:t,source:o,reason:s,elapsedMs:a,status:e.adapterSession.status,autoPollActive:!!e.autoPollActive,idleToolActiveAt:e.idleToolActiveAt??null,pendingTool:e.pendingToolEventData?.rawToolName??null}),r(`[ACode] Watchdog (${s}): calling runtime.abort() after ${Math.round(a/1e3)}s...`);try{e.runtime.abort(),r(`[ACode] Watchdog (${s}): runtime.abort() called`)}catch(i){console.warn(`[ACode] \u26A0\uFE0F Watchdog (${s}): runtime.abort() threw: ${i instanceof Error?i.message:String(i)}`)}this.cancelSubmitTimeoutDetection(e),this.recoverTurnFailure(t,e),console.warn(`[ACode] \u26A0\uFE0F Watchdog (${s}) recovery complete. If abort() could not cancel the underlying operation, submitQueue may still be deadlocked.`)}cancelSubmitTimeoutDetection(t){t.watchdogTimer&&(clearInterval(t.watchdogTimer),t.watchdogTimer=void 0,k("turn_watchdog_cancel",{sessionId:t.adapterSession.sessionId,status:t.adapterSession.status,autoPollActive:!!t.autoPollActive,idleToolActiveAt:t.idleToolActiveAt??null})),t.watchdogSubmitStartTime=void 0,t.watchdogLastDataFlowTime=void 0}resetDataFlowWatchdog(t,e){e.watchdogLastDataFlowTime=Date.now(),e.watchdogSubmitStartTime=Date.now()}startDataFlowWatchdog(t,e){e.watchdogLastDataFlowTime=Date.now()}cancelDataFlowWatchdog(t){t.watchdogLastDataFlowTime=Date.now()}startLivenessWatchdog(t,e){this.stopLivenessWatchdog(e),e.lastAcodeEventAt=Date.now(),!(B<=0)&&(e.livenessTimer=setInterval(()=>{const o=this.sessions.get(t);if(!o){this.stopLivenessWatchdog(e);return}this.checkSessionLiveness(t,o)},Y),k("liveness_watchdog_arm",{sessionId:t,stallTimeoutMs:B,pollIntervalMs:Y}))}stopLivenessWatchdog(t){t.livenessTimer&&(clearInterval(t.livenessTimer),t.livenessTimer=void 0)}checkSessionLiveness(t,e){if(this.isTerminalStatus(e.adapterSession.status)){this.stopLivenessWatchdog(e);return}if(e.adapterSession.status!=="waiting_input"||e.autoPollActive||e.idleListeningIntentionallyStopped||e.pendingQuestionToolCallId||(e.pendingToolAuthRequests?.size??0)>0||this.hasActiveBlockingToolCall(e))return;e.idleToolActiveAt!==void 0&&(r(`[ACode] liveness: runtime \u672A\u62A5\u544A\u963B\u585E\u578B\u5DE5\u5177\u5728\u98DE\uFF0C\u6E05\u9664\u6B8B\u7559 idleToolActiveAt \u6807\u8BB0 (session: ${t})`),e.idleToolActiveAt=void 0);const o=e.lastAcodeEventAt??Date.now(),s=Date.now()-o;if(s<B)return;console.warn(`[ACode] CRITICAL: session liveness stall detected \u2014 no runtime event for ${Math.round(s/1e3)}s (session: ${t}, status: waiting_input). Forcing recovery (abort + re-arm listening loop).`),k("liveness_stall_detected",{sessionId:t,stalledForMs:s,status:e.adapterSession.status,idleToolActiveAt:e.idleToolActiveAt??null}),this.recoverIdleStall(t,e,s);const a=this.sessions.get(t);a&&(a.lastAcodeEventAt=Date.now())}recoverIdleStall(t,e,o){try{e.runtime.abort()}catch(s){console.warn(`[ACode] liveness recovery: runtime.abort() threw: ${s instanceof Error?s.message:String(s)}`)}this.cancelScheduledAutoPoll(e),e.autoPollActive=!1,e.idleToolActiveAt=void 0,this.isTerminalStatus(e.adapterSession.status)||(e.adapterSession.status="waiting_input",this.armIdleLoopOrAutoPoll(t)),k("liveness_recovery",{sessionId:t,stalledForMs:o,rearmedStatus:e.adapterSession.status}),console.warn(`[ACode] liveness recovery complete: session ${t} re-armed listening loop after ${Math.round(o/1e3)}s stall`)}hasActiveBlockingToolCall(t){const e=t.runtime.hasActiveBlockingToolCall;if(typeof e=="function")try{return e.call(t.runtime)===!0}catch(o){r(`[ACode] hasActiveBlockingToolCall probe threw, falling back to idle marker: ${o instanceof Error?o.message:String(o)}`)}return t.idleToolActiveAt!==void 0}formatAiRequestActionDetail(t){const e=`
1
+ import{EventEmitter as nt}from"node:events";import rt from"node:fs/promises";import H from"node:path";import{pathToFileURL as lt}from"node:url";import{isMcpGroupKey as ut}from"@agentswork/acode";import{v4 as x}from"uuid";import{getBridgeInstancePluginsDir as dt,getBridgeInstanceSkillsDir as ct,getBridgeTemplateConfigFile as O,getBridgeTemplateSkillsDir as pt}from"../config.js";import{getReleasedAcodeEntryPath as mt}from"../services/acode-package.js";import{syncAgentSkillFarm as K}from"../services/agent-capability-sync.js";import{agentPtyManager as ft}from"../services/agent-pty-manager.js";import{getBrowserTools as R,closeBrowserSession as gt,registerListenerWakeHook as ht,unregisterListenerWakeHook as j}from"../services/browser-session-manager.js";import{getDesktopTools as v,getDesktopToolsIfReady as Tt}from"../services/desktop-mcp-manager.js";import{redactForLog as G}from"../services/instance-ai-config-service.js";import{BROWSER_FEATURE_KEY as L,DESKTOP_FEATURE_KEY as P,getAgentToolPermissions as At,getFeatureState as U,isFeatureEnabled as yt,resolveAgentToolPermissions as St,resolveGroupFeatureKey as bt}from"../services/instance-features.js";import{pluginManager as M}from"../services/plugin-manager.js";import{dumpInvalidProviderRequest as _t}from"../services/request-invalid-dump.js";import{buildRuntimeResourcesSnapshot as Ct}from"../services/runtime-resources-snapshot.js";import{subAgentManager as kt}from"../services/sub-agent-manager-instance.js";import{recordAgentFileChange as wt}from"../services/workspaceTaskChangeWatcher.js";import{getInstanceAiConfigDebugLogger as F}from"../utils/instance-ai-config-debug-logger.js";import{recordLifecycleEvent as k}from"../utils/lifecycle-log.js";import{isMessagePollingIdleCommand as q,isPollMessageToolDescriptor as Pt}from"./acode-tool-names.js";import{IdlePollLoop as $t}from"./idle-poll-loop.js";import{resolveAcodeProviderConfig as Et}from"./instance-ai-config-resolver.js";import{MESSAGE_POLLING_IDLE_PROMPT as z}from"./prompts.js";import{getCanonicalMcpDetail as J,getToolActionInfo as xt}from"./types.js";const Lt=process.env.ACODE_COMPACTION_DEBUG==="1";function r(...u){Lt&&console.log(...u)}const It=process.env.ACODE_TOKEN_DEBUG==="1";function w(...u){It&&console.log("[TokenDebug][Adapter]",...u)}const Dt=z,vt=5e3;function $(u,t){const e=process.env[u];if(e===void 0||e.trim()==="")return t;const o=Number(e.trim());return Number.isFinite(o)&&o>=0?Math.floor(o):t}const Q=$("ACODE_DATA_FLOW_WATCHDOG_MS",12e4),Mt=5*6e4,Ot=$("ACODE_STUCK_AUTOPOLL_TIMEOUT_MS",5*6e4),Y=$("ACODE_LIVENESS_POLL_INTERVAL_MS",15e3),B=$("ACODE_LIVENESS_STALL_TIMEOUT_MS",10*6e4),Rt=250,Ut=1e3,Ft=$("ACODE_DEFERRED_IDLE_REARM_MS",3e3),V=[2e3,3e3,1e4,4e4],X=4e3;function Z(u){const t=String(u||"").trim();if(t)return t.length>X?`${t.slice(0,X)}\u2026(truncated)`:t}function qt(u){const t=u.toLowerCase();return/tool[_ ]?call/.test(t)||t.includes("invalid_request")?!0:/(?:failed:\s*|http[\s/]*|status[\s:="']*|code[\s:="']*)(400|401|403|404|422)(?!\d)/.test(t)}const N={[L]:"browser_",[P]:"desktop_"};function Bt(u){if(!u||typeof u!="object")return;const t=u,e=typeof t.exposedName=="string"&&t.exposedName||typeof t.toolName=="string"&&t.toolName||typeof t.name=="string"&&t.name||"";if(!e)return;const o=typeof t.execute=="function"?t.execute:void 0;return{name:e,...typeof t.description=="string"?{description:t.description}:{},...t.inputSchema!==void 0?{inputSchema:t.inputSchema}:{},definition:t,...o?{execute:o}:{}}}const tt=$("ACODE_SUBMIT_TIMEOUT_MS",12e4),et=3e3,Nt=z;function Wt(){return H.resolve(mt())}function Ht(u){return lt(H.resolve(u)).href}const ot=128e3,E={"claude-4":{contextLimit:2e5,maxOutput:8192},"claude-sonnet-4":{contextLimit:2e5,maxOutput:8192},"claude-3-5-sonnet":{contextLimit:2e5,maxOutput:8192},"claude-3-opus":{contextLimit:2e5,maxOutput:8192},"claude-3-haiku":{contextLimit:2e5,maxOutput:8192},"claude-2":{contextLimit:1e5,maxOutput:4096},"gpt-4o":{contextLimit:128e3,maxOutput:16384},"gpt-4-turbo":{contextLimit:128e3,maxOutput:4096},"gpt-4":{contextLimit:8192,maxOutput:4096},"gpt-3.5-turbo":{contextLimit:16384,maxOutput:4096},o1:{contextLimit:2e5,maxOutput:1e5},"o3-mini":{contextLimit:2e5,maxOutput:1e5},"gemini-2.0-flash":{contextLimit:1048576,maxOutput:8192},"gemini-2.5-pro":{contextLimit:1048576,maxOutput:8192},"gemini-1.5-pro":{contextLimit:2097152,maxOutput:8192},"gemini-1.5-flash":{contextLimit:1048576,maxOutput:8192},deepseek:{contextLimit:64e3,maxOutput:8192},"deepseek-chat":{contextLimit:64e3,maxOutput:8192},"deepseek-reasoner":{contextLimit:64e3,maxOutput:8192},"qwen-max":{contextLimit:32e3,maxOutput:8192},"qwen-plus":{contextLimit:128e3,maxOutput:8192},"qwen-turbo":{contextLimit:1e6,maxOutput:8192},"glm-4":{contextLimit:128e3,maxOutput:4096},"yi-":{contextLimit:2e5,maxOutput:4096},"llama-3":{contextLimit:8192,maxOutput:4096},"llama-2":{contextLimit:4096,maxOutput:4096},mistral:{contextLimit:32e3,maxOutput:4096},mixtral:{contextLimit:32e3,maxOutput:4096},codestral:{contextLimit:256e3,maxOutput:8192},grok:{contextLimit:131072,maxOutput:4096},"nova-":{contextLimit:2e5,maxOutput:8192}};function Kt(u){if(!u)return ot;const t=u.toLowerCase().trim(),e=E[t];if(e)return e.contextLimit;const o=Object.keys(E).filter(i=>t.startsWith(i)).sort((i,a)=>a.length-i.length),s=o[0]!==void 0?E[o[0]]:void 0;return s?s.contextLimit:ot}const st=4096;function jt(u){if(!u)return st;const t=u.toLowerCase().trim(),e=E[t];if(e)return e.maxOutput;const o=Object.keys(E).filter(i=>t.startsWith(i)).sort((i,a)=>a.length-i.length),s=o[0]!==void 0?E[o[0]]:void 0;return s?s.maxOutput:st}function it(u){if(!u||typeof u!="object")return;const t=u,e=y(t.inputTokens,t.input_tokens,t.promptTokens,t.prompt_tokens),o=y(t.outputTokens,t.output_tokens,t.completionTokens,t.completion_tokens);if(e===0&&o===0)return;let s=y(t.cacheHitTokens,t.promptCacheHitTokens,t.prompt_cache_hit_tokens),i=y(t.cacheMissTokens,t.promptCacheMissTokens,t.prompt_cache_miss_tokens),a=t.cacheHitTokens!==void 0||t.cacheMissTokens!==void 0||t.promptCacheHitTokens!==void 0||t.promptCacheMissTokens!==void 0||t.prompt_cache_hit_tokens!==void 0||t.prompt_cache_miss_tokens!==void 0;if(s===0&&i===0){const n=y(t.cache_read_input_tokens),d=y(t.cache_creation_input_tokens);if(n>0||d>0){const m=t.input_tokens!==void 0&&Number.isFinite(Number(t.input_tokens))&&Number(t.input_tokens)>=0?y(t.input_tokens):Math.max(0,e-n-d);s=n,i=d+m,a=!0}else s=y(t.cache_hit_tokens),i=y(t.cache_miss_tokens),a=a||t.cache_hit_tokens!==void 0||t.cache_miss_tokens!==void 0}if(s===0&&i===0){const n=y(t.prompt_tokens_details?.cached_tokens);n>0&&(s=n,i=e>n?e-n:0,a=!0)}return{inputTokens:e,outputTokens:o,...a?{cacheHitTokens:s,cacheMissTokens:i}:{},...a?{hasCache:!0}:{}}}function y(...u){for(const t of u){const e=Number(t);if(Number.isFinite(e)&&e>0)return e}return 0}function Gt(u){return u==="stderr"||u==="mixed"?u:"stdout"}function I(u){const t=Number(u);return Number.isFinite(t)?t:0}function W(u){if(u==null)return;const t=Number(u);return Number.isFinite(t)?t:void 0}function zt(u){if(!u||typeof u!="object"||Array.isArray(u))return;const t={};for(const[e,o]of Object.entries(u))typeof o=="string"&&(t[e]=o);return Object.keys(t).length>0?t:void 0}function Jt(u){return u.failed===!0}function at(u,t,e){if(!u)return e?`${t}/${e}`:t;const o=`${t}__`;return u.startsWith(o)?J(`${t}__${u.slice(o.length)}`):J(u.replace("/","__"))}function Qt(u){return u==="read_file"||u==="edit_file"||u==="write_file"||u==="bash"}function Yt(u){const t=Vt(u);return t?[t.directMessages,t.groupMessages,t.messages].some(e=>Array.isArray(e)&&e.length>0):typeof u=="string"&&u.trim().length>0}function Vt(u){if(u&&typeof u=="object"&&!Array.isArray(u))return u;if(!(typeof u!="string"||!u.trim()))try{const t=JSON.parse(u);return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}catch{return}}class we extends nt{constructor(){super(),this.providerId="acode",this.displayName="ACode",this.sessions=new Map,this.expandedBuiltInCapabilities=new Map,this.builtInCapabilityToolCache=new Map,this.listenerWakeHooks=new Map,M.setOnPluginsChanged(t=>{this.syncPluginCommands(t)})}async syncPluginCommands(t){try{const e=await M.getPluginCommands(t);for(const o of this.sessions.values())o.config.agentId===t&&(o.runtime.addPluginCommands?.(e),o.runtime.syncPluginGroups?.())}catch(e){r(`[acode-adapter] syncPluginCommands failed for agent ${t}:`,e.message)}}async startSession(t,e){const o=e.mcpConfigPath||O(),{resolved:s,configContextLimit:i,supportsImage:a}=await this.resolveAcodeProvider(e,o),n=s.model,d=i??Kt(n),l=jt(n),m={sessionId:t,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0,contextLimit:d,maxOutput:l,cacheHitTokens:0,cacheMissTokens:0}};this.sessions.set(t,{adapterSession:m,config:e,runtime:await this.createRuntime(t,n,e,s,a),autoPollActive:!1,retryAttempt:0,retryActive:!1,retryEpoch:0}),this.emit("status-change",t,"starting");const c=this.sessions.get(t);if(!c)throw new Error("ACode session was not initialized");this.startLivenessWatchdog(t,c);const p=()=>{const f=this.sessions.get(t);f&&(f.autoPollDelayMs=void 0,this.getIdlePollLoop(f).start())};this.listenerWakeHooks.set(t,p),ht(e.agentId,p);try{if(await c.runtime.start(),console.log(`[HIBERNATE-REPLAY] startSession: agentId=${e.agentId??"?"} resumeTranscript=${Array.isArray(c.config.resumeTranscript)?`${c.config.resumeTranscript.length}\u6761`:"\u65E0"} importTranscript\u652F\u6301=${typeof c.runtime.importTranscript=="function"}`),m.status="waiting_input",this.emit("status-change",t,"waiting_input",{usage:c.adapterSession.totalUsage}),c.config.resumeTranscript&&c.runtime.importTranscript)try{const f=await c.runtime.importTranscript(c.config.resumeTranscript);console.log(`[HIBERNATE-REPLAY] importTranscript \u5B8C\u6210: agentId=${e.agentId??"?"} \u91CD\u653E=${f}\u6761 conversation=${c.runtime.exportConversation?.().length??"?"}\u6761`),f>0&&c.adapterSession.messages.push({id:x(),sessionId:t,role:"assistant",content:`[\u4F11\u7720\u6062\u590D] \u5DF2\u91CD\u653E\u4F11\u7720\u524D\u7684 ${f} \u6761\u5BF9\u8BDD\u8BB0\u5F55\uFF0C\u4E0A\u4E0B\u6587\u5DF2\u63A5\u7EED\u3002`,timestamp:new Date().toISOString()})}catch(f){console.error(`[HIBERNATE-REPLAY] importTranscript \u5931\u8D25\uFF08\u964D\u7EA7\u4E3A\u6458\u8981\u901A\u9053\uFF09: agentId=${e.agentId??"?"}`,f instanceof Error?f.stack:f)}e.initialPrompt?.trim()?this.startInitialPromptTurn(t,e.initialPrompt):this.armIdleLoopOrAutoPoll(t)}catch(f){m.status="error",this.emitRuntimeErrorEvent(t,f),this.emit("status-change",t,"error");const T=this.sessions.get(t);throw T?.capabilitiesFallbackTimer&&clearTimeout(T.capabilitiesFallbackTimer),T&&this.stopLivenessWatchdog(T),this.sessions.delete(t),j(e.agentId,this.listenerWakeHooks.get(t)),this.listenerWakeHooks.delete(t),f}}async sendMessage(t,e){const o=Date.now();r("[ACode] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),r("[ACode] \u25B6\uFE0F sendMessage STARTED"),r(`[ACode] Session: ${t}`),r(`[ACode] Message: ${e.slice(0,100)}${e.length>100?"...":""}`),r("[ACode] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");const s=this.requireSession(t),i=s.adapterSession.status;r(`[ACode] Previous status: ${i}`),this.cancelScheduledAutoPoll(s),s.failedTurnRecoveryScheduled=!1,s.idlePollLoop?.stop(),s.idleListeningIntentionallyStopped=!1,this.cancelRequestRetry(s),s.retryAttempt=0,s.retryCircuitBroken=!1,s.retryEpoch+=1,s.turnModelRequestSucceeded=!1;const a={id:x(),sessionId:t,role:"user",content:e,timestamp:new Date().toISOString()};s.adapterSession.messages.push(a),this.emit("conversation-message",t,a),r(`[ACode] Changing status: ${i} \u2192 thinking`),s.adapterSession.status="thinking",this.emit("status-change",t,"thinking"),s.autoPollObservedAssistantText=!1,s.autoPollObservedAnyTool=!1,s.autoPollObservedPollingTool=!1,s.lastSubmittedPrompt=e,s.retryEpoch+=1,s.turnModelRequestSucceeded=!1,this.startSubmitTimeoutDetection(t,s,"sendMessage");try{r("[ACode] \u25B6\uFE0F Calling runtime.submit()...");const n=Date.now();await s.runtime.submit(e);const d=Date.now()-n;this.cancelSubmitTimeoutDetection(s),r(`[ACode] \u2705 runtime.submit() completed in ${d}ms`),r(`[ACode] Current status after submit: ${s.adapterSession.status}`),r("[ACode] \u25B6\uFE0F Calling recoverResolvedTurnWithoutTerminalEvent()..."),this.recoverResolvedTurnWithoutTerminalEvent(t),r(`[ACode] Status after recovery: ${s.adapterSession.status}`);const l=Date.now()-o;r("[ACode] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550"),r(`[ACode] \u2705 sendMessage COMPLETED in ${l}ms`),r("[ACode] \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550")}catch(n){const d=Date.now()-o;console.error(`[ACode] \u274C sendMessage FAILED after ${d}ms:`,n instanceof Error?n.message:String(n)),this.cancelSubmitTimeoutDetection(s),r("[ACode] \u25B6\uFE0F sendMessage failed, scheduling request retry..."),this.emitRuntimeErrorEvent(t,n),this.scheduleRequestRetry(t,"sendMessage"),r(`[ACode] Status after failure: ${s.adapterSession.status}`)}}async sendConfirmation(t,e){}submitToolPermissionDecision(t,e,o){const s=this.sessions.get(t);if(!s)return!1;s.pendingToolAuthRequests?.delete(e);const i=s.runtime.submitToolPermissionDecision?.(e,o)??!1;return i&&this.startSubmitTimeoutDetection(t,s,"submitToolPermissionDecision"),i}getPendingToolAuthRequests(t){const e=this.sessions.get(t);return e?.pendingToolAuthRequests?Array.from(e.pendingToolAuthRequests.entries()).map(([o,s])=>({requestId:o,capability:s.capability,detail:s.detail,requestedAt:s.requestedAt})):[]}async sendQuestionAnswer(t,e){const o=this.sessions.get(t);if(!o)return;const s=o.pendingQuestionToolCallId;if(!s){r(`[AcodeSdkAdapter] sendQuestionAnswer: no pending question for session ${t}`);return}o.pendingQuestionToolCallId=void 0,o.pendingQuestions=void 0,o.runtime.submitQuestionAnswer&&o.runtime.submitQuestionAnswer(s,e),this.startSubmitTimeoutDetection(t,o,"sendQuestionAnswer")}async abortCurrentTurn(t){await this.requireSession(t).runtime.abort()}async resetContext(t){const e=this.requireSession(t);if(this.cancelScheduledAutoPoll(e),e.failedTurnRecoveryScheduled=!1,e.autoPollActive=!1,e.autoPollObservedPollingTool=!1,e.autoPollObservedAssistantText=!1,e.autoPollObservedAnyTool=!1,e.stopAutoPollAfterCurrentTurn=!1,e.idleListeningIntentionallyStopped=!1,e.idlePollLoop?.stop(),!e.runtime.resetContext)throw new Error("ACode runtime does not support context reset");await e.runtime.resetContext(),e.adapterSession.messages=[];const o=e.adapterSession.totalUsage;if(e.adapterSession.totalUsage={inputTokens:0,outputTokens:0,contextLimit:o.contextLimit,maxOutput:o.maxOutput,inputLimit:o.inputLimit,compactionThreshold:o.compactionThreshold,cacheHitTokens:o.cacheHitTokens,cacheMissTokens:o.cacheMissTokens},e.adapterSession.status="waiting_input",this.emit("status-change",t,"waiting_input",{usage:e.adapterSession.totalUsage}),e.config.initialPrompt?.trim()){this.startInitialPromptTurn(t,e.config.initialPrompt);return}this.armIdleLoopOrAutoPoll(t)}compactContext(t,e){const o=this.requireSession(t);if(!o.runtime.compactContext)throw new Error("ACode runtime does not support manual context compaction");return o.runtime.compactContext(e)}getCompactionPreview(t){const e=this.requireSession(t);if(!e.runtime.getCompactionPreview)throw new Error("ACode runtime does not support compaction preview");return e.runtime.getCompactionPreview()}async terminateSession(t){const e=this.sessions.get(t);if(!e)return;this.cancelScheduledAutoPoll(e),e.failedTurnRecoveryScheduled=!1,e.idlePollLoop?.stop(),this.stopLivenessWatchdog(e),this.cancelRequestRetry(e),e.capabilitiesFallbackTimer&&(clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=void 0),await e.runtime.stop();const o=e.config.agentId;o&&(j(o,this.listenerWakeHooks.get(t)),gt(o)),this.listenerWakeHooks.delete(t),e.adapterSession.status="terminated",this.sessions.delete(t),o&&![...this.sessions.values()].some(s=>s.config.agentId===o)&&(this.expandedBuiltInCapabilities.delete(o),this.builtInCapabilityToolCache.delete(o)),this.emit("status-change",t,"terminated")}getConversation(t){return this.sessions.get(t)?.adapterSession.messages??[]}exportRawTranscript(t){const e=this.sessions.get(t);if(e?.runtime.exportConversation)try{const o=e.runtime.exportConversation();return Array.isArray(o)?o:void 0}catch{return}}async importRawTranscript(t,e){const o=this.sessions.get(t);return!o?.runtime.importTranscript||!Array.isArray(e)?0:o.runtime.importTranscript(e)}hasSession(t){return this.sessions.has(t)}getProviderSessionId(t){return this.sessions.has(t)?t:void 0}getSessionStatus(t){return this.sessions.get(t)?.adapterSession.status}getTotalUsage(t){const e=this.sessions.get(t)?.adapterSession.totalUsage;if(e)return{inputTokens:e.inputTokens,outputTokens:e.outputTokens}}notifyForceMessage(t){const e=this.sessions.get(t);return e?.runtime?.notifyForceMessage?(e.autoPollDelayMs=void 0,e.runtime.notifyForceMessage(),!0):!1}getCapabilities(t){return this.sessions.get(t)?.lastCombinedCapabilities}async resolveAgentAiInfo(t){try{const e=[...this.sessions.values()].find(a=>a.config.agentId===t);if(!e)return;const o=e.config.mcpConfigPath||O(),{resolved:s,supportsImage:i}=await this.resolveAcodeProvider(e.config,o);return s?.model?{model:s.model,supportsImage:i===!0,...s.baseURL?{baseURL:s.baseURL}:{},...s.apiKey?{apiKey:s.apiKey}:{}}:void 0}catch{return}}resolveAgentSkillsDir(t){if(t){try{const e=K(t);if(e)return e}catch(e){r(`[acode-adapter] skill farm sync failed for agent ${t}:`,e.message)}return ct(t)}return pt()}async applyAgentFeatures(t){if(!t)return;const e=this.shouldInjectCapabilityTools(t,P),o=this.shouldInjectCapabilityTools(t,L);for(const[i,a]of this.sessions){if(a.config.agentId!==t)continue;const n=a.runtime,d=e,l=o;try{if(d){const m=await v(t,await this.resolveAgentAiInfo(t)),c=n.addBuiltInTools?.(m)??0;c>0&&r(`[acode-adapter] session ${i}: ${c} desktop tools hot-added for agent ${t}`)}else{const m=n.removeBuiltInToolsByPrefix?.("desktop_")??0;m>0&&r(`[acode-adapter] session ${i}: ${m} desktop tools hot-removed for agent ${t}`)}}catch(m){r(`[acode-adapter] session ${i}: desktop feature hot-sync failed for agent ${t}:`,m.message)}if(l)try{const m=await R(t,a.config.scopeKey,typeof a.config.browserAllowPrivate=="boolean"?{allowPrivate:a.config.browserAllowPrivate}:void 0),c=n.addBuiltInTools?.(m)??0;c>0&&r(`[acode-adapter] session ${i}: ${c} browser tools hot-added for agent ${t}`)}catch(m){r(`[acode-adapter] session ${i}: browser feature hot-sync failed for agent ${t}:`,m.message)}else{const m=n.removeBuiltInToolsByPrefix?.("browser_")??0;m>0&&r(`[acode-adapter] session ${i}: ${m} browser tools hot-removed for agent ${t}`)}}this.syncMcpToolsForAgent(t);try{K(t)}catch(i){r(`[acode-adapter] skill farm hot-sync failed for agent ${t}:`,i.message)}try{await M.applyCapabilities(t)}catch(i){r(`[acode-adapter] plugin capability hot-sync failed for agent ${t}:`,i.message)}const s=St(t);for(const[i,a]of this.sessions)if(a.config.agentId===t)try{a.runtime.setToolPermissionPolicy?.(s)}catch(n){r(`[acode-adapter] session ${i}: tool permission policy hot-sync failed for agent ${t}:`,n.message)}}syncMcpToolsForAgent(t){if(t){for(const[e,o]of this.sessions)if(o.config.agentId===t)try{o.runtime.requestMcpToolsRefresh?.()}catch(s){r(`[acode-adapter] session ${e}: mcp tools refresh failed for agent ${t}:`,s.message)}}}async debugMountMcpServer(t,e,o){if(!t)return{ok:!1,mounted:!1,sessions:0,tools:0,error:"agentId is required"};let s=0,i=0,a,n;for(const[d,l]of this.sessions)if(l.config.agentId===t&&typeof l.runtime.addMcpServer=="function")try{const m=await l.runtime.addMcpServer(e,o);s+=1,m.ok?(i=m.tools,a=m.toolNames):n=m.error}catch(m){n=m.message,r(`[acode-adapter] session ${d}: debug mount mcp ${e} failed for agent ${t}:`,n)}return s===0?{ok:!1,mounted:!1,sessions:0,tools:0,error:`No active SDK session for agentId "${t}"\uFF08\u8C03\u8BD5\u6302\u8F7D\u4EC5\u5BF9\u8FD0\u884C\u4E2D\u7684\u4F1A\u8BDD\u751F\u6548\uFF09`}:{ok:!n,mounted:!0,sessions:s,tools:i,toolNames:a,error:n}}async debugUnmountMcpServer(t,e){if(!t)return{ok:!1,sessions:0};let o=0;for(const[,s]of this.sessions)if(s.config.agentId===t&&typeof s.runtime.removeMcpServer=="function")try{await s.runtime.removeMcpServer(e),o+=1}catch(i){r(`[acode-adapter] debug unmount mcp ${e} failed for agent ${t}:`,i.message)}return{ok:o>0,sessions:o}}getMcpServerStderr(t,e,o=100){if(!t)return[];for(const[,s]of this.sessions)if(s.config.agentId===t&&typeof s.runtime.getMcpServerStderr=="function")return s.runtime.getMcpServerStderr(e,o);return[]}shouldInjectCapabilityTools(t,e){return t?U(t,e)==="expanded":!0}resolveCapabilityToolPrefix(t){return N[String(t??"").trim()]}async loadCapabilityToolsForSession(t,e,o){const s=t===L?await R(e,o.config.scopeKey,typeof o.config.browserAllowPrivate=="boolean"?{allowPrivate:o.config.browserAllowPrivate}:void 0):await v(e,await this.resolveAgentAiInfo(e)),i=[];for(const a of s){const n=Bt(a);n&&i.push(n)}return i}async setBuiltInCapabilityTools(t,e,o){const s=String(t??"").trim(),i=this.resolveCapabilityToolPrefix(e);if(!s||!i)return{sessions:0,tools:0};const a=[...this.sessions.entries()].filter(([,l])=>l.config.agentId===s);if(a.length===0)return{sessions:0,tools:0};if(o==="collapse"){let l=0;for(const[m,c]of a){const p=c.runtime.removeBuiltInToolsByPrefix?.(i)??0;l+=p,p>0&&r(`[acode-adapter] session ${m}: ${p} ${e} tools removed on collapse (agent ${s})`)}return this.expandedBuiltInCapabilities.get(s)?.delete(e),this.builtInCapabilityToolCache.get(s)?.delete(e),r(`[acode-adapter] capability collapse: agent=${s} capability=${e} sessions=${a.length} removedTools=${l}`),{sessions:a.length,tools:l}}const n=new Map;for(const[l,m]of a){let c;try{c=await this.loadCapabilityToolsForSession(e,s,m)}catch(p){throw r(`[acode-adapter] session ${l}: capability ${e} tool load failed for agent ${s}:`,p.message),p}for(const p of c)n.has(p.name)||n.set(p.name,p)}const d=this.expandedBuiltInCapabilities.get(s)??new Set;return d.add(e),this.expandedBuiltInCapabilities.set(s,d),this.builtInCapabilityToolCache.set(s,n),r(`[acode-adapter] capability expand: agent=${s} capability=${e} sessions=${a.length} tools=${n.size} (manifests only, no session tool injection)`),{sessions:a.length,tools:n.size,manifests:[...n.values()].map(l=>({name:l.name,...l.description!==void 0?{description:l.description}:{},...l.inputSchema!==void 0?{inputSchema:l.inputSchema}:{}}))}}async callBuiltInCapabilityTool(t,e,o,s){const i=String(t??"").trim(),a=this.resolveCapabilityToolPrefix(e);if(!a)return{ok:!1,error:`\u672A\u77E5\u80FD\u529B\u300C${String(e)}\u300D\uFF1A\u4EC5\u652F\u6301 browser / desktop`};const n=String(o??"").trim();if(!n)return{ok:!1,error:"\u5DE5\u5177\u540D\u7F3A\u5931"};if(!n.startsWith(a))return{ok:!1,error:`\u5DE5\u5177\u300C${n}\u300D\u4E0D\u5C5E\u4E8E\u80FD\u529B\u300C${e}\u300D`};if(i&&U(i,e)==="disabled")return{ok:!1,error:`\u80FD\u529B\u300C${e}\u300D\u5DF2\u7981\u7528\uFF0C\u65E0\u6CD5\u8C03\u5EA6\u8BE5\u5DE5\u5177`};if(!(this.expandedBuiltInCapabilities.get(i)?.has(e)??!1))return{ok:!1,error:`\u80FD\u529B\u300C${e}\u300D\u5C1A\u672A\u5C55\u5F00\uFF0C\u8BF7\u5148\u8C03\u7528 expand_tools \u5C55\u5F00\u540E\u518D\u8C03\u5EA6\u8BE5\u5DE5\u5177`};const l=this.builtInCapabilityToolCache.get(i)?.get(n);return l?typeof l.execute!="function"?{ok:!1,error:`\u5DE5\u5177\u300C${n}\u300D\u4E0D\u53EF\u8C03\u5EA6\uFF08\u7F3A\u5C11 execute \u5B9E\u73B0\uFF09`}:{ok:!0,result:await l.execute.call(l.definition,s??{})}:{ok:!1,error:`\u5DE5\u5177\u300C${n}\u300D\u65E0\u7F13\u5B58\u5B9A\u4E49\uFF0C\u8BF7\u91CD\u65B0\u8C03\u7528 expand_tools \u5237\u65B0`}}getPendingQuestion(t){const e=this.sessions.get(t);if(e?.pendingQuestionToolCallId)return{toolCallId:e.pendingQuestionToolCallId,questions:e.pendingQuestions??[]}}cleanup(){for(const t of this.sessions.keys())this.terminateSession(t)}setIdleCommands(t,e){const o=this.sessions.get(t);if(o){if(o.idleCommands=e,this.cancelScheduledAutoPoll(o),e.idleInputCommand&&q(e.idleInputCommand)){this.getIdlePollLoop(o).start();return}o.adapterSession.status==="waiting_input"&&(e.idleInputCommand||e.nonInputCommand)&&this.getIdlePollLoop(o).start()}}setRuntimeConstructorForTest(t){this.runtimeConstructor=t}async loadAcodeProviderSection(t){try{const e=await rt.readFile(t,"utf-8"),o=JSON.parse(e),i=o.provider?.default,a=i?.options,n=y(o.contextLimit),d={},l={},m=i?.models;if(m&&typeof m=="object"){for(const[c,p]of Object.entries(m))if(p&&typeof p=="object"){const f=y(p.contextLimit);f>0&&(d[c.trim()]=f);const T=p.modalities?.input,g=Array.isArray(T)&&T.includes("image")||p.supportsImageInput===!0;l[c.trim()]=g===!0}}return{...i?.model?{model:i.model}:{},...a?.baseURL||a?.baseUrl?{baseURL:a?.baseURL||a?.baseUrl}:{},...a?.apiKey?{apiKey:a.apiKey}:{},...n>0?{contextLimit:n}:{},...Object.keys(d).length>0?{modelContextLimits:d}:{},...Object.keys(l).length>0?{modelImageSupport:l}:{}}}catch(e){const o=e instanceof Error?e.message:String(e);return F().log({level:"warn",category:"load",message:`loadAcodeProviderSection failed: ${t}: ${o}`,source:"bridge"}),{}}}async resolveAcodeProvider(t,e){const o=typeof t.model=="string"&&t.model.trim()?t.model.trim():void 0,s=F();s.log({level:"info",category:"resolve",message:"resolveAcodeProvider \u8F93\u5165",source:"bridge",details:{configModel:t.model??null,configInstanceAiConfig:t.instanceAiConfig?G(t.instanceAiConfig):null,configPath:e}});const i={...t.instanceAiConfig?.model?{model:t.instanceAiConfig.model}:{},...t.instanceAiConfig?.baseURL?{baseURL:t.instanceAiConfig.baseURL}:{},...t.instanceAiConfig?.apiKey?{apiKey:t.instanceAiConfig.apiKey}:{},...t.instanceAiConfig?.effort?{effort:t.instanceAiConfig.effort}:{},...o?{model:o}:{}},a=await this.loadAcodeProviderSection(e);let n=a.contextLimit;if(!n&&a.modelContextLimits){const l=o||t.instanceAiConfig?.model||a.model;l&&a.modelContextLimits[l]&&(n=a.modelContextLimits[l])}const d=Et(i,a,"acode-default");return s.log({level:"info",category:"resolve",message:"resolveAcodeProvider \u89E3\u6790\u7ED3\u679C",source:"bridge",details:{instanceConfig:G(i),globalConfigModel:a?.model??null,resolvedModel:d.model,resolvedBaseURL:d.baseURL??null,resolvedApiKey:d.apiKey?"[set]":null,configContextLimit:n,resolvedSource:d.source}}),{resolved:d,configPath:e,perSessionModel:o,configContextLimit:n,supportsImage:a.modelImageSupport?.[d.model]===!0}}async createRuntime(t,e,o,s,i){const a=await this.loadRuntimeConstructor(),n=o.mcpConfigPath||O();let d=[];try{d=await R(o.agentId,o.scopeKey,typeof o.browserAllowPrivate=="boolean"?{allowPrivate:o.browserAllowPrivate}:void 0)}catch(p){r(`[acode-adapter] browser tools injection skipped for agent ${o.agentId}:`,p.message)}let l=[];if(this.shouldInjectCapabilityTools(o.agentId??"",L)&&(l=d),o.agentId&&this.shouldInjectCapabilityTools(o.agentId,P))try{const p=s?.model?{model:s.model,supportsImage:i===!0,...s.baseURL?{baseURL:s.baseURL}:{},...s.apiKey?{apiKey:s.apiKey}:{}}:void 0,f=await v(o.agentId,p);f.length>0&&(l=[...l,...f])}catch(p){r(`[acode-adapter] desktop tools injection skipped for agent ${o.agentId}:`,p.message)}const m=new a({sessionId:t,agentId:o.agentId,workingDirectory:o.workingDirectory,configPath:n,skillsDir:this.resolveAgentSkillsDir(o.agentId),pluginsDir:o.agentId?dt(o.agentId):void 0,model:e,systemPrompt:typeof o.systemPrompt=="string"?o.systemPrompt:void 0,globalPrompt:typeof o.globalPrompt=="string"?o.globalPrompt:void 0,rolePrompt:typeof o.rolePrompt=="string"?o.rolePrompt:void 0,memory:typeof o.memory=="string"?o.memory:void 0,resumeContext:typeof o.resumeContext=="string"?o.resumeContext:void 0,env:o.envOverrides,subAgentManager:kt,terminalManager:ft,capabilityState:p=>ut(p)?"collapsed":U(o.agentId??"",bt(p)),capabilityToolRelay:o.agentId?{handlesGroup:p=>this.resolveCapabilityToolPrefix(p)!==void 0,handlesTool:p=>Object.values(N).some(f=>p.startsWith(f)),expand:async p=>(await this.setBuiltInCapabilityTools(o.agentId??"",p,"expand")).manifests??[],collapse:async p=>{await this.setBuiltInCapabilityTools(o.agentId??"",p,"collapse")},call:async(p,f)=>{const T=p.startsWith(N[P]??"desktop_")?P:L;return this.callBuiltInCapabilityTool(o.agentId??"",T,p,f)}}:void 0,pluginBridge:o.agentId?M.forAgent(o.agentId):void 0,runtimeResourcesProvider:o.agentId?()=>Ct(o.agentId):void 0,...o.subAgentModel?{subAgentModel:o.subAgentModel}:{},...o.subAgentEffort?{subAgentEffort:o.subAgentEffort}:{},...o.instanceAiConfig?.effort?{effort:o.instanceAiConfig.effort}:{},onFileChange:p=>wt({...p,agentId:o.agentId,workspacePath:o.workingDirectory}),extraBuiltInTools:l,...o.agentId?{toolPermissionPolicy:At(o.agentId)??void 0}:{},subAgentSuiteTools:d,subAgentSuiteToolProvider:this.buildSubAgentSuiteToolProvider(o.agentId)});return F().log({level:"info",category:"resolve",message:"ACode provider resolved",source:"bridge",sessionId:t,details:{resolvedModel:e,perInstanceModel:o.instanceAiConfig?.model||null,perInstanceBaseURL:o.instanceAiConfig?.baseURL?"[set]":null,perInstanceApiKey:o.instanceAiConfig?.apiKey?"[set]":null,configPath:n}}),m.on("event",p=>this.forwardAcodeEvent(p)),m}buildSubAgentSuiteToolProvider(t){return async e=>{if(!t)return[];if(!yt(t,P))return[];if(e.length===0)return Tt();if(!e.some(i=>{const a=i.trim().replace(/[.*]+$/,"");return a==="desktop"||a.startsWith("desktop.")}))return[];const s=await this.resolveAgentAiInfo(t);return v(t,s)}}async loadRuntimeConstructor(){if(this.runtimeConstructor)return this.runtimeConstructor;const t=Wt(),e=await import(Ht(t));if(!e.ACodeRuntime)throw new Error(`ACode runtime export not found: ${t}`);return this.runtimeConstructor=e.ACodeRuntime,this.runtimeConstructor}requireSession(t){const e=this.sessions.get(t);if(!e)throw new Error("ACode session not found");return e}startInitialPromptTurn(t,e){const o=this.sessions.get(t);o&&(o.adapterSession.status="thinking",this.emit("status-change",t,"thinking"),o.autoPollObservedAssistantText=!1,o.autoPollObservedAnyTool=!1,o.autoPollObservedPollingTool=!1,o.lastSubmittedPrompt=e,o.retryEpoch+=1,o.turnModelRequestSucceeded=!1,this.startSubmitTimeoutDetection(t,o,"startInitialPromptTurn"),o.runtime.submit(e).then(()=>{this.cancelSubmitTimeoutDetection(o),this.recoverResolvedTurnWithoutTerminalEvent(t)}).catch(s=>{const i=this.sessions.get(t);i&&(this.cancelSubmitTimeoutDetection(i),i.lastErrorText=s instanceof Error?s.message:String(s),this.emitRuntimeErrorEvent(t,s),this.scheduleRequestRetry(t,"startInitialPromptTurn"))}))}forwardAcodeEvent(t){const e=this.sessions.get(t.sessionId);if(e){if(e.lastAcodeEventAt=Date.now(),e.autoPollActive&&(e.autoPollLastActivityAt=Date.now()),t.type==="assistant_delta"){const o=typeof t.data.text=="string"?t.data.text:"";e.turnModelRequestSucceeded=!0,e.turnModelRequestSucceededEpoch=e.retryEpoch,e.autoPollObservedAssistantText=!0,e.adapterSession.messages.push({id:x(),sessionId:t.sessionId,role:"assistant",content:o,timestamp:t.timestamp}),this.resetDataFlowWatchdog(t.sessionId,e),this.emitProviderEvent(t,"text_delta",{text:o});return}if(t.type==="thinking_delta"){const o=typeof t.data.text=="string"?t.data.text:"";e.turnModelRequestSucceeded=!0,e.turnModelRequestSucceededEpoch=e.retryEpoch,this.resetDataFlowWatchdog(t.sessionId,e),this.emitProviderEvent(t,"thinking",{text:o});return}if(t.type==="command_output"){this.emitProviderEvent(t,"command_output",{text:typeof t.data.text=="string"?t.data.text:"",stream:Gt(t.data.stream),sequence:typeof t.data.sequence=="number"?t.data.sequence:void 0,cwd:typeof t.data.cwd=="string"?t.data.cwd:void 0,commandLineCount:typeof t.data.commandLineCount=="number"?t.data.commandLineCount:void 0,commandFilePath:typeof t.data.commandFilePath=="string"?t.data.commandFilePath:void 0});return}if(t.type==="background_command_completed"){this.emitProviderEvent(t,"background_command_completed",t.data);return}if(t.type==="ai_request"){const o=t.data.lastUsage,s=y(o?.inputTokens),i=y(o?.outputTokens),a=y(o?.cacheHitTokens),n=y(o?.cacheMissTokens),d=!!(o&&(s>0||i>0));let l;d&&(s>0&&(e.adapterSession.totalUsage.inputTokens=s),i>0&&(e.adapterSession.totalUsage.outputTokens=i),(o?.cacheHitTokens!==void 0||o?.cacheMissTokens!==void 0)&&(e.adapterSession.totalUsage.cacheHitTokens=a,e.adapterSession.totalUsage.cacheMissTokens=n),l={...e.adapterSession.totalUsage},w(`ai_request lastUsage applied: ${JSON.stringify(o)} -> totalUsage=${JSON.stringify(e.adapterSession.totalUsage)}`)),e.adapterSession.status==="compacting"&&(e.adapterSession.status="thinking"),e.adapterSession.status==="waiting_input"&&(e.adapterSession.status="thinking");const c={actionType:"ai_request",actionLabel:"AI\u8BF7\u6C42",actionDetail:this.formatAiRequestActionDetail(t.data)};l&&(c.usage=l),w(`ai_request handled: estimatedContextTokens=${t.data.estimatedContextTokens??"n/a"} totalUsage=${JSON.stringify(e.adapterSession.totalUsage)} displayUsage=${JSON.stringify(l??null)}`),this.emit("status-change",t.sessionId,e.adapterSession.status,c),this.startDataFlowWatchdog(t.sessionId,e),e.adapterSession.status==="thinking"&&e.watchdogSubmitStartTime&&(e.watchdogSubmitStartTime=Date.now()),this.emitProviderEvent(t,"ai_request",{model:typeof t.data.model=="string"?t.data.model:void 0,endpoint:typeof t.data.endpoint=="string"?t.data.endpoint:void 0,requestMethod:typeof t.data.requestMethod=="string"?t.data.requestMethod:void 0,requestUrl:typeof t.data.requestUrl=="string"?t.data.requestUrl:void 0,requestHeaders:zt(t.data.requestHeaders),stream:typeof t.data.stream=="boolean"?t.data.stream:void 0,messageCount:typeof t.data.messageCount=="number"?t.data.messageCount:void 0,toolCount:typeof t.data.toolCount=="number"?t.data.toolCount:void 0,lastUserMessagePreview:typeof t.data.lastUserMessagePreview=="string"?t.data.lastUserMessagePreview:void 0});return}if(t.type==="iteration_usage"){const o=it(t.data);o&&(e.adapterSession.totalUsage.inputTokens=o.inputTokens,e.adapterSession.totalUsage.outputTokens=o.outputTokens,o.hasCache&&(e.adapterSession.totalUsage.cacheHitTokens=o.cacheHitTokens,e.adapterSession.totalUsage.cacheMissTokens=o.cacheMissTokens),w(`iteration_usage applied: raw=${JSON.stringify(t.data)} -> totalUsage=${JSON.stringify(e.adapterSession.totalUsage)}`),this.emit("status-change",t.sessionId,e.adapterSession.status,{usage:{...e.adapterSession.totalUsage}}));return}if(t.type==="turn_complete"){const o=it(t.data.usage);if(o){const i=e.adapterSession.totalUsage.inputTokens,a=i>0&&o.inputTokens<Math.floor(i*.2)&&!o.hasCache;w(`turn_complete usage: raw=${JSON.stringify(t.data.usage)} parsed=${JSON.stringify(o)} currentInput=${i} threshold20pct=${Math.floor(i*.2)} isFallbackUsage=${a}`),a?o.outputTokens>0&&(e.adapterSession.totalUsage.outputTokens=o.outputTokens):(e.adapterSession.totalUsage.inputTokens=o.inputTokens,e.adapterSession.totalUsage.outputTokens=o.outputTokens),o.hasCache&&(e.adapterSession.totalUsage.cacheHitTokens=o.cacheHitTokens,e.adapterSession.totalUsage.cacheMissTokens=o.cacheMissTokens,r(`[ACode] \u{1F4B0} Cache usage (overwrite from runtime cumulative): hit=${e.adapterSession.totalUsage.cacheHitTokens}, miss=${e.adapterSession.totalUsage.cacheMissTokens} (turn delta: hit=${o.cacheHitTokens??0}, miss=${o.cacheMissTokens??0})`)),w(`totalUsage after turn_complete: ${JSON.stringify(e.adapterSession.totalUsage)}`)}else w(`turn_complete has NO parseable usage: raw=${JSON.stringify(t.data.usage)} failed=${t.data.failed===!0} aborted=${t.data.aborted===!0}`);const s=e.adapterSession.status;if(r(`[ACode] turn_complete event received (session: ${t.sessionId}), previous status: ${s}, failed: ${t.data.failed===!0}, aborted: ${t.data.aborted===!0}`),Jt(t.data)){r(`[ACode] Scheduling retry from failed turn_complete (session: ${t.sessionId})`),this.cancelDataFlowWatchdog(e),this.recoverTurnFailure(t.sessionId,e);return}if(t.data.aborted===!0&&(e.autoPollActive||e.retryActive||e.retryTimer)){r(`[ACode] Scheduling retry from aborted turn_complete (session: ${t.sessionId})`),this.cancelDataFlowWatchdog(e),this.recoverTurnFailure(t.sessionId,e);return}if(this.cancelDataFlowWatchdog(e),this.emitProviderEvent(t,"turn_complete",{usage:e.adapterSession.totalUsage,responseBody:typeof t.data.responseBody=="string"?t.data.responseBody:void 0,finishReason:typeof t.data.finishReason=="string"?t.data.finishReason:void 0}),e.adapterSession.status="waiting_input",k("turn_complete_to_waiting_input",{sessionId:t.sessionId,autoPollActive:!!e.autoPollActive,observedAnyTool:!!e.autoPollObservedAnyTool,observedPollingTool:!!e.autoPollObservedPollingTool,observedAssistantText:!!e.autoPollObservedAssistantText}),this.emit("status-change",t.sessionId,"waiting_input",{usage:e.adapterSession.totalUsage}),w(`status-change emitted (waiting_input after turn_complete): usage=${JSON.stringify(e.adapterSession.totalUsage)}`),r(`[ACode] Status changed to waiting_input after turn_complete (session: ${t.sessionId})`),e.autoPollActive&&e.autoPollObservedAssistantText&&!e.autoPollObservedPollingTool&&!e.autoPollObservedAnyTool){e.stopAutoPollAfterCurrentTurn=!0,e.idleListeningIntentionallyStopped=!0,console.warn(`[${this.displayName}] Auto-poll turn produced assistant text without calling any tool; stopping auto-poll rearm for session ${t.sessionId}`);return}if(!e.autoPollActive&&e.autoPollObservedAnyTool&&!e.autoPollObservedPollingTool){r(`[ACode] User-message turn called work tools; deferring idle rearm (no immediate dispatch) for this turn (session: ${t.sessionId})`),this.scheduleDeferredIdleRearm(t.sessionId);return}this.armIdleLoopOrAutoPoll(t.sessionId);return}if(t.type==="session_complete"){this.cancelDataFlowWatchdog(e),this.cancelScheduledAutoPoll(e),e.failedTurnRecoveryScheduled=!1,e.idlePollLoop?.stop(),e.adapterSession.status="completed",this.emitProviderEvent(t,"session_complete",{exitCode:Number(t.data.exitCode)||0}),this.emit("status-change",t.sessionId,"completed");return}if(t.type==="question_request"){this.cancelDataFlowWatchdog(e),this.cancelSubmitTimeoutDetection(e);const o=typeof t.data.toolCallId=="string"?t.data.toolCallId:"",s=Array.isArray(t.data.questions)?t.data.questions:[];o&&(e.pendingQuestionToolCallId=o,e.pendingQuestions=s),this.emit("ask-user-question",{sessionId:t.sessionId,toolCallId:o||void 0,questions:s});return}if(t.type==="tool_permission_request"){this.cancelDataFlowWatchdog(e),this.cancelSubmitTimeoutDetection(e);const o=typeof t.data.requestId=="string"?t.data.requestId:"";o&&(e.pendingToolAuthRequests||(e.pendingToolAuthRequests=new Map),e.pendingToolAuthRequests.set(o,{capability:String(t.data.capability||""),detail:{path:t.data.path,command:t.data.command,cwd:t.data.cwd,operation:t.data.operation},requestedAt:Date.now()})),this.emit("tool-permission-request",{sessionId:t.sessionId,requestId:o,capability:String(t.data.capability||""),agentId:e.config.agentId,detail:{path:t.data.path,command:t.data.command,cwd:t.data.cwd,operation:t.data.operation}});return}if(t.type==="error"){if(t.data.nonFatal){this.resetDataFlowWatchdog(t.sessionId,e),this.emitProviderEvent(t,"error",{text:String(t.data.message||"ACode runtime error")});return}this.cancelDataFlowWatchdog(e),e.adapterSession.status="error",e.lastErrorText=String(t.data.message||""),this.emitProviderEvent(t,"error",{text:String(t.data.message||"ACode runtime error")}),this.emit("status-change",t.sessionId,"error"),e.autoPollActive||this.recoverTurnFailure(t.sessionId,e);return}if(t.type==="mcp_status"){if(!t.data.action&&Array.isArray(t.data.tools)){const g=t.data.tools;g.some(A=>Pt(A))||console.warn(`[${this.displayName}] ACode runtime is not exposing a poll_message tool. The LLM cannot call poll_message. Please configure an MCP server that provides poll_message (e.g. aws-mcp) in the dashboard panel for this runtime.`);const S=Array.isArray(t.data.servers)?t.data.servers:[],b=g.map(A=>({name:String(A.name??""),source:String(A.source??""),description:String(A.description??"")})).filter(A=>A.name),C={kind:"mcp",mcpServers:S,mcpTools:b};e.cachedMcpCapabilities=C,e.lastMcpCapabilities=C,e.lastCombinedCapabilities={kind:"combined",mcpServers:S,mcpTools:b,skills:e.lastCombinedCapabilities?.skills??[],skillsDir:e.lastCombinedCapabilities?.skillsDir,skillGroups:e.lastCombinedCapabilities?.skillGroups??[]},r(`[cap-diag] MCP capabilities cached: ${S.length} servers, ${b.length} tools`,{sessionId:t.sessionId,servers:S,toolNames:b.map(A=>A.name)}),e.capabilitiesFallbackTimer&&clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=setTimeout(()=>{const A=e.cachedMcpCapabilities;if(!A)return;const _={...A,skills:[],skillGroups:[]};this.emitProviderEvent(t,"runtime_capabilities",{capabilities:_,actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:JSON.stringify(_)}),r(`[cap-diag] MCP capabilities emitted via fallback (skill_status not received within ${et}ms)`,{sessionId:t.sessionId,mcpServers:A.mcpServers,mcpToolsCount:A.mcpTools?.length??0}),e.cachedMcpCapabilities=void 0,e.capabilitiesFallbackTimer=void 0},et);return}const o=String(t.data.action??"");if(o==="tool_batch_start"){const g=typeof t.data.batchId=="string"?t.data.batchId:void 0;if(!g){r(`[ACode] \u{1F9E9} tool_batch_start without batchId, ignored (session=${t.sessionId})`);return}const h=typeof t.data.toolCount=="number"?t.data.toolCount:0,S=Array.isArray(t.data.toolNames)?t.data.toolNames.map(b=>String(b??"")).filter(Boolean):[];r(`[ACode] \u{1F9E9} tool_batch_start: batch=${g.slice(0,20)}\u2026, tools=${h}`),this.emitProviderEvent(t,"tool_batch_start",{batchId:g,batchToolCount:h,batchToolNames:S,actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionDetail:S.length>0?S.join(", "):void 0,actionId:g});return}if(o==="tool_batch_metrics"){const g=typeof t.data.batchId=="string"?t.data.batchId:void 0;if(!g){r(`[ACode] \u26A1 tool_batch_metrics without batchId, ignored (session=${t.sessionId})`);return}const h={toolCount:I(t.data.toolCount),parallelism:I(t.data.parallelism),speedup:I(t.data.speedup),wallClockMs:I(t.data.wallClockMs),totalWaitMs:W(t.data.totalWaitMs),contentionCount:I(t.data.contentionCount),failureCount:W(t.data.failureCount),maxConcurrentObserved:W(t.data.maxConcurrentObserved)};r(`[ACode] \u26A1 tool_batch_metrics: batch=${g.slice(0,20)}\u2026, speedup=${h.speedup}x parallelism=${h.parallelism}x wall=${h.wallClockMs}ms contentions=${h.contentionCount} failures=${h.failureCount??"-"}`),this.emitProviderEvent(t,"tool_batch_metrics",{batchId:g,batchMetrics:h,actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionId:g});return}if(o!=="call_tool"&&o!=="tool_result"){r(`[ACode] \u{1F4AC} mcp_status status report ignored (action=${o||"none"}, server=${typeof t.data.server=="string"?t.data.server:"?"}, session=${t.sessionId})`);return}r(`[ACode] \u{1F4E1} mcp_status event: action=${o}, server=${typeof t.data.server=="string"?t.data.server:"?"}, tool=${typeof t.data.tool=="string"?t.data.tool:"?"}, toolUseId=${typeof t.data.toolUseId=="string"?t.data.toolUseId.slice(0,16)+"\u2026":"none"}, failed=${t.data.failed===!0}, session=${t.sessionId}, status=${e.adapterSession.status}`);const s=typeof t.data.server=="string"?t.data.server:"mcp",i=typeof t.data.tool=="string"?t.data.tool:"",a=s&&i?`${s}__${i}`:i||s,n=t.data.arguments&&typeof t.data.arguments=="object"&&!Array.isArray(t.data.arguments)?t.data.arguments:void 0,d=xt(a,n);e.autoPollObservedAnyTool=!0,d.actionType==="idle"&&(e.autoPollObservedPollingTool=!0);const l=Qt(d.actionType)?d.actionDetail||at(void 0,s,i):at(d.actionDetail,s,i),m=typeof t.data.toolUseId=="string"?t.data.toolUseId:void 0,c=n?JSON.stringify(n,null,2):void 0,p=typeof t.data.batchId=="string"?t.data.batchId:void 0,f={toolName:l,rawToolName:a,actionType:d.actionType,actionLabel:d.actionLabel,actionDetail:l,...c?{actionInput:c}:{},...n?{toolInput:n}:{},...m?{toolUseId:m,actionId:m}:{},...p?{batchId:p,parentId:p}:{},metadata:{mcpServer:s}};if(t.data.action==="tool_result"){this.emitProviderEvent(t,"tool_use_end",{...f,toolResult:typeof t.data.result=="string"?t.data.result:JSON.stringify(t.data.result??"")}),e.adapterSession.messages.push({id:x(),sessionId:t.sessionId,role:"tool_result",content:typeof t.data.result=="string"?t.data.result:JSON.stringify(t.data.result??""),timestamp:t.timestamp,toolName:a,toolUseId:m,isError:t.data.failed===!0});const g=d.actionType==="idle"&&!Yt(t.data.result)?"waiting_input":"thinking";e.adapterSession.status=g,d.actionType==="idle"&&(e.idleToolActiveAt=void 0),k("tool_use_end",{sessionId:t.sessionId,actionType:d.actionType,tool:a,nextStatus:g,idleToolActiveAtAfter:e.idleToolActiveAt??null}),this.cancelDataFlowWatchdog(e),e.pendingToolEventData=void 0;const h=d.actionType==="idle";this.emit("status-change",t.sessionId,g,h||g==="thinking"?void 0:f);return}const T=d.actionType==="idle"?"waiting_input":"tool_using";e.adapterSession.status=T,d.actionType==="idle"&&(e.idleToolActiveAt=Date.now()),T==="tool_using"&&(this.resetDataFlowWatchdog(t.sessionId,e),e.pendingToolEventData={...f}),e.adapterSession.messages.push({id:x(),sessionId:t.sessionId,role:"tool_use",content:c??"",timestamp:t.timestamp,toolName:a,toolInput:n,toolUseId:m}),this.emitProviderEvent(t,"tool_use_start",f),this.emit("status-change",t.sessionId,T,f);return}if(t.type==="skill_status"){const s=(Array.isArray(t.data.skills)?t.data.skills:[]).map(c=>({name:String(c.name??""),description:typeof c.description=="string"?c.description:void 0,directory:typeof c.directory=="string"?c.directory:void 0})).filter(c=>c.name),i=typeof t.data.skillsDir=="string"?t.data.skillsDir:void 0,n=(Array.isArray(t.data.skillGroups)?t.data.skillGroups:[]).map(c=>{const p=Array.isArray(c.skills)?c.skills:[];return{dir:typeof c.dir=="string"?c.dir:"",exists:c.exists===!0,skills:p.map(f=>({name:String(f.name??""),description:typeof f.description=="string"?f.description:void 0,directory:typeof f.directory=="string"?f.directory:void 0})).filter(f=>f.name)}}).filter(c=>c.dir),d=e.cachedMcpCapabilities??e.lastMcpCapabilities,l=e.cachedMcpCapabilities!==void 0,m={kind:"combined",mcpServers:d?.mcpServers??[],mcpTools:d?.mcpTools??[],skills:s,skillsDir:i,skillGroups:n};this.emitProviderEvent(t,"runtime_capabilities",{capabilities:m,actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:JSON.stringify(m)}),e.lastCombinedCapabilities=m,r(`[cap-diag] Combined capabilities emitted ${l?"(startup merge)":"(runtime refresh)"}: ${(d?.mcpTools??[]).length} MCP tools, ${s.length} skills`,{sessionId:t.sessionId,mcpServers:d?.mcpServers??[],skillsDir:i}),e.capabilitiesFallbackTimer&&(clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=void 0),e.cachedMcpCapabilities=void 0;return}if(t.type==="startup_phase"){r(`[ACode] \u{1F680} startup_phase swallowed: ${String(t.data.phase??"unknown")}`,{sessionId:t.sessionId});return}if(t.type==="command_status"){if(t.data.action==="commands_loaded"){r(`[ACode] \u{1F4CB} command_status commands_loaded swallowed: ${typeof t.data.installedCommandCount=="number"?t.data.installedCommandCount:"?"} commands`,{sessionId:t.sessionId});return}this.emitProviderEvent(t,"thinking",{text:JSON.stringify(t.data)});return}if(t.type==="session_started"){const o=y(t.data.contextLimit)||void 0,s=y(t.data.maxOutput)||void 0,i=y(t.data.inputLimit)||void 0,a=y(t.data.compactionThreshold)||void 0;let n=!1;o!==void 0&&(e.adapterSession.totalUsage.contextLimit=o,n=!0),s!==void 0&&(e.adapterSession.totalUsage.maxOutput=s,n=!0),i!==void 0&&(e.adapterSession.totalUsage.inputLimit=i,n=!0),a!==void 0&&(e.adapterSession.totalUsage.compactionThreshold=a,n=!0),n&&this.emit("status-change",t.sessionId,e.adapterSession.status,{usage:e.adapterSession.totalUsage});return}if(t.type==="exit_plan_mode"){e.adapterSession.status="waiting_input";const o=typeof t.data.plan=="string"?t.data.plan:void 0;this.emitProviderEvent(t,"exit_plan_mode",{toolInput:t.data.toolInput&&typeof t.data.toolInput=="object"?t.data.toolInput:void 0,text:o||"\u9000\u51FA\u8BA1\u5212\u6A21\u5F0F"}),this.emit("status-change",t.sessionId,"waiting_input",{actionLabel:"\u5BA1\u6279\u8BA1\u5212",actionDetail:o||"\u7B49\u5F85\u7528\u6237\u5BA1\u6279\u9000\u51FA\u8BA1\u5212\u6A21\u5F0F"});return}if(t.type==="context_compaction"){const o=t.data,s=o.action,i=s==="start",a=s==="end",n=s==="phase",d=o.parentId,l=o.compactionId;if(o.trigger==="hibernation_replay"){const T=typeof o.replayedMessageCount=="number"?o.replayedMessageCount:void 0,g=o.estimatedTokens;typeof g=="number"&&g>0&&(e.adapterSession.totalUsage.inputTokens=g);const h={actionType:"context_compaction",actionLabel:"\u4F11\u7720\u6062\u590D",actionDetail:T?`\u5DF2\u91CD\u653E\u4F11\u7720\u524D\u7684 ${T} \u6761\u5BF9\u8BDD\u8BB0\u5F55\uFF0C\u4E0A\u4E0B\u6587\u5DF2\u63A5\u7EED`:"\u5DF2\u91CD\u653E\u4F11\u7720\u524D\u7684\u5BF9\u8BDD\u8BB0\u5F55\uFF0C\u4E0A\u4E0B\u6587\u5DF2\u63A5\u7EED",...l?{actionId:l}:{},...g?{usage:{...e.adapterSession.totalUsage,inputTokens:g}}:{}};this.emitProviderEvent(t,"context_compaction",h),this.emit("status-change",t.sessionId,e.adapterSession.status,h);return}let c,p;if(i){const T=String(o.sizeKB??o.sizeBeforeKB??"?"),g=String(o.messageCount??o.messageCountBefore??"?"),h=o.estimatedTokens,S=o.actualInputTokens?`input=${o.actualInputTokens}`:"",b=o.actualOutputTokens?`output=${o.actualOutputTokens}`:"",C=o.trigger;c="\u4E0A\u4E0B\u6587\u538B\u7F29\u5F00\u59CB";const A=C==="provider_overflow_error"?"\u6A21\u578B\u8FD4\u56DE\u4E0A\u4E0B\u6587\u8D85\u9650\u4FE1\u53F7":C==="finish_reason_context_overflow"?"\u54CD\u5E94\u4E2D\u7684\u8D85\u9650\u6807\u8BB0":C==="request_body_byte_limit"?"\u8BF7\u6C42\u4F53\u5B57\u8282\u4E0A\u9650":C,_=A?`, \u89E6\u53D1: ${A}`:"";h!==void 0?p=`\u538B\u7F29\u524D: ~${h} tokens, \u6D88\u606F: ${g}\u6761`+(S?`, \u5B9E\u9645 tokens: ${S} ${b}`:"")+_:p=`\u538B\u7F29\u524D: ${T}KB, \u6D88\u606F: ${g}\u6761`+(S?`, \u5B9E\u9645 tokens: ${S} ${b}`:"")+_}else if(n){const T=String(o.phase??""),g=String(o.phaseLabel??"\u538B\u7F29\u9636\u6BB5"),h=String(o.phaseDetail??"");T==="detect"?(c="\u5F00\u59CB\u89E6\u53D1\u54CD\u5E94\u5F0F\u538B\u7F29",p=h||"\u68C0\u6D4B\u5230\u4E0A\u4E0B\u6587\u8D85\u9650\uFF0C\u5373\u5C06\u5F00\u59CB\u538B\u7F29..."):(c=g,p=h)}else{const T=o.tokensBefore,g=o.tokensAfter,h=o.freedTokens,S=String(o.sizeBeforeKB??"?"),b=String(o.sizeAfterKB??"?"),C=String(o.freedKB??"?"),A=String(o.strategy??"?"),_=Number(o.prunedToolMessages??0),D=Number(o.summarizedMessages??0);c="\u538B\u7F29\u5B8C\u6210",T!==void 0&&g!==void 0?p=`\u91CA\u653E: ${h??T-g} tokens, ${T} tokens \u2192 ${g} tokens, \u7B56\u7565: ${A}`+(_?`, \u88C1\u526A\u5DE5\u5177: ${_}\u6761`:"")+(D?`, \u6458\u8981\u5316: ${D}\u6761`:""):p=`\u91CA\u653E: ${C}KB, ${S}KB \u2192 ${b}KB, \u7B56\u7565: ${A}`+(_?`, \u88C1\u526A\u5DE5\u5177: ${_}\u6761`:"")+(D?`, \u6458\u8981\u5316: ${D}\u6761`:"")}i&&(e.adapterSession.status="compacting");const f={actionType:"context_compaction",actionLabel:c,actionDetail:p};if(i&&l)f.actionId=l;else if((n||a)&&l)if(f.parentId=l,n){const T=String(o.phase??"unknown");f.actionId=`${l}-phase-${T}`}else f.actionId=`${l}-end`;n&&d&&!f.parentId&&(f.parentId=d),a&&(e.adapterSession.totalUsage.inputTokens=y(o.tokensAfter),e.adapterSession.totalUsage.outputTokens=0,f.usage={...e.adapterSession.totalUsage}),this.emitProviderEvent(t,"context_compaction",f),this.emit("status-change",t.sessionId,"compacting",f);return}this.emitProviderEvent(t,"thinking",{text:JSON.stringify(t.data)})}}emitProviderEvent(t,e,o){this.emit("event",{type:e,sessionId:t.sessionId,timestamp:t.timestamp,data:o})}armIdleLoopOrAutoPoll(t){const e=this.sessions.get(t);if(!(!e||this.isTerminalStatus(e.adapterSession.status))){if(e.autoPollTimer&&(clearTimeout(e.autoPollTimer),e.autoPollTimer=void 0),this.cancelRequestRetry(e),e.retryAttempt=0,e.idleCommands?.idleInputCommand){this.getIdlePollLoop(e).start();return}this.scheduleAutoPoll(t)}}scheduleDeferredIdleRearm(t){const e=this.sessions.get(t);!e||e.autoPollActive||e.autoPollTimer||this.isTerminalStatus(e.adapterSession.status)||this.scheduleAutoPoll(t,Ft)}getIdlePollLoop(t){if(t.idlePollLoop)return t.idlePollLoop;const e=t.adapterSession.sessionId;return t.idlePollLoop=new $t({getStatus:()=>this.sessions.get(e)?.adapterSession.status,getCommand:()=>this.sessions.get(e)?.idleCommands?.idleInputCommand,isPollingCommand:o=>q(o),preDispatchHook:()=>null,dispatchPollingPrompt:(o,s)=>this.submitAutoPollPrompt(e,s?o:Nt,{keepWaitingStatus:!0}),dispatchRegularIdleCommand:o=>this.submitAutoPollPrompt(e,o)}),t.idlePollLoop}submitAutoPollPrompt(t,e,o){const s=this.sessions.get(t);if(!s||this.isTerminalStatus(s.adapterSession.status))return;const i=(s.autoPollToken??0)+1;s.autoPollToken=i,s.autoPollActive=!0,s.autoPollObservedPollingTool=!1,s.autoPollObservedAssistantText=!1,s.autoPollObservedAnyTool=!1,s.stopAutoPollAfterCurrentTurn=!1,s.idleListeningIntentionallyStopped=!1,s.autoPollQueuedAt=Date.now(),s.autoPollLastActivityAt=Date.now(),s.idleToolActiveAt=void 0,s.lastSubmittedPrompt=e,s.retryEpoch+=1,s.turnModelRequestSucceeded=!1,o?.keepWaitingStatus||(s.adapterSession.status="thinking",this.emit("status-change",t,"thinking")),this.startSubmitTimeoutDetection(t,s,"submitAutoPollPrompt"),s.runtime.submit(e).catch(a=>{this.emitRuntimeErrorEvent(t,a),this.scheduleRequestRetry(t,"submitAutoPollPrompt")}).finally(()=>{const a=this.sessions.get(t);if(a){if(a.autoPollToken!==i){r(`[ACode] submitAutoPollPrompt.finally: token mismatch (my=${i}, current=${a.autoPollToken}), skipping cleanup \u2014 newer turn has taken over`);return}if(this.cancelSubmitTimeoutDetection(a),a.autoPollActive=!1,a.failedTurnRecoveryScheduled||a.autoPollTimer){a.failedTurnRecoveryScheduled=!1;return}if(a.stopAutoPollAfterCurrentTurn){a.stopAutoPollAfterCurrentTurn=!1,a.autoPollObservedPollingTool=!1,a.autoPollObservedAssistantText=!1,a.autoPollObservedAnyTool=!1;return}if(a.adapterSession.status==="error"){this.recoverTurnFailure(t,a);return}if(a.adapterSession.status==="thinking"||a.adapterSession.status==="tool_using"){this.recoverResolvedTurnWithoutTerminalEvent(t);return}a.adapterSession.status==="waiting_input"&&this.armIdleLoopOrAutoPoll(t)}})}scheduleAutoPoll(t,e){const o=this.sessions.get(t);if(!o||o.autoPollActive||o.autoPollTimer||this.isTerminalStatus(o.adapterSession.status))return;const s=e??o.autoPollDelayMs??Rt;e===void 0&&(o.autoPollDelayMs=Math.min(s*2,Ut)),o.autoPollTimer=setTimeout(()=>{const i=this.sessions.get(t);!i||i.autoPollActive||this.isTerminalStatus(i.adapterSession.status)||(i.autoPollTimer=void 0,this.submitAutoPollPrompt(t,Dt,{keepWaitingStatus:!0}))},s)}cancelScheduledAutoPoll(t){t.autoPollDelayMs=void 0,t.autoPollTimer&&(clearTimeout(t.autoPollTimer),t.autoPollTimer=void 0)}scheduleRequestRetry(t,e){const o=this.sessions.get(t);if(!o||this.isTerminalStatus(o.adapterSession.status))return;if(o.retryCircuitBroken){r(`[ACode] scheduleRequestRetry(${e}): retry terminated by non-retryable error, suppress further auto-retry`);return}if(o.retryActive||o.retryTimer)return;if(!o.lastSubmittedPrompt){o.adapterSession.status="error",this.emit("status-change",t,"error");return}if(o.turnModelRequestSucceeded&&o.turnModelRequestSucceededEpoch===o.retryEpoch&&(o.turnModelRequestSucceeded=!1,o.retryAttempt=0),o.lastErrorText&&qt(o.lastErrorText)){r(`[ACode] scheduleRequestRetry(${e}): non-retryable provider error, giving up retry: ${o.lastErrorText.slice(0,200)}`),this.cancelRequestRetry(o);const i=Math.max(1,o.retryAttempt+1);o.retryAttempt=0,o.retryCircuitBroken=!0,o.adapterSession.status="error",_t({sessionId:t,agentId:o.config.agentId,model:o.config.model,attempt:i,errorText:o.lastErrorText,conversation:this.exportRawTranscript(t),extra:{reason:e,status:o.adapterSession.status}}),this.emit("status-change",t,"error",{actionType:"retry_aborted",actionLabel:"\u8BF7\u6C42\u65E0\u6548",actionDetail:"Provider \u8FD4\u56DE 4xx \u8BF7\u6C42\u9519\u8BEF\uFF08\u539F\u6837\u91CD\u8BD5\u5FC5\u7136\u5931\u8D25\uFF09\uFF0C\u5DF2\u505C\u6B62\u81EA\u52A8\u91CD\u8BD5\uFF0C\u8BF7\u68C0\u67E5\u6E20\u9053\u914D\u7F6E\u6216\u91CD\u542F\u4F1A\u8BDD\u3002",actionError:Z(o.lastErrorText)});return}o.retryAttempt+=1,o.retryActive=!0,this.cancelScheduledAutoPoll(o),o.idlePollLoop?.stop();const s=V[Math.min(o.retryAttempt-1,V.length-1)];o.adapterSession.status="error",this.emit("status-change",t,"error",{actionType:"retry",actionLabel:"\u91CD\u8BD5\u4E2D",actionDetail:`\u7B2C${o.retryAttempt}\u6B21 \xB7 ${Math.round(s/1e3)}s\u540E`,actionError:Z(o.lastErrorText)}),r(`[ACode] scheduleRequestRetry(${e}): attempt=${o.retryAttempt} delay=${s}ms`),o.retryTimer=setTimeout(()=>{o.retryTimer=void 0,this.retryFailedRequest(t,e)},s)}retryFailedRequest(t,e){const o=this.sessions.get(t);if(!o)return;if(o.retryTimer=void 0,this.isTerminalStatus(o.adapterSession.status)||!o.lastSubmittedPrompt){o.retryActive=!1;return}o.retryActive=!1;const s=o.lastSubmittedPrompt;r(`[ACode] retryFailedRequest(${e}): attempt=${o.retryAttempt} re-submitting...`),o.retryEpoch+=1,o.turnModelRequestSucceeded=!1,o.autoPollObservedAssistantText=!1,o.autoPollObservedAnyTool=!1,o.autoPollObservedPollingTool=!1,o.adapterSession.status="thinking",this.emit("status-change",t,"thinking",{usage:o.adapterSession.totalUsage}),this.startSubmitTimeoutDetection(t,o,"retryFailedRequest"),o.runtime.submit(s,{resume:!0}).then(()=>{const i=this.sessions.get(t);!i||i.retryTimer||(this.cancelSubmitTimeoutDetection(i),i.retryAttempt=0,i.retryActive=!1,i.retryCircuitBroken=!1,this.recoverResolvedTurnWithoutTerminalEvent(t))}).catch(i=>{const a=this.sessions.get(t);a&&(this.cancelSubmitTimeoutDetection(a),a.lastErrorText=i instanceof Error?i.message:String(i),this.emitRuntimeErrorEvent(t,i),this.scheduleRequestRetry(t,`retry#${a.retryAttempt+1}`))})}cancelRequestRetry(t){t.retryTimer&&(clearTimeout(t.retryTimer),t.retryTimer=void 0),t.retryActive=!1}isTerminalStatus(t){return t==="completed"||t==="terminated"}emitRuntimeErrorEvent(t,e){const o=new Date().toISOString();this.emit("event",{type:"error",sessionId:t,timestamp:o,data:{text:e instanceof Error?e.message:String(e)}})}estimateOutputTokensFromMessages(t){const e=t.filter(o=>o.role==="assistant").map(o=>o.content).join("");return Math.max(0,Math.round(e.length/4))}recoverTurnFailure(t,e){if(this.isTerminalStatus(e.adapterSession.status))return;if(e.idleToolActiveAt=void 0,e.pendingToolAuthRequests?.size&&e.pendingToolAuthRequests.clear(),e.adapterSession.status==="tool_using"&&e.pendingToolEventData){const s=e.pendingToolEventData;r(`[ACode] recoverTurnFailure: \u8865\u53D1 tool_use_end (tool: ${s.toolName??"unknown"}) \u5173\u95ED\u65F6\u95F4\u7EBF\u6761\u76EE\uFF0C\u907F\u514D\u6C38\u4E45\u5361\u5728\u5DE5\u5177\u6267\u884C\u72B6\u6001`),this.emit("event",{type:"tool_use_end",sessionId:t,timestamp:new Date().toISOString(),data:{...s,toolResult:"[aborted] \u5DE5\u5177\u6267\u884C\u88AB\u6570\u636E\u6D41\u770B\u95E8\u72D7\u4E2D\u65AD"}}),e.pendingToolEventData=void 0}const o=this.estimateOutputTokensFromMessages(e.adapterSession.messages);if(o>0){const s=e.adapterSession.totalUsage.outputTokens;e.adapterSession.totalUsage.outputTokens=o,r(`[ACode] recoverTurnFailure: \u4F30\u7B97\u8986\u76D6 output tokens ${s} -> ${o} (totalUsage now: input=${e.adapterSession.totalUsage.inputTokens}, output=${e.adapterSession.totalUsage.outputTokens})`)}this.cancelScheduledAutoPoll(e),this.scheduleRequestRetry(t,"recoverTurnFailure")}recoverResolvedTurnWithoutTerminalEvent(t){r(`[ACode] \u25B6\uFE0F recoverResolvedTurnWithoutTerminalEvent called for session ${t}`);const e=this.sessions.get(t);if(!e||this.isTerminalStatus(e.adapterSession.status)){r(`[ACode] Skipping recovery: entry=${!!e}, isTerminal=${e?this.isTerminalStatus(e.adapterSession.status):"N/A"}`);return}if(r(`[ACode] Current status: ${e.adapterSession.status}`),e.adapterSession.status!=="thinking"&&e.adapterSession.status!=="tool_using"){r(`[ACode] Skipping recovery: status is ${e.adapterSession.status} (not thinking/tool_using)`);return}console.warn(`[ACode] \u26A0\uFE0F Detected stuck state: ${e.adapterSession.status} after submit resolved! Recovering to waiting_input. If runtime.submit() is still pending (e.g., built-in tool execution not interruptible by abort()), the submitQueue is deadlocked and subsequent auto-poll/user submits will never execute.`),r("[ACode] Recovering to waiting_input..."),e.adapterSession.status="waiting_input";const o=e.idleCommands?.idleInputCommand,i=!!(o&&q(o))?{actionType:"idle",actionLabel:"\u76D1\u542C\u6D88\u606F",actionDetail:"aws-mcp/poll_message"}:void 0;if(this.emit("status-change",t,"waiting_input",i),r(`[ACode] \u2705 Recovery complete, status now: ${e.adapterSession.status}`),r("[ACode] \u25B6\uFE0F Arming idle loop or auto-poll..."),!e.autoPollActive&&e.autoPollObservedAnyTool&&!e.autoPollObservedPollingTool){r(`[ACode] User-message turn called work tools; deferring idle rearm in recoverResolvedTurnWithoutTerminalEvent (session: ${t})`),this.scheduleDeferredIdleRearm(t);return}this.armIdleLoopOrAutoPoll(t),r("[ACode] \u2705 Idle loop armed, recovery process complete")}startSubmitTimeoutDetection(t,e,o){this.cancelSubmitTimeoutDetection(e),e.watchdogSubmitStartTime=Date.now(),e.watchdogLastDataFlowTime=Date.now(),k("turn_watchdog_arm",{sessionId:t,source:o,status:e.adapterSession.status,autoPollActive:!!e.autoPollActive,idleToolActiveAt:e.idleToolActiveAt??null}),e.watchdogTimer=setInterval(()=>{const s=this.sessions.get(t);if(!s){this.cancelSubmitTimeoutDetection(e);return}const i=s.adapterSession.status,a=Date.now();if(i==="waiting_input"){if(s.autoPollActive&&s.autoPollLastActivityAt&&!this.hasActiveBlockingToolCall(s)&&a-s.autoPollLastActivityAt>=Ot){console.warn(`[ACode] CRITICAL: stuck auto-poll detected after ${Math.round((a-s.autoPollLastActivityAt)/1e3)}s (source: ${o}, session: ${t}): submit queued but no runtime events and no active poll_message tool. Forcing recovery (runtime force-settle will unblock submitQueue).`),this.executeWatchdogRecovery(t,s,o,"stuck_autopoll",a-s.autoPollLastActivityAt);return}s.watchdogSubmitStartTime=a,s.watchdogLastDataFlowTime=a;return}if(i==="tool_using"){const l=a-(s.watchdogLastDataFlowTime||a);if(l>=Mt){const m=String(s.pendingToolEventData?.rawToolName??"");if((s.pendingToolAuthRequests?.size??0)>0){const c=s.pendingToolAuthRequests?.size??0;console.warn(`[ACode] tool_using elapsed ${Math.round(l/1e3)}s but ${c} tool permission request(s) awaiting user decision (session: ${t}), skipping recovery`),s.watchdogSubmitStartTime=a,s.watchdogLastDataFlowTime=a;return}if(m.endsWith("await_complete")){console.warn(`[ACode] tool_using elapsed ${Math.round(l/1e3)}s but await_complete is running (session: ${t}, tool: ${m}), skipping recovery (sub-agents have their own watchdogs, bg commands have timeout limits)`),s.watchdogSubmitStartTime=a,s.watchdogLastDataFlowTime=a;return}if(console.warn(`[ACode] CRITICAL: tool_using slow timeout triggered after ${Math.round(l/1e3)}s (source: ${o}, session: ${t}). Tool execution likely hung. Forcing recovery via recoverTurnFailure.`),s.runtime.detachCurrentToolExecution?.()){console.warn(`[ACode] tool_using slow (${Math.round(l/1e3)}s): detached tool ${m} to background (session: ${t}); waiting for the real tool_result to continue the turn`),s.watchdogSubmitStartTime=a,s.watchdogLastDataFlowTime=a;return}this.executeWatchdogRecovery(t,s,o,"tool_using_slow",l);return}s.watchdogSubmitStartTime=a;return}if(i!=="thinking")return;const n=a-(s.watchdogSubmitStartTime||a),d=a-(s.watchdogLastDataFlowTime||a);if(Q>0&&d>=Q){console.warn(`[ACode] CRITICAL: Data flow watchdog triggered after ${Math.round(d/1e3)}s (source: ${o}, session: ${t}, status: ${i}). No stream data received. Forcing recovery via recoverTurnFailure.`),this.executeWatchdogRecovery(t,s,o,"data_flow",d);return}if(tt>0&&n>=tt){console.warn(`[ACode] CRITICAL: submit timeout detected after ${Math.round(n/1e3)}s (source: ${o}, session: ${t}, status: ${i}). Forcing recovery to prevent permanent state stuck.`),this.executeWatchdogRecovery(t,s,o,"submit_timeout",n);return}},vt)}executeWatchdogRecovery(t,e,o,s,i){k("turn_watchdog_trigger",{sessionId:t,source:o,reason:s,elapsedMs:i,status:e.adapterSession.status,autoPollActive:!!e.autoPollActive,idleToolActiveAt:e.idleToolActiveAt??null,pendingTool:e.pendingToolEventData?.rawToolName??null}),r(`[ACode] Watchdog (${s}): calling runtime.abort() after ${Math.round(i/1e3)}s...`);try{e.runtime.abort(),r(`[ACode] Watchdog (${s}): runtime.abort() called`)}catch(a){console.warn(`[ACode] \u26A0\uFE0F Watchdog (${s}): runtime.abort() threw: ${a instanceof Error?a.message:String(a)}`)}this.cancelSubmitTimeoutDetection(e),this.recoverTurnFailure(t,e),console.warn(`[ACode] \u26A0\uFE0F Watchdog (${s}) recovery complete. If abort() could not cancel the underlying operation, submitQueue may still be deadlocked.`)}cancelSubmitTimeoutDetection(t){t.watchdogTimer&&(clearInterval(t.watchdogTimer),t.watchdogTimer=void 0,k("turn_watchdog_cancel",{sessionId:t.adapterSession.sessionId,status:t.adapterSession.status,autoPollActive:!!t.autoPollActive,idleToolActiveAt:t.idleToolActiveAt??null})),t.watchdogSubmitStartTime=void 0,t.watchdogLastDataFlowTime=void 0}resetDataFlowWatchdog(t,e){e.watchdogLastDataFlowTime=Date.now(),e.watchdogSubmitStartTime=Date.now()}startDataFlowWatchdog(t,e){e.watchdogLastDataFlowTime=Date.now()}cancelDataFlowWatchdog(t){t.watchdogLastDataFlowTime=Date.now()}startLivenessWatchdog(t,e){this.stopLivenessWatchdog(e),e.lastAcodeEventAt=Date.now(),!(B<=0)&&(e.livenessTimer=setInterval(()=>{const o=this.sessions.get(t);if(!o){this.stopLivenessWatchdog(e);return}this.checkSessionLiveness(t,o)},Y),k("liveness_watchdog_arm",{sessionId:t,stallTimeoutMs:B,pollIntervalMs:Y}))}stopLivenessWatchdog(t){t.livenessTimer&&(clearInterval(t.livenessTimer),t.livenessTimer=void 0)}checkSessionLiveness(t,e){if(this.isTerminalStatus(e.adapterSession.status)){this.stopLivenessWatchdog(e);return}if(e.adapterSession.status!=="waiting_input"||e.autoPollActive||e.idleListeningIntentionallyStopped||e.pendingQuestionToolCallId||(e.pendingToolAuthRequests?.size??0)>0||this.hasActiveBlockingToolCall(e))return;e.idleToolActiveAt!==void 0&&(r(`[ACode] liveness: runtime \u672A\u62A5\u544A\u963B\u585E\u578B\u5DE5\u5177\u5728\u98DE\uFF0C\u6E05\u9664\u6B8B\u7559 idleToolActiveAt \u6807\u8BB0 (session: ${t})`),e.idleToolActiveAt=void 0);const o=e.lastAcodeEventAt??Date.now(),s=Date.now()-o;if(s<B)return;console.warn(`[ACode] CRITICAL: session liveness stall detected \u2014 no runtime event for ${Math.round(s/1e3)}s (session: ${t}, status: waiting_input). Forcing recovery (abort + re-arm listening loop).`),k("liveness_stall_detected",{sessionId:t,stalledForMs:s,status:e.adapterSession.status,idleToolActiveAt:e.idleToolActiveAt??null}),this.recoverIdleStall(t,e,s);const i=this.sessions.get(t);i&&(i.lastAcodeEventAt=Date.now())}recoverIdleStall(t,e,o){try{e.runtime.abort()}catch(s){console.warn(`[ACode] liveness recovery: runtime.abort() threw: ${s instanceof Error?s.message:String(s)}`)}this.cancelScheduledAutoPoll(e),e.autoPollActive=!1,e.idleToolActiveAt=void 0,this.isTerminalStatus(e.adapterSession.status)||(e.adapterSession.status="waiting_input",this.armIdleLoopOrAutoPoll(t)),k("liveness_recovery",{sessionId:t,stalledForMs:o,rearmedStatus:e.adapterSession.status}),console.warn(`[ACode] liveness recovery complete: session ${t} re-armed listening loop after ${Math.round(o/1e3)}s stall`)}hasActiveBlockingToolCall(t){const e=t.runtime.hasActiveBlockingToolCall;if(typeof e=="function")try{return e.call(t.runtime)===!0}catch(o){r(`[ACode] hasActiveBlockingToolCall probe threw, falling back to idle marker: ${o instanceof Error?o.message:String(o)}`)}return t.idleToolActiveAt!==void 0}formatAiRequestActionDetail(t){const e=`
2
2
 
3
3
  \u8BF7\u6C42\u5934:
4
- `,o=typeof t.model=="string"?t.model:"",s=typeof t.endpoint=="string"?t.endpoint:typeof t.requestUrl=="string"?t.requestUrl:"",a=typeof t.requestMethod=="string"?t.requestMethod:"",i=typeof t.stream=="boolean"?t.stream:void 0,n=typeof t.messageCount=="number"?t.messageCount:void 0,c=typeof t.toolCount=="number"?t.toolCount:void 0,u=typeof t.lastUserMessagePreview=="string"?t.lastUserMessagePreview:"",f=[o?`\u6A21\u578B: ${o}`:void 0,s?`\u63A5\u53E3: ${s}`:void 0,a?`\u65B9\u6CD5: ${a}`:void 0,i!==void 0?`\u6D41\u5F0F: ${i?"\u662F":"\u5426"}`:void 0,n!==void 0?`\u4E0A\u4E0B\u6587\u6D88\u606F: ${n}`:void 0,c!==void 0?`\u53EF\u7528\u5DE5\u5177: ${c}`:void 0,u?`\u6700\u540E\u8BF7\u6C42: ${u}`:void 0].filter(h=>!!h),d=/^(authorization|x-api-key|api-key|cookie|set-cookie|x-auth-token|token)$/i,p=t.requestHeaders,m=p?Object.entries(p).filter(([h])=>!d.test(h)).map(([h,S])=>`${h}: ${S}`).filter(h=>h.trim().length>0):[],T=f.join(`
5
- `)||"ACode \u6B63\u5728\u53D1\u9001 AI \u8BF7\u6C42",g=m.length>0?`${e}${m.join(`
6
- `)}`:"";return`${T}${g}`}}export{ke as AcodeSdkAdapter,Jt as isFailedAcodeTurnComplete,Ht as toAcodeEsmImportSpecifier};
4
+ `,o=typeof t.model=="string"?t.model:"",s=typeof t.endpoint=="string"?t.endpoint:typeof t.requestUrl=="string"?t.requestUrl:"",i=typeof t.requestMethod=="string"?t.requestMethod:"",a=typeof t.stream=="boolean"?t.stream:void 0,n=typeof t.messageCount=="number"?t.messageCount:void 0,d=typeof t.toolCount=="number"?t.toolCount:void 0,l=typeof t.lastUserMessagePreview=="string"?t.lastUserMessagePreview:"",m=[o?`\u6A21\u578B: ${o}`:void 0,s?`\u63A5\u53E3: ${s}`:void 0,i?`\u65B9\u6CD5: ${i}`:void 0,a!==void 0?`\u6D41\u5F0F: ${a?"\u662F":"\u5426"}`:void 0,n!==void 0?`\u4E0A\u4E0B\u6587\u6D88\u606F: ${n}`:void 0,d!==void 0?`\u53EF\u7528\u5DE5\u5177: ${d}`:void 0,l?`\u6700\u540E\u8BF7\u6C42: ${l}`:void 0].filter(h=>!!h),c=/^(authorization|x-api-key|api-key|cookie|set-cookie|x-auth-token|token)$/i,p=t.requestHeaders,f=p?Object.entries(p).filter(([h])=>!c.test(h)).map(([h,S])=>`${h}: ${S}`).filter(h=>h.trim().length>0):[],T=m.join(`
5
+ `)||"ACode \u6B63\u5728\u53D1\u9001 AI \u8BF7\u6C42",g=f.length>0?`${e}${f.join(`
6
+ `)}`:"";return`${T}${g}`}}export{we as AcodeSdkAdapter,Jt as isFailedAcodeTurnComplete,Ht as toAcodeEsmImportSpecifier};
7
7