aws-runtime-bridge 1.9.124 → 1.9.126
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/README.md +23 -2
- package/dist/adapter/AcodeSdkAdapter.js +4 -4
- package/dist/adapter/OpencodeSdkAdapter.js +2 -2
- package/dist/adapter/types.js +1 -1
- package/dist/config.d.ts +30 -4
- package/dist/config.js +3 -1
- package/dist/index.js +1 -1
- package/dist/routes/acode-todos.js +1 -1
- package/dist/routes/background-tasks.js +1 -1
- package/dist/routes/dashboard.js +58 -3
- package/dist/routes/git.d.ts +28 -0
- package/dist/routes/git.js +32 -31
- package/dist/routes/terminal.js +24 -24
- package/dist/services/auto-register.d.ts +2 -2
- package/dist/services/auto-register.js +1 -1
- package/dist/services/aws-client-agent-mcp.d.ts +2 -1
- package/dist/services/aws-client-agent-mcp.js +2 -2
- package/dist/services/cc-switch-sdk.js +1 -1
- package/dist/services/cli-commands.js +5 -5
- package/dist/services/fileSnapshotStore.js +1 -1
- package/dist/services/instance-ai-config-service.js +1 -1
- package/dist/services/instance-features.d.ts +2 -0
- package/dist/services/instance-features.js +1 -1
- package/dist/services/panel-auth.d.ts +2 -0
- package/dist/services/panel-auth.js +1 -1
- package/dist/services/startup-config-wizard.js +6 -6
- package/dist/services/tunnel-client.js +1 -1
- package/dist/services/update-notifier.js +2 -2
- package/package/acode/dist/ask-user-question-tool.js +2 -2
- package/package/acode/dist/background-command-store.js +1 -1
- package/package/acode/dist/builtins/commandArtifacts.js +3 -3
- package/package/acode/dist/mcpToolNames.d.ts +2 -0
- package/package/acode/dist/mcpToolNames.js +1 -1
- package/package/acode/dist/meeting-debug-log.d.ts +1 -0
- package/package/acode/dist/meeting-debug-log.js +3 -0
- package/package/acode/dist/paths.d.ts +2 -0
- package/package/acode/dist/paths.js +2 -0
- package/package/acode/dist/runtime.d.ts +4 -0
- package/package/acode/dist/runtime.js +20 -20
- package/package/acode/dist/sub-agent-manager.d.ts +1 -0
- package/package/acode/dist/sub-agent-manager.js +1 -1
- package/package/acode/dist/sub-agent-store.js +3 -3
- package/package/acode/dist/sub-agent-tools.js +27 -31
- package/package/acode/dist/sub-agent-types.d.ts +1 -1
- package/package/acode/dist/todo-store.js +1 -1
- package/package/acode/dist/tool-allocation.d.ts +18 -4
- package/package/acode/dist/tool-allocation.js +1 -1
- package/package/acode/dist/types.d.ts +0 -3
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +17 -0
- package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.test.js +251 -1
- package/package/aws-client-agent-mcp/dist/config.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/config.js +1 -1
- package/package/aws-client-agent-mcp/dist/config.test.js +93 -1
- package/package/aws-client-agent-mcp/dist/http-client.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/http-client.js +1 -1
- package/package/aws-client-agent-mcp/dist/launch-config-tools.test.js +6 -2
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +21 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.js +28 -28
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js +628 -7
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +10 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +12 -10
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.js +38 -0
- package/package/aws-client-agent-mcp/dist/meeting-debug-log.d.ts +13 -0
- package/package/aws-client-agent-mcp/dist/meeting-debug-log.js +3 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/message-buffer.js +1 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.test.js +60 -0
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.d.ts +14 -0
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js +1 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.js +39 -1
- package/package/aws-client-agent-mcp/dist/types.d.ts +11 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.js +1 -1
- package/package/aws-client-agent-mcp/package.json +1 -1
- package/package.json +1 -1
package/dist/routes/terminal.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import{spawn as
|
|
1
|
+
import{spawn as Xe}from"node:child_process";import{promises as N}from"node:fs";import Qe from"node:os";import j from"node:path";import{TextDecoder as ee}from"node:util";import{Router as Ve}from"express";import{v4 as Ge}from"uuid";import be from"axios";import{adapterRegistry as w,getToolActionInfo as ye,isTransientClipboardPasteFilePath as Ce,redactTransientClipboardPastePaths as v,registerSdkProviders as Je,resolveSdkProviderIdByCommand as Ye}from"../adapter/index.js";import{validateToken as S}from"../middleware/auth.js";import{getActiveBridgeHttpPort as Ze,getAcodeDataHome as _e}from"../config.js";import{getAgentProcessManager as he}from"../services/agent-process-manager.js";import{setAgentFeatures as et,getAgentFeatures as tt,isFeatureEnabled as $e,LAUNCH_ITEM_FEATURE_KEY as nt,HIRE_FEATURE_KEY as ot}from"../services/instance-features.js";import{setPanelEnvVars as rt}from"../services/panel-env.js";import{setChangeCacheRetentionDays as st}from"../services/change-cache-retention.js";import{getAiConfigService as it}from"../services/cc-switch-sdk.js";import{prepareAcodeInstanceConfig as at,redactForLog as te}from"../services/instance-ai-config-service.js";import{enqueueMcpLaunchBinding as ct}from"../services/mcp-launch-binding-queue.js";import{resolveSchedulerBaseUrlFromToken as De}from"../services/auto-register.js";import{findClaudeCodeProcesses as ut,isProcessRunning as dt}from"../services/process-detector.js";import{bridgeEventBuffer as Re,sendOutput as X,sendQuestionRequest as lt,sendStatus as _}from"../services/session-output.js";import{getAllPushStats as mt,startHeartbeatScheduler as ft}from"../services/event-delta-pusher.js";import{forgetSession as q,onSdkToolUseEnd as pt,onSdkToolUseStart as gt}from"../services/sdk-tool-file-change-recorder.js";import{findPersistedSessionByAgentId as yt,removePersistedSession as F,savePersistedSessions as ht,updatePersistedSessionAutoCommands as It,updatePersistedSessionRuntimeState as St,upsertPersistedSession as At}from"../services/terminal-persistence.js";import{getInstanceAiConfigDebugLogger as Tt}from"../utils/instance-ai-config-debug-logger.js";import{logger as h}from"../utils/logger.js";const A=Ve();function Pe(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 p=new Map,kt=45e3,ne=new Map;function wt(e){if(ne.has(e))return;const n=setInterval(()=>{const t=p.get(e);if(!t){L(e);return}const o=t.currentRuntimeStatus;if(o!=="thinking"&&o!=="tool_using"&&o!=="compacting"){L(e);return}_(t.agentId,e,o,void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl}).catch(()=>{})},kt);ne.set(e,n)}function L(e){const n=ne.get(e);n&&(clearInterval(n),ne.delete(e))}const Ee=4e3,bt=`
|
|
2
2
|
|
|
3
3
|
\u8BF7\u6C42\u4F53:
|
|
4
|
-
`;function Ie(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
|
|
4
|
+
`;function Ie(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 Ct=`
|
|
5
5
|
|
|
6
6
|
\u8BF7\u6C42\u5934:
|
|
7
|
-
`,K=new Set;async function
|
|
7
|
+
`,K=new Set;async function _t(e,n){const t=[],o=[],r=j.join(e,".agentswork","memory");try{const c=(await N.readdir(r)).filter(u=>u.endsWith(".json")),d=await Promise.all(c.map(async u=>{try{const l=await N.readFile(j.join(r,u),"utf-8");return JSON.parse(l)}catch{return h.warn("[loadAgentStartupMemories] Failed to parse memory file: %s",j.join(r,u)),null}}));for(const u of d)if(u?.by_uri)for(const l of Object.values(u.by_uri)){const m=l.memory_type||"memory",f=(l.content||"").trim();f&&(m==="recently_memory"?t.push({title:l.title,content:f,uri:l.uri||""}):m==="agent_memory"&&o.push({title:l.title,content:f,uri:l.uri||""}))}}catch{h.debug("[loadAgentStartupMemories] \u65E0\u6CD5\u8BFB\u53D6\u8BB0\u5FC6\u76EE\u5F55: %s",r)}if(t.length===0&&o.length===0&&n?.schedulerBaseUrl&&n?.runtimeAccessToken&&n?.agentId){const a=`${n.schedulerBaseUrl.replace(/\/+$/,"")}/mcp/call`,c={"Content-Type":"application/json","X-Runtime-Token":n.runtimeAccessToken,Authorization:`Bearer ${n.runtimeAccessToken}`},d=["recently_memory","agent_memory"],u=await Promise.allSettled(d.map(l=>fetch(a,{method:"POST",headers:c,body:JSON.stringify({tool:"list_memories",arguments:{agentId:n.agentId,memory_type:l}})}).then(m=>{if(!m.ok)throw new Error(`Server returned ${m.status}`);return m.json()})));for(let l=0;l<u.length;l++){const m=u[l];if(m.status!=="fulfilled")continue;const f=m.value;if(!Array.isArray(f))continue;const T=d[l]==="recently_memory"?t:o;for(const y of f){const g=(y.content||"").trim();g&&T.push({title:y.title,content:g,uri:y.uri||""})}}(t.length>0||o.length>0)&&h.info(`[loadAgentStartupMemories] Loaded ${t.length} task(s) and ${o.length} memory(s) from server for ${n.agentId}`)}const s=10;t.sort((a,c)=>c.uri.localeCompare(a.uri)),o.sort((a,c)=>c.uri.localeCompare(a.uri));const i=[];if(t.length>0){const c=t.slice(0,s).map((d,u)=>`${d.title?`\u3010${d.title}\u3011`:`\u6761\u76EE ${u+1}`}
|
|
8
8
|
${d.content}`);i.push(`\u3010\u77ED\u671F\u8BB0\u5FC6\u3011
|
|
9
9
|
${c.join(`
|
|
10
10
|
|
|
11
|
-
`)}`),t.length>s&&i.push(`... \u53CA\u53E6\u5916 ${t.length-s} \u6761\u77ED\u671F\u8BB0\u5FC6`)}if(
|
|
11
|
+
`)}`),t.length>s&&i.push(`... \u53CA\u53E6\u5916 ${t.length-s} \u6761\u77ED\u671F\u8BB0\u5FC6`)}if(o.length>0){const c=o.slice(0,s).map(d=>{const u=d.title?`\u3010${d.title}\u3011`:"";return u?`${u}
|
|
12
12
|
${d.content}`:d.content});i.push(`\u3010agent\u8BA4\u77E5\u3011
|
|
13
13
|
${c.join(`
|
|
14
14
|
|
|
15
|
-
`)}`),
|
|
15
|
+
`)}`),o.length>s&&i.push(`... \u53CA\u53E6\u5916 ${o.length-s} \u6761 agent \u8BA4\u77E5`)}if(i.length!==0)return i.join(`
|
|
16
16
|
|
|
17
|
-
`)}function
|
|
17
|
+
`)}function $t(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 Dt(e){return e!=="acode"}function Rt(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 oe(e){const n=e?.usage;if(!n)return;const t=Number.isFinite(n.inputTokens)?n.inputTokens:0,o=Number.isFinite(n.outputTokens)?n.outputTokens:0;if(t<=0&&o<=0&&!n.contextLimit&&!n.maxOutput&&!n.inputLimit&&!n.compactionThreshold)return;const r={inputTokens:t,outputTokens:o,...n.contextLimit?{contextLimit:n.contextLimit}:{},...n.maxOutput?{maxOutput:n.maxOutput}:{},...n.inputLimit?{inputLimit:n.inputLimit}:{},...n.compactionThreshold?{compactionThreshold:n.compactionThreshold}:{},...n.cacheHitTokens?{cacheHitTokens:n.cacheHitTokens}:{},...n.cacheMissTokens?{cacheMissTokens:n.cacheMissTokens}:{}};return process.env.ACODE_TOKEN_DEBUG==="1"&&(r.inputTokens>0||r.outputTokens>0||r.cacheHitTokens!==void 0||r.cacheMissTokens!==void 0)&&console.log(`[TokenDebug][Terminal] resolveStatusChangeUsage: input=${r.inputTokens} output=${r.outputTokens} cacheHit=${r.cacheHitTokens??"(none)"} cacheMiss=${r.cacheMissTokens??"(none)"} actionType=${e?.actionType??"(none)"}`),r}function Pt(e,n){const t=String(e||"").trim().toLowerCase(),o=String(n?.actionType||"").trim().toLowerCase();return t==="tool_using"&&o==="idle"?n?{status:"waiting_input",actionInfo:n}:{status:"waiting_input"}:n?{status:e,actionInfo:n}:{status:e}}const Q=new Map,Et="utf-8",Me="utf-8",Le=300,xe=6e4;function V(e){return String(e).padStart(2,"0")}function Mt(e,n=new Date){const t=n.getFullYear(),o=V(n.getMonth()+1),r=V(n.getDate()),s=V(n.getHours()),i=V(n.getMinutes()),a=`${t}${o}${r}-${s}${i}${V(n.getSeconds())}-${String(n.getMilliseconds()).padStart(3,"0")}`;return j.join(_e(),"cmd-dist",e,`${t}-${o}-${r}`,s,i,`${a}-cmd.out`)}function Lt(e){if(!e)return 0;const n=e.replace(/\r\n/g,`
|
|
18
18
|
`).replace(/\r/g,`
|
|
19
19
|
`),t=n.endsWith(`
|
|
20
20
|
`)?n.slice(0,-1):n;return t?t.split(`
|
|
21
|
-
`).length:1}function
|
|
21
|
+
`).length:1}function xt(e,n=Le){return`\r
|
|
22
22
|
[ACode] \u547D\u4EE4\u8F93\u51FA\u8D85\u8FC7 ${n} \u884C\uFF0C\u5B8C\u6574\u8F93\u51FA\u5DF2\u5199\u5165: ${e}\r
|
|
23
23
|
[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
|
|
24
|
-
`}function
|
|
24
|
+
`}function Ut(e=xe){return`\r
|
|
25
25
|
[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
|
|
26
|
-
`}async function
|
|
27
|
-
`).trim()}function
|
|
28
|
-
`),!0;const
|
|
29
|
-
`),!0):(b(e,`cd: not a directory: ${
|
|
26
|
+
`}async function Ue(e){const n=e.outputPath||Mt(e.agentId,e.startedAt);return e.outputPath=n,await N.mkdir(j.dirname(n),{recursive:!0}),await N.writeFile(n,e.chunks.join(""),"utf-8"),n}function jt(e){return String(e??"").replace(/\r/g,`
|
|
27
|
+
`).trim()}function Bt(e=process.platform,n=process.env){const t=n.AWS_TERMINAL_OUTPUT_ENCODING?.trim();return t||(e==="win32"?Et:Me)}function je(e=Bt()){if(e!=="utf-8")try{return new ee(e,{fatal:!1})}catch{return new ee(Me,{fatal:!1})}return Ot()}function Ot(){let e=null,n=null,t=null;const o=[];function r(s){try{return new ee(s,{fatal:!1})}catch{return new ee("utf-8",{fatal:!1})}}return{decode(s,i){if(s!=null&&o.push(s instanceof ArrayBuffer?Buffer.from(s):Buffer.isBuffer(s)?s:Buffer.from(s.buffer,s.byteOffset,s.byteLength)),t==="gb18030")return n||(n=r("gb18030")),n.decode(s,i);e||(e=r("utf-8"));const a=e.decode(s,i);if(t===null&&a.includes("\uFFFD")){t="gb18030",n=r("gb18030");const c=Buffer.concat(o);return n.decode(c)}return t===null&&!i?.stream&&(t="utf-8"),a}}}function re(e,n,t=!1){return t?e.decode():!n||n.length===0?"":e.decode(n,{stream:!0})}function Nt(e){const n=e.trim().match(/^cd(?:\s+(.*))?$/i);if(!n)return;const t=n[1]?.trim();if(!t)return null;const o=t.replace(/^\/d\s+/i,"").trim();return o.startsWith('"')&&o.endsWith('"')||o.startsWith("'")&&o.endsWith("'")?o.slice(1,-1):o}function vt(e){const n=Q.get(e.sessionId);if(n)return n;const t={currentDirectory:e.workspacePath,runningProcess:null};return Q.set(e.sessionId,t),t}function Be(e){for(const n of p.values())if(n.agentId===e)return n}async function qt(e){const n=w.get(e.providerId||"claude-code"),t=se(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 se(e,n,t){const o=String(e||"").trim();if(o){const s=String(n||"").trim(),i=String(t||"").trim().toLowerCase();return o.toLowerCase()==="tool_using"&&s.toLowerCase()==="waiting_input"&&i==="idle"?s:o}return String(n||"").trim()||"running"}function Ft(e,n=dt){return e.pid?n(e.pid)?Ke(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 Zn(e){const n=Be(e);if(!n)h.info(`[cleanupSdkSessionByAgentId] No active SDK session found for agentId=${e}, cleaning residual state anyway`);else{const t=n.sessionId;return h.info(`[cleanupSdkSessionByAgentId] Cleaning up SDK session for agentId=${e}, sessionId=${t}`),L(t),p.delete(t),q(t),ie(t),F(t).catch(o=>{h.warn(`[cleanupSdkSessionByAgentId] Failed to remove persisted session for agentId=${e}: ${o}`)}),t}K.has(e)&&(K.delete(e),h.info(`[cleanupSdkSessionByAgentId] Released startingAgents lock for agentId=${e}`))}function ie(e){const n=Q.get(e);if(!n?.runningProcess){Q.delete(e);return}try{n.runningProcess.kill()}catch{}finally{n.runningProcess=null,Q.delete(e)}}function b(e,n){n&&(e.seq+=1,X(e.agentId,n,e.sessionId,e.seq,void 0,{runtimeAccessToken:e.runtimeAccessToken,schedulerBaseUrl:e.schedulerBaseUrl}).catch(()=>{}))}function Se(e){return`\x1B[36m${e}>\x1B[0m `}function Kt(e,n){return n==="~"?Qe.homedir():j.resolve(e,n)}async function zt(e,n,t){const o=Nt(t);if(o===void 0)return!1;if(o===null)return b(e,`${n.currentDirectory}\r
|
|
28
|
+
`),!0;const r=Kt(n.currentDirectory,o);try{return(await N.stat(r)).isDirectory()?(n.currentDirectory=r,b(e,`${n.currentDirectory}\r
|
|
29
|
+
`),!0):(b(e,`cd: not a directory: ${r}\r
|
|
30
30
|
`),!0)}catch(s){const i=s instanceof Error?s.message:String(s);return b(e,`cd: ${i}\r
|
|
31
|
-
`),!0}}async function
|
|
32
|
-
`),
|
|
33
|
-
`),b(t,Se(
|
|
31
|
+
`),!0}}async function Ht(e,n){const t=p.get(e);if(!t)throw new Error("SDK session not found");const o=jt(n),r=vt(t);if(!o)return{started:!1,cwd:r.currentDirectory};if(r.runningProcess)throw new Error("A terminal command is already running for this session");const s=v(o);if(b(t,`${Se(r.currentDirectory)}${s}\r
|
|
32
|
+
`),Ce(o))return b(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
|
|
33
|
+
`),b(t,Se(r.currentDirectory)),{started:!1,cwd:r.currentDirectory};if(await zt(t,r,o))return{started:!1,cwd:r.currentDirectory};await _(t.agentId,e,"tool_using",{actionType:"bash",actionLabel:"\u7EC8\u7AEF\u547D\u4EE4",actionDetail:s},void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl});const a=Xe(o,{cwd:r.currentDirectory,shell:!0,env:Oe(t.agentId,t.workspacePath,process.env,t.config.envOverrides)});r.runningProcess=a;const c=je(),d=je(),u=t.providerId==="acode",l={agentId:t.agentId,startedAt:new Date,chunks:[],spilled:!1};let m;const f=()=>{m&&(clearTimeout(m),m=void 0)},T=()=>{f(),m=setTimeout(()=>{r.runningProcess===a&&(b(t,Ut()),a.kill())},xe)},y=(g,C=!0)=>{if(g&&(u&&l.chunks.push(g),u&&C&&T(),!(u&&l.spilled))){if(u&&Lt(l.chunks.join(""))>Le){l.spilled=!0,Ue(l).then($=>{b(t,xt($))}).catch($=>{const M=$ instanceof Error?$.message:String($);b(t,`\r
|
|
34
34
|
[ACode] \u547D\u4EE4\u8F93\u51FA\u843D\u76D8\u5931\u8D25: ${M}\r
|
|
35
|
-
`)});return}b(t,g)}};return u&&T(),a.stdout.on("data",g=>{y(
|
|
35
|
+
`)});return}b(t,g)}};return u&&T(),a.stdout.on("data",g=>{y(re(c,g))}),a.stderr.on("data",g=>{y(re(d,g))}),a.on("error",g=>{b(t,`\r
|
|
36
36
|
[Terminal Error] ${g.message}\r
|
|
37
|
-
`)}),a.on("close",(g,C)=>{f(),
|
|
37
|
+
`)}),a.on("close",(g,C)=>{f(),r.runningProcess=null,y(re(c,void 0,!0),!1),y(re(d,void 0,!0),!1),l.spilled&&Ue(l).catch($=>{const M=$ instanceof Error?$.message:String($);b(t,`\r
|
|
38
38
|
[ACode] \u547D\u4EE4\u8F93\u51FA\u6700\u7EC8\u843D\u76D8\u5931\u8D25: ${M}\r
|
|
39
39
|
`)}),g&&g!==0?b(t,`\r
|
|
40
40
|
[exit ${g}]\r
|
|
41
41
|
`):C&&b(t,`\r
|
|
42
42
|
[signal ${C}]\r
|
|
43
|
-
`),b(t,Se(
|
|
44
|
-
...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function
|
|
43
|
+
`),b(t,Se(r.currentDirectory)),_(t.agentId,e,"waiting_input",void 0,void 0,{runtimeAccessToken:t.runtimeAccessToken,schedulerBaseUrl:t.schedulerBaseUrl})}),{started:!0,cwd:r.currentDirectory}}function Oe(e,n,t,o){const r={};for(const[s,i]of Object.entries(t))i!==void 0&&(r[s]=i);if(n&&(r.AWS_WORKSPACE_PATH=String(n)),o)for(const[s,i]of Object.entries(o)){const a=s.trim();if(!a||i===void 0||i===null)continue;const c=String(i).trim();c&&(r[a]=c)}return r.AWS_AGENT_ID=String(e),r.AWS_MCP_CLAIM_LAUNCH_BINDING="true",r.AWS_RUNTIME_BRIDGE_BASE_URL=`http://127.0.0.1:${Ze()}`,String(r.ACODE_HOME||"").trim()||(r.ACODE_HOME=_e()),$e(e,nt)&&(r.AWS_LAUNCH_CONFIG_TOOLS="1"),$e(e,ot)&&(r.AWS_HIRE_TOOLS="1"),r}function Wt(e){const n=e.trim(),t=n[0],o=n[n.length-1];return(t==='"'||t==="'")&&t===o?n.slice(1,-1):n}async function Xt(e){const n=String(e);if(!Ce(n))return n;const t=Wt(n);return j.isAbsolute(t)?N.readFile(t,"utf-8"):n}function Ne(e,n){const t={};for(const r of[e?.env,n])if(r)for(const[s,i]of Object.entries(r)){const a=s.trim();if(!a||i===void 0||i===null)continue;const c=String(i).trim();c&&(t[a]=c)}const o=t.ANTHROPIC_MODEL?.trim()||t.CODEX_MODEL?.trim()||void 0;return{envOverrides:t,model:o}}async function Qt(){try{return await it().readClaudeCodeConfig()}catch(e){return console.warn(`[Runtime] Failed to read saved ClaudeCode AI config: ${e.message}`),{}}}function Vt(e){if(e==null)return;const t=(typeof e=="string"?e:JSON.stringify(e,null,2)).trim();if(t)return t.length<=Ee?t:`${t.slice(0,Ee)}
|
|
44
|
+
...\uFF08\u7ED3\u679C\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`}function Gt(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 Jt(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 Yt(e){if(e.type!=="tool_use_end")return;const n=Vt(e.data.toolResult??e.data.actionResult);if(!n)return;const t=ye(e.data.toolName,e.data.toolInput),o=e.data.actionType||t.actionType;if(o==="idle"){const r=String(e.data.rawToolName||e.data.toolName||"").toLowerCase();if((r.includes("poll_message")||r.includes("get_message"))&&!Gt(n))return}return o==="mcp"&&Jt(e)?{actionType:"mcp",actionLabel:"MCP\u8FD4\u56DE",actionDetail:e.data.actionDetail||e.data.toolName,actionId:e.data.actionId||e.data.toolUseId,actionResult:n}:{actionType:o,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:e.data.actionDetail||t.actionDetail||e.data.toolName,actionId:e.data.actionId||e.data.toolUseId,actionResult:n}}function Zt(e){if(e.type==="ai_request"){const n=e.data.model?` ${e.data.model}`:"",t=e.data.lastUserMessagePreview?`\uFF1A${e.data.lastUserMessagePreview}`:"";return`\r
|
|
45
45
|
[ACode] \u6B63\u5728\u8BF7\u6C42\u6A21\u578B${n}${t}\r
|
|
46
46
|
`}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
|
|
47
47
|
[SDK Error] ${e.data.text}\r
|
|
48
|
-
`:void 0}function
|
|
49
|
-
...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function
|
|
50
|
-
`)||"ACode \u6B63\u5728\u53D1\u9001 AI \u8BF7\u6C42",
|
|
51
|
-
`)}`:"",s=e.requestBody?`${Tt}${e.requestBody}`:"";return`${r}${o}${s}`}function un(e){return e?Object.entries(e).map(([n,t])=>`${n}: ${t}`).filter(n=>n.trim().length>0):[]}function dn(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function ln(e){for(const n of["estimatedContextTokens","contextTokens","context_tokens","contextUsedTokens","context_used_tokens"]){const t=e[n],r=Number(t);if(Number.isFinite(r)&&r>0)return r}}function mn(e,n){if(!dn(e,n)){if(e.type==="ai_request"){const t=ln(e.data);return{status:"thinking",actionInfo:{actionType:"ai_request",actionLabel:"AI\u8BF7\u6C42",actionDetail:cn(e.data),...t!==void 0?{usage:{inputTokens:t,outputTokens:0}}:{}}}}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=ye(e.data.toolName,e.data.toolInput),r=ve(e,t),o=an(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:o,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:o,actionId:e.data.actionId||e.data.toolUseId}}}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}}}}const L=new Map,ae=new Map,ce=new Map,G=new Map,fn=20,pn=500,gn=3e4;async function ue(e,n=gn,t=2){for(let r=0;r<=t;r++){const o=new AbortController;let s;try{const i=e(o.signal);i.catch(()=>{}),await Promise.race([i,new Promise((a,c)=>{s=setTimeout(()=>{o.abort(),c(new Error(`sendOutput timeout after ${n}ms`))},n)})]),s&&clearTimeout(s);return}catch(i){s&&clearTimeout(s);const a=i instanceof Error?i.message:String(i);if(r<t){const c=1e3*(r+1);h.warn(`sendOutput attempt ${r+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(d=>setTimeout(d,c));continue}h.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}function de(e,n){const t=n?`${e}:${n}`:void 0;let r,o;if(t)r=G.get(t),o=t;else{const f=[];for(const[T,y]of G)T.startsWith(e+":")&&y.buffer&&f.push(y.sourceEventType);for(const T of f)de(e,T);return}if(!r||!r.buffer)return;r.timer=null;const s=r.buffer,i=r.seq,a=r.entry,c=r.sourceEventType;r.buffer="",o&&G.delete(o);const d={sourceEventType:c,logCategory:"acode"},u={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},m=(L.get(e)??Promise.resolve()).then(()=>ue(f=>X(a.agentId,s,e,i,d,u,f)),()=>ue(f=>X(a.agentId,s,e,i,d,u,f)));L.set(e,m),m.finally(()=>{L.get(e)===m&&L.delete(e)})}function yn(e,n){const t=Gt(e);if(!t)return;n.seq+=1;const r=n.seq,o=Jt(e),s={runtimeAccessToken:n.runtimeAccessToken,schedulerBaseUrl:n.schedulerBaseUrl};if((e.type==="command_output"||e.type==="text_delta"||e.type==="thinking")&&t.length<fn){const c=`${e.sessionId}:${e.type}`;let d=G.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,l=e.type;d.timer=setTimeout(()=>de(u,l),pn)}G.set(c,d);return}de(e.sessionId);const a=(L.get(e.sessionId)??Promise.resolve()).then(()=>ue(c=>X(n.agentId,t,e.sessionId,r,o,s,c)),()=>ue(c=>X(n.agentId,t,e.sessionId,r,o,s,c)));L.set(e.sessionId,a),a.finally(()=>{L.get(e.sessionId)===a&&L.delete(e.sessionId)})}function Fe(e){return Ge(e)}let Ke=!1;function hn(){Ke||(Ve(w,In),dt(),Ke=!0)}function In(e,n){e.on("event",t=>{const r=p.get(t.sessionId);if(r){if(t.type==="tool_use_start"?mt(r.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,r.workspacePath):t.type==="tool_use_end"&<(t,{sessionId:r.sessionId,agentId:r.agentId,workspacePath:r.workspacePath,providerId:r.providerId}),console.log(`[${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==="runtime_capabilities"&&t.data.actionDetail&&(r.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=mn(t,r.currentRuntimeStatus);i&&_(r.agentId,t.sessionId,i.status,i.actionInfo,re(i.actionInfo),{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}yn(t,r);const s=Vt(t);if(s){const i={runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},a=t.timestamp?new Date(t.timestamp).getTime():void 0,c=String(t.data?.toolName||"").toLowerCase()==="browser_launch",d=t.type==="tool_use_end"&&String(t.data?.rawToolName||t.data?.toolName||"").toLowerCase().replace(/[_-]/g,"").includes("todowrite");c?(async()=>{for(let l=0;l<3;l++){if(await _(r.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)!==void 0)return;l<2&&await new Promise(f=>setTimeout(f,3e3*(l+1)))}})().catch(u=>console.warn("[Runtime] browser_launch sendStatus retry exhausted:",u)):d?(async()=>{for(let l=0;l<3;l++){if(await _(r.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)!==void 0)return;l<2&&await new Promise(f=>setTimeout(f,1e3*(l+1)))}})().catch(u=>console.warn("[Runtime] todo_write sendStatus retry exhausted:",u)):_(r.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)}}}),e.on("status-change",(t,r,o)=>{const s=p.get(t);if(s){de(t),r==="thinking"||r==="tool_using"||r==="compacting"?At(t):x(t);const i=$t(r,o);s.currentRuntimeStatus=i.status;const a=s.currentRuntimeActionDetail??"",c=a.includes("poll_message")||a.includes("get_message"),u=!(i.actionInfo?.actionType==="ai_request")&&(i.status==="thinking"||i.status==="waiting_input")&&(s.currentRuntimeActionType==="idle"||s.currentRuntimeActionType==="mcp")&&c;(i.actionInfo?.actionType||!u)&&(s.currentRuntimeActionType=i.actionInfo?.actionType,s.currentRuntimeActionLabel=i.actionInfo?.actionLabel,s.currentRuntimeActionDetail=i.actionInfo?.actionDetail,s.currentRuntimeActionInput=i.actionInfo?.actionInput),console.log(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${s.agentId}`,i.actionInfo||""),yt(t,{runtimeStatus:i.status,runtimeActionType:s.currentRuntimeActionType,runtimeActionLabel:s.currentRuntimeActionLabel,runtimeActionDetail:s.currentRuntimeActionDetail});const l=i.actionInfo?.actionType?i.actionInfo:s.currentRuntimeActionType?{actionType:s.currentRuntimeActionType,actionLabel:s.currentRuntimeActionLabel??"",actionDetail:s.currentRuntimeActionDetail,actionInput:s.currentRuntimeActionInput}:void 0;if(i.status==="compacting"){const f=(ae.get(t)??Promise.resolve()).then(async()=>{for(let y=0;y<=2;y++){if(await _(s.agentId,t,i.status,l,re(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})!==void 0)return;y<2&&(h.warn(`[${n.displayName}] compaction sendStatus attempt ${y+1} failed (HTTP), retrying in ${1e3*(y+1)}ms...`),await new Promise(C=>setTimeout(C,1e3*(y+1))))}h.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(T=>{h.warn(`[${n.displayName}] compaction status chain error:`,T)});ae.set(t,f),f.finally(()=>{ae.get(t)===f&&ae.delete(t)})}else{const m=u&&!i.actionInfo?.actionType;if(l?.actionType==="idle"||s.currentRuntimeActionType==="idle"&&u){const y=(ce.get(t)??Promise.resolve()).then(async()=>{for(let C=0;C<=2;C++){if(await _(s.agentId,t,i.status,m?void 0:l,re(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})!==void 0)return;C<2&&await new Promise(M=>setTimeout(M,1e3*(C+1)))}h.warn(`[${n.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`)}).catch(g=>{h.warn(`[${n.displayName}] idle status chain error:`,g)});ce.set(t,y),y.finally(()=>{ce.get(t)===y&&ce.delete(t)})}else _(s.agentId,t,i.status,m?void 0:l,re(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}if(i.status==="waiting_input"&&s.cachedCapabilitiesActionDetail){const m=s.cachedCapabilitiesActionDetail;s.cachedCapabilitiesActionDetail=void 0,console.log(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${s.agentId} (session stabilized to waiting_input)`),_(s.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:m},void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const r=p.get(t.sessionId);r&&(console.log(`[${n.displayName} Adapter] AskUserQuestion for agent ${r.agentId}`),ct(r.agentId,t.sessionId,Array.isArray(t.questions)?t.questions:[],{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl},t.toolCallId))}),e.on("permission-request",t=>{const r=p.get(t.sessionId);if(r){console.log(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${r.agentId}`);const o=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:o||t.toolName},void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl})}})}A.post("/start",S,async(e,n)=>{const{agentId:t,workspacePath:r,mode:o="sdk"}=e.body||{};if(!t||!r){n.status(400).json({error:"agentId and workspacePath are required"});return}const s=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||$e(Re(e))||void 0;st({agentId:String(t),workspacePath:String(r),serverUrl:e.body?.serverUrl||s,runtimeAccessToken:e.body?.runtimeAccessToken,userId:e.body?.userId,schedulerBaseUrl:s}),e.body?.runtimeFeatures!=null&&(Je(String(t),e.body.runtimeFeatures),console.log(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(Ye(String(t)))}`)),e.body?.envVars!=null&&typeof e.body.envVars=="object"&&(tt(e.body.envVars),console.log(`[Runtime] agent ${t} \u4E0B\u53D1\u9762\u677F\u73AF\u5883\u53D8\u91CF: ${Object.keys(e.body.envVars).length} \u9879 \u2192 \u684C\u9762\u5DE5\u5177\u5B50\u8FDB\u7A0B`)),e.body?.changeCacheRetentionDays!==void 0&&(nt(e.body.changeCacheRetentionDays),console.log(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),o&&o!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${o}" requested for agent ${t}; starting SDK session instead.`),await Sn(e,n)});async function Sn(e,n){const{agentId:t,workspacePath:r,command:o,autoAccept:s=!0,initialPrompt:i,systemPrompt:a,globalPrompt:c,rolePrompt:d,memory:u,mcpConfigPath:l,extraMcpServers:m,envOverrides:f,idleInputAutoCommand:T,nonInputAutoCommand:y,model:g,instanceAiConfig:C,subAgentModel:$,subAgentEffort:M,scopeKey:Te,browserAllowPrivate:ke}=e.body||{},z=It();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:C?te(C):null,perAgentModel:g??null}});let D=null;const I=String(t||"").trim(),le=String(e.body?.runtimeAccessToken||"").trim()||void 0,B=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||$e(Re(e))||void 0;B?h.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${B} (agentId=${I})`):h.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${I})`);try{if(hn(),!I){n.status(400).json({error:"agentId is required"});return}const O=je(I);if(O){n.json(await Ot(O));return}const k=await ft(I);if(k){const R=Nt(k);if(!R.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${I}, sessionId=${k.sessionId}, reason=${R.reason}`),await F(k.sessionId);else{const P=se(k.runtimeStatus,k.runtimeStatus,k.runtimeActionType);n.json({sessionId:k.sessionId,status:P,runtimeStatus:P,runtimeActionType:k.runtimeActionType,runtimeActionLabel:k.runtimeActionLabel,runtimeActionDetail:k.runtimeActionDetail,agentId:k.agentId,workspacePath:k.workspacePath,command:k.command,mode:k.mode||"sdk",pid:k.pid,reused:!0,persistedOnly:!0});return}}if(K.has(I)){n.status(409).json({error:"SDK session is already starting for this agent"});return}K.add(I);const wn=(o||"acode").toLowerCase(),E=Fe(o),ze=w.get(E);D=Qe();const He=E==="claude-code"?await Ht():null,J=Oe(E==="claude-code"?He:null,f),H=E==="acode"?g?String(g).trim():void 0:(()=>{const R=g?String(g).trim():void 0,P=J.model?String(J.model).trim():void 0;return R||P})();z.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:I,sessionId:D??void 0,details:{perAgentModel:g??null,globalModel:J.model??null,resolvedModel:H??null,providerId:E,note:E==="acode"?"adapter handles full priority":"request > global"}});const me={...J.envOverrides};H&&(me.ANTHROPIC_MODEL=H,me.CODEX_MODEL=H);let W,fe=l;if(E==="acode"){const R=C||{},P=await ot({apiOverrides:Ie(R)??void 0,agentId:I,sessionId:D??void 0,runtimeBridgeBaseUrl:B});W=P.instanceConfig.config,fe=P.perInstanceConfigPath,z.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:I,sessionId:D??void 0,details:{sanitizedApiOverrides:Ie(R)?te(Ie(R)):null,resolvedInstanceAiConfig:W?te(W):null,perInstanceConfigPath:fe,instanceConfigSources:P.instanceConfig.source??null}})}let we=a||void 0,pe,ge,Y;if(E==="acode")if(pe=typeof c=="string"&&c.trim()||void 0,ge=typeof d=="string"&&d.trim()||void 0,typeof u=="string"&&u.trim())Y=u.trim();else{const R=await wt(r,{schedulerBaseUrl:B,runtimeAccessToken:le,agentId:I});R&&(Y=R,h.info(`[startSdkSession] Auto-loaded memories for ACode agent ${I}`))}else if(typeof c=="string"&&c.trim()||typeof d=="string"&&d.trim()||typeof u=="string"&&u.trim()){const P=[c,d,u,a].filter(Z=>typeof Z=="string"&&Z.trim().length>0).map(Z=>Z.trim());we=P.length>0?P.join(`
|
|
48
|
+
`:void 0}function en(e){const n=on(e);return{sourceEventType:e.type,logCategory:"acode",...nn(e),...n?{logLevel:tn(e),logMessage:n}:{}}}function tn(e){return e.type==="error"?"error":e.type==="command_output"&&e.data.stream==="stderr"?"warn":"info"}function nn(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 on(e){if(e.type==="ai_request"){const n=e.data.model||"unknown-model",t=e.data.endpoint?` @ ${e.data.endpoint}`:"",o=typeof e.data.toolCount=="number"?`, tools=${e.data.toolCount}`:"";return`AI request started: ${n}${t}${o}`}if(e.type==="tool_use_start")return ve(e,"\u5F00\u59CB");if(e.type==="tool_use_end")return ve(e,"\u5B8C\u6210");if(e.type==="command_output")return an(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 rn=/\x1b\[[0-9;?]*[a-zA-Z]/g;function sn(e){return e.replace(rn,"")}function an(e){const n=typeof e.data.stream=="string"?e.data.stream:"mixed",t=typeof e.data.sequence=="number"?` #${e.data.sequence}`:"",o=sn(String(e.data.text||"")).replace(/\s+/g," ").trim(),r=o.length>240?`${o.slice(0,240)}...`:o;return`\u547D\u4EE4\u8F93\u51FA(${n}${t}): ${r||"(empty)"}`}function ve(e,n){const t=ye(e.data.toolName,e.data.toolInput),o=e.data.actionLabel||t.actionLabel||"\u8C03\u7528\u5DE5\u5177",r=qe(e,t);return r?`${n}${o}: ${r}`:`${n}${o}: ${e.data.actionDetail||e.data.toolName||"tool"}`}function qe(e,n){const t=e.data.toolInput;return n.actionType==="bash"?cn(t)||e.data.actionDetail||n.actionDetail:n.actionType==="read_file"||n.actionType==="edit_file"||n.actionType==="write_file"?un(t)||e.data.actionDetail||n.actionDetail:e.data.actionDetail||n.actionDetail}function cn(e){const n=Ae(e?.command,e?.cmd);if(n)return n;if(Array.isArray(e?.argv)){const t=e.argv.map(o=>String(o??"").trim()).filter(Boolean).join(" ");return t?v(t):void 0}return Ae(e?.args)}function un(e){const n=Fe(e?.paths);return n.length>0?n.length===1?n[0]:`${n.length}\u4E2A\u6587\u4EF6: ${n.join(", ")}`:Ae(e?.file_path,e?.filePath,e?.path,e?.target_file,e?.targetFile)}function Ae(...e){for(const n of e){if(typeof n=="string"&&n.trim())return v(n.trim());if(Array.isArray(n)){const t=Fe(n)[0];if(t)return t}}}function Fe(e){return Array.isArray(e)?e.map(n=>typeof n=="string"?n.trim():"").filter(Boolean).map(n=>v(n)):[]}function dn(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)}
|
|
49
|
+
...\uFF08\u8F93\u5165\u53C2\u6570\u8FC7\u957F\uFF0C\u5DF2\u622A\u65AD\uFF09`:n}catch{return}}function ln(e){const n=[e.model?`\u6A21\u578B: ${e.model}`:void 0,e.endpoint||e.requestUrl?`\u63A5\u53E3: ${e.endpoint||e.requestUrl}`:void 0,e.requestMethod?`\u65B9\u6CD5: ${e.requestMethod}`:void 0,typeof e.stream=="boolean"?`\u6D41\u5F0F: ${e.stream?"\u662F":"\u5426"}`:void 0,typeof e.messageCount=="number"?`\u4E0A\u4E0B\u6587\u6D88\u606F: ${e.messageCount}`:void 0,typeof e.toolCount=="number"?`\u53EF\u7528\u5DE5\u5177: ${e.toolCount}`:void 0,e.lastUserMessagePreview?`\u6700\u540E\u8BF7\u6C42: ${e.lastUserMessagePreview}`:void 0].filter(i=>!!i),t=mn(e.requestHeaders),o=n.join(`
|
|
50
|
+
`)||"ACode \u6B63\u5728\u53D1\u9001 AI \u8BF7\u6C42",r=t.length>0?`${Ct}${t.join(`
|
|
51
|
+
`)}`:"",s=e.requestBody?`${bt}${e.requestBody}`:"";return`${o}${r}${s}`}function mn(e){return e?Object.entries(e).map(([n,t])=>`${n}: ${t}`).filter(n=>n.trim().length>0):[]}function fn(e,n){return String(n||"").trim().toLowerCase()!=="waiting_input"?!1:e.type==="thinking"||e.type==="text_delta"}function pn(e){for(const n of["estimatedContextTokens","contextTokens","context_tokens","contextUsedTokens","context_used_tokens"]){const t=e[n],o=Number(t);if(Number.isFinite(o)&&o>0)return o}}function gn(e,n){if(!fn(e,n)){if(e.type==="ai_request"){const t=pn(e.data);return{status:"thinking",actionInfo:{actionType:"ai_request",actionLabel:"AI\u8BF7\u6C42",actionDetail:ln(e.data),...t!==void 0?{usage:{inputTokens:t,outputTokens:0}}:{}}}}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=ye(e.data.toolName,e.data.toolInput),o=qe(e,t),r=dn(e.data.toolInput);return e.data.actionType==="idle"||t.actionType==="idle"?{status:"waiting_input",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:o||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:r,actionId:e.data.actionId||e.data.toolUseId}}:{status:"tool_using",actionInfo:{actionType:e.data.actionType||t.actionType,actionLabel:e.data.actionLabel||t.actionLabel,actionDetail:o||e.data.actionDetail||t.actionDetail||e.data.toolName,actionInput:r,actionId:e.data.actionId||e.data.toolUseId}}}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}}}}const x=new Map,ae=new Map,ce=new Map,G=new Map,yn=20,hn=500,In=3e4;async function ue(e,n=In,t=2){for(let o=0;o<=t;o++){const r=new AbortController;let s;try{const i=e(r.signal);i.catch(()=>{}),await Promise.race([i,new Promise((a,c)=>{s=setTimeout(()=>{r.abort(),c(new Error(`sendOutput timeout after ${n}ms`))},n)})]),s&&clearTimeout(s);return}catch(i){s&&clearTimeout(s);const a=i instanceof Error?i.message:String(i);if(o<t){const c=1e3*(o+1);h.warn(`sendOutput attempt ${o+1}/${t+1} failed (${a}), retrying in ${c}ms...`),await new Promise(d=>setTimeout(d,c));continue}h.warn(`sendOutput failed after ${t+1} attempts (${a}), giving up to unblock serial queue`)}}}function de(e,n){const t=n?`${e}:${n}`:void 0;let o,r;if(t)o=G.get(t),r=t;else{const f=[];for(const[T,y]of G)T.startsWith(e+":")&&y.buffer&&f.push(y.sourceEventType);for(const T of f)de(e,T);return}if(!o||!o.buffer)return;o.timer=null;const s=o.buffer,i=o.seq,a=o.entry,c=o.sourceEventType;o.buffer="",r&&G.delete(r);const d={sourceEventType:c,logCategory:"acode"},u={runtimeAccessToken:a.runtimeAccessToken,schedulerBaseUrl:a.schedulerBaseUrl},m=(x.get(e)??Promise.resolve()).then(()=>ue(f=>X(a.agentId,s,e,i,d,u,f)),()=>ue(f=>X(a.agentId,s,e,i,d,u,f)));x.set(e,m),m.finally(()=>{x.get(e)===m&&x.delete(e)})}function Sn(e,n){const t=Zt(e);if(!t)return;n.seq+=1;const o=n.seq,r=en(e),s={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=G.get(c);if(d||(d={buffer:"",seq:0,timer:null,entry:n,sourceEventType:e.type}),d.buffer+=t,d.seq=o,d.entry=n,!d.timer){const u=e.sessionId,l=e.type;d.timer=setTimeout(()=>de(u,l),hn)}G.set(c,d);return}de(e.sessionId);const a=(x.get(e.sessionId)??Promise.resolve()).then(()=>ue(c=>X(n.agentId,t,e.sessionId,o,r,s,c)),()=>ue(c=>X(n.agentId,t,e.sessionId,o,r,s,c)));x.set(e.sessionId,a),a.finally(()=>{x.get(e.sessionId)===a&&x.delete(e.sessionId)})}function Ke(e){return Ye(e)}let ze=!1;function An(){ze||(Je(w,Tn),ft(),ze=!0)}function Tn(e,n){e.on("event",t=>{const o=p.get(t.sessionId);if(o){if(t.type==="tool_use_start"?gt(o.sessionId,t.data.toolUseId||t.data.actionId,t.data.toolInput,t.data.toolName,o.workspacePath):t.type==="tool_use_end"&&pt(t,{sessionId:o.sessionId,agentId:o.agentId,workspacePath:o.workspacePath,providerId:o.providerId}),console.log(`[${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==="runtime_capabilities"&&t.data.actionDetail&&(o.cachedCapabilitiesActionDetail=t.data.actionDetail);const i=gn(t,o.currentRuntimeStatus);i&&_(o.agentId,t.sessionId,i.status,i.actionInfo,oe(i.actionInfo),{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl},t.timestamp?new Date(t.timestamp).getTime():void 0,t.type)}Sn(t,o);const s=Yt(t);if(s){const i={runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl},a=t.timestamp?new Date(t.timestamp).getTime():void 0,c=String(t.data?.toolName||"").toLowerCase()==="browser_launch",d=t.type==="tool_use_end"&&String(t.data?.rawToolName||t.data?.toolName||"").toLowerCase().replace(/[_-]/g,"").includes("todowrite");c?(async()=>{for(let l=0;l<3;l++){if(await _(o.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)!==void 0)return;l<2&&await new Promise(f=>setTimeout(f,3e3*(l+1)))}})().catch(u=>console.warn("[Runtime] browser_launch sendStatus retry exhausted:",u)):d?(async()=>{for(let l=0;l<3;l++){if(await _(o.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)!==void 0)return;l<2&&await new Promise(f=>setTimeout(f,1e3*(l+1)))}})().catch(u=>console.warn("[Runtime] todo_write sendStatus retry exhausted:",u)):_(o.agentId,t.sessionId,"tool_result",s,void 0,i,a,t.type)}}}),e.on("status-change",(t,o,r)=>{const s=p.get(t);if(s){de(t),o==="thinking"||o==="tool_using"||o==="compacting"?wt(t):L(t);const i=Pt(o,r);s.currentRuntimeStatus=i.status;const a=s.currentRuntimeActionDetail??"",c=a.includes("poll_message")||a.includes("get_message"),u=!(i.actionInfo?.actionType==="ai_request")&&(i.status==="thinking"||i.status==="waiting_input")&&(s.currentRuntimeActionType==="idle"||s.currentRuntimeActionType==="mcp")&&c;(i.actionInfo?.actionType||!u)&&(s.currentRuntimeActionType=i.actionInfo?.actionType,s.currentRuntimeActionLabel=i.actionInfo?.actionLabel,s.currentRuntimeActionDetail=i.actionInfo?.actionDetail,s.currentRuntimeActionInput=i.actionInfo?.actionInput),console.log(`[${n.displayName} Adapter] Status changed: ${i.status} for agent ${s.agentId}`,i.actionInfo||""),St(t,{runtimeStatus:i.status,runtimeActionType:s.currentRuntimeActionType,runtimeActionLabel:s.currentRuntimeActionLabel,runtimeActionDetail:s.currentRuntimeActionDetail});const l=i.actionInfo?.actionType?i.actionInfo:s.currentRuntimeActionType?{actionType:s.currentRuntimeActionType,actionLabel:s.currentRuntimeActionLabel??"",actionDetail:s.currentRuntimeActionDetail,actionInput:s.currentRuntimeActionInput}:void 0;if(i.status==="compacting"){const f=(ae.get(t)??Promise.resolve()).then(async()=>{for(let y=0;y<=2;y++){if(await _(s.agentId,t,i.status,l,oe(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})!==void 0)return;y<2&&(h.warn(`[${n.displayName}] compaction sendStatus attempt ${y+1} failed (HTTP), retrying in ${1e3*(y+1)}ms...`),await new Promise(C=>setTimeout(C,1e3*(y+1))))}h.warn(`[${n.displayName}] compaction sendStatus failed after 3 attempts, event may be lost`)}).catch(T=>{h.warn(`[${n.displayName}] compaction status chain error:`,T)});ae.set(t,f),f.finally(()=>{ae.get(t)===f&&ae.delete(t)})}else{const m=u&&!i.actionInfo?.actionType;if(l?.actionType==="idle"||s.currentRuntimeActionType==="idle"&&u){const y=(ce.get(t)??Promise.resolve()).then(async()=>{for(let C=0;C<=2;C++){if(await _(s.agentId,t,i.status,m?void 0:l,oe(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})!==void 0)return;C<2&&await new Promise(M=>setTimeout(M,1e3*(C+1)))}h.warn(`[${n.displayName}] idle tool sendStatus failed after 3 attempts, status may be stale (frontend will fall back to timeline tool_use event)`)}).catch(g=>{h.warn(`[${n.displayName}] idle status chain error:`,g)});ce.set(t,y),y.finally(()=>{ce.get(t)===y&&ce.delete(t)})}else _(s.agentId,t,i.status,m?void 0:l,oe(i.actionInfo),{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}if(i.status==="waiting_input"&&s.cachedCapabilitiesActionDetail){const m=s.cachedCapabilitiesActionDetail;s.cachedCapabilitiesActionDetail=void 0,console.log(`[${n.displayName} Adapter] Re-sending cached runtime_capabilities for agent ${s.agentId} (session stabilized to waiting_input)`),_(s.agentId,t,"waiting_input",{actionType:"runtime_capabilities",actionLabel:"\u8FD0\u884C\u65F6\u80FD\u529B",actionDetail:m},void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}}}),e.on("ask-user-question",t=>{const o=p.get(t.sessionId);o&&(console.log(`[${n.displayName} Adapter] AskUserQuestion for agent ${o.agentId}`),lt(o.agentId,t.sessionId,Array.isArray(t.questions)?t.questions:[],{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl},t.toolCallId))}),e.on("permission-request",t=>{const o=p.get(t.sessionId);if(o){console.log(`[${n.displayName} Adapter] Permission request: ${t.toolName} for agent ${o.agentId}`);const r=t.toolInput?v(JSON.stringify(t.toolInput).slice(0,400)):void 0;_(o.agentId,t.sessionId,"waiting_input",{actionType:"other",actionLabel:"\u6743\u9650\u786E\u8BA4",actionDetail:r||t.toolName},void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl})}})}A.post("/start",S,async(e,n)=>{const{agentId:t,workspacePath:o,mode:r="sdk"}=e.body||{};if(!t||!o){n.status(400).json({error:"agentId and workspacePath are required"});return}const s=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||De(Pe(e))||void 0;ct({agentId:String(t),workspacePath:String(o),serverUrl:e.body?.serverUrl||s,runtimeAccessToken:e.body?.runtimeAccessToken,userId:e.body?.userId,schedulerBaseUrl:s}),e.body?.runtimeFeatures!=null&&(et(String(t),e.body.runtimeFeatures),console.log(`[Runtime] agent ${t} \u542F\u52A8\u4E0B\u53D1\u80FD\u529B\u5F00\u5173: ${JSON.stringify(tt(String(t)))}`)),e.body?.envVars!=null&&typeof e.body.envVars=="object"&&(rt(e.body.envVars),console.log(`[Runtime] agent ${t} \u4E0B\u53D1\u9762\u677F\u73AF\u5883\u53D8\u91CF: ${Object.keys(e.body.envVars).length} \u9879 \u2192 \u684C\u9762\u5DE5\u5177\u5B50\u8FDB\u7A0B`)),e.body?.changeCacheRetentionDays!==void 0&&(st(e.body.changeCacheRetentionDays),console.log(`[Runtime] agent ${t} \u4E0B\u53D1\u53D8\u66F4\u7F13\u5B58\u4FDD\u7559\u5929\u6570: ${e.body.changeCacheRetentionDays??"\u4E0D\u6E05\u7406"}`)),r&&r!=="sdk"&&console.warn(`[Runtime] Unsupported runtime mode "${r}" requested for agent ${t}; starting SDK session instead.`),await kn(e,n)});async function kn(e,n){const{agentId:t,workspacePath:o,command:r,autoAccept:s=!0,initialPrompt:i,systemPrompt:a,globalPrompt:c,rolePrompt:d,memory:u,mcpConfigPath:l,extraMcpServers:m,envOverrides:f,idleInputAutoCommand:T,nonInputAutoCommand:y,model:g,instanceAiConfig:C,subAgentModel:$,subAgentEffort:M,scopeKey:Te,browserAllowPrivate:ke}=e.body||{},z=Tt();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:C?te(C):null,perAgentModel:g??null}});let D=null;const I=String(t||"").trim(),le=String(e.body?.runtimeAccessToken||"").trim()||void 0,B=String(e.body?.schedulerBaseUrl||"").trim()||String(e.header("x-bridge-tunnel-source")||"").trim()||De(Pe(e))||void 0;B?h.info(`[startSdkSession] \u56DE\u8C03\u76EE\u6807 server: ${B} (agentId=${I})`):h.warn(`[startSdkSession] \u672A\u89E3\u6790\u5230 schedulerBaseUrl\uFF0C\u5C06\u56DE\u9000\u5230\u9ED8\u8BA4\u5730\u5740 (agentId=${I})`);try{if(An(),!I){n.status(400).json({error:"agentId is required"});return}const O=Be(I);if(O){n.json(await qt(O));return}const k=await yt(I);if(k){const R=Ft(k);if(!R.reusable)console.warn(`[Runtime] Ignoring stale persisted SDK session for agentId=${I}, sessionId=${k.sessionId}, reason=${R.reason}`),await F(k.sessionId);else{const P=se(k.runtimeStatus,k.runtimeStatus,k.runtimeActionType);n.json({sessionId:k.sessionId,status:P,runtimeStatus:P,runtimeActionType:k.runtimeActionType,runtimeActionLabel:k.runtimeActionLabel,runtimeActionDetail:k.runtimeActionDetail,agentId:k.agentId,workspacePath:k.workspacePath,command:k.command,mode:k.mode||"sdk",pid:k.pid,reused:!0,persistedOnly:!0});return}}if(K.has(I)){n.status(409).json({error:"SDK session is already starting for this agent"});return}K.add(I);const _n=(r||"acode").toLowerCase(),E=Ke(r),He=w.get(E);D=Ge();const We=E==="claude-code"?await Qt():null,J=Ne(E==="claude-code"?We:null,f),H=E==="acode"?g?String(g).trim():void 0:(()=>{const R=g?String(g).trim():void 0,P=J.model?String(J.model).trim():void 0;return R||P})();z.log({level:"info",category:"resolve",message:"\u6A21\u578B\u89E3\u6790\u7ED3\u679C",source:"bridge",agentId:I,sessionId:D??void 0,details:{perAgentModel:g??null,globalModel:J.model??null,resolvedModel:H??null,providerId:E,note:E==="acode"?"adapter handles full priority":"request > global"}});const me={...J.envOverrides};H&&(me.ANTHROPIC_MODEL=H,me.CODEX_MODEL=H);let W,fe=l;if(E==="acode"){const R=C||{},P=await at({apiOverrides:Ie(R)??void 0,agentId:I,sessionId:D??void 0,runtimeBridgeBaseUrl:B});W=P.instanceConfig.config,fe=P.perInstanceConfigPath,z.log({level:"info",category:"apply",message:"prepareAcodeInstanceConfig \u5B8C\u6210",source:"bridge",agentId:I,sessionId:D??void 0,details:{sanitizedApiOverrides:Ie(R)?te(Ie(R)):null,resolvedInstanceAiConfig:W?te(W):null,perInstanceConfigPath:fe,instanceConfigSources:P.instanceConfig.source??null}})}let we=a||void 0,pe,ge,Y;if(E==="acode")if(pe=typeof c=="string"&&c.trim()||void 0,ge=typeof d=="string"&&d.trim()||void 0,typeof u=="string"&&u.trim())Y=u.trim();else{const R=await _t(o,{schedulerBaseUrl:B,runtimeAccessToken:le,agentId:I});R&&(Y=R,h.info(`[startSdkSession] Auto-loaded memories for ACode agent ${I}`))}else if(typeof c=="string"&&c.trim()||typeof d=="string"&&d.trim()||typeof u=="string"&&u.trim()){const P=[c,d,u,a].filter(Z=>typeof Z=="string"&&Z.trim().length>0).map(Z=>Z.trim());we=P.length>0?P.join(`
|
|
52
52
|
|
|
53
|
-
`):void 0}const U={command:o||"acode",workingDirectory:r,agentId:I,...Te?{scopeKey:Te}:{},...typeof ke=="boolean"?{browserAllowPrivate:ke}:{},autoAccept:!!s,initialPrompt:i,systemPrompt:we,...pe!==void 0?{globalPrompt:pe}:{},...ge!==void 0?{rolePrompt:ge}:{},...Y!==void 0?{memory:Y}:{},model:H,mcpConfigPath:fe,...W?{instanceAiConfig:W}:{},...typeof $=="string"&&$.trim()?{subAgentModel:$.trim()}:{},...typeof M=="string"&&M.trim()?{subAgentEffort:M.trim()}:{},extraMcpServers:m||{},envOverrides:Be(String(t),String(r),process.env,me)};z.log({level:"info",category:"launch",message:"\u4F20\u9012\u7ED9 Adapter \u7684\u5B8C\u6574 AdapterSessionConfig",source:"bridge",agentId:I,sessionId:D,details:{adapterModel:U.model??null,adapterInstanceAiConfig:U.instanceAiConfig?te(U.instanceAiConfig):null,adapterMcpConfigPath:U.mcpConfigPath??null}}),await z.flush(),p.set(D,{agentId:I,workspacePath:r,sessionId:D,config:U,providerId:E,seq:0,runtimeAccessToken:le,schedulerBaseUrl:B}),n.json({sessionId:D,status:"starting",runtimeStatus:"starting",agentId:I,workspacePath:r,command:U.command,mode:"sdk"}),An({sessionId:D,agentId:I,config:U,adapter:ze,providerId:E,idleInputAutoCommand:T,nonInputAutoCommand:y,runtimeAccessToken:le,requestedSchedulerBaseUrl:B})}catch(O){if(D&&(x(D),p.delete(D),q(D)),I&&K.delete(I),!n.headersSent){const k=O instanceof Error?O.message:String(O);n.status(500).json({error:`Failed to start SDK session: ${k}`})}}}async function An(e){const{sessionId:n,agentId:t,config:r,adapter:o,providerId:s,idleInputAutoCommand:i,nonInputAutoCommand:a,runtimeAccessToken:c,requestedSchedulerBaseUrl:d}=e;try{await o.startSession(n,r),(i||a)&&o.setIdleCommands?.(n,{idleInputCommand:i||"",nonInputCommand:a||""});let u;if(Ct(s))try{if(await new Promise(m=>setTimeout(m,500)),u=o.getSessionPid?.(n),!u){const f=(await it()).find(T=>T.agentId===t||T.cwd===r.workingDirectory||T.command.includes(r.workingDirectory));f&&(u=f.pid,console.log(`[Runtime] Found SDK process PID: ${u} for agentId=${t}`))}}catch(m){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,m)}const l=se(o.getSessionStatus(n),p.get(n)?.currentRuntimeStatus,p.get(n)?.currentRuntimeActionType);await ht({sessionId:n,agentId:t,workspacePath:r.workingDirectory,command:r.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:l,mode:"sdk",pid:u,providerSessionId:o.getProviderSessionId(n)}),u&&await he().startProcess({agentId:t,sessionId:n,pid:u,mode:"sdk",workspacePath:r.workingDirectory,command:r.command}),await Tn({agentId:t,sessionId:n,sdkPid:u,status:l,schedulerBaseUrl:d,runtimeAccessToken:c})}catch(u){x(n),p.delete(n),q(n),await F(n);const l=u instanceof Error?u.message:String(u);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${l}`),await kn({agentId:t,sessionId:n,schedulerBaseUrl:d,runtimeAccessToken:c,errorMessage:l})}finally{K.delete(t)}}async function Tn(e){const{agentId:n,sessionId:t,sdkPid:r,status:o,schedulerBaseUrl:s,runtimeAccessToken:i}=e;if(!s||!i){h.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${s.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Ce.post(a,{agentId:n,sessionId:t,status:o,pid:r},{headers:{"X-Runtime-Token":i,"Content-Type":"application/json"},timeout:5e3}),h.debug(`[Runtime] Notified server session ready: agentId=${n}, sessionId=${t}, status=${o}`)}catch(c){const d=c instanceof Error?c.message:String(c);h.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${d}`)}}async function kn(e){const{agentId:n,sessionId:t,schedulerBaseUrl:r,runtimeAccessToken:o}=e;if(!r||!o)return;const s=`${r.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await Ce.post(s,{agentId:n,sessionId:t,status:"stopped"},{headers:{"X-Runtime-Token":o,"Content-Type":"application/json"},timeout:5e3}),h.debug(`[Runtime] Notified server session failed: agentId=${n}, sessionId=${t}`)}catch(i){const a=i instanceof Error?i.message:String(i);h.warn(`[Runtime] Failed to notify server session failed: agentId=${n}, error=${a}`)}}A.post("/sdk/message",S,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 o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code";await w.get(s).sendMessage(t,r),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),A.post("/sdk/answer",S,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 o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code",i=w.get(s);i.sendQuestionAnswer&&await i.sendQuestionAnswer(t,r),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),A.post("/sdk/confirm",S,async(e,n)=>{const{sessionId:t,accept:r}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const s=o.providerId||"claude-code";await w.get(s).sendConfirmation(t,!!r),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),A.post("/sdk/abort",S,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code";await w.get(o).abortCurrentTurn(t),n.json({ok:!0})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),A.post("/sdk/stop",S,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.json({ok:!0,status:"stopped"});return}try{const o=r.providerId||"claude-code",s=w.get(o);s.abortCurrentTurn(t).catch(()=>{}),await s.terminateSession(t),x(t),p.delete(t),q(t),ie(t),await F(t),await he().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(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),A.get("/sdk/status/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code",s=w.get(o),i=s.getSessionStatus(t),a=s.getConversation(t);n.json({sessionId:t,status:i,agentId:r.agentId,workspacePath:r.workspacePath,messageCount:a.length})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),A.get("/sdk/capabilities/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code",i=w.get(o).getCapabilities?.(t)??null;n.json({ok:!0,sessionId:t,agentId:r.agentId,capabilities:i,fetchedAt:Date.now()})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),A.get("/sdk/pending-questions/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const o=r.providerId||"claude-code",i=w.get(o).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(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),A.post("/command",S,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 o=await Ft(String(t),r);n.json({ok:!0,mode:"terminal",...o})}catch(o){const s=o instanceof Error?o.message:String(o);n.status(500).json({error:s})}}),A.post("/input",S,async(e,n)=>{const{sessionId:t,input:r,mode:o}=e.body||{};if(!t||r===void 0||r===null){n.status(400).json({error:"sessionId and input are required"});return}const s=p.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const i=s.providerId||"claude-code",a=w.get(i);if(o==="shortcut"){if(!a.sendShortcutInput){n.status(400).json({error:"shortcut input is not supported by this SDK provider"});return}await a.sendShortcutInput(t,String(r)),n.json({ok:!0,mode:"shortcut"});return}await a.sendMessage(t,await zt(r)),n.json({ok:!0,mode:"sdk"})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),A.post("/update-auto-commands",S,async(e,n)=>{const{agentId:t,idleInputAutoCommand:r="",nonInputAutoCommand:o=""}=e.body||{},s=String(t||"").trim();if(!s){n.status(400).json({error:"agentId is required"});return}const i=[...p.values()].find(c=>c.agentId===s),a={idleInputCommand:String(r||""),nonInputCommand:String(o||"")};try{let c=!1;i&&(w.get(i.providerId||"claude-code").setIdleCommands?.(i.sessionId,a),c=!0);const d=await gt(s,{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})}}),A.post("/resize",S,(e,n)=>{const{sessionId:t,cols:r,rows:o}=e.body||{};if(!t||!r||!o){n.status(400).json({error:"sessionId, cols, rows are required"});return}if(!p.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(o)})}),A.post("/reset-context",S,async(e,n)=>{const{sessionId:t,reason:r}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}const s=o.providerId||"claude-code",i=w.get(s),a=i.resetContext?.bind(i),c=bt(s,!!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=se(i.getSessionStatus(String(t)),o.currentRuntimeStatus,o.currentRuntimeActionType);n.json({ok:!0,contextReset:!0,sessionId:t,status:d,runtimeStatus:d,agentId:o.agentId,mode:"sdk",providerId:s,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})}}),A.post("/stop",S,async(e,n)=>{const{sessionId:t}=e.body||{},r=_t(e.body);if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){await F(t),n.json({ok:!0,status:"stopped",mode:"none",statusNotified:!1,reason:r.reason});return}const s=o.agentId;try{console.log(`[Runtime] Stopping SDK session ${t}; suppressStatus=${!r.statusNotified}, reason=${r.reason||"unspecified"}`);const i=o.providerId||"claude-code",a=w.get(i);a.abortCurrentTurn(t).catch(()=>{}),await a.terminateSession(t),x(t),p.delete(t),q(t),ie(t),await F(t),await he().removeProcess(s),r.statusNotified?await _(s,null,"stopped",void 0,void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl}):console.log(`[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})}}),A.post("/stop-all",S,async(e,n)=>{const t=[],r=[];for(const[o,s]of p.entries())try{const i=s.providerId||"claude-code",a=w.get(i);a.abortCurrentTurn(o).catch(()=>{}),await a.terminateSession(o),x(o),p.delete(o),q(o),ie(o),t.push(o),await _(s.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}catch(i){const a=i instanceof Error?i.message:String(i);r.push(`SDK ${o}: ${a}`)}try{await pt([]),console.log("[Runtime] \u5DF2\u6E05\u7A7A\u6240\u6709\u6301\u4E45\u5316\u4F1A\u8BDD")}catch(o){const s=o instanceof Error?o.message:String(o);r.push(`Persistence: ${s}`)}n.json({ok:!0,stopped:{sdk:t.length},errors:r.length>0?r:void 0})}),A.get("/events/last/:n",S,(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=De.getLastN(t);n.json({ok:!0,count:r.length,entries:r})}),A.get("/events/since/:index",S,(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=De.getSinceIndex(t);n.json({ok:!0,entries:r.entries,nextIndex:r.nextIndex,oldestIndex:r.oldestIndex,dataLoss:r.oldestIndex>t+1})}),A.get("/events/push-stats",S,(e,n)=>{const t=ut();n.json({ok:!0,count:t.length,agents:t})});export{Rt as buildAcodeCommandOutputPath,Oe as buildClaudeCodeLaunchConfig,Be as buildRuntimeEnv,Jt as buildSdkOutputMetadata,Vt as buildToolResultTimelineActionInfo,Vn as cleanupSdkSessionByAgentId,Pt as countTerminalOutputLines,Ue as createTerminalOutputDecoder,oe as decodeTerminalOutputChunk,Nt as evaluatePersistedSessionReuse,Mt as formatCommandInactivityTimeoutNotice,Et as formatCommandOutputSpilloverNotice,Gt as formatSdkOutputEvent,Se as formatTerminalPrompt,xt as normalizeTerminalCommandInput,_t as parseRuntimeStopOptions,jt as parseTerminalDirectoryChangeTarget,ue as raceSendOutputWithRetry,bt as resolveRuntimeContextResetSupport,mn as resolveRuntimeStatusFromProviderEvent,zt as resolveSdkInputMessage,Fe as resolveSdkProviderId,se as resolveSdkSessionDisplayStatus,$t as resolveStatusChangeRuntimeState,re as resolveStatusChangeUsage,Lt as resolveTerminalOutputEncoding,p as sdkSessions,Ct as shouldProbeSdkProcessPid,A as terminalRouter};
|
|
53
|
+
`):void 0}const U={command:r||"acode",workingDirectory:o,agentId:I,...Te?{scopeKey:Te}:{},...typeof ke=="boolean"?{browserAllowPrivate:ke}:{},autoAccept:!!s,initialPrompt:i,systemPrompt:we,...pe!==void 0?{globalPrompt:pe}:{},...ge!==void 0?{rolePrompt:ge}:{},...Y!==void 0?{memory:Y}:{},model:H,mcpConfigPath:fe,...W?{instanceAiConfig:W}:{},...typeof $=="string"&&$.trim()?{subAgentModel:$.trim()}:{},...typeof M=="string"&&M.trim()?{subAgentEffort:M.trim()}:{},extraMcpServers:m||{},envOverrides:Oe(String(t),String(o),process.env,me)};z.log({level:"info",category:"launch",message:"\u4F20\u9012\u7ED9 Adapter \u7684\u5B8C\u6574 AdapterSessionConfig",source:"bridge",agentId:I,sessionId:D,details:{adapterModel:U.model??null,adapterInstanceAiConfig:U.instanceAiConfig?te(U.instanceAiConfig):null,adapterMcpConfigPath:U.mcpConfigPath??null}}),await z.flush(),p.set(D,{agentId:I,workspacePath:o,sessionId:D,config:U,providerId:E,seq:0,runtimeAccessToken:le,schedulerBaseUrl:B}),n.json({sessionId:D,status:"starting",runtimeStatus:"starting",agentId:I,workspacePath:o,command:U.command,mode:"sdk"}),wn({sessionId:D,agentId:I,config:U,adapter:He,providerId:E,idleInputAutoCommand:T,nonInputAutoCommand:y,runtimeAccessToken:le,requestedSchedulerBaseUrl:B})}catch(O){if(D&&(L(D),p.delete(D),q(D)),I&&K.delete(I),!n.headersSent){const k=O instanceof Error?O.message:String(O);n.status(500).json({error:`Failed to start SDK session: ${k}`})}}}async function wn(e){const{sessionId:n,agentId:t,config:o,adapter:r,providerId:s,idleInputAutoCommand:i,nonInputAutoCommand:a,runtimeAccessToken:c,requestedSchedulerBaseUrl:d}=e;try{await r.startSession(n,o),(i||a)&&r.setIdleCommands?.(n,{idleInputCommand:i||"",nonInputCommand:a||""});let u;if(Dt(s))try{if(await new Promise(m=>setTimeout(m,500)),u=r.getSessionPid?.(n),!u){const f=(await ut()).find(T=>T.agentId===t||T.cwd===o.workingDirectory||T.command.includes(o.workingDirectory));f&&(u=f.pid,console.log(`[Runtime] Found SDK process PID: ${u} for agentId=${t}`))}}catch(m){console.warn(`[Runtime] Failed to get SDK PID for agentId=${t}:`,m)}const l=se(r.getSessionStatus(n),p.get(n)?.currentRuntimeStatus,p.get(n)?.currentRuntimeActionType);await At({sessionId:n,agentId:t,workspacePath:o.workingDirectory,command:o.command,startedAt:new Date().toISOString(),status:"running",runtimeStatus:l,mode:"sdk",pid:u,providerSessionId:r.getProviderSessionId(n)}),u&&await he().startProcess({agentId:t,sessionId:n,pid:u,mode:"sdk",workspacePath:o.workingDirectory,command:o.command}),await bn({agentId:t,sessionId:n,sdkPid:u,status:l,schedulerBaseUrl:d,runtimeAccessToken:c})}catch(u){L(n),p.delete(n),q(n),await F(n);const l=u instanceof Error?u.message:String(u);console.error(`[Runtime] Background SDK session startup failed for agentId=${t}: ${l}`),await Cn({agentId:t,sessionId:n,schedulerBaseUrl:d,runtimeAccessToken:c,errorMessage:l})}finally{K.delete(t)}}async function bn(e){const{agentId:n,sessionId:t,sdkPid:o,status:r,schedulerBaseUrl:s,runtimeAccessToken:i}=e;if(!s||!i){h.debug(`[Runtime] notifyServerSessionReady skipped: missing schedulerBaseUrl or runtimeAccessToken for agentId=${n}`);return}const a=`${s.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await be.post(a,{agentId:n,sessionId:t,status:r,pid:o},{headers:{"X-Runtime-Token":i,"Content-Type":"application/json"},timeout:5e3}),h.debug(`[Runtime] Notified server session ready: agentId=${n}, sessionId=${t}, status=${r}`)}catch(c){const d=c instanceof Error?c.message:String(c);h.warn(`[Runtime] Failed to notify server session ready: agentId=${n}, error=${d}`)}}async function Cn(e){const{agentId:n,sessionId:t,schedulerBaseUrl:o,runtimeAccessToken:r}=e;if(!o||!r)return;const s=`${o.replace(/\/+$/,"")}/api/runtime/callback/status`;try{await be.post(s,{agentId:n,sessionId:t,status:"stopped"},{headers:{"X-Runtime-Token":r,"Content-Type":"application/json"},timeout:5e3}),h.debug(`[Runtime] Notified server session failed: agentId=${n}, sessionId=${t}`)}catch(i){const a=i instanceof Error?i.message:String(i);h.warn(`[Runtime] Failed to notify server session failed: agentId=${n}, error=${a}`)}}A.post("/sdk/message",S,async(e,n)=>{const{sessionId:t,message:o}=e.body||{};if(!t||!o){n.status(400).json({error:"sessionId and message are required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code";await w.get(s).sendMessage(t,o),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),A.post("/sdk/answer",S,async(e,n)=>{const{sessionId:t,answers:o}=e.body||{};if(!t||!o){n.status(400).json({error:"sessionId and answers are required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code",i=w.get(s);i.sendQuestionAnswer&&await i.sendQuestionAnswer(t,o),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),A.post("/sdk/confirm",S,async(e,n)=>{const{sessionId:t,accept:o}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}try{const s=r.providerId||"claude-code";await w.get(s).sendConfirmation(t,!!o),n.json({ok:!0})}catch(s){const i=s instanceof Error?s.message:String(s);n.status(500).json({error:i})}}),A.post("/sdk/abort",S,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const r=o.providerId||"claude-code";await w.get(r).abortCurrentTurn(t),n.json({ok:!0})}catch(r){const s=r instanceof Error?r.message:String(r);n.status(500).json({error:s})}}),A.post("/sdk/stop",S,async(e,n)=>{const{sessionId:t}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.json({ok:!0,status:"stopped"});return}try{const r=o.providerId||"claude-code",s=w.get(r);s.abortCurrentTurn(t).catch(()=>{}),await s.terminateSession(t),L(t),p.delete(t),q(t),ie(t),await F(t),await he().removeProcess(o.agentId),await _(o.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:o.runtimeAccessToken,schedulerBaseUrl:o.schedulerBaseUrl}),n.json({ok:!0,status:"stopped"})}catch(r){const s=r instanceof Error?r.message:String(r);n.status(500).json({error:s})}}),A.get("/sdk/status/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const r=o.providerId||"claude-code",s=w.get(r),i=s.getSessionStatus(t),a=s.getConversation(t);n.json({sessionId:t,status:i,agentId:o.agentId,workspacePath:o.workspacePath,messageCount:a.length})}catch(r){const s=r instanceof Error?r.message:String(r);n.status(500).json({error:s})}}),A.get("/sdk/capabilities/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const r=o.providerId||"claude-code",i=w.get(r).getCapabilities?.(t)??null;n.json({ok:!0,sessionId:t,agentId:o.agentId,capabilities:i,fetchedAt:Date.now()})}catch(r){const s=r instanceof Error?r.message:String(r);n.status(500).json({error:s})}}),A.get("/sdk/pending-questions/:sessionId",S,(e,n)=>{const t=e.params.sessionId;if(!t){n.status(400).json({error:"sessionId is required"});return}const o=p.get(t);if(!o){n.status(404).json({error:"SDK session not found"});return}try{const r=o.providerId||"claude-code",i=w.get(r).getPendingQuestion?.(t)??null;n.json({ok:!0,sessionId:t,agentId:o.agentId,pendingQuestion:i?{toolCallId:i.toolCallId,questions:i.questions}:null,fetchedAt:Date.now()})}catch(r){const s=r instanceof Error?r.message:String(r);n.status(500).json({error:s})}}),A.post("/command",S,async(e,n)=>{const{sessionId:t,command:o}=e.body||{};if(!t||o===void 0||o===null){n.status(400).json({error:"sessionId and command are required"});return}try{const r=await Ht(String(t),o);n.json({ok:!0,mode:"terminal",...r})}catch(r){const s=r instanceof Error?r.message:String(r);n.status(500).json({error:s})}}),A.post("/input",S,async(e,n)=>{const{sessionId:t,input:o,mode:r}=e.body||{};if(!t||o===void 0||o===null){n.status(400).json({error:"sessionId and input are required"});return}const s=p.get(t);if(!s){n.status(404).json({error:"SDK session not found"});return}try{const i=s.providerId||"claude-code",a=w.get(i);if(r==="shortcut"){if(!a.sendShortcutInput){n.status(400).json({error:"shortcut input is not supported by this SDK provider"});return}await a.sendShortcutInput(t,String(o)),n.json({ok:!0,mode:"shortcut"});return}await a.sendMessage(t,await Xt(o)),n.json({ok:!0,mode:"sdk"})}catch(i){const a=i instanceof Error?i.message:String(i);n.status(500).json({error:a})}}),A.post("/update-auto-commands",S,async(e,n)=>{const{agentId:t,idleInputAutoCommand:o="",nonInputAutoCommand:r=""}=e.body||{},s=String(t||"").trim();if(!s){n.status(400).json({error:"agentId is required"});return}const i=[...p.values()].find(c=>c.agentId===s),a={idleInputCommand:String(o||""),nonInputCommand:String(r||"")};try{let c=!1;i&&(w.get(i.providerId||"claude-code").setIdleCommands?.(i.sessionId,a),c=!0);const d=await It(s,{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})}}),A.post("/resize",S,(e,n)=>{const{sessionId:t,cols:o,rows:r}=e.body||{};if(!t||!o||!r){n.status(400).json({error:"sessionId, cols, rows are required"});return}if(!p.has(t)){n.status(404).json({error:"SDK session not found"});return}n.json({ok:!0,mode:"sdk",noop:!0,cols:Number(o),rows:Number(r)})}),A.post("/reset-context",S,async(e,n)=>{const{sessionId:t,reason:o}=e.body||{};if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){n.status(404).json({error:"SDK session not found"});return}const s=r.providerId||"claude-code",i=w.get(s),a=i.resetContext?.bind(i),c=$t(s,!!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=se(i.getSessionStatus(String(t)),r.currentRuntimeStatus,r.currentRuntimeActionType);n.json({ok:!0,contextReset:!0,sessionId:t,status:d,runtimeStatus:d,agentId:r.agentId,mode:"sdk",providerId:s,reason:typeof o=="string"&&o.trim()?o.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})}}),A.post("/stop",S,async(e,n)=>{const{sessionId:t}=e.body||{},o=Rt(e.body);if(!t){n.status(400).json({error:"sessionId is required"});return}const r=p.get(t);if(!r){await F(t),n.json({ok:!0,status:"stopped",mode:"none",statusNotified:!1,reason:o.reason});return}const s=r.agentId;try{console.log(`[Runtime] Stopping SDK session ${t}; suppressStatus=${!o.statusNotified}, reason=${o.reason||"unspecified"}`);const i=r.providerId||"claude-code",a=w.get(i);a.abortCurrentTurn(t).catch(()=>{}),await a.terminateSession(t),L(t),p.delete(t),q(t),ie(t),await F(t),await he().removeProcess(s),o.statusNotified?await _(s,null,"stopped",void 0,void 0,{runtimeAccessToken:r.runtimeAccessToken,schedulerBaseUrl:r.schedulerBaseUrl}):console.log(`[Runtime] Stopped status notification suppressed for SDK session ${t}; reason=${o.reason||"unspecified"}`),n.json({ok:!0,status:"stopped",mode:"sdk",statusNotified:o.statusNotified,reason:o.reason})}catch(i){const a=i instanceof Error?i.message:String(i);console.error(`[Runtime] Failed to terminate SDK session ${t}:`,a),n.status(500).json({ok:!1,status:"stop_failed",mode:"sdk",error:a})}}),A.post("/stop-all",S,async(e,n)=>{const t=[],o=[];for(const[r,s]of p.entries())try{const i=s.providerId||"claude-code",a=w.get(i);a.abortCurrentTurn(r).catch(()=>{}),await a.terminateSession(r),L(r),p.delete(r),q(r),ie(r),t.push(r),await _(s.agentId,null,"stopped",void 0,void 0,{runtimeAccessToken:s.runtimeAccessToken,schedulerBaseUrl:s.schedulerBaseUrl})}catch(i){const a=i instanceof Error?i.message:String(i);o.push(`SDK ${r}: ${a}`)}try{await ht([]),console.log("[Runtime] \u5DF2\u6E05\u7A7A\u6240\u6709\u6301\u4E45\u5316\u4F1A\u8BDD")}catch(r){const s=r instanceof Error?r.message:String(r);o.push(`Persistence: ${s}`)}n.json({ok:!0,stopped:{sdk:t.length},errors:o.length>0?o:void 0})}),A.get("/events/last/:n",S,(e,n)=>{const t=parseInt(e.params.n,10);if(!Number.isFinite(t)||t<1){n.status(400).json({error:":n must be a positive integer"});return}const o=Re.getLastN(t);n.json({ok:!0,count:o.length,entries:o})}),A.get("/events/since/:index",S,(e,n)=>{const t=parseInt(e.params.index,10);if(!Number.isFinite(t)||t<0){n.status(400).json({error:":index must be a non-negative integer"});return}const o=Re.getSinceIndex(t);n.json({ok:!0,entries:o.entries,nextIndex:o.nextIndex,oldestIndex:o.oldestIndex,dataLoss:o.oldestIndex>t+1})}),A.get("/events/push-stats",S,(e,n)=>{const t=mt();n.json({ok:!0,count:t.length,agents:t})});export{Mt as buildAcodeCommandOutputPath,Ne as buildClaudeCodeLaunchConfig,Oe as buildRuntimeEnv,en as buildSdkOutputMetadata,Yt as buildToolResultTimelineActionInfo,Zn as cleanupSdkSessionByAgentId,Lt as countTerminalOutputLines,je as createTerminalOutputDecoder,re as decodeTerminalOutputChunk,Ft as evaluatePersistedSessionReuse,Ut as formatCommandInactivityTimeoutNotice,xt as formatCommandOutputSpilloverNotice,Zt as formatSdkOutputEvent,Se as formatTerminalPrompt,jt as normalizeTerminalCommandInput,Rt as parseRuntimeStopOptions,Nt as parseTerminalDirectoryChangeTarget,ue as raceSendOutputWithRetry,$t as resolveRuntimeContextResetSupport,gn as resolveRuntimeStatusFromProviderEvent,Xt as resolveSdkInputMessage,Ke as resolveSdkProviderId,se as resolveSdkSessionDisplayStatus,Pt as resolveStatusChangeRuntimeState,oe as resolveStatusChangeUsage,Bt as resolveTerminalOutputEncoding,p as sdkSessions,Dt as shouldProbeSdkProcessPid,A as terminalRouter};
|
|
54
54
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
|
|
2
|
+
import { getAutoRegisterConfigFilePath } from "../config.js";
|
|
2
3
|
|
|
3
4
|
interface AutoRegisterConfig {
|
|
4
5
|
|
|
@@ -40,7 +41,7 @@ export declare function getConfiguredConnectionKeys(): string[];
|
|
|
40
41
|
|
|
41
42
|
export declare function cancelBackgroundRegisterRetries(): void;
|
|
42
43
|
|
|
43
|
-
export
|
|
44
|
+
export { getAutoRegisterConfigFilePath };
|
|
44
45
|
|
|
45
46
|
export declare function loadConfig(): AutoRegisterConfig;
|
|
46
47
|
export declare function loadConfigs(): AutoRegisterConfig[];
|
|
@@ -82,4 +83,3 @@ export declare function bridgeRestartCleanup(): Promise<{
|
|
|
82
83
|
agentCount?: number;
|
|
83
84
|
error?: string;
|
|
84
85
|
}>;
|
|
85
|
-
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{v4 as G}from"uuid";import I from"axios";import m from"node:os";import M from"node:path";import g from"node:fs";import{logger as i}from"../utils/logger.js";import{schedulerBaseUrl as d}from"../config.js";import{runExclusiveConfigWrite as z}from"../utils/config-write-queue.js";import{clearRuntimeBinding as J,clearScopedRuntimeAccessToken as Y,getRuntimeAccessToken as E,getRuntimeBindingPublicState as w,getScopedRuntimeAccessToken as q,loadRuntimeBinding as v,normalizeSchedulerBaseUrl as p,saveRuntimeBinding as K,saveScopedRuntimeAccessToken as C}from"./runtime-binding.js";const b={enabled:!1,serverUrl:d,preferSameLanIp:!0,maxRetries:3,retryInterval:2e3};let u={registered:!1,registrations:{}},P=[];function Ae(){return[...P]}const H=3e4;function W(){const e=Number(process.env.AWS_REGISTER_BACKGROUND_RETRY_INTERVAL);return Number.isFinite(e)&&e>0?e:H}const A=new Map;function L(e){const r=e.serverUrl||d,t=p(r)||r;if(A.has(t))return;const n=setTimeout(()=>{A.delete(t),V(e,t)},W());n.unref?.(),A.set(t,n)}async function V(e,r){try{const t=R().find(n=>(p(n.serverUrl||d)||n.serverUrl||d)===r)||e;await B(t,{backgroundRetry:!0})}catch(t){i.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u5F02\u5E38: ${t.message}`),L(e)}}function Re(){for(const e of A.values())clearTimeout(e);A.clear()}function f(e){return e==null?void 0:String(e).trim()||void 0}function O(e){return p(e)}function y(e){if(typeof e=="boolean")return e;if(typeof e=="string"){const r=e.trim().toLowerCase();if(["true","1","yes","y"].includes(r))return!0;if(["false","0","no","n"].includes(r))return!1}}function x(e){if(e==null||e==="")return;const r=Number(e);return Number.isFinite(r)?r:void 0}function h(e){const r=f(e.serverUrl)||f(e.schedulerBaseUrl),t=f(e.connectionKey)||f(e.password);return{enabled:y(e.enabled),serverUrl:r,tenantId:f(e.tenantId),userKey:f(e.userKey),connectionKey:t,instanceName:f(e.instanceName),instanceId:f(e.instanceId),projectId:f(e.projectId),roleName:f(e.roleName),workspacePath:f(e.workspacePath),registerAddr:f(e.registerAddr),registerIp:f(e.registerIp),virtualIp:f(e.virtualIp),tunnel:y(e.tunnel),preferSameLanIp:y(e.preferSameLanIp),maxRetries:x(e.maxRetries),retryInterval:x(e.retryInterval)}}function N(){const e=String(process.env.AWS_RUNTIME_HOME_DIR||"").trim()||m.homedir();return M.join(e,".aws-bridge","config.json")}function j(){const e=N();try{if(!g.existsSync(e))return i.debug(`[AutoRegister] \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`),null;const r=g.readFileSync(e,"utf-8"),t=JSON.parse(r);return i.info(`[AutoRegister] \u4ECE\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u914D\u7F6E: ${e}`),h(t)}catch(r){const t=r;return i.warn(`[AutoRegister] \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6\u5931\u8D25: ${e}, error: ${t.message}`),null}}function X(){const e=N();try{if(!g.existsSync(e))return[];const r=g.readFileSync(e,"utf-8"),t=JSON.parse(r),n=h(t),o=Array.isArray(t.autoRegisterTargets)?t.autoRegisterTargets:[];return o.length===0?n.userKey?[n]:[]:o.filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))).map(s=>{const a=h(s);return{...n,...a,connectionKey:a.connectionKey||n.connectionKey}})}catch(r){const t=r;return i.warn(`[AutoRegister] \u8BFB\u53D6\u81EA\u52A8\u6CE8\u518C\u76EE\u6807\u5931\u8D25: ${e}, error: ${t.message}`),[]}}function D(){const e={};return process.env.AWS_AUTO_REGISTER==="true"&&(e.enabled=!0),process.env.AWS_RUNTIME_SCHEDULER_BASE_URL&&(e.serverUrl=process.env.AWS_RUNTIME_SCHEDULER_BASE_URL),process.env.AWS_TENANT_ID&&(e.tenantId=process.env.AWS_TENANT_ID),process.env.AWS_USER_KEY&&(e.userKey=process.env.AWS_USER_KEY),process.env.AWS_BRIDGE_CONNECTION_KEY&&(e.connectionKey=process.env.AWS_BRIDGE_CONNECTION_KEY),process.env.AWS_INSTANCE_NAME&&(e.instanceName=process.env.AWS_INSTANCE_NAME),process.env.AWS_PROJECT_NAME&&(e.projectId=process.env.AWS_PROJECT_NAME),process.env.AWS_ROLE_NAME&&(e.roleName=process.env.AWS_ROLE_NAME),process.env.AWS_WORKSPACE_PATH&&(e.workspacePath=process.env.AWS_WORKSPACE_PATH),process.env.AWS_REGISTER_ADDR&&(e.registerAddr=process.env.AWS_REGISTER_ADDR),process.env.AWS_REGISTER_IP&&(e.registerIp=process.env.AWS_REGISTER_IP),process.env.AWS_VIRTUAL_IP&&(e.virtualIp=process.env.AWS_VIRTUAL_IP),process.env.AWS_PREFER_SAME_LAN_IP&&(e.preferSameLanIp=y(process.env.AWS_PREFER_SAME_LAN_IP)??!0),process.env.AWS_REGISTER_MAX_RETRIES&&(e.maxRetries=parseInt(process.env.AWS_REGISTER_MAX_RETRIES,10)),process.env.AWS_REGISTER_RETRY_INTERVAL&&(e.retryInterval=parseInt(process.env.AWS_REGISTER_RETRY_INTERVAL,10)),e}function T(){const e=j(),r=D(),t={...b,...e||{},...r},n=t.instanceName||m.hostname();let o=!1;return process.env.AWS_AUTO_REGISTER!==void 0?o=process.env.AWS_AUTO_REGISTER==="true":e&&(o=!0),{enabled:o,serverUrl:t.serverUrl||d,tenantId:t.tenantId||"",userKey:t.userKey||"",connectionKey:t.connectionKey,instanceName:n,instanceId:t.instanceId,projectId:t.projectId,roleName:t.roleName,workspacePath:t.workspacePath,registerAddr:t.registerAddr,registerIp:t.registerIp,virtualIp:t.virtualIp,tunnel:typeof t.tunnel=="boolean"?t.tunnel:void 0,preferSameLanIp:t.preferSameLanIp!==!1,maxRetries:t.maxRetries,retryInterval:t.retryInterval}}function R(){const e=X(),r=D(),n=(e.length>0?e:[j()||{}]).map(o=>{const s={...b,...o,...r};let a=!1;return process.env.AWS_AUTO_REGISTER!==void 0?a=process.env.AWS_AUTO_REGISTER==="true":a=e.length>0||!!s.userKey,{enabled:a,serverUrl:s.serverUrl||d,tenantId:s.tenantId||"",userKey:s.userKey||"",connectionKey:s.connectionKey,instanceName:s.instanceName||m.hostname(),instanceId:s.instanceId,projectId:s.projectId,roleName:s.roleName,workspacePath:s.workspacePath,registerAddr:s.registerAddr,registerIp:s.registerIp,virtualIp:s.virtualIp,tunnel:typeof s.tunnel=="boolean"?s.tunnel:void 0,preferSameLanIp:s.preferSameLanIp!==!1,maxRetries:s.maxRetries,retryInterval:s.retryInterval}});return P=n.map(o=>o.connectionKey).filter(o=>!!(o&&o.trim())),n}function Q(){const e=m.networkInterfaces(),r=[];for(const t of Object.keys(e)){const n=e[t];if(n)for(const o of n)o.family==="IPv4"&&!o.internal&&r.push({address:o.address,netmask:o.netmask,name:t})}return r}function k(e){const r=e.split(".").map(Number);return(r[0]<<24)+(r[1]<<16)+(r[2]<<8)+r[3]}function Z(e,r,t){const n=k(e),o=k(r),s=k(t);return(n&s)===(o&s)}function ee(e){try{const r=new URL(e);return r.hostname==="localhost"||r.hostname==="127.0.0.1"?"127.0.0.1":/^(\d{1,3}\.){3}\d{1,3}$/.test(r.hostname)?r.hostname:null}catch{return null}}function re(e){return e==="127.0.0.1"}function te(e){const r=Q();if(r.length===0)return i.warn("[AutoRegister] \u672A\u627E\u5230\u4EFB\u4F55\u975E\u5185\u90E8 IP \u5730\u5740\uFF0C\u4F7F\u7528 127.0.0.1"),"127.0.0.1";const t=ee(e);if(t){if(re(t))return"127.0.0.1";for(const n of r)if(Z(n.address,t,n.netmask))return i.info(`[AutoRegister] \u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u540C\u5B50\u7F51\u7684 IP: ${n.address} (\u7F51\u5361: ${n.name}, \u5B50\u7F51\u63A9\u7801: ${n.netmask})`),n.address;i.warn(`[AutoRegister] \u672A\u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3 (${t}) \u540C\u5B50\u7F51\u7684\u672C\u673A IP\uFF0C\u4F7F\u7528 127.0.0.1`)}else i.warn("[AutoRegister] \u65E0\u6CD5\u89E3\u6790\u8C03\u5EA6\u4E2D\u5FC3 IP\uFF0C\u4F7F\u7528 127.0.0.1");return"127.0.0.1"}function ne(e=d){return te(e)}function F(e){const r=e||T();return!r.enabled||!r.userKey?!1:r.tunnel===!0?!0:r.tunnel===!1?!1:!r.registerAddr&&!r.registerIp&&!r.virtualIp}function _(e){const r=process.env.AWS_RUNTIME_BRIDGE_PORT||18081;if(F(e)){const s=e.serverUrl||d;try{const a=new URL(s);if(!e.instanceId)i.warn("[AutoRegister] \u96A7\u9053\u6A21\u5F0F\u4F46\u7F3A\u5C11 instanceId\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F");else return`${a.protocol}//${a.host}/tunnel/${e.instanceId}`}catch{i.warn("[AutoRegister] serverUrl \u89E3\u6790\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F")}}const t=e.preferSameLanIp===!1?"127.0.0.1":ne(e.serverUrl||d),n=e.registerAddr||e.registerIp||e.virtualIp||t;return n?/^https?:\/\//i.test(n)?n:/:[0-9]+$/.test(n)?`http://${n}`:`http://${n}:${r}`:`http://127.0.0.1:${r}`}function S(){return R()[0]||T()}function Se(e){const r=String(e||"").trim();if(!r)return;const t=[];for(const o of R())o?.serverUrl&&t.push(o.serverUrl);const n=v();n.schedulerBaseUrl&&t.push(n.schedulerBaseUrl);for(const o of t){const s=q(o);if(s&&s===r)return p(o)}}function se(e){return e?Object.entries(u.registrations).find(([,t])=>t===e)?.[0]:void 0}function U(e,r){const t=se(r);if(t)return t;const n=f(e.serverUrl);if(n&&(n!==d||process.env.AWS_RUNTIME_SCHEDULER_BASE_URL))return n;const o=v(),s=f(o.schedulerBaseUrl);return o.status==="paired"&&s?s:n||d}async function oe(e){const r=e.instanceName||m.hostname(),t=e.serverUrl||d,n={tenantId:e.tenantId,userKey:e.userKey,instanceId:e.instanceId,instanceName:r,hostname:m.hostname(),virtualIp:e.registerAddr||e.registerIp||e.virtualIp,runtimeBridgeBaseUrl:_(e),connectionKey:e.connectionKey,workspacePath:e.workspacePath,projectId:e.projectId,roleName:e.roleName};return i.info(`[AutoRegister] \u6B63\u5728\u6CE8\u518C\u5B9E\u4F8B: ${r}`),i.info(`[AutoRegister] \u8C03\u5EA6\u4E2D\u5FC3: ${t}`),i.info(`[AutoRegister] \u7528\u6237 Key: ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),i.info(`[AutoRegister] \u79DF\u6237 ID: ${e.tenantId||"(\u81EA\u52A8\u63A8\u5BFC)"}`),(await I.post(`${t}/api/instances/register`,n,{headers:{"Content-Type":"application/json"},timeout:1e4})).data}function ie(e,r){const t=N();return z(t,()=>{if(!g.existsSync(t))return;const n=g.readFileSync(t,"utf-8"),o=JSON.parse(n),s=p(e);if(!s)return;let a=!1;const l=c=>{p(String(c.serverUrl||c.schedulerBaseUrl||""))===s&&r&&c.instanceId!==r&&(c.instanceId=r,a=!0)};if(Array.isArray(o.autoRegisterTargets))for(const c of o.autoRegisterTargets)c&&typeof c=="object"&&!Array.isArray(c)&&l(c);else l(o);a&&(g.writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),i.info(`[AutoRegister] \u5DF2\u56DE\u5199 instanceId \u5230 config.json (serverUrl=${e})`))})}async function ae(e){const r=U(S(),e),t=v(),n=E(r);if(!n)throw new Error("runtimeAccessToken is required to unregister bridge instance");return(await I.post(`${r}/api/instances/unregister`,{instanceId:e},{headers:{"Content-Type":"application/json","X-Runtime-Token":n},timeout:1e4})).data}async function ve(e){const r=e?[{...T(),...e}]:R(),n=(r.length>1?await Promise.all(r.map(s=>B(s))):[await B(r[0]||T())]).every(Boolean),o=r.every(s=>!s.enabled||!s.userKey);if(!e&&(n||o)){const{stopTunnelClientsExcept:s}=await import("./tunnel-client.js");s(r.map(a=>a.serverUrl).filter(a=>!!a))}return n}async function B(e,r){if(!e.enabled)return i.info("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u672A\u542F\u7528"),i.info("[AutoRegister] \u8981\u542F\u7528\u81EA\u52A8\u6CE8\u518C\uFF0C\u8BF7\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6 ~/.aws-bridge/config.json \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_AUTO_REGISTER=true"),!1;if(!e.userKey)return i.error("[AutoRegister] \u7F3A\u5C11\u7528\u6237 Key\uFF08\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E userKey \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_USER_KEY\uFF09"),!1;const t=F(e);t&&!e.instanceId&&(e={...e,instanceId:`bridge-${G().replace(/-/g,"").slice(0,12)}`},i.info(`[AutoRegister] \u96A7\u9053\u6A21\u5F0F\uFF1A\u5DF2\u9884\u58F0\u660E instanceId=${e.instanceId}`));const n=r?.backgroundRetry?1:e.maxRetries??3,o=e.retryInterval??2e3;for(let s=1;s<=n;s++){try{u.lastAttempt=new Date;const a=await oe(e);if(a.success){if(u.registered=!0,u.instanceId=a.instanceId,a.instanceId&&(u.registrations[e.serverUrl||d]=a.instanceId),u.error=void 0,i.info("[AutoRegister] \u2713 \u6CE8\u518C\u6210\u529F\uFF01"),i.info(`[AutoRegister] \u5B9E\u4F8B ID: ${a.instanceId}`),i.info(`[AutoRegister] \u6D88\u606F: ${a.message}`),i.info(`[AutoRegister] \u66F4\u65B0: ${a.isUpdate?"\u662F":"\u5426"}`),a.runtimeAccessToken)try{const l=e.serverUrl||d;K({accessToken:a.runtimeAccessToken,instanceId:a.instanceId,userId:a.userId,schedulerBaseUrl:l});const c=p(a.serverUrl);c&&c!==p(l)&&(C({serverBaseUrl:c,accessToken:a.runtimeAccessToken}),i.info(`[AutoRegister] \u68C0\u6D4B\u5230 server \u4E0B\u53D1\u5730\u5740(${c})\u4E0E\u8FDE\u63A5\u5730\u5740(${l})\u4E0D\u540C\uFF0C\u5DF2\u6309\u4E24\u4E2A\u5730\u5740\u5206\u522B\u4FDD\u5B58 scoped token`)),i.info("[AutoRegister] \u5DF2\u4FDD\u5B58\u8C03\u5EA6\u4E2D\u5FC3\u4E0B\u53D1\u7684 runtime access token"),a.instanceId&&ie(e.serverUrl||d,a.instanceId).catch($=>{i.warn(`[AutoRegister] \u56DE\u5199 instanceId \u5230 config.json \u5931\u8D25: ${$.message}`)})}catch(l){const c=l;return i.error(`[AutoRegister] \u4FDD\u5B58 runtime access token \u5931\u8D25: ${c.message}`),u.error=c.message,!1}else i.warn("[AutoRegister] \u6CE8\u518C\u54CD\u5E94\u672A\u5305\u542B runtime access token\uFF0CMCP \u5C06\u65E0\u6CD5\u8BBF\u95EE\u8C03\u5EA6\u4E2D\u5FC3\uFF0C\u8BF7\u68C0\u67E5 server \u7684 bridge \u5B9E\u4F8B token \u9881\u53D1\u903B\u8F91");if(t&&a.instanceId&&a.runtimeAccessToken){const{startTunnelClient:l}=await import("./tunnel-client.js"),c=e.serverUrl||d;l(c,a.instanceId),i.info(`[AutoRegister] \u96A7\u9053\u5BA2\u6237\u7AEF\u5DF2\u542F\u52A8: server=${c}, instanceId=${a.instanceId}`)}return!0}else i.warn(`[AutoRegister] \u6CE8\u518C\u5931\u8D25: ${a.message}`),u.error=a.message}catch(a){const l=a,c=l.response?.data?JSON.stringify(l.response.data):l.message;i.error(`[AutoRegister] \u6CE8\u518C\u8BF7\u6C42\u5931\u8D25 (\u5C1D\u8BD5 ${s}/${n}): ${c}`),u.error=c}s<n&&(i.info(`[AutoRegister] ${o/1e3} \u79D2\u540E\u91CD\u8BD5...`),await new Promise(a=>setTimeout(a,o)))}return r?.backgroundRetry?i.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u4ECD\u672A\u6210\u529F (server=${e.serverUrl||d}): ${u.error||"\u672A\u77E5"}`):(i.error("[AutoRegister] \u2717 \u6CE8\u518C\u5931\u8D25\uFF0C\u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570"),i.error("[AutoRegister] ========================================"),i.error("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u5DF2\u542F\u7528\u4F46\u6CE8\u518C\u5931\u8D25\uFF0C\u5B9E\u4F8B\u6682\u65F6\u65E0\u6CD5\u6B63\u5E38\u5DE5\u4F5C"),i.error("[AutoRegister] \u8BF7\u68C0\u67E5\u4EE5\u4E0B\u914D\u7F6E\uFF1A"),i.error(`[AutoRegister] - \u7528\u6237 Key (userKey): ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),i.error(`[AutoRegister] - \u79DF\u6237 ID (tenantId): ${e.tenantId||"(\u53EF\u9009\uFF0C\u5C06\u81EA\u52A8\u63A8\u5BFC)"}`),i.error(`[AutoRegister] - \u5B9E\u4F8B\u540D (instanceName): ${e.instanceName||"(\u4F7F\u7528\u4E3B\u673A\u540D)"}`),i.error(`[AutoRegister] - \u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740: ${e.serverUrl||d}`),i.error(`[AutoRegister] - \u6700\u540E\u9519\u8BEF: ${u.error||"\u672A\u77E5"}`),i.error("[AutoRegister] ========================================"),i.error("[AutoRegister] \u914D\u7F6E\u6765\u6E90\uFF1A~/.aws-bridge/config.json \u6216\u73AF\u5883\u53D8\u91CF"),i.warn(`[AutoRegister] \u5C06\u5728\u540E\u53F0\u6301\u7EED\u91CD\u8BD5\u6CE8\u518C\uFF08\u6BCF ${Math.round(W()/1e3)} \u79D2\uFF09\uFF0C\u76F4\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u5EFA\u7ACB\u8FDE\u63A5`)),L(e),!1}async function ye(){const e=S();if(!e.userKey)return{success:!1,error:"userKey is required for runtime token refresh"};const r=w(),t=U(e),n=_(e);try{const o=await I.post(`${t}/api/instances/runtime-tokens/refresh`,{tenantId:e.tenantId,userKey:e.userKey,instanceId:r.instanceId,instanceName:e.instanceName,runtimeBridgeBaseUrl:n},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!o.data.success||!o.data.runtimeAccessToken)return{success:!1,error:o.data.message||"scheduler did not return runtimeAccessToken"};const a=E()!==o.data.runtimeAccessToken;return K({accessToken:o.data.runtimeAccessToken,instanceId:r.instanceId,userId:o.data.userId||e.userKey,schedulerBaseUrl:t}),{success:!0,runtimeAccessToken:o.data.runtimeAccessToken,updated:a}}catch(o){const s=o;return{success:!1,error:s.response?.data?JSON.stringify(s.response.data):s.message}}}async function Te(e){const r=O(e);if(!r)return{success:!1,error:"serverUrl is required for runtime token refresh"};const t=R().find(s=>O(s.serverUrl)===r)||S();if(!t.userKey)return{success:!1,error:"userKey is required for runtime token refresh"};const n=w(),o=_(t);try{const s=await I.post(`${r}/api/instances/runtime-tokens/refresh`,{tenantId:t.tenantId,userKey:t.userKey,instanceId:n.instanceId,instanceName:t.instanceName,runtimeBridgeBaseUrl:o},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!s.data.success||!s.data.runtimeAccessToken)return{success:!1,error:s.data.message||"scheduler did not return runtimeAccessToken"};const l=E(r)!==s.data.runtimeAccessToken;return C({serverBaseUrl:r,accessToken:s.data.runtimeAccessToken}),{success:!0,runtimeAccessToken:s.data.runtimeAccessToken,updated:l}}catch(s){const a=s;return{success:!1,error:a.response?.data?JSON.stringify(a.response.data):a.message}}}async function _e(){if(!u.registered||!u.instanceId)return i.info("[AutoRegister] \u5B9E\u4F8B\u672A\u6CE8\u518C\uFF0C\u65E0\u9700\u6CE8\u9500"),!0;try{const e=await ae(u.instanceId);if(e.success){i.info(`[AutoRegister] \u2713 \u6CE8\u9500\u6210\u529F: ${u.instanceId}`);const r=U(S(),u.instanceId);v().schedulerBaseUrl&&Y(r),J();try{const{stopTunnelClientForServer:n}=await import("./tunnel-client.js");n(r)}catch(n){i.warn(`[AutoRegister] \u6CE8\u9500\u540E\u505C\u6B62\u96A7\u9053\u5931\u8D25: ${n.message}`)}return u.registered=!1,u.instanceId=void 0,!0}else return i.warn(`[AutoRegister] \u6CE8\u9500\u5931\u8D25: ${e.message}`),!1}catch(e){const r=e;return i.error(`[AutoRegister] \u6CE8\u9500\u8BF7\u6C42\u5931\u8D25: ${r.message}`),!1}}function Ue(){return{...u}}function Ee(){return u.registered}function he(){return u.instanceId}async function Ne(){const e=S(),r=u.instanceId,t=U(e,r),n={};if(r&&(n.instanceId=r),e.enabled&&(n.runtimeBridgeBaseUrl=_(e)),!n.instanceId&&!n.runtimeBridgeBaseUrl)return i.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6CA1\u6709 instanceId \u6216 runtimeBridgeBaseUrl\uFF0C\u8DF3\u8FC7\u6E05\u7406"),{success:!0,agentCount:0};try{i.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6B63\u5728\u901A\u77E5\u8C03\u5EA6\u4E2D\u5FC3..."),i.info(`[AutoRegister] instanceId: ${n.instanceId||"(\u65E0)"}`),i.info(`[AutoRegister] runtimeBridgeBaseUrl: ${n.runtimeBridgeBaseUrl||"(\u65E0)"}`);const o=await I.post(`${t}/api/instances/bridge-restart-cleanup`,n,{headers:{"Content-Type":"application/json"},timeout:1e4});return o.data.success?(i.info(`[AutoRegister] \u2713 Bridge \u91CD\u542F\u6E05\u7406\u6210\u529F\uFF1A${o.data.message}`),i.info(`[AutoRegister] \u6E05\u7406\u4E86 ${o.data.agentCount||0} \u4E2A Agent`),{success:!0,agentCount:o.data.agentCount||0}):(i.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u5931\u8D25\uFF1A${o.data.message}`),{success:!1,error:o.data.message})}catch(o){const s=o,a=s.response?.data?JSON.stringify(s.response.data):s.message;return i.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u8BF7\u6C42\u5931\u8D25\uFF1A${a}`),{success:!1,error:a}}}export{ve as autoRegister,Ne as bridgeRestartCleanup,Re as cancelBackgroundRegisterRetries,N as getAutoRegisterConfigFilePath,Ae as getConfiguredConnectionKeys,he as getInstanceId,Ue as getRegistrationState,Ee as isRegistered,F as isTunnelConfig,T as loadConfig,R as loadConfigs,S as loadPrimaryLifecycleConfig,ye as requestRuntimeAccessTokenRefresh,Te as requestRuntimeAccessTokenRefreshForServer,Se as resolveSchedulerBaseUrlFromToken,_e as unregister};
|
|
1
|
+
import{v4 as G}from"uuid";import A from"axios";import I from"node:os";import g from"node:fs";import{logger as i}from"../utils/logger.js";import{getActiveBridgeHttpPort as M,getAutoRegisterConfigFilePath as m,schedulerBaseUrl as d}from"../config.js";import{runExclusiveConfigWrite as z}from"../utils/config-write-queue.js";import{clearRuntimeBinding as J,clearScopedRuntimeAccessToken as Y,getRuntimeAccessToken as h,getRuntimeBindingPublicState as w,getScopedRuntimeAccessToken as q,loadRuntimeBinding as y,normalizeSchedulerBaseUrl as p,saveRuntimeBinding as K,saveScopedRuntimeAccessToken as C}from"./runtime-binding.js";const b={enabled:!1,serverUrl:d,preferSameLanIp:!0,maxRetries:3,retryInterval:2e3};let u={registered:!1,registrations:{}},P=[];function Ae(){return[...P]}const H=3e4;function W(){const e=Number(process.env.AWS_REGISTER_BACKGROUND_RETRY_INTERVAL);return Number.isFinite(e)&&e>0?e:H}const R=new Map;function L(e){const r=e.serverUrl||d,t=p(r)||r;if(R.has(t))return;const n=setTimeout(()=>{R.delete(t),V(e,t)},W());n.unref?.(),R.set(t,n)}async function V(e,r){try{const t=S().find(n=>(p(n.serverUrl||d)||n.serverUrl||d)===r)||e;await $(t,{backgroundRetry:!0})}catch(t){i.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u5F02\u5E38: ${t.message}`),L(e)}}function Ie(){for(const e of R.values())clearTimeout(e);R.clear()}function f(e){return e==null?void 0:String(e).trim()||void 0}function O(e){return p(e)}function T(e){if(typeof e=="boolean")return e;if(typeof e=="string"){const r=e.trim().toLowerCase();if(["true","1","yes","y"].includes(r))return!0;if(["false","0","no","n"].includes(r))return!1}}function x(e){if(e==null||e==="")return;const r=Number(e);return Number.isFinite(r)?r:void 0}function k(e){const r=f(e.serverUrl)||f(e.schedulerBaseUrl),t=f(e.connectionKey)||f(e.password);return{enabled:T(e.enabled),serverUrl:r,tenantId:f(e.tenantId),userKey:f(e.userKey),connectionKey:t,instanceName:f(e.instanceName),instanceId:f(e.instanceId),projectId:f(e.projectId),roleName:f(e.roleName),workspacePath:f(e.workspacePath),registerAddr:f(e.registerAddr),registerIp:f(e.registerIp),virtualIp:f(e.virtualIp),tunnel:T(e.tunnel),preferSameLanIp:T(e.preferSameLanIp),maxRetries:x(e.maxRetries),retryInterval:x(e.retryInterval)}}function j(){const e=m();try{if(!g.existsSync(e))return i.debug(`[AutoRegister] \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728: ${e}`),null;const r=g.readFileSync(e,"utf-8"),t=JSON.parse(r);return i.info(`[AutoRegister] \u4ECE\u914D\u7F6E\u6587\u4EF6\u52A0\u8F7D\u914D\u7F6E: ${e}`),k(t)}catch(r){const t=r;return i.warn(`[AutoRegister] \u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6\u5931\u8D25: ${e}, error: ${t.message}`),null}}function X(){const e=m();try{if(!g.existsSync(e))return[];const r=g.readFileSync(e,"utf-8"),t=JSON.parse(r),n=k(t),o=Array.isArray(t.autoRegisterTargets)?t.autoRegisterTargets:[];return o.length===0?n.userKey?[n]:[]:o.filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))).map(s=>{const a=k(s);return{...n,...a,connectionKey:a.connectionKey||n.connectionKey}})}catch(r){const t=r;return i.warn(`[AutoRegister] \u8BFB\u53D6\u81EA\u52A8\u6CE8\u518C\u76EE\u6807\u5931\u8D25: ${e}, error: ${t.message}`),[]}}function F(){const e={};return process.env.AWS_AUTO_REGISTER==="true"&&(e.enabled=!0),process.env.AWS_RUNTIME_SCHEDULER_BASE_URL&&(e.serverUrl=process.env.AWS_RUNTIME_SCHEDULER_BASE_URL),process.env.AWS_TENANT_ID&&(e.tenantId=process.env.AWS_TENANT_ID),process.env.AWS_USER_KEY&&(e.userKey=process.env.AWS_USER_KEY),process.env.AWS_BRIDGE_CONNECTION_KEY&&(e.connectionKey=process.env.AWS_BRIDGE_CONNECTION_KEY),process.env.AWS_INSTANCE_NAME&&(e.instanceName=process.env.AWS_INSTANCE_NAME),process.env.AWS_PROJECT_NAME&&(e.projectId=process.env.AWS_PROJECT_NAME),process.env.AWS_ROLE_NAME&&(e.roleName=process.env.AWS_ROLE_NAME),process.env.AWS_WORKSPACE_PATH&&(e.workspacePath=process.env.AWS_WORKSPACE_PATH),process.env.AWS_REGISTER_ADDR&&(e.registerAddr=process.env.AWS_REGISTER_ADDR),process.env.AWS_REGISTER_IP&&(e.registerIp=process.env.AWS_REGISTER_IP),process.env.AWS_VIRTUAL_IP&&(e.virtualIp=process.env.AWS_VIRTUAL_IP),process.env.AWS_PREFER_SAME_LAN_IP&&(e.preferSameLanIp=T(process.env.AWS_PREFER_SAME_LAN_IP)??!0),process.env.AWS_REGISTER_MAX_RETRIES&&(e.maxRetries=parseInt(process.env.AWS_REGISTER_MAX_RETRIES,10)),process.env.AWS_REGISTER_RETRY_INTERVAL&&(e.retryInterval=parseInt(process.env.AWS_REGISTER_RETRY_INTERVAL,10)),e}function U(){const e=j(),r=F(),t={...b,...e||{},...r},n=t.instanceName||I.hostname();let o=!1;return process.env.AWS_AUTO_REGISTER!==void 0?o=process.env.AWS_AUTO_REGISTER==="true":e&&(o=!0),{enabled:o,serverUrl:t.serverUrl||d,tenantId:t.tenantId||"",userKey:t.userKey||"",connectionKey:t.connectionKey,instanceName:n,instanceId:t.instanceId,projectId:t.projectId,roleName:t.roleName,workspacePath:t.workspacePath,registerAddr:t.registerAddr,registerIp:t.registerIp,virtualIp:t.virtualIp,tunnel:typeof t.tunnel=="boolean"?t.tunnel:void 0,preferSameLanIp:t.preferSameLanIp!==!1,maxRetries:t.maxRetries,retryInterval:t.retryInterval}}function S(){const e=X(),r=F(),n=(e.length>0?e:[j()||{}]).map(o=>{const s={...b,...o,...r};let a=!1;return process.env.AWS_AUTO_REGISTER!==void 0?a=process.env.AWS_AUTO_REGISTER==="true":a=e.length>0||!!s.userKey,{enabled:a,serverUrl:s.serverUrl||d,tenantId:s.tenantId||"",userKey:s.userKey||"",connectionKey:s.connectionKey,instanceName:s.instanceName||I.hostname(),instanceId:s.instanceId,projectId:s.projectId,roleName:s.roleName,workspacePath:s.workspacePath,registerAddr:s.registerAddr,registerIp:s.registerIp,virtualIp:s.virtualIp,tunnel:typeof s.tunnel=="boolean"?s.tunnel:void 0,preferSameLanIp:s.preferSameLanIp!==!1,maxRetries:s.maxRetries,retryInterval:s.retryInterval}});return P=n.map(o=>o.connectionKey).filter(o=>!!(o&&o.trim())),n}function Q(){const e=I.networkInterfaces(),r=[];for(const t of Object.keys(e)){const n=e[t];if(n)for(const o of n)o.family==="IPv4"&&!o.internal&&r.push({address:o.address,netmask:o.netmask,name:t})}return r}function N(e){const r=e.split(".").map(Number);return(r[0]<<24)+(r[1]<<16)+(r[2]<<8)+r[3]}function Z(e,r,t){const n=N(e),o=N(r),s=N(t);return(n&s)===(o&s)}function ee(e){try{const r=new URL(e);return r.hostname==="localhost"||r.hostname==="127.0.0.1"?"127.0.0.1":/^(\d{1,3}\.){3}\d{1,3}$/.test(r.hostname)?r.hostname:null}catch{return null}}function re(e){return e==="127.0.0.1"}function te(e){const r=Q();if(r.length===0)return i.warn("[AutoRegister] \u672A\u627E\u5230\u4EFB\u4F55\u975E\u5185\u90E8 IP \u5730\u5740\uFF0C\u4F7F\u7528 127.0.0.1"),"127.0.0.1";const t=ee(e);if(t){if(re(t))return"127.0.0.1";for(const n of r)if(Z(n.address,t,n.netmask))return i.info(`[AutoRegister] \u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u540C\u5B50\u7F51\u7684 IP: ${n.address} (\u7F51\u5361: ${n.name}, \u5B50\u7F51\u63A9\u7801: ${n.netmask})`),n.address;i.warn(`[AutoRegister] \u672A\u627E\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3 (${t}) \u540C\u5B50\u7F51\u7684\u672C\u673A IP\uFF0C\u4F7F\u7528 127.0.0.1`)}else i.warn("[AutoRegister] \u65E0\u6CD5\u89E3\u6790\u8C03\u5EA6\u4E2D\u5FC3 IP\uFF0C\u4F7F\u7528 127.0.0.1");return"127.0.0.1"}function ne(e=d){return te(e)}function D(e){const r=e||U();return!r.enabled||!r.userKey?!1:r.tunnel===!0?!0:r.tunnel===!1?!1:!r.registerAddr&&!r.registerIp&&!r.virtualIp}function _(e){const r=M();if(D(e)){const s=e.serverUrl||d;try{const a=new URL(s);if(!e.instanceId)i.warn("[AutoRegister] \u96A7\u9053\u6A21\u5F0F\u4F46\u7F3A\u5C11 instanceId\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F");else return`${a.protocol}//${a.host}/tunnel/${e.instanceId}`}catch{i.warn("[AutoRegister] serverUrl \u89E3\u6790\u5931\u8D25\uFF0C\u964D\u7EA7\u4E3A\u76F4\u8FDE\u6A21\u5F0F")}}const t=e.preferSameLanIp===!1?"127.0.0.1":ne(e.serverUrl||d),n=e.registerAddr||e.registerIp||e.virtualIp||t;return n?/^https?:\/\//i.test(n)?n:/:[0-9]+$/.test(n)?`http://${n}`:`http://${n}:${r}`:`http://127.0.0.1:${r}`}function v(){return S()[0]||U()}function Re(e){const r=String(e||"").trim();if(!r)return;const t=[];for(const o of S())o?.serverUrl&&t.push(o.serverUrl);const n=y();n.schedulerBaseUrl&&t.push(n.schedulerBaseUrl);for(const o of t){const s=q(o);if(s&&s===r)return p(o)}}function se(e){return e?Object.entries(u.registrations).find(([,t])=>t===e)?.[0]:void 0}function E(e,r){const t=se(r);if(t)return t;const n=f(e.serverUrl);if(n&&(n!==d||process.env.AWS_RUNTIME_SCHEDULER_BASE_URL))return n;const o=y(),s=f(o.schedulerBaseUrl);return o.status==="paired"&&s?s:n||d}async function oe(e){const r=e.instanceName||I.hostname(),t=e.serverUrl||d,n={tenantId:e.tenantId,userKey:e.userKey,instanceId:e.instanceId,instanceName:r,hostname:I.hostname(),virtualIp:e.registerAddr||e.registerIp||e.virtualIp,runtimeBridgeBaseUrl:_(e),connectionKey:e.connectionKey,workspacePath:e.workspacePath,projectId:e.projectId,roleName:e.roleName};return i.info(`[AutoRegister] \u6B63\u5728\u6CE8\u518C\u5B9E\u4F8B: ${r}`),i.info(`[AutoRegister] \u8C03\u5EA6\u4E2D\u5FC3: ${t}`),i.info(`[AutoRegister] \u7528\u6237 Key: ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),i.info(`[AutoRegister] \u79DF\u6237 ID: ${e.tenantId||"(\u81EA\u52A8\u63A8\u5BFC)"}`),(await A.post(`${t}/api/instances/register`,n,{headers:{"Content-Type":"application/json"},timeout:1e4})).data}function ie(e,r){const t=m();return z(t,()=>{if(!g.existsSync(t))return;const n=g.readFileSync(t,"utf-8"),o=JSON.parse(n),s=p(e);if(!s)return;let a=!1;const l=c=>{p(String(c.serverUrl||c.schedulerBaseUrl||""))===s&&r&&c.instanceId!==r&&(c.instanceId=r,a=!0)};if(Array.isArray(o.autoRegisterTargets))for(const c of o.autoRegisterTargets)c&&typeof c=="object"&&!Array.isArray(c)&&l(c);else l(o);a&&(g.writeFileSync(t,JSON.stringify(o,null,2),"utf-8"),i.info(`[AutoRegister] \u5DF2\u56DE\u5199 instanceId \u5230 config.json (serverUrl=${e})`))})}async function ae(e){const r=E(v(),e),t=y(),n=h(r);if(!n)throw new Error("runtimeAccessToken is required to unregister bridge instance");return(await A.post(`${r}/api/instances/unregister`,{instanceId:e},{headers:{"Content-Type":"application/json","X-Runtime-Token":n},timeout:1e4})).data}async function Se(e){const r=e?[{...U(),...e}]:S(),n=(r.length>1?await Promise.all(r.map(s=>$(s))):[await $(r[0]||U())]).every(Boolean),o=r.every(s=>!s.enabled||!s.userKey);if(!e&&(n||o)){const{stopTunnelClientsExcept:s}=await import("./tunnel-client.js");s(r.map(a=>a.serverUrl).filter(a=>!!a))}return n}async function $(e,r){if(!e.enabled)return i.info("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u672A\u542F\u7528"),i.info(`[AutoRegister] \u8981\u542F\u7528\u81EA\u52A8\u6CE8\u518C\uFF0C\u8BF7\u521B\u5EFA\u914D\u7F6E\u6587\u4EF6 ${m()} \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_AUTO_REGISTER=true`),!1;if(!e.userKey)return i.error("[AutoRegister] \u7F3A\u5C11\u7528\u6237 Key\uFF08\u5728\u914D\u7F6E\u6587\u4EF6\u4E2D\u8BBE\u7F6E userKey \u6216\u8BBE\u7F6E\u73AF\u5883\u53D8\u91CF AWS_USER_KEY\uFF09"),!1;const t=D(e);t&&!e.instanceId&&(e={...e,instanceId:`bridge-${G().replace(/-/g,"").slice(0,12)}`},i.info(`[AutoRegister] \u96A7\u9053\u6A21\u5F0F\uFF1A\u5DF2\u9884\u58F0\u660E instanceId=${e.instanceId}`));const n=r?.backgroundRetry?1:e.maxRetries??3,o=e.retryInterval??2e3;for(let s=1;s<=n;s++){try{u.lastAttempt=new Date;const a=await oe(e);if(a.success){if(u.registered=!0,u.instanceId=a.instanceId,a.instanceId&&(u.registrations[e.serverUrl||d]=a.instanceId),u.error=void 0,i.info("[AutoRegister] \u2713 \u6CE8\u518C\u6210\u529F\uFF01"),i.info(`[AutoRegister] \u5B9E\u4F8B ID: ${a.instanceId}`),i.info(`[AutoRegister] \u6D88\u606F: ${a.message}`),i.info(`[AutoRegister] \u66F4\u65B0: ${a.isUpdate?"\u662F":"\u5426"}`),a.runtimeAccessToken)try{const l=e.serverUrl||d;K({accessToken:a.runtimeAccessToken,instanceId:a.instanceId,userId:a.userId,schedulerBaseUrl:l});const c=p(a.serverUrl);c&&c!==p(l)&&(C({serverBaseUrl:c,accessToken:a.runtimeAccessToken}),i.info(`[AutoRegister] \u68C0\u6D4B\u5230 server \u4E0B\u53D1\u5730\u5740(${c})\u4E0E\u8FDE\u63A5\u5730\u5740(${l})\u4E0D\u540C\uFF0C\u5DF2\u6309\u4E24\u4E2A\u5730\u5740\u5206\u522B\u4FDD\u5B58 scoped token`)),i.info("[AutoRegister] \u5DF2\u4FDD\u5B58\u8C03\u5EA6\u4E2D\u5FC3\u4E0B\u53D1\u7684 runtime access token"),a.instanceId&&ie(e.serverUrl||d,a.instanceId).catch(B=>{i.warn(`[AutoRegister] \u56DE\u5199 instanceId \u5230 config.json \u5931\u8D25: ${B.message}`)})}catch(l){const c=l;return i.error(`[AutoRegister] \u4FDD\u5B58 runtime access token \u5931\u8D25: ${c.message}`),u.error=c.message,!1}else i.warn("[AutoRegister] \u6CE8\u518C\u54CD\u5E94\u672A\u5305\u542B runtime access token\uFF0CMCP \u5C06\u65E0\u6CD5\u8BBF\u95EE\u8C03\u5EA6\u4E2D\u5FC3\uFF0C\u8BF7\u68C0\u67E5 server \u7684 bridge \u5B9E\u4F8B token \u9881\u53D1\u903B\u8F91");if(t&&a.instanceId&&a.runtimeAccessToken){const{startTunnelClient:l}=await import("./tunnel-client.js"),c=e.serverUrl||d;l(c,a.instanceId),i.info(`[AutoRegister] \u96A7\u9053\u5BA2\u6237\u7AEF\u5DF2\u542F\u52A8: server=${c}, instanceId=${a.instanceId}`)}return!0}else i.warn(`[AutoRegister] \u6CE8\u518C\u5931\u8D25: ${a.message}`),u.error=a.message}catch(a){const l=a,c=l.response?.data?JSON.stringify(l.response.data):l.message;i.error(`[AutoRegister] \u6CE8\u518C\u8BF7\u6C42\u5931\u8D25 (\u5C1D\u8BD5 ${s}/${n}): ${c}`),u.error=c}s<n&&(i.info(`[AutoRegister] ${o/1e3} \u79D2\u540E\u91CD\u8BD5...`),await new Promise(a=>setTimeout(a,o)))}return r?.backgroundRetry?i.warn(`[AutoRegister] \u540E\u53F0\u91CD\u8BD5\u6CE8\u518C\u4ECD\u672A\u6210\u529F (server=${e.serverUrl||d}): ${u.error||"\u672A\u77E5"}`):(i.error("[AutoRegister] \u2717 \u6CE8\u518C\u5931\u8D25\uFF0C\u5DF2\u8FBE\u6700\u5927\u91CD\u8BD5\u6B21\u6570"),i.error("[AutoRegister] ========================================"),i.error("[AutoRegister] \u81EA\u52A8\u6CE8\u518C\u5DF2\u542F\u7528\u4F46\u6CE8\u518C\u5931\u8D25\uFF0C\u5B9E\u4F8B\u6682\u65F6\u65E0\u6CD5\u6B63\u5E38\u5DE5\u4F5C"),i.error("[AutoRegister] \u8BF7\u68C0\u67E5\u4EE5\u4E0B\u914D\u7F6E\uFF1A"),i.error(`[AutoRegister] - \u7528\u6237 Key (userKey): ${e.userKey?"****"+e.userKey.slice(-4):"(\u672A\u8BBE\u7F6E)"}`),i.error(`[AutoRegister] - \u79DF\u6237 ID (tenantId): ${e.tenantId||"(\u53EF\u9009\uFF0C\u5C06\u81EA\u52A8\u63A8\u5BFC)"}`),i.error(`[AutoRegister] - \u5B9E\u4F8B\u540D (instanceName): ${e.instanceName||"(\u4F7F\u7528\u4E3B\u673A\u540D)"}`),i.error(`[AutoRegister] - \u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740: ${e.serverUrl||d}`),i.error(`[AutoRegister] - \u6700\u540E\u9519\u8BEF: ${u.error||"\u672A\u77E5"}`),i.error("[AutoRegister] ========================================"),i.error(`[AutoRegister] \u914D\u7F6E\u6765\u6E90\uFF1A${m()} \u6216\u73AF\u5883\u53D8\u91CF`),i.warn(`[AutoRegister] \u5C06\u5728\u540E\u53F0\u6301\u7EED\u91CD\u8BD5\u6CE8\u518C\uFF08\u6BCF ${Math.round(W()/1e3)} \u79D2\uFF09\uFF0C\u76F4\u5230\u4E0E\u8C03\u5EA6\u4E2D\u5FC3\u5EFA\u7ACB\u8FDE\u63A5`)),L(e),!1}async function ve(){const e=v();if(!e.userKey)return{success:!1,error:"userKey is required for runtime token refresh"};const r=w(),t=E(e),n=_(e);try{const o=await A.post(`${t}/api/instances/runtime-tokens/refresh`,{tenantId:e.tenantId,userKey:e.userKey,instanceId:r.instanceId,instanceName:e.instanceName,runtimeBridgeBaseUrl:n},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!o.data.success||!o.data.runtimeAccessToken)return{success:!1,error:o.data.message||"scheduler did not return runtimeAccessToken"};const a=h()!==o.data.runtimeAccessToken;return K({accessToken:o.data.runtimeAccessToken,instanceId:r.instanceId,userId:o.data.userId||e.userKey,schedulerBaseUrl:t}),{success:!0,runtimeAccessToken:o.data.runtimeAccessToken,updated:a}}catch(o){const s=o;return{success:!1,error:s.response?.data?JSON.stringify(s.response.data):s.message}}}async function ye(e){const r=O(e);if(!r)return{success:!1,error:"serverUrl is required for runtime token refresh"};const t=S().find(s=>O(s.serverUrl)===r)||v();if(!t.userKey)return{success:!1,error:"userKey is required for runtime token refresh"};const n=w(),o=_(t);try{const s=await A.post(`${r}/api/instances/runtime-tokens/refresh`,{tenantId:t.tenantId,userKey:t.userKey,instanceId:n.instanceId,instanceName:t.instanceName,runtimeBridgeBaseUrl:o},{headers:{"Content-Type":"application/json"},timeout:1e4});if(!s.data.success||!s.data.runtimeAccessToken)return{success:!1,error:s.data.message||"scheduler did not return runtimeAccessToken"};const l=h(r)!==s.data.runtimeAccessToken;return C({serverBaseUrl:r,accessToken:s.data.runtimeAccessToken}),{success:!0,runtimeAccessToken:s.data.runtimeAccessToken,updated:l}}catch(s){const a=s;return{success:!1,error:a.response?.data?JSON.stringify(a.response.data):a.message}}}async function Te(){if(!u.registered||!u.instanceId)return i.info("[AutoRegister] \u5B9E\u4F8B\u672A\u6CE8\u518C\uFF0C\u65E0\u9700\u6CE8\u9500"),!0;try{const e=await ae(u.instanceId);if(e.success){i.info(`[AutoRegister] \u2713 \u6CE8\u9500\u6210\u529F: ${u.instanceId}`);const r=E(v(),u.instanceId);y().schedulerBaseUrl&&Y(r),J();try{const{stopTunnelClientForServer:n}=await import("./tunnel-client.js");n(r)}catch(n){i.warn(`[AutoRegister] \u6CE8\u9500\u540E\u505C\u6B62\u96A7\u9053\u5931\u8D25: ${n.message}`)}return u.registered=!1,u.instanceId=void 0,!0}else return i.warn(`[AutoRegister] \u6CE8\u9500\u5931\u8D25: ${e.message}`),!1}catch(e){const r=e;return i.error(`[AutoRegister] \u6CE8\u9500\u8BF7\u6C42\u5931\u8D25: ${r.message}`),!1}}function Ue(){return{...u}}function _e(){return u.registered}function Ee(){return u.instanceId}async function he(){const e=v(),r=u.instanceId,t=E(e,r),n={};if(r&&(n.instanceId=r),e.enabled&&(n.runtimeBridgeBaseUrl=_(e)),!n.instanceId&&!n.runtimeBridgeBaseUrl)return i.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6CA1\u6709 instanceId \u6216 runtimeBridgeBaseUrl\uFF0C\u8DF3\u8FC7\u6E05\u7406"),{success:!0,agentCount:0};try{i.info("[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\uFF1A\u6B63\u5728\u901A\u77E5\u8C03\u5EA6\u4E2D\u5FC3..."),i.info(`[AutoRegister] instanceId: ${n.instanceId||"(\u65E0)"}`),i.info(`[AutoRegister] runtimeBridgeBaseUrl: ${n.runtimeBridgeBaseUrl||"(\u65E0)"}`);const o=await A.post(`${t}/api/instances/bridge-restart-cleanup`,n,{headers:{"Content-Type":"application/json"},timeout:1e4});return o.data.success?(i.info(`[AutoRegister] \u2713 Bridge \u91CD\u542F\u6E05\u7406\u6210\u529F\uFF1A${o.data.message}`),i.info(`[AutoRegister] \u6E05\u7406\u4E86 ${o.data.agentCount||0} \u4E2A Agent`),{success:!0,agentCount:o.data.agentCount||0}):(i.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u5931\u8D25\uFF1A${o.data.message}`),{success:!1,error:o.data.message})}catch(o){const s=o,a=s.response?.data?JSON.stringify(s.response.data):s.message;return i.warn(`[AutoRegister] Bridge \u91CD\u542F\u6E05\u7406\u8BF7\u6C42\u5931\u8D25\uFF1A${a}`),{success:!1,error:a}}}export{Se as autoRegister,he as bridgeRestartCleanup,Ie as cancelBackgroundRegisterRetries,m as getAutoRegisterConfigFilePath,Ae as getConfiguredConnectionKeys,Ee as getInstanceId,Ue as getRegistrationState,_e as isRegistered,D as isTunnelConfig,U as loadConfig,S as loadConfigs,v as loadPrimaryLifecycleConfig,ve as requestRuntimeAccessTokenRefresh,ye as requestRuntimeAccessTokenRefreshForServer,Re as resolveSchedulerBaseUrlFromToken,Te as unregister};
|
|
2
2
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createHash as w}from"node:crypto";import{cpSync as l,existsSync as c,lstatSync as L,mkdirSync as U,readdirSync as b,readFileSync as d,realpathSync as S,rmSync as E,statSync as
|
|
2
|
-
`,"utf-8"),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u66F4\u65B0\u5230: ${u}`)):(N(e,s),T(e,s),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u662F\u6700\u65B0: ${u}`)),
|
|
1
|
+
import{createHash as w}from"node:crypto";import{cpSync as l,existsSync as c,lstatSync as L,mkdirSync as U,readdirSync as b,readFileSync as d,realpathSync as S,rmSync as E,statSync as M,symlinkSync as v,writeFileSync as W}from"node:fs";import t from"node:path";import{fileURLToPath as I}from"node:url";import{getActiveBridgeHttpPort as B,getRuntimeHomeDir as D,isDevMode as O,schedulerBaseUrl as $}from"../config.js";import{logger as i}from"../utils/logger.js";import{loadRuntimeBinding as H}from"./runtime-binding.js";const a=O()?"aws-mcp-dev":"aws-mcp",k=["AWS_PROJECT_NAME","AWS_PROMPT","AWS_ROLE_NAME","AWS_SERVER_URL","AWS_MCP_HTTP_URL","AWS_RUNTIME_BRIDGE_BASE_URL","AWS_HEARTBEAT_INTERVAL","AWS_HEARTBEAT_TIMEOUT","PATH","HOME","USERPROFILE","TMP","TEMP","SystemRoot","COMSPEC","PATHEXT","WINDIR"];function R(){const r=I(import.meta.url);return t.resolve(t.dirname(r),"..","..")}function V(r=R()){return t.join(p(r),"dist","index.js")}function p(r){return t.join(r,"package","aws-client-agent-mcp")}function f(){return t.join(D(),".aws-bridge","mcp")}function de(){return t.join(f(),"dist")}function C(r=f()){return t.join(r,".release.json")}function y(r){try{return JSON.parse(d(r,"utf-8")).version||"unknown"}catch{return"unknown"}}function x(r){return y(t.join(r,"package.json"))}function G(r){return y(t.join(p(r),"package.json"))}function g(r,e){c(r)&&F(r,e)}function F(r,e){if(M(r).isDirectory()){l(r,e,{errorOnExist:!1,force:!0,recursive:!0});return}l(r,e,{errorOnExist:!1,force:!0})}function N(r,e){const n=p(r);g(t.join(n,"package.json"),t.join(e,"package.json")),g(t.join(n,"README.md"),t.join(e,"README.md")),g(t.join(n,"package-lock.json"),t.join(e,"package-lock.json"))}function J(r){if(!c(r))return!0;const e=L(r);return e.isSymbolicLink()||e.isDirectory()}function z(r,e){if(!c(r))return!1;try{return S(r)===S(e)}catch{return!1}}function T(r,e){const n=t.join(r,"node_modules"),o=t.join(e,"node_modules");if(!c(n)){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230\u4F9D\u8D56\u76EE\u5F55\uFF0Crelease \u4EA7\u7269\u53EF\u80FD\u65E0\u6CD5\u89E3\u6790\u8FD0\u884C\u65F6\u4F9D\u8D56: ${n}`);return}if(!z(o,n)){if(!J(o)){i.warn(`[runtime-bridge] ${a} MCP \u4F9D\u8D56\u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55\u6216\u94FE\u63A5\uFF0C\u5DF2\u4FDD\u7559: ${o}`);return}E(o,{recursive:!0,force:!0}),v(n,o,process.platform==="win32"?"junction":"dir")}}function P(r,e=r){return b(r,{withFileTypes:!0}).flatMap(n=>{const o=t.join(r,n.name);return n.isDirectory()?P(o,e):n.isFile()?[t.relative(e,o).split(t.sep).join("/")]:[]})}function K(r){const e=w("sha256");for(const n of P(r).sort()){const o=t.join(r,...n.split("/")),s=M(o);e.update(n),e.update("\0"),e.update(String(s.size)),e.update("\0"),e.update(d(o)),e.update("\0")}return`sha256:${e.digest("hex")}`}function X(r){try{const e=JSON.parse(d(C(r),"utf-8"));if(typeof e.bridgeVersion=="string"&&typeof e.mcpVersion=="string"&&typeof e.distHash=="string")return{bridgeVersion:e.bridgeVersion,mcpVersion:e.mcpVersion,distHash:e.distHash,releasedAt:typeof e.releasedAt=="string"?e.releasedAt:""}}catch{return null}return null}function Y(r,e,n){return!c(r)||!e||e.bridgeVersion!==n.bridgeVersion||e.mcpVersion!==n.mcpVersion||e.distHash!==n.distHash}function q(r={}){const e=r.packageRoot||R(),n=t.dirname(V(e)),o=t.join(n,"index.js");if(!c(o))return null;if(c(t.join(e,"src")))return i.info(`[runtime-bridge] ${a} MCP \u672C\u5730\u5F00\u53D1\u6A21\u5F0F\uFF0C\u76F4\u63A5\u4F7F\u7528\u9879\u76EE dist: ${o}`),o;const s=r.releasedRoot||f(),u=t.join(s,"dist"),A=t.join(u,"index.js"),_={bridgeVersion:x(e),mcpVersion:G(e),distHash:K(n)},j=X(s);return Y(A,j,_)?(E(u,{recursive:!0,force:!0}),U(s,{recursive:!0}),N(e,s),T(e,s),l(n,u,{errorOnExist:!1,force:!0,recursive:!0}),W(C(s),`${JSON.stringify({..._,releasedAt:r.now?r.now():new Date().toISOString()},null,2)}
|
|
2
|
+
`,"utf-8"),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u66F4\u65B0\u5230: ${u}`)):(N(e,s),T(e,s),i.info(`[runtime-bridge] ${a} MCP \u5DF2\u662F\u6700\u65B0: ${u}`)),A}function Q(){return Object.fromEntries(Object.entries(process.env).filter(r=>typeof r[1]=="string"))}function Z(r){return Object.fromEntries(k.flatMap(e=>{const n=r[e];return typeof n=="string"&&n.length>0?[[e,n]]:[]}))}function ee(r){try{const e=JSON.parse(r);if(Array.isArray(e)&&e.every(n=>typeof n=="string"))return e}catch(e){i.warn(`[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u4E0D\u662F\u5408\u6CD5 JSON\uFF0C\u5DF2\u5FFD\u7565: ${e instanceof Error?e.message:String(e)}`)}return i.warn("[runtime-bridge] AWS_CLIENT_AGENT_MCP_ARGS \u5FC5\u987B\u662F string[] JSON\uFF0C\u5DF2\u5FFD\u7565"),[]}function h(r){const e=r.replace(/^((?:https?|wss?):\/\/(?:\[[^\]]+\]|[^/:?#]+):\d+):\d+(?=\/|$)/i,"$1");try{const n=new URL(e);return n.protocol==="ws:"?n.protocol="http:":n.protocol==="wss:"?n.protocol="https:":n.protocol=n.protocol.toLowerCase(),n.origin}catch{return e.replace(/\/+$/,"")}}function re(r){const e=new URL("/ws/agent",h(r));return e.protocol==="https:"?e.protocol="wss:":e.protocol="ws:",e.toString()}function ne(r){const e=h(r);return new URL("/mcp/call",e).toString()}function te(){const r=String(process.env.AWS_RUNTIME_SCHEDULER_BASE_URL||"").trim();if(r)return r;const e=H(),n=String(e.schedulerBaseUrl||"").trim();return e.status==="paired"&&n?n:$}function pe(r={}){return m(r)}function m(r={}){const e=String(process.env.AWS_CLIENT_AGENT_MCP_COMMAND||"").trim();if(e)return{source:"override",command:e,args:process.env.AWS_CLIENT_AGENT_MCP_ARGS?ee(process.env.AWS_CLIENT_AGENT_MCP_ARGS):[]};const n=r.exists||c,s=(r.release||q)();return s&&n(s)?{source:"bundled",command:process.execPath,args:[s]}:{source:"global",command:"aws-client-agent-mcp",args:[]}}function fe(r){const e=Q(),n=m(),o=te();return{command:n.command,args:n.args,env:{...Z(e),AWS_AGENT_ID:r.agentId,AWS_WORKSPACE_PATH:r.workspacePath,AWS_SERVER_URL:e.AWS_SERVER_URL||re(o),AWS_MCP_HTTP_URL:e.AWS_MCP_HTTP_URL||ne(o),AWS_RUNTIME_BRIDGE_BASE_URL:e.AWS_RUNTIME_BRIDGE_BASE_URL||`http://127.0.0.1:${B()}`,AWS_MCP_CLAIM_LAUNCH_BINDING:e.AWS_MCP_CLAIM_LAUNCH_BINDING||"true"}}}function ge(){const r=m(),e=r.args[0]?`${r.command} ${r.args.join(" ")}`:r.command;if(r.source==="global"){i.warn(`[runtime-bridge] ${a} MCP \u672A\u627E\u5230 bundled \u4EA7\u7269\uFF0C\u542F\u52A8\u65F6\u5C06\u56DE\u9000\u5230 PATH \u547D\u4EE4: ${e}`);return}i.info(`[runtime-bridge] ${a} MCP \u5DF2\u51C6\u5907(${r.source}): ${e}`)}export{a as AWS_MCP_SERVER_NAME,fe as buildAwsMcpServerConfig,ge as ensureAwsClientAgentMcpReleased,m as getAwsClientAgentMcpPreparedInfo,de as getReleasedMcpDistPath,q as releaseBundledAwsClientAgentMcp,pe as resolveAwsClientAgentMcpCommand};
|
|
3
3
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import l from"node:path";import{AiConfigService as p,CcSwitchSdk as f}from"@cc-switch/sdk";import{createMcpAdapters as g,createSkillAdapters as u}from"../adapters/cc-switch/index.js";import{getAcodeConfigFile as C,getAcodeSkillsDir as S,getClaudeConfigFile as k,getClaudeMcpConfigFile as
|
|
1
|
+
import l from"node:path";import{AiConfigService as p,CcSwitchSdk as f}from"@cc-switch/sdk";import{createMcpAdapters as g,createSkillAdapters as u}from"../adapters/cc-switch/index.js";import{getAcodeConfigFile as C,getAcodeSkillsDir as S,getClaudeConfigFile as k,getClaudeMcpConfigFile as F,getClaudeSkillsDir as m,getCodexConfigFile as x,getCodexSkillsDir as D,getUserHomeDir as v,getOpencodeConfigFile as w,getOpencodeSkillsDir as A}from"../config.js";import{getAgentInitRoot as s}from"./instance-state.js";import{InstanceService as h}from"./instance-service.js";function r(){const e=l.resolve(v());return{runtimeHome:e,acodeConfigFile:l.resolve(C()),acodeSkillsDir:l.resolve(S()),claudeConfigFile:l.resolve(k(e)),claudeMcpConfigFile:l.resolve(F(e)),claudeSkillsDir:l.resolve(m(e)),codexConfigFile:l.resolve(x(e)),codexSkillsDir:l.resolve(D(e)),opencodeConfigFile:l.resolve(w(e)),opencodeSkillsDir:l.resolve(A(e))}}function d(e){const c=s(e),o=l.join(c,"cc-switch-sdk"),i=r(),n={stateFile:l.join(o,"state.json"),backupDir:l.join(o,"backups"),acodeConfigFile:i.acodeConfigFile,acodeSkillsDir:i.acodeSkillsDir,claudeConfigFile:i.claudeConfigFile,claudeSkillsDir:i.claudeSkillsDir,claudecodeConfigFile:i.claudeMcpConfigFile,claudecodeSkillsDir:i.claudeSkillsDir,codexConfigFile:i.codexConfigFile,codexSkillsDir:i.codexSkillsDir,opencodeConfigFile:i.opencodeConfigFile,opencodeSkillsDir:i.opencodeSkillsDir,ssotSkillsDir:l.join(o,"skills")},t=g(n),a=u(n);return new f({rootDir:o,paths:n,adapters:{mcp:t,skill:a}})}async function B(e){const c=d(e);return await c.load(),c}async function b(e){const[c,o]=await Promise.all([e.importMcpFromApps(),e.importSkillsFromApps()]);return{mcpServers:c,skills:o}}function H(){const e=r();return new p({acodeConfigFile:e.acodeConfigFile,claudecodeConfigFile:e.claudeConfigFile,codexConfigFile:e.codexConfigFile,opencodeConfigFile:e.opencodeConfigFile})}function O(e,c){const o=d(e),i=s(e);return new h(o,i,c)}async function E(e,c,o,i){const n=i||await B(c),t=r();return{ok:!0,adapter:"cc-switch-sdk",action:e,agentId:String(c),payload:o,paths:t,snapshot:{skills:n.getAllSkills().length,mcpServers:n.getAllMcpServers().length}}}function U(e){const c=Array.isArray(e)?e:[],o=i=>c.includes(i);return{acode:o("acode"),claude:!1,claudecode:o("claudecode")||o("claude"),codex:o("codex"),gemini:o("gemini"),opencode:o("opencode"),openclaw:o("openclaw")}}function q(e){return e?{acode:!!e.acode,claude:!1,claudecode:!!e.claudecode||!!e.claude,codex:!!e.codex,gemini:!!e.gemini,opencode:!!e.opencode,openclaw:!!e.openclaw}:{acode:!1,claude:!1,claudecode:!1,codex:!1,gemini:!1,opencode:!1,openclaw:!1}}export{b as discoverCcSwitchConfiguredItems,H as getAiConfigService,r as getCcSwitchAppPaths,d as getCcSwitchSdk,O as getInstanceService,B as loadCcSwitchSdk,E as runCcSwitchAdapter,q as toSdkApps,U as toSdkAppsFromEnabledTools};
|
|
2
2
|
|