aws-runtime-bridge 1.9.170 → 1.9.171
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/dist/adapter/AcodeSdkAdapter.js +3 -3
- package/dist/index.js +1 -1
- package/dist/routes/terminal.js +19 -25
- package/dist/services/agent-startup-memory.d.ts +11 -0
- package/dist/services/agent-startup-memory.js +8 -0
- package/dist/services/log-retention.d.ts +37 -0
- package/dist/services/log-retention.js +2 -0
- package/dist/services/request-invalid-dump.d.ts +21 -0
- package/dist/services/request-invalid-dump.js +2 -0
- package/dist/utils/lifecycle-log.d.ts +2 -0
- package/dist/utils/lifecycle-log.js +2 -2
- package/package/acode/dist/image-utils.js +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +4 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +32 -18
- package/package/aws-client-agent-mcp/dist/status-reporter.js +1 -1
- package/package/aws-client-agent-mcp/dist/tool-groups.js +2 -2
- package/package/aws-client-agent-mcp/dist/types.d.ts +15 -1
- package/package.json +1 -1
package/dist/routes/terminal.js
CHANGED
|
@@ -1,48 +1,42 @@
|
|
|
1
|
-
import{spawn as
|
|
1
|
+
import{spawn as It}from"node:child_process";import{promises as ne}from"node:fs";import St from"node:os";import re from"node:path";import{TextDecoder as oe}from"node:util";import Oe from"axios";import{Router as ht}from"express";import{v4 as At}from"uuid";import{adapterRegistry as h,getToolActionInfo as ke,isTransientClipboardPasteFilePath as Le,redactTransientClipboardPastePaths as v,registerSdkProviders as Tt,resolveSdkProviderIdByCommand as _t}from"../adapter/index.js";import{MESSAGE_POLLING_IDLE_PROMPT as Me}from"../adapter/prompts.js";import{getActiveBridgeHttpPort as bt,getAcodeDataHome as xe}from"../config.js";import{buildResumeContextBlock as kt}from"@agentswork/acode";import{validateToken as y}from"../middleware/auth.js";import{getAgentProcessManager as Ce}from"../services/agent-process-manager.js";import{loadAgentStartupMemories as Ct}from"../services/agent-startup-memory.js";import{createAiConfigService as Et}from"../services/ai-config-service.js";import{resolveSchedulerBaseUrlFromToken as Ue}from"../services/auto-register.js";import{setChangeCacheRetentionDays as wt}from"../services/change-cache-retention.js";import{clearDebugMounts as se}from"../services/debug-mount.js";import{getAllPushStats as $t,startHeartbeatScheduler as Rt}from"../services/event-delta-pusher.js";import{prepareAcodeInstanceConfig as Dt,redactForLog as ie}from"../services/instance-ai-config-service.js";import{setLogRetentionDays as Pt}from"../services/log-retention.js";import{setAgentFeatures as Ot,setAgentCapabilities as Lt,setAgentInheritedFeatures as Mt,setAgentCapabilitiesInherited as xt,getAgentFeatures as Ut,getAgentInheritedFeatures as Nt,getFeatureState as I,LAUNCH_ITEM_FEATURE_KEY as Ne,HIRE_FEATURE_KEY as je,PENCIL_FEATURE_KEY as Be,DRAW_FEATURE_KEY as ve,OFFICE_FEATURE_KEY as Fe,COLLABORATION_TASK_FEATURE_KEY as Ke,COLLABORATION_MEETING_FEATURE_KEY as He,COLLABORATION_DEBUG_FEATURE_KEY as qe,COLLABORATION_FILE_HISTORY_FEATURE_KEY as ze,EMAIL_FEATURE_KEY as We,SKILL_INSTALL_FEATURE_KEY as Ge,ABILITY_DEV_FEATURE_KEY as Ye}from"../services/instance-features.js";import{enqueueMcpLaunchBinding as jt}from"../services/mcp-launch-binding-queue.js";import{setPanelEnvVars as Bt,setAgentMeta as vt}from"../services/panel-env.js";import{findClaudeCodeProcesses as Ft,isProcessRunning as Kt}from"../services/process-detector.js";import{forgetSession as F,onSdkToolUseEnd as Ht,onSdkToolUseStart as qt}from"../services/sdk-tool-file-change-recorder.js";import{bridgeEventBuffer as Xe,sendOutput as Y,sendQuestionRequest as zt,sendToolAuthRequest as Wt,sendStatus as $}from"../services/session-output.js";import{findPersistedSessionByAgentId as Gt,removePersistedSession as K,savePersistedSessions as Yt,updatePersistedSessionAutoCommands as Xt,updatePersistedSessionRuntimeState as Vt,upsertPersistedSession as Jt}from"../services/terminal-persistence.js";import{getInstanceAiConfigDebugLogger as Qt}from"../utils/instance-ai-config-debug-logger.js";import{logger as l}from"../utils/logger.js";const S=ht();function Ve(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,Zt=45e3,ae=new Map;function en(e){if(ae.has(e))return;const n=setInterval(()=>{const t=f.get(e);if(!t){M(e);return}const r=t.currentRuntimeStatus;if(r!=="thinking"&&r!=="tool_using"&&r!=="compacting"){M(e);return}$(t.agentId,e,r,void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl}).catch(()=>{})},Zt);ae.set(e,n)}function M(e){const n=ae.get(e);n&&(clearInterval(n),ae.delete(e))}const Je=4e3,tn=200,nn=2e3,Qe=24e3,Ze=200,et=8e3;function rn(e){if(!Array.isArray(e)||e.length===0)return{snapshot:"",truncated:!1};const n=[];let t=null,r=[];const s=()=>{if(t===null)return;const d=r.join("").trim();if(r=[],!d){t=null;return}const u=t==="user"?"\u7528\u6237":t==="assistant"?"\u52A9\u624B":t;n.push(`\u3010${u}\u3011${ce(d,nn)}`),t=null};for(const d of e){const u=String(d?.role||"").trim();if(!u||u==="system")continue;if(u==="tool_use"||u==="tool_result"){s();const m=String(d.toolName||"").trim()||"\u672A\u77E5\u5DE5\u5177";if(on(m))continue;if(u==="tool_use"){const g=an(String(d.content||""));n.push(`\u3010\u5DE5\u5177\u8C03\u7528\u3011${m}${g?` ${g}`:""}`)}else{const g=ce(String(d.content||"").trim(),tn);n.push(`\u3010\u5DE5\u5177\u7ED3\u679C\u3011${m}${d.isError?"\uFF08\u5931\u8D25\uFF09":""}${g?`\uFF1A${g}`:""}`)}continue}const p=String(d.content||"");p.trim()&&(t===u||(s(),t=u),r.push(p))}if(s(),n.length===0)return{snapshot:"",truncated:!1};const o=n.join(`
|
|
2
2
|
`);if(o.length<=Qe)return{snapshot:o,truncated:!1};const i=Qe-et,a=o.slice(0,et),c=o.slice(o.length-i);return{snapshot:`${a}
|
|
3
3
|
|
|
4
4
|
...\uFF08\u6B64\u5904\u7701\u7565\u4E2D\u6BB5 ${o.length-a.length-c.length} \u5B57\u7B26\u5386\u53F2\uFF09...
|
|
5
5
|
|
|
6
|
-
${c}`,truncated:!0}}function ce(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
|
|
7
|
-
${c.content}`);o.push(`\u3010\u5B9E\u4F8B\u5373\u65F6\u8BB0\u5FC6\u3011
|
|
8
|
-
${a.join(`
|
|
9
|
-
|
|
10
|
-
`)}`),t.length>s&&o.push(`... \u53CA\u53E6\u5916 ${t.length-s} \u6761\u5B9E\u4F8B\u5373\u65F6\u8BB0\u5FC6`)}if(o.length!==0)return o.join(`
|
|
11
|
-
|
|
12
|
-
`)}function an(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 dn(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;return{statusNotified:!n,reason:t}}function de(e){const n=e?.usage;if(!n)return;const t=Number.isFinite(n.inputTokens)?n.inputTokens:0,r=Number.isFinite(n.outputTokens)?n.outputTokens:0;if(t<=0&&r<=0&&!n.contextLimit&&!n.maxOutput&&!n.inputLimit&&!n.compactionThreshold)return;const s={inputTokens:t,outputTokens:r,...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}:{}};return process.env.ACODE_TOKEN_DEBUG==="1"&&(s.inputTokens>0||s.outputTokens>0||s.cacheHitTokens!==void 0||s.cacheMissTokens!==void 0)&&l.info(`[TokenDebug][Terminal] resolveStatusChangeUsage: input=${s.inputTokens} output=${s.outputTokens} cacheHit=${s.cacheHitTokens??"(none)"} cacheMiss=${s.cacheMissTokens??"(none)"} actionType=${e?.actionType??"(none)"}`),s}function un(e,n){const t=String(e||"").trim().toLowerCase(),r=String(n?.actionType||"").trim().toLowerCase();return t==="tool_using"&&r==="idle"?n?{status:"waiting_input",actionInfo:n}:{status:"waiting_input"}:n?{status:e,actionInfo:n}:{status:e}}function ln(e){return e.restoredActionInfo?.actionType==="idle"||e.currentRuntimeActionType==="idle"&&e.shouldPreservePrevAction||e.status==="waiting_input"&&!e.actionInfo?.actionType}const V=new Map,fn="utf-8",nt="utf-8",rt=300,ot=6e4;function Q(e){return String(e).padStart(2,"0")}function mn(e,n=new Date){const t=n.getFullYear(),r=Q(n.getMonth()+1),s=Q(n.getDate()),o=Q(n.getHours()),i=Q(n.getMinutes()),a=`${t}${r}${s}-${o}${i}${Q(n.getSeconds())}-${String(n.getMilliseconds()).padStart(3,"0")}`;return N.join(je(),"cmd-dist",e,`${t}-${r}-${s}`,o,i,`${a}-cmd.out`)}function pn(e){if(!e)return 0;const n=e.replace(/\r\n/g,`
|
|
6
|
+
${c}`,truncated:!0}}function ce(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 on(e){const n=e.toLowerCase();return n.includes("poll_message")||n.includes("get_message")||n.includes("await_complete")}function sn(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"]),r=1e6,o=n.filter(i=>!!i&&typeof i=="object"&&t.has(String(i.role))).filter(i=>JSON.stringify(i).length<=r).slice(0,5e3);return o.length>0?o:void 0}catch{return}}function an(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 ce(n,Ze)}const r=[];for(const s of["file_path","path","filePath","pattern","query","command","cmd","url"]){const o=t[s];if(typeof o=="string"&&o.trim()&&r.push(`${s}=${o.trim()}`),r.length>=3)break}if(r.length===0){const s=Object.keys(t).slice(0,5);return s.length>0?`(${s.join(", ")})`:""}return ce(r.join(" "),Ze)}function tt(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 H=new Set;function cn(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 dn(e){return e!=="acode"}function un(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;return{statusNotified:!n,reason:t}}function de(e){const n=e?.usage;if(!n)return;const t=Number.isFinite(n.inputTokens)?n.inputTokens:0,r=Number.isFinite(n.outputTokens)?n.outputTokens:0;if(t<=0&&r<=0&&!n.contextLimit&&!n.maxOutput&&!n.inputLimit&&!n.compactionThreshold)return;const s={inputTokens:t,outputTokens:r,...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}:{}};return process.env.ACODE_TOKEN_DEBUG==="1"&&(s.inputTokens>0||s.outputTokens>0||s.cacheHitTokens!==void 0||s.cacheMissTokens!==void 0)&&l.info(`[TokenDebug][Terminal] resolveStatusChangeUsage: input=${s.inputTokens} output=${s.outputTokens} cacheHit=${s.cacheHitTokens??"(none)"} cacheMiss=${s.cacheMissTokens??"(none)"} actionType=${e?.actionType??"(none)"}`),s}function ln(e,n){const t=String(e||"").trim().toLowerCase(),r=String(n?.actionType||"").trim().toLowerCase();return t==="tool_using"&&r==="idle"?n?{status:"waiting_input",actionInfo:n}:{status:"waiting_input"}:n?{status:e,actionInfo:n}:{status:e}}function fn(e){return e.restoredActionInfo?.actionType==="idle"||e.currentRuntimeActionType==="idle"&&e.shouldPreservePrevAction||e.status==="waiting_input"&&!e.actionInfo?.actionType}const X=new Map,pn="utf-8",nt="utf-8",rt=300,ot=6e4;function V(e){return String(e).padStart(2,"0")}function mn(e,n=new Date){const t=n.getFullYear(),r=V(n.getMonth()+1),s=V(n.getDate()),o=V(n.getHours()),i=V(n.getMinutes()),a=`${t}${r}${s}-${o}${i}${V(n.getSeconds())}-${String(n.getMilliseconds()).padStart(3,"0")}`;return re.join(xe(),"cmd-dist",e,`${t}-${r}-${s}`,o,i,`${a}-cmd.out`)}function gn(e){if(!e)return 0;const n=e.replace(/\r\n/g,`
|
|
13
7
|
`).replace(/\r/g,`
|
|
14
8
|
`),t=n.endsWith(`
|
|
15
9
|
`)?n.slice(0,-1):n;return t?t.split(`
|
|
16
|
-
`).length:1}function
|
|
10
|
+
`).length:1}function yn(e,n=rt){return`\r
|
|
17
11
|
[ACode] \u547D\u4EE4\u8F93\u51FA\u8D85\u8FC7 ${n} \u884C\uFF0C\u5B8C\u6574\u8F93\u51FA\u5DF2\u5199\u5165: ${e}\r
|
|
18
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
|
|
19
|
-
`}function
|
|
13
|
+
`}function In(e=ot){return`\r
|
|
20
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
|
|
21
|
-
`}async function st(e){const n=e.outputPath||mn(e.agentId,e.startedAt);return e.outputPath=n,await
|
|
22
|
-
`).trim()}function
|
|
23
|
-
`),!0;const s=
|
|
15
|
+
`}async function st(e){const n=e.outputPath||mn(e.agentId,e.startedAt);return e.outputPath=n,await ne.mkdir(re.dirname(n),{recursive:!0}),await ne.writeFile(n,e.chunks.join(""),"utf-8"),n}function Sn(e){return String(e??"").replace(/\r/g,`
|
|
16
|
+
`).trim()}function hn(e=process.platform,n=process.env){const t=n.AWS_TERMINAL_OUTPUT_ENCODING?.trim();return t||(e==="win32"?pn:nt)}function it(e=hn()){if(e!=="utf-8")try{return new oe(e,{fatal:!1})}catch{return new oe(nt,{fatal:!1})}return An()}function An(){let e=null,n=null,t=null;const r=[];function s(o){try{return new oe(o,{fatal:!1})}catch{return new oe("utf-8",{fatal:!1})}}return{decode(o,i){if(o!=null&&r.push(o instanceof ArrayBuffer?Buffer.from(o):Buffer.isBuffer(o)?o:Buffer.from(o.buffer,o.byteOffset,o.byteLength)),t==="gb18030")return n||(n=s("gb18030")),n.decode(o,i);e||(e=s("utf-8"));const a=e.decode(o,i);if(t===null&&a.includes("\uFFFD")){t="gb18030",n=s("gb18030");const c=Buffer.concat(r);return n.decode(c)}return t===null&&!i?.stream&&(t="utf-8"),a}}}function ue(e,n,t=!1){return t?e.decode():!n||n.length===0?"":e.decode(n,{stream:!0})}function Tn(e){const n=e.trim().match(/^cd(?:\s+(.*))?$/i);if(!n)return;const t=n[1]?.trim();if(!t)return null;const r=t.replace(/^\/d\s+/i,"").trim();return r.startsWith('"')&&r.endsWith('"')||r.startsWith("'")&&r.endsWith("'")?r.slice(1,-1):r}function _n(e){const n=X.get(e.sessionId);if(n)return n;const t={currentDirectory:e.workspacePath,runningProcess:null};return X.set(e.sessionId,t),t}function at(e){for(const n of f.values())if(n.agentId===e)return n}async function bn(e){const n=h.get(e.providerId||"claude-code"),t=J(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 J(e,n,t){const r=String(e||"").trim();if(r){const o=String(n||"").trim(),i=String(t||"").trim().toLowerCase();return r.toLowerCase()==="tool_using"&&o.toLowerCase()==="waiting_input"&&i==="idle"?o:r}return String(n||"").trim()||"running"}async function kn(e,n=Kt){return e.pid?await n(e.pid)?pt(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 jr(e){try{se(e)}catch(t){l.warn(`[cleanupSdkSessionByAgentId] clear debug mounts failed for agentId=${e}: ${t}`)}const n=at(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}`),M(t),f.delete(t),F(t),le(t),K(t).catch(r=>{l.warn(`[cleanupSdkSessionByAgentId] Failed to remove persisted session for agentId=${e}: ${r}`)}),t}H.has(e)&&(H.delete(e),l.info(`[cleanupSdkSessionByAgentId] Released startingAgents lock for agentId=${e}`))}function le(e){const n=X.get(e);if(!n?.runningProcess){X.delete(e);return}try{n.runningProcess.kill()}catch{}finally{n.runningProcess=null,X.delete(e)}}function C(e,n){n&&(e.seq+=1,Y(e.agentId,n,e.sessionId,e.seq,void 0,{runtimeAccessToken:e.runtimeAccessToken,schedulerBaseUrl:e.schedulerBaseUrl}).catch(()=>{}))}function Ee(e){return`\x1B[36m${e}>\x1B[0m `}function Cn(e,n){return n==="~"?St.homedir():re.resolve(e,n)}async function En(e,n,t){const r=Tn(t);if(r===void 0)return!1;if(r===null)return C(e,`${n.currentDirectory}\r
|
|
17
|
+
`),!0;const s=Cn(n.currentDirectory,r);try{return(await ne.stat(s)).isDirectory()?(n.currentDirectory=s,C(e,`${n.currentDirectory}\r
|
|
24
18
|
`),!0):(C(e,`cd: not a directory: ${s}\r
|
|
25
19
|
`),!0)}catch(o){const i=o instanceof Error?o.message:String(o);return C(e,`cd: ${i}\r
|
|
26
|
-
`),!0}}async function wn(e,n){const t=
|
|
27
|
-
`),
|
|
28
|
-
`),C(t,
|
|
20
|
+
`),!0}}async function wn(e,n){const t=f.get(e);if(!t)throw new Error("SDK session not found");const r=Sn(n),s=_n(t);if(!r)return{started:!1,cwd:s.currentDirectory};if(s.runningProcess)throw new Error("A terminal command is already running for this session");const o=v(r);if(C(t,`${Ee(s.currentDirectory)}${o}\r
|
|
21
|
+
`),Le(r))return C(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
|
+
`),C(t,Ee(s.currentDirectory)),{started:!1,cwd:s.currentDirectory};if(await En(t,s,r))return{started:!1,cwd:s.currentDirectory};await $(t.agentId,e,"tool_using",{actionType:"bash",actionLabel:"\u7EC8\u7AEF\u547D\u4EE4",actionDetail:o},void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl});const a=It(r,{cwd:s.currentDirectory,shell:!0,env:ct(t.agentId,t.workspacePath,process.env,t.config.envOverrides)});s.runningProcess=a;const c=it(),d=it(),u=t.providerId==="acode",p={agentId:t.agentId,startedAt:new Date,chunks:[],spilled:!1};let m;const g=()=>{m&&(clearTimeout(m),m=void 0)},k=()=>{g(),m=setTimeout(()=>{s.runningProcess===a&&(C(t,In()),a.kill())},ot)},A=(T,E=!0)=>{if(T&&(u&&p.chunks.push(T),u&&E&&k(),!(u&&p.spilled))){if(u&&gn(p.chunks.join(""))>rt){p.spilled=!0,st(p).then(R=>{C(t,yn(R))}).catch(R=>{const D=R instanceof Error?R.message:String(R);C(t,`\r
|
|
29
23
|
[ACode] \u547D\u4EE4\u8F93\u51FA\u843D\u76D8\u5931\u8D25: ${D}\r
|
|
30
24
|
`)});return}C(t,T)}};return u&&k(),a.stdout.on("data",T=>{A(ue(c,T))}),a.stderr.on("data",T=>{A(ue(d,T))}),a.on("error",T=>{C(t,`\r
|
|
31
25
|
[Terminal Error] ${T.message}\r
|
|
32
|
-
`)}),a.on("close",(T,
|
|
26
|
+
`)}),a.on("close",(T,E)=>{g(),s.runningProcess=null,A(ue(c,void 0,!0),!1),A(ue(d,void 0,!0),!1),p.spilled&&st(p).catch(R=>{const D=R instanceof Error?R.message:String(R);C(t,`\r
|
|
33
27
|
[ACode] \u547D\u4EE4\u8F93\u51FA\u6700\u7EC8\u843D\u76D8\u5931\u8D25: ${D}\r
|
|
34
28
|
`)}),T&&T!==0?C(t,`\r
|
|
35
29
|
[exit ${T}]\r
|
|
36
|
-
`):
|
|
37
|
-
[signal ${
|
|
38
|
-
`),C(t,
|
|
39
|
-
...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function
|
|
30
|
+
`):E&&C(t,`\r
|
|
31
|
+
[signal ${E}]\r
|
|
32
|
+
`),C(t,Ee(s.currentDirectory)),$(t.agentId,e,"waiting_input",void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl})}),{started:!0,cwd:s.currentDirectory}}function ct(e,n,t,r,s){const o={};for(const[i,a]of Object.entries(t))a!==void 0&&(o[i]=a);if(n&&(o.AWS_WORKSPACE_PATH=String(n)),s&&String(s).trim()&&(o.AWS_PROJECT_ROOT=String(s).trim()),r)for(const[i,a]of Object.entries(r)){const c=i.trim();if(!c||a===void 0||a===null)continue;const d=String(a).trim();d&&(o[c]=d)}return o.AWS_AGENT_ID=String(e),o.AWS_MCP_CLAIM_LAUNCH_BINDING="true",o.AWS_RUNTIME_BRIDGE_BASE_URL=`http://127.0.0.1:${bt()}`,String(o.ACODE_HOME||"").trim()||(o.ACODE_HOME=xe()),I(e,Ne)!=="disabled"&&(o.AWS_LAUNCH_CONFIG_TOOLS=I(e,Ne)),I(e,je)!=="disabled"&&(o.AWS_HIRE_TOOLS=I(e,je)),I(e,Be)!=="disabled"&&(o.AWS_PENCIL_TOOLS=I(e,Be)),I(e,ve)!=="disabled"&&(o.AWS_DRAW_TOOLS=I(e,ve)),I(e,Fe)!=="disabled"&&(o.AWS_OFFICE_TOOLS=I(e,Fe)),I(e,Ke)!=="disabled"&&(o.AWS_COLLABORATION_TASK_TOOLS=I(e,Ke)),I(e,He)!=="disabled"&&(o.AWS_COLLABORATION_MEETING_TOOLS=I(e,He)),I(e,qe)!=="disabled"&&(o.AWS_COLLABORATION_DEBUG_TOOLS=I(e,qe)),I(e,ze)!=="disabled"&&(o.AWS_COLLABORATION_FILE_HISTORY_TOOLS=I(e,ze)),I(e,We)!=="disabled"&&(o.AWS_EMAIL_TOOLS=I(e,We)),I(e,Ge)!=="disabled"&&(o.AWS_ABILITY_MARKET_TOOLS=I(e,Ge)),I(e,Ye)!=="disabled"&&(o.AWS_ABILITY_DEV_TOOLS=I(e,Ye)),o}function $n(e){const n=e.trim(),t=n[0],r=n[n.length-1];return(t==='"'||t==="'")&&t===r?n.slice(1,-1):n}async function Rn(e){const n=String(e);if(!Le(n))return n;const t=$n(n);return re.isAbsolute(t)?ne.readFile(t,"utf-8"):n}function dt(e,n){const t={};for(const s of[e?.env,n])if(s)for(const[o,i]of Object.entries(s)){const a=o.trim();if(!a||i===void 0||i===null)continue;const c=String(i).trim();c&&(t[a]=c)}const r=t.ANTHROPIC_MODEL?.trim()||t.CODEX_MODEL?.trim()||void 0;return{envOverrides:t,model:r}}async function Dn(){try{return await Et().readClaudeCodeConfig()}catch(e){return console.warn(`[Runtime] Failed to read saved ClaudeCode AI config: ${e.message}`),{}}}function Pn(e){if(e==null)return;const t=(typeof e=="string"?e:JSON.stringify(e,null,2)).trim();if(t)return t.length<=Je?t:`${t.slice(0,Je)}
|
|
33
|
+
...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function On(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 Ln(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 Mn(e){if(e.type!=="tool_use_end")return;const n=Pn(e.data.toolResult??e.data.actionResult);if(!n)return;const t=ke(e.data.toolName,e.data.toolInput),r=e.data.actionType||t.actionType;if(r==="idle"){const s=String(e.data.rawToolName||e.data.toolName||"").toLowerCase();if((s.includes("poll_message")||s.includes("get_message"))&&!On(n))return}return r==="mcp"&&Ln(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:r,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 xn(e){if(e.type==="ai_request"){const n=e.data.model?` ${e.data.model}`:"",t=e.data.lastUserMessagePreview?`\uFF1A${e.data.lastUserMessagePreview}`:"";return`\r
|
|
40
34
|
[ACode] \u6B63\u5728\u8BF7\u6C42\u6A21\u578B${n}${t}\r
|
|
41
35
|
`}if(e.type==="text_delta"||e.type==="thinking"||e.type==="command_output")return e.data.text||void 0;if(e.type==="error")return e.data.text?`\r
|
|
42
36
|
[SDK Error] ${e.data.text}\r
|
|
43
|
-
`:void 0}function
|
|
44
|
-
...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function zn(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function Wn(e,n){if(!zn(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=ke(e.data.toolName,e.data.toolInput),r=lt(e,t),s=qn(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:r||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:r||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 j=new Map,fe=new Map,me=new Map;async function $e(e){const{entry:n,sessionId:t,actionInfo:r,timestamp:s,sourceEventType:o,backoffBaseMs:i,label:a}=e,c={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl},d=3;for(let u=0;u<d;u++){if(await $(n.agentId,t,"tool_result",r,void 0,c,s,o)!==void 0)return;u<d-1&&await new Promise(p=>setTimeout(p,i*(u+1)))}l.warn(`[Runtime] ${a} tool_result sendStatus retry exhausted (result may be lost): agentId=${n.agentId}`)}const ee=new Map,Gn=20,Yn=500,Xn=3e4;async function pe(e,n=Xn,t=2){for(let r=0;r<=t;r++){const s=new AbortController;let o;try{const i=e(s.signal);i.catch(()=>{}),await Promise.race([i,new Promise((a,c)=>{o=setTimeout(()=>{s.abort(),c(new Error(`sendOutput timeout after ${n}ms`))},n)})]),o&&clearTimeout(o);return}catch(i){o&&clearTimeout(o);const a=i instanceof Error?i.message:String(i);if(r<t){const c=1e3*(r+1);l.warn(`sendOutput attempt ${r+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(d=>setTimeout(d,c));continue}l.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}function ge(e,n){const t=n?`${e}:${n}`:void 0;let r,s;if(t)r=ee.get(t),s=t;else{const g=[];for(const[k,A]of ee)k.startsWith(e+":")&&A.buffer&&g.push(A.sourceEventType);for(const k of g)ge(e,k);return}if(!r||!r.buffer)return;r.timer=null;const o=r.buffer,i=r.seq,a=r.entry,c=r.sourceEventType;r.buffer="",s&&ee.delete(s);const d={sourceEventType:c,logCategory:"acode"},u={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},p=(j.get(e)??Promise.resolve()).then(()=>pe(g=>J(a.agentId,o,e,i,d,u,g)),()=>pe(g=>J(a.agentId,o,e,i,d,u,g)));j.set(e,p),p.finally(()=>{j.get(e)===p&&j.delete(e)})}function Jn(e,n){const t=Ln(e);if(!t)return;n.seq+=1;const r=n.seq,s=jn(e),o={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<Gn){const c=`${e.sessionId}:${e.type}`;let d=ee.get(c);if(d||(d={buffer:"",seq:0,timer:null,entry:n,sourceEventType:e.type}),d.buffer+=t,d.seq=r,d.entry=n,!d.timer){const u=e.sessionId,f=e.type;d.timer=setTimeout(()=>ge(u,f),Yn)}ee.set(c,d);return}ge(e.sessionId);const a=(j.get(e.sessionId)??Promise.resolve()).then(()=>pe(c=>J(n.agentId,t,e.sessionId,r,s,o,c)),()=>pe(c=>J(n.agentId,t,e.sessionId,r,s,o,c)));j.set(e.sessionId,a),a.finally(()=>{j.get(e.sessionId)===a&&j.delete(e.sessionId)})}function mt(e){return _t(e)}let pt=!1;function Vn(){pt||(Tt(h,Qn),$t(),pt=!0)}function Qn(e,n){e.on("event",t=>{const r=m.get(t.sessionId);if(r){if(t.type==="tool_use_start"?Kt(r.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,r.workspacePath):t.type==="tool_use_end"&&Ft(t,{sessionId:r.sessionId,agentId:r.agentId,workspacePath:r.workspacePath,providerId:r.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==="ai_request"||t.type==="error")){t.type==="runtime_capabilities"&&t.data.actionDetail&&(r.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=Wn(t,r.currentRuntimeStatus);i&&$(r.agentId,t.sessionId,i.status,i.actionInfo,de(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}Jn(t,r);const o=Mn(t);if(o){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");$e(a?{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:3e3,label:"browser_launch"}:c?{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"todo_write"}:{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"tool_result"})}}}),e.on("status-change",(t,r,s)=>{const o=m.get(t);if(o){ge(t),r==="thinking"||r==="tool_using"||r==="compacting"?Qt(t):L(t);const i=un(r,s);o.currentRuntimeStatus=i.status;const a=o.currentRuntimeActionDetail??"",c=a.includes("poll_message")||a.includes("get_message"),u=!(i.actionInfo?.actionType==="ai_request")&&(i.status==="thinking"||i.status==="waiting_input")&&(o.currentRuntimeActionType==="idle"||o.currentRuntimeActionType==="mcp")&&c;(i.actionInfo?.actionType||!u)&&(o.currentRuntimeActionType=i.actionInfo?.actionType,o.currentRuntimeActionLabel=i.actionInfo?.actionLabel,o.currentRuntimeActionDetail=i.actionInfo?.actionDetail,o.currentRuntimeActionInput=i.actionInfo?.actionInput),l.info(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${o.agentId}`,i.actionInfo||""),Yt(t,{runtimeStatus:i.status,runtimeActionType:o.currentRuntimeActionType,runtimeActionLabel:o.currentRuntimeActionLabel,runtimeActionDetail:o.currentRuntimeActionDetail});const f=i.actionInfo?.actionType?i.actionInfo:o.currentRuntimeActionType?{actionType:o.currentRuntimeActionType,actionLabel:o.currentRuntimeActionLabel??"",actionDetail:o.currentRuntimeActionDetail,actionInput:o.currentRuntimeActionInput}:void 0;if(i.status==="compacting"){const g=(fe.get(t)??Promise.resolve()).then(async()=>{for(let A=0;A<=2;A++){if(await $(o.agentId,t,i.status,f,de(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;A<2&&(l.warn(`[${n.displayName}] compaction sendStatus attempt ${A+1} failed (HTTP), retrying in ${1e3*(A+1)}ms...`),await new Promise(w=>setTimeout(w,1e3*(A+1))))}l.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(k=>{l.warn(`[${n.displayName}] compaction status chain error:`,k)});fe.set(t,g),g.finally(()=>{fe.get(t)===g&&fe.delete(t)})}else{const p=u&&!i.actionInfo?.actionType;if(ln({status:i.status,actionInfo:i.actionInfo,restoredActionInfo:f,currentRuntimeActionType:o.currentRuntimeActionType,shouldPreservePrevAction:u})){const A=(me.get(t)??Promise.resolve()).then(async()=>{for(let w=0;w<=2;w++){if(await $(o.agentId,t,i.status,p?void 0:f,de(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;w<2&&await new Promise(D=>setTimeout(D,1e3*(w+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(T=>{l.warn(`[${n.displayName}] idle status chain error:`,T)});me.set(t,A),A.finally(()=>{me.get(t)===A&&me.delete(t)})}else $(o.agentId,t,i.status,p?void 0:f,de(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}if(i.status==="waiting_input"&&o.cachedCapabilitiesActionDetail){const p=o.cachedCapabilitiesActionDetail;o.cachedCapabilitiesActionDetail=void 0,l.info(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${o.agentId} (session stabilized to waiting_input)`),$(o.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:p},void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const r=m.get(t.sessionId);r&&(l.info(`[${n.displayName} Adapter] AskUserQuestion for agent ${r.agentId}`),Ht(r.agentId,t.sessionId,Array.isArray(t.questions)?t.questions:[],{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.toolCallId))}),e.on("tool-permission-request",t=>{const r=m.get(t.sessionId);r&&t.requestId&&(l.info(`[${n.displayName} Adapter] Tool permission request (${t.capability}) for agent ${r.agentId}`),qt(r.agentId,t.sessionId,{requestId:t.requestId,capability:t.capability,...t.detail||{}},{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}))}),e.on("permission-request",t=>{const r=m.get(t.sessionId);if(r){l.info(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${r.agentId}`);const s=t.toolInput?K(JSON.stringify(t.toolInput).slice(0,400)):void 0;$(r.agentId,t.sessionId,"waiting_input",{actionType:"other",actionLabel:"\u6743\u9650\u786E\u8BA4",actionDetail:s||t.toolName},void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}})}I.post("/start",y,async(e,n)=>{const{agentId:t,workspacePath:r,mode:s="sdk"}=e.body||{};if(!t||!r){n.status(400).json({error:"agentId and workspacePath are required"});return}const o=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ue(Je(e))||void 0;Ut({agentId:String(t),workspacePath:String(r),serverUrl:e.body?.serverUrl||o,runtimeAccessToken:e.body?.runtimeAccessToken,userId:e.body?.userId,schedulerBaseUrl:o}),e.body?.runtimeFeatures!==null&&e.body?.runtimeFeatures!==void 0&&(Dt(String(t),e.body.runtimeFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(Lt(String(t)))}`)),e.body?.inheritedFeatures!==null&&e.body?.inheritedFeatures!==void 0&&(Ot(String(t),e.body.inheritedFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u7EE7\u627F\u4E09\u6001\u5C42: ${JSON.stringify(jt(String(t)))}`)),e.body?.capabilities!==void 0&&Pt(String(t),e.body.capabilities),e.body?.capabilitiesInherited!==void 0&&Mt(String(t),e.body.capabilitiesInherited),e.body?.envVars!==null&&e.body?.envVars!==void 0&&typeof e.body.envVars=="object"&&(xt(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&&(Nt(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&&(wt(e.body.changeCacheRetentionDays),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),s&&s!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${s}" requested for agent ${t}; starting SDK session instead.`),await Zn(e,n)});async function Zn(e,n){const{agentId:t,workspacePath:r,command:s,projectRoot:o,autoAccept:i=!0,initialPrompt:a,systemPrompt:c,globalPrompt:d,rolePrompt:u,memory:f,resumeContext:p,resumeTranscript:g,mcpConfigPath:k,extraMcpServers:A,envOverrides:T,idleInputAutoCommand:w,nonInputAutoCommand:R,model:D,instanceAiConfig:ye,subAgentModel:Se,subAgentEffort:Ie,scopeKey:Re,browserAllowPrivate:De}=e.body||{},W=rn(g);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 g=="string"?`${g.length}\u5B57`:typeof g} \u89E3\u6790\u7ED3\u679C=${W?`${W.length}\u6761`:"null"}`);const G=Jt();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:ye?ie(ye):null,perAgentModel:D??null}});let E=null;const _=String(t||"").trim(),he=String(e.body?.runtimeAccessToken||"").trim()||void 0,B=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ue(Je(e))||void 0;B?l.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${B} (agentId=${_})`):l.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${_})`);try{if(Vn(),!_){n.status(400).json({error:"agentId is required"});return}const v=at(_);if(v){n.json(await _n(v));return}const b=await zt(_);if(b){const O=await bn(b);if(!O.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${_}, sessionId=${b.sessionId}, reason=${O.reason}`),await q(b.sessionId);else{const M=Z(b.runtimeStatus,b.runtimeStatus,b.runtimeActionType);n.json({sessionId:b.sessionId,status:M,runtimeStatus:M,runtimeActionType:b.runtimeActionType,runtimeActionLabel:b.runtimeActionLabel,runtimeActionDetail:b.runtimeActionDetail,agentId:b.agentId,workspacePath:b.workspacePath,command:b.command,mode:b.mode||"sdk",pid:b.pid,reused:!0,persistedOnly:!0});return}}if(z.has(_)){n.status(409).json({error:"SDK session is already starting for this agent"});return}z.add(_);const P=mt(s),gt=h.get(P);E=At();const yt=P==="claude-code"?await Rn():null,te=dt(P==="claude-code"?yt:null,T),Y=P==="acode"?D?String(D).trim():void 0:(()=>{const O=D?String(D).trim():void 0,M=te.model?String(te.model).trim():void 0;return O||M})();G.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:_,sessionId:E??void 0,details:{perAgentModel:D??null,globalModel:te.model??null,resolvedModel:Y??null,providerId:P,note:P==="acode"?"adapter handles full priority":"request > global"}});const Ae={...te.envOverrides};Y&&(Ae.ANTHROPIC_MODEL=Y,Ae.CODEX_MODEL=Y);let X,Te=k;if(P==="acode"){const O=ye||{},M=await Rt({apiOverrides:tt(O)??void 0,agentId:_,sessionId:E??void 0,runtimeBridgeBaseUrl:B});X=M.instanceConfig.config,Te=M.perInstanceConfigPath,G.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:_,sessionId:E??void 0,details:{sanitizedApiOverrides:(()=>{const x=tt(O);return x?ie(x):null})(),resolvedInstanceAiConfig:X?ie(X):null,perInstanceConfigPath:Te,instanceConfigSources:M.instanceConfig.source??null}})}let Pe=c||void 0,_e,be,ne;const re=typeof p=="string"&&p.trim()?kt(p):void 0;if(P==="acode")if(_e=typeof d=="string"&&d.trim()||void 0,be=typeof u=="string"&&u.trim()||void 0,typeof f=="string"&&f.trim())ne=f.trim();else{const O=await sn(r,{schedulerBaseUrl:B,runtimeAccessToken:he,agentId:_});O&&(ne=O,l.info(`[startSdkSession] Auto-loaded memories for ACode agent ${_}`))}else if(typeof d=="string"&&d.trim()||typeof u=="string"&&u.trim()||typeof f=="string"&&f.trim()||re!==void 0){const M=[d,u,f,re,c].filter(x=>typeof x=="string"&&x.trim().length>0).map(x=>x.trim());Pe=M.length>0?M.join(`
|
|
37
|
+
`:void 0}function Un(e){const n=Bn(e);return{sourceEventType:e.type,logCategory:"acode",...jn(e),...n?{logLevel:Nn(e),logMessage:n}:{}}}function Nn(e){return e.type==="error"?"error":e.type==="command_output"&&e.data.stream==="stderr"?"warn":"info"}function jn(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 Bn(e){if(e.type==="ai_request"){const n=e.data.model||"unknown-model",t=e.data.endpoint?` @ ${e.data.endpoint}`:"",r=typeof e.data.toolCount=="number"?`, tools=${e.data.toolCount}`:"";return`AI request started: ${n}${t}${r}`}if(e.type==="tool_use_start")return ut(e,"\u5F00\u59CB");if(e.type==="tool_use_end")return ut(e,"\u5B8C\u6210");if(e.type==="command_output")return Kn(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 vn=/\x1b\[[0-9;?]*[a-zA-Z]/g;function Fn(e){return e.replace(vn,"")}function Kn(e){const n=typeof e.data.stream=="string"?e.data.stream:"mixed",t=typeof e.data.sequence=="number"?` #${e.data.sequence}`:"",r=Fn(String(e.data.text||"")).replace(/\s+/g," ").trim(),s=r.length>240?`${r.slice(0,240)}...`:r;return`\u547D\u4EE4\u8F93\u51FA(${n}${t}): ${s||"(empty)"}`}function ut(e,n){const t=ke(e.data.toolName,e.data.toolInput),r=e.data.actionLabel||t.actionLabel||"\u8C03\u7528\u5DE5\u5177",s=lt(e,t);return s?`${n}${r}: ${s}`:`${n}${r}: ${e.data.actionDetail||e.data.toolName||"tool"}`}function lt(e,n){const t=e.data.toolInput;return n.actionType==="bash"?Hn(t)||e.data.actionDetail||n.actionDetail:n.actionType==="read_file"||n.actionType==="edit_file"||n.actionType==="write_file"?qn(t)||e.data.actionDetail||n.actionDetail:e.data.actionDetail||n.actionDetail}function Hn(e){const n=we(e?.command,e?.cmd);if(n)return n;if(Array.isArray(e?.argv)){const t=e.argv.map(r=>String(r??"").trim()).filter(Boolean).join(" ");return t?v(t):void 0}return we(e?.args)}function qn(e){const n=ft(e?.paths);return n.length>0?n.length===1?n[0]:`${n.length}\u4E2A\u6587\u4EF6: ${n.join(", ")}`:we(e?.file_path,e?.filePath,e?.path,e?.target_file,e?.targetFile)}function we(...e){for(const n of e){if(typeof n=="string"&&n.trim())return v(n.trim());if(Array.isArray(n)){const t=ft(n)[0];if(t)return t}}}function ft(e){return Array.isArray(e)?e.map(n=>typeof n=="string"?n.trim():"").filter(Boolean).map(n=>v(n)):[]}function zn(e){if(!(!e||Object.keys(e).length===0))try{const n=v(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 Wn(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function Gn(e,n){if(!Wn(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=ke(e.data.toolName,e.data.toolInput),r=lt(e,t),s=zn(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:r||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:r||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 x=new Map,fe=new Map,pe=new Map;async function $e(e){const{entry:n,sessionId:t,actionInfo:r,timestamp:s,sourceEventType:o,backoffBaseMs:i,label:a}=e,c={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl},d=3;for(let u=0;u<d;u++){if(await $(n.agentId,t,"tool_result",r,void 0,c,s,o)!==void 0)return;u<d-1&&await new Promise(m=>setTimeout(m,i*(u+1)))}l.warn(`[Runtime] ${a} tool_result sendStatus retry exhausted (result may be lost): agentId=${n.agentId}`)}const Q=new Map,Yn=20,Xn=500,Vn=3e4;async function me(e,n=Vn,t=2){for(let r=0;r<=t;r++){const s=new AbortController;let o;try{const i=e(s.signal);i.catch(()=>{}),await Promise.race([i,new Promise((a,c)=>{o=setTimeout(()=>{s.abort(),c(new Error(`sendOutput timeout after ${n}ms`))},n)})]),o&&clearTimeout(o);return}catch(i){o&&clearTimeout(o);const a=i instanceof Error?i.message:String(i);if(r<t){const c=1e3*(r+1);l.warn(`sendOutput attempt ${r+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(d=>setTimeout(d,c));continue}l.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}function ge(e,n){const t=n?`${e}:${n}`:void 0;let r,s;if(t)r=Q.get(t),s=t;else{const g=[];for(const[k,A]of Q)k.startsWith(e+":")&&A.buffer&&g.push(A.sourceEventType);for(const k of g)ge(e,k);return}if(!r||!r.buffer)return;r.timer=null;const o=r.buffer,i=r.seq,a=r.entry,c=r.sourceEventType;r.buffer="",s&&Q.delete(s);const d={sourceEventType:c,logCategory:"acode"},u={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},m=(x.get(e)??Promise.resolve()).then(()=>me(g=>Y(a.agentId,o,e,i,d,u,g)),()=>me(g=>Y(a.agentId,o,e,i,d,u,g)));x.set(e,m),m.finally(()=>{x.get(e)===m&&x.delete(e)})}function Jn(e,n){const t=xn(e);if(!t)return;n.seq+=1;const r=n.seq,s=Un(e),o={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<Yn){const c=`${e.sessionId}:${e.type}`;let d=Q.get(c);if(d||(d={buffer:"",seq:0,timer:null,entry:n,sourceEventType:e.type}),d.buffer+=t,d.seq=r,d.entry=n,!d.timer){const u=e.sessionId,p=e.type;d.timer=setTimeout(()=>ge(u,p),Xn)}Q.set(c,d);return}ge(e.sessionId);const a=(x.get(e.sessionId)??Promise.resolve()).then(()=>me(c=>Y(n.agentId,t,e.sessionId,r,s,o,c)),()=>me(c=>Y(n.agentId,t,e.sessionId,r,s,o,c)));x.set(e.sessionId,a),a.finally(()=>{x.get(e.sessionId)===a&&x.delete(e.sessionId)})}function pt(e){return _t(e)}let mt=!1;function Qn(){mt||(Tt(h,Zn),Rt(),mt=!0)}function Zn(e,n){e.on("event",t=>{const r=f.get(t.sessionId);if(r){if(t.type==="tool_use_start"?qt(r.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,r.workspacePath):t.type==="tool_use_end"&&Ht(t,{sessionId:r.sessionId,agentId:r.agentId,workspacePath:r.workspacePath,providerId:r.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==="ai_request"||t.type==="error")){t.type==="runtime_capabilities"&&t.data.actionDetail&&(r.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=Gn(t,r.currentRuntimeStatus);i&&$(r.agentId,t.sessionId,i.status,i.actionInfo,de(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}Jn(t,r);const o=Mn(t);if(o){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");$e(a?{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:3e3,label:"browser_launch"}:c?{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"todo_write"}:{entry:r,sessionId:t.sessionId,actionInfo:o,timestamp:i,sourceEventType:t.type,backoffBaseMs:1e3,label:"tool_result"})}}}),e.on("status-change",(t,r,s)=>{const o=f.get(t);if(o){ge(t),r==="thinking"||r==="tool_using"||r==="compacting"?en(t):M(t);const i=ln(r,s);o.currentRuntimeStatus=i.status;const a=o.currentRuntimeActionDetail??"",c=a.includes("poll_message")||a.includes("get_message"),u=!(i.actionInfo?.actionType==="ai_request")&&(i.status==="thinking"||i.status==="waiting_input")&&(o.currentRuntimeActionType==="idle"||o.currentRuntimeActionType==="mcp")&&c;(i.actionInfo?.actionType||!u)&&(o.currentRuntimeActionType=i.actionInfo?.actionType,o.currentRuntimeActionLabel=i.actionInfo?.actionLabel,o.currentRuntimeActionDetail=i.actionInfo?.actionDetail,o.currentRuntimeActionInput=i.actionInfo?.actionInput),l.info(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${o.agentId}`,i.actionInfo||""),Vt(t,{runtimeStatus:i.status,runtimeActionType:o.currentRuntimeActionType,runtimeActionLabel:o.currentRuntimeActionLabel,runtimeActionDetail:o.currentRuntimeActionDetail});const p=i.actionInfo?.actionType?i.actionInfo:o.currentRuntimeActionType?{actionType:o.currentRuntimeActionType,actionLabel:o.currentRuntimeActionLabel??"",actionDetail:o.currentRuntimeActionDetail,actionInput:o.currentRuntimeActionInput}:void 0;if(i.status==="compacting"){const g=(fe.get(t)??Promise.resolve()).then(async()=>{for(let A=0;A<=2;A++){if(await $(o.agentId,t,i.status,p,de(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;A<2&&(l.warn(`[${n.displayName}] compaction sendStatus attempt ${A+1} failed (HTTP), retrying in ${1e3*(A+1)}ms...`),await new Promise(E=>setTimeout(E,1e3*(A+1))))}l.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(k=>{l.warn(`[${n.displayName}] compaction status chain error:`,k)});fe.set(t,g),g.finally(()=>{fe.get(t)===g&&fe.delete(t)})}else{const m=u&&!i.actionInfo?.actionType;if(fn({status:i.status,actionInfo:i.actionInfo,restoredActionInfo:p,currentRuntimeActionType:o.currentRuntimeActionType,shouldPreservePrevAction:u})){const A=(pe.get(t)??Promise.resolve()).then(async()=>{for(let E=0;E<=2;E++){if(await $(o.agentId,t,i.status,m?void 0:p,de(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})!==void 0)return;E<2&&await new Promise(D=>setTimeout(D,1e3*(E+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(T=>{l.warn(`[${n.displayName}] idle status chain error:`,T)});pe.set(t,A),A.finally(()=>{pe.get(t)===A&&pe.delete(t)})}else $(o.agentId,t,i.status,m?void 0:p,de(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}if(i.status==="waiting_input"&&o.cachedCapabilitiesActionDetail){const m=o.cachedCapabilitiesActionDetail;o.cachedCapabilitiesActionDetail=void 0,l.info(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${o.agentId} (session stabilized to waiting_input)`),$(o.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:m},void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const r=f.get(t.sessionId);r&&(l.info(`[${n.displayName} Adapter] AskUserQuestion for agent ${r.agentId}`),zt(r.agentId,t.sessionId,Array.isArray(t.questions)?t.questions:[],{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.toolCallId))}),e.on("tool-permission-request",t=>{const r=f.get(t.sessionId);r&&t.requestId&&(l.info(`[${n.displayName} Adapter] Tool permission request (${t.capability}) for agent ${r.agentId}`),Wt(r.agentId,t.sessionId,{requestId:t.requestId,capability:t.capability,...t.detail||{}},{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}))}),e.on("permission-request",t=>{const r=f.get(t.sessionId);if(r){l.info(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${r.agentId}`);const s=t.toolInput?v(JSON.stringify(t.toolInput).slice(0,400)):void 0;$(r.agentId,t.sessionId,"waiting_input",{actionType:"other",actionLabel:"\u6743\u9650\u786E\u8BA4",actionDetail:s||t.toolName},void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}})}S.post("/start",y,async(e,n)=>{const{agentId:t,workspacePath:r,mode:s="sdk"}=e.body||{};if(!t||!r){n.status(400).json({error:"agentId and workspacePath are required"});return}const o=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ue(Ve(e))||void 0;if(jt({agentId:String(t),workspacePath:String(r),serverUrl:e.body?.serverUrl||o,runtimeAccessToken:e.body?.runtimeAccessToken,userId:e.body?.userId,schedulerBaseUrl:o}),e.body?.runtimeFeatures!==null&&e.body?.runtimeFeatures!==void 0&&(Ot(String(t),e.body.runtimeFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(Ut(String(t)))}`)),e.body?.inheritedFeatures!==null&&e.body?.inheritedFeatures!==void 0&&(Mt(String(t),e.body.inheritedFeatures),l.info(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u7EE7\u627F\u4E09\u6001\u5C42: ${JSON.stringify(Nt(String(t)))}`)),e.body?.capabilities!==void 0&&Lt(String(t),e.body.capabilities),e.body?.capabilitiesInherited!==void 0&&xt(String(t),e.body.capabilitiesInherited),e.body?.envVars!==null&&e.body?.envVars!==void 0&&typeof e.body.envVars=="object"&&(Bt(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&&(vt(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&&(wt(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?.logRetentionDays!==void 0){const i=Math.min(Number(e.body.logRetentionDays)||0,7);i>0&&(Pt(i),l.info(`[Runtime] agent ${t} \u4E0B\u53D1\u65E5\u5FD7\u4FDD\u7559\u5929\u6570: ${i}`))}s&&s!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${s}" requested for agent ${t}; starting SDK session instead.`),await er(e,n)});async function er(e,n){const{agentId:t,workspacePath:r,command:s,projectRoot:o,autoAccept:i=!0,initialPrompt:a,systemPrompt:c,globalPrompt:d,rolePrompt:u,memory:p,resumeContext:m,resumeTranscript:g,mcpConfigPath:k,extraMcpServers:A,envOverrides:T,idleInputAutoCommand:E,nonInputAutoCommand:R,model:D,instanceAiConfig:ye,subAgentModel:Ie,subAgentEffort:Se,scopeKey:Re,browserAllowPrivate:De}=e.body||{},q=sn(g);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=${q?`${q.length}\u6761`:"null"}`);const z=Qt();z.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:ye?ie(ye):null,perAgentModel:D??null}});let w=null;const _=String(t||"").trim(),he=String(e.body?.runtimeAccessToken||"").trim()||void 0,j=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||Ue(Ve(e))||void 0;j?l.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${j} (agentId=${_})`):l.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${_})`);try{if(Qn(),!_){n.status(400).json({error:"agentId is required"});return}const B=at(_);if(B){n.json(await bn(B));return}const b=await Gt(_);if(b){const O=await kn(b);if(!O.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${_}, sessionId=${b.sessionId}, reason=${O.reason}`),await K(b.sessionId);else{const L=J(b.runtimeStatus,b.runtimeStatus,b.runtimeActionType);n.json({sessionId:b.sessionId,status:L,runtimeStatus:L,runtimeActionType:b.runtimeActionType,runtimeActionLabel:b.runtimeActionLabel,runtimeActionDetail:b.runtimeActionDetail,agentId:b.agentId,workspacePath:b.workspacePath,command:b.command,mode:b.mode||"sdk",pid:b.pid,reused:!0,persistedOnly:!0});return}}if(H.has(_)){n.status(409).json({error:"SDK session is already starting for this agent"});return}H.add(_);const P=pt(s),gt=h.get(P);w=At();const yt=P==="claude-code"?await Dn():null,Z=dt(P==="claude-code"?yt:null,T),W=P==="acode"?D?String(D).trim():void 0:(()=>{const O=D?String(D).trim():void 0,L=Z.model?String(Z.model).trim():void 0;return O||L})();z.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:_,sessionId:w??void 0,details:{perAgentModel:D??null,globalModel:Z.model??null,resolvedModel:W??null,providerId:P,note:P==="acode"?"adapter handles full priority":"request > global"}});const Ae={...Z.envOverrides};W&&(Ae.ANTHROPIC_MODEL=W,Ae.CODEX_MODEL=W);let G,Te=k;if(P==="acode"){const O=ye||{},L=await Dt({apiOverrides:tt(O)??void 0,agentId:_,sessionId:w??void 0,runtimeBridgeBaseUrl:j});G=L.instanceConfig.config,Te=L.perInstanceConfigPath,z.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:_,sessionId:w??void 0,details:{sanitizedApiOverrides:(()=>{const N=tt(O);return N?ie(N):null})(),resolvedInstanceAiConfig:G?ie(G):null,perInstanceConfigPath:Te,instanceConfigSources:L.instanceConfig.source??null}})}let Pe=c||void 0,_e,be,ee;const te=typeof m=="string"&&m.trim()?kt(m):void 0;if(P==="acode")if(_e=typeof d=="string"&&d.trim()||void 0,be=typeof u=="string"&&u.trim()||void 0,typeof p=="string"&&p.trim())ee=p.trim();else{const O=await Ct(r,{schedulerBaseUrl:j,runtimeAccessToken:he,agentId:_});O&&(ee=O,l.info(`[startSdkSession] Auto-loaded memories for ACode agent ${_}`))}else if(typeof d=="string"&&d.trim()||typeof u=="string"&&u.trim()||typeof p=="string"&&p.trim()||te!==void 0){const L=[d,u,p,te,c].filter(N=>typeof N=="string"&&N.trim().length>0).map(N=>N.trim());Pe=L.length>0?L.join(`
|
|
45
39
|
|
|
46
|
-
`):void 0}const U={command:s||"acode",workingDirectory:r,agentId:_,...Re?{scopeKey:Re}:{},...typeof De=="boolean"?{browserAllowPrivate:De}:{},autoAccept:!!i,initialPrompt:a,systemPrompt:Pe,..._e!==void 0?{globalPrompt:_e}:{},...be!==void 0?{rolePrompt:be}:{},...ne!==void 0?{memory:ne}:{},...re!==void 0?{resumeContext:re}:{},...P==="acode"&&Array.isArray(W)&&W.length>0?{resumeTranscript:W}:{},model:Y,mcpConfigPath:Te,...X?{instanceAiConfig:X}:{},...typeof Se=="string"&&Se.trim()?{subAgentModel:Se.trim()}:{},...typeof Ie=="string"&&Ie.trim()?{subAgentEffort:Ie.trim()}:{},extraMcpServers:A||{},envOverrides:ct(String(t),String(r),process.env,Ae,typeof o=="string"?o:void 0)};G.log({level:"info",category:"launch",message:"\u4F20\u9012\u7ED9 Adapter \u7684\u5B8C\u6574 AdapterSessionConfig",source:"bridge",agentId:_,sessionId:E,details:{adapterModel:U.model??null,adapterInstanceAiConfig:U.instanceAiConfig?ie(U.instanceAiConfig):null,adapterMcpConfigPath:U.mcpConfigPath??null}}),await G.flush(),m.set(E,{agentId:_,workspacePath:r,sessionId:E,config:U,providerId:P,seq:0,runtimeAccessToken:he,schedulerBaseUrl:B}),n.json({sessionId:E,status:"starting",runtimeStatus:"starting",agentId:_,workspacePath:r,command:U.command,mode:"sdk"}),er({sessionId:E,agentId:_,config:U,adapter:gt,providerId:P,idleInputAutoCommand:w,nonInputAutoCommand:R,runtimeAccessToken:he,requestedSchedulerBaseUrl:B})}catch(v){if(E&&(L(E),m.delete(E),H(E)),_&&z.delete(_),!n.headersSent){const b=v instanceof Error?v.message:String(v);n.status(500).json({error:`Failed to start SDK session: ${b}`})}}}async function er(e){const{sessionId:n,agentId:t,config:r,adapter:s,providerId:o,idleInputAutoCommand:i,nonInputAutoCommand:a,runtimeAccessToken:c,requestedSchedulerBaseUrl:d}=e;try{await s.startSession(n,r),s.setIdleCommands?.(n,{idleInputCommand:i||Le,nonInputCommand:a||""});let u;if(cn(o))try{if(await new Promise(p=>setTimeout(p,500)),u=s.getSessionPid?.(n),!u){const g=(await Bt()).find(k=>k.agentId===t||k.cwd===r.workingDirectory||k.command.includes(r.workingDirectory));g&&(u=g.pid,l.info(`[Runtime] Found SDK process PID: ${u} for agentId=${t}`))}}catch(p){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,p)}const f=Z(s.getSessionStatus(n),m.get(n)?.currentRuntimeStatus,m.get(n)?.currentRuntimeActionType);await Xt({sessionId:n,agentId:t,workspacePath:r.workingDirectory,command:r.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:f,mode:"sdk",pid:u,providerSessionId:s.getProviderSessionId(n)}),u&&await Ce().startProcess({agentId:t,sessionId:n,pid:u,mode:"sdk",workspacePath:r.workingDirectory,command:r.command}),await tr({agentId:t,sessionId:n,sdkPid:u,status:f,schedulerBaseUrl:d,runtimeAccessToken:c})}catch(u){L(n),m.delete(n),H(n),await q(n);const f=u instanceof Error?u.message:String(u);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${f}`),await nr({agentId:t,sessionId:n,schedulerBaseUrl:d,runtimeAccessToken:c,errorMessage:f})}finally{z.delete(t)}}async function tr(e){const{agentId:n,sessionId:t,sdkPid:r,status:s,schedulerBaseUrl:o,runtimeAccessToken:i}=e;if(!o||!i){l.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${o.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Oe.post(a,{agentId:n,sessionId:t,status:s,pid:r},{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 d=c instanceof Error?c.message:String(c);l.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${d}`)}}async function nr(e){const{agentId:n,sessionId:t,schedulerBaseUrl:r,runtimeAccessToken:s}=e;if(!r||!s)return;const o=`${r.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Oe.post(o,{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}`)}}I.post("/sdk/message",y,async(e,n)=>{const{sessionId:t,message:r}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and message are required"});return}const s=m.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code";await h.get(o).sendMessage(t,r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),I.post("/sdk/answer",y,async(e,n)=>{const{sessionId:t,answers:r}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and answers are required"});return}const s=m.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code",i=h.get(o);i.sendQuestionAnswer&&await i.sendQuestionAnswer(t,r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),I.post("/tool-auth/answer",y,async(e,n)=>{const{sessionId:t,requestId:r,allowed:s}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and requestId are required"});return}const o=m.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const i=o.providerId||"claude-code",a=h.get(i);if(!a.submitToolPermissionDecision){n.status(400).json({error:"adapter does not support tool authorization"});return}const c=a.submitToolPermissionDecision(t,String(r),!!s);n.json({ok:!0,existed:c})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),I.get("/tool-auth/pending/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=m.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=h.get(s).getPendingToolAuthRequests?.(t)??[];n.json({ok:!0,sessionId:t,agentId:r.agentId,pendingRequests:i,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),I.post("/sdk/confirm",y,async(e,n)=>{const{sessionId:t,accept:r}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const s=m.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code";await h.get(o).sendConfirmation(t,!!r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),I.post("/sdk/abort",y,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=m.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code";await h.get(s).abortCurrentTurn(t),n.json({ok:!0})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),I.post("/sdk/stop",y,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=m.get(t);if(!r){n.json({ok:!0,status:"stopped"});return}try{const s=r.providerId||"claude-code",o=h.get(s);o.abortCurrentTurn(t).catch(()=>{}),await o.terminateSession(t),L(t),m.delete(t),H(t),le(t),se(r.agentId),await q(t),await Ce().removeProcess(r.agentId),await $(r.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}),n.json({ok:!0,status:"stopped"})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),I.get("/sdk/snapshot/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=m.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=h.get(s),i=o.getConversation(t),a=tn(i);let c=null;if(s==="acode"){const u=o;typeof u.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=u.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 d=o.getTotalUsage?.(t);l.info(`[HIBERNATE-EXPORT] \u5FEB\u7167\u5BFC\u51FA: sessionId=${t} agentId=${r.agentId} providerId=${s} messages=${i.length} summaryChars=${a.snapshot.length} truncated=${a.truncated} transcript=${c?`${c.length}\u6761`:"null"} usage=${d?`in=${d.inputTokens??"?"}/out=${d.outputTokens??"?"}`:"null"}`),n.json({sessionId:t,agentId:r.agentId,workspacePath:r.workspacePath,messageCount:i.length,truncated:a.truncated,snapshot:a.snapshot,transcript:c,tokenUsage:d?{inputTokens:d.inputTokens??null,outputTokens:d.outputTokens??null}:null,providerId:s})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),I.get("/sdk/status/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=m.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=h.get(s),i=o.getSessionStatus(t),a=o.getConversation(t);n.json({sessionId:t,status:i,agentId:r.agentId,workspacePath:r.workspacePath,messageCount:a.length})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),I.get("/sdk/capabilities/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=m.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=h.get(s).getCapabilities?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,capabilities:i,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),I.get("/sdk/pending-questions/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=m.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=h.get(s).getPendingQuestion?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,pendingQuestion:i?{toolCallId:i.toolCallId,questions:i.questions}:null,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),I.post("/command",y,async(e,n)=>{const{sessionId:t,command:r}=e.body||{};if(!t||r===void 0||r===null){n.status(400).json({error:"sessionId and command are required"});return}try{const s=await wn(String(t),r);n.json({ok:!0,mode:"terminal",...s})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}});function rr(e,n){if(typeof e!="string"||!e||!n||typeof n!="object")return e;const{userId:t,name:r,type:s}=n,o=typeof t=="string"&&t.trim()?t.trim():"",i=typeof r=="string"&&r.trim()?r.trim():o;if(!o&&!i)return e;const a=typeof s=="string"&&s.trim()?s.trim().toUpperCase():"HUMAN",c=i||o,d=o?`, userId: ${o}`:"";return`\u3010${c}\uFF08${a}${d}\uFF09\u53D1\u6765\u3011
|
|
47
|
-
${e}`}
|
|
40
|
+
`):void 0}const U={command:s||"acode",workingDirectory:r,agentId:_,...Re?{scopeKey:Re}:{},...typeof De=="boolean"?{browserAllowPrivate:De}:{},autoAccept:!!i,initialPrompt:a,systemPrompt:Pe,..._e!==void 0?{globalPrompt:_e}:{},...be!==void 0?{rolePrompt:be}:{},...ee!==void 0?{memory:ee}:{},...te!==void 0?{resumeContext:te}:{},...P==="acode"&&Array.isArray(q)&&q.length>0?{resumeTranscript:q}:{},model:W,mcpConfigPath:Te,...G?{instanceAiConfig:G}:{},...typeof Ie=="string"&&Ie.trim()?{subAgentModel:Ie.trim()}:{},...typeof Se=="string"&&Se.trim()?{subAgentEffort:Se.trim()}:{},extraMcpServers:A||{},envOverrides:ct(String(t),String(r),process.env,Ae,typeof o=="string"?o:void 0)};z.log({level:"info",category:"launch",message:"\u4F20\u9012\u7ED9 Adapter \u7684\u5B8C\u6574 AdapterSessionConfig",source:"bridge",agentId:_,sessionId:w,details:{adapterModel:U.model??null,adapterInstanceAiConfig:U.instanceAiConfig?ie(U.instanceAiConfig):null,adapterMcpConfigPath:U.mcpConfigPath??null}}),await z.flush(),f.set(w,{agentId:_,workspacePath:r,sessionId:w,config:U,providerId:P,seq:0,runtimeAccessToken:he,schedulerBaseUrl:j}),n.json({sessionId:w,status:"starting",runtimeStatus:"starting",agentId:_,workspacePath:r,command:U.command,mode:"sdk"}),tr({sessionId:w,agentId:_,config:U,adapter:gt,providerId:P,idleInputAutoCommand:E,nonInputAutoCommand:R,runtimeAccessToken:he,requestedSchedulerBaseUrl:j})}catch(B){if(w&&(M(w),f.delete(w),F(w)),_&&H.delete(_),!n.headersSent){const b=B instanceof Error?B.message:String(B);n.status(500).json({error:`Failed to start SDK session: ${b}`})}}}async function tr(e){const{sessionId:n,agentId:t,config:r,adapter:s,providerId:o,idleInputAutoCommand:i,nonInputAutoCommand:a,runtimeAccessToken:c,requestedSchedulerBaseUrl:d}=e;try{await s.startSession(n,r),s.setIdleCommands?.(n,{idleInputCommand:i||Me,nonInputCommand:a||""});let u;if(dn(o))try{if(await new Promise(m=>setTimeout(m,500)),u=s.getSessionPid?.(n),!u){const g=(await Ft()).find(k=>k.agentId===t||k.cwd===r.workingDirectory||k.command.includes(r.workingDirectory));g&&(u=g.pid,l.info(`[Runtime] Found SDK process PID: ${u} for agentId=${t}`))}}catch(m){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,m)}const p=J(s.getSessionStatus(n),f.get(n)?.currentRuntimeStatus,f.get(n)?.currentRuntimeActionType);await Jt({sessionId:n,agentId:t,workspacePath:r.workingDirectory,command:r.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:p,mode:"sdk",pid:u,providerSessionId:s.getProviderSessionId(n)}),u&&await Ce().startProcess({agentId:t,sessionId:n,pid:u,mode:"sdk",workspacePath:r.workingDirectory,command:r.command}),await nr({agentId:t,sessionId:n,sdkPid:u,status:p,schedulerBaseUrl:d,runtimeAccessToken:c})}catch(u){M(n),f.delete(n),F(n),await K(n);const p=u instanceof Error?u.message:String(u);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${p}`),await rr({agentId:t,sessionId:n,schedulerBaseUrl:d,runtimeAccessToken:c,errorMessage:p})}finally{H.delete(t)}}async function nr(e){const{agentId:n,sessionId:t,sdkPid:r,status:s,schedulerBaseUrl:o,runtimeAccessToken:i}=e;if(!o||!i){l.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${o.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Oe.post(a,{agentId:n,sessionId:t,status:s,pid:r},{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 d=c instanceof Error?c.message:String(c);l.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${d}`)}}async function rr(e){const{agentId:n,sessionId:t,schedulerBaseUrl:r,runtimeAccessToken:s}=e;if(!r||!s)return;const o=`${r.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Oe.post(o,{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}`)}}S.post("/sdk/message",y,async(e,n)=>{const{sessionId:t,message:r}=e.body||{};if(!t||!r){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 o=s.providerId||"claude-code";await h.get(o).sendMessage(t,r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),S.post("/sdk/answer",y,async(e,n)=>{const{sessionId:t,answers:r}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and answers are required"});return}const s=f.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const o=s.providerId||"claude-code",i=h.get(o);i.sendQuestionAnswer&&await i.sendQuestionAnswer(t,r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),S.post("/tool-auth/answer",y,async(e,n)=>{const{sessionId:t,requestId:r,allowed:s}=e.body||{};if(!t||!r){n.status(400).json({error:"sessionId and requestId are required"});return}const o=f.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const i=o.providerId||"claude-code",a=h.get(i);if(!a.submitToolPermissionDecision){n.status(400).json({error:"adapter does not support tool authorization"});return}const c=a.submitToolPermissionDecision(t,String(r),!!s);n.json({ok:!0,existed:c})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),S.get("/tool-auth/pending/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=h.get(s).getPendingToolAuthRequests?.(t)??[];n.json({ok:!0,sessionId:t,agentId:r.agentId,pendingRequests:i,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.post("/sdk/confirm",y,async(e,n)=>{const{sessionId:t,accept:r}=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 o=s.providerId||"claude-code";await h.get(o).sendConfirmation(t,!!r),n.json({ok:!0})}catch(o){const i=o instanceof Error?o.message:String(o);n.status(500).json({error:i})}}),S.post("/sdk/abort",y,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code";await h.get(s).abortCurrentTurn(t),n.json({ok:!0})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.post("/sdk/stop",y,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=f.get(t);if(!r){n.json({ok:!0,status:"stopped"});return}try{const s=r.providerId||"claude-code",o=h.get(s);o.abortCurrentTurn(t).catch(()=>{}),await o.terminateSession(t),M(t),f.delete(t),F(t),le(t),se(r.agentId),await K(t),await Ce().removeProcess(r.agentId),await $(r.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}),n.json({ok:!0,status:"stopped"})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.get("/sdk/snapshot/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=h.get(s),i=o.getConversation(t),a=rn(i);let c=null;if(s==="acode"){const u=o;typeof u.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=u.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 d=o.getTotalUsage?.(t);l.info(`[HIBERNATE-EXPORT] \u5FEB\u7167\u5BFC\u51FA: sessionId=${t} agentId=${r.agentId} providerId=${s} messages=${i.length} summaryChars=${a.snapshot.length} truncated=${a.truncated} transcript=${c?`${c.length}\u6761`:"null"} usage=${d?`in=${d.inputTokens??"?"}/out=${d.outputTokens??"?"}`:"null"}`),n.json({sessionId:t,agentId:r.agentId,workspacePath:r.workspacePath,messageCount:i.length,truncated:a.truncated,snapshot:a.snapshot,transcript:c,tokenUsage:d?{inputTokens:d.inputTokens??null,outputTokens:d.outputTokens??null}:null,providerId:s})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.get("/sdk/status/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",o=h.get(s),i=o.getSessionStatus(t),a=o.getConversation(t);n.json({sessionId:t,status:i,agentId:r.agentId,workspacePath:r.workspacePath,messageCount:a.length})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.get("/sdk/capabilities/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=h.get(s).getCapabilities?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,capabilities:i,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.get("/sdk/pending-questions/:sessionId",y,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=h.get(s).getPendingQuestion?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,pendingQuestion:i?{toolCallId:i.toolCallId,questions:i.questions}:null,fetchedAt:Date.now()})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}}),S.post("/command",y,async(e,n)=>{const{sessionId:t,command:r}=e.body||{};if(!t||r===void 0||r===null){n.status(400).json({error:"sessionId and command are required"});return}try{const s=await wn(String(t),r);n.json({ok:!0,mode:"terminal",...s})}catch(s){const o=s instanceof Error?s.message:String(s);n.status(500).json({error:o})}});function or(e,n){if(typeof e!="string"||!e||!n||typeof n!="object")return e;const{userId:t,name:r,type:s}=n,o=typeof t=="string"&&t.trim()?t.trim():"",i=typeof r=="string"&&r.trim()?r.trim():o;if(!o&&!i)return e;const a=typeof s=="string"&&s.trim()?s.trim().toUpperCase():"HUMAN",c=i||o,d=o?`, userId: ${o}`:"";return`\u3010${c}\uFF08${a}${d}\uFF09\u53D1\u6765\u3011
|
|
41
|
+
${e}`}S.post("/input",y,async(e,n)=>{const{sessionId:t,input:r,mode:s,sender:o}=e.body||{};if(!t||r===void 0||r===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=h.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(r)),n.json({ok:!0,mode:"shortcut"});return}await c.sendMessage(t,or(await Rn(r),o)),n.json({ok:!0,mode:"sdk"})}catch(a){const c=a instanceof Error?a.message:String(a);n.status(500).json({error:c})}}),S.post("/update-auto-commands",y,async(e,n)=>{const{agentId:t,idleInputAutoCommand:r="",nonInputAutoCommand:s=""}=e.body||{},o=String(t||"").trim();if(!o){n.status(400).json({error:"agentId is required"});return}const i=[...f.values()].find(c=>c.agentId===o),a={idleInputCommand:String(r||"").trim()||Me,nonInputCommand:String(s||"")};try{let c=!1;i&&(h.get(i.providerId||"claude-code").setIdleCommands?.(i.sessionId,a),c=!0);const d=await Xt(o,{idleInputAutoCommand:a.idleInputCommand,nonInputAutoCommand:a.nonInputCommand});n.json({ok:!0,mode:"sdk",sessionUpdated:c,persistedUpdated:d})}catch(c){const d=c instanceof Error?c.message:String(c);n.status(500).json({ok:!1,mode:"sdk",error:d})}}),S.post("/resize",y,(e,n)=>{const{sessionId:t,cols:r,rows:s}=e.body||{};if(!t||!r||!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(r),rows:Number(s)})}),S.post("/reset-context",y,async(e,n)=>{const{sessionId:t,reason:r}=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 o=s.providerId||"claude-code",i=h.get(o),a=i.resetContext?.bind(i),c=cn(o,!!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 d=J(i.getSessionStatus(String(t)),s.currentRuntimeStatus,s.currentRuntimeActionType);n.json({ok:!0,contextReset:!0,sessionId:t,status:d,runtimeStatus:d,agentId:s.agentId,mode:"sdk",providerId:o,reason:typeof r=="string"&&r.trim()?r.trim():void 0})}catch(d){const u=d instanceof Error?d.message:String(d);n.status(500).json({ok:!1,contextReset:!1,mode:"sdk",error:u})}}),S.post("/compact-context",y,async(e,n)=>{const{sessionId:t,plan:r}=e.body||{};if(!t){n.status(400).json({ok:!1,error:"sessionId is required"});return}const s=f.get(t);if(!s){n.status(404).json({ok:!1,error:"SDK session not found"});return}const o=s.providerId||"claude-code",i=h.get(o),a=i.compactContext?.bind(i);if(!a){n.status(400).json({ok:!1,error:`context compaction is not supported by provider: ${o}`});return}try{const c=sr(r),d=a(String(t),c??void 0),u=J(i.getSessionStatus(String(t)),s.currentRuntimeStatus,s.currentRuntimeActionType);n.json({ok:!0,requested:!0,compacted:!0,sessionId:t,agentId:s.agentId,mode:"sdk",providerId:o,plan:c??null,status:u,runtimeStatus:u,result:d??null})}catch(c){const d=c instanceof Error?c.message:String(c);l.warn(`[Runtime] compact-context failed: sessionId=${t}, error=${d}`),n.status(500).json({ok:!1,compacted:!1,mode:"sdk",error:d})}});function sr(e){if(!e||typeof e!="object")return null;const n=e,t={};return Array.isArray(n.pruneCategories)&&(t.pruneCategories=n.pruneCategories.filter(r=>typeof r=="string").filter(r=>ir.has(r))),typeof n.summarize=="boolean"&&(t.summarize=n.summarize),Object.keys(t).length>0?t:null}const ir=new Set(["fileReads","fileEdits","otherTools","commands","browser"]);S.post("/compaction-preview",y,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({ok:!1,error:"sessionId is required"});return}const r=f.get(t);if(!r){n.status(404).json({ok:!1,error:"SDK session not found"});return}const s=r.providerId||"claude-code",o=h.get(s),i=o.getCompactionPreview?.bind(o);if(!i){n.status(400).json({ok:!1,error:`compaction preview is not supported by provider: ${s}`});return}try{const a=i(String(t));n.json({ok:!0,sessionId:t,mode:"sdk",providerId:s,preview:a??null})}catch(a){const c=a instanceof Error?a.message:String(a);l.warn(`[Runtime] compaction-preview failed: sessionId=${t}, error=${c}`),n.status(500).json({ok:!1,mode:"sdk",error:c})}}),S.post("/stop",y,async(e,n)=>{const{sessionId:t}=e.body||{},r=un(e.body);if(!t){n.status(400).json({error:"sessionId is required"});return}const s=f.get(t);if(!s){await K(t),n.json({ok:!0,status:"stopped",mode:"none",statusNotified:!1,reason:r.reason});return}const o=s.agentId;try{l.info(`[Runtime] Stopping SDK session ${t}; suppressStatus=${!r.statusNotified}, reason=${r.reason||"unspecified"}`);const i=s.providerId||"claude-code",a=h.get(i);a.abortCurrentTurn(t).catch(()=>{}),await a.terminateSession(t),M(t),f.delete(t),F(t),le(t),se(o),await K(t),await Ce().removeProcess(o),r.statusNotified?await $(o,null,"stopped",void 0,void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl}):l.info(`[Runtime] Stopped status notification suppressed for SDK session ${t}; reason=${r.reason||"unspecified"}`),n.json({ok:!0,status:"stopped",mode:"sdk",statusNotified:r.statusNotified,reason:r.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})}}),S.post("/stop-all",y,async(e,n)=>{const t=[],r=[];for(const[s,o]of f.entries())try{const i=o.providerId||"claude-code",a=h.get(i);a.abortCurrentTurn(s).catch(()=>{}),await a.terminateSession(s),M(s),f.delete(s),F(s),le(s),se(o.agentId),t.push(s),await $(o.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}catch(i){const a=i instanceof Error?i.message:String(i);r.push(`SDK ${s}: ${a}`)}try{await Yt([]),l.info("[Runtime] \u5DF2\u6E05\u7A7A\u6240\u6709\u6301\u4E45\u5316\u4F1A\u8BDD")}catch(s){const o=s instanceof Error?s.message:String(s);r.push(`Persistence: ${o}`)}n.json({ok:!0,stopped:{sdk:t.length},errors:r.length>0?r:void 0})}),S.get("/events/last/:n",y,(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 r=Xe.getLastN(t);n.json({ok:!0,count:r.length,entries:r})}),S.get("/events/since/:index",y,(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 r=Xe.getSinceIndex(t);n.json({ok:!0,entries:r.entries,nextIndex:r.nextIndex,oldestIndex:r.oldestIndex,dataLoss:r.oldestIndex>t+1})}),S.get("/events/push-stats",y,(e,n)=>{const t=$t();n.json({ok:!0,count:t.length,agents:t})});export{mn as buildAcodeCommandOutputPath,dt as buildClaudeCodeLaunchConfig,ct as buildRuntimeEnv,Un as buildSdkOutputMetadata,Mn as buildToolResultTimelineActionInfo,jr as cleanupSdkSessionByAgentId,gn as countTerminalOutputLines,it as createTerminalOutputDecoder,ue as decodeTerminalOutputChunk,kn as evaluatePersistedSessionReuse,In as formatCommandInactivityTimeoutNotice,yn as formatCommandOutputSpilloverNotice,xn as formatSdkOutputEvent,Ee as formatTerminalPrompt,fn as isIdleStatusChangeRetryable,Sn as normalizeTerminalCommandInput,sn as parseResumeTranscript,un as parseRuntimeStopOptions,Tn as parseTerminalDirectoryChangeTarget,me as raceSendOutputWithRetry,rn as renderSessionSnapshot,cn as resolveRuntimeContextResetSupport,Gn as resolveRuntimeStatusFromProviderEvent,Rn as resolveSdkInputMessage,pt as resolveSdkProviderId,J as resolveSdkSessionDisplayStatus,ln as resolveStatusChangeRuntimeState,de as resolveStatusChangeUsage,hn as resolveTerminalOutputEncoding,f as sdkSessions,dn as shouldProbeSdkProcessPid,S as terminalRouter,or as withSenderSignature};
|
|
48
42
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export interface AgentStartupMemoryOptions {
|
|
4
|
+
schedulerBaseUrl?: string;
|
|
5
|
+
runtimeAccessToken?: string;
|
|
6
|
+
agentId?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export declare function loadAgentStartupMemories(workspacePath: string, options?: AgentStartupMemoryOptions): Promise<string | undefined>;
|
|
10
|
+
|
|
11
|
+
export declare function buildAgentStartupMemorySnapshot(workspacePath: string, agentId: string | undefined): () => Promise<string | null>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{promises as y}from"node:fs";import f from"node:path";import{resolveSchedulerBaseUrl as h}from"../config.js";import{getRuntimeAccessToken as d}from"./runtime-binding.js";import{createLogger as A}from"../utils/logger.js";const m=A("agent-startup-memory"),p=10;async function S(u,n){const e=[],i=f.join(u,".agentswork","memory");try{const s=(await y.readdir(i)).filter(r=>r.endsWith(".json")),t=await Promise.all(s.map(async r=>{try{const o=await y.readFile(f.join(i,r),"utf-8");return JSON.parse(o)}catch{return m.warn("[loadAgentStartupMemories] Failed to parse memory file: %s",f.join(i,r)),null}}));for(const r of t)if(r?.by_uri)for(const o of Object.values(r.by_uri)){const l=o.memory_type||"memory",g=(o.content||"").trim();g&&l==="instance_memory"&&e.push({title:o.title,content:g,uri:o.uri||""})}}catch{m.debug("[loadAgentStartupMemories] \u65E0\u6CD5\u8BFB\u53D6\u8BB0\u5FC6\u76EE\u5F55: %s",i)}if(e.length===0&&n?.schedulerBaseUrl&&n?.runtimeAccessToken&&n?.agentId){const c=`${n.schedulerBaseUrl.replace(/\/+$/,"")}/mcp/call`,s={"Content-Type":"application/json","X-Runtime-Token":n.runtimeAccessToken,Authorization:`Bearer ${n.runtimeAccessToken}`};try{const t=await fetch(c,{method:"POST",headers:s,body:JSON.stringify({tool:"list_memories",arguments:{agentId:n.agentId,memory_type:"instance_memory"}})});if(!t.ok)throw new Error(`Server returned ${t.status}`);const r=await t.json();if(Array.isArray(r))for(const o of r){const l=(o.content||"").trim();l&&e.push({title:o.title,content:l,uri:o.uri||""})}e.length>0&&m.info(`[loadAgentStartupMemories] Loaded ${e.length} instance memory(s) from server for ${n.agentId}`)}catch(t){m.warn("[loadAgentStartupMemories] \u4ECE server \u52A0\u8F7D instance_memory \u5931\u8D25: %s",t instanceof Error?t.message:String(t))}}e.sort((c,s)=>s.uri.localeCompare(c.uri));const a=[];if(e.length>0){const s=e.slice(0,p).map((t,r)=>`${t.title?`\u3010${t.title}\u3011`:`\u6761\u76EE ${r+1}`}
|
|
2
|
+
${t.content}`);a.push(`\u3010\u5B9E\u4F8B\u5373\u65F6\u8BB0\u5FC6\u3011
|
|
3
|
+
${s.join(`
|
|
4
|
+
|
|
5
|
+
`)}`),e.length>p&&a.push(`... \u53CA\u53E6\u5916 ${e.length-p} \u6761\u5B9E\u4F8B\u5373\u65F6\u8BB0\u5FC6`)}if(a.length!==0)return a.join(`
|
|
6
|
+
|
|
7
|
+
`)}function M(u,n){return async()=>{try{const{url:e}=h(),i=e?d(e)||d():d();return await S(u,{schedulerBaseUrl:e,runtimeAccessToken:i,agentId:n})??null}catch(e){return m.warn(`buildAgentStartupMemorySnapshot failed (memory refresh skipped): agentId=${n??"?"}, error=${e?.message}`),null}}}export{M as buildAgentStartupMemorySnapshot,S as loadAgentStartupMemories};
|
|
8
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export declare const DEFAULT_LOG_RETENTION_DAYS = 7;
|
|
4
|
+
|
|
5
|
+
export declare function normalizeLogRetentionDays(value: unknown): number;
|
|
6
|
+
|
|
7
|
+
export declare function setLogRetentionDays(value: unknown): number;
|
|
8
|
+
|
|
9
|
+
export declare function getLogRetentionDays(): number;
|
|
10
|
+
|
|
11
|
+
export declare function resetLogRetentionDaysForTest(): void;
|
|
12
|
+
|
|
13
|
+
export declare function stopLogRetentionForTest(): void;
|
|
14
|
+
|
|
15
|
+
export interface LogRetentionTargets {
|
|
16
|
+
|
|
17
|
+
logDir: string;
|
|
18
|
+
|
|
19
|
+
agentLogDir: string;
|
|
20
|
+
|
|
21
|
+
instanceAiDebugLogPath: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function getLogRetentionTargets(): LogRetentionTargets;
|
|
24
|
+
|
|
25
|
+
export interface LogRetentionSweepResult {
|
|
26
|
+
retentionDays: number;
|
|
27
|
+
removedFiles: number;
|
|
28
|
+
removedDirs: number;
|
|
29
|
+
failures: number;
|
|
30
|
+
bytesFreed: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export declare function sweepExpiredLogs(): Promise<LogRetentionSweepResult>;
|
|
34
|
+
|
|
35
|
+
export declare function startLogRetention(): void;
|
|
36
|
+
|
|
37
|
+
export declare function stopLogRetention(): void;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import c from"node:fs/promises";import o from"node:path";import{getAutoRegisterConfigFilePath as N,getBridgeDataHome as I,getRuntimeHomeDir as S}from"../config.js";import{createLogger as x}from"../utils/logger.js";const w=x("log-retention"),m=7,b=7,_=6*60*60*1e3,M="Instance-ai-configuration-debug.log";let r=m,l=null,p=!1,y=!1,h=!1;function A(t,e){h||(h=!0,w.warn(`${t}${e instanceof Error?`: ${e.message}`:""}`))}function E(t){if(t==null||t===""||typeof t=="boolean")return m;const e=Number(t);return!Number.isFinite(e)||e<=0?m:Math.min(Math.floor(e),b)}function Y(t){const e=E(t);return y=!0,e!==r&&(r=e,F()),r}function V(){return r}function k(){r=m}function J(){r=m,y=!1,l&&(clearInterval(l),l=null),p=!1,h=!1}function O(){const t=o.join(I(),"log");return{logDir:t,agentLogDir:o.join(t,"agent"),instanceAiDebugLogPath:o.join(j(),M)}}function j(){return String(process.env.AWS_TEST_HOME||"").trim()||String(process.env.AWS_RUNTIME_HOME_DIR||"").trim()||S()}async function D(t,e,i){try{const n=await c.stat(t);return n.mtimeMs>=e?!1:(await c.unlink(t),i.removedFiles+=1,i.bytesFreed+=n.size,!0)}catch(n){return n.code!=="ENOENT"&&(i.failures+=1,A("[log-retention] \u5220\u9664\u8FC7\u671F\u65E5\u5FD7\u5931\u8D25",n)),!1}}async function $(t,e,i){let n=o.normalize(t);const s=o.normalize(e);for(;n.startsWith(s)&&n!==s;){try{await c.rmdir(n),i.removedDirs+=1}catch{return}n=o.dirname(n)}}async function W(t,e,i){let n;try{n=await c.readdir(t)}catch{return}for(const s of n)!s.startsWith("lifecycle-")||!s.endsWith(".jsonl")||await D(o.join(t,s),e,i)}async function z(t,e,i){const n=o.join(t,"aws-mcp-node");let s;try{s=(await c.readdir(n,{withFileTypes:!0})).filter(u=>u.isDirectory()).map(u=>o.join(n,u.name))}catch{return}for(const g of s){let u;try{u=(await c.readdir(g,{withFileTypes:!0})).filter(a=>a.isDirectory()).map(a=>o.join(g,a.name))}catch{continue}for(const f of u){let a;try{a=(await c.readdir(f,{withFileTypes:!0})).filter(d=>d.isFile()).map(d=>o.join(f,d.name))}catch{continue}let R=!0;for(const T of a)await D(T,e,i)||(R=!1);R&&a.length>0&&await $(f,n,i)}let L;try{L=(await c.readdir(g,{withFileTypes:!0})).filter(a=>a.isFile()).map(a=>o.join(g,a.name))}catch{continue}for(const f of L)await D(f,e,i)}}async function G(t,e,i){await D(t,e,i)}function F(){const t=async()=>{const e={retentionDays:r,removedFiles:0,removedDirs:0,failures:0,bytesFreed:0},i=Date.now()-r*24*60*60*1e3,n=O();try{await W(n.logDir,i,e),await z(n.agentLogDir,i,e),await G(n.instanceAiDebugLogPath,i,e)}catch(s){A("[log-retention] \u6E05\u7406\u8FC7\u671F\u65E5\u5FD7\u51FA\u9519",s)}return(e.removedFiles>0||e.removedDirs>0)&&w.info(`[log-retention] \u6E05\u7406\u5B8C\u6210\uFF1A\u5220\u9664 ${e.removedFiles} \u4E2A\u6587\u4EF6 / ${e.removedDirs} \u4E2A\u76EE\u5F55\uFF0C\u91CA\u653E ${(e.bytesFreed/1024/1024).toFixed(1)} MB\uFF08\u4FDD\u7559 ${r} \u5929\uFF09`),e};return p||(p=!0,v=t().finally(()=>{p=!1})),v}let v=Promise.resolve({retentionDays:r,removedFiles:0,removedDirs:0,failures:0,bytesFreed:0});function X(){if(l)return;const t=String(process.env.AWS_BRIDGE_LOG_RETENTION_DAYS||"").trim();t&&(r=E(t),y=!0),l=setInterval(()=>{F()},_),H().finally(()=>{F(),w.info(`[log-retention] \u65E5\u5FD7\u4FDD\u7559\u7B56\u7565\u5DF2\u542F\u52A8\uFF1A\u4FDD\u7559 ${r} \u5929\uFF0C\u6BCF ${_/36e5}h \u6E05\u7406\u4E00\u6B21`)})}async function H(){try{const t=await c.readFile(N(),"utf-8"),e=JSON.parse(t);e.logRetentionDays!==void 0&&!y&&(r=E(e.logRetentionDays))}catch{}}function q(){l&&(clearInterval(l),l=null)}export{m as DEFAULT_LOG_RETENTION_DAYS,V as getLogRetentionDays,O as getLogRetentionTargets,E as normalizeLogRetentionDays,k as resetLogRetentionDaysForTest,Y as setLogRetentionDays,X as startLogRetention,q as stopLogRetention,J as stopLogRetentionForTest,F as sweepExpiredLogs};
|
|
2
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface InvalidProviderRequestDumpInput {
|
|
2
|
+
sessionId: string;
|
|
3
|
+
|
|
4
|
+
agentId?: string;
|
|
5
|
+
|
|
6
|
+
model?: string;
|
|
7
|
+
|
|
8
|
+
attempt: number;
|
|
9
|
+
|
|
10
|
+
errorText: string;
|
|
11
|
+
|
|
12
|
+
conversation?: unknown[];
|
|
13
|
+
|
|
14
|
+
extra?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export declare function resetInvalidRequestDumpStateForTest(): void;
|
|
18
|
+
|
|
19
|
+
export declare function getInvalidRequestDumpDir(): string;
|
|
20
|
+
|
|
21
|
+
export declare function dumpInvalidProviderRequest(input: InvalidProviderRequestDumpInput): Promise<string | null>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createHash as T}from"node:crypto";import i from"node:fs/promises";import d from"node:path";import{getBridgeDataHome as v}from"../config.js";const p="acode-request-invalid-",I=20,h=10*6e4,_=8e3,w=2*1024*1024,u=800;let m=!1;const g=new Map;function C(){g.clear(),m=!1}function S(){return d.join(v(),"log")}function D(e){return T("sha1").update(e).digest("hex").slice(0,16)}function E(e){return new Date(e).toISOString().replace(/[:.]/g,"-")}function x(e){if(!Array.isArray(e))return{conversation:[],truncated:!1};try{if(JSON.stringify(e).length<=w)return{conversation:e,truncated:!1}}catch{}return{conversation:e.map(n=>{if(!n||typeof n!="object")return{value:String(n).slice(0,u)};const r=n,t=r.content;let o;if(typeof t=="string")o=t.slice(0,u);else if(t==null)o=t;else try{o=JSON.stringify(t).slice(0,u)}catch{o="[unserializable]"}return{role:r.role,tool_call_id:r.tool_call_id,tool_calls:Array.isArray(r.tool_calls)?r.tool_calls.map(c=>{const s=c;return{id:s?.id,type:s?.type,name:s?.name??s?.function?.name}}):void 0,contentPreview:o}}),truncated:!0}}async function O(e){try{const n=(await i.readdir(e)).filter(t=>t.startsWith(p)&&t.endsWith(".json")).sort(),r=n.length-I;if(r<=0)return;await Promise.all(n.slice(0,r).map(t=>i.rm(d.join(e,t),{force:!0})))}catch{}}async function M(e){const a=S(),n=D(e.errorText),r=Date.now(),t=g.get(e.sessionId);if(t&&t.fingerprint===n&&r-t.at<h)return t.file;const{conversation:o,truncated:c}=x(e.conversation),s=`${p}${E(r)}-${e.sessionId.slice(0,8)}.json`,l=d.join(a,s),y={timestamp:new Date(r).toISOString(),kind:"provider-request-invalid",sessionId:e.sessionId,agentId:e.agentId,model:e.model,attempt:e.attempt,errorText:e.errorText.slice(0,_),errorTextTruncated:e.errorText.length>_,messageCount:Array.isArray(e.conversation)?e.conversation.length:0,conversationTruncated:c,conversation:o,...e.extra?{extra:e.extra}:{}};try{return await i.mkdir(a,{recursive:!0}),await i.writeFile(l,JSON.stringify(y,null,2),"utf8"),g.set(e.sessionId,{fingerprint:n,file:l,at:r}),await O(a),l}catch(f){return m||(m=!0,console.warn(`[request-invalid-dump] \u4E0A\u4E0B\u6587\u5FEB\u7167\u5199\u5165\u5931\u8D25\uFF0C\u540E\u7EED\u5FEB\u7167\u5C06\u88AB\u4E22\u5F03: ${f instanceof Error?f.message:String(f)}`)),null}}export{M as dumpInvalidProviderRequest,S as getInvalidRequestDumpDir,C as resetInvalidRequestDumpStateForTest};
|
|
2
|
+
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{appendFile as
|
|
2
|
-
`,"utf8").catch(
|
|
1
|
+
import{appendFile as u,mkdir as g}from"node:fs/promises";import s from"node:path";import{getBridgeDataHome as d}from"../config.js";const L=process.env.ACODE_LIFECYCLE_LOG!=="0";let f=null,t=null,i=!1;const r=new Set;async function S(){for(;r.size>0;)await Promise.allSettled([...r])}function m(){const e=new Date().toISOString().slice(0,10);return s.join(d(),"log",`lifecycle-${e}.jsonl`)}function E(e){return f===e&&t||(f=e,t=g(e,{recursive:!0}).then(()=>{}).catch(n=>{i||(i=!0,console.warn(`[lifecycle-log] \u65E0\u6CD5\u521B\u5EFA\u8BCA\u65AD\u65E5\u5FD7\u76EE\u5F55\uFF0C\u540E\u7EED\u8BCA\u65AD\u8BB0\u5F55\u5C06\u88AB\u4E22\u5F03: ${n instanceof Error?n.message:String(n)}`))})),t}function h(e,n){if(!L)return;const a={ts:new Date().toISOString(),event:e,...n},l=m(),c=E(s.dirname(l)).then(()=>u(l,`${JSON.stringify(a)}
|
|
2
|
+
`,"utf8")).then(()=>{}).catch(o=>{i||(i=!0,console.warn(`[lifecycle-log] \u8BCA\u65AD\u65E5\u5FD7\u5199\u5165\u5931\u8D25\uFF0C\u540E\u7EED\u8BB0\u5F55\u5C06\u88AB\u4E22\u5F03: ${o instanceof Error?o.message:String(o)}`))}).finally(()=>{r.delete(c)});r.add(c)}export{S as flushLifecycleLogForTest,h as recordLifecycleEvent};
|
|
3
3
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function q(e){return`image/${e}`}function W(e){return e>=1024*1024?`${(e/(1024*1024)).toFixed(2)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function S(e){return e.length<12?null:e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71?"png":e[0]===255&&e[1]===216&&e[2]===255?"jpeg":e[0]===71&&e[1]===73&&e[2]===70?"gif":e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80?"webp":null}function D(e){if(!(e.length<24||e.toString("hex",0,8)!=="89504e470d0a1a0a"))return{width:e.readUInt32BE(16),height:e.readUInt32BE(20)}}function F(e){if(!(e.length<10||e.toString("ascii",0,6)!=="GIF87a"&&e.toString("ascii",0,6)!=="GIF89a"))return{width:e.readUInt16LE(6),height:e.readUInt16LE(8)}}function v(e){if(e.length<4||e[0]!==255||e[1]!==216)return;let i=2;for(;i+9<e.length;){if(e[i]!==255){i+=1;continue}const r=e[i+1],
|
|
1
|
+
function q(e){return`image/${e}`}function W(e){return e>=1024*1024?`${(e/(1024*1024)).toFixed(2)} MB`:e>=1024?`${(e/1024).toFixed(1)} KB`:`${e} B`}function S(e){return e.length<12?null:e[0]===137&&e[1]===80&&e[2]===78&&e[3]===71?"png":e[0]===255&&e[1]===216&&e[2]===255?"jpeg":e[0]===71&&e[1]===73&&e[2]===70?"gif":e[0]===82&&e[1]===73&&e[2]===70&&e[3]===70&&e[8]===87&&e[9]===69&&e[10]===66&&e[11]===80?"webp":null}function D(e){if(!(e.length<24||e.toString("hex",0,8)!=="89504e470d0a1a0a"))return{width:e.readUInt32BE(16),height:e.readUInt32BE(20)}}function F(e){if(!(e.length<10||e.toString("ascii",0,6)!=="GIF87a"&&e.toString("ascii",0,6)!=="GIF89a"))return{width:e.readUInt16LE(6),height:e.readUInt16LE(8)}}function v(e){if(e.length<4||e[0]!==255||e[1]!==216)return;let i=2;for(;i+9<e.length;){if(e[i]!==255){i+=1;continue}const r=e[i+1],h=e.readUInt16BE(i+2);if(h<2)return;if(r>=192&&r<=207&&![196,200,204].includes(r)&&i+8<e.length)return{height:e.readUInt16BE(i+5),width:e.readUInt16BE(i+7)};i+=2+h}}function z(e){if(e.length<30||e.toString("ascii",0,4)!=="RIFF"||e.toString("ascii",8,12)!=="WEBP")return;const i=e.toString("ascii",12,16);if(i==="VP8X")return{width:1+e.readUIntLE(24,3),height:1+e.readUIntLE(27,3)};if(i==="VP8 ")return{width:e.readUInt16LE(26)&16383,height:e.readUInt16LE(28)&16383};if(i==="VP8L"&&e.length>=25){const r=e.readUInt32LE(21);return{width:(r&16383)+1,height:(r>>14&16383)+1}}}function B(e){const i=S(e);if(!i)return null;const h=(i==="png"?D:i==="gif"?F:i==="jpeg"?v:z)(e);return!h||!h.width||!h.height?null:h}let x;async function M(){return x===void 0&&(x=import("sharp").then(i=>{const r=i,h=typeof r=="function"?r:r.default;return typeof h=="function"?h:null}).catch(()=>null)),x}function R(){x=void 0}function H(e){x=Promise.resolve(e)}async function O(e,i,r){const h=await M();if(!h)return null;try{const p=await h(e).metadata();let g=p.width??0,c=p.height??0;if(!g||!c){const d=B(e);g=d?.width??0,c=d?.height??0}const a=g>0&&c>0,s=a&&g<=r.maxWidth&&c<=r.maxHeight;if(s&&e.length<=r.maxBytes)return{buffer:e,mediaType:i,width:g,height:c,changed:!1};if(s){if(i==="png"){const d=await h(e).png({compressionLevel:9,palette:!0}).toBuffer();if(d.length<=r.maxBytes)return{buffer:d,mediaType:"png",width:g,height:c,changed:!0}}for(const d of[80,60,40,20]){const m=await h(e).jpeg({quality:d}).toBuffer();if(m.length<=r.maxBytes)return{buffer:m,mediaType:"jpeg",width:g,height:c,changed:!0}}}let n=a?g:r.maxWidth,t=a?c:r.maxHeight;n>r.maxWidth&&(t=Math.round(t*r.maxWidth/n),n=r.maxWidth),t>r.maxHeight&&(n=Math.round(n*r.maxHeight/t),t=r.maxHeight),n=Math.max(1,n),t=Math.max(1,t);const l={fit:"inside",withoutEnlargement:!0};if(i==="png"){const d=await h(e).resize(n,t,l).png({compressionLevel:9,palette:!0}).toBuffer();if(d.length<=r.maxBytes)return{buffer:d,mediaType:"png",width:n,height:t,changed:!0}}for(const d of[80,60,40,20]){const m=await h(e).resize(n,t,l).jpeg({quality:d}).toBuffer();if(m.length<=r.maxBytes)return{buffer:m,mediaType:"jpeg",width:n,height:t,changed:!0}}const o=Math.min(n,1e3),u=Math.max(1,Math.round(t*o/Math.max(n,1)));return{buffer:await h(e).resize(o,u,l).jpeg({quality:20}).toBuffer(),mediaType:"jpeg",width:o,height:u,changed:!0}}catch{return null}}const U=2e3,j=1e3;async function I(e){try{const i=await e();return i.length>0?i:null}catch{return null}}async function P(e,i,r){const h=await M();if(!h)return null;try{if(i==="gif")return c(null);const a=await p(h,e,i);if(a!==null&&a.buffer.length<=r.normalMaxBytes)return c({...a,level:"lossy"});const s=a!==null?{buffer:a.buffer,mediaType:a.mediaType}:{buffer:e,mediaType:i},n=await g(h,s.buffer,s.mediaType,{maxBytes:r.normalMaxBytes,targetDimension:U,qualityBias:"high"});if(n!==null&&n.buffer.length<=r.clearMaxBytes)return c({...n,level:"normal"});const t=n!==null?{buffer:n.buffer,mediaType:n.mediaType}:{buffer:s.buffer,mediaType:s.mediaType},l=await g(h,t.buffer,t.mediaType,{maxBytes:r.clearMaxBytes,targetDimension:j,qualityBias:"low"});return c(l!==null?{...l,level:"clear"}:n!==null?{...n,level:"normal"}:a!==null?{...a,level:"lossy"}:null)}catch{return null}async function p(a,s,n){const t=[];n==="png"?(t.push({mediaType:"png",encode:()=>a(s).png({compressionLevel:9}).toBuffer()}),t.push({mediaType:"webp",encode:()=>a(s).webp({lossless:!0}).toBuffer()})):n==="webp"&&t.push({mediaType:"webp",encode:()=>a(s).webp({lossless:!0}).toBuffer()});let l=null;for(const o of t){const u=await I(o.encode);u&&u.length<s.length&&(!l||u.length<l.buffer.length)&&(l={buffer:u,mediaType:o.mediaType})}return l}async function g(a,s,n,t){let l=B(s)?.width??0,o=B(s)?.height??0;l>t.targetDimension&&(o=Math.round(o*t.targetDimension/l),l=t.targetDimension),o>t.targetDimension&&(l=Math.round(l*t.targetDimension/o),o=t.targetDimension),l=Math.max(1,l),o=Math.max(1,o);const u={fit:"inside",withoutEnlargement:!0},T=n==="gif"?"png":n,d=[],m=t.qualityBias==="high"?[90,80,70]:[60,50,40],E=t.qualityBias==="high"?[80,70,60]:[50,40,30],L=t.qualityBias==="high"?[80,70,60]:[50,40,30];if(T==="png")for(const f of m)d.push({mediaType:"png",encode:()=>a(s).resize(l,o,u).png({compressionLevel:9,palette:!0,quality:f}).toBuffer()});for(const f of E)d.push({mediaType:"webp",encode:()=>a(s).resize(l,o,u).webp({quality:f}).toBuffer()});if(T!=="webp")for(const f of L)d.push({mediaType:"jpeg",encode:()=>a(s).resize(l,o,u).jpeg({quality:f}).toBuffer()});let y=null;for(const f of d){const w=await I(f.encode);if(w&&w.length<s.length&&((!y||w.length<y.buffer.length)&&(y={buffer:w,mediaType:f.mediaType}),y.buffer.length<=t.maxBytes))break}return y}function c(a){const s=a!==null,n=s?a.buffer:e,t=B(n),l=s?Math.max(0,Math.round((1-n.length/e.length)*100)):0;return{buffer:n,mediaType:s?a.mediaType:i,width:t?.width??0,height:t?.height??0,compressed:s,level:s?a.level:null,originalSize:e.length,compressedSize:n.length,savedPercent:l}}}export{S as detectImageFormatFromBuffer,W as formatBytes,q as imageMediaType,B as readImageDimensions,R as resetSharpCacheForTest,H as setSharpFactoryForTest,P as tryCompressImageWithSharp,O as tryResizeWithSharp};
|
|
2
2
|
|
|
@@ -134,6 +134,8 @@ export declare class AgentClient {
|
|
|
134
134
|
|
|
135
135
|
queryFileChangesHistory(args: Record<string, unknown>): Promise<unknown>;
|
|
136
136
|
|
|
137
|
+
listColleagueEvents(args: Record<string, unknown>): Promise<unknown>;
|
|
138
|
+
|
|
137
139
|
getRuntimeFeatures(): Promise<Record<string, unknown>>;
|
|
138
140
|
|
|
139
141
|
listLaunchConfigs(): Promise<unknown>;
|