aws-runtime-bridge 1.9.189 → 1.9.192

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 (47) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/dist/adapter/AcodeSdkAdapter.d.ts +13 -0
  3. package/dist/adapter/AcodeSdkAdapter.js +3 -3
  4. package/dist/config.d.ts +0 -31
  5. package/dist/config.js +2 -2
  6. package/dist/index.js +1 -1
  7. package/dist/routes/media-files.d.ts +19 -0
  8. package/dist/routes/media-files.js +2 -0
  9. package/dist/routes/plugin-ui.d.ts +17 -0
  10. package/dist/routes/plugin-ui.js +2 -0
  11. package/dist/routes/plugins.d.ts +3 -0
  12. package/dist/routes/plugins.js +1 -1
  13. package/dist/routes/terminal.d.ts +83 -0
  14. package/dist/routes/terminal.js +25 -25
  15. package/dist/scripts/migrate-user-scopes.js +1 -1
  16. package/dist/services/agent-capability-sync.js +1 -1
  17. package/dist/services/capability-config.d.ts +0 -1
  18. package/dist/services/capability-config.js +2 -2
  19. package/dist/services/instance-ai-config-service.js +1 -1
  20. package/dist/services/plugin-deployment.d.ts +2 -30
  21. package/dist/services/plugin-deployment.js +2 -2
  22. package/dist/services/plugin-handler-adapter.d.ts +10 -1
  23. package/dist/services/plugin-handler-adapter.js +2 -2
  24. package/dist/services/plugin-listener-runner.js +4 -4
  25. package/dist/services/plugin-loader.d.ts +7 -1
  26. package/dist/services/plugin-loader.js +1 -1
  27. package/dist/services/plugin-manager.d.ts +32 -12
  28. package/dist/services/plugin-manager.js +4 -4
  29. package/dist/services/plugin-manifest.d.ts +53 -3
  30. package/dist/services/plugin-manifest.js +1 -1
  31. package/dist/services/plugin-runtime.d.ts +8 -9
  32. package/dist/services/plugin-ui-status-runtime.d.ts +8 -0
  33. package/dist/services/plugin-ui-status-runtime.js +2 -0
  34. package/dist/services/plugin-ui-status.d.ts +96 -0
  35. package/dist/services/plugin-ui-status.js +2 -0
  36. package/dist/services/plugin-wecom-callback.d.ts +61 -0
  37. package/dist/services/plugin-wecom-callback.js +3 -0
  38. package/dist/services/user-scope.d.ts +1 -9
  39. package/dist/services/user-scope.js +1 -1
  40. package/package/acode/dist/plugin-types.d.ts +41 -1
  41. package/package/acode/dist/runtime.d.ts +17 -0
  42. package/package/acode/dist/runtime.js +20 -20
  43. package/package/aws-client-agent-mcp/dist/mcp-server.js +1 -1
  44. package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +15 -0
  45. package/package/aws-client-agent-mcp/dist/mcp-tools.js +35 -5
  46. package/package/aws-client-agent-mcp/dist/tool-groups.js +2 -2
  47. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,117 @@ files 白名单),供调度中心「查看本次更新内容」弹窗按 `##
5
5
  展示。发布新版本时须在仓库中先写好 `## v<version>` 段(prepack-guard 校验缺段
6
6
  即阻断发布);Bridge 自更新成功后的运行时追加仅作为包内缺段时的兜底。
7
7
 
8
+ ## v1.9.192
9
+
10
+ _发布日期:2026-11-07_
11
+
12
+ ### 插件前端配置通道与示例插件未配置引导(github-console)
13
+
14
+ - **awp 协议新增 `awp:get-config` / `awp:save-config`**:插件前端可在自己的面板里
15
+ 直接读取/保存 userConfig——宿主转发到既有插件配置端点(sensitive 字段不回显真实
16
+ 值,提交 "********" = 保留旧值;保存后 bridge 原子重载即时生效)。
17
+ - **示例插件 github-console 未配置语义收紧**:GITHUB_REPO 未配置且未显式开启
18
+ MOCK 时不再静默落 mock 数据——数据工具抛 `PLUGIN_NOT_CONFIGURED`(agent 调用
19
+ 收到配置指引),面板渲染配置引导页(表单直接保存生效),状态徽标返回
20
+ `unconfigured` 引导态而非错误刷屏;MOCK 不再默认开启(plugin.json 移除
21
+ default,GITHUB_REPO 变为 required)。顺带修复 simulate 工具引用不存在
22
+ 全局变量的既有 bug。
23
+ - **配置就绪判定以后端实际探测为准**:插件摘要 userConfig 的 value 下发口径
24
+ 修正为与工具执行一致(安装 JSON > bridge 进程环境变量兜底 > 清单 default)——
25
+ 此前只读安装 JSON,值配在 bridge 环境变量时前端误判「未配置」而弹配置表单;
26
+ 插件前端引导页改为先调状态工具探测(unconfigured 才显示),不再凭配置值猜测。
27
+ - **github-console 成为技能市场内置项**:服务端启动时把 classpath 内置包释放到
28
+ 市场包目录并登记 kind=plugin 系统档模板(幂等,管理员下架不复活;升级服务
29
+ 换包自动更新落地文件),所有租户在能力市场直接可见可装。
30
+
31
+ ### 重构:插件系统 v2 契约(无历史包袱,项目未上线不保留兼容层)
32
+
33
+ **清单契约加严**(plugin.json):
34
+
35
+ - `schemaVersion: 2` 必填——缺失/不支持的版本安装即失败并指引补字段;
36
+ - **未知字段一律拒绝**(清单顶层与 ui/ui.status/ui.view/userConfig 项/handler/
37
+ listener/transport 全部收严),安装时报出未知键名——拼错字段立刻暴露;
38
+ - 移除未实现声明:handler `type:"mcp"`、listener `delivery:"force"|"wake"`
39
+ (此前声明可用但执行时报错或静默降级 poll)。
40
+
41
+ **配置契约收口**:process handler 经 env、module handler 经 `ctx.config` 注入
42
+ userConfig 终值(优先级:安装 JSON > bridge 进程环境变量 > 清单 default);插件
43
+ 摘要 `userConfig[].source` 标注每键生效来源(json/env/default);插件 UI 通道
44
+ invoke 每次调用留审计日志。
45
+
46
+ **遗留层移除**(存储模型简化为两条路径:私有 `cache/{agentId}` 与用户部署区
47
+ `users/{t}/{u}/plugins/deployed/`):
48
+
49
+ - 删除 legacy 只读回退层(instance-template/plugins 及能力配置/AI 配置/技能源
50
+ 的同名回退)、`AWS_BRIDGE_DISABLE_LEGACY_FALLBACK`/`AWS_BRIDGE_LEGACY_SCOPE`
51
+ 两个环境开关、`users/_legacy/_legacy` 逃逸;
52
+ - 删除旧 `shared/` zip-bag 一次性迁移(`migrateLegacySharedIfNeeded`)、移除墓碑
53
+ 机制(部署清单成为唯一事实:移除即删条目)、`zipFile` 遗留字段与 re-export 垫片;
54
+ - 部署清单 `manifest.json` 升 **version 3**(旧版本文件按空部署集处理并 warn,
55
+ 重新部署即恢复);agent 归属未登记(owner.json 缺失)明确报错,不再静默回退。
56
+
57
+ **测试补齐**:新增 `routes/plugin-ui.test.ts`(invoke 白名单 403 / params 校验 /
58
+ assets 穿越与扩展名白名单 / base href 注入);manifest v2 严格契约与部署清单
59
+ v3 语义用例;全量 2100+ 用例通过。
60
+
61
+ ### 升级注意(无自动迁移)
62
+
63
+ - 旧版 plugin.json(无 `schemaVersion: 2`)的 zip 需补字段后重新上传;
64
+ - 旧格式部署清单(version<3)按空处理,模板插件请在全局配置/能力市场重新部署;
65
+ - 私有插件(`cache/{agentId}`)与 secrets 不受影响。
66
+
67
+ ## v1.9.191
68
+
69
+ _发布日期:2026-11-07_
70
+
71
+ ### 新增:生图/生视频工具集(media 工具组)与工作区媒体读写通道
72
+
73
+ Agent 现在具备按需媒体生成能力(生图 + 生视频同属一个默认收纳的工具组):
74
+
75
+ - **工具组 `media`**(`generate_image` / `generate_video` / `query_media_task`,
76
+ 默认收纳,`expand_tools` 展开后调用):生成结果按 agent 指定的 `savePath`
77
+ 直接写入实例工作区(不落服务端存储、不发用户);
78
+ - **工作区媒体读写端点**:`POST /runtime/media-write`(生成结果落盘,
79
+ base64 → 工作区相对路径,上限 200MB)与 `POST /runtime/media-read`
80
+ (参考图/视频首帧读取回传 base64,上限默认 20MB)——路径逃逸双端校验
81
+ (绝对路径/盘符/`..` 拒绝),鉴权与 file-diff-rollback 同款;
82
+ - **工具组声明**:`tool-groups.ts` 注册 `media`(featureKey `media`,collapsible,
83
+ defaultState collapsed),`mcp-tools.ts` 新增三个工具定义与 `MEDIA_TOOL_NAMES`。
84
+
85
+ 配套(服务端侧):生图走 OpenAI 兼容 `/v1/images/generations`;生视频走
86
+ 「提交 → 轮询 → 落盘」任务式协议,任务落 `t_media_job`,重启续轮询、绝不重提
87
+ (防重复扣费);实例级生图/生视频模型必选配置见实例编辑弹窗。
88
+
89
+ ## v1.9.190
90
+
91
+ _发布日期:2026-11-06_
92
+
93
+ ### 新增:插件前端入口(plugin.json ui 字段)—— 状态徽标 + 主前端视图
94
+
95
+ 插件现在可以声明两个 dashboard 前端入口(此前只能注入工具/监听器/斜杠命令):
96
+
97
+ - **会话行状态徽标**(`ui.status`):插件声明一个状态工具(如 `get_status`),
98
+ bridge 状态看护按 `pollIntervalMs`(默认 30s)调用并做内容指纹比对,仅变化时
99
+ 回调调度中心经 `PLUGIN_UI_STATUS_CHANGED` WS 广播到前端——徽标显示
100
+ `插件icon + metrics 计数`(如 GitHub 的 open issues / 待处理 PR);
101
+ `persistent: false`(默认)时状态有数据才显示,`true` 永驻。点击徽标可按状态
102
+ 工具返回的 `items[].route` 深链进插件主前端;
103
+ - **主前端视图**(`ui.view`):功能格(远程桌面/日志系统/…)追加插件声明的按钮,
104
+ 点击打开排队弹窗内嵌插件自带页面(iframe + `agentswork-plugin-ui:1` postMessage
105
+ 协议)。页面可经宿主转发调用 `ui.view.invoke` 白名单内的插件工具(写操作如
106
+ 评论/关闭/合并),白名单外一律被 bridge 拒绝;插件 icon 未声明时用默认拼图。
107
+
108
+ 配套链路:`/runtime/plugin-ui/snapshot`(批量状态快照对账)、
109
+ `/runtime/plugin-ui/:agentId/:name/invoke`(白名单工具调用)、
110
+ `/runtime/plugin-ui/.../assets/*`(插件静态资源托管,ui/ 子树 + 扩展名白名单 +
111
+ 路径穿越防护)。清单校验:`ui.status.tool` / `ui.view.invoke` 引用的工具必须
112
+ 真实存在于 tools 定义,入口文件必须存在,否则安装/重载即失败并给出明确错误。
113
+ 无 `ui` 声明的既有插件行为完全不变。
114
+
115
+ 新增 `examples/plugins/github-console`:完整 npm 工程示例(Vite + TS 前端 +
116
+ module handler 工具 + Mock/真实 GitHub REST 双模式 + 跨平台打包脚本),
117
+ README 即插件前端开发模板文档。
118
+
8
119
  ## v1.9.189
9
120
 
10
121
  _发布日期:2026-11-06_
