aws-runtime-bridge 1.9.182 → 1.9.184
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 +82 -0
- package/dist/adapter/AcodeSdkAdapter.d.ts +30 -1
- package/dist/adapter/AcodeSdkAdapter.js +3 -3
- package/dist/adapter/ClaudeSdkAdapter.d.ts +3 -1
- package/dist/adapter/ClaudeSdkAdapter.js +3 -3
- package/dist/adapter/CodexSdkAdapter.d.ts +3 -1
- package/dist/adapter/CodexSdkAdapter.js +2 -2
- package/dist/adapter/OpencodeSdkAdapter.d.ts +3 -1
- package/dist/adapter/OpencodeSdkAdapter.js +3 -3
- package/dist/adapter/types.d.ts +7 -1
- package/dist/index.js +1 -1
- package/dist/routes/terminal.d.ts +13 -0
- package/dist/routes/terminal.js +28 -28
- package/dist/services/agent-ownership.d.ts +16 -0
- package/dist/services/agent-ownership.js +2 -2
- package/dist/services/plugin-deployment.d.ts +14 -0
- package/dist/services/plugin-deployment.js +2 -2
- package/dist/services/plugin-manager.d.ts +3 -0
- package/dist/services/plugin-manager.js +4 -4
- package/dist/services/plugin-runtime.d.ts +10 -2
- package/dist/services/user-scope.d.ts +1 -0
- package/dist/services/user-scope.js +1 -1
- package/package/acode/dist/background-command-manager.d.ts +22 -0
- package/package/acode/dist/background-command-manager.js +5 -5
- package/package/acode/dist/built-in-file-tools.js +2 -2
- package/package/acode/dist/hibernation-journal.d.ts +67 -0
- package/package/acode/dist/hibernation-journal.js +2 -0
- package/package/acode/dist/index.d.ts +1 -0
- package/package/acode/dist/index.js +1 -1
- package/package/acode/dist/runtime-environment.d.ts +4 -1
- package/package/acode/dist/runtime-environment.js +3 -3
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +7 -0
- package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.js +4 -4
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +8 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +20 -20
- package/package/aws-client-agent-mcp/dist/types.d.ts +5 -0
- package/package.json +1 -1
package/dist/routes/terminal.js
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import{spawn as
|
|
2
|
-
`);if(r.length<=
|
|
1
|
+
import{spawn as Et}from"node:child_process";import{promises as ue}from"node:fs";import Rt from"node:os";import de from"node:path";import{TextDecoder as le}from"node:util";import{buildResumeContextBlock as He,deleteJournal as $t,readJournal as wt}from"@agentswork/acode";import Ke from"axios";import{Router as Ot}from"express";import{v4 as Dt}from"uuid";import{adapterRegistry as _,getToolActionInfo as Me,isTransientClipboardPasteFilePath as ze,redactTransientClipboardPastePaths as W,registerSdkProviders as Mt,resolveSdkProviderIdByCommand as Pt}from"../adapter/index.js";import{MESSAGE_POLLING_IDLE_PROMPT as We}from"../adapter/prompts.js";import{getActiveBridgeHttpPort as Lt,getAcodeDataHome as qe}from"../config.js";import{validateToken as h}from"../middleware/auth.js";import{registerAgentOwner as Ut}from"../services/agent-ownership.js";import{getAgentProcessManager as Pe}from"../services/agent-process-manager.js";import{loadAgentStartupMemories as xt}from"../services/agent-startup-memory.js";import{resolveSchedulerBaseUrlFromToken as Ye}from"../services/auto-register.js";import{setChangeCacheRetentionDays as Nt}from"../services/change-cache-retention.js";import{clearDebugMounts as fe}from"../services/debug-mount.js";import{getAllPushStats as jt,startHeartbeatScheduler as Bt}from"../services/event-delta-pusher.js";import{sweepExpiredSnapshots as Ft}from"../services/fileSnapshotStore.js";import{prepareAcodeInstanceConfig as vt,redactForLog as pe}from"../services/instance-ai-config-service.js";import{setAgentFeatures as Ht,setAgentCapabilities as Kt,setAgentInheritedFeatures as zt,setAgentCapabilitiesInherited as Wt,getAgentFeatures as qt,getAgentInheritedFeatures as Yt,getFeatureState as S,LAUNCH_ITEM_FEATURE_KEY as Ge,HIRE_FEATURE_KEY as Ve,PENCIL_FEATURE_KEY as Je,DRAW_FEATURE_KEY as Xe,OFFICE_FEATURE_KEY as Qe,COLLABORATION_TASK_FEATURE_KEY as Ze,COLLABORATION_MEETING_FEATURE_KEY as et,COLLABORATION_DEBUG_FEATURE_KEY as tt,COLLABORATION_FILE_HISTORY_FEATURE_KEY as nt,EMAIL_FEATURE_KEY as ot,SKILL_INSTALL_FEATURE_KEY as rt,ABILITY_DEV_FEATURE_KEY as st}from"../services/instance-features.js";import{setLogRetentionDays as Gt}from"../services/log-retention.js";import{enqueueMcpLaunchBinding as Vt}from"../services/mcp-launch-binding-queue.js";import{setPanelEnvVars as Jt,setAgentMeta as Xt}from"../services/panel-env.js";import{findClaudeCodeProcesses as Qt,isProcessRunning as Zt}from"../services/process-detector.js";import{forgetSession as q,onSdkToolUseEnd as en,onSdkToolUseStart as tn}from"../services/sdk-tool-file-change-recorder.js";import{bridgeEventBuffer as it,sendOutput as Y,sendQuestionRequest as nn,sendToolAuthRequest as on,sendStatus as $}from"../services/session-output.js";import{getSnapshotRetentionDays as Le,setSnapshotRetentionDays as rn}from"../services/snapshot-retention.js";import{findPersistedSessionByAgentId as sn,removePersistedSession as G,savePersistedSessions as an,updatePersistedSessionAutoCommands as cn,updatePersistedSessionRuntimeState as un,upsertPersistedSession as dn}from"../services/terminal-persistence.js";import{extractUserScope as ln,normalizeUserScope as fn}from"../services/user-scope.js";import{getInstanceAiConfigDebugLogger as pn}from"../utils/instance-ai-config-debug-logger.js";import{logger as l}from"../utils/logger.js";const T=Ot();function at(e){const n=e.header("X-Runtime-Token");return n&&n.trim()?n.trim():(e.header("Authorization")||"").match(/^Bearer\s+(.+)$/i)?.[1]?.trim()||void 0}const f=new Map,mn=45e3,me=new Map;function gn(e){if(me.has(e))return;const n=setInterval(()=>{const t=f.get(e);if(!t){U(e);return}const o=t.currentRuntimeStatus;if(o!=="thinking"&&o!=="tool_using"&&o!=="compacting"){U(e);return}$(t.agentId,e,o,void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl}).catch(()=>{})},mn);me.set(e,n)}function U(e){const n=me.get(e);n&&(clearInterval(n),me.delete(e))}const ct=4e3,yn=200,In=2e3,ut=24e3,dt=200,lt=8e3;function Sn(e){if(!Array.isArray(e)||e.length===0)return{snapshot:"",truncated:!1};const n=[];let t=null,o=[];const s=()=>{if(t===null)return;const u=o.join("").trim();if(o=[],!u){t=null;return}const d=t==="user"?"\u7528\u6237":t==="assistant"?"\u52A9\u624B":t;n.push(`\u3010${d}\u3011${ge(u,In)}`),t=null};for(const u of e){const d=String(u?.role||"").trim();if(!d||d==="system")continue;if(d==="tool_use"||d==="tool_result"){s();const p=String(u.toolName||"").trim()||"\u672A\u77E5\u5DE5\u5177";if(hn(p))continue;if(d==="tool_use"){const y=_n(String(u.content||""));n.push(`\u3010\u5DE5\u5177\u8C03\u7528\u3011${p}${y?` ${y}`:""}`)}else{const y=ge(String(u.content||"").trim(),yn);n.push(`\u3010\u5DE5\u5177\u7ED3\u679C\u3011${p}${u.isError?"\uFF08\u5931\u8D25\uFF09":""}${y?`\uFF1A${y}`:""}`)}continue}const g=String(u.content||"");g.trim()&&(t===d||(s(),t=d),o.push(g))}if(s(),n.length===0)return{snapshot:"",truncated:!1};const r=n.join(`
|
|
2
|
+
`);if(r.length<=ut)return{snapshot:r,truncated:!1};const i=ut-lt,a=r.slice(0,lt),c=r.slice(r.length-i);return{snapshot:`${a}
|
|
3
3
|
|
|
4
4
|
...\uFF08\u6B64\u5904\u7701\u7565\u4E2D\u6BB5 ${r.length-a.length-c.length} \u5B57\u7B26\u5386\u53F2\uFF09...
|
|
5
5
|
|
|
6
|
-
${c}`,truncated:!0}}function
|
|
6
|
+
${c}`,truncated:!0}}function ge(e,n){const t=String(e??"");return t.length<=n?t:`${t.slice(0,n)}...\uFF08\u622A\u65AD ${t.length-n} \u5B57\u7B26\uFF09`}function hn(e){const n=e.toLowerCase();return n.includes("poll_message")||n.includes("get_message")||n.includes("await_complete")}function Tn(e){if(typeof e!="string"||!e.trim())return Array.isArray(e)&&e.length>0?e:void 0;try{const n=JSON.parse(e);if(!Array.isArray(n)||n.length===0)return;const t=new Set(["system","user","assistant","tool"]),o=1e6,r=n.filter(i=>!!i&&typeof i=="object"&&t.has(String(i.role))).filter(i=>JSON.stringify(i).length<=o).slice(0,5e3);return r.length>0?r:void 0}catch{return}}function An(e){if(!(typeof e!="string"||!e.trim()))try{const n=JSON.parse(e);if(!n||typeof n!="object"||Array.isArray(n))return;const t=a=>{const c=Number(a);return Number.isFinite(c)&&c>=0?c:void 0},o=t(n.totalInputTokens),s=t(n.totalOutputTokens),r=t(n.cacheHitTokens),i=t(n.cacheMissTokens);return o===void 0&&s===void 0&&r===void 0&&i===void 0?void 0:{...o!==void 0?{totalInputTokens:o}:{},...s!==void 0?{totalOutputTokens:s}:{},...r!==void 0?{cacheHitTokens:r}:{},...i!==void 0?{cacheMissTokens:i}:{}}}catch{return}}const kn="\u6CE8\u610F\uFF1A\u4E0A\u6B21\u8FD0\u884C\u56E0\u610F\u5916\u4E2D\u65AD\u5BFC\u81F4\u672C\u5B9E\u4F8B\u8FDB\u5165\u4E86\u4F11\u7720\uFF0C\u4E0A\u9762\u7684\u5FEB\u7167\u662F\u4E2D\u65AD\u524D\u6700\u540E\u4E00\u6B21\u81EA\u52A8\u4FDD\u5B58\u7684\u8FDB\u5EA6\uFF0C\u90E8\u5206\u6700\u8FD1\u7684\u5DE5\u4F5C\u72B6\u6001\u53EF\u80FD\u5DF2\u7ECF\u4E22\u5931\u3002\u9047\u5230\u4E2D\u65AD\u5BFC\u81F4\u4F60\u8FDB\u5165\u4E86\u4F11\u7720\uFF0C\u90E8\u5206\u5DE5\u4F5C\u72B6\u6001\u53EF\u80FD\u5DF2\u7ECF\u4E22\u5931\uFF0C\u8BF7\u7EE7\u7EED\u5DE5\u4F5C\uFF01\u884C\u52A8\u524D\u5148\u81EA\u67E5\u73B0\u573A\uFF08\u8BFB\u6587\u4EF6/poll_message\uFF09\uFF0C\u786E\u8BA4\u4E0A\u4E00\u6B65\u662F\u5426\u5DF2\u843D\u76D8\uFF0C\u518D\u7EE7\u7EED\u63A8\u8FDB\u672A\u5B8C\u6210\u7684\u4E8B\u9879\u3002",ft="\u6CE8\u610F\uFF1A\u672C\u5B9E\u4F8B\u4E0A\u6B21\u6B63\u5E38\u7ED3\u675F\u8FD0\u884C\u5E76\u81EA\u52A8\u4FDD\u5B58\u4E86\u5B8C\u6574\u8FDB\u5EA6\u3002\u8BF7\u57FA\u4E8E\u5FEB\u7167\u7EE7\u7EED\u63A8\u8FDB\u672A\u5B8C\u6210\u7684\u4E8B\u9879\u3002";function _n(e){const n=String(e??"").trim();if(!n)return"";let t;try{const s=JSON.parse(n);if(!s||typeof s!="object"||Array.isArray(s))return"";t=s}catch{return ge(n,dt)}const o=[];for(const s of["file_path","path","filePath","pattern","query","command","cmd","url"]){const r=t[s];if(typeof r=="string"&&r.trim()&&o.push(`${s}=${r.trim()}`),o.length>=3)break}if(o.length===0){const s=Object.keys(t).slice(0,5);return s.length>0?`(${s.join(", ")})`:""}return ge(o.join(" "),dt)}function pt(e){if(e==null||typeof e!="object"||Array.isArray(e))return;const n=e,t={};return typeof n.model=="string"&&n.model.trim()&&(t.model=n.model.trim()),typeof n.baseURL=="string"&&n.baseURL.trim()&&(t.baseURL=n.baseURL.trim()),typeof n.apiKey=="string"&&n.apiKey.trim()&&(t.apiKey=n.apiKey.trim()),typeof n.effort=="string"&&n.effort.trim()&&(t.effort=n.effort.trim()),t}const V=new Set;function bn(e,n){return e!=="acode"?{supported:!1,statusCode:400,error:"context reset without restart is only supported by ACode"}:n?{supported:!0}:{supported:!1,statusCode:500,error:"ACode adapter does not expose resetContext"}}function Cn(e){return e!=="acode"}function En(e){const n=typeof e=="object"&&e!==null&&"suppressStatus"in e&&e.suppressStatus===!0,t=typeof e=="object"&&e!==null&&"reason"in e&&typeof e.reason=="string"&&e.reason.trim()?e.reason.trim():void 0,o=typeof e=="object"&&e!==null&&"discardContext"in e&&e.discardContext===!0;return{statusNotified:!n,reason:t,discardContext:o}}function Z(e){const n=e?.usage;if(!n)return;const t=Number.isFinite(n.inputTokens)?n.inputTokens:0,o=Number.isFinite(n.outputTokens)?n.outputTokens:0;if(t<=0&&o<=0&&!n.contextLimit&&!n.maxOutput&&!n.inputLimit&&!n.compactionThreshold&&n.totalInputTokens===void 0&&n.totalOutputTokens===void 0)return;const s={inputTokens:t,outputTokens:o,...n.contextLimit?{contextLimit:n.contextLimit}:{},...n.maxOutput?{maxOutput:n.maxOutput}:{},...n.inputLimit?{inputLimit:n.inputLimit}:{},...n.compactionThreshold?{compactionThreshold:n.compactionThreshold}:{},...n.cacheHitTokens!==void 0?{cacheHitTokens:n.cacheHitTokens}:{},...n.cacheMissTokens!==void 0?{cacheMissTokens:n.cacheMissTokens}:{},...n.totalInputTokens!==void 0?{totalInputTokens:n.totalInputTokens}:{},...n.totalOutputTokens!==void 0?{totalOutputTokens:n.totalOutputTokens}:{}};return process.env.ACODE_TOKEN_DEBUG==="1"&&(s.inputTokens>0||s.outputTokens>0||s.cacheHitTokens!==void 0||s.cacheMissTokens!==void 0||s.totalInputTokens!==void 0||s.totalOutputTokens!==void 0)&&l.info(`[TokenDebug][Terminal] resolveStatusChangeUsage: input=${s.inputTokens} output=${s.outputTokens} cacheHit=${s.cacheHitTokens??"(none)"} cacheMiss=${s.cacheMissTokens??"(none)"} totalInput=${s.totalInputTokens??"(none)"} totalOutput=${s.totalOutputTokens??"(none)"} actionType=${e?.actionType??"(none)"}`),s}function Rn(e,n){const t=String(e||"").trim().toLowerCase(),o=String(n?.actionType||"").trim().toLowerCase();return t==="tool_using"&&o==="idle"?n?{status:"waiting_input",actionInfo:n}:{status:"waiting_input"}:n?{status:e,actionInfo:n}:{status:e}}function $n(e){return e.restoredActionInfo?.actionType==="idle"||e.currentRuntimeActionType==="idle"&&e.shouldPreservePrevAction||e.status==="waiting_input"&&!e.actionInfo?.actionType}function wn(e){return e.actionInfo?.actionType?!1:!!e.usage}const ee=new Map,On="utf-8",mt="utf-8",gt=300,yt=6e4;function te(e){return String(e).padStart(2,"0")}function Dn(e,n=new Date){const t=n.getFullYear(),o=te(n.getMonth()+1),s=te(n.getDate()),r=te(n.getHours()),i=te(n.getMinutes()),a=`${t}${o}${s}-${r}${i}${te(n.getSeconds())}-${String(n.getMilliseconds()).padStart(3,"0")}`;return de.join(qe(),"cmd-dist",e,`${t}-${o}-${s}`,r,i,`${a}-cmd.out`)}function Mn(e){if(!e)return 0;const n=e.replace(/\r\n/g,`
|
|
7
7
|
`).replace(/\r/g,`
|
|
8
8
|
`),t=n.endsWith(`
|
|
9
9
|
`)?n.slice(0,-1):n;return t?t.split(`
|
|
10
|
-
`).length:1}function
|
|
10
|
+
`).length:1}function Pn(e,n=gt){return`\r
|
|
11
11
|
[ACode] \u547D\u4EE4\u8F93\u51FA\u8D85\u8FC7 ${n} \u884C\uFF0C\u5B8C\u6574\u8F93\u51FA\u5DF2\u5199\u5165: ${e}\r
|
|
12
12
|
[ACode] Agent \u53EF\u81EA\u884C\u8BFB\u53D6\u8BE5\u6587\u4EF6\uFF0C\u6216\u5728\u8BE5\u6587\u4EF6\u4E2D\u641C\u7D22\u9700\u8981\u7684\u5185\u5BB9\u3002\r
|
|
13
|
-
`}function
|
|
13
|
+
`}function Ln(e=yt){return`\r
|
|
14
14
|
[ACode] \u547D\u4EE4\u8D85\u8FC7 ${Math.round(e/1e3)} \u79D2\u6CA1\u6709\u65B0\u7684\u8F93\u51FA\uFF0C\u5DF2\u505C\u6B62\u6267\u884C\u5E76\u4FDD\u7559\u6B64\u524D\u8F93\u51FA\u3002\r
|
|
15
|
-
`}async function
|
|
16
|
-
`).trim()}function
|
|
17
|
-
`),!0;const s=
|
|
18
|
-
`),!0):(
|
|
19
|
-
`),!0)}catch(r){const i=r instanceof Error?r.message:String(r);return
|
|
20
|
-
`),!0}}async function
|
|
21
|
-
`),
|
|
22
|
-
`),
|
|
23
|
-
[ACode] \u547D\u4EE4\u8F93\u51FA\u843D\u76D8\u5931\u8D25: ${
|
|
24
|
-
`)});return}
|
|
25
|
-
[Terminal Error] ${
|
|
26
|
-
`)}),a.on("close",(
|
|
27
|
-
[ACode] \u547D\u4EE4\u8F93\u51FA\u6700\u7EC8\u843D\u76D8\u5931\u8D25: ${
|
|
28
|
-
`)}),
|
|
29
|
-
[exit ${
|
|
30
|
-
`):
|
|
31
|
-
[signal ${
|
|
32
|
-
`),
|
|
33
|
-
...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function
|
|
15
|
+
`}async function It(e){const n=e.outputPath||Dn(e.agentId,e.startedAt);return e.outputPath=n,await ue.mkdir(de.dirname(n),{recursive:!0}),await ue.writeFile(n,e.chunks.join(""),"utf-8"),n}function Un(e){return String(e??"").replace(/\r/g,`
|
|
16
|
+
`).trim()}function xn(e=process.platform,n=process.env){const t=n.AWS_TERMINAL_OUTPUT_ENCODING?.trim();return t||(e==="win32"?On:mt)}function St(e=xn()){if(e!=="utf-8")try{return new le(e,{fatal:!1})}catch{return new le(mt,{fatal:!1})}return Nn()}function Nn(){let e=null,n=null,t=null;const o=[];function s(r){try{return new le(r,{fatal:!1})}catch{return new le("utf-8",{fatal:!1})}}return{decode(r,i){if(r!=null&&o.push(r instanceof ArrayBuffer?Buffer.from(r):Buffer.isBuffer(r)?r:Buffer.from(r.buffer,r.byteOffset,r.byteLength)),t==="gb18030")return n||(n=s("gb18030")),n.decode(r,i);e||(e=s("utf-8"));const a=e.decode(r,i);if(t===null&&a.includes("\uFFFD")){t="gb18030",n=s("gb18030");const c=Buffer.concat(o);return n.decode(c)}return t===null&&!i?.stream&&(t="utf-8"),a}}}function ye(e,n,t=!1){return t?e.decode():!n||n.length===0?"":e.decode(n,{stream:!0})}function jn(e){const n=e.trim().match(/^cd(?:\s+(.*))?$/i);if(!n)return;const t=n[1]?.trim();if(!t)return null;const o=t.replace(/^\/d\s+/i,"").trim();return o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'")?o.slice(1,-1):o}function Bn(e){const n=ee.get(e.sessionId);if(n)return n;const t={currentDirectory:e.workspacePath,runningProcess:null};return ee.set(e.sessionId,t),t}function ht(e){for(const n of f.values())if(n.agentId===e)return n}async function Fn(e){const n=_.get(e.providerId||"claude-code"),t=ne(n.getSessionStatus(e.sessionId),e.currentRuntimeStatus,e.currentRuntimeActionType);return{sessionId:e.sessionId,status:t,runtimeStatus:t,runtimeActionType:e.currentRuntimeActionType,runtimeActionLabel:e.currentRuntimeActionLabel,runtimeActionDetail:e.currentRuntimeActionDetail,agentId:e.agentId,workspacePath:e.workspacePath,command:e.config.command,mode:"sdk",providerSessionId:n.getProviderSessionId(e.sessionId),reused:!0}}function ne(e,n,t){const o=String(e||"").trim();if(o){const r=String(n||"").trim(),i=String(t||"").trim().toLowerCase();return o.toLowerCase()==="tool_using"&&r.toLowerCase()==="waiting_input"&&i==="idle"?r:o}return String(n||"").trim()||"running"}async function vn(e,n=Zt){return e.pid?await n(e.pid)?bt(e.command)==="acode"?{reusable:!1,reason:"in-process-provider"}:{reusable:!0,reason:"active-pid"}:{reusable:!1,reason:"dead-pid"}:{reusable:!1,reason:"missing-pid"}}function ar(e){try{fe(e)}catch(t){l.warn(`[cleanupSdkSessionByAgentId] clear debug mounts failed for agentId=${e}: ${t}`)}const n=ht(e);if(!n)l.info(`[cleanupSdkSessionByAgentId] No active SDK session found for agentId=${e}, cleaning residual state anyway`);else{const t=n.sessionId;return l.info(`[cleanupSdkSessionByAgentId] Cleaning up SDK session for agentId=${e}, sessionId=${t}`),U(t),f.delete(t),q(t),Ie(t),G(t).catch(o=>{l.warn(`[cleanupSdkSessionByAgentId] Failed to remove persisted session for agentId=${e}: ${o}`)}),t}V.has(e)&&(V.delete(e),l.info(`[cleanupSdkSessionByAgentId] Released startingAgents lock for agentId=${e}`))}function Ie(e){const n=ee.get(e);if(!n?.runningProcess){ee.delete(e);return}try{n.runningProcess.kill()}catch{}finally{n.runningProcess=null,ee.delete(e)}}function E(e,n){n&&(e.seq+=1,Y(e.agentId,n,e.sessionId,e.seq,void 0,{runtimeAccessToken:e.runtimeAccessToken,schedulerBaseUrl:e.schedulerBaseUrl}).catch(()=>{}))}function Ue(e){return`\x1B[36m${e}>\x1B[0m `}function Hn(e,n){return n==="~"?Rt.homedir():de.resolve(e,n)}async function Kn(e,n,t){const o=jn(t);if(o===void 0)return!1;if(o===null)return E(e,`${n.currentDirectory}\r
|
|
17
|
+
`),!0;const s=Hn(n.currentDirectory,o);try{return(await ue.stat(s)).isDirectory()?(n.currentDirectory=s,E(e,`${n.currentDirectory}\r
|
|
18
|
+
`),!0):(E(e,`cd: not a directory: ${s}\r
|
|
19
|
+
`),!0)}catch(r){const i=r instanceof Error?r.message:String(r);return E(e,`cd: ${i}\r
|
|
20
|
+
`),!0}}async function zn(e,n){const t=f.get(e);if(!t)throw new Error("SDK session not found");const o=Un(n),s=Bn(t);if(!o)return{started:!1,cwd:s.currentDirectory};if(s.runningProcess)throw new Error("A terminal command is already running for this session");const r=W(o);if(E(t,`${Ue(s.currentDirectory)}${r}\r
|
|
21
|
+
`),ze(o))return E(t,`[Terminal Warning] \u68C0\u6D4B\u5230\u526A\u8D34\u677F\u4E34\u65F6 paste \u6587\u4EF6\u8DEF\u5F84\uFF0C\u5DF2\u8DF3\u8FC7\u6267\u884C\u3002\u8BF7\u7C98\u8D34\u6587\u4EF6\u5185\u5BB9\u6216\u4F7F\u7528\u663E\u5F0F\u8BFB\u53D6\u547D\u4EE4\u3002\r
|
|
22
|
+
`),E(t,Ue(s.currentDirectory)),{started:!1,cwd:s.currentDirectory};if(await Kn(t,s,o))return{started:!1,cwd:s.currentDirectory};await $(t.agentId,e,"tool_using",{actionType:"bash",actionLabel:"\u7EC8\u7AEF\u547D\u4EE4",actionDetail:r},void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl});const a=Et(o,{cwd:s.currentDirectory,shell:!0,env:Tt(t.agentId,t.workspacePath,process.env,t.config.envOverrides)});s.runningProcess=a;const c=St(),u=St(),d=t.providerId==="acode",g={agentId:t.agentId,startedAt:new Date,chunks:[],spilled:!1};let p;const y=()=>{p&&(clearTimeout(p),p=void 0)},C=()=>{y(),p=setTimeout(()=>{s.runningProcess===a&&(E(t,Ln()),a.kill())},yt)},w=(I,P=!0)=>{if(I&&(d&&g.chunks.push(I),d&&P&&C(),!(d&&g.spilled))){if(d&&Mn(g.chunks.join(""))>gt){g.spilled=!0,It(g).then(b=>{E(t,Pn(b))}).catch(b=>{const K=b instanceof Error?b.message:String(b);E(t,`\r
|
|
23
|
+
[ACode] \u547D\u4EE4\u8F93\u51FA\u843D\u76D8\u5931\u8D25: ${K}\r
|
|
24
|
+
`)});return}E(t,I)}};return d&&C(),a.stdout.on("data",I=>{w(ye(c,I))}),a.stderr.on("data",I=>{w(ye(u,I))}),a.on("error",I=>{E(t,`\r
|
|
25
|
+
[Terminal Error] ${I.message}\r
|
|
26
|
+
`)}),a.on("close",(I,P)=>{y(),s.runningProcess=null,w(ye(c,void 0,!0),!1),w(ye(u,void 0,!0),!1),g.spilled&&It(g).catch(b=>{const K=b instanceof Error?b.message:String(b);E(t,`\r
|
|
27
|
+
[ACode] \u547D\u4EE4\u8F93\u51FA\u6700\u7EC8\u843D\u76D8\u5931\u8D25: ${K}\r
|
|
28
|
+
`)}),I&&I!==0?E(t,`\r
|
|
29
|
+
[exit ${I}]\r
|
|
30
|
+
`):P&&E(t,`\r
|
|
31
|
+
[signal ${P}]\r
|
|
32
|
+
`),E(t,Ue(s.currentDirectory)),$(t.agentId,e,"waiting_input",void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl})}),{started:!0,cwd:s.currentDirectory}}function Tt(e,n,t,o,s){const r={};for(const[i,a]of Object.entries(t))a!==void 0&&(r[i]=a);if(n&&(r.AWS_WORKSPACE_PATH=String(n)),s&&String(s).trim()&&(r.AWS_PROJECT_ROOT=String(s).trim()),o)for(const[i,a]of Object.entries(o)){const c=i.trim();if(!c||a===void 0||a===null)continue;const u=String(a).trim();u&&(r[c]=u)}return r.AWS_AGENT_ID=String(e),r.AWS_MCP_CLAIM_LAUNCH_BINDING="true",r.AWS_RUNTIME_BRIDGE_BASE_URL=`http://127.0.0.1:${Lt()}`,String(r.ACODE_HOME||"").trim()||(r.ACODE_HOME=qe()),S(e,Ge)!=="disabled"&&(r.AWS_LAUNCH_CONFIG_TOOLS=S(e,Ge)),S(e,Ve)!=="disabled"&&(r.AWS_HIRE_TOOLS=S(e,Ve)),S(e,Je)!=="disabled"&&(r.AWS_PENCIL_TOOLS=S(e,Je)),S(e,Xe)!=="disabled"&&(r.AWS_DRAW_TOOLS=S(e,Xe)),S(e,Qe)!=="disabled"&&(r.AWS_OFFICE_TOOLS=S(e,Qe)),S(e,Ze)!=="disabled"&&(r.AWS_COLLABORATION_TASK_TOOLS=S(e,Ze)),S(e,et)!=="disabled"&&(r.AWS_COLLABORATION_MEETING_TOOLS=S(e,et)),S(e,tt)!=="disabled"&&(r.AWS_COLLABORATION_DEBUG_TOOLS=S(e,tt)),S(e,nt)!=="disabled"&&(r.AWS_COLLABORATION_FILE_HISTORY_TOOLS=S(e,nt)),S(e,ot)!=="disabled"&&(r.AWS_EMAIL_TOOLS=S(e,ot)),S(e,rt)!=="disabled"&&(r.AWS_ABILITY_MARKET_TOOLS=S(e,rt)),S(e,st)!=="disabled"&&(r.AWS_ABILITY_DEV_TOOLS=S(e,st)),r}function Wn(e){const n=e.trim(),t=n[0],o=n[n.length-1];return(t==='"'||t==="'")&&t===o?n.slice(1,-1):n}async function qn(e){const n=String(e);if(!ze(n))return n;const t=Wn(n);return de.isAbsolute(t)?ue.readFile(t,"utf-8"):n}function Yn(e,n){const t={};for(const s of[e?.env,n])if(s)for(const[r,i]of Object.entries(s)){const a=r.trim();if(!a||i===void 0||i===null)continue;const c=String(i).trim();c&&(t[a]=c)}const o=t.ANTHROPIC_MODEL?.trim()||t.CODEX_MODEL?.trim()||void 0;return{envOverrides:t,model:o}}function Gn(e){if(e==null)return;const t=(typeof e=="string"?e:JSON.stringify(e,null,2)).trim();if(t)return t.length<=ct?t:`${t.slice(0,ct)}
|
|
33
|
+
...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function Vn(e){try{const n=JSON.parse(e);if(n&&typeof n=="object"&&!Array.isArray(n))return["directMessages","groupMessages","messages"].some(t=>Array.isArray(n[t])&&n[t].length>0)}catch{}return e.trim().length>0}function Jn(e){if(e.data.actionType==="mcp")return!0;const t=String(e.data.toolName||"").toLowerCase();return t.startsWith("mcp__")||t.includes("-mcp__")||t.includes("mcp_")}function Xn(e){if(e.type!=="tool_use_end")return;const n=Gn(e.data.toolResult??e.data.actionResult);if(!n)return;const t=Me(e.data.toolName,e.data.toolInput),o=e.data.actionType||t.actionType;if(o==="idle"){const s=String(e.data.rawToolName||e.data.toolName||"").toLowerCase();if((s.includes("poll_message")||s.includes("get_message"))&&!Vn(n))return}return o==="mcp"&&Jn(e)?{actionType:"mcp",actionLabel:"MCP\u8FD4\u56DE",actionDetail:e.data.actionDetail||e.data.toolName,actionId:e.data.actionId||e.data.toolUseId,actionResult:n,...e.data.parentId?{parentId:e.data.parentId}:{}}:{actionType:o,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:e.data.actionDetail||t.actionDetail||e.data.toolName,actionId:e.data.actionId||e.data.toolUseId,actionResult:n,...e.data.parentId?{parentId:e.data.parentId}:{}}}function Qn(e){if(e.type==="ai_request"){const n=e.data.model?` ${e.data.model}`:"",t=e.data.lastUserMessagePreview?`\uFF1A${e.data.lastUserMessagePreview}`:"";return`\r
|
|
34
34
|
[ACode] \u6B63\u5728\u8BF7\u6C42\u6A21\u578B${n}${t}\r
|
|
35
35
|
`}if(e.type==="text_delta"||e.type==="thinking"||e.type==="compaction_summary"||e.type==="command_output")return e.data.text||void 0;if(e.type==="error")return e.data.text?`\r
|
|
36
36
|
[SDK Error] ${e.data.text}\r
|
|
37
|
-
`:void 0}function
|
|
38
|
-
...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function to(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function no(e,n){if(!to(e,n)){if(e.type==="background_command_completed")return{status:"tool_result",actionInfo:{actionType:"background_command",actionLabel:"\u540E\u53F0\u547D\u4EE4",actionDetail:"background_command_completed"}};if(e.type==="thinking"||e.type==="text_delta")return{status:"thinking"};if(e.type==="tool_use_start"){const t=$e(e.data.toolName,e.data.toolInput),o=gt(e,t),s=eo(e.data.toolInput);return e.data.actionType==="idle"||t.actionType==="idle"?{status:"waiting_input",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:o||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:s,actionId:e.data.actionId||e.data.toolUseId}}:{status:"tool_using",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:o||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:s,actionId:e.data.actionId||e.data.toolUseId,...e.data.batchId?{parentId:e.data.batchId}:{}}}}if(e.type==="turn_complete")return{status:"waiting_input",actionInfo:e.data.usage?{usage:e.data.usage}:void 0};if(e.type==="error")return{status:"error"};if(e.type==="context_compaction")return{status:"compacting",actionInfo:{actionType:"context_compaction",actionLabel:e.data.actionLabel,actionDetail:e.data.actionDetail,...e.data.actionId?{actionId:e.data.actionId}:{},...e.data.parentId?{parentId:e.data.parentId}:{}}};if(e.type==="runtime_capabilities")return{status:n||"waiting_input",actionInfo:{actionType:"runtime_capabilities",actionLabel:e.data.actionLabel||"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:e.data.actionDetail}};if(e.type==="tool_batch_start"){const t=e.data.batchId;return t?{status:"tool_result",actionInfo:{actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionDetail:e.data.actionDetail,actionId:t}}:void 0}if(e.type==="tool_batch_metrics"){const t=e.data.batchId;return t?{status:"tool_result",actionInfo:{actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionId:t,batchId:t,...e.data.batchMetrics?{batchMetrics:e.data.batchMetrics}:{}}}:void 0}}}const U=new Map,me=new Map,ge=new Map;async function Me(e){const{entry:n,sessionId:t,actionInfo:o,timestamp:s,sourceEventType:r,backoffBaseMs:i,label:a}=e,c={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl},u=3;for(let d=0;d<u;d++){if(await R(n.agentId,t,"tool_result",o,void 0,c,s,r)!==void 0)return;d<u-1&&await new Promise(m=>setTimeout(m,i*(d+1)))}l.warn(`[Runtime] ${a} tool_result sendStatus retry exhausted (result may be lost): agentId=${n.agentId}`)}const ee=new Map,oo=20,ro=500,so=3e4;async function ye(e,n=so,t=2){for(let o=0;o<=t;o++){const s=new AbortController;let r;try{const i=e(s.signal);i.catch(()=>{}),await Promise.race([i,new Promise((a,c)=>{r=setTimeout(()=>{s.abort(),c(new Error(`sendOutput timeout after ${n}ms`))},n)})]),r&&clearTimeout(r);return}catch(i){r&&clearTimeout(r);const a=i instanceof Error?i.message:String(i);if(o<t){const c=1e3*(o+1);l.warn(`sendOutput attempt ${o+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(u=>setTimeout(u,c));continue}l.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}async function io(e,n,t,o,s,r){try{await H(e,n,t,o,{...s,sourceEventType:"compaction_summary",skipLocalPersist:!0},r)}catch(i){l.debug("Compaction summary realtime push failed (non-persisted)",{agentId:e,sessionId:t,error:i instanceof Error?i.message:String(i)})}}const Ie=new Map,ao=120,co=120;function uo(e,n,t,o){const s=`${n}:compaction_summary`;let r=Ie.get(s);if(r||(r={buffer:"",timer:null,entry:e,sessionId:n,seq:o},Ie.set(s,r)),r.buffer+=t,r.seq=o,r.entry=e,r.buffer.length>=ao){Pe(n);return}r.timer||(r.timer=setTimeout(()=>Pe(n),co))}function Pe(e){const n=`${e}:compaction_summary`,t=Ie.get(n);if(!t)return;t.timer&&(clearTimeout(t.timer),t.timer=null);const o=t.buffer;Ie.delete(n),o&&io(t.entry.agentId,o,t.sessionId,t.seq,{sourceEventType:"compaction_summary",skipLocalPersist:!0},{runtimeAccessToken:t.entry.runtimeAccessToken,schedulerBaseUrl:t.entry.schedulerBaseUrl})}function Se(e,n){const t=n?`${e}:${n}`:void 0;let o,s;if(t)o=ee.get(t),s=t;else{const g=[];for(const[b,E]of ee)b.startsWith(e+":")&&E.buffer&&g.push(E.sourceEventType);for(const b of g)Se(e,b);return}if(!o||!o.buffer)return;o.timer=null;const r=o.buffer,i=o.seq,a=o.entry,c=o.sourceEventType;o.buffer="",s&&ee.delete(s);const u={sourceEventType:c,logCategory:"acode"},d={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},m=(U.get(e)??Promise.resolve()).then(()=>ye(g=>H(a.agentId,r,e,i,u,d,g)),()=>ye(g=>H(a.agentId,r,e,i,u,d,g)));U.set(e,m),m.finally(()=>{U.get(e)===m&&U.delete(e)})}function lo(e,n){const t=qn(e);if(!t)return;n.seq+=1;const o=n.seq,s=zn(e),r={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if(e.type==="compaction_summary"){uo(n,e.sessionId,t,o);return}if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<oo){const c=`${e.sessionId}:${e.type}`;let u=ee.get(c);if(u||(u={buffer:"",seq:0,timer:null,entry:n,sourceEventType:e.type}),u.buffer+=t,u.seq=o,u.entry=n,!u.timer){const d=e.sessionId,p=e.type;u.timer=setTimeout(()=>Se(d,p),ro)}ee.set(c,u);return}Se(e.sessionId);const a=(U.get(e.sessionId)??Promise.resolve()).then(()=>ye(c=>H(n.agentId,t,e.sessionId,o,s,r,c)),()=>ye(c=>H(n.agentId,t,e.sessionId,o,s,r,c)));U.set(e.sessionId,a),a.finally(()=>{U.get(e.sessionId)===a&&U.delete(e.sessionId)})}function It(e){return Et(e)}let St=!1;function fo(){St||(Ct(A,po),Mt(),St=!0)}function po(e,n){e.on("event",t=>{const o=f.get(t.sessionId);if(o){if(t.type==="tool_use_start"?Yt(o.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,o.workspacePath):t.type==="tool_use_end"&&Gt(t,{sessionId:o.sessionId,agentId:o.agentId,workspacePath:o.workspacePath,providerId:o.providerId}),l.info(`[${n.displayName} Adapter] Event: ${t.type} for session ${t.sessionId}`),!(t.type==="thinking"||t.type==="text_delta"||t.type==="tool_use_start"||t.type==="context_compaction"||t.type==="compaction_summary"||t.type==="ai_request"||t.type==="error")){t.type==="runtime_capabilities"&&t.data.actionDetail&&(o.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=no(t,o.currentRuntimeStatus);i&&R(o.agentId,t.sessionId,i.status,i.actionInfo,J(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}t.type==="context_compaction"&&Pe(t.sessionId),lo(t,o);const r=Hn(t);if(r){const i=t.timestamp?new Date(t.timestamp).getTime():void 0,a=String(t.data?.toolName||"").toLowerCase()==="browser_launch",c=t.type==="tool_use_end"&&String(t.data?.rawToolName||t.data?.toolName||"").toLowerCase().replace(/[_-]/g,"").includes("todowrite");Me(a?{entry:o,sessionId:t.sessionId,actionInfo:r,timestamp:i,sourceEventType:t.type,backoffBaseMs:3e3,label:"browser_launch"}:c?{entry:o,sessionId:t.sessionId,actionInfo:r,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"todo_write"}:{entry:o,sessionId:t.sessionId,actionInfo:r,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"tool_result"})}}}),e.on("status-change",(t,o,s)=>{const r=f.get(t);if(r){Se(t),o==="thinking"||o==="tool_using"||o==="compacting"?cn(t):P(t);const i=hn(o,s);r.currentRuntimeStatus=i.status;const a=r.currentRuntimeActionDetail??"",c=a.includes("poll_message")||a.includes("get_message"),d=!(i.actionInfo?.actionType==="ai_request")&&(i.status==="thinking"||i.status==="waiting_input")&&(r.currentRuntimeActionType==="idle"||r.currentRuntimeActionType==="mcp")&&c;(i.actionInfo?.actionType||!d)&&(r.currentRuntimeActionType=i.actionInfo?.actionType,r.currentRuntimeActionLabel=i.actionInfo?.actionLabel,r.currentRuntimeActionDetail=i.actionInfo?.actionDetail,r.currentRuntimeActionInput=i.actionInfo?.actionInput),l.info(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${r.agentId}`,i.actionInfo||""),tn(t,{runtimeStatus:i.status,runtimeActionType:r.currentRuntimeActionType,runtimeActionLabel:r.currentRuntimeActionLabel,runtimeActionDetail:r.currentRuntimeActionDetail});const p=An({actionInfo:i.actionInfo,usage:J(i.actionInfo)}),m=p?void 0:i.actionInfo?.actionType?i.actionInfo:r.currentRuntimeActionType?{actionType:r.currentRuntimeActionType,actionLabel:r.currentRuntimeActionLabel??"",actionDetail:r.currentRuntimeActionDetail,actionInput:r.currentRuntimeActionInput}:void 0;if(i.status==="compacting"){const b=(me.get(t)??Promise.resolve()).then(async()=>{for(let y=0;y<=2;y++){if(await R(r.agentId,t,i.status,m,J(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})!==void 0)return;y<2&&(l.warn(`[${n.displayName}] compaction sendStatus attempt ${y+1} failed (HTTP), retrying in ${1e3*(y+1)}ms...`),await new Promise(k=>setTimeout(k,1e3*(y+1))))}l.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(E=>{l.warn(`[${n.displayName}] compaction status chain error:`,E)});me.set(t,b),b.finally(()=>{me.get(t)===b&&me.delete(t)})}else{const g=d&&!i.actionInfo?.actionType||p;if(Tn({status:i.status,actionInfo:i.actionInfo,restoredActionInfo:m,currentRuntimeActionType:r.currentRuntimeActionType,shouldPreservePrevAction:d})){const y=(ge.get(t)??Promise.resolve()).then(async()=>{for(let k=0;k<=2;k++){if(await R(r.agentId,t,i.status,g?void 0:m,J(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})!==void 0)return;k<2&&await new Promise(L=>setTimeout(L,1e3*(k+1)))}l.warn(`[${n.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`)}).catch(O=>{l.warn(`[${n.displayName}] idle status chain error:`,O)});ge.set(t,y),y.finally(()=>{ge.get(t)===y&&ge.delete(t)})}else R(r.agentId,t,i.status,g?void 0:m,J(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}if(i.status==="waiting_input"&&r.cachedCapabilitiesActionDetail){const g=r.cachedCapabilitiesActionDetail;r.cachedCapabilitiesActionDetail=void 0,l.info(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${r.agentId} (session stabilized to waiting_input)`),R(r.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:g},void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const o=f.get(t.sessionId);o&&(l.info(`[${n.displayName} Adapter] AskUserQuestion for agent ${o.agentId}`),Xt(o.agentId,t.sessionId,Array.isArray(t.questions)?t.questions:[],{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl},t.toolCallId))}),e.on("tool-permission-request",t=>{const o=f.get(t.sessionId);o&&t.requestId&&(l.info(`[${n.displayName} Adapter] Tool permission request (${t.capability}) for agent ${o.agentId}`),Jt(o.agentId,t.sessionId,{requestId:t.requestId,capability:t.capability,...t.detail||{}},{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl}))}),e.on("permission-request",t=>{const o=f.get(t.sessionId);if(o){l.info(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${o.agentId}`);const s=t.toolInput?K(JSON.stringify(t.toolInput).slice(0,400)):void 0;R(o.agentId,t.sessionId,"waiting_input",{actionType:"other",actionLabel:"\u6743\u9650\u786E\u8BA4",actionDetail:s||t.toolName},void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}})}h.post("/start",S,async(e,n)=>{const{agentId:t,workspacePath:o,mode:s="sdk"}=e.body||{};if(!t||!o){n.status(400).json({error:"agentId and workspacePath are required"});return}const r=on(e),i=rn(e.body?.tenantId??r?.tenantId,e.body?.ownerUserId??e.body?.userId??r?.userId);if(i)try{Rt(String(t),i,String(e.body?.userId??"").trim()||void 0)}catch(c){if(c instanceof Error&&c.message.includes("agent-ownership-mismatch")){n.status(403).json({ok:!1,error:"agent-ownership-mismatch"});return}throw c}const a=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ke(tt(e))||void 0;if(vt({agentId:String(t),workspacePath:String(o),serverUrl:e.body?.serverUrl||a,runtimeAccessToken:e.body?.runtimeAccessToken,userId:e.body?.userId,schedulerBaseUrl:a}),e.body?.runtimeFeatures!==null&&e.body?.runtimeFeatures!==void 0&&(Ut(String(t),e.body.runtimeFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(jt(String(t)))}`)),e.body?.inheritedFeatures!==null&&e.body?.inheritedFeatures!==void 0&&(Nt(String(t),e.body.inheritedFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u7EE7\u627F\u4E09\u6001\u5C42: ${JSON.stringify(Ft(String(t)))}`)),e.body?.capabilities!==void 0&&xt(String(t),e.body.capabilities),e.body?.capabilitiesInherited!==void 0&&Bt(String(t),e.body.capabilitiesInherited),e.body?.envVars!==null&&e.body?.envVars!==void 0&&typeof e.body.envVars=="object"&&(Ht(String(t),e.body.envVars),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u6709\u6548\u73AF\u5883\u53D8\u91CF: ${Object.keys(e.body.envVars).length} \u9879 \u2192 \u5DE5\u5177\u5B50\u8FDB\u7A0B + MCP spec`)),e.body?.agentMeta!==void 0&&(qt(String(t),e.body.agentMeta),l.info(`[Runtime] agent ${t} \u4E0B\u53D1 agent \u5143\u4FE1\u606F: ${JSON.stringify(e.body.agentMeta)} \u2192 MCP \u4FDD\u7559\u952E\u6CE8\u5165`)),e.body?.changeCacheRetentionDays!==void 0&&(Dt(e.body.changeCacheRetentionDays),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),e.body?.snapshotRetentionDays!==void 0){const c=we();Vt(e.body.snapshotRetentionDays),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u5FEB\u7167\u4FDD\u7559\u5929\u6570: ${e.body.snapshotRetentionDays??"\u4E0D\u6E05\u7406"}`),c!==we()&&Pt(we())}if(e.body?.logRetentionDays!==void 0){const c=Math.min(Number(e.body.logRetentionDays)||0,7);c>0&&(Kt(c),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u65E5\u5FD7\u4FDD\u7559\u5929\u6570: ${c}`))}s&&s!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${s}" requested for agent ${t}; starting SDK session instead.`),await mo(e,n)});async function mo(e,n){const{agentId:t,workspacePath:o,command:s,projectRoot:r,autoAccept:i=!0,initialPrompt:a,systemPrompt:c,globalPrompt:u,rolePrompt:d,memory:p,resumeContext:m,resumeTranscript:g,resumeTokenUsage:b,mcpConfigPath:E,extraMcpServers:y,envOverrides:O,idleInputAutoCommand:k,nonInputAutoCommand:B,model:L,instanceAiConfig:he,subAgentModel:Te,subAgentEffort:Ae,scopeKey:Le,browserAllowPrivate:Ue}=e.body||{},W=pn(g),te=mn(b);l.info(`[HIBERNATE-IMPORT] \u542F\u52A8\u8BF7\u6C42\u643A\u5E26\u4F11\u7720\u6062\u590D: agentId=${String(t||"").trim()||"?"} resumeContext=${typeof m=="string"?`${m.length}\u5B57`:"\u65E0"} resumeTranscript\u539F\u59CB=${typeof g=="string"?`${g.length}\u5B57`:typeof g} \u89E3\u6790\u7ED3\u679C=${W?`${W.length}\u6761`:"null"} resumeTokenUsage\u89E3\u6790=${te?JSON.stringify(te):"null"}`);const G=sn();G.log({level:"info",category:"launch",message:"startSdkSession: \u6536\u5230\u542F\u52A8\u8BF7\u6C42",source:"bridge",agentId:String(t||"").trim()||void 0,details:{reqBodyKeys:Object.keys(e.body||{}),perInstanceAiConfig:he?ue(he):null,perAgentModel:L??null}});let $=null;const T=String(t||"").trim(),ke=String(e.body?.runtimeAccessToken||"").trim()||void 0,j=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ke(tt(e))||void 0;j?l.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${j} (agentId=${T})`):l.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${T})`);try{if(fo(),!T){n.status(400).json({error:"agentId is required"});return}const F=ft(T);if(F){n.json(await Mn(F));return}const _=await Qt(T);if(_){const w=await Pn(_);if(!w.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${T}, sessionId=${_.sessionId}, reason=${w.reason}`),await q(_.sessionId);else{const D=Z(_.runtimeStatus,_.runtimeStatus,_.runtimeActionType);n.json({sessionId:_.sessionId,status:D,runtimeStatus:D,runtimeActionType:_.runtimeActionType,runtimeActionLabel:_.runtimeActionLabel,runtimeActionDetail:_.runtimeActionDetail,agentId:_.agentId,workspacePath:_.workspacePath,command:_.command,mode:_.mode||"sdk",pid:_.pid,reused:!0,persistedOnly:!0});return}}if(z.has(T)){n.status(409).json({error:"SDK session is already starting for this agent"});return}z.add(T);const M=It(s),ht=A.get(M);$=bt();const ne=jn(null,O),Y=M==="acode"?L?String(L).trim():void 0:(()=>{const w=L?String(L).trim():void 0,D=ne.model?String(ne.model).trim():void 0;return w||D})();G.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:T,sessionId:$??void 0,details:{perAgentModel:L??null,globalModel:ne.model??null,resolvedModel:Y??null,providerId:M,note:M==="acode"?"adapter handles full priority":"request > global"}});const _e={...ne.envOverrides};Y&&(_e.ANTHROPIC_MODEL=Y,_e.CODEX_MODEL=Y);let X,be=E;if(M==="acode"){const w=he||{},D=await Lt({apiOverrides:it(w)??void 0,agentId:T,sessionId:$??void 0,runtimeBridgeBaseUrl:j});X=D.instanceConfig.config,be=D.perInstanceConfigPath,G.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:T,sessionId:$??void 0,details:{sanitizedApiOverrides:(()=>{const N=it(w);return N?ue(N):null})(),resolvedInstanceAiConfig:X?ue(X):null,perInstanceConfigPath:be,instanceConfigSources:D.instanceConfig.source??null}})}let xe=c||void 0,Ce,Ee,oe;const re=typeof m=="string"&&m.trim()?kt(m):void 0;if(M==="acode")if(Ce=typeof u=="string"&&u.trim()||void 0,Ee=typeof d=="string"&&d.trim()||void 0,typeof p=="string"&&p.trim())oe=p.trim();else{const w=await wt(o,{schedulerBaseUrl:j,runtimeAccessToken:ke,agentId:T});w&&(oe=w,l.info(`[startSdkSession] Auto-loaded memories for ACode agent ${T}`))}else if(typeof u=="string"&&u.trim()||typeof d=="string"&&d.trim()||typeof p=="string"&&p.trim()||re!==void 0){const D=[u,d,p,re,c].filter(N=>typeof N=="string"&&N.trim().length>0).map(N=>N.trim());xe=D.length>0?D.join(`
|
|
37
|
+
`:void 0}function Zn(e){const n=no(e);return{sourceEventType:e.type,logCategory:"acode",...to(e),...n?{logLevel:eo(e),logMessage:n}:{}}}function eo(e){return e.type==="error"?"error":e.type==="command_output"&&e.data.stream==="stderr"?"warn":"info"}function to(e){return e.type!=="command_output"?{}:{...typeof e.data.stream=="string"?{stream:e.data.stream}:{},...typeof e.data.sequence=="number"?{sequence:e.data.sequence}:{},...typeof e.data.cwd=="string"?{cwd:e.data.cwd}:{},...typeof e.data.commandFilePath=="string"?{commandFilePath:e.data.commandFilePath}:{},...typeof e.data.commandLineCount=="number"?{commandLineCount:e.data.commandLineCount}:{}}}function no(e){if(e.type==="ai_request"){const n=e.data.model||"unknown-model",t=e.data.endpoint?` @ ${e.data.endpoint}`:"",o=typeof e.data.toolCount=="number"?`, tools=${e.data.toolCount}`:"";return`AI request started: ${n}${t}${o}`}if(e.type==="tool_use_start")return At(e,"\u5F00\u59CB");if(e.type==="tool_use_end")return At(e,"\u5B8C\u6210");if(e.type==="command_output")return so(e);if(e.type==="turn_complete")return`Turn completed${e.data.finishReason?`, finish=${e.data.finishReason}`:""}`;if(e.type==="session_complete")return`Session completed: exitCode=${e.data.exitCode??0}`;if(e.type==="error")return e.data.text||"ACode runtime error"}const oo=/\x1b\[[0-9;?]*[a-zA-Z]/g;function ro(e){return e.replace(oo,"")}function so(e){const n=typeof e.data.stream=="string"?e.data.stream:"mixed",t=typeof e.data.sequence=="number"?` #${e.data.sequence}`:"",o=ro(String(e.data.text||"")).replace(/\s+/g," ").trim(),s=o.length>240?`${o.slice(0,240)}...`:o;return`\u547D\u4EE4\u8F93\u51FA(${n}${t}): ${s||"(empty)"}`}function At(e,n){const t=Me(e.data.toolName,e.data.toolInput),o=e.data.actionLabel||t.actionLabel||"\u8C03\u7528\u5DE5\u5177",s=kt(e,t);return s?`${n}${o}: ${s}`:`${n}${o}: ${e.data.actionDetail||e.data.toolName||"tool"}`}function kt(e,n){const t=e.data.toolInput;return n.actionType==="bash"?io(t)||e.data.actionDetail||n.actionDetail:n.actionType==="read_file"||n.actionType==="edit_file"||n.actionType==="write_file"?ao(t)||e.data.actionDetail||n.actionDetail:e.data.actionDetail||n.actionDetail}function io(e){const n=xe(e?.command,e?.cmd);if(n)return n;if(Array.isArray(e?.argv)){const t=e.argv.map(o=>String(o??"").trim()).filter(Boolean).join(" ");return t?W(t):void 0}return xe(e?.args)}function ao(e){const n=_t(e?.paths);return n.length>0?n.length===1?n[0]:`${n.length}\u4E2A\u6587\u4EF6: ${n.join(", ")}`:xe(e?.file_path,e?.filePath,e?.path,e?.target_file,e?.targetFile)}function xe(...e){for(const n of e){if(typeof n=="string"&&n.trim())return W(n.trim());if(Array.isArray(n)){const t=_t(n)[0];if(t)return t}}}function _t(e){return Array.isArray(e)?e.map(n=>typeof n=="string"?n.trim():"").filter(Boolean).map(n=>W(n)):[]}function co(e){if(!(!e||Object.keys(e).length===0))try{const n=W(JSON.stringify(e,null,2));return n.length>8e3?`${n.slice(0,8e3)}
|
|
38
|
+
...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function uo(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function lo(e,n){if(!uo(e,n)){if(e.type==="background_command_completed")return{status:"tool_result",actionInfo:{actionType:"background_command",actionLabel:"\u540E\u53F0\u547D\u4EE4",actionDetail:"background_command_completed"}};if(e.type==="thinking"||e.type==="text_delta")return{status:"thinking"};if(e.type==="tool_use_start"){const t=Me(e.data.toolName,e.data.toolInput),o=kt(e,t),s=co(e.data.toolInput);return e.data.actionType==="idle"||t.actionType==="idle"?{status:"waiting_input",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:o||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:s,actionId:e.data.actionId||e.data.toolUseId}}:{status:"tool_using",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:o||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:s,actionId:e.data.actionId||e.data.toolUseId,...e.data.batchId?{parentId:e.data.batchId}:{}}}}if(e.type==="turn_complete")return{status:"waiting_input",actionInfo:e.data.usage?{usage:e.data.usage}:void 0};if(e.type==="error")return{status:"error"};if(e.type==="context_compaction")return{status:"compacting",actionInfo:{actionType:"context_compaction",actionLabel:e.data.actionLabel,actionDetail:e.data.actionDetail,...e.data.actionId?{actionId:e.data.actionId}:{},...e.data.parentId?{parentId:e.data.parentId}:{}}};if(e.type==="runtime_capabilities")return{status:n||"waiting_input",actionInfo:{actionType:"runtime_capabilities",actionLabel:e.data.actionLabel||"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:e.data.actionDetail}};if(e.type==="tool_batch_start"){const t=e.data.batchId;return t?{status:"tool_result",actionInfo:{actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionDetail:e.data.actionDetail,actionId:t}}:void 0}if(e.type==="tool_batch_metrics"){const t=e.data.batchId;return t?{status:"tool_result",actionInfo:{actionType:"tool_batch",actionLabel:"\u5E76\u884C\u6267\u884C\u5DE5\u5177",actionId:t,batchId:t,...e.data.batchMetrics?{batchMetrics:e.data.batchMetrics}:{}}}:void 0}}}const B=new Map,Se=new Map,he=new Map;async function Ne(e){const{entry:n,sessionId:t,actionInfo:o,timestamp:s,sourceEventType:r,backoffBaseMs:i,label:a}=e,c={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl},u=3;for(let d=0;d<u;d++){if(await $(n.agentId,t,"tool_result",o,void 0,c,s,r)!==void 0)return;d<u-1&&await new Promise(p=>setTimeout(p,i*(d+1)))}l.warn(`[Runtime] ${a} tool_result sendStatus retry exhausted (result may be lost): agentId=${n.agentId}`)}const oe=new Map,fo=20,po=500,mo=3e4;async function Te(e,n=mo,t=2){for(let o=0;o<=t;o++){const s=new AbortController;let r;try{const i=e(s.signal);i.catch(()=>{}),await Promise.race([i,new Promise((a,c)=>{r=setTimeout(()=>{s.abort(),c(new Error(`sendOutput timeout after ${n}ms`))},n)})]),r&&clearTimeout(r);return}catch(i){r&&clearTimeout(r);const a=i instanceof Error?i.message:String(i);if(o<t){const c=1e3*(o+1);l.warn(`sendOutput attempt ${o+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(u=>setTimeout(u,c));continue}l.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}async function go(e,n,t,o,s,r){try{await Y(e,n,t,o,{...s,sourceEventType:"compaction_summary",skipLocalPersist:!0},r)}catch(i){l.debug("Compaction summary realtime push failed (non-persisted)",{agentId:e,sessionId:t,error:i instanceof Error?i.message:String(i)})}}const Ae=new Map,yo=120,Io=120;function So(e,n,t,o){const s=`${n}:compaction_summary`;let r=Ae.get(s);if(r||(r={buffer:"",timer:null,entry:e,sessionId:n,seq:o},Ae.set(s,r)),r.buffer+=t,r.seq=o,r.entry=e,r.buffer.length>=yo){je(n);return}r.timer||(r.timer=setTimeout(()=>je(n),Io))}function je(e){const n=`${e}:compaction_summary`,t=Ae.get(n);if(!t)return;t.timer&&(clearTimeout(t.timer),t.timer=null);const o=t.buffer;Ae.delete(n),o&&go(t.entry.agentId,o,t.sessionId,t.seq,{sourceEventType:"compaction_summary",skipLocalPersist:!0},{runtimeAccessToken:t.entry.runtimeAccessToken,schedulerBaseUrl:t.entry.schedulerBaseUrl})}function ke(e,n){const t=n?`${e}:${n}`:void 0;let o,s;if(t)o=oe.get(t),s=t;else{const y=[];for(const[C,w]of oe)C.startsWith(e+":")&&w.buffer&&y.push(w.sourceEventType);for(const C of y)ke(e,C);return}if(!o||!o.buffer)return;o.timer=null;const r=o.buffer,i=o.seq,a=o.entry,c=o.sourceEventType;o.buffer="",s&&oe.delete(s);const u={sourceEventType:c,logCategory:"acode"},d={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},p=(B.get(e)??Promise.resolve()).then(()=>Te(y=>Y(a.agentId,r,e,i,u,d,y)),()=>Te(y=>Y(a.agentId,r,e,i,u,d,y)));B.set(e,p),p.finally(()=>{B.get(e)===p&&B.delete(e)})}function ho(e,n){const t=Qn(e);if(!t)return;n.seq+=1;const o=n.seq,s=Zn(e),r={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if(e.type==="compaction_summary"){So(n,e.sessionId,t,o);return}if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<fo){const c=`${e.sessionId}:${e.type}`;let u=oe.get(c);if(u||(u={buffer:"",seq:0,timer:null,entry:n,sourceEventType:e.type}),u.buffer+=t,u.seq=o,u.entry=n,!u.timer){const d=e.sessionId,g=e.type;u.timer=setTimeout(()=>ke(d,g),po)}oe.set(c,u);return}ke(e.sessionId);const a=(B.get(e.sessionId)??Promise.resolve()).then(()=>Te(c=>Y(n.agentId,t,e.sessionId,o,s,r,c)),()=>Te(c=>Y(n.agentId,t,e.sessionId,o,s,r,c)));B.set(e.sessionId,a),a.finally(()=>{B.get(e.sessionId)===a&&B.delete(e.sessionId)})}function bt(e){return Pt(e)}let Ct=!1;function To(){Ct||(Mt(_,Ao),Bt(),Ct=!0)}function Ao(e,n){e.on("event",t=>{const o=f.get(t.sessionId);if(o){if(t.type==="tool_use_start"?tn(o.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,o.workspacePath):t.type==="tool_use_end"&&en(t,{sessionId:o.sessionId,agentId:o.agentId,workspacePath:o.workspacePath,providerId:o.providerId}),l.info(`[${n.displayName} Adapter] Event: ${t.type} for session ${t.sessionId}`),!(t.type==="thinking"||t.type==="text_delta"||t.type==="tool_use_start"||t.type==="context_compaction"||t.type==="compaction_summary"||t.type==="ai_request"||t.type==="error")){t.type==="runtime_capabilities"&&t.data.actionDetail&&(o.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=lo(t,o.currentRuntimeStatus);i&&$(o.agentId,t.sessionId,i.status,i.actionInfo,Z(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}t.type==="context_compaction"&&je(t.sessionId),ho(t,o);const r=Xn(t);if(r){const i=t.timestamp?new Date(t.timestamp).getTime():void 0,a=String(t.data?.toolName||"").toLowerCase()==="browser_launch",c=t.type==="tool_use_end"&&String(t.data?.rawToolName||t.data?.toolName||"").toLowerCase().replace(/[_-]/g,"").includes("todowrite");Ne(a?{entry:o,sessionId:t.sessionId,actionInfo:r,timestamp:i,sourceEventType:t.type,backoffBaseMs:3e3,label:"browser_launch"}:c?{entry:o,sessionId:t.sessionId,actionInfo:r,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"todo_write"}:{entry:o,sessionId:t.sessionId,actionInfo:r,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"tool_result"})}}}),e.on("status-change",(t,o,s)=>{const r=f.get(t);if(r){ke(t),o==="thinking"||o==="tool_using"||o==="compacting"?gn(t):U(t);const i=Rn(o,s);r.currentRuntimeStatus=i.status;const a=r.currentRuntimeActionDetail??"",c=a.includes("poll_message")||a.includes("get_message"),d=!(i.actionInfo?.actionType==="ai_request")&&(i.status==="thinking"||i.status==="waiting_input")&&(r.currentRuntimeActionType==="idle"||r.currentRuntimeActionType==="mcp")&&c;(i.actionInfo?.actionType||!d)&&(r.currentRuntimeActionType=i.actionInfo?.actionType,r.currentRuntimeActionLabel=i.actionInfo?.actionLabel,r.currentRuntimeActionDetail=i.actionInfo?.actionDetail,r.currentRuntimeActionInput=i.actionInfo?.actionInput),l.info(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${r.agentId}`,i.actionInfo||""),un(t,{runtimeStatus:i.status,runtimeActionType:r.currentRuntimeActionType,runtimeActionLabel:r.currentRuntimeActionLabel,runtimeActionDetail:r.currentRuntimeActionDetail});const g=wn({actionInfo:i.actionInfo,usage:Z(i.actionInfo)}),p=g?void 0:i.actionInfo?.actionType?i.actionInfo:r.currentRuntimeActionType?{actionType:r.currentRuntimeActionType,actionLabel:r.currentRuntimeActionLabel??"",actionDetail:r.currentRuntimeActionDetail,actionInput:r.currentRuntimeActionInput}:void 0;if(i.status==="compacting"){const C=(Se.get(t)??Promise.resolve()).then(async()=>{for(let I=0;I<=2;I++){if(await $(r.agentId,t,i.status,p,Z(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})!==void 0)return;I<2&&(l.warn(`[${n.displayName}] compaction sendStatus attempt ${I+1} failed (HTTP), retrying in ${1e3*(I+1)}ms...`),await new Promise(b=>setTimeout(b,1e3*(I+1))))}l.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(w=>{l.warn(`[${n.displayName}] compaction status chain error:`,w)});Se.set(t,C),C.finally(()=>{Se.get(t)===C&&Se.delete(t)})}else{const y=d&&!i.actionInfo?.actionType||g;if($n({status:i.status,actionInfo:i.actionInfo,restoredActionInfo:p,currentRuntimeActionType:r.currentRuntimeActionType,shouldPreservePrevAction:d})){const I=(he.get(t)??Promise.resolve()).then(async()=>{for(let b=0;b<=2;b++){if(await $(r.agentId,t,i.status,y?void 0:p,Z(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})!==void 0)return;b<2&&await new Promise(x=>setTimeout(x,1e3*(b+1)))}l.warn(`[${n.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`)}).catch(P=>{l.warn(`[${n.displayName}] idle status chain error:`,P)});he.set(t,I),I.finally(()=>{he.get(t)===I&&he.delete(t)})}else $(r.agentId,t,i.status,y?void 0:p,Z(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}if(i.status==="waiting_input"&&r.cachedCapabilitiesActionDetail){const y=r.cachedCapabilitiesActionDetail;r.cachedCapabilitiesActionDetail=void 0,l.info(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${r.agentId} (session stabilized to waiting_input)`),$(r.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:y},void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const o=f.get(t.sessionId);o&&(l.info(`[${n.displayName} Adapter] AskUserQuestion for agent ${o.agentId}`),nn(o.agentId,t.sessionId,Array.isArray(t.questions)?t.questions:[],{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl},t.toolCallId))}),e.on("tool-permission-request",t=>{const o=f.get(t.sessionId);o&&t.requestId&&(l.info(`[${n.displayName} Adapter] Tool permission request (${t.capability}) for agent ${o.agentId}`),on(o.agentId,t.sessionId,{requestId:t.requestId,capability:t.capability,...t.detail||{}},{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl}))}),e.on("permission-request",t=>{const o=f.get(t.sessionId);if(o){l.info(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${o.agentId}`);const s=t.toolInput?W(JSON.stringify(t.toolInput).slice(0,400)):void 0;$(o.agentId,t.sessionId,"waiting_input",{actionType:"other",actionLabel:"\u6743\u9650\u786E\u8BA4",actionDetail:s||t.toolName},void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}})}T.post("/start",h,async(e,n)=>{const{agentId:t,workspacePath:o,mode:s="sdk"}=e.body||{};if(!t||!o){n.status(400).json({error:"agentId and workspacePath are required"});return}const r=ln(e),i=fn(e.body?.tenantId??r?.tenantId,e.body?.ownerUserId??e.body?.userId??r?.userId);if(i)try{Ut(String(t),i,String(e.body?.userId??"").trim()||void 0)}catch(c){if(c instanceof Error&&c.message.includes("agent-ownership-mismatch")){n.status(403).json({ok:!1,error:"agent-ownership-mismatch"});return}throw c}const a=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ye(at(e))||void 0;if(Vt({agentId:String(t),workspacePath:String(o),serverUrl:e.body?.serverUrl||a,runtimeAccessToken:e.body?.runtimeAccessToken,userId:e.body?.userId,schedulerBaseUrl:a}),e.body?.runtimeFeatures!==null&&e.body?.runtimeFeatures!==void 0&&(Ht(String(t),e.body.runtimeFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(qt(String(t)))}`)),e.body?.inheritedFeatures!==null&&e.body?.inheritedFeatures!==void 0&&(zt(String(t),e.body.inheritedFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u7EE7\u627F\u4E09\u6001\u5C42: ${JSON.stringify(Yt(String(t)))}`)),e.body?.capabilities!==void 0&&Kt(String(t),e.body.capabilities),e.body?.capabilitiesInherited!==void 0&&Wt(String(t),e.body.capabilitiesInherited),e.body?.envVars!==null&&e.body?.envVars!==void 0&&typeof e.body.envVars=="object"&&(Jt(String(t),e.body.envVars),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u6709\u6548\u73AF\u5883\u53D8\u91CF: ${Object.keys(e.body.envVars).length} \u9879 \u2192 \u5DE5\u5177\u5B50\u8FDB\u7A0B + MCP spec`)),e.body?.agentMeta!==void 0&&(Xt(String(t),e.body.agentMeta),l.info(`[Runtime] agent ${t} \u4E0B\u53D1 agent \u5143\u4FE1\u606F: ${JSON.stringify(e.body.agentMeta)} \u2192 MCP \u4FDD\u7559\u952E\u6CE8\u5165`)),e.body?.changeCacheRetentionDays!==void 0&&(Nt(e.body.changeCacheRetentionDays),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),e.body?.snapshotRetentionDays!==void 0){const c=Le();rn(e.body.snapshotRetentionDays),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u5FEB\u7167\u4FDD\u7559\u5929\u6570: ${e.body.snapshotRetentionDays??"\u4E0D\u6E05\u7406"}`),c!==Le()&&Ft(Le())}if(e.body?.logRetentionDays!==void 0){const c=Math.min(Number(e.body.logRetentionDays)||0,7);c>0&&(Gt(c),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u65E5\u5FD7\u4FDD\u7559\u5929\u6570: ${c}`))}s&&s!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${s}" requested for agent ${t}; starting SDK session instead.`),await ko(e,n)});async function ko(e,n){const{agentId:t,workspacePath:o,command:s,projectRoot:r,autoAccept:i=!0,initialPrompt:a,systemPrompt:c,globalPrompt:u,rolePrompt:d,memory:g,resumeContext:p,resumeTranscript:y,resumeTokenUsage:C,mcpConfigPath:w,extraMcpServers:I,envOverrides:P,idleInputAutoCommand:b,nonInputAutoCommand:K,model:x,instanceAiConfig:_e,subAgentModel:be,subAgentEffort:Ce,scopeKey:Be,browserAllowPrivate:Fe}=e.body||{},z=Tn(y),re=An(C);l.info(`[HIBERNATE-IMPORT] \u542F\u52A8\u8BF7\u6C42\u643A\u5E26\u4F11\u7720\u6062\u590D: agentId=${String(t||"").trim()||"?"} resumeContext=${typeof p=="string"?`${p.length}\u5B57`:"\u65E0"} resumeTranscript\u539F\u59CB=${typeof y=="string"?`${y.length}\u5B57`:typeof y} \u89E3\u6790\u7ED3\u679C=${z?`${z.length}\u6761`:"null"} resumeTokenUsage\u89E3\u6790=${re?JSON.stringify(re):"null"}`);let N=!1,se,Ee,Re;{const O=String(t||"").trim();if(O&&!z&&!(typeof p=="string"&&p.trim()))try{const m=await wt(O);if(m&&Array.isArray(m.transcript)&&m.transcript.length>0){se=m.transcript;const k=m.tokenUsage,L=j=>typeof j=="number"&&Number.isFinite(j)?j:void 0;Ee=k?{...L(k.totalInputTokens)!==void 0?{totalInputTokens:L(k.totalInputTokens)}:{},...L(k.totalOutputTokens)!==void 0?{totalOutputTokens:L(k.totalOutputTokens)}:{},...L(k.cacheHitTokens)!==void 0?{cacheHitTokens:L(k.cacheHitTokens)}:{},...L(k.cacheMissTokens)!==void 0?{cacheMissTokens:L(k.cacheMissTokens)}:{}}:void 0,Re=m.reason==="clean"?ft:kn,N=!0,l.info(`[CRASH-RECOVERY] \u547D\u4E2D\u65AD\u70B9 journal: agentId=${O} reason=${m.reason} savedAt=${m.savedAt} messages=${m.messageCount}`)}}catch(m){l.warn(`[CRASH-RECOVERY] journal \u8BFB\u53D6\u5931\u8D25\uFF08\u6309\u65E0 journal \u5904\u7406\uFF09: agentId=${O}, error=${m instanceof Error?m.message:String(m)}`)}}const J=pn();J.log({level:"info",category:"launch",message:"startSdkSession: \u6536\u5230\u542F\u52A8\u8BF7\u6C42",source:"bridge",agentId:String(t||"").trim()||void 0,details:{reqBodyKeys:Object.keys(e.body||{}),perInstanceAiConfig:_e?pe(_e):null,perAgentModel:x??null}});let R=null;const A=String(t||"").trim(),ie=String(e.body?.runtimeAccessToken||"").trim()||void 0,F=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ye(at(e))||void 0;F?l.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${F} (agentId=${A})`):l.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${A})`);try{if(To(),!A){n.status(400).json({error:"agentId is required"});return}const O=ht(A);if(O){n.json(await Fn(O));return}const m=await sn(A);if(m){const D=await vn(m);if(!D.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${A}, sessionId=${m.sessionId}, reason=${D.reason}`),await G(m.sessionId);else{const M=ne(m.runtimeStatus,m.runtimeStatus,m.runtimeActionType);n.json({sessionId:m.sessionId,status:M,runtimeStatus:M,runtimeActionType:m.runtimeActionType,runtimeActionLabel:m.runtimeActionLabel,runtimeActionDetail:m.runtimeActionDetail,agentId:m.agentId,workspacePath:m.workspacePath,command:m.command,mode:m.mode||"sdk",pid:m.pid,reused:!0,persistedOnly:!0});return}}if(V.has(A)){n.status(409).json({error:"SDK session is already starting for this agent"});return}V.add(A);const k=bt(s),L=_.get(k);R=Dt();const j=Yn(null,P),X=k==="acode"?x?String(x).trim():void 0:(()=>{const D=x?String(x).trim():void 0,M=j.model?String(j.model).trim():void 0;return D||M})();J.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:A,sessionId:R??void 0,details:{perAgentModel:x??null,globalModel:j.model??null,resolvedModel:X??null,providerId:k,note:k==="acode"?"adapter handles full priority":"request > global"}});const $e={...j.envOverrides};X&&($e.ANTHROPIC_MODEL=X,$e.CODEX_MODEL=X);let Q,we=w;if(k==="acode"){const D=_e||{},M=await vt({apiOverrides:pt(D)??void 0,agentId:A,sessionId:R??void 0,runtimeBridgeBaseUrl:F});Q=M.instanceConfig.config,we=M.perInstanceConfigPath,J.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:A,sessionId:R??void 0,details:{sanitizedApiOverrides:(()=>{const H=pt(D);return H?pe(H):null})(),resolvedInstanceAiConfig:Q?pe(Q):null,perInstanceConfigPath:we,instanceConfigSources:M.instanceConfig.source??null}})}let ve=c||void 0,Oe,De,ae;const ce=N?He(`\uFF08\u65E0\u8FDB\u5EA6\u6458\u8981\uFF1A\u5B8C\u6574\u5BF9\u8BDD\u8BB0\u5F55\u7ECF ${Re===ft?"\u6B63\u5E38\u6536\u5C3E\u843D\u76D8":"\u5D29\u6E83\u524D\u81EA\u52A8\u843D\u76D8"}\u5DF2\u539F\u6837\u63A5\u7EED\uFF09`,Re):typeof p=="string"&&p.trim()?He(p):void 0;if(k==="acode")if(Oe=typeof u=="string"&&u.trim()||void 0,De=typeof d=="string"&&d.trim()||void 0,typeof g=="string"&&g.trim())ae=g.trim();else{const D=await xt(o,{schedulerBaseUrl:F,runtimeAccessToken:ie,agentId:A});D&&(ae=D,l.info(`[startSdkSession] Auto-loaded memories for ACode agent ${A}`))}else if(typeof u=="string"&&u.trim()||typeof d=="string"&&d.trim()||typeof g=="string"&&g.trim()||ce!==void 0){const M=[u,d,g,ce,c].filter(H=>typeof H=="string"&&H.trim().length>0).map(H=>H.trim());ve=M.length>0?M.join(`
|
|
39
39
|
|
|
40
|
-
`):void 0}const x={command:s||"acode",workingDirectory:o,agentId:T,...Le?{scopeKey:Le}:{},...typeof Ue=="boolean"?{browserAllowPrivate:Ue}:{},autoAccept:!!i,initialPrompt:a,systemPrompt:xe,...Ce!==void 0?{globalPrompt:Ce}:{},...Ee!==void 0?{rolePrompt:Ee}:{},...oe!==void 0?{memory:oe}:{},...re!==void 0?{resumeContext:re}:{},...M==="acode"&&Array.isArray(W)&&W.length>0?{resumeTranscript:W}:{},...M==="acode"&&te?{resumeTokenUsage:te}:{},model:Y,mcpConfigPath:be,...X?{instanceAiConfig:X}:{},...typeof Te=="string"&&Te.trim()?{subAgentModel:Te.trim()}:{},...typeof Ae=="string"&&Ae.trim()?{subAgentEffort:Ae.trim()}:{},extraMcpServers:y||{},envOverrides:pt(String(t),String(o),process.env,_e,typeof r=="string"?r:void 0)};G.log({level:"info",category:"launch",message:"\u4F20\u9012\u7ED9 Adapter \u7684\u5B8C\u6574 AdapterSessionConfig",source:"bridge",agentId:T,sessionId:$,details:{adapterModel:x.model??null,adapterInstanceAiConfig:x.instanceAiConfig?ue(x.instanceAiConfig):null,adapterMcpConfigPath:x.mcpConfigPath??null}}),await G.flush(),f.set($,{agentId:T,workspacePath:o,sessionId:$,config:x,providerId:M,seq:0,runtimeAccessToken:ke,schedulerBaseUrl:j}),n.json({sessionId:$,status:"starting",runtimeStatus:"starting",agentId:T,workspacePath:o,command:x.command,mode:"sdk"}),go({sessionId:$,agentId:T,config:x,adapter:ht,providerId:M,idleInputAutoCommand:k,nonInputAutoCommand:B,runtimeAccessToken:ke,requestedSchedulerBaseUrl:j})}catch(F){if($&&(P($),f.delete($),v($)),T&&z.delete(T),!n.headersSent){const _=F instanceof Error?F.message:String(F);n.status(500).json({error:`Failed to start SDK session: ${_}`})}}}async function go(e){const{sessionId:n,agentId:t,config:o,adapter:s,providerId:r,idleInputAutoCommand:i,nonInputAutoCommand:a,runtimeAccessToken:c,requestedSchedulerBaseUrl:u}=e;try{await s.startSession(n,o),s.setIdleCommands?.(n,{idleInputCommand:i||je,nonInputCommand:a||""});let d;if(In(r))try{if(await new Promise(m=>setTimeout(m,500)),d=s.getSessionPid?.(n),!d){const g=(await zt()).find(b=>b.agentId===t||b.cwd===o.workingDirectory||b.command.includes(o.workingDirectory));g&&(d=g.pid,l.info(`[Runtime] Found SDK process PID: ${d} for agentId=${t}`))}}catch(m){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,m)}const p=Z(s.getSessionStatus(n),f.get(n)?.currentRuntimeStatus,f.get(n)?.currentRuntimeActionType);await nn({sessionId:n,agentId:t,workspacePath:o.workingDirectory,command:o.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:p,mode:"sdk",pid:d,providerSessionId:s.getProviderSessionId(n)}),d&&await Re().startProcess({agentId:t,sessionId:n,pid:d,mode:"sdk",workspacePath:o.workingDirectory,command:o.command}),await yo({agentId:t,sessionId:n,sdkPid:d,status:p,schedulerBaseUrl:u,runtimeAccessToken:c})}catch(d){P(n),f.delete(n),v(n),await q(n);const p=d instanceof Error?d.message:String(d);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${p}`),await Io({agentId:t,sessionId:n,schedulerBaseUrl:u,runtimeAccessToken:c,errorMessage:p})}finally{z.delete(t)}}async function yo(e){const{agentId:n,sessionId:t,sdkPid:o,status:s,schedulerBaseUrl:r,runtimeAccessToken:i}=e;if(!r||!i){l.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${r.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Ne.post(a,{agentId:n,sessionId:t,status:s,pid:o},{headers:{"X-Runtime-Token":i,"Content-Type":"application/json"},timeout:5e3}),l.debug(`[Runtime] Notified server session ready: agentId=${n}, sessionId=${t}, status=${s}`)}catch(c){const u=c instanceof Error?c.message:String(c);l.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${u}`)}}async function Io(e){const{agentId:n,sessionId:t,schedulerBaseUrl:o,runtimeAccessToken:s}=e;if(!o||!s)return;const r=`${o.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Ne.post(r,{agentId:n,sessionId:t,status:"stopped"},{headers:{"X-Runtime-Token":s,"Content-Type":"application/json"},timeout:5e3}),l.debug(`[Runtime] Notified server session failed: agentId=${n}, sessionId=${t}`)}catch(i){const a=i instanceof Error?i.message:String(i);l.warn(`[Runtime] Failed to notify server session failed: agentId=${n}, error=${a}`)}}h.post("/sdk/message",S,async(e,n)=>{const{sessionId:t,message:o}=e.body||{};if(!t||!o){n.status(400).json({error:"sessionId and message are required"});return}const s=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const r=s.providerId||"claude-code";await A.get(r).sendMessage(t,o),n.json({ok:!0})}catch(r){const i=r instanceof Error?r.message:String(r);n.status(500).json({error:i})}}),h.post("/sdk/answer",S,async(e,n)=>{const{sessionId:t,answers:o,cancelled:s,reason:r}=e.body||{},i=s===!0;if(!t||!i&&!o){n.status(400).json({error:i?"sessionId is required":"sessionId and answers are required"});return}const a=f.get(t);if(!a){n.status(404).json({error:"SDK session not found"});return}try{const c=a.providerId||"claude-code",u=A.get(c);if(i){if(!u.cancelQuestionAnswer){n.status(400).json({error:"adapter does not support cancelling a question"});return}l.debug(`[sdk/answer] cancel question: sessionId=${t}, providerId=${c}, hasReason=${!!String(r||"").trim()}`),await u.cancelQuestionAnswer(t,typeof r=="string"?r:void 0)}else u.sendQuestionAnswer&&await u.sendQuestionAnswer(t,o);n.json({ok:!0})}catch(c){const u=c instanceof Error?c.message:String(c);n.status(500).json({error:u})}}),h.post("/tool-auth/answer",S,async(e,n)=>{const{sessionId:t,requestId:o,allowed:s}=e.body||{};if(!t||!o){n.status(400).json({error:"sessionId and requestId are required"});return}const r=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const i=r.providerId||"claude-code",a=A.get(i);if(!a.submitToolPermissionDecision){n.status(400).json({error:"adapter does not support tool authorization"});return}const c=a.submitToolPermissionDecision(t,String(o),!!s);n.json({ok:!0,existed:c})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),h.get("/tool-auth/pending/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",i=A.get(s).getPendingToolAuthRequests?.(t)??[];n.json({ok:!0,sessionId:t,agentId:o.agentId,pendingRequests:i,fetchedAt:Date.now()})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),h.post("/sdk/confirm",S,async(e,n)=>{const{sessionId:t,accept:o}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const s=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const r=s.providerId||"claude-code";await A.get(r).sendConfirmation(t,!!o),n.json({ok:!0})}catch(r){const i=r instanceof Error?r.message:String(r);n.status(500).json({error:i})}}),h.post("/sdk/abort",S,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code";await A.get(s).abortCurrentTurn(t),n.json({ok:!0})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),h.post("/sdk/stop",S,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.json({ok:!0,status:"stopped"});return}try{const s=o.providerId||"claude-code",r=A.get(s);r.abortCurrentTurn(t).catch(()=>{}),await r.terminateSession(t),P(t),f.delete(t),v(t),pe(t),ce(o.agentId),await q(t),await Re().removeProcess(o.agentId),await R(o.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl}),n.json({ok:!0,status:"stopped"})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),h.get("/sdk/snapshot/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",r=A.get(s),i=r.getConversation(t),a=ln(i);let c=null;if(s==="acode"){const d=r;typeof d.exportRawTranscript!="function"?l.warn(`[HIBERNATE-EXPORT] adapter \u65E0 exportRawTranscript \u65B9\u6CD5 \u2014 bridge \u8FDB\u7A0B\u53EF\u80FD\u8FD0\u884C\u7684\u662F\u65E7\u6784\u5EFA\uFF08\u8BF7\u91CD\u542F bridge\uFF09\u3002providerId=${s}`):(c=d.exportRawTranscript?.(t)??null,c===null&&l.warn(`[HIBERNATE-EXPORT] exportRawTranscript \u8FD4\u56DE\u7A7A \u2014 runtime \u53EF\u80FD\u672A\u5B8C\u6210 start() \u6216\u4E0D\u652F\u6301\u3002providerId=${s}`))}else l.info(`[HIBERNATE-EXPORT] provider=${s} \u4E0D\u652F\u6301\u5B8C\u6574\u91CD\u653E\uFF0C\u6309\u4EC5\u6458\u8981\u4F11\u7720`);const u=r.getTotalUsage?.(t);l.info(`[HIBERNATE-EXPORT] \u5FEB\u7167\u5BFC\u51FA: sessionId=${t} agentId=${o.agentId} providerId=${s} messages=${i.length} summaryChars=${a.snapshot.length} truncated=${a.truncated} transcript=${c?`${c.length}\u6761`:"null"} usage=${u?`in=${u.inputTokens??"?"}/out=${u.outputTokens??"?"}`:"null"} totalUsage=${u?`in=${u.totalInputTokens??"?"}/out=${u.totalOutputTokens??"?"}`:"null"}`),n.json({sessionId:t,agentId:o.agentId,workspacePath:o.workspacePath,messageCount:i.length,truncated:a.truncated,snapshot:a.snapshot,transcript:c,tokenUsage:u?{inputTokens:u.inputTokens??null,outputTokens:u.outputTokens??null,totalInputTokens:u.totalInputTokens??null,totalOutputTokens:u.totalOutputTokens??null,cacheHitTokens:u.cacheHitTokens??null,cacheMissTokens:u.cacheMissTokens??null}:null,providerId:s})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),h.get("/sdk/status/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",r=A.get(s),i=r.getSessionStatus(t),a=r.getConversation(t);n.json({sessionId:t,status:i,agentId:o.agentId,workspacePath:o.workspacePath,messageCount:a.length})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),h.get("/sdk/capabilities/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",i=A.get(s).getCapabilities?.(t)??null;n.json({ok:!0,sessionId:t,agentId:o.agentId,capabilities:i,fetchedAt:Date.now()})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),h.get("/sdk/pending-questions/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",i=A.get(s).getPendingQuestion?.(t)??null;n.json({ok:!0,sessionId:t,agentId:o.agentId,pendingQuestion:i?{toolCallId:i.toolCallId,questions:i.questions}:null,fetchedAt:Date.now()})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),h.post("/command",S,async(e,n)=>{const{sessionId:t,command:o}=e.body||{};if(!t||o===void 0||o===null){n.status(400).json({error:"sessionId and command are required"});return}try{const s=await xn(String(t),o);n.json({ok:!0,mode:"terminal",...s})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}});function So(e,n){if(typeof e!="string"||!e||!n||typeof n!="object")return e;const{userId:t,name:o,type:s}=n,r=typeof t=="string"&&t.trim()?t.trim():"",i=typeof o=="string"&&o.trim()?o.trim():r;if(!r&&!i)return e;const a=typeof s=="string"&&s.trim()?s.trim().toUpperCase():"HUMAN",c=i||r,u=r?`, userId: ${r}`:"";return`\u3010${c}\uFF08${a}${u}\uFF09\u53D1\u6765\u3011
|
|
41
|
-
${e}`}
|
|
40
|
+
`):void 0}const v={command:s||"acode",workingDirectory:o,agentId:A,...Be?{scopeKey:Be}:{},...typeof Fe=="boolean"?{browserAllowPrivate:Fe}:{},autoAccept:!!i,initialPrompt:a,systemPrompt:ve,...Oe!==void 0?{globalPrompt:Oe}:{},...De!==void 0?{rolePrompt:De}:{},...ae!==void 0?{memory:ae}:{},...ce!==void 0?{resumeContext:ce}:{},...k==="acode"&&Array.isArray(N?se:z)&&((N?se:z)?.length??0)>0?{resumeTranscript:N?se:z}:{},...k==="acode"&&!N&&re?{resumeTokenUsage:re}:{},...k==="acode"&&N&&Ee?{resumeTokenUsage:Ee}:{},model:X,mcpConfigPath:we,...Q?{instanceAiConfig:Q}:{},...typeof be=="string"&&be.trim()?{subAgentModel:be.trim()}:{},...typeof Ce=="string"&&Ce.trim()?{subAgentEffort:Ce.trim()}:{},extraMcpServers:I||{},envOverrides:Tt(String(t),String(o),process.env,$e,typeof r=="string"?r:void 0)};J.log({level:"info",category:"launch",message:"\u4F20\u9012\u7ED9 Adapter \u7684\u5B8C\u6574 AdapterSessionConfig",source:"bridge",agentId:A,sessionId:R,details:{adapterModel:v.model??null,adapterInstanceAiConfig:v.instanceAiConfig?pe(v.instanceAiConfig):null,adapterMcpConfigPath:v.mcpConfigPath??null}}),await J.flush(),f.set(R,{agentId:A,workspacePath:o,sessionId:R,config:v,providerId:k,seq:0,runtimeAccessToken:ie,schedulerBaseUrl:F}),N&&$(A,R,"starting",{actionType:"hibernation_wake",actionLabel:"\u4F11\u7720\u5524\u9192\u4E2D",actionDetail:"\u68C0\u6D4B\u5230\u4E0A\u6B21\u8FD0\u884C\u5F02\u5E38\u4E2D\u65AD\u7684\u672C\u5730\u8FDB\u5EA6\uFF0C\u6B63\u5728\u63A5\u7EED\u4E0A\u4E0B\u6587\u2026",actionId:`crash-recovery-${R}`},void 0,{runtimeAccessToken:ie,schedulerBaseUrl:F}).catch(()=>{}),n.json({sessionId:R,status:"starting",runtimeStatus:"starting",agentId:A,workspacePath:o,command:v.command,mode:"sdk"}),_o({sessionId:R,agentId:A,config:v,adapter:L,providerId:k,idleInputAutoCommand:b,nonInputAutoCommand:K,runtimeAccessToken:ie,requestedSchedulerBaseUrl:F})}catch(O){if(R&&(U(R),f.delete(R),q(R)),A&&V.delete(A),!n.headersSent){const m=O instanceof Error?O.message:String(O);n.status(500).json({error:`Failed to start SDK session: ${m}`})}}}async function _o(e){const{sessionId:n,agentId:t,config:o,adapter:s,providerId:r,idleInputAutoCommand:i,nonInputAutoCommand:a,runtimeAccessToken:c,requestedSchedulerBaseUrl:u}=e;try{await s.startSession(n,o),s.setIdleCommands?.(n,{idleInputCommand:i||We,nonInputCommand:a||""});let d;if(Cn(r))try{if(await new Promise(p=>setTimeout(p,500)),d=s.getSessionPid?.(n),!d){const y=(await Qt()).find(C=>C.agentId===t||C.cwd===o.workingDirectory||C.command.includes(o.workingDirectory));y&&(d=y.pid,l.info(`[Runtime] Found SDK process PID: ${d} for agentId=${t}`))}}catch(p){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,p)}const g=ne(s.getSessionStatus(n),f.get(n)?.currentRuntimeStatus,f.get(n)?.currentRuntimeActionType);await dn({sessionId:n,agentId:t,workspacePath:o.workingDirectory,command:o.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:g,mode:"sdk",pid:d,providerSessionId:s.getProviderSessionId(n)}),d&&await Pe().startProcess({agentId:t,sessionId:n,pid:d,mode:"sdk",workspacePath:o.workingDirectory,command:o.command}),await bo({agentId:t,sessionId:n,sdkPid:d,status:g,schedulerBaseUrl:u,runtimeAccessToken:c})}catch(d){U(n),f.delete(n),q(n),await G(n);const g=d instanceof Error?d.message:String(d);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${g}`),await Co({agentId:t,sessionId:n,schedulerBaseUrl:u,runtimeAccessToken:c,errorMessage:g})}finally{V.delete(t)}}async function bo(e){const{agentId:n,sessionId:t,sdkPid:o,status:s,schedulerBaseUrl:r,runtimeAccessToken:i}=e;if(!r||!i){l.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${r.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Ke.post(a,{agentId:n,sessionId:t,status:s,pid:o},{headers:{"X-Runtime-Token":i,"Content-Type":"application/json"},timeout:5e3}),l.debug(`[Runtime] Notified server session ready: agentId=${n}, sessionId=${t}, status=${s}`)}catch(c){const u=c instanceof Error?c.message:String(c);l.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${u}`)}}async function Co(e){const{agentId:n,sessionId:t,schedulerBaseUrl:o,runtimeAccessToken:s}=e;if(!o||!s)return;const r=`${o.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Ke.post(r,{agentId:n,sessionId:t,status:"stopped"},{headers:{"X-Runtime-Token":s,"Content-Type":"application/json"},timeout:5e3}),l.debug(`[Runtime] Notified server session failed: agentId=${n}, sessionId=${t}`)}catch(i){const a=i instanceof Error?i.message:String(i);l.warn(`[Runtime] Failed to notify server session failed: agentId=${n}, error=${a}`)}}T.post("/sdk/message",h,async(e,n)=>{const{sessionId:t,message:o}=e.body||{};if(!t||!o){n.status(400).json({error:"sessionId and message are required"});return}const s=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const r=s.providerId||"claude-code";await _.get(r).sendMessage(t,o),n.json({ok:!0})}catch(r){const i=r instanceof Error?r.message:String(r);n.status(500).json({error:i})}}),T.post("/sdk/answer",h,async(e,n)=>{const{sessionId:t,answers:o,cancelled:s,reason:r}=e.body||{},i=s===!0;if(!t||!i&&!o){n.status(400).json({error:i?"sessionId is required":"sessionId and answers are required"});return}const a=f.get(t);if(!a){n.status(404).json({error:"SDK session not found"});return}try{const c=a.providerId||"claude-code",u=_.get(c);if(i){if(!u.cancelQuestionAnswer){n.status(400).json({error:"adapter does not support cancelling a question"});return}l.debug(`[sdk/answer] cancel question: sessionId=${t}, providerId=${c}, hasReason=${!!String(r||"").trim()}`),await u.cancelQuestionAnswer(t,typeof r=="string"?r:void 0)}else u.sendQuestionAnswer&&await u.sendQuestionAnswer(t,o);n.json({ok:!0})}catch(c){const u=c instanceof Error?c.message:String(c);n.status(500).json({error:u})}}),T.post("/tool-auth/answer",h,async(e,n)=>{const{sessionId:t,requestId:o,allowed:s}=e.body||{};if(!t||!o){n.status(400).json({error:"sessionId and requestId are required"});return}const r=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const i=r.providerId||"claude-code",a=_.get(i);if(!a.submitToolPermissionDecision){n.status(400).json({error:"adapter does not support tool authorization"});return}const c=a.submitToolPermissionDecision(t,String(o),!!s);n.json({ok:!0,existed:c})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),T.get("/tool-auth/pending/:sessionId",h,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",i=_.get(s).getPendingToolAuthRequests?.(t)??[];n.json({ok:!0,sessionId:t,agentId:o.agentId,pendingRequests:i,fetchedAt:Date.now()})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),T.post("/sdk/confirm",h,async(e,n)=>{const{sessionId:t,accept:o}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const s=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const r=s.providerId||"claude-code";await _.get(r).sendConfirmation(t,!!o),n.json({ok:!0})}catch(r){const i=r instanceof Error?r.message:String(r);n.status(500).json({error:i})}}),T.post("/sdk/abort",h,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code";await _.get(s).abortCurrentTurn(t),n.json({ok:!0})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),T.post("/sdk/stop",h,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.json({ok:!0,status:"stopped"});return}try{const s=o.providerId||"claude-code",r=_.get(s);r.abortCurrentTurn(t).catch(()=>{}),await r.terminateSession(t),U(t),f.delete(t),q(t),Ie(t),fe(o.agentId),await G(t),await Pe().removeProcess(o.agentId),await $(o.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl}),n.json({ok:!0,status:"stopped"})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),T.get("/sdk/snapshot/:sessionId",h,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",r=_.get(s),i=r.getConversation(t),a=Sn(i);let c=null;if(s==="acode"){const d=r;typeof d.exportRawTranscript!="function"?l.warn(`[HIBERNATE-EXPORT] adapter \u65E0 exportRawTranscript \u65B9\u6CD5 \u2014 bridge \u8FDB\u7A0B\u53EF\u80FD\u8FD0\u884C\u7684\u662F\u65E7\u6784\u5EFA\uFF08\u8BF7\u91CD\u542F bridge\uFF09\u3002providerId=${s}`):(c=d.exportRawTranscript?.(t)??null,c===null&&l.warn(`[HIBERNATE-EXPORT] exportRawTranscript \u8FD4\u56DE\u7A7A \u2014 runtime \u53EF\u80FD\u672A\u5B8C\u6210 start() \u6216\u4E0D\u652F\u6301\u3002providerId=${s}`))}else l.info(`[HIBERNATE-EXPORT] provider=${s} \u4E0D\u652F\u6301\u5B8C\u6574\u91CD\u653E\uFF0C\u6309\u4EC5\u6458\u8981\u4F11\u7720`);const u=r.getTotalUsage?.(t);l.info(`[HIBERNATE-EXPORT] \u5FEB\u7167\u5BFC\u51FA: sessionId=${t} agentId=${o.agentId} providerId=${s} messages=${i.length} summaryChars=${a.snapshot.length} truncated=${a.truncated} transcript=${c?`${c.length}\u6761`:"null"} usage=${u?`in=${u.inputTokens??"?"}/out=${u.outputTokens??"?"}`:"null"} totalUsage=${u?`in=${u.totalInputTokens??"?"}/out=${u.totalOutputTokens??"?"}`:"null"}`),n.json({sessionId:t,agentId:o.agentId,workspacePath:o.workspacePath,messageCount:i.length,truncated:a.truncated,snapshot:a.snapshot,transcript:c,tokenUsage:u?{inputTokens:u.inputTokens??null,outputTokens:u.outputTokens??null,totalInputTokens:u.totalInputTokens??null,totalOutputTokens:u.totalOutputTokens??null,cacheHitTokens:u.cacheHitTokens??null,cacheMissTokens:u.cacheMissTokens??null}:null,providerId:s})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),T.get("/sdk/status/:sessionId",h,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",r=_.get(s),i=r.getSessionStatus(t),a=r.getConversation(t);n.json({sessionId:t,status:i,agentId:o.agentId,workspacePath:o.workspacePath,messageCount:a.length})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),T.get("/sdk/capabilities/:sessionId",h,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",i=_.get(s).getCapabilities?.(t)??null;n.json({ok:!0,sessionId:t,agentId:o.agentId,capabilities:i,fetchedAt:Date.now()})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),T.get("/sdk/pending-questions/:sessionId",h,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",i=_.get(s).getPendingQuestion?.(t)??null;n.json({ok:!0,sessionId:t,agentId:o.agentId,pendingQuestion:i?{toolCallId:i.toolCallId,questions:i.questions}:null,fetchedAt:Date.now()})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}}),T.post("/command",h,async(e,n)=>{const{sessionId:t,command:o}=e.body||{};if(!t||o===void 0||o===null){n.status(400).json({error:"sessionId and command are required"});return}try{const s=await zn(String(t),o);n.json({ok:!0,mode:"terminal",...s})}catch(s){const r=s instanceof Error?s.message:String(s);n.status(500).json({error:r})}});function Eo(e,n){if(typeof e!="string"||!e||!n||typeof n!="object")return e;const{userId:t,name:o,type:s}=n,r=typeof t=="string"&&t.trim()?t.trim():"",i=typeof o=="string"&&o.trim()?o.trim():r;if(!r&&!i)return e;const a=typeof s=="string"&&s.trim()?s.trim().toUpperCase():"HUMAN",c=i||r,u=r?`, userId: ${r}`:"";return`\u3010${c}\uFF08${a}${u}\uFF09\u53D1\u6765\u3011
|
|
41
|
+
${e}`}T.post("/input",h,async(e,n)=>{const{sessionId:t,input:o,mode:s,sender:r}=e.body||{};if(!t||o===void 0||o===null){n.status(400).json({error:"sessionId and input are required"});return}const i=f.get(t);if(!i){n.status(404).json({error:"SDK session not found"});return}try{const a=i.providerId||"claude-code",c=_.get(a);if(s==="shortcut"){if(!c.sendShortcutInput){n.status(400).json({error:"shortcut input is not supported by this SDK provider"});return}await c.sendShortcutInput(t,String(o)),n.json({ok:!0,mode:"shortcut"});return}await c.sendMessage(t,Eo(await qn(o),r)),n.json({ok:!0,mode:"sdk"})}catch(a){const c=a instanceof Error?a.message:String(a);n.status(500).json({error:c})}}),T.post("/update-auto-commands",h,async(e,n)=>{const{agentId:t,idleInputAutoCommand:o="",nonInputAutoCommand:s=""}=e.body||{},r=String(t||"").trim();if(!r){n.status(400).json({error:"agentId is required"});return}const i=[...f.values()].find(c=>c.agentId===r),a={idleInputCommand:String(o||"").trim()||We,nonInputCommand:String(s||"")};try{let c=!1;i&&(_.get(i.providerId||"claude-code").setIdleCommands?.(i.sessionId,a),c=!0);const u=await cn(r,{idleInputAutoCommand:a.idleInputCommand,nonInputAutoCommand:a.nonInputCommand});n.json({ok:!0,mode:"sdk",sessionUpdated:c,persistedUpdated:u})}catch(c){const u=c instanceof Error?c.message:String(c);n.status(500).json({ok:!1,mode:"sdk",error:u})}}),T.post("/resize",h,(e,n)=>{const{sessionId:t,cols:o,rows:s}=e.body||{};if(!t||!o||!s){n.status(400).json({error:"sessionId, cols, rows are required"});return}if(!f.has(t)){n.status(404).json({error:"SDK session not found"});return}n.json({ok:!0,mode:"sdk",noop:!0,cols:Number(o),rows:Number(s)})}),T.post("/reset-context",h,async(e,n)=>{const{sessionId:t,reason:o}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const s=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}const r=s.providerId||"claude-code",i=_.get(r),a=i.resetContext?.bind(i),c=bn(r,!!a);if(!c.supported){n.status(c.statusCode).json({error:c.error});return}if(!a){n.status(500).json({error:"ACode adapter does not expose resetContext"});return}try{await a(String(t));const u=ne(i.getSessionStatus(String(t)),s.currentRuntimeStatus,s.currentRuntimeActionType);n.json({ok:!0,contextReset:!0,sessionId:t,status:u,runtimeStatus:u,agentId:s.agentId,mode:"sdk",providerId:r,reason:typeof o=="string"&&o.trim()?o.trim():void 0})}catch(u){const d=u instanceof Error?u.message:String(u);n.status(500).json({ok:!1,contextReset:!1,mode:"sdk",error:d})}}),T.post("/compact-context",h,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({ok:!1,error:"sessionId is required"});return}const o=f.get(t);if(!o){n.status(404).json({ok:!1,error:"SDK session not found"});return}const s=o.providerId||"claude-code",r=_.get(s),i=r.compactContext?.bind(r);if(!i){n.status(400).json({ok:!1,error:`context compaction is not supported by provider: ${s}`});return}try{const a=i(String(t)),c=ne(r.getSessionStatus(String(t)),o.currentRuntimeStatus,o.currentRuntimeActionType);n.json({ok:!0,requested:!0,compacted:!0,sessionId:t,agentId:o.agentId,mode:"sdk",providerId:s,status:c,runtimeStatus:c,result:a??null})}catch(a){const c=a instanceof Error?a.message:String(a);l.warn(`[Runtime] compact-context failed: sessionId=${t}, error=${c}`),n.status(500).json({ok:!1,compacted:!1,mode:"sdk",error:c})}}),T.post("/stop",h,async(e,n)=>{const{sessionId:t}=e.body||{},o=En(e.body);if(!t&&!o.discardContext){n.status(400).json({error:"sessionId is required"});return}const s=t?f.get(t):void 0;if(!s){if(o.discardContext){const i=typeof(e.body||{})?.agentId=="string"?e.body.agentId:void 0;i&&await $t(i).catch(()=>{})}t&&await G(t),n.json({ok:!0,status:"stopped",mode:"none",statusNotified:!1,reason:o.reason});return}const r=s.agentId;try{l.info(`[Runtime] Stopping SDK session ${t}; suppressStatus=${!o.statusNotified}, reason=${o.reason||"unspecified"}`);const i=s.providerId||"claude-code",a=_.get(i);a.abortCurrentTurn(t).catch(()=>{}),await a.terminateSession(t,{discardContext:o.discardContext}),U(t),f.delete(t),q(t),Ie(t),fe(r),await G(t),await Pe().removeProcess(r),o.statusNotified?await $(r,null,"stopped",void 0,void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl}):l.info(`[Runtime] Stopped status notification suppressed for SDK session ${t}; reason=${o.reason||"unspecified"}`),n.json({ok:!0,status:"stopped",mode:"sdk",statusNotified:o.statusNotified,reason:o.reason})}catch(i){const a=i instanceof Error?i.message:String(i);console.error(`[Runtime] Failed to terminate SDK session ${t}:`,a),n.status(500).json({ok:!1,status:"stop_failed",mode:"sdk",error:a})}}),T.post("/stop-all",h,async(e,n)=>{const t=[],o=[];for(const[s,r]of f.entries())try{const i=r.providerId||"claude-code",a=_.get(i);a.abortCurrentTurn(s).catch(()=>{}),await a.terminateSession(s),U(s),f.delete(s),q(s),Ie(s),fe(r.agentId),t.push(s),await $(r.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}catch(i){const a=i instanceof Error?i.message:String(i);o.push(`SDK ${s}: ${a}`)}try{await an([]),l.info("[Runtime] \u5DF2\u6E05\u7A7A\u6240\u6709\u6301\u4E45\u5316\u4F1A\u8BDD")}catch(s){const r=s instanceof Error?s.message:String(s);o.push(`Persistence: ${r}`)}n.json({ok:!0,stopped:{sdk:t.length},errors:o.length>0?o:void 0})}),T.get("/events/last/:n",h,(e,n)=>{const t=parseInt(e.params.n,10);if(!Number.isFinite(t)||t<1){n.status(400).json({error:":n must be a positive integer"});return}const o=it.getLastN(t);n.json({ok:!0,count:o.length,entries:o})}),T.get("/events/since/:index",h,(e,n)=>{const t=parseInt(e.params.index,10);if(!Number.isFinite(t)||t<0){n.status(400).json({error:":index must be a non-negative integer"});return}const o=it.getSinceIndex(t);n.json({ok:!0,entries:o.entries,nextIndex:o.nextIndex,oldestIndex:o.oldestIndex,dataLoss:o.oldestIndex>t+1})}),T.get("/events/push-stats",h,(e,n)=>{const t=jt();n.json({ok:!0,count:t.length,agents:t})});export{ft as CRASH_RECOVERY_NOTICE_CLEAN,kn as CRASH_RECOVERY_NOTICE_INTERRUPTED,Dn as buildAcodeCommandOutputPath,Yn as buildClaudeCodeLaunchConfig,Tt as buildRuntimeEnv,Zn as buildSdkOutputMetadata,Xn as buildToolResultTimelineActionInfo,ar as cleanupSdkSessionByAgentId,Mn as countTerminalOutputLines,St as createTerminalOutputDecoder,ye as decodeTerminalOutputChunk,So as enqueueCompactionSummaryChunk,vn as evaluatePersistedSessionReuse,je as flushCompactionSummaryAccumulator,Ln as formatCommandInactivityTimeoutNotice,Pn as formatCommandOutputSpilloverNotice,Qn as formatSdkOutputEvent,Ue as formatTerminalPrompt,$n as isIdleStatusChangeRetryable,wn as isUsageOnlyStatusChange,Un as normalizeTerminalCommandInput,An as parseResumeTokenUsage,Tn as parseResumeTranscript,En as parseRuntimeStopOptions,jn as parseTerminalDirectoryChangeTarget,Te as raceSendOutputWithRetry,Sn as renderSessionSnapshot,bn as resolveRuntimeContextResetSupport,lo as resolveRuntimeStatusFromProviderEvent,qn as resolveSdkInputMessage,bt as resolveSdkProviderId,ne as resolveSdkSessionDisplayStatus,Rn as resolveStatusChangeRuntimeState,Z as resolveStatusChangeUsage,xn as resolveTerminalOutputEncoding,f as sdkSessions,Cn as shouldProbeSdkProcessPid,T as terminalRouter,Eo as withSenderSignature};
|
|
42
42
|
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
|
|
19
20
|
import { type UserScope } from "./user-scope.js";
|
|
20
21
|
export interface AgentOwnerRecord {
|
|
21
22
|
tenantId: string;
|
|
@@ -56,3 +57,18 @@ export declare function listAgentsOwnedBy(scope: UserScope): string[];
|
|
|
56
57
|
|
|
57
58
|
|
|
58
59
|
export declare function removeAgentOwner(agentId: string): void;
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
export declare function ensureMachineAgentOwnership(agentId: string, scope: UserScope | null | undefined): boolean;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{existsSync as
|
|
2
|
-
`,"utf8"),o.set(
|
|
1
|
+
import{existsSync as h,mkdirSync as m,readdirSync as I,readFileSync as S,rmSync as O,writeFileSync as y}from"node:fs";import a from"node:path";import{getBridgeDataHome as A,getBridgeInstanceRuntimeDir as x}from"../config.js";import{createLogger as F}from"../utils/logger.js";import{normalizeUserScope as w,scopeEquals as f,sanitizeScopeId as j,setAgentOwnershipChecker as k,setMachineOwnershipSelfHeal as D}from"./user-scope.js";const g=F("agent-ownership"),o=new Map;function d(e){return a.join(x(e),"owner.json")}function u(e){return j(e)}function J(e){o.delete(u(e))}function N(){o.clear()}function p(e){const t=d(e);try{if(!h(t))return null;const n=JSON.parse(S(t,"utf8")),r=w(n.tenantId,n.userId);return r?{tenantId:r.tenantId,userId:r.userId,...n.operatorUserId?{operatorUserId:String(n.operatorUserId)}:{},updatedAt:String(n.updatedAt??new Date().toISOString())}:null}catch(n){return g.warn("[ownership] owner.json \u8BFB\u53D6\u5931\u8D25 agent=%s: %s",e,n instanceof Error?n.message:String(n)),null}}function E(e,t,n){const r=w(t.tenantId,t.userId);if(!r)throw new Error("registerAgentOwner: (tenantId, userId) \u4E0D\u5B8C\u6574");const i=c(e);if(i&&!f(i,r))throw new Error("agent-ownership-mismatch: agent \u5DF2\u5F52\u5C5E\u5176\u4ED6\u7528\u6237\uFF0C\u4E0D\u80FD\u8986\u76D6");const s={tenantId:r.tenantId,userId:r.userId,...n?{operatorUserId:n}:{},updatedAt:new Date().toISOString()},l=d(e);return m(a.dirname(l),{recursive:!0}),y(l,`${JSON.stringify(s,null,2)}
|
|
2
|
+
`,"utf8"),o.set(u(e),s),s}function c(e){const t=u(e);if(o.has(t)){const r=o.get(t);return r?{tenantId:r.tenantId,userId:r.userId}:null}const n=p(e);return o.set(t,n),n?{tenantId:n.tenantId,userId:n.userId}:null}function R(e){const t=u(e);if(o.has(t))return o.get(t)??null;const n=p(e);return o.set(t,n),n}function v(e,t){if(!t)return!1;const n=c(e);return n?f(n,t):!1}function $(e){const t=a.join(A(),"instance-runtime");let n=[];try{n=I(t)}catch{return[]}const r=[];for(const i of n){if(i.startsWith("."))continue;const s=c(i);s&&f(s,e)&&r.push(i)}return r}function q(e){try{O(d(e),{force:!0})}catch{}o.delete(u(e))}function z(e,t){return!t||!/^machine-[0-9a-fA-F-]+$/.test(String(e??"").trim())||c(e)?!1:(E(e,t),g.info("[ownership] machine \u4F2A agent \u5F52\u5C5E\u81EA\u6108\u767B\u8BB0 agent=%s tenant=%s user=%s",e,t.tenantId,t.userId),!0)}k((e,t)=>v(e,t)),D(z);export{v as assertAgentOwnership,N as clearAgentOwnerCache,z as ensureMachineAgentOwnership,c as getAgentOwner,R as getAgentOwnerRecord,J as invalidateAgentOwner,$ as listAgentsOwnedBy,E as registerAgentOwner,q as removeAgentOwner};
|
|
3
3
|
|
|
@@ -41,6 +41,20 @@ export declare class PluginDeploymentStore {
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
resolveDeployedSourceDir(name: string): string | null;
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
private readMergedManifest;
|
|
50
|
+
|
|
51
|
+
hasLegacyManifestEntry(pluginName: string): boolean;
|
|
52
|
+
|
|
53
|
+
activeSharedManifest(): SharedPluginEntry[];
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
44
58
|
readSharedManifest(): SharedPluginEntry[];
|
|
45
59
|
writeSharedManifest(entries: SharedPluginEntry[]): void;
|
|
46
60
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{cpSync as S,existsSync as
|
|
2
|
-
`,"utf8")}async migrateLegacySharedIfNeeded(){try{if(
|
|
1
|
+
import{cpSync as S,existsSync as a,lstatSync as M,mkdirSync as f,readFileSync as d,readdirSync as P,renameSync as D,rmSync as u,symlinkSync as w,writeFileSync as N}from"node:fs";import{join as n,resolve as m}from"node:path";import{getBridgeInstancePluginsDir as v}from"../config.js";import{sanitizeAgentId as F,sanitizeArchiveFileName as k,withFileLock as L}from"../utils/file-utils.js";import{createLogger as $}from"../utils/logger.js";import{isValidPluginName as h,PLUGIN_NAME_PATTERN as A}from"./plugin-manifest.js";import{extractPluginZip as R}from"./plugin-package.js";const l=$("plugin-manager"),E=process.platform==="win32"?"junction":"dir";class x{constructor(e,i,r,t){this.rootDir=e,this.runtimeRootDir=i,this.loader=r,this.legacyRootDir=t}deployedDir(){return n(this.rootDir,"deployed")}deployedManifestFile(){return n(this.deployedDir(),"manifest.json")}legacyDeployedDir(){return this.legacyRootDir?n(this.legacyRootDir,"deployed"):""}legacyDeployedManifestFile(){return this.legacyDeployedDir()?n(this.legacyDeployedDir(),"manifest.json"):""}deployedPluginDir(e){if(!h(e))throw new Error(`\u975E\u6CD5\u63D2\u4EF6\u540D\uFF08\u4EC5\u5141\u8BB8 ${A}\uFF09: ${JSON.stringify(e)}`);const i=n(this.deployedDir(),e),r=m(this.deployedDir());if(m(i)!==n(r,e))throw new Error(`\u63D2\u4EF6\u76EE\u5F55\u8D8A\u51FA\u90E8\u7F72\u533A: ${e}`);return i}legacySharedDir(){return n(this.rootDir,"shared")}deployedPluginHealthy(e){return a(n(this.deployedPluginDir(e),"plugin.json"))||this.legacyPluginHealthy(e)}legacyPluginHealthy(e){if(!this.legacyDeployedDir())return!1;try{const i=n(this.legacyDeployedDir(),e);return a(n(i,"plugin.json"))}catch{return!1}}resolveDeployedSourceDir(e){return a(n(this.deployedPluginDir(e),"plugin.json"))?this.deployedPluginDir(e):this.legacyPluginHealthy(e)?n(this.legacyDeployedDir(),e):null}readMergedManifest(){const e=new Map;if(this.legacyDeployedManifestFile())try{const i=JSON.parse(d(this.legacyDeployedManifestFile(),"utf8"));for(const r of Array.isArray(i.plugins)?i.plugins:[])r&&h(r.pluginName)&&e.set(r.pluginName,r)}catch{}try{const i=JSON.parse(d(this.deployedManifestFile(),"utf8"));for(const r of Array.isArray(i.plugins)?i.plugins:[])r&&h(r.pluginName)&&e.set(r.pluginName,r)}catch{}return[...e.values()]}hasLegacyManifestEntry(e){if(!this.legacyDeployedManifestFile())return!1;try{const i=JSON.parse(d(this.legacyDeployedManifestFile(),"utf8"));return(Array.isArray(i.plugins)?i.plugins:[]).some(r=>r&&h(r.pluginName)&&r.pluginName===e)}catch{return!1}}activeSharedManifest(){return this.readMergedManifest().filter(e=>!e.removed)}readSharedManifest(){return this.activeSharedManifest()}writeSharedManifest(e){f(this.deployedDir(),{recursive:!0}),N(this.deployedManifestFile(),`${JSON.stringify({version:2,plugins:e},null,2)}
|
|
2
|
+
`,"utf8")}async migrateLegacySharedIfNeeded(){try{if(a(this.deployedManifestFile()))return;const e=n(this.legacySharedDir(),"manifest.json");if(!a(e))return;const i=JSON.parse(d(e,"utf8")),r=Array.isArray(i.plugins)?i.plugins:[];if(r.length===0)return;const t=[];let s=0,o=0;for(const y of r){const g=k(y.zipFile??"","");if(!y.pluginName||!g)continue;const p=n(this.legacySharedDir(),g);if(a(p)){s+=1;try{const c=await this.deployPluginZipToPersistentDir(d(p),y.pluginName);if(!c){o+=1;continue}t.push(c),l.info("[shared] \u65E7\u5171\u4EAB\u63D2\u4EF6\u8FC1\u79FB\u5230\u90E8\u7F72\u533A: %s",y.pluginName)}catch(c){o+=1,l.warn("[shared] \u65E7\u5171\u4EAB\u63D2\u4EF6 %s \u8FC1\u79FB\u5931\u8D25: %s",y.pluginName,c instanceof Error?c.message:String(c))}}}t.length>0&&this.writeSharedManifest(t),o===0?u(this.legacySharedDir(),{recursive:!0,force:!0}):l.warn("[shared] \u65E7\u5171\u4EAB\u63D2\u4EF6\u8FC1\u79FB\u90E8\u5206\u5931\u8D25\uFF08%d/%d\uFF09\uFF0C\u4FDD\u7559 shared/ \u76EE\u5F55\u4EE5\u514D\u6570\u636E\u4E22\u5931",o,s)}catch(e){l.warn("[shared] \u65E7\u5171\u4EAB\u63D2\u4EF6\u8FC1\u79FB\u672A\u6267\u884C\uFF08\u4E0B\u6B21\u91CD\u8BD5\uFF09: %s",e instanceof Error?e.message:String(e))}}async deployPluginZipToPersistentDir(e,i){if(!e||e.length===0)return null;const r=n(this.rootDir,"tmp",`migrate-${Date.now()}-${Math.random().toString(36).slice(2,8)}`);try{const t=await R(e,r),s=this.loader.loadManifestOnly(t.pluginDir);if(!s.ok)return null;const o=s.manifest.name;return i&&o!==i?null:(this.replaceDeployedDir(o,t.pluginDir),{pluginName:o,zipFile:`${o}.zip`,fileName:`${o}.zip`,defaultEnabled:!0})}finally{u(r,{recursive:!0,force:!0})}}replaceDeployedDir(e,i){f(this.deployedDir(),{recursive:!0});const r=this.deployedPluginDir(e),t=n(this.deployedDir(),`.old-${e}-${Date.now()}-${Math.random().toString(36).slice(2,8)}`);a(r)&&D(r,t);try{S(i,r,{recursive:!0,filter:s=>!/[\\/]\.git([\\/]|$)/.test(s)&&!/[\\/]node_modules([\\/]|$)/.test(s)})}catch(s){throw a(t)&&(u(r,{recursive:!0,force:!0}),D(t,r)),s}a(t)&&u(t,{recursive:!0,force:!0})}removeDeployedDir(e){u(this.deployedPluginDir(e),{recursive:!0,force:!0})}async updateSharedManifest(e){await L(this.deployedManifestFile(),async()=>{this.writeSharedManifest(e(this.readMergedManifest()))})}runtimeDirFor(e){return this.runtimeRootDir?n(this.runtimeRootDir,F(e)):v(e)}runtimeLinkPath(e,i){return n(this.runtimeDirFor(e),i)}ensureRuntimeLink(e,i){const r=this.runtimeLinkPath(e,i),t=this.resolveDeployedSourceDir(i);if(!t)return!1;f(this.runtimeDirFor(e),{recursive:!0});try{if(a(r)){let s=!1;try{s=M(r).isSymbolicLink()}catch{s=!1}if(s)try{return P(r),!0}catch{}u(r,{recursive:!0,force:!0})}return w(t,r,E),l.info("[agent:%s] \u63D2\u4EF6\u8FD0\u884C\u65F6\u94FE\u63A5\u5DF2\u5EFA\u7ACB: %s \u2192 %s",e,r,t),!0}catch(s){return l.warn("[agent:%s] \u63D2\u4EF6\u8FD0\u884C\u65F6\u94FE\u63A5\u5931\u8D25\uFF08%s \u2192 %s\uFF09: %s",e,i,t,s instanceof Error?s.message:String(s)),!1}}removeRuntimeLink(e,i){const r=this.runtimeLinkPath(e,i);try{a(r)&&(u(r,{recursive:!0,force:!0}),l.info("[agent:%s] \u63D2\u4EF6\u8FD0\u884C\u65F6\u94FE\u63A5\u5DF2\u79FB\u9664: %s",e,i))}catch(t){l.warn("[agent:%s] \u63D2\u4EF6\u8FD0\u884C\u65F6\u94FE\u63A5\u79FB\u9664\u5931\u8D25\uFF08%s\uFF09: %s",e,i,t instanceof Error?t.message:String(t))}}}export{x as PluginDeploymentStore};
|
|
3
3
|
|
|
@@ -29,11 +29,14 @@ export interface PluginManagerOptions {
|
|
|
29
29
|
rootDir?: string;
|
|
30
30
|
|
|
31
31
|
runtimeRootDir?: string;
|
|
32
|
+
|
|
33
|
+
legacyRootDir?: string;
|
|
32
34
|
}
|
|
33
35
|
export declare class PluginManager {
|
|
34
36
|
private agents;
|
|
35
37
|
private readonly rootDir?;
|
|
36
38
|
private readonly runtimeRootDir?;
|
|
39
|
+
private readonly legacyRootDir?;
|
|
37
40
|
|
|
38
41
|
private readonly deployStores;
|
|
39
42
|
|