aws-runtime-bridge 1.9.186 → 1.9.189
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.
- package/CHANGELOG.md +1767 -1673
- package/README.md +256 -256
- package/dist/adapter/AcodeSdkAdapter.js +3 -3
- package/dist/browser/browser-pool.d.ts +2 -0
- package/dist/browser/browser-pool.js +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.js +2 -2
- package/dist/index.js +1 -1
- package/dist/remote-desktop/win32-api.js +1 -1
- package/dist/routes/background-tasks.js +4 -4
- package/dist/routes/dashboard.js +17 -17
- package/dist/routes/terminal.js +19 -19
- package/dist/services/acode-bg-manager.js +1 -1
- package/dist/services/auto-register.js +1 -1
- package/dist/services/instance-features.d.ts +9 -0
- package/dist/services/instance-features.js +1 -1
- package/dist/services/panel-auth.d.ts +4 -0
- package/dist/services/panel-auth.js +1 -1
- package/dist/services/plugin-handler-adapter.js +2 -2
- package/dist/services/workspace-files.js +1 -1
- package/dist/utils/dynamic-import.d.ts +31 -0
- package/dist/utils/dynamic-import.js +2 -0
- package/dist/utils/sdk-package-loader.js +1 -1
- package/node_modules/playwright/cli.js +0 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_beta_linux.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_beta_mac.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_stable_linux.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_chrome_stable_mac.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_beta_linux.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_beta_mac.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_dev_linux.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_dev_mac.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_stable_linux.sh +0 -0
- package/node_modules/playwright-core/bin/reinstall_msedge_stable_mac.sh +0 -0
- package/node_modules/playwright-core/cli.js +0 -0
- package/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
- package/node_modules/playwright-core/lib/xdg-open +0 -0
- package/package/acode/dist/await-complete-tool.js +3 -3
- package/package/acode/dist/runtime.d.ts +9 -0
- package/package/acode/dist/runtime.js +20 -21
- package/package/acode/dist/sub-agent-manager.d.ts +33 -0
- package/package/acode/dist/sub-agent-manager.js +9 -1
- package/package/acode/dist/sub-agent-tools.d.ts +4 -0
- package/package/acode/dist/sub-agent-tools.js +27 -12
- package/package/acode/dist/subagent-handback.d.ts +16 -0
- package/package/acode/dist/subagent-handback.js +7 -0
- package/package/acode/dist/tool-allocation.js +1 -1
- package/package/acode/package.json +38 -38
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +10 -5
- package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +27 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.js +16 -16
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +19 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +35 -19
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +10 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.js +1 -1
- package/package/aws-client-agent-mcp/dist/tool-groups.js +2 -2
- package/package/aws-client-agent-mcp/dist/types.d.ts +81 -3
- package/package/aws-client-agent-mcp/package.json +53 -53
- package/package.json +134 -132
- /package/package/acode/dist/grammars/{grammars/tree-sitter-bash.wasm → tree-sitter-bash.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-c-sharp.wasm → tree-sitter-c-sharp.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-c.wasm → tree-sitter-c.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-cpp.wasm → tree-sitter-cpp.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-go.wasm → tree-sitter-go.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-java.wasm → tree-sitter-java.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-javascript.wasm → tree-sitter-javascript.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-jsx.wasm → tree-sitter-jsx.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-lua.wasm → tree-sitter-lua.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-php.wasm → tree-sitter-php.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-python.wasm → tree-sitter-python.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-ruby.wasm → tree-sitter-ruby.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-rust.wasm → tree-sitter-rust.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-tsx.wasm → tree-sitter-tsx.wasm} +0 -0
- /package/package/acode/dist/grammars/{grammars/tree-sitter-typescript.wasm → tree-sitter-typescript.wasm} +0 -0
|
@@ -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 St,unregisterListenerWakeHook as J}from"../services/browser-session-manager.js";import{getDesktopTools as M,getDesktopToolsIfReady as yt}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{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 Rt}from"./acode-tool-names.js";import{IdlePollLoop as Ut}from"./idle-poll-loop.js";import{resolveAcodeProviderConfig as Ft}from"./instance-ai-config-resolver.js";import{MESSAGE_POLLING_IDLE_PROMPT as Q}from"./prompts.js";import{getCanonicalMcpDetail as z,getToolActionInfo as Nt}from"./types.js";const qt=process.env.ACODE_COMPACTION_DEBUG==="1";function r(...d){qt&&console.log(...d)}const Bt=process.env.ACODE_TOKEN_DEBUG==="1";function w(...d){Bt&&console.log("[TokenDebug][Adapter]",...d)}const Wt=Q,Ht=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),Kt=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),jt=250,Qt=1e3,zt=I("ACODE_DEFERRED_IDLE_REARM_MS",3e3),Y=[2e3,3e3,1e4,4e4],X=4e3;function Gt(d){const t=String(d||"").trim();if(t)return t.length>X?`${t.slice(0,X)}\u2026(truncated)`:t}function Vt(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 Yt(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,Xt=Q;function Zt(){return H.resolve(gt())}function te(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 ee(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 oe(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 se(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 ie(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 ae(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 ne(d){return d==="read_file"||d==="edit_file"||d==="write_file"||d==="bash"}function re(d){const t=le(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 le(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??ee(n),u=oe(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),St(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&<(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=Yt(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=Ft(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 yt(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=Zt(),e=await import(te(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:se(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:ie(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}`),ae(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(S=>Rt(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??[]},r(`[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(_)}),r(`[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){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,y=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: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){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=Nt(i,n);e.autoPollObservedAnyTool=!0,p.actionType==="idle"&&(e.autoPollObservedPollingTool=!0);const u=ne(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"&&!re(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,y=o.actualInputTokens?`input=${o.actualInputTokens}`:"",b=o.actualOutputTokens?`output=${o.actualOutputTokens}`:"",C=o.trigger;l="\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"?(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,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);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: ${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: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,zt)}getIdlePollLoop(t){if(t.idlePollLoop)return t.idlePollLoop;const e=t.adapterSession.sessionId;return t.idlePollLoop=new Ut({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:Xt,{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??jt;e===void 0&&(o.autoPollDelayMs=Math.min(s*2,Qt)),o.autoPollTimer=setTimeout(()=>{const a=this.sessions.get(t);!a||a.autoPollActive||this.isTerminalStatus(a.adapterSession.status)||(a.autoPollTimer=void 0,this.submitAutoPollPrompt(t,Wt,{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&&Vt(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:Gt(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>=Kt){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}},Ht)}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,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&<(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=`
|
|
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,
|
|
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(`
|
|
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,
|
|
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};
|
|
7
7
|
|
|
@@ -16,6 +16,8 @@ import type { Page } from "playwright";
|
|
|
16
16
|
import type { ListenerTriggerEvent, PageListener } from "./page-listener-types.js";
|
|
17
17
|
import { type BrowserPoolConfig, type SessionBrowser } from "./types.js";
|
|
18
18
|
|
|
19
|
+
export declare function sanitizeLaunchArgs(args: readonly string[]): string[];
|
|
20
|
+
|
|
19
21
|
export interface SessionSummary {
|
|
20
22
|
agentId: string;
|
|
21
23
|
browserId: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{chromium as I}from"playwright";import{formatBrowserLaunchError as _,installPlaywrightChromium as D,isBrowserMissingError as b}from"./browser-bootstrap.js";import{BrowserProfileStore as H}from"./browser-profile-store.js";import{ListenerStore as k}from"./listener-store.js";import{PageListenerManager as B}from"./page-listener-manager.js";import{ScreencastManager as L}from"./screencast-manager.js";import{buildStealthInitScript as N,STEALTH_LAUNCH_ARGS as O,STEALTH_IGNORE_ARGS as K}from"./stealth.js";import{StepArchive as R}from"./step-archive.js";import{DEFAULT_BROWSER_ID as l,IDLE_CHECK_INTERVAL_MS as z,IDLE_TIMEOUT_MS as U,MAX_PAGES_PER_SESSION as W,MAX_SESSIONS as $,MAX_SESSIONS_PER_AGENT as C,SESSION_TIMEOUT_MS as G,makeBrowserKey as q}from"./types.js";const V=1280,X=720;class F{onSessionClose(e){this.sessionCloseHandlers.push(e)}getSsrfConfig(){return this.config.ssrfConfig}setListenerTriggerHook(e){this.listenerTriggerHook=e}resolveKey(e,s){if(!e||typeof e!="string")throw new Error("scopeKey must be a non-empty string");const i=s&&s.trim()?s.trim():l;if(i.includes("::"))throw new Error(`browserId must not contain "::" (reserved separator): ${i}`);return q(e,i)}constructor(e){this.sessions=new Map,this.closingKeys=new Set,this.idleTimer=null,this.sessionCloseHandlers=[],this.listenerTriggerHook=null,this.config={headless:e?.headless??!0,executablePath:e?.executablePath,viewportWidth:e?.viewportWidth??V,viewportHeight:e?.viewportHeight??X,maxPagesPerSession:e?.maxPagesPerSession??W,maxSessionDurationMs:e?.maxSessionDurationMs??G,idleTimeoutMs:e?.idleTimeoutMs??U,launchArgs:e?.launchArgs,screencastConfig:e?.screencastConfig,archiveConfig:e?.archiveConfig,ssrfConfig:e?.ssrfConfig,userAgent:e?.userAgent,locale:e?.locale,timezone:e?.timezone,profileDir:e?.profileDir,stealth:e?.stealth??!0},this.profileStore=e?.profileDir?new H({profileDir:e.profileDir}):null,this.listenerStore=e?.profileDir?new k({listenerDir:e.profileDir}):null}async launch(e,s,i,t){const r=t??`agent:${e}`,o=this.resolveKey(r,s);if(this.sessions.has(o))throw new Error(`Browser session already exists for ${e}/${s??l}`);if(this.sessions.size>=$)throw new Error(`BrowserPool reached MAX_SESSIONS=${$}; close existing sessions before launching new ones`);let c=0;for(const n of this.sessions.values())n.agentId===e&&(c+=1);if(c>=C)throw new Error(`BrowserPool reached MAX_SESSIONS_PER_AGENT=${C} for agent ${e}; close some browser sessions first`);const h={headless:this.config.headless};this.config.executablePath&&(h.executablePath=this.config.executablePath);const S=[`--window-size=${this.config.viewportWidth},${this.config.viewportHeight}`];this.config.stealth?(h.ignoreDefaultArgs=[...K],h.args=[...S,...O,...this.config.launchArgs??[]]):this.config.launchArgs&&this.config.launchArgs.length>0?h.args=[...S,...this.config.launchArgs]:h.args=[...S];const f=await this.launchChromium(h);let v=this.config.userAgent,P;if(this.config.stealth)try{const n=await f.newBrowserCDPSession(),g=await n.send("Browser.getVersion"),m=g.product?.match(/Chrome\/(\d+)/);m&&(P=m[1]),!v&&g.userAgent&&(v=String(g.userAgent).replace(/HeadlessChrome\/([\d.]+)/g,"Chrome/$1")),await n.detach().catch(()=>{})}catch{}const w={viewport:{width:this.config.viewportWidth,height:this.config.viewportHeight}};if(v&&(w.userAgent=v),this.config.locale&&(w.locale=this.config.locale),this.config.timezone&&(w.timezoneId=this.config.timezone),this.profileStore)try{let n=await this.profileStore.load(r);!n&&r!==e&&(n=await this.profileStore.load(e),n&&await this.profileStore.save(r,n)),n&&(w.storageState=n)}catch{}const p=await f.newContext(w).catch(async n=>{throw await f.close().catch(()=>{}),n});this.config.stealth&&await p.addInitScript(N(P??"126")).catch(()=>{});const d=await p.newPage().catch(async n=>{throw await f.close().catch(()=>{}),n}),A=new L(this.config.screencastConfig),M=new R(this.config.archiveConfig),T=new B(e,s?.trim()||l,{onTrigger:(n,g)=>{const m=this.listenerTriggerHook;if(m)try{m(e,s?.trim()||l,n,g)}catch{}},store:this.listenerStore,scopeKey:r});try{await A.start(d)}catch{}try{const n=d;n.screencast?.showActions&&await n.screencast.showActions({cursor:"pointer"})}catch{}const E=Date.now(),a={agentId:e,scopeKey:r,browserId:s?.trim()||l,title:i?.trim()||"\u6D4F\u89C8\u5668\u4F1A\u8BDD",browser:f,context:p,pages:[d],activePageIndex:0,screencast:A,archive:M,listenerManager:T,launchedAt:E,lastActivityAt:E,humanTakeover:!1,qualityPreset:"original"};p.on("page",n=>{if(a.pages.length>=this.config.maxPagesPerSession){n.close().catch(()=>{});return}a.pages.push(n);const g=a.pages.length-1;this.setActivePage(e,g,a.browserId).catch(()=>{}),this.registerPageClose(a,n)});try{await T.attach(d)}catch{}this.sessions.set(o,a),this.ensureIdleTimer(),this.registerPageClose(a,d),f.on("disconnected",()=>{this.sessions.get(o)===a&&this.close(a.agentId,a.browserId).catch(()=>{})}),p.on("close",()=>{this.sessions.get(o)===a&&this.close(a.agentId,a.browserId).catch(()=>{})});const x=this.profileStore;return x&&(a.autoSaveTimer=setInterval(async()=>{try{const n=await a.context.storageState();await x.save(a.scopeKey,n)}catch{}},3e4),a.autoSaveTimer.unref&&a.autoSaveTimer.unref()),a}async launchChromium(e){try{return await I.launch(e)}catch(s){if(this.config.executablePath||!b(s))throw s;const i=await D();try{return await I.launch(e)}catch(t){throw _(t instanceof Error?t:new Error(String(t)),i)}}}get(e,s){const i=s&&s.trim()?s.trim():l;for(const t of this.sessions.values())if(t.agentId===e&&t.browserId===i)return t}async getOrLaunch(e,s,i,t){const r=t??`agent:${e}`,o=this.resolveKey(r,s),c=this.sessions.get(o);return c||this.launch(e,s,i,t)}async close(e,s){const i=s&&s.trim()?s.trim():l;let t,r;for(const[c,h]of this.sessions)if(h.agentId===e&&h.browserId===i){t=c,r=h;break}if(!t||!r||this.closingKeys.has(t))return;this.closingKeys.add(t);const o=r;try{o.autoSaveTimer&&(clearInterval(o.autoSaveTimer),o.autoSaveTimer=void 0);try{await o.screencast.dispose()}catch{}try{await o.listenerManager.dispose()}catch{}if(o.archive.clear(),this.profileStore)try{const c=await o.context.storageState();await this.profileStore.save(o.scopeKey,c)}catch{}try{await o.browser.close()}catch{}this.sessions.delete(t);for(const c of this.sessionCloseHandlers)try{c(e,i)}catch{}this.sessions.size===0&&this.stopIdleTimer()}finally{this.closingKeys.delete(t)}}registerPageClose(e,s){s.on("close",()=>{const i=e.pages.indexOf(s);if(i!==-1){if(e.pages.splice(i,1),e.pages.length===0){this.close(e.agentId,e.browserId).catch(()=>{});return}e.activePageIndex>=e.pages.length?e.activePageIndex=e.pages.length-1:i<e.activePageIndex&&(e.activePageIndex-=1)}})}async closeByAgent(e){if(!e)return;const s=[];for(const[i,t]of this.sessions)t.agentId===e&&s.push(i);await Promise.all(s.map(i=>{const r=this.sessions.get(i)?.browserId;return this.close(e,r)}))}async collectListenerEvents(e){if(!e)return[];const s=[];for(const i of this.sessions.values()){if(i.agentId!==e)continue;await i.listenerManager.scanExistsAtPoll();const t=i.listenerManager.collectEvents();t.length>0&&s.push(...t)}return s.sort((i,t)=>i.triggeredAt-t.triggeredAt),s}getActivePage(e,s){const i=this.requireSession(e,s),t=i.pages[i.activePageIndex];if(!t||t.isClosed())throw new Error(`No active page for agent ${e}/${i.browserId} (index ${i.activePageIndex})`);return t}async setActivePage(e,s,i){const t=this.requireSession(e,i);if(!Number.isInteger(s)||s<0||s>=t.pages.length)throw new Error(`Page index ${s} out of range (0..${t.pages.length-1}) for agent ${e}/${t.browserId}`);if(t.activePageIndex===s){const c=t.pages[s];if(c==null)throw new Error(`Page index ${s} out of range for agent ${e}/${t.browserId}`);return c}const r=t.pages[t.activePageIndex];if(r&&!r.isClosed())try{await t.screencast.stop(r)}catch{}t.activePageIndex=s;const o=t.pages[s];if(o==null)throw new Error(`Page index ${s} out of range for agent ${e}/${t.browserId}`);try{await t.screencast.start(o)}catch{}try{await t.listenerManager.reattach(o)}catch{}return this.touchActivity(e,i),o}async newPage(e,s){const i=this.requireSession(e,s);if(i.pages.length>=this.config.maxPagesPerSession)throw new Error(`Agent ${e}/${i.browserId} reached maxPagesPerSession=${this.config.maxPagesPerSession}; close a tab first`);const t=await i.context.newPage();i.pages.push(t);const r=i.pages.length-1;return this.touchActivity(e,s),this.setActivePage(e,r,s)}async closePage(e,s,i){const t=this.requireSession(e,i);if(!Number.isInteger(s)||s<0||s>=t.pages.length)throw new Error(`Page index ${s} out of range (0..${t.pages.length-1}) for agent ${e}/${t.browserId}`);const r=t.pages[s];if(r==null)throw new Error(`Page index ${s} out of range for agent ${e}/${t.browserId}`);if(s===t.activePageIndex)try{await t.screencast.stop(r)}catch{}try{await r.close()}catch{}if(t.pages.splice(s,1),t.pages.length===0){await this.close(e,i);return}t.activePageIndex>=t.pages.length?t.activePageIndex=t.pages.length-1:s<t.activePageIndex&&(t.activePageIndex-=1);const o=t.pages[t.activePageIndex];if(o==null)throw new Error(`No active page for agent ${e}/${t.browserId}`);if(!o.isClosed()){try{await t.screencast.start(o)}catch{}try{await t.listenerManager.reattach(o)}catch{}}this.touchActivity(e,i)}listSessions(e){const s=[];for(const i of this.sessions.values()){if(e&&i.agentId!==e)continue;const t=i.pages[i.activePageIndex];let r="";const o="";if(t&&!t.isClosed())try{r=t.url()}catch{}s.push({agentId:i.agentId,browserId:i.browserId,title:i.title,pageCount:i.pages.length,activePageIndex:i.activePageIndex,launchedAt:i.launchedAt,lastActivityAt:i.lastActivityAt,currentUrl:r,currentTitle:o})}return s}touchActivity(e,s){const i=s&&s.trim()?s.trim():l;for(const t of this.sessions.values())if(t.agentId===e&&t.browserId===i){t.lastActivityAt=Date.now();return}}async dispose(){this.stopIdleTimer();const e=Array.from(this.sessions.keys());await Promise.all(e.map(s=>{const i=this.sessions.get(s);return i?this.close(i.agentId,i.browserId):Promise.resolve()}))}requireSession(e,s){const i=s&&s.trim()?s.trim():l;for(const t of this.sessions.values())if(t.agentId===e&&t.browserId===i)return t;throw new Error(`Browser session not launched for ${e}/${s??l}`)}ensureIdleTimer(){this.idleTimer||this.config.idleTimeoutMs<=0&&this.config.maxSessionDurationMs<=0||(this.idleTimer=setInterval(()=>{this.checkIdleSessions()},z),this.idleTimer.unref&&this.idleTimer.unref())}stopIdleTimer(){this.idleTimer&&(clearInterval(this.idleTimer),this.idleTimer=null)}async checkIdleSessions(){const e=Date.now(),s=[];for(const i of this.sessions.values()){if(i.humanTakeover)continue;const t=e-i.lastActivityAt,r=e-i.launchedAt;if(this.config.idleTimeoutMs>0&&t>this.config.idleTimeoutMs){s.push(i);continue}this.config.maxSessionDurationMs>0&&r>this.config.maxSessionDurationMs&&s.push(i)}await Promise.all(s.map(i=>this.close(i.agentId,i.browserId)))}}let u=null;function re(y){return u||(u=new F(y)),u}async function oe(){u&&(await u.dispose(),u=null)}export{F as BrowserPool,oe as disposeBrowserPool,re as getBrowserPool};
|
|
1
|
+
import{chromium as I}from"playwright";import{formatBrowserLaunchError as b,installPlaywrightChromium as D,isBrowserMissingError as H}from"./browser-bootstrap.js";import{BrowserProfileStore as k}from"./browser-profile-store.js";import{ListenerStore as N}from"./listener-store.js";import{PageListenerManager as L}from"./page-listener-manager.js";import{ScreencastManager as B}from"./screencast-manager.js";import{buildStealthInitScript as O,STEALTH_LAUNCH_ARGS as K,STEALTH_IGNORE_ARGS as R}from"./stealth.js";import{StepArchive as z}from"./step-archive.js";import{DEFAULT_BROWSER_ID as l,IDLE_CHECK_INTERVAL_MS as U,IDLE_TIMEOUT_MS as G,MAX_PAGES_PER_SESSION as W,MAX_SESSIONS as $,MAX_SESSIONS_PER_AGENT as C,SESSION_TIMEOUT_MS as q,makeBrowserKey as V}from"./types.js";const X=1280,F=720,j=[/^--remote-debugging-(port|pipe|address)(=|$)/i,/^--inspect(=|$)/i,/^--inspect-brk(=|$)/i,/^--debugging-port(=|$)/i];function M(v){return v.filter(e=>!j.some(s=>s.test(e)))}class J{onSessionClose(e){this.sessionCloseHandlers.push(e)}getSsrfConfig(){return this.config.ssrfConfig}setListenerTriggerHook(e){this.listenerTriggerHook=e}resolveKey(e,s){if(!e||typeof e!="string")throw new Error("scopeKey must be a non-empty string");const i=s&&s.trim()?s.trim():l;if(i.includes("::"))throw new Error(`browserId must not contain "::" (reserved separator): ${i}`);return V(e,i)}constructor(e){this.sessions=new Map,this.closingKeys=new Set,this.idleTimer=null,this.sessionCloseHandlers=[],this.listenerTriggerHook=null,this.config={headless:e?.headless??!0,executablePath:e?.executablePath,viewportWidth:e?.viewportWidth??X,viewportHeight:e?.viewportHeight??F,maxPagesPerSession:e?.maxPagesPerSession??W,maxSessionDurationMs:e?.maxSessionDurationMs??q,idleTimeoutMs:e?.idleTimeoutMs??G,launchArgs:e?.launchArgs,screencastConfig:e?.screencastConfig,archiveConfig:e?.archiveConfig,ssrfConfig:e?.ssrfConfig,userAgent:e?.userAgent,locale:e?.locale,timezone:e?.timezone,profileDir:e?.profileDir,stealth:e?.stealth??!0},this.profileStore=e?.profileDir?new k({profileDir:e.profileDir}):null,this.listenerStore=e?.profileDir?new N({listenerDir:e.profileDir}):null}async launch(e,s,i,t){const r=t??`agent:${e}`,o=this.resolveKey(r,s);if(this.sessions.has(o))throw new Error(`Browser session already exists for ${e}/${s??l}`);if(this.sessions.size>=$)throw new Error(`BrowserPool reached MAX_SESSIONS=${$}; close existing sessions before launching new ones`);let c=0;for(const n of this.sessions.values())n.agentId===e&&(c+=1);if(c>=C)throw new Error(`BrowserPool reached MAX_SESSIONS_PER_AGENT=${C} for agent ${e}; close some browser sessions first`);const h={headless:this.config.headless};this.config.executablePath&&(h.executablePath=this.config.executablePath);const y=[`--window-size=${this.config.viewportWidth},${this.config.viewportHeight}`];this.config.stealth?(h.ignoreDefaultArgs=[...R],h.args=[...y,...K,...M(this.config.launchArgs??[])]):this.config.launchArgs&&this.config.launchArgs.length>0?h.args=[...y,...M(this.config.launchArgs)]:h.args=[...y];const f=await this.launchChromium(h);let S=this.config.userAgent,P;if(this.config.stealth)try{const n=await f.newBrowserCDPSession(),g=await n.send("Browser.getVersion"),m=g.product?.match(/Chrome\/(\d+)/);m&&(P=m[1]),!S&&g.userAgent&&(S=String(g.userAgent).replace(/HeadlessChrome\/([\d.]+)/g,"Chrome/$1")),await n.detach().catch(()=>{})}catch{}const w={viewport:{width:this.config.viewportWidth,height:this.config.viewportHeight}};if(S&&(w.userAgent=S),this.config.locale&&(w.locale=this.config.locale),this.config.timezone&&(w.timezoneId=this.config.timezone),this.profileStore)try{let n=await this.profileStore.load(r);!n&&r!==e&&(n=await this.profileStore.load(e),n&&await this.profileStore.save(r,n)),n&&(w.storageState=n)}catch{}const p=await f.newContext(w).catch(async n=>{throw await f.close().catch(()=>{}),n});this.config.stealth&&await p.addInitScript(O(P??"126")).catch(()=>{});const d=await p.newPage().catch(async n=>{throw await f.close().catch(()=>{}),n}),A=new B(this.config.screencastConfig),_=new z(this.config.archiveConfig),T=new L(e,s?.trim()||l,{onTrigger:(n,g)=>{const m=this.listenerTriggerHook;if(m)try{m(e,s?.trim()||l,n,g)}catch{}},store:this.listenerStore,scopeKey:r});try{await A.start(d)}catch{}try{const n=d;n.screencast?.showActions&&await n.screencast.showActions({cursor:"pointer"})}catch{}const E=Date.now(),a={agentId:e,scopeKey:r,browserId:s?.trim()||l,title:i?.trim()||"\u6D4F\u89C8\u5668\u4F1A\u8BDD",browser:f,context:p,pages:[d],activePageIndex:0,screencast:A,archive:_,listenerManager:T,launchedAt:E,lastActivityAt:E,humanTakeover:!1,qualityPreset:"original"};p.on("page",n=>{if(a.pages.length>=this.config.maxPagesPerSession){n.close().catch(()=>{});return}a.pages.push(n);const g=a.pages.length-1;this.setActivePage(e,g,a.browserId).catch(()=>{}),this.registerPageClose(a,n)});try{await T.attach(d)}catch{}this.sessions.set(o,a),this.ensureIdleTimer(),this.registerPageClose(a,d),f.on("disconnected",()=>{this.sessions.get(o)===a&&this.close(a.agentId,a.browserId).catch(()=>{})}),p.on("close",()=>{this.sessions.get(o)===a&&this.close(a.agentId,a.browserId).catch(()=>{})});const x=this.profileStore;return x&&(a.autoSaveTimer=setInterval(async()=>{try{const n=await a.context.storageState();await x.save(a.scopeKey,n)}catch{}},3e4),a.autoSaveTimer.unref&&a.autoSaveTimer.unref()),a}async launchChromium(e){try{return await I.launch(e)}catch(s){if(this.config.executablePath||!H(s))throw s;const i=await D();try{return await I.launch(e)}catch(t){throw b(t instanceof Error?t:new Error(String(t)),i)}}}get(e,s){const i=s&&s.trim()?s.trim():l;for(const t of this.sessions.values())if(t.agentId===e&&t.browserId===i)return t}async getOrLaunch(e,s,i,t){const r=t??`agent:${e}`,o=this.resolveKey(r,s),c=this.sessions.get(o);return c||this.launch(e,s,i,t)}async close(e,s){const i=s&&s.trim()?s.trim():l;let t,r;for(const[c,h]of this.sessions)if(h.agentId===e&&h.browserId===i){t=c,r=h;break}if(!t||!r||this.closingKeys.has(t))return;this.closingKeys.add(t);const o=r;try{o.autoSaveTimer&&(clearInterval(o.autoSaveTimer),o.autoSaveTimer=void 0);try{await o.screencast.dispose()}catch{}try{await o.listenerManager.dispose()}catch{}if(o.archive.clear(),this.profileStore)try{const c=await o.context.storageState();await this.profileStore.save(o.scopeKey,c)}catch{}try{await o.browser.close()}catch{}this.sessions.delete(t);for(const c of this.sessionCloseHandlers)try{c(e,i)}catch{}this.sessions.size===0&&this.stopIdleTimer()}finally{this.closingKeys.delete(t)}}registerPageClose(e,s){s.on("close",()=>{const i=e.pages.indexOf(s);if(i!==-1){if(e.pages.splice(i,1),e.pages.length===0){this.close(e.agentId,e.browserId).catch(()=>{});return}e.activePageIndex>=e.pages.length?e.activePageIndex=e.pages.length-1:i<e.activePageIndex&&(e.activePageIndex-=1)}})}async closeByAgent(e){if(!e)return;const s=[];for(const[i,t]of this.sessions)t.agentId===e&&s.push(i);await Promise.all(s.map(i=>{const r=this.sessions.get(i)?.browserId;return this.close(e,r)}))}async collectListenerEvents(e){if(!e)return[];const s=[];for(const i of this.sessions.values()){if(i.agentId!==e)continue;await i.listenerManager.scanExistsAtPoll();const t=i.listenerManager.collectEvents();t.length>0&&s.push(...t)}return s.sort((i,t)=>i.triggeredAt-t.triggeredAt),s}getActivePage(e,s){const i=this.requireSession(e,s),t=i.pages[i.activePageIndex];if(!t||t.isClosed())throw new Error(`No active page for agent ${e}/${i.browserId} (index ${i.activePageIndex})`);return t}async setActivePage(e,s,i){const t=this.requireSession(e,i);if(!Number.isInteger(s)||s<0||s>=t.pages.length)throw new Error(`Page index ${s} out of range (0..${t.pages.length-1}) for agent ${e}/${t.browserId}`);if(t.activePageIndex===s){const c=t.pages[s];if(c==null)throw new Error(`Page index ${s} out of range for agent ${e}/${t.browserId}`);return c}const r=t.pages[t.activePageIndex];if(r&&!r.isClosed())try{await t.screencast.stop(r)}catch{}t.activePageIndex=s;const o=t.pages[s];if(o==null)throw new Error(`Page index ${s} out of range for agent ${e}/${t.browserId}`);try{await t.screencast.start(o)}catch{}try{await t.listenerManager.reattach(o)}catch{}return this.touchActivity(e,i),o}async newPage(e,s){const i=this.requireSession(e,s);if(i.pages.length>=this.config.maxPagesPerSession)throw new Error(`Agent ${e}/${i.browserId} reached maxPagesPerSession=${this.config.maxPagesPerSession}; close a tab first`);const t=await i.context.newPage();i.pages.push(t);const r=i.pages.length-1;return this.touchActivity(e,s),this.setActivePage(e,r,s)}async closePage(e,s,i){const t=this.requireSession(e,i);if(!Number.isInteger(s)||s<0||s>=t.pages.length)throw new Error(`Page index ${s} out of range (0..${t.pages.length-1}) for agent ${e}/${t.browserId}`);const r=t.pages[s];if(r==null)throw new Error(`Page index ${s} out of range for agent ${e}/${t.browserId}`);if(s===t.activePageIndex)try{await t.screencast.stop(r)}catch{}try{await r.close()}catch{}if(t.pages.splice(s,1),t.pages.length===0){await this.close(e,i);return}t.activePageIndex>=t.pages.length?t.activePageIndex=t.pages.length-1:s<t.activePageIndex&&(t.activePageIndex-=1);const o=t.pages[t.activePageIndex];if(o==null)throw new Error(`No active page for agent ${e}/${t.browserId}`);if(!o.isClosed()){try{await t.screencast.start(o)}catch{}try{await t.listenerManager.reattach(o)}catch{}}this.touchActivity(e,i)}listSessions(e){const s=[];for(const i of this.sessions.values()){if(e&&i.agentId!==e)continue;const t=i.pages[i.activePageIndex];let r="";const o="";if(t&&!t.isClosed())try{r=t.url()}catch{}s.push({agentId:i.agentId,browserId:i.browserId,title:i.title,pageCount:i.pages.length,activePageIndex:i.activePageIndex,launchedAt:i.launchedAt,lastActivityAt:i.lastActivityAt,currentUrl:r,currentTitle:o})}return s}touchActivity(e,s){const i=s&&s.trim()?s.trim():l;for(const t of this.sessions.values())if(t.agentId===e&&t.browserId===i){t.lastActivityAt=Date.now();return}}async dispose(){this.stopIdleTimer();const e=Array.from(this.sessions.keys());await Promise.all(e.map(s=>{const i=this.sessions.get(s);return i?this.close(i.agentId,i.browserId):Promise.resolve()}))}requireSession(e,s){const i=s&&s.trim()?s.trim():l;for(const t of this.sessions.values())if(t.agentId===e&&t.browserId===i)return t;throw new Error(`Browser session not launched for ${e}/${s??l}`)}ensureIdleTimer(){this.idleTimer||this.config.idleTimeoutMs<=0&&this.config.maxSessionDurationMs<=0||(this.idleTimer=setInterval(()=>{this.checkIdleSessions()},U),this.idleTimer.unref&&this.idleTimer.unref())}stopIdleTimer(){this.idleTimer&&(clearInterval(this.idleTimer),this.idleTimer=null)}async checkIdleSessions(){const e=Date.now(),s=[];for(const i of this.sessions.values()){if(i.humanTakeover)continue;const t=e-i.lastActivityAt,r=e-i.launchedAt;if(this.config.idleTimeoutMs>0&&t>this.config.idleTimeoutMs){s.push(i);continue}this.config.maxSessionDurationMs>0&&r>this.config.maxSessionDurationMs&&s.push(i)}await Promise.all(s.map(i=>this.close(i.agentId,i.browserId)))}}let u=null;function ne(v){return u||(u=new J(v)),u}async function ae(){u&&(await u.dispose(),u=null)}export{J as BrowserPool,ae as disposeBrowserPool,ne as getBrowserPool,M as sanitizeLaunchArgs};
|
|
2
2
|
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import a from"node:fs";import C from"node:net";import{homedir as B}from"node:os";import r from"node:path";import{fileURLToPath as v}from"node:url";import{logger as M}from"./utils/logger.js";function h(e){return String(e??"").replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^\.+/g,"")}function U(){return String(process.env.AWS_RUNTIME_ENV||"").trim().toLowerCase()==="development"}function ee(){return String(process.env.AWS_BRIDGE_APP_MODE||"").trim().toLowerCase()==="desktop"}function H(){return String(process.env.AWS_BRIDGE_LISTEN_HOST||"").trim()||void 0}let
|
|
1
|
+
import a from"node:fs";import C from"node:net";import{homedir as B}from"node:os";import r from"node:path";import{fileURLToPath as v}from"node:url";import{logger as M}from"./utils/logger.js";function h(e){return String(e??"").replace(/[^a-zA-Z0-9_.-]/g,"_").replace(/^\.+/g,"")}function U(){return String(process.env.AWS_RUNTIME_ENV||"").trim().toLowerCase()==="development"}function ee(){return String(process.env.AWS_BRIDGE_APP_MODE||"").trim().toLowerCase()==="desktop"}function te(){return String(process.env.AWS_BRIDGE_SHELL_TOKEN||"").trim()}function H(){return String(process.env.AWS_BRIDGE_LISTEN_HOST||"").trim()||void 0}let E;function W(){if(E!==void 0)return E;const e=r.dirname(v(import.meta.url)),n=r.resolve(e,".."),t=r.resolve(n,".."),o=a.existsSync(r.join(t,".git"))||a.existsSync(r.join(t,"package.json"));return E=r.join(o?t:n,".dev-home"),E}function x(){return String(process.env.AWS_TEST_HOME||"").trim()||String(process.env.AWS_RUNTIME_HOME_DIR||"").trim()||B()}function m(){return U()?String(process.env.AWS_TEST_HOME||"").trim()||String(process.env.AWS_RUNTIME_HOME_DIR||"").trim()||W():x()}const j=18081,k=28081,D=Number(process.env.AWS_RUNTIME_BRIDGE_PORT||(U()?k:j));let T;function w(){return T??D}function y(e){T=e}function re(){T=void 0}function I(e){return new Promise(n=>{const t=C.createServer();t.once("error",o=>{const s=o.code==="EADDRINUSE"||o.code==="EACCES"||o.code==="EPERM";n(!s)}),t.once("listening",()=>{t.close(()=>n(!0))}),t.listen(e)})}async function P(e,n){return n?await I({port:e,host:n})?e:null:await I({port:e})&&await I({port:e,host:"0.0.0.0"})?e:null}async function F(e,n=20,t){let o=Math.floor(e);for(let c=0;c<n;c+=1){if(o>=1&&o<=65535){const i=await P(o,t);if(i!==null)return i}o+=1}return await P(0,t)??e}async function ne(e=D,n=H()){const t=await F(e,20,n);return y(t),process.env.AWS_RUNTIME_BRIDGE_PORT=String(t),t!==e&&M.warn(`[runtime-bridge] \u9996\u9009\u7AEF\u53E3 ${e} \u5DF2\u88AB\u5360\u7528\uFF0C\u81EA\u52A8\u6539\u7528 ${t} \u542F\u52A8`),t}const d="http://localhost:8080";function A(e){return e==null?void 0:String(e).trim()||void 0}function _(e){const n=A(e);if(!n)return;const t=n.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1");try{const o=new URL(t);return o.protocol==="ws:"?o.protocol="http:":o.protocol==="wss:"?o.protocol="https:":o.protocol=o.protocol.toLowerCase(),o.hostname=o.hostname.toLowerCase(),o.origin}catch{return t.replace(/\/+$/,"")}}function G(){return r.join(m(),".aws-bridge","config.json")}function b(){return r.join(m(),".aws-bridge","bridge-runtime.properties")}function oe(){const e=b();a.mkdirSync(r.dirname(e),{recursive:!0});const n=[`port=${w()}`,`pid=${process.pid}`,`startedAt=${new Date().toISOString()}`];a.writeFileSync(e,`${n.join(`
|
|
2
2
|
`)}
|
|
3
|
-
`,{encoding:"utf8",mode:384})}function f(){const e=G();try{if(!a.existsSync(e))return[];const n=JSON.parse(a.readFileSync(e,"utf-8")),t=i=>({serverUrl:_(i.serverUrl)||_(i.schedulerBaseUrl),instanceId:A(i.instanceId),instanceName:A(i.instanceName),userKey:A(i.userKey)}),s=(Array.isArray(n.autoRegisterTargets)?n.autoRegisterTargets:[]).filter(i=>!!(i&&typeof i=="object"&&!Array.isArray(i))).map(t).filter(i=>!!i.serverUrl);if(s.length>0)return s;const c=t(n);return c.serverUrl?[c]:[]}catch{return[]}}function K(){const n=f().map(t=>t.serverUrl).filter(t=>!!t);return Array.from(new Set(n))}function V(){return f().length}function
|
|
3
|
+
`,{encoding:"utf8",mode:384})}function f(){const e=G();try{if(!a.existsSync(e))return[];const n=JSON.parse(a.readFileSync(e,"utf-8")),t=i=>({serverUrl:_(i.serverUrl)||_(i.schedulerBaseUrl),instanceId:A(i.instanceId),instanceName:A(i.instanceName),userKey:A(i.userKey)}),s=(Array.isArray(n.autoRegisterTargets)?n.autoRegisterTargets:[]).filter(i=>!!(i&&typeof i=="object"&&!Array.isArray(i))).map(t).filter(i=>!!i.serverUrl);if(s.length>0)return s;const c=t(n);return c.serverUrl?[c]:[]}catch{return[]}}function K(){const n=f().map(t=>t.serverUrl).filter(t=>!!t);return Array.from(new Set(n))}function V(){return f().length}function ie(){return $(void 0)}function $(e,n,t){const o=_(e);if(o)return{url:o,source:"request",ambiguousTargetUrls:[]};const s=typeof n=="string"?n.trim():"",c=typeof t=="string"?t.trim():"";if(s||c){const R=f();let u;if(s&&(u=R.find(g=>g.instanceId===s)),!u&&c&&(u=R.find(g=>g.instanceName===c)),!u&&s&&!c&&(u=R.find(g=>g.instanceName===s)),u?.serverUrl)return{url:u.serverUrl,source:"instance-id-match",ambiguousTargetUrls:[],instanceId:u.instanceId,instanceName:u.instanceName,userKey:u.userKey}}const i=_(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL);if(i)return{url:i,source:"env",ambiguousTargetUrls:[]};const l=K(),N=V();return N===1&&l.length===1?{url:l[0]||d,source:"single-auto-register-target",ambiguousTargetUrls:[],userKey:f()[0]?.userKey}:N>1||l.length>1?{url:d,source:"ambiguous-auto-register-targets",ambiguousTargetUrls:l}:{url:d,source:"default",ambiguousTargetUrls:[]}}const se=_(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL)||d,ce=process.env.NODE_ENV||"development",ue=process.env.AWS_ALLOW_HOST_FILE_BROWSER==="true",ae=String(process.env.AWS_RUNTIME_CORS_ORIGINS||"http://localhost:3000,http://127.0.0.1:3000,http://localhost:5173,http://127.0.0.1:5173").split(",").map(e=>e.trim()).filter(e=>e.length>0);function pe(){}function le(e){return String(process.env.AWS_RUNTIME_CLAUDE_CONFIG_FILE||"").trim()||r.join(e,".claude","settings.json")}function ge(e){return String(process.env.AWS_RUNTIME_CLAUDE_MCP_CONFIG_FILE||"").trim()||r.join(e,".claude.json")}function _e(e){return String(process.env.AWS_RUNTIME_CLAUDE_SKILLS_DIR||"").trim()||r.join(e,".claude","skills")}function Se(e){return String(process.env.AWS_RUNTIME_OPENCODE_CONFIG_FILE||"").trim()||r.join(e,".config","opencode","opencode.json")}function L(){return r.join(m(),".aws-bridge")}function S(){return r.join(L(),"instance-template")}function Ee(){return String(process.env.AWS_RUNTIME_ACODE_CONFIG_FILE||"").trim()||r.join(S(),"config.json")}function de(){return String(process.env.AWS_RUNTIME_ACODE_SKILLS_DIR||"").trim()||r.join(S(),"skills")}function Ae(){return String(process.env.AWS_RUNTIME_ACODE_PLUGINS_DIR||"").trim()||r.join(S(),"plugins")}function z(){return r.join(S(),"mcp")}function fe(){return r.join(z(),"packages")}function Re(){return r.join(S(),"agents")}function p(e){return r.join(L(),"instance-runtime",h(String(e)))}function me(e){return r.join(p(e),"config.json")}function Te(e){return r.join(p(e),"skills")}function Ie(e){return r.join(p(e),"plugins")}function Oe(e){return r.join(p(e),"private-skills")}function Ne(e){return r.join(p(e),"private-skills.json")}function ve(e){return r.join(p(e),"mcp-extra.json")}function Ue(){return String(process.env.ACODE_HOME||"").trim()||r.join(x(),".acode")}function xe(e){return String(process.env.AWS_RUNTIME_CODEX_CONFIG_FILE||"").trim()||r.join(e,".codex","config.toml")}function De(e){return String(process.env.AWS_RUNTIME_CODEX_SKILLS_DIR||"").trim()||r.join(e,".codex","skills")}function Pe(e){return String(process.env.AWS_RUNTIME_OPENCODE_SKILLS_DIR||"").trim()||r.join(e,".opencode","skills")}const Le=Number(process.env.AWS_ORPHAN_SCAN_INTERVAL||3e4),Ce=process.env.AWS_ORPHAN_AUTO_CLEAN_MODE||"alert",Be=process.env.AWS_ORPHAN_SCAN_ENABLED!=="false",Me=Number(process.env.AWS_ORPHAN_UNRESPONSIVE_TIMEOUT||3e5),he=Number(process.env.AWS_ORPHAN_CPU_THRESHOLD||100),He=Number(process.env.AWS_ORPHAN_MEMORY_THRESHOLD||2048),We=process.env.AWS_AUTO_REGISTER==="true",je=process.env.AWS_TENANT_ID||"",ke=process.env.AWS_USER_KEY||"",we=process.env.AWS_INSTANCE_NAME||"",ye=process.env.AWS_PROJECT_NAME||"",Fe=process.env.AWS_ROLE_NAME||"",Ge=process.env.AWS_WORKSPACE_PATH||"",be=process.env.AWS_REGISTER_IP||process.env.AWS_VIRTUAL_IP||"";let O;function Ke(){if(O!==void 0)return O;let e="unknown";try{const n=r.dirname(v(import.meta.url)),t=r.resolve(n,"..","package.json");a.existsSync(t)&&(e=JSON.parse(a.readFileSync(t,"utf-8")).version||"unknown")}catch{}return O=e,e}export{We as AUTO_REGISTER_ENABLED,we as AUTO_REGISTER_INSTANCE_NAME,ye as AUTO_REGISTER_PROJECT_NAME,Fe as AUTO_REGISTER_ROLE_NAME,je as AUTO_REGISTER_TENANT_ID,ke as AUTO_REGISTER_USER_KEY,be as AUTO_REGISTER_VIRTUAL_IP,Ge as AUTO_REGISTER_WORKSPACE_PATH,j as DEFAULT_BRIDGE_PORT,d as DEFAULT_SCHEDULER_BASE_URL,k as DEV_DEFAULT_BRIDGE_PORT,Ce as ORPHAN_AUTO_CLEAN_MODE,he as ORPHAN_CPU_THRESHOLD,He as ORPHAN_MEMORY_THRESHOLD,Be as ORPHAN_SCAN_ENABLED,Le as ORPHAN_SCAN_INTERVAL,Me as ORPHAN_UNRESPONSIVE_TIMEOUT,ue as allowHostFileBrowser,ae as allowedCorsOrigins,F as findAvailableListenPort,Ue as getAcodeDataHome,w as getActiveBridgeHttpPort,G as getAutoRegisterConfigFilePath,L as getBridgeDataHome,me as getBridgeInstanceConfigFile,ve as getBridgeInstanceMcpExtraFile,Ie as getBridgeInstancePluginsDir,Oe as getBridgeInstancePrivateSkillsDir,Ne as getBridgeInstancePrivateSkillsManifest,p as getBridgeInstanceRuntimeDir,Te as getBridgeInstanceSkillsDir,H as getBridgeListenHost,b as getBridgeRuntimePropertiesFilePath,Re as getBridgeTemplateAgentsDir,Ee as getBridgeTemplateConfigFile,S as getBridgeTemplateDir,z as getBridgeTemplateMcpDir,fe as getBridgeTemplateMcpPackagesDir,Ae as getBridgeTemplatePluginsDir,de as getBridgeTemplateSkillsDir,Ke as getBridgeVersion,le as getClaudeConfigFile,ge as getClaudeMcpConfigFile,_e as getClaudeSkillsDir,xe as getCodexConfigFile,De as getCodexSkillsDir,Se as getOpencodeConfigFile,Pe as getOpencodeSkillsDir,m as getRuntimeHomeDir,te as getShellPairToken,x as getUserHomeDir,ee as isDesktopAppMode,U as isDevMode,ce as nodeEnv,D as port,ne as reserveBridgeListenPort,re as resetActiveBridgeHttpPort,ie as resolveSchedulerBaseUrl,$ as resolveSchedulerBaseUrlFrom,se as schedulerBaseUrl,y as setActiveBridgeHttpPort,pe as validateProductionToken,oe as writeBridgeRuntimePropertiesFile};
|
|
4
4
|
|