@@ -48,6 +48,12 @@ type ACodeRuntimeInstance = {
48
48
 
49
49
  importTranscript?(transcript: unknown[]): Promise<number>;
50
50
 
51
+
52
+
53
+
54
+
55
+ appendResumeContextNotice?(): void;
56
+
51
57
  submitQuestionAnswer?(toolCallId: string, answers: Record<string, string>): boolean;
52
58
 
53
59
  cancelQuestionAnswer?(toolCallId: string, reason?: string): boolean;
@@ -328,9 +334,15 @@ export declare class AcodeSdkAdapter extends EventEmitter implements BaseProvide
328
334
 
329
335
 
330
336
 
337
+
338
+
331
339
  getTotalUsage(sessionId: string): {
332
340
  inputTokens?: number;
333
341
  outputTokens?: number;
342
+ contextLimit?: number;
343
+ maxOutput?: number;
344
+ inputLimit?: number;
345
+ compactionThreshold?: number;
334
346
  totalInputTokens?: number;
335
347
  totalOutputTokens?: number;
336
348
  cacheHitTokens?: number;
@@ -367,6 +379,7 @@ export declare class AcodeSdkAdapter extends EventEmitter implements BaseProvide
367
379
 
368
380
 
369
381
 
382
+
370
383
  private resolveAgentSkillsDir;
371
384
  applyAgentFeatures(agentId: string): Promise<void>;
372
385
 
@@ -1,7 +1,7 @@
1
- import{EventEmitter as at}from"node:events";import nt from"node:fs/promises";import H from"node:path";import{pathToFileURL as rt}from"node:url";import{deleteJournal as lt,isMcpGroupKey as ut,writeJournal as dt}from"@agentswork/acode";import{v4 as P}from"uuid";import{getBridgeInstancePluginsDir as ct,getBridgeInstanceSkillsDir as pt,getBridgeTemplateConfigFile as mt,getBridgeTemplateSkillsDir as ft}from"../config.js";import{getReleasedAcodeEntryPath as gt}from"../services/acode-package.js";import{syncAgentSkillFarm as K}from"../services/agent-capability-sync.js";import{getAgentOwner as ht}from"../services/agent-ownership.js";import{agentPtyManager as Tt}from"../services/agent-pty-manager.js";import{getBrowserTools as R,closeBrowserSession as At,registerListenerWakeHook as yt,unregisterListenerWakeHook as J}from"../services/browser-session-manager.js";import{getDesktopTools as M,getDesktopToolsIfReady as St}from"../services/desktop-mcp-manager.js";import{redactForLog as j}from"../services/instance-ai-config-service.js";import{BROWSER_FEATURE_KEY as x,DESKTOP_FEATURE_KEY as E,getAgentToolPermissions as bt,getFeatureState as U,isFeatureEnabled as _t,resolveAgentToolPermissions as Ct,resolveGroupFeatureKey as kt}from"../services/instance-features.js";import{resolveOpenDocEvent as wt}from"../services/open-doc-events.js";import{closeOpenDocument as Pt,clearOpenDocuments as Et,recordOpenDocument as It,removeOpenDocument as $t}from"../services/open-doc-registry.js";import{pluginManager as v}from"../services/plugin-manager.js";import{dumpInvalidProviderRequest as xt}from"../services/request-invalid-dump.js";import{buildRuntimeResourcesSnapshot as Lt}from"../services/runtime-resources-snapshot.js";import{subAgentManager as Ot}from"../services/sub-agent-manager-instance.js";import{getUserAiConfigFile as Dt,isLegacyFallbackDisabled as Mt}from"../services/user-scope.js";import{recordAgentFileChange as vt}from"../services/workspaceTaskChangeWatcher.js";import{loadDynamicModule as Rt}from"../utils/dynamic-import.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 N,isPollMessageToolDescriptor as Ut}from"./acode-tool-names.js";import{IdlePollLoop as Ft}from"./idle-poll-loop.js";import{resolveAcodeProviderConfig as Nt}from"./instance-ai-config-resolver.js";import{MESSAGE_POLLING_IDLE_PROMPT as Q}from"./prompts.js";import{getCanonicalMcpDetail as z,getToolActionInfo as qt}from"./types.js";const Bt=process.env.ACODE_COMPACTION_DEBUG==="1";function r(...d){Bt&&console.log(...d)}const Wt=process.env.ACODE_TOKEN_DEBUG==="1";function w(...d){Wt&&console.log("[TokenDebug][Adapter]",...d)}const Ht=Q,Kt=5e3;function I(d,t){const e=process.env[d];if(e===void 0||e.trim()==="")return t;const o=Number(e.trim());return Number.isFinite(o)&&o>=0?Math.floor(o):t}const G=I("ACODE_DATA_FLOW_WATCHDOG_MS",12e4),Jt=5*6e4,jt=I("ACODE_STUCK_AUTOPOLL_TIMEOUT_MS",5*6e4),V=I("ACODE_LIVENESS_POLL_INTERVAL_MS",15e3),q=I("ACODE_LIVENESS_STALL_TIMEOUT_MS",10*6e4),Qt=250,zt=1e3,Gt=I("ACODE_DEFERRED_IDLE_REARM_MS",3e3),Y=[2e3,3e3,1e4,4e4],X=4e3;function Vt(d){const t=String(d||"").trim();if(t)return t.length>X?`${t.slice(0,X)}\u2026(truncated)`:t}function Yt(d){const t=d.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 B={[x]:"browser_",[E]:"desktop_"};function Xt(d){if(!d||typeof d!="object")return;const t=d,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 Z=I("ACODE_SUBMIT_TIMEOUT_MS",12e4),tt=3e3,Zt=Q;function te(){return H.resolve(gt())}function ee(d){return rt(H.resolve(d)).href}const et=128e3,$={"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 oe(d){if(!d)return et;const t=d.toLowerCase().trim(),e=$[t];if(e)return e.contextLimit;const o=Object.keys($).filter(a=>t.startsWith(a)).sort((a,i)=>i.length-a.length),s=o[0]!==void 0?$[o[0]]:void 0;return s?s.contextLimit:et}const ot=4096;function se(d){if(!d)return ot;const t=d.toLowerCase().trim(),e=$[t];if(e)return e.maxOutput;const o=Object.keys($).filter(a=>t.startsWith(a)).sort((a,i)=>i.length-a.length),s=o[0]!==void 0?$[o[0]]:void 0;return s?s.maxOutput:ot}function st(d){if(!d||typeof d!="object")return;const t=d,e=A(t.inputTokens,t.input_tokens,t.promptTokens,t.prompt_tokens),o=A(t.outputTokens,t.output_tokens,t.completionTokens,t.completion_tokens);if(e===0&&o===0)return;let s=A(t.cacheHitTokens,t.promptCacheHitTokens,t.prompt_cache_hit_tokens),a=A(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 c=A(t.cache_read_input_tokens),l=A(t.cache_creation_input_tokens);if(c>0||l>0){const f=t.input_tokens!==void 0&&Number.isFinite(Number(t.input_tokens))&&Number(t.input_tokens)>=0?A(t.input_tokens):Math.max(0,e-c-l);s=c,a=l+f,i=!0}else s=A(t.cache_hit_tokens),a=A(t.cache_miss_tokens),i=i||t.cache_hit_tokens!==void 0||t.cache_miss_tokens!==void 0}if(s===0&&a===0){const c=A(t.prompt_tokens_details?.cached_tokens);c>0&&(s=c,a=e>c?e-c:0,i=!0)}const n=c=>{const l=Number(c);return Number.isFinite(l)&&l>=0?l:void 0},p=n(t.totalInputTokens??t.total_input_tokens),u=n(t.totalOutputTokens??t.total_output_tokens);return{inputTokens:e,outputTokens:o,...i?{cacheHitTokens:s,cacheMissTokens:a}:{},...i?{hasCache:!0}:{},...p!==void 0||u!==void 0?{totalInputTokens:p,totalOutputTokens:u}:{}}}function A(...d){for(const t of d){const e=Number(t);if(Number.isFinite(e)&&e>0)return e}return 0}function ie(d){return d==="stderr"||d==="mixed"?d:"stdout"}function L(d){const t=Number(d);return Number.isFinite(t)?t:0}function W(d){if(d==null)return;const t=Number(d);return Number.isFinite(t)?t:void 0}function ae(d){if(!d||typeof d!="object"||Array.isArray(d))return;const t={};for(const[e,o]of Object.entries(d))typeof o=="string"&&(t[e]=o);return Object.keys(t).length>0?t:void 0}function ne(d){return d.failed===!0}function it(d,t,e){if(!d)return e?`${t}/${e}`:t;const o=`${t}__`;return d.startsWith(o)?z(`${t}__${d.slice(o.length)}`):z(d.replace("/","__"))}function re(d){return d==="read_file"||d==="edit_file"||d==="write_file"||d==="bash"}function le(d){const t=ue(d);return t?[t.directMessages,t.groupMessages,t.messages].some(e=>Array.isArray(e)&&e.length>0):typeof d=="string"&&d.trim().length>0}function ue(d){if(d&&typeof d=="object"&&!Array.isArray(d))return d;if(!(typeof d!="string"||!d.trim()))try{const t=JSON.parse(d);return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}catch{return}}class O extends at{constructor(){super(),this.providerId="acode",this.displayName="ACode",this.sessions=new Map,this.expandedBuiltInCapabilities=new Map,this.builtInCapabilityToolCache=new Map,this.listenerWakeHooks=new Map,v.setOnPluginsChanged(t=>{this.syncPluginCommands(t)})}async syncPluginCommands(t){try{const e=await v.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)}}resolveAgentConfigPath(t,e){if(e)return e;const o=t?ht(t):null;return o?Dt(o):Mt()?"":mt()}async startSession(t,e){const o=this.resolveAgentConfigPath(e.agentId,e.mcpConfigPath),{resolved:s,configContextLimit:a,supportsImage:i}=await this.resolveAcodeProvider(e,o),n=s.model,p=a??oe(n),u=se(n),c={sessionId:t,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0,contextLimit:p,maxOutput:u,cacheHitTokens:e.resumeTokenUsage?.cacheHitTokens??0,cacheMissTokens:e.resumeTokenUsage?.cacheMissTokens??0,totalInputTokens:e.resumeTokenUsage?.totalInputTokens??0,totalOutputTokens:e.resumeTokenUsage?.totalOutputTokens??0}};this.sessions.set(t,{adapterSession:c,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 l=this.sessions.get(t);if(!l)throw new Error("ACode session was not initialized");this.startLivenessWatchdog(t,l);const m=()=>{const f=this.sessions.get(t);f&&(f.autoPollDelayMs=void 0,this.getIdlePollLoop(f).start())};this.listenerWakeHooks.set(t,m),yt(e.agentId,m);try{if(await l.runtime.start(),console.log(`[HIBERNATE-REPLAY] startSession: agentId=${e.agentId??"?"} resumeTranscript=${Array.isArray(l.config.resumeTranscript)?`${l.config.resumeTranscript.length}\u6761`:"\u65E0"} importTranscript\u652F\u6301=${typeof l.runtime.importTranscript=="function"}`),c.status="waiting_input",this.emit("status-change",t,"waiting_input",{usage:l.adapterSession.totalUsage}),l.config.resumeTranscript&&l.runtime.importTranscript)try{const f=await l.runtime.importTranscript(l.config.resumeTranscript);console.log(`[HIBERNATE-REPLAY] importTranscript \u5B8C\u6210: agentId=${e.agentId??"?"} \u91CD\u653E=${f}\u6761 conversation=${l.runtime.exportConversation?.().length??"?"}\u6761`),f>0&&l.adapterSession.messages.push({id:P(),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)}if(!l.hibernationReplayCardEmitted&&((l.config.resumeTranscript?.length??0)>0||l.config.resumeContext)){const h={actionType:"context_compaction",actionLabel:"\u4F11\u7720\u6062\u590D",actionDetail:l.config.resumeTranscript&&l.runtime.importTranscript?"\u4F11\u7720\u524D\u7684\u5BF9\u8BDD\u91CD\u653E\u672A\u5B8C\u6210\uFF0C\u5DF2\u6309\u8FDB\u5EA6\u6458\u8981\u63A5\u7EED\u4E0A\u4E0B\u6587":"\u5DF2\u6309\u4F11\u7720\u524D\u7684\u8FDB\u5EA6\u6458\u8981\u63A5\u7EED\u4E0A\u4E0B\u6587",actionId:`transcript-replay-fallback-${P()}`};l.hibernationReplayCardEmitted=!0,this.emit("status-change",t,c.status,h)}e.initialPrompt?.trim()?this.startInitialPromptTurn(t,e.initialPrompt):this.armIdleLoopOrAutoPoll(t)}catch(f){c.status="error",this.emitRuntimeErrorEvent(t,f),this.emit("status-change",t,"error");const h=this.sessions.get(t);throw h?.capabilitiesFallbackTimer&&clearTimeout(h.capabilitiesFallbackTimer),h&&this.stopLivenessWatchdog(h),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),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.retryEpoch+=1,s.turnModelRequestSucceeded=!1;const i={id:P(),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 p=Date.now()-n;this.cancelSubmitTimeoutDetection(s),r(`[ACode] \u2705 runtime.submit() completed in ${p}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 p=Date.now()-o;console.error(`[ACode] \u274C sendMessage FAILED after ${p}ms:`,n instanceof Error?n.message:String(n)),this.cancelSubmitTimeoutDetection(s),r("[ACode] \u25B6\uFE0F sendMessage failed, scheduling request retry..."),s.lastErrorText=n instanceof Error?n.message:String(n),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 cancelQuestionAnswer(t,e){const o=this.sessions.get(t);if(!o)return;const s=o.pendingQuestionToolCallId;if(!s){r(`[AcodeSdkAdapter] cancelQuestionAnswer: no pending question for session ${t}`);return}if(!o.runtime.cancelQuestionAnswer)throw new Error("ACode runtime does not support cancelling a question");const a=o.runtime.cancelQuestionAnswer(s,e);o.pendingQuestionToolCallId=void 0,o.pendingQuestions=void 0,r(`[AcodeSdkAdapter] cancelQuestionAnswer: session=${t}, toolCallId=${s}, settled=${a}, hasReason=${!!String(e||"").trim()}`),this.startSubmitTimeoutDetection(t,o,"cancelQuestionAnswer")}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.usageInputEstimated=!1,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){const e=this.requireSession(t);if(!e.runtime.compactContext)throw new Error("ACode runtime does not support manual context compaction");return e.runtime.compactContext()}async terminateSession(t,e){const o=this.sessions.get(t);if(!o)return;if(this.cancelScheduledAutoPoll(o),o.failedTurnRecoveryScheduled=!1,o.idlePollLoop?.stop(),this.stopLivenessWatchdog(o),this.cancelRequestRetry(o),o.capabilitiesFallbackTimer&&(clearTimeout(o.capabilitiesFallbackTimer),o.capabilitiesFallbackTimer=void 0),e?.discardContext){const a=o.config.agentId;a&&lt(a).catch(()=>{})}else e?.discardJournalFinalize||this.persistHibernationJournalSafe(o,t,"clean");await o.runtime.stop();const s=o.config.agentId;s&&(J(s,this.listenerWakeHooks.get(t)),At(s)),this.listenerWakeHooks.delete(t),o.adapterSession.status="terminated",this.sessions.delete(t),s&&![...this.sessions.values()].some(a=>a.config.agentId===s)&&(this.expandedBuiltInCapabilities.delete(s),this.builtInCapabilityToolCache.delete(s),Et(s)),this.emit("status-change",t,"terminated")}persistHibernationJournalSafe(t,e,o){const s=t.config.agentId;if(s)try{const a=this.exportRawTranscript(e);if(!a||a.length===0)return;const i=this.getTotalUsage(e);dt(s,{sessionId:e,reason:o,transcript:a,tokenUsage:{inputTokens:i?.inputTokens??null,outputTokens:i?.outputTokens??null,totalInputTokens:i?.totalInputTokens??null,totalOutputTokens:i?.totalOutputTokens??null,cacheHitTokens:i?.cacheHitTokens??null,cacheMissTokens:i?.cacheMissTokens??null}}).then(()=>{t.hibernationJournalLastSavedAt=Date.now()}).catch(n=>{console.warn(`[HIBERNATION-JOURNAL] write failed: agentId=${s} sessionId=${e}`,n instanceof Error?n.message:n)})}catch(a){console.warn(`[HIBERNATION-JOURNAL] export failed: agentId=${s} sessionId=${e}`,a instanceof Error?a.message:a)}}maybePersistHibernationJournalOnTurnComplete(t,e){const o=t.hibernationJournalLastSavedAt??0;Date.now()-o<O.HIBERNATION_JOURNAL_MIN_INTERVAL_MS||this.persistHibernationJournalSafe(t,e,"periodic")}maybePersistHibernationJournalOnTick(t,e){const o=t.adapterSession.status;if(o!=="thinking"&&o!=="tool_using"&&o!=="starting"&&o!=="compacting")return;const s=t.hibernationJournalLastSavedAt??0;Date.now()-s<O.HIBERNATION_JOURNAL_TICK_INTERVAL_MS||this.persistHibernationJournalSafe(t,e,"periodic")}getConversation(t){return this.sessions.get(t)?.adapterSession.messages??[]}trackOpenDocumentEvent(t,e,o,s){const a=t.config.agentId;if(a)try{const i=wt(e,o,s);if(!i)return;i.action==="open"?It(a,{kind:i.kind,docId:i.docId,name:i.name,...i.detail?{detail:i.detail}:{}}):i.action==="close"?Pt(a,i.kind):$t(a,i.kind,i.docId)}catch(i){r(`[acode-adapter] open doc registry update failed: ${i?.message}`)}}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}hasActiveBlockingToolCall(t){const e=this.sessions.get(t);return e?this.hasActiveBlockingToolCallEntry(e):!1}getTotalUsage(t){const e=this.sessions.get(t)?.adapterSession.totalUsage;if(e)return{inputTokens:e.inputTokens,outputTokens:e.outputTokens,totalInputTokens:e.totalInputTokens,totalOutputTokens:e.totalOutputTokens,cacheHitTokens:e.cacheHitTokens,cacheMissTokens:e.cacheMissTokens}}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=this.resolveAgentConfigPath(e.config.agentId,e.config.mcpConfigPath),{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 ft()}async applyAgentFeatures(t){if(!t)return;const e=this.shouldInjectCapabilityTools(t,E),o=this.shouldInjectCapabilityTools(t,x);for(const[a,i]of this.sessions){if(i.config.agentId!==t)continue;const n=i.runtime,p=e,u=o;try{if(p){const c=await M(t,await this.resolveAgentAiInfo(t)),l=n.addBuiltInTools?.(c)??0;l>0&&r(`[acode-adapter] session ${a}: ${l} desktop tools hot-added for agent ${t}`)}else{const c=n.removeBuiltInToolsByPrefix?.("desktop_")??0;c>0&&r(`[acode-adapter] session ${a}: ${c} desktop tools hot-removed for agent ${t}`)}}catch(c){r(`[acode-adapter] session ${a}: desktop feature hot-sync failed for agent ${t}:`,c.message)}if(u)try{const c=await R(t,i.config.scopeKey,typeof i.config.browserAllowPrivate=="boolean"?{allowPrivate:i.config.browserAllowPrivate}:void 0),l=n.addBuiltInTools?.(c)??0;l>0&&r(`[acode-adapter] session ${a}: ${l} browser tools hot-added for agent ${t}`)}catch(c){r(`[acode-adapter] session ${a}: browser feature hot-sync failed for agent ${t}:`,c.message)}else{const c=n.removeBuiltInToolsByPrefix?.("browser_")??0;c>0&&r(`[acode-adapter] session ${a}: ${c} 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 v.applyCapabilities(t)}catch(a){r(`[acode-adapter] plugin capability hot-sync failed for agent ${t}:`,a.message)}const s=Ct(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)}}}async debugMountMcpServer(t,e,o){if(!t)return{ok:!1,mounted:!1,sessions:0,tools:0,error:"agentId is required"};let s=0,a=0,i,n;for(const[p,u]of this.sessions)if(u.config.agentId===t&&typeof u.runtime.addMcpServer=="function")try{const c=await u.runtime.addMcpServer(e,o);s+=1,c.ok?(a=c.tools,i=c.toolNames):n=c.error}catch(c){n=c.message,r(`[acode-adapter] session ${p}: 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:a,toolNames:i,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(a){r(`[acode-adapter] debug unmount mcp ${e} failed for agent ${t}:`,a.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 B[String(t??"").trim()]}async loadCapabilityToolsForSession(t,e,o){const s=t===x?await R(e,o.config.scopeKey,typeof o.config.browserAllowPrivate=="boolean"?{allowPrivate:o.config.browserAllowPrivate}:void 0):await M(e,await this.resolveAgentAiInfo(e)),a=[];for(const i of s){const n=Xt(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[c,l]of i){const m=l.runtime.removeBuiltInToolsByPrefix?.(a)??0;u+=m,m>0&&r(`[acode-adapter] session ${c}: ${m} ${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,c]of i){let l;try{l=await this.loadCapabilityToolsForSession(e,s,c)}catch(m){throw r(`[acode-adapter] session ${u}: capability ${e} tool load failed for agent ${s}:`,m.message),m}for(const m of l)n.has(m.name)||n.set(m.name,m)}const p=this.expandedBuiltInCapabilities.get(s)??new Set;return p.add(e),this.expandedBuiltInCapabilities.set(s,p),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,{discardJournalFinalize:!0})}setIdleCommands(t,e){const o=this.sessions.get(t);if(o){if(o.idleCommands=e,this.cancelScheduledAutoPoll(o),e.idleInputCommand&&N(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 nt.readFile(t,"utf-8"),o=JSON.parse(e),a=o.provider?.default,i=a?.options,n=A(o.contextLimit),p={},u={},c=a?.models;if(c&&typeof c=="object"){for(const[l,m]of Object.entries(c))if(m&&typeof m=="object"){const f=A(m.contextLimit);f>0&&(p[l.trim()]=f);const h=m.modalities?.input,g=Array.isArray(h)&&h.includes("image")||m.supportsImageInput===!0;u[l.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(p).length>0?{modelContextLimits:p}:{},...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?j(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 p=Nt(a,i,"acode-default");return s.log({level:"info",category:"resolve",message:"resolveAcodeProvider \u89E3\u6790\u7ED3\u679C",source:"bridge",details:{instanceConfig:j(a),globalConfigModel:i?.model??null,resolvedModel:p.model,resolvedBaseURL:p.baseURL??null,resolvedApiKey:p.apiKey?"[set]":null,configContextLimit:n,resolvedSource:p.source}}),{resolved:p,configPath:e,perSessionModel:o,configContextLimit:n,supportsImage:i.modelImageSupport?.[p.model]===!0}}async createRuntime(t,e,o,s,a){const i=await this.loadRuntimeConstructor(),n=this.resolveAgentConfigPath(o.agentId,o.mcpConfigPath);let p=[];try{p=await R(o.agentId,o.scopeKey,typeof o.browserAllowPrivate=="boolean"?{allowPrivate:o.browserAllowPrivate}:void 0)}catch(m){r(`[acode-adapter] browser tools injection skipped for agent ${o.agentId}:`,m.message)}let u=[];if(this.shouldInjectCapabilityTools(o.agentId??"",x)&&(u=p),o.agentId&&this.shouldInjectCapabilityTools(o.agentId,E))try{const m=s?.model?{model:s.model,supportsImage:a===!0,...s.baseURL?{baseURL:s.baseURL}:{},...s.apiKey?{apiKey:s.apiKey}:{}}:void 0,f=await M(o.agentId,m);f.length>0&&(u=[...u,...f])}catch(m){r(`[acode-adapter] desktop tools injection skipped for agent ${o.agentId}:`,m.message)}const c=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,initialTokenUsage:o.resumeTokenUsage,env:o.envOverrides,subAgentManager:Ot,terminalManager:Tt,capabilityState:m=>ut(m)?"collapsed":U(o.agentId??"",kt(m)),capabilityToolRelay:o.agentId?{handlesGroup:m=>this.resolveCapabilityToolPrefix(m)!==void 0,handlesTool:m=>Object.values(B).some(f=>m.startsWith(f)),expand:async m=>(await this.setBuiltInCapabilityTools(o.agentId??"",m,"expand")).manifests??[],collapse:async m=>{await this.setBuiltInCapabilityTools(o.agentId??"",m,"collapse")},call:async(m,f)=>{const h=m.startsWith(B[E]??"desktop_")?E:x;return this.callBuiltInCapabilityTool(o.agentId??"",h,m,f)}}:void 0,pluginBridge:o.agentId?v.forAgent(o.agentId):void 0,runtimeResourcesProvider:o.agentId?()=>Lt(o.agentId):void 0,...o.subAgentModel?{subAgentModel:o.subAgentModel}:{},...o.subAgentEffort?{subAgentEffort:o.subAgentEffort}:{},...o.instanceAiConfig?.effort?{effort:o.instanceAiConfig.effort}:{},onFileChange:m=>vt({...m,agentId:o.agentId,workspacePath:o.workingDirectory}),extraBuiltInTools:u,...o.agentId?{toolPermissionPolicy:bt(o.agentId)??void 0}:{},subAgentSuiteTools:p,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}}),c.on("event",m=>this.forwardAcodeEvent(m)),c}buildSubAgentSuiteToolProvider(t){return async e=>{if(!t)return[];if(!_t(t,E))return[];if(e.length===0)return St(t);if(!e.some(a=>{const i=a.trim().replace(/[.*]+$/,"");return i==="desktop"||i.startsWith("desktop.")}))return[];const s=await this.resolveAgentAiInfo(t);return M(t,s)}}async loadRuntimeConstructor(){if(this.runtimeConstructor)return this.runtimeConstructor;const t=te(),e=await Rt(ee(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:P(),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:ie(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=A(o?.inputTokens),a=A(o?.outputTokens),i=A(o?.cacheHitTokens),n=A(o?.cacheMissTokens),p=!!(o&&(s>0||a>0));let u;p&&(s>0&&(e.adapterSession.totalUsage.inputTokens=s,e.usageInputEstimated=!1),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},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 l={actionType:"ai_request",actionLabel:"AI\u8BF7\u6C42",actionDetail:this.formatAiRequestActionDetail(t.data)};u&&(l.usage=u),w(`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,l),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:ae(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=st(t.data);o&&(o.inputTokens>0&&(e.adapterSession.totalUsage.inputTokens=o.inputTokens,e.usageInputEstimated=!1),e.adapterSession.totalUsage.outputTokens=o.outputTokens,o.hasCache&&(e.adapterSession.totalUsage.cacheHitTokens=o.cacheHitTokens,e.adapterSession.totalUsage.cacheMissTokens=o.cacheMissTokens),o.totalInputTokens!==void 0&&(e.adapterSession.totalUsage.totalInputTokens=o.totalInputTokens),o.totalOutputTokens!==void 0&&(e.adapterSession.totalUsage.totalOutputTokens=o.totalOutputTokens),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"){this.maybePersistHibernationJournalOnTurnComplete(e,t.sessionId);const o=st(t.data.usage);if(o){const a=e.adapterSession.totalUsage.inputTokens,n=typeof t.data.usageEstimated=="boolean"?t.data.usageEstimated===!0:a>0&&o.inputTokens<Math.floor(a*.2)&&!o.hasCache&&!e.usageInputEstimated;w(`turn_complete usage: raw=${JSON.stringify(t.data.usage)} parsed=${JSON.stringify(o)} currentInput=${a} threshold20pct=${Math.floor(a*.2)} isFallbackUsage=${n}`),n?o.outputTokens>0&&(e.adapterSession.totalUsage.outputTokens=o.outputTokens):(o.inputTokens>0&&(e.adapterSession.totalUsage.inputTokens=o.inputTokens,e.usageInputEstimated=!1),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})`)),o.totalInputTokens!==void 0&&(e.adapterSession.totalUsage.totalInputTokens=o.totalInputTokens),o.totalOutputTokens!==void 0&&(e.adapterSession.totalUsage.totalOutputTokens=o.totalOutputTokens),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}`),ne(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(y=>Ut(y))||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(y=>({name:String(y.name??""),source:String(y.source??""),description:String(y.description??"")})).filter(y=>y.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(y=>y.name)}),e.capabilitiesFallbackTimer&&clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=setTimeout(()=>{const y=e.cachedMcpCapabilities;if(!y)return;const _={...y,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 ${tt}ms)`,{sessionId:t.sessionId,mcpServers:y.mcpServers,mcpToolsCount:y.mcpTools?.length??0}),e.cachedMcpCapabilities=void 0,e.capabilitiesFallbackTimer=void 0},tt);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 T=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=${T}`),this.emitProviderEvent(t,"tool_batch_start",{batchId:g,batchToolCount:T,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 T={toolCount:L(t.data.toolCount),parallelism:L(t.data.parallelism),speedup:L(t.data.speedup),wallClockMs:L(t.data.wallClockMs),totalWaitMs:W(t.data.totalWaitMs),contentionCount:L(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=${T.speedup}x parallelism=${T.parallelism}x wall=${T.wallClockMs}ms contentions=${T.contentionCount} failures=${T.failureCount??"-"}`),this.emitProviderEvent(t,"tool_batch_metrics",{batchId:g,batchMetrics:T,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,p=qt(i,n);e.autoPollObservedAnyTool=!0,p.actionType==="idle"&&(e.autoPollObservedPollingTool=!0);const u=re(p.actionType)?p.actionDetail||it(void 0,s,a):it(p.actionDetail,s,a),c=typeof t.data.toolUseId=="string"?t.data.toolUseId:void 0,l=n?JSON.stringify(n,null,2):void 0,m=typeof t.data.batchId=="string"?t.data.batchId:void 0,f={toolName:u,rawToolName:i,actionType:p.actionType,actionLabel:p.actionLabel,actionDetail:u,...l?{actionInput:l}:{},...n?{toolInput:n}:{},...c?{toolUseId:c,actionId:c}:{},...m?{batchId:m,parentId:m}:{},metadata:{mcpServer:s}};if(t.data.action==="tool_result"){this.trackOpenDocumentEvent(e,i,n,t.data.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:P(),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:c,isError:t.data.failed===!0});const g=p.actionType==="idle"&&!le(t.data.result)?"waiting_input":"thinking";e.adapterSession.status=g,p.actionType==="idle"&&(e.idleToolActiveAt=void 0),k("tool_use_end",{sessionId:t.sessionId,actionType:p.actionType,tool:i,nextStatus:g,idleToolActiveAtAfter:e.idleToolActiveAt??null}),this.cancelDataFlowWatchdog(e),e.pendingToolEventData=void 0;const T=p.actionType==="idle";this.emit("status-change",t.sessionId,g,T||g==="thinking"?void 0:f);return}const h=p.actionType==="idle"?"waiting_input":"tool_using";e.adapterSession.status=h,p.actionType==="idle"&&(e.idleToolActiveAt=Date.now()),h==="tool_using"&&(this.resetDataFlowWatchdog(t.sessionId,e),e.pendingToolEventData={...f}),e.adapterSession.messages.push({id:P(),sessionId:t.sessionId,role:"tool_use",content:l??"",timestamp:t.timestamp,toolName:i,toolInput:n,toolUseId:c}),this.emitProviderEvent(t,"tool_use_start",f),this.emit("status-change",t.sessionId,h,f);return}if(t.type==="skill_status"){const s=(Array.isArray(t.data.skills)?t.data.skills:[]).map(l=>({name:String(l.name??""),description:typeof l.description=="string"?l.description:void 0,directory:typeof l.directory=="string"?l.directory:void 0})).filter(l=>l.name),a=typeof t.data.skillsDir=="string"?t.data.skillsDir:void 0,n=(Array.isArray(t.data.skillGroups)?t.data.skillGroups:[]).map(l=>{const m=Array.isArray(l.skills)?l.skills:[];return{dir:typeof l.dir=="string"?l.dir:"",exists:l.exists===!0,skills:m.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(l=>l.dir),p=e.cachedMcpCapabilities??e.lastMcpCapabilities,u=e.cachedMcpCapabilities!==void 0,c={kind:"combined",mcpServers:p?.mcpServers??[],mcpTools:p?.mcpTools??[],skills:s,skillsDir:a,skillGroups:n};this.emitProviderEvent(t,"runtime_capabilities",{capabilities:c,actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:JSON.stringify(c)}),e.lastCombinedCapabilities=c,r(`[cap-diag] Combined capabilities emitted ${u?"(startup merge)":"(runtime refresh)"}: ${(p?.mcpTools??[]).length} MCP tools, ${s.length} skills`,{sessionId:t.sessionId,mcpServers:p?.mcpServers??[],skillsDir:a}),e.capabilitiesFallbackTimer&&(clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=void 0),e.cachedMcpCapabilities=void 0;return}if(t.type==="compaction_summary"){const o=typeof t.data.text=="string"?t.data.text:"";o&&this.emitProviderEvent(t,"compaction_summary",{text:o});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"){w(`session_started estimate intentionally not displayed as context size: estimatedContextTokens=${t.data.estimatedContextTokens??"n/a"} (waiting for provider usage)`);const o=A(t.data.contextLimit)||void 0,s=A(t.data.maxOutput)||void 0,a=A(t.data.inputLimit)||void 0,i=A(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",p=o.parentId,u=o.compactionId;if(o.trigger==="hibernation_replay"){e.hibernationReplayCardEmitted=!0;const h=typeof o.replayedMessageCount=="number"?o.replayedMessageCount:void 0,g=o.estimatedTokens;typeof g=="number"&&g>0&&(e.adapterSession.totalUsage.inputTokens=g,e.usageInputEstimated=!0);const T={actionType:"context_compaction",actionLabel:"\u4F11\u7720\u6062\u590D",actionDetail:h?`\u5DF2\u91CD\u653E\u4F11\u7720\u524D\u7684 ${h} \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",T),this.emit("status-change",t.sessionId,e.adapterSession.status,T);return}let l,m;if(a){const h=String(o.sizeKB??o.sizeBeforeKB??"?"),g=String(o.messageCount??o.messageCountBefore??"?"),T=o.estimatedTokens,S=o.actualInputTokens?`input=${o.actualInputTokens}`:"",b=o.actualOutputTokens?`output=${o.actualOutputTokens}`:"",C=o.trigger;l="\u4E0A\u4E0B\u6587\u538B\u7F29\u5F00\u59CB";const y=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,_=y?`, \u89E6\u53D1: ${y}`:"";T!==void 0?m=`\u538B\u7F29\u524D: ~${T} tokens, \u6D88\u606F: ${g}\u6761`+(S?`, \u5B9E\u9645 tokens: ${S} ${b}`:"")+_:m=`\u538B\u7F29\u524D: ${h}KB, \u6D88\u606F: ${g}\u6761`+(S?`, \u5B9E\u9645 tokens: ${S} ${b}`:"")+_}else if(n){const h=String(o.phase??""),g=String(o.phaseLabel??"\u538B\u7F29\u9636\u6BB5"),T=String(o.phaseDetail??"");h==="detect"?(l="\u5F00\u59CB\u89E6\u53D1\u54CD\u5E94\u5F0F\u538B\u7F29",m=T||"\u68C0\u6D4B\u5230\u4E0A\u4E0B\u6587\u8D85\u9650\uFF0C\u5373\u5C06\u5F00\u59CB\u538B\u7F29..."):(l=g,m=T)}else{const h=o.tokensBefore,g=o.tokensAfter,T=o.freedTokens,S=String(o.sizeBeforeKB??"?"),b=String(o.sizeAfterKB??"?"),C=String(o.freedKB??"?"),y=String(o.strategy??"?"),_=Number(o.prunedToolMessages??0),D=Number(o.summarizedMessages??0);l="\u538B\u7F29\u5B8C\u6210",h!==void 0&&g!==void 0?m=`\u91CA\u653E: ${T??h-g} tokens, ${h} tokens \u2192 ${g} tokens, \u7B56\u7565: ${y}`+(_?`, \u88C1\u526A\u5DE5\u5177: ${_}\u6761`:"")+(D?`, \u6458\u8981\u5316: ${D}\u6761`:""):m=`\u91CA\u653E: ${C}KB, ${S}KB \u2192 ${b}KB, \u7B56\u7565: ${y}`+(_?`, \u88C1\u526A\u5DE5\u5177: ${_}\u6761`:"")+(D?`, \u6458\u8981\u5316: ${D}\u6761`:"")}a&&(e.adapterSession.status="compacting");const f={actionType:"context_compaction",actionLabel:l,actionDetail:m};if(a&&u)f.actionId=u;else if((n||i)&&u)if(f.parentId=u,n){const h=String(o.phase??"unknown");f.actionId=`${u}-phase-${h}`}else f.actionId=`${u}-end`;if(n&&p&&!f.parentId&&(f.parentId=p),i){const h=A(o.contextTokensAfter)||A(o.tokensAfter);e.adapterSession.totalUsage.inputTokens=A(h),e.adapterSession.totalUsage.outputTokens=0,e.usageInputEstimated=!1,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,Gt)}getIdlePollLoop(t){if(t.idlePollLoop)return t.idlePollLoop;const e=t.adapterSession.sessionId;return t.idlePollLoop=new Ft({getStatus:()=>this.sessions.get(e)?.adapterSession.status,getCommand:()=>this.sessions.get(e)?.idleCommands?.idleInputCommand,isPollingCommand:o=>N(o),preDispatchHook:()=>null,dispatchPollingPrompt:(o,s)=>this.submitAutoPollPrompt(e,s?o:Zt,{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=>{const n=this.sessions.get(t);n&&(n.lastErrorText=i instanceof Error?i.message:String(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??Qt;e===void 0&&(o.autoPollDelayMs=Math.min(s*2,zt)),o.autoPollTimer=setTimeout(()=>{const a=this.sessions.get(t);!a||a.autoPollActive||this.isTerminalStatus(a.adapterSession.status)||(a.autoPollTimer=void 0,this.submitAutoPollPrompt(t,Ht,{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)||o.retryActive||o.retryTimer)return;if(!o.lastSubmittedPrompt){o.adapterSession.status="error",this.emit("status-change",t,"error");return}o.turnModelRequestSucceeded&&o.turnModelRequestSucceededEpoch===o.retryEpoch&&(o.turnModelRequestSucceeded=!1,o.retryAttempt=0),o.lastErrorText&&Yt(o.lastErrorText)&&xt({sessionId:t,agentId:o.config.agentId,model:o.config.model,attempt:Math.max(1,o.retryAttempt+1),errorText:o.lastErrorText,conversation:this.exportRawTranscript(t),extra:{reason:e,status:o.adapterSession.status}}),o.retryAttempt+=1,o.retryActive=!0,this.cancelScheduledAutoPoll(o),o.idlePollLoop?.stop();const s=Y[Math.min(o.retryAttempt-1,Y.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:Vt(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,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&&N(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.hasActiveBlockingToolCallEntry(s)&&i-s.autoPollLastActivityAt>=jt){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>=Jt){const c=String(s.pendingToolEventData?.rawToolName??"");if((s.pendingToolAuthRequests?.size??0)>0){const l=s.pendingToolAuthRequests?.size??0;console.warn(`[ACode] tool_using elapsed ${Math.round(u/1e3)}s but ${l} tool permission request(s) awaiting user decision (session: ${t}), skipping recovery`),s.watchdogSubmitStartTime=i,s.watchdogLastDataFlowTime=i;return}if(c.endsWith("await_complete")){console.warn(`[ACode] tool_using elapsed ${Math.round(u/1e3)}s but await_complete is running (session: ${t}, tool: ${c}), 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 ${c} 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),p=i-(s.watchdogLastDataFlowTime||i);if(G>0&&p>=G){console.warn(`[ACode] CRITICAL: Data flow watchdog triggered after ${Math.round(p/1e3)}s (source: ${o}, session: ${t}, status: ${a}). No stream data received. Forcing recovery via recoverTurnFailure.`),this.executeWatchdogRecovery(t,s,o,"data_flow",p);return}if(Z>0&&n>=Z){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}},Kt)}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(),!(q<=0)&&(e.livenessTimer=setInterval(()=>{const o=this.sessions.get(t);if(!o){this.stopLivenessWatchdog(e);return}this.checkSessionLiveness(t,o)},V),k("liveness_watchdog_arm",{sessionId:t,stallTimeoutMs:q,pollIntervalMs:V}))}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(this.maybePersistHibernationJournalOnTick(e,t),e.adapterSession.status!=="waiting_input"||e.autoPollActive||e.idleListeningIntentionallyStopped||e.pendingQuestionToolCallId||(e.pendingToolAuthRequests?.size??0)>0||this.hasActiveBlockingToolCallEntry(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<q)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`)}hasActiveBlockingToolCallEntry(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 at}from"node:events";import nt from"node:fs/promises";import H from"node:path";import{pathToFileURL as rt}from"node:url";import{deleteJournal as lt,isMcpGroupKey as ut,writeJournal as dt}from"@agentswork/acode";import{v4 as P}from"uuid";import{getBridgeInstancePluginsDir as ct,getBridgeInstanceSkillsDir as pt}from"../config.js";import{getReleasedAcodeEntryPath as mt}from"../services/acode-package.js";import{syncAgentSkillFarm as J}from"../services/agent-capability-sync.js";import{getAgentOwner as ft}from"../services/agent-ownership.js";import{agentPtyManager as gt}from"../services/agent-pty-manager.js";import{getBrowserTools as R,closeBrowserSession as ht,registerListenerWakeHook as Tt,unregisterListenerWakeHook as K}from"../services/browser-session-manager.js";import{getDesktopTools as M,getDesktopToolsIfReady as At}from"../services/desktop-mcp-manager.js";import{redactForLog as j}from"../services/instance-ai-config-service.js";import{BROWSER_FEATURE_KEY as x,DESKTOP_FEATURE_KEY as E,getAgentToolPermissions as St,getFeatureState as U,isFeatureEnabled as yt,resolveAgentToolPermissions as bt,resolveGroupFeatureKey as _t}from"../services/instance-features.js";import{resolveOpenDocEvent as Ct}from"../services/open-doc-events.js";import{closeOpenDocument as kt,clearOpenDocuments as wt,recordOpenDocument as Pt,removeOpenDocument as Et}from"../services/open-doc-registry.js";import{pluginManager as v}from"../services/plugin-manager.js";import{dumpInvalidProviderRequest as It}from"../services/request-invalid-dump.js";import{buildRuntimeResourcesSnapshot as $t}from"../services/runtime-resources-snapshot.js";import{subAgentManager as xt}from"../services/sub-agent-manager-instance.js";import{getUserAiConfigFile as Lt}from"../services/user-scope.js";import{recordAgentFileChange as Ot}from"../services/workspaceTaskChangeWatcher.js";import{loadDynamicModule as Dt}from"../utils/dynamic-import.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 N,isPollMessageToolDescriptor as Mt}from"./acode-tool-names.js";import{IdlePollLoop as vt}from"./idle-poll-loop.js";import{resolveAcodeProviderConfig as Rt}from"./instance-ai-config-resolver.js";import{MESSAGE_POLLING_IDLE_PROMPT as Q}from"./prompts.js";import{getCanonicalMcpDetail as z,getToolActionInfo as Ut}from"./types.js";const Ft=process.env.ACODE_COMPACTION_DEBUG==="1";function l(...d){Ft&&console.log(...d)}const Nt=process.env.ACODE_TOKEN_DEBUG==="1";function w(...d){Nt&&console.log("[TokenDebug][Adapter]",...d)}const qt=Q,Bt=5e3;function I(d,t){const e=process.env[d];if(e===void 0||e.trim()==="")return t;const o=Number(e.trim());return Number.isFinite(o)&&o>=0?Math.floor(o):t}const G=I("ACODE_DATA_FLOW_WATCHDOG_MS",12e4),Wt=5*6e4,Ht=I("ACODE_STUCK_AUTOPOLL_TIMEOUT_MS",5*6e4),V=I("ACODE_LIVENESS_POLL_INTERVAL_MS",15e3),q=I("ACODE_LIVENESS_STALL_TIMEOUT_MS",10*6e4),Jt=250,Kt=1e3,jt=I("ACODE_DEFERRED_IDLE_REARM_MS",3e3),Y=[2e3,3e3,1e4,4e4],X=4e3;function Qt(d){const t=String(d||"").trim();if(t)return t.length>X?`${t.slice(0,X)}\u2026(truncated)`:t}function zt(d){const t=d.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 B={[x]:"browser_",[E]:"desktop_"};function Gt(d){if(!d||typeof d!="object")return;const t=d,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 Z=I("ACODE_SUBMIT_TIMEOUT_MS",12e4),tt=3e3,Vt=Q;function Yt(){return H.resolve(mt())}function Xt(d){return rt(H.resolve(d)).href}const et=128e3,$={"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 Zt(d){if(!d)return et;const t=d.toLowerCase().trim(),e=$[t];if(e)return e.contextLimit;const o=Object.keys($).filter(a=>t.startsWith(a)).sort((a,i)=>i.length-a.length),s=o[0]!==void 0?$[o[0]]:void 0;return s?s.contextLimit:et}const ot=4096;function te(d){if(!d)return ot;const t=d.toLowerCase().trim(),e=$[t];if(e)return e.maxOutput;const o=Object.keys($).filter(a=>t.startsWith(a)).sort((a,i)=>i.length-a.length),s=o[0]!==void 0?$[o[0]]:void 0;return s?s.maxOutput:ot}function st(d){if(!d||typeof d!="object")return;const t=d,e=A(t.inputTokens,t.input_tokens,t.promptTokens,t.prompt_tokens),o=A(t.outputTokens,t.output_tokens,t.completionTokens,t.completion_tokens);if(e===0&&o===0)return;let s=A(t.cacheHitTokens,t.promptCacheHitTokens,t.prompt_cache_hit_tokens),a=A(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 c=A(t.cache_read_input_tokens),r=A(t.cache_creation_input_tokens);if(c>0||r>0){const f=t.input_tokens!==void 0&&Number.isFinite(Number(t.input_tokens))&&Number(t.input_tokens)>=0?A(t.input_tokens):Math.max(0,e-c-r);s=c,a=r+f,i=!0}else s=A(t.cache_hit_tokens),a=A(t.cache_miss_tokens),i=i||t.cache_hit_tokens!==void 0||t.cache_miss_tokens!==void 0}if(s===0&&a===0){const c=A(t.prompt_tokens_details?.cached_tokens);c>0&&(s=c,a=e>c?e-c:0,i=!0)}const n=c=>{const r=Number(c);return Number.isFinite(r)&&r>=0?r:void 0},p=n(t.totalInputTokens??t.total_input_tokens),u=n(t.totalOutputTokens??t.total_output_tokens);return{inputTokens:e,outputTokens:o,...i?{cacheHitTokens:s,cacheMissTokens:a}:{},...i?{hasCache:!0}:{},...p!==void 0||u!==void 0?{totalInputTokens:p,totalOutputTokens:u}:{}}}function A(...d){for(const t of d){const e=Number(t);if(Number.isFinite(e)&&e>0)return e}return 0}function ee(d){return d==="stderr"||d==="mixed"?d:"stdout"}function L(d){const t=Number(d);return Number.isFinite(t)?t:0}function W(d){if(d==null)return;const t=Number(d);return Number.isFinite(t)?t:void 0}function oe(d){if(!d||typeof d!="object"||Array.isArray(d))return;const t={};for(const[e,o]of Object.entries(d))typeof o=="string"&&(t[e]=o);return Object.keys(t).length>0?t:void 0}function se(d){return d.failed===!0}function it(d,t,e){if(!d)return e?`${t}/${e}`:t;const o=`${t}__`;return d.startsWith(o)?z(`${t}__${d.slice(o.length)}`):z(d.replace("/","__"))}function ie(d){return d==="read_file"||d==="edit_file"||d==="write_file"||d==="bash"}function ae(d){const t=ne(d);return t?[t.directMessages,t.groupMessages,t.messages].some(e=>Array.isArray(e)&&e.length>0):typeof d=="string"&&d.trim().length>0}function ne(d){if(d&&typeof d=="object"&&!Array.isArray(d))return d;if(!(typeof d!="string"||!d.trim()))try{const t=JSON.parse(d);return t&&typeof t=="object"&&!Array.isArray(t)?t:void 0}catch{return}}class O extends at{constructor(){super(),this.providerId="acode",this.displayName="ACode",this.sessions=new Map,this.expandedBuiltInCapabilities=new Map,this.builtInCapabilityToolCache=new Map,this.listenerWakeHooks=new Map,v.setOnPluginsChanged(t=>{this.syncPluginCommands(t)})}async syncPluginCommands(t){try{const e=await v.getPluginCommands(t);for(const o of this.sessions.values())o.config.agentId===t&&(o.runtime.addPluginCommands?.(e),o.runtime.syncPluginGroups?.())}catch(e){l(`[acode-adapter] syncPluginCommands failed for agent ${t}:`,e.message)}}resolveAgentConfigPath(t,e){if(e)return e;const o=t?ft(t):null;return o?Lt(o):""}async startSession(t,e){const o=this.resolveAgentConfigPath(e.agentId,e.mcpConfigPath),{resolved:s,configContextLimit:a,supportsImage:i}=await this.resolveAcodeProvider(e,o),n=s.model,p=a??Zt(n),u=te(n),c={sessionId:t,status:"starting",messages:[],createdAt:new Date().toISOString(),totalUsage:{inputTokens:0,outputTokens:0,contextLimit:p,maxOutput:u,cacheHitTokens:e.resumeTokenUsage?.cacheHitTokens??0,cacheMissTokens:e.resumeTokenUsage?.cacheMissTokens??0,totalInputTokens:e.resumeTokenUsage?.totalInputTokens??0,totalOutputTokens:e.resumeTokenUsage?.totalOutputTokens??0}};this.sessions.set(t,{adapterSession:c,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 r=this.sessions.get(t);if(!r)throw new Error("ACode session was not initialized");this.startLivenessWatchdog(t,r);const m=()=>{const f=this.sessions.get(t);f&&(f.autoPollDelayMs=void 0,this.getIdlePollLoop(f).start())};this.listenerWakeHooks.set(t,m),Tt(e.agentId,m);try{await r.runtime.start(),console.log(`[HIBERNATE-REPLAY] startSession: agentId=${e.agentId??"?"} resumeTranscript=${Array.isArray(r.config.resumeTranscript)?`${r.config.resumeTranscript.length}\u6761`:"\u65E0"} importTranscript\u652F\u6301=${typeof r.runtime.importTranscript=="function"}`),c.status="waiting_input",this.emit("status-change",t,"waiting_input",{usage:r.adapterSession.totalUsage});let f=0;if(r.config.resumeTranscript&&r.runtime.importTranscript)try{f=await r.runtime.importTranscript(r.config.resumeTranscript),console.log(`[HIBERNATE-REPLAY] importTranscript \u5B8C\u6210: agentId=${e.agentId??"?"} \u91CD\u653E=${f}\u6761 conversation=${r.runtime.exportConversation?.().length??"?"}\u6761`),f>0&&r.adapterSession.messages.push({id:P(),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(h){console.error(`[HIBERNATE-REPLAY] importTranscript \u5931\u8D25\uFF08\u964D\u7EA7\u4E3A\u6458\u8981\u901A\u9053\uFF09: agentId=${e.agentId??"?"}`,h instanceof Error?h.stack:h)}if(!r.hibernationReplayCardEmitted&&((r.config.resumeTranscript?.length??0)>0||r.config.resumeContext)){const g={actionType:"context_compaction",actionLabel:"\u4F11\u7720\u6062\u590D",actionDetail:r.config.resumeTranscript&&r.runtime.importTranscript?"\u4F11\u7720\u524D\u7684\u5BF9\u8BDD\u91CD\u653E\u672A\u5B8C\u6210\uFF0C\u5DF2\u6309\u8FDB\u5EA6\u6458\u8981\u63A5\u7EED\u4E0A\u4E0B\u6587":"\u5DF2\u6309\u4F11\u7720\u524D\u7684\u8FDB\u5EA6\u6458\u8981\u63A5\u7EED\u4E0A\u4E0B\u6587",actionId:`transcript-replay-fallback-${P()}`};r.hibernationReplayCardEmitted=!0,this.emit("status-change",t,c.status,g)}f===0&&r.runtime.appendResumeContextNotice?.(),e.initialPrompt?.trim()?this.startInitialPromptTurn(t,e.initialPrompt):this.armIdleLoopOrAutoPoll(t)}catch(f){c.status="error",this.emitRuntimeErrorEvent(t,f),this.emit("status-change",t,"error");const h=this.sessions.get(t);throw h?.capabilitiesFallbackTimer&&clearTimeout(h.capabilitiesFallbackTimer),h&&this.stopLivenessWatchdog(h),this.sessions.delete(t),K(e.agentId,this.listenerWakeHooks.get(t)),this.listenerWakeHooks.delete(t),f}}async sendMessage(t,e){const o=Date.now();l("[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"),l("[ACode] \u25B6\uFE0F sendMessage STARTED"),l(`[ACode] Session: ${t}`),l(`[ACode] Message: ${e.slice(0,100)}${e.length>100?"...":""}`),l("[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;l(`[ACode] Previous status: ${a}`),this.cancelScheduledAutoPoll(s),s.failedTurnRecoveryScheduled=!1,s.idlePollLoop?.stop(),s.idleListeningIntentionallyStopped=!1,this.cancelRequestRetry(s),s.retryAttempt=0,s.retryEpoch+=1,s.turnModelRequestSucceeded=!1;const i={id:P(),sessionId:t,role:"user",content:e,timestamp:new Date().toISOString()};s.adapterSession.messages.push(i),this.emit("conversation-message",t,i),l(`[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{l("[ACode] \u25B6\uFE0F Calling runtime.submit()...");const n=Date.now();await s.runtime.submit(e);const p=Date.now()-n;this.cancelSubmitTimeoutDetection(s),l(`[ACode] \u2705 runtime.submit() completed in ${p}ms`),l(`[ACode] Current status after submit: ${s.adapterSession.status}`),l("[ACode] \u25B6\uFE0F Calling recoverResolvedTurnWithoutTerminalEvent()..."),this.recoverResolvedTurnWithoutTerminalEvent(t),l(`[ACode] Status after recovery: ${s.adapterSession.status}`);const u=Date.now()-o;l("[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"),l(`[ACode] \u2705 sendMessage COMPLETED in ${u}ms`),l("[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 p=Date.now()-o;console.error(`[ACode] \u274C sendMessage FAILED after ${p}ms:`,n instanceof Error?n.message:String(n)),this.cancelSubmitTimeoutDetection(s),l("[ACode] \u25B6\uFE0F sendMessage failed, scheduling request retry..."),s.lastErrorText=n instanceof Error?n.message:String(n),this.emitRuntimeErrorEvent(t,n),this.scheduleRequestRetry(t,"sendMessage"),l(`[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){l(`[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 cancelQuestionAnswer(t,e){const o=this.sessions.get(t);if(!o)return;const s=o.pendingQuestionToolCallId;if(!s){l(`[AcodeSdkAdapter] cancelQuestionAnswer: no pending question for session ${t}`);return}if(!o.runtime.cancelQuestionAnswer)throw new Error("ACode runtime does not support cancelling a question");const a=o.runtime.cancelQuestionAnswer(s,e);o.pendingQuestionToolCallId=void 0,o.pendingQuestions=void 0,l(`[AcodeSdkAdapter] cancelQuestionAnswer: session=${t}, toolCallId=${s}, settled=${a}, hasReason=${!!String(e||"").trim()}`),this.startSubmitTimeoutDetection(t,o,"cancelQuestionAnswer")}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.usageInputEstimated=!1,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){const e=this.requireSession(t);if(!e.runtime.compactContext)throw new Error("ACode runtime does not support manual context compaction");return e.runtime.compactContext()}async terminateSession(t,e){const o=this.sessions.get(t);if(!o)return;if(this.cancelScheduledAutoPoll(o),o.failedTurnRecoveryScheduled=!1,o.idlePollLoop?.stop(),this.stopLivenessWatchdog(o),this.cancelRequestRetry(o),o.capabilitiesFallbackTimer&&(clearTimeout(o.capabilitiesFallbackTimer),o.capabilitiesFallbackTimer=void 0),e?.discardContext){o.hibernationJournalDiscarded=!0;const a=o.config.agentId;a&&lt(a).catch(()=>{})}else e?.discardJournalFinalize||this.persistHibernationJournalSafe(o,t,"clean");await o.runtime.stop();const s=o.config.agentId;s&&(K(s,this.listenerWakeHooks.get(t)),ht(s)),this.listenerWakeHooks.delete(t),o.adapterSession.status="terminated",this.sessions.delete(t),s&&![...this.sessions.values()].some(a=>a.config.agentId===s)&&(this.expandedBuiltInCapabilities.delete(s),this.builtInCapabilityToolCache.delete(s),wt(s)),this.emit("status-change",t,"terminated")}persistHibernationJournalSafe(t,e,o){if(t.hibernationJournalDiscarded)return;const s=t.config.agentId;if(s)try{const a=this.exportRawTranscript(e);if(!a||a.length===0)return;const i=this.getTotalUsage(e);dt(s,{sessionId:e,reason:o,transcript:a,tokenUsage:{inputTokens:i?.inputTokens??null,outputTokens:i?.outputTokens??null,totalInputTokens:i?.totalInputTokens??null,totalOutputTokens:i?.totalOutputTokens??null,cacheHitTokens:i?.cacheHitTokens??null,cacheMissTokens:i?.cacheMissTokens??null}}).then(()=>{t.hibernationJournalLastSavedAt=Date.now()}).catch(n=>{console.warn(`[HIBERNATION-JOURNAL] write failed: agentId=${s} sessionId=${e}`,n instanceof Error?n.message:n)})}catch(a){console.warn(`[HIBERNATION-JOURNAL] export failed: agentId=${s} sessionId=${e}`,a instanceof Error?a.message:a)}}maybePersistHibernationJournalOnTurnComplete(t,e){const o=t.hibernationJournalLastSavedAt??0;Date.now()-o<O.HIBERNATION_JOURNAL_MIN_INTERVAL_MS||this.persistHibernationJournalSafe(t,e,"periodic")}maybePersistHibernationJournalOnTick(t,e){const o=t.adapterSession.status;if(o!=="thinking"&&o!=="tool_using"&&o!=="starting"&&o!=="compacting")return;const s=t.hibernationJournalLastSavedAt??0;Date.now()-s<O.HIBERNATION_JOURNAL_TICK_INTERVAL_MS||this.persistHibernationJournalSafe(t,e,"periodic")}getConversation(t){return this.sessions.get(t)?.adapterSession.messages??[]}trackOpenDocumentEvent(t,e,o,s){const a=t.config.agentId;if(a)try{const i=Ct(e,o,s);if(!i)return;i.action==="open"?Pt(a,{kind:i.kind,docId:i.docId,name:i.name,...i.detail?{detail:i.detail}:{}}):i.action==="close"?kt(a,i.kind):Et(a,i.kind,i.docId)}catch(i){l(`[acode-adapter] open doc registry update failed: ${i?.message}`)}}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}hasActiveBlockingToolCall(t){const e=this.sessions.get(t);return e?this.hasActiveBlockingToolCallEntry(e):!1}getTotalUsage(t){const e=this.sessions.get(t)?.adapterSession.totalUsage;if(e)return{inputTokens:e.inputTokens,outputTokens:e.outputTokens,contextLimit:e.contextLimit,maxOutput:e.maxOutput,inputLimit:e.inputLimit,compactionThreshold:e.compactionThreshold,totalInputTokens:e.totalInputTokens,totalOutputTokens:e.totalOutputTokens,cacheHitTokens:e.cacheHitTokens,cacheMissTokens:e.cacheMissTokens}}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=this.resolveAgentConfigPath(e.config.agentId,e.config.mcpConfigPath),{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)return"";try{const e=J(t);if(e)return e}catch(e){l(`[acode-adapter] skill farm sync failed for agent ${t}:`,e.message)}return pt(t)}async applyAgentFeatures(t){if(!t)return;const e=this.shouldInjectCapabilityTools(t,E),o=this.shouldInjectCapabilityTools(t,x);for(const[a,i]of this.sessions){if(i.config.agentId!==t)continue;const n=i.runtime,p=e,u=o;try{if(p){const c=await M(t,await this.resolveAgentAiInfo(t)),r=n.addBuiltInTools?.(c)??0;r>0&&l(`[acode-adapter] session ${a}: ${r} desktop tools hot-added for agent ${t}`)}else{const c=n.removeBuiltInToolsByPrefix?.("desktop_")??0;c>0&&l(`[acode-adapter] session ${a}: ${c} desktop tools hot-removed for agent ${t}`)}}catch(c){l(`[acode-adapter] session ${a}: desktop feature hot-sync failed for agent ${t}:`,c.message)}if(u)try{const c=await R(t,i.config.scopeKey,typeof i.config.browserAllowPrivate=="boolean"?{allowPrivate:i.config.browserAllowPrivate}:void 0),r=n.addBuiltInTools?.(c)??0;r>0&&l(`[acode-adapter] session ${a}: ${r} browser tools hot-added for agent ${t}`)}catch(c){l(`[acode-adapter] session ${a}: browser feature hot-sync failed for agent ${t}:`,c.message)}else{const c=n.removeBuiltInToolsByPrefix?.("browser_")??0;c>0&&l(`[acode-adapter] session ${a}: ${c} browser tools hot-removed for agent ${t}`)}}this.syncMcpToolsForAgent(t);try{J(t)}catch(a){l(`[acode-adapter] skill farm hot-sync failed for agent ${t}:`,a.message)}try{await v.applyCapabilities(t)}catch(a){l(`[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){l(`[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){l(`[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,a=0,i,n;for(const[p,u]of this.sessions)if(u.config.agentId===t&&typeof u.runtime.addMcpServer=="function")try{const c=await u.runtime.addMcpServer(e,o);s+=1,c.ok?(a=c.tools,i=c.toolNames):n=c.error}catch(c){n=c.message,l(`[acode-adapter] session ${p}: 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:a,toolNames:i,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(a){l(`[acode-adapter] debug unmount mcp ${e} failed for agent ${t}:`,a.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 B[String(t??"").trim()]}async loadCapabilityToolsForSession(t,e,o){const s=t===x?await R(e,o.config.scopeKey,typeof o.config.browserAllowPrivate=="boolean"?{allowPrivate:o.config.browserAllowPrivate}:void 0):await M(e,await this.resolveAgentAiInfo(e)),a=[];for(const i of s){const n=Gt(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[c,r]of i){const m=r.runtime.removeBuiltInToolsByPrefix?.(a)??0;u+=m,m>0&&l(`[acode-adapter] session ${c}: ${m} ${e} tools removed on collapse (agent ${s})`)}return this.expandedBuiltInCapabilities.get(s)?.delete(e),this.builtInCapabilityToolCache.get(s)?.delete(e),l(`[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,c]of i){let r;try{r=await this.loadCapabilityToolsForSession(e,s,c)}catch(m){throw l(`[acode-adapter] session ${u}: capability ${e} tool load failed for agent ${s}:`,m.message),m}for(const m of r)n.has(m.name)||n.set(m.name,m)}const p=this.expandedBuiltInCapabilities.get(s)??new Set;return p.add(e),this.expandedBuiltInCapabilities.set(s,p),this.builtInCapabilityToolCache.set(s,n),l(`[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,{discardJournalFinalize:!0})}setIdleCommands(t,e){const o=this.sessions.get(t);if(o){if(o.idleCommands=e,this.cancelScheduledAutoPoll(o),e.idleInputCommand&&N(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 nt.readFile(t,"utf-8"),o=JSON.parse(e),a=o.provider?.default,i=a?.options,n=A(o.contextLimit),p={},u={},c=a?.models;if(c&&typeof c=="object"){for(const[r,m]of Object.entries(c))if(m&&typeof m=="object"){const f=A(m.contextLimit);f>0&&(p[r.trim()]=f);const h=m.modalities?.input,g=Array.isArray(h)&&h.includes("image")||m.supportsImageInput===!0;u[r.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(p).length>0?{modelContextLimits:p}:{},...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?j(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 p=Rt(a,i,"acode-default");return s.log({level:"info",category:"resolve",message:"resolveAcodeProvider \u89E3\u6790\u7ED3\u679C",source:"bridge",details:{instanceConfig:j(a),globalConfigModel:i?.model??null,resolvedModel:p.model,resolvedBaseURL:p.baseURL??null,resolvedApiKey:p.apiKey?"[set]":null,configContextLimit:n,resolvedSource:p.source}}),{resolved:p,configPath:e,perSessionModel:o,configContextLimit:n,supportsImage:i.modelImageSupport?.[p.model]===!0}}async createRuntime(t,e,o,s,a){const i=await this.loadRuntimeConstructor(),n=this.resolveAgentConfigPath(o.agentId,o.mcpConfigPath);let p=[];try{p=await R(o.agentId,o.scopeKey,typeof o.browserAllowPrivate=="boolean"?{allowPrivate:o.browserAllowPrivate}:void 0)}catch(m){l(`[acode-adapter] browser tools injection skipped for agent ${o.agentId}:`,m.message)}let u=[];if(this.shouldInjectCapabilityTools(o.agentId??"",x)&&(u=p),o.agentId&&this.shouldInjectCapabilityTools(o.agentId,E))try{const m=s?.model?{model:s.model,supportsImage:a===!0,...s.baseURL?{baseURL:s.baseURL}:{},...s.apiKey?{apiKey:s.apiKey}:{}}:void 0,f=await M(o.agentId,m);f.length>0&&(u=[...u,...f])}catch(m){l(`[acode-adapter] desktop tools injection skipped for agent ${o.agentId}:`,m.message)}const c=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,initialTokenUsage:o.resumeTokenUsage,env:o.envOverrides,subAgentManager:xt,terminalManager:gt,capabilityState:m=>ut(m)?"collapsed":U(o.agentId??"",_t(m)),capabilityToolRelay:o.agentId?{handlesGroup:m=>this.resolveCapabilityToolPrefix(m)!==void 0,handlesTool:m=>Object.values(B).some(f=>m.startsWith(f)),expand:async m=>(await this.setBuiltInCapabilityTools(o.agentId??"",m,"expand")).manifests??[],collapse:async m=>{await this.setBuiltInCapabilityTools(o.agentId??"",m,"collapse")},call:async(m,f)=>{const h=m.startsWith(B[E]??"desktop_")?E:x;return this.callBuiltInCapabilityTool(o.agentId??"",h,m,f)}}:void 0,pluginBridge:o.agentId?v.forAgent(o.agentId):void 0,runtimeResourcesProvider:o.agentId?()=>$t(o.agentId):void 0,...o.subAgentModel?{subAgentModel:o.subAgentModel}:{},...o.subAgentEffort?{subAgentEffort:o.subAgentEffort}:{},...o.instanceAiConfig?.effort?{effort:o.instanceAiConfig.effort}:{},onFileChange:m=>Ot({...m,agentId:o.agentId,workspacePath:o.workingDirectory}),extraBuiltInTools:u,...o.agentId?{toolPermissionPolicy:St(o.agentId)??void 0}:{},subAgentSuiteTools:p,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}}),c.on("event",m=>this.forwardAcodeEvent(m)),c}buildSubAgentSuiteToolProvider(t){return async e=>{if(!t)return[];if(!yt(t,E))return[];if(e.length===0)return At(t);if(!e.some(a=>{const i=a.trim().replace(/[.*]+$/,"");return i==="desktop"||i.startsWith("desktop.")}))return[];const s=await this.resolveAgentAiInfo(t);return M(t,s)}}async loadRuntimeConstructor(){if(this.runtimeConstructor)return this.runtimeConstructor;const t=Yt(),e=await Dt(Xt(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:P(),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:ee(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=A(o?.inputTokens),a=A(o?.outputTokens),i=A(o?.cacheHitTokens),n=A(o?.cacheMissTokens),p=!!(o&&(s>0||a>0));let u;p&&(s>0&&(e.adapterSession.totalUsage.inputTokens=s,e.usageInputEstimated=!1),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},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 r={actionType:"ai_request",actionLabel:"AI\u8BF7\u6C42",actionDetail:this.formatAiRequestActionDetail(t.data)};u&&(r.usage=u),w(`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,r),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:oe(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=st(t.data);o&&(o.inputTokens>0&&(e.adapterSession.totalUsage.inputTokens=o.inputTokens,e.usageInputEstimated=!1),e.adapterSession.totalUsage.outputTokens=o.outputTokens,o.hasCache&&(e.adapterSession.totalUsage.cacheHitTokens=o.cacheHitTokens,e.adapterSession.totalUsage.cacheMissTokens=o.cacheMissTokens),o.totalInputTokens!==void 0&&(e.adapterSession.totalUsage.totalInputTokens=o.totalInputTokens),o.totalOutputTokens!==void 0&&(e.adapterSession.totalUsage.totalOutputTokens=o.totalOutputTokens),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"){this.maybePersistHibernationJournalOnTurnComplete(e,t.sessionId);const o=st(t.data.usage);if(o){const a=e.adapterSession.totalUsage.inputTokens,n=typeof t.data.usageEstimated=="boolean"?t.data.usageEstimated===!0:a>0&&o.inputTokens<Math.floor(a*.2)&&!o.hasCache&&!e.usageInputEstimated;w(`turn_complete usage: raw=${JSON.stringify(t.data.usage)} parsed=${JSON.stringify(o)} currentInput=${a} threshold20pct=${Math.floor(a*.2)} isFallbackUsage=${n}`),n?o.outputTokens>0&&(e.adapterSession.totalUsage.outputTokens=o.outputTokens):(o.inputTokens>0&&(e.adapterSession.totalUsage.inputTokens=o.inputTokens,e.usageInputEstimated=!1),e.adapterSession.totalUsage.outputTokens=o.outputTokens),o.hasCache&&(e.adapterSession.totalUsage.cacheHitTokens=o.cacheHitTokens,e.adapterSession.totalUsage.cacheMissTokens=o.cacheMissTokens,l(`[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})`)),o.totalInputTokens!==void 0&&(e.adapterSession.totalUsage.totalInputTokens=o.totalInputTokens),o.totalOutputTokens!==void 0&&(e.adapterSession.totalUsage.totalOutputTokens=o.totalOutputTokens),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(l(`[ACode] turn_complete event received (session: ${t.sessionId}), previous status: ${s}, failed: ${t.data.failed===!0}, aborted: ${t.data.aborted===!0}`),se(t.data)){l(`[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)){l(`[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)}`),l(`[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){l(`[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(S=>Mt(S))||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 y=Array.isArray(t.data.servers)?t.data.servers:[],b=g.map(S=>({name:String(S.name??""),source:String(S.source??""),description:String(S.description??"")})).filter(S=>S.name),C={kind:"mcp",mcpServers:y,mcpTools:b};e.cachedMcpCapabilities=C,e.lastMcpCapabilities=C,e.lastCombinedCapabilities={kind:"combined",mcpServers:y,mcpTools:b,skills:e.lastCombinedCapabilities?.skills??[],skillsDir:e.lastCombinedCapabilities?.skillsDir,skillGroups:e.lastCombinedCapabilities?.skillGroups??[]},l(`[cap-diag] MCP capabilities cached: ${y.length} servers, ${b.length} tools`,{sessionId:t.sessionId,servers:y,toolNames:b.map(S=>S.name)}),e.capabilitiesFallbackTimer&&clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=setTimeout(()=>{const S=e.cachedMcpCapabilities;if(!S)return;const _={...S,skills:[],skillGroups:[]};this.emitProviderEvent(t,"runtime_capabilities",{capabilities:_,actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:JSON.stringify(_)}),l(`[cap-diag] MCP capabilities emitted via fallback (skill_status not received within ${tt}ms)`,{sessionId:t.sessionId,mcpServers:S.mcpServers,mcpToolsCount:S.mcpTools?.length??0}),e.cachedMcpCapabilities=void 0,e.capabilitiesFallbackTimer=void 0},tt);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){l(`[ACode] \u{1F9E9} tool_batch_start without batchId, ignored (session=${t.sessionId})`);return}const T=typeof t.data.toolCount=="number"?t.data.toolCount:0,y=Array.isArray(t.data.toolNames)?t.data.toolNames.map(b=>String(b??"")).filter(Boolean):[];l(`[ACode] \u{1F9E9} tool_batch_start: batch=${g.slice(0,20)}\u2026, tools=${T}`),this.emitProviderEvent(t,"tool_batch_start",{batchId:g,batchToolCount:T,batchToolNames:y,actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionDetail:y.length>0?y.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){l(`[ACode] \u26A1 tool_batch_metrics without batchId, ignored (session=${t.sessionId})`);return}const T={toolCount:L(t.data.toolCount),parallelism:L(t.data.parallelism),speedup:L(t.data.speedup),wallClockMs:L(t.data.wallClockMs),totalWaitMs:W(t.data.totalWaitMs),contentionCount:L(t.data.contentionCount),failureCount:W(t.data.failureCount),maxConcurrentObserved:W(t.data.maxConcurrentObserved)};l(`[ACode] \u26A1 tool_batch_metrics: batch=${g.slice(0,20)}\u2026, speedup=${T.speedup}x parallelism=${T.parallelism}x wall=${T.wallClockMs}ms contentions=${T.contentionCount} failures=${T.failureCount??"-"}`),this.emitProviderEvent(t,"tool_batch_metrics",{batchId:g,batchMetrics:T,actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionId:g});return}if(o!=="call_tool"&&o!=="tool_result"){l(`[ACode] \u{1F4AC} mcp_status status report ignored (action=${o||"none"}, server=${typeof t.data.server=="string"?t.data.server:"?"}, session=${t.sessionId})`);return}l(`[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,p=Ut(i,n);e.autoPollObservedAnyTool=!0,p.actionType==="idle"&&(e.autoPollObservedPollingTool=!0);const u=ie(p.actionType)?p.actionDetail||it(void 0,s,a):it(p.actionDetail,s,a),c=typeof t.data.toolUseId=="string"?t.data.toolUseId:void 0,r=n?JSON.stringify(n,null,2):void 0,m=typeof t.data.batchId=="string"?t.data.batchId:void 0,f={toolName:u,rawToolName:i,actionType:p.actionType,actionLabel:p.actionLabel,actionDetail:u,...r?{actionInput:r}:{},...n?{toolInput:n}:{},...c?{toolUseId:c,actionId:c}:{},...m?{batchId:m,parentId:m}:{},metadata:{mcpServer:s}};if(t.data.action==="tool_result"){this.trackOpenDocumentEvent(e,i,n,t.data.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:P(),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:c,isError:t.data.failed===!0});const g=p.actionType==="idle"&&!ae(t.data.result)?"waiting_input":"thinking";e.adapterSession.status=g,p.actionType==="idle"&&(e.idleToolActiveAt=void 0),k("tool_use_end",{sessionId:t.sessionId,actionType:p.actionType,tool:i,nextStatus:g,idleToolActiveAtAfter:e.idleToolActiveAt??null}),this.cancelDataFlowWatchdog(e),e.pendingToolEventData=void 0;const T=p.actionType==="idle";this.emit("status-change",t.sessionId,g,T||g==="thinking"?void 0:f);return}const h=p.actionType==="idle"?"waiting_input":"tool_using";e.adapterSession.status=h,p.actionType==="idle"&&(e.idleToolActiveAt=Date.now()),h==="tool_using"&&(this.resetDataFlowWatchdog(t.sessionId,e),e.pendingToolEventData={...f}),e.adapterSession.messages.push({id:P(),sessionId:t.sessionId,role:"tool_use",content:r??"",timestamp:t.timestamp,toolName:i,toolInput:n,toolUseId:c}),this.emitProviderEvent(t,"tool_use_start",f),this.emit("status-change",t.sessionId,h,f);return}if(t.type==="skill_status"){const s=(Array.isArray(t.data.skills)?t.data.skills:[]).map(r=>({name:String(r.name??""),description:typeof r.description=="string"?r.description:void 0,directory:typeof r.directory=="string"?r.directory:void 0})).filter(r=>r.name),a=typeof t.data.skillsDir=="string"?t.data.skillsDir:void 0,n=(Array.isArray(t.data.skillGroups)?t.data.skillGroups:[]).map(r=>{const m=Array.isArray(r.skills)?r.skills:[];return{dir:typeof r.dir=="string"?r.dir:"",exists:r.exists===!0,skills:m.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(r=>r.dir),p=e.cachedMcpCapabilities??e.lastMcpCapabilities,u=e.cachedMcpCapabilities!==void 0,c={kind:"combined",mcpServers:p?.mcpServers??[],mcpTools:p?.mcpTools??[],skills:s,skillsDir:a,skillGroups:n};this.emitProviderEvent(t,"runtime_capabilities",{capabilities:c,actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:JSON.stringify(c)}),e.lastCombinedCapabilities=c,l(`[cap-diag] Combined capabilities emitted ${u?"(startup merge)":"(runtime refresh)"}: ${(p?.mcpTools??[]).length} MCP tools, ${s.length} skills`,{sessionId:t.sessionId,mcpServers:p?.mcpServers??[],skillsDir:a}),e.capabilitiesFallbackTimer&&(clearTimeout(e.capabilitiesFallbackTimer),e.capabilitiesFallbackTimer=void 0),e.cachedMcpCapabilities=void 0;return}if(t.type==="compaction_summary"){const o=typeof t.data.text=="string"?t.data.text:"";o&&this.emitProviderEvent(t,"compaction_summary",{text:o});return}if(t.type==="startup_phase"){l(`[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"){l(`[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"){w(`session_started estimate intentionally not displayed as context size: estimatedContextTokens=${t.data.estimatedContextTokens??"n/a"} (waiting for provider usage)`);const o=A(t.data.contextLimit)||void 0,s=A(t.data.maxOutput)||void 0,a=A(t.data.inputLimit)||void 0,i=A(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",p=o.parentId,u=o.compactionId;if(o.trigger==="hibernation_replay"){e.hibernationReplayCardEmitted=!0;const h=typeof o.replayedMessageCount=="number"?o.replayedMessageCount:void 0,g=o.estimatedTokens;typeof g=="number"&&g>0&&(e.adapterSession.totalUsage.inputTokens=g,e.usageInputEstimated=!0);const T={actionType:"context_compaction",actionLabel:"\u4F11\u7720\u6062\u590D",actionDetail:h?`\u5DF2\u91CD\u653E\u4F11\u7720\u524D\u7684 ${h} \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",T),this.emit("status-change",t.sessionId,e.adapterSession.status,T);return}let r,m;if(a){const h=String(o.sizeKB??o.sizeBeforeKB??"?"),g=String(o.messageCount??o.messageCountBefore??"?"),T=o.estimatedTokens,y=o.actualInputTokens?`input=${o.actualInputTokens}`:"",b=o.actualOutputTokens?`output=${o.actualOutputTokens}`:"",C=o.trigger;r="\u4E0A\u4E0B\u6587\u538B\u7F29\u5F00\u59CB";const S=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,_=S?`, \u89E6\u53D1: ${S}`:"";T!==void 0?m=`\u538B\u7F29\u524D: ~${T} tokens, \u6D88\u606F: ${g}\u6761`+(y?`, \u5B9E\u9645 tokens: ${y} ${b}`:"")+_:m=`\u538B\u7F29\u524D: ${h}KB, \u6D88\u606F: ${g}\u6761`+(y?`, \u5B9E\u9645 tokens: ${y} ${b}`:"")+_}else if(n){const h=String(o.phase??""),g=String(o.phaseLabel??"\u538B\u7F29\u9636\u6BB5"),T=String(o.phaseDetail??"");h==="detect"?(r="\u5F00\u59CB\u89E6\u53D1\u54CD\u5E94\u5F0F\u538B\u7F29",m=T||"\u68C0\u6D4B\u5230\u4E0A\u4E0B\u6587\u8D85\u9650\uFF0C\u5373\u5C06\u5F00\u59CB\u538B\u7F29..."):(r=g,m=T)}else{const h=o.tokensBefore,g=o.tokensAfter,T=o.freedTokens,y=String(o.sizeBeforeKB??"?"),b=String(o.sizeAfterKB??"?"),C=String(o.freedKB??"?"),S=String(o.strategy??"?"),_=Number(o.prunedToolMessages??0),D=Number(o.summarizedMessages??0);r="\u538B\u7F29\u5B8C\u6210",h!==void 0&&g!==void 0?m=`\u91CA\u653E: ${T??h-g} tokens, ${h} tokens \u2192 ${g} tokens, \u7B56\u7565: ${S}`+(_?`, \u88C1\u526A\u5DE5\u5177: ${_}\u6761`:"")+(D?`, \u6458\u8981\u5316: ${D}\u6761`:""):m=`\u91CA\u653E: ${C}KB, ${y}KB \u2192 ${b}KB, \u7B56\u7565: ${S}`+(_?`, \u88C1\u526A\u5DE5\u5177: ${_}\u6761`:"")+(D?`, \u6458\u8981\u5316: ${D}\u6761`:"")}a&&(e.adapterSession.status="compacting");const f={actionType:"context_compaction",actionLabel:r,actionDetail:m};if(a&&u)f.actionId=u;else if((n||i)&&u)if(f.parentId=u,n){const h=String(o.phase??"unknown");f.actionId=`${u}-phase-${h}`}else f.actionId=`${u}-end`;if(n&&p&&!f.parentId&&(f.parentId=p),i){const h=A(o.contextTokensAfter)||A(o.tokensAfter);e.adapterSession.totalUsage.inputTokens=A(h),e.adapterSession.totalUsage.outputTokens=0,e.usageInputEstimated=!1,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,jt)}getIdlePollLoop(t){if(t.idlePollLoop)return t.idlePollLoop;const e=t.adapterSession.sessionId;return t.idlePollLoop=new vt({getStatus:()=>this.sessions.get(e)?.adapterSession.status,getCommand:()=>this.sessions.get(e)?.idleCommands?.idleInputCommand,isPollingCommand:o=>N(o),preDispatchHook:()=>null,dispatchPollingPrompt:(o,s)=>this.submitAutoPollPrompt(e,s?o:Vt,{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=>{const n=this.sessions.get(t);n&&(n.lastErrorText=i instanceof Error?i.message:String(i)),this.emitRuntimeErrorEvent(t,i),this.scheduleRequestRetry(t,"submitAutoPollPrompt")}).finally(()=>{const i=this.sessions.get(t);if(i){if(i.autoPollToken!==a){l(`[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??Jt;e===void 0&&(o.autoPollDelayMs=Math.min(s*2,Kt)),o.autoPollTimer=setTimeout(()=>{const a=this.sessions.get(t);!a||a.autoPollActive||this.isTerminalStatus(a.adapterSession.status)||(a.autoPollTimer=void 0,this.submitAutoPollPrompt(t,qt,{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)||o.retryActive||o.retryTimer)return;if(!o.lastSubmittedPrompt){o.adapterSession.status="error",this.emit("status-change",t,"error");return}o.turnModelRequestSucceeded&&o.turnModelRequestSucceededEpoch===o.retryEpoch&&(o.turnModelRequestSucceeded=!1,o.retryAttempt=0),o.lastErrorText&&zt(o.lastErrorText)&&It({sessionId:t,agentId:o.config.agentId,model:o.config.model,attempt:Math.max(1,o.retryAttempt+1),errorText:o.lastErrorText,conversation:this.exportRawTranscript(t),extra:{reason:e,status:o.adapterSession.status}}),o.retryAttempt+=1,o.retryActive=!0,this.cancelScheduledAutoPoll(o),o.idlePollLoop?.stop();const s=Y[Math.min(o.retryAttempt-1,Y.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:Qt(o.lastErrorText)}),l(`[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;l(`[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,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;l(`[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,l(`[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){l(`[ACode] \u25B6\uFE0F recoverResolvedTurnWithoutTerminalEvent called for session ${t}`);const e=this.sessions.get(t);if(!e||this.isTerminalStatus(e.adapterSession.status)){l(`[ACode] Skipping recovery: entry=${!!e}, isTerminal=${e?this.isTerminalStatus(e.adapterSession.status):"N/A"}`);return}if(l(`[ACode] Current status: ${e.adapterSession.status}`),e.adapterSession.status!=="thinking"&&e.adapterSession.status!=="tool_using"){l(`[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.`),l("[ACode] Recovering to waiting_input..."),e.adapterSession.status="waiting_input";const o=e.idleCommands?.idleInputCommand,a=!!(o&&N(o))?{actionType:"idle",actionLabel:"\u76D1\u542C\u6D88\u606F",actionDetail:"aws-mcp/poll_message"}:void 0;if(this.emit("status-change",t,"waiting_input",a),l(`[ACode] \u2705 Recovery complete, status now: ${e.adapterSession.status}`),l("[ACode] \u25B6\uFE0F Arming idle loop or auto-poll..."),!e.autoPollActive&&e.autoPollObservedAnyTool&&!e.autoPollObservedPollingTool){l(`[ACode] User-message turn called work tools; deferring idle rearm in recoverResolvedTurnWithoutTerminalEvent (session: ${t})`),this.scheduleDeferredIdleRearm(t);return}this.armIdleLoopOrAutoPoll(t),l("[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.hasActiveBlockingToolCallEntry(s)&&i-s.autoPollLastActivityAt>=Ht){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>=Wt){const c=String(s.pendingToolEventData?.rawToolName??"");if((s.pendingToolAuthRequests?.size??0)>0){const r=s.pendingToolAuthRequests?.size??0;console.warn(`[ACode] tool_using elapsed ${Math.round(u/1e3)}s but ${r} tool permission request(s) awaiting user decision (session: ${t}), skipping recovery`),s.watchdogSubmitStartTime=i,s.watchdogLastDataFlowTime=i;return}if(c.endsWith("await_complete")){console.warn(`[ACode] tool_using elapsed ${Math.round(u/1e3)}s but await_complete is running (session: ${t}, tool: ${c}), 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 ${c} 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),p=i-(s.watchdogLastDataFlowTime||i);if(G>0&&p>=G){console.warn(`[ACode] CRITICAL: Data flow watchdog triggered after ${Math.round(p/1e3)}s (source: ${o}, session: ${t}, status: ${a}). No stream data received. Forcing recovery via recoverTurnFailure.`),this.executeWatchdogRecovery(t,s,o,"data_flow",p);return}if(Z>0&&n>=Z){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}},Bt)}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}),l(`[ACode] Watchdog (${s}): calling runtime.abort() after ${Math.round(a/1e3)}s...`);try{e.runtime.abort(),l(`[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(),!(q<=0)&&(e.livenessTimer=setInterval(()=>{const o=this.sessions.get(t);if(!o){this.stopLivenessWatchdog(e);return}this.checkSessionLiveness(t,o)},V),k("liveness_watchdog_arm",{sessionId:t,stallTimeoutMs:q,pollIntervalMs:V}))}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(this.maybePersistHibernationJournalOnTick(e,t),e.adapterSession.status!=="waiting_input"||e.autoPollActive||e.idleListeningIntentionallyStopped||e.pendingQuestionToolCallId||(e.pendingToolAuthRequests?.size??0)>0||this.hasActiveBlockingToolCallEntry(e))return;e.idleToolActiveAt!==void 0&&(l(`[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<q)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`)}hasActiveBlockingToolCallEntry(t){const e=t.runtime.hasActiveBlockingToolCall;if(typeof e=="function")try{return e.call(t.runtime)===!0}catch(o){l(`[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,p=typeof t.toolCount=="number"?t.toolCount:void 0,u=typeof t.lastUserMessagePreview=="string"?t.lastUserMessagePreview:"",c=[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,p!==void 0?`\u53EF\u7528\u5DE5\u5177: ${p}`:void 0,u?`\u6700\u540E\u8BF7\u6C42: ${u}`:void 0].filter(T=>!!T),l=/^(authorization|x-api-key|api-key|cookie|set-cookie|x-auth-token|token)$/i,m=t.requestHeaders,f=m?Object.entries(m).filter(([T])=>!l.test(T)).map(([T,S])=>`${T}: ${S}`).filter(T=>T.trim().length>0):[],h=c.join(`
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,p=typeof t.toolCount=="number"?t.toolCount:void 0,u=typeof t.lastUserMessagePreview=="string"?t.lastUserMessagePreview:"",c=[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,p!==void 0?`\u53EF\u7528\u5DE5\u5177: ${p}`:void 0,u?`\u6700\u540E\u8BF7\u6C42: ${u}`:void 0].filter(T=>!!T),r=/^(authorization|x-api-key|api-key|cookie|set-cookie|x-auth-token|token)$/i,m=t.requestHeaders,f=m?Object.entries(m).filter(([T])=>!r.test(T)).map(([T,y])=>`${T}: ${y}`).filter(T=>T.trim().length>0):[],h=c.join(`
5
5
  `)||"ACode \u6B63\u5728\u53D1\u9001 AI \u8BF7\u6C42",g=f.length>0?`${e}${f.join(`
6
- `)}`:"";return`${h}${g}`}}O.HIBERNATION_JOURNAL_MIN_INTERVAL_MS=1e4,O.HIBERNATION_JOURNAL_TICK_INTERVAL_MS=3e4;export{O as AcodeSdkAdapter,ne as isFailedAcodeTurnComplete,ee as toAcodeEsmImportSpecifier};
6
+ `)}`:"";return`${h}${g}`}}O.HIBERNATION_JOURNAL_MIN_INTERVAL_MS=1e4,O.HIBERNATION_JOURNAL_TICK_INTERVAL_MS=3e4;export{O as AcodeSdkAdapter,se as isFailedAcodeTurnComplete,Xt as toAcodeEsmImportSpecifier};
7
7
 
package/dist/config.d.ts CHANGED
@@ -177,37 +177,6 @@ export declare function getBridgeDataHome(): string;
177
177
 
178
178
  export declare function getBridgeTemplateDir(): string;
179
179
 
180
-
181
-
182
-
183
- export declare function getBridgeTemplateConfigFile(): string;
184
-
185
-
186
-
187
-
188
- export declare function getBridgeTemplateSkillsDir(): string;
189
-
190
-
191
-
192
-
193
- export declare function getBridgeTemplatePluginsDir(): string;
194
-
195
-
196
-
197
-
198
- export declare function getBridgeTemplateMcpDir(): string;
199
-
200
-
201
-
202
-
203
-
204
- export declare function getBridgeTemplateMcpPackagesDir(): string;
205
-
206
-
207
-
208
-
209
- export declare function getBridgeTemplateAgentsDir(): string;
210
-
211
180
  export declare function getBridgeInstanceRuntimeDir(agentId: string): string;
212
181
 
213
182
  export declare function getBridgeInstanceConfigFile(agentId: string): string;