@orcha-ai/runtime-bridge 0.1.42 → 0.1.43
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 +4 -4
- package/bin/orcha-runtime-bridge.js +21 -18
- package/openclaw-plugin/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,16 +76,16 @@ npm run build
|
|
|
76
76
|
|
|
77
77
|
Build produces `bin/orcha-runtime-bridge.js` and the clean npm package in `dist/package`, including the OpenClaw plugin. Bridge is distributed through npm; backend images do not bundle a separate browser download.
|
|
78
78
|
|
|
79
|
-
Version 0.1.
|
|
79
|
+
Version 0.1.43 routes replies, native `message` tool sends, and background notifications through the same Orcha IM sender, and streams native Channel tools and host-visible reasoning/process updates through the existing Orcha progress UI. The plugin sends response headers immediately and heartbeats every 15 seconds; task deadlines and transport timeouts remain explicit failures. Bridge and the bundled plugin must upgrade together: native delivery preflight and content negotiation reject the old JSON-only contract before starting a host turn. `orcha-runtime-node.v2` is unchanged. Deploying Orcha does not publish npm or upgrade connected devices automatically. Build and validate the release tarball before publishing:
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
82
|
npm run pack:local
|
|
83
|
-
npm publish ./dist/orcha-ai-runtime-bridge-0.1.
|
|
83
|
+
npm publish ./dist/orcha-ai-runtime-bridge-0.1.43.tgz --access public --registry=https://registry.npmjs.org
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
After updating the npm package on a device, run `orcha-runtime-bridge reload --url ...` to switch the existing background process to the installed version. The earlier manually downloaded foreground process must be stopped before connecting with npm to avoid duplicate connections.
|
|
86
|
+
After updating the npm package on a device, run `orcha-runtime-bridge reload --url ...` to switch the existing background process to the installed version. `reload` and `restart` also install/update the bundled plugin for OpenClaw targets saved on that device, using the target's executable and environment. Bridge stops before `openclaw plugins install <bundled-path> --force` and `openclaw gateway restart`; it starts again only after Gateway health succeeds and any configured MCP binding endpoint passes native Channel protocol preflight. Targets sharing an executable and environment update together. Installation/restart/health failures stop the command with an error and leave Bridge stopped; fix the reported problem and rerun `reload`. Package/executable preflight failures leave the existing Bridge running. The earlier manually downloaded foreground process must be stopped before connecting with npm to avoid duplicate connections.
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
Installing/updating the npm package alone does not change OpenClaw; run Bridge `reload` afterwards. Automatic plugin installation uses OpenClaw's official installer and preserves existing plugin/channel configuration. It does not create account credentials or configure MCP authorization. Create a binding in the Orcha Agent's **消息通道** tab, merge its generated `channels.orcha.accounts` configuration into OpenClaw, and retain the existing Gateway/MCP binding configuration below. A remote `mcpBridgeUrl` cannot be upgraded by the local reload command: update its plugin on the Gateway host. Source-checkout reload requires `npm run build` first to provide the self-contained plugin in `dist/package`. Existing ACP/CLI targets without a native binding continue using their configured execution path. Real OpenClaw host/model acceptance remains required before production use.
|
|
89
89
|
|
|
90
90
|
Native delivery uses `application/x-orcha-channel-events-v2+ndjson` with `heartbeat`, `update`, `result`, and `error` frames. Tool events are restricted to the exact host run and honor hidden-progress flags; reasoning uses only the host's public reply callback without enabling hidden reasoning. Final text and attachments are sent through `POST /api/agent-channels/messages`; terminal frames carry only `messageIds` and status. Core validates the existing receipts and projects execution metadata onto the original reply. Core, Bridge and plugin must upgrade together; old JSON/v1 streams and body-based background completion are incompatible. Skill authors use the native `message` tool with `action: "send"`, `channel: "orcha"`, `accountId` (binding ID), `target` (session ID), and `message`/`media`. Credentials stay in the configured account. Durable queue IDs and native tool idempotency keys are persisted before sending; unknown acknowledgements reconcile through the same idempotent Core endpoint. Core persists updates under the Attempt fence and deduplicates their stable channel IDs before acknowledging them. An active plugin operation keeps at most 16 MiB of replay history; exceeding it fails explicitly. Plugin restarts cannot reconstruct an in-flight host turn and continue to fail with `RUNTIME_OPERATION_NOT_FOUND`. This release requires no database migration or new environment variables.
|
|
91
91
|
|
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawn as Da}from"node:child_process";import{closeSync as va,existsSync as Xn,mkdirSync as Ha,openSync as Fa,readFileSync as cr,rmSync as $a,statSync as Gn,writeFileSync as Yn}from"node:fs";import{dirname as Ba,resolve as dr}from"node:path";import{fileURLToPath as ja}from"node:url";import{createHash as Rr}from"node:crypto";import{mkdir as fs,readFile as ps,writeFile as hs,rename as ms}from"node:fs/promises";import{join as yr}from"node:path";import{homedir as gs,hostname as _s}from"node:os";import{execFile as is}from"node:child_process";import{access as os,realpath as as}from"node:fs/promises";import{constants as cs}from"node:fs";import{delimiter as us,join as gr,isAbsolute as _r}from"node:path";import{homedir as mr}from"node:os";async function ls(e,t=process.env){let r=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let n of(t.PATH||"").split(us).filter(_r))for(let s of r){let i=gr(n,`${e}${s}`);try{return await os(i,cs.X_OK),i}catch{}}return null}function ds(e,t){return new Promise(r=>is(e,t,{timeout:8e3,maxBuffer:1024*1024,windowsHide:!0},(n,s)=>r({code:n?n.code:0,stdout:String(s||"")})))}async function ae(e){let t=e==="~"?mr():e.startsWith("~/")?gr(mr(),e.slice(2)):e;if(!_r(t))throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u5FC5\u987B\u662F\u8BBE\u5907\u4E0A\u7684\u7EDD\u5BF9\u8DEF\u5F84\u6216 ~/ \u5F00\u5934\u7684\u8DEF\u5F84");let r=await as(t),{stat:n}=await import("node:fs/promises");if(!(await n(r)).isDirectory())throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u662F\u6587\u4EF6\u5939");return r}async function Tr({find:e=ls,run:t=ds,cwd:r=process.cwd()}={}){return(await Promise.all(["codex","claude","openclaw"].map(async s=>{let i=await e(s);if(!i)return[];let o={codex:"Codex",claude:"Claude Code",openclaw:"OpenClaw"}[s],c=await t(i,["--version"]),u=c.code===0&&c.stdout.match(/\d+\.\d+\.\d+[^\s]*/)?.[0]||"",d={id:s,name:o,framework:s,version:u,workspace:r,managed:!1};if(c.code!==0)return[{...d,status:"error",message:"\u7A0B\u5E8F\u65E0\u6CD5\u542F\u52A8\uFF0C\u8BF7\u5728\u672C\u673A\u68C0\u67E5\u5B89\u88C5"}];if(s==="openclaw"){let h=await t(i,["agents","list","--json"]),m;try{m=JSON.parse(h.stdout)}catch{}if(h.code!==0||!Array.isArray(m))return[{...d,status:"error",message:"\u65E0\u6CD5\u8BFB\u53D6 OpenClaw \u667A\u80FD\u4F53\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u914D\u7F6E"}];let T=await t(i,["health","--json"]);return m.filter(R=>typeof R.id=="string"&&typeof R.workspace=="string").slice(0,32).map(R=>({...d,id:`openclaw:${R.id}`,name:R.name||R.identityName||R.id,workspace:R.workspace,managed:!0,localAgentId:R.id,command:i,status:T.code===0?"ready":"needs_setup",message:T.code===0?"":"\u8BF7\u5148\u5728\u672C\u673A\u542F\u52A8\u5E76\u914D\u7F6E OpenClaw Gateway"}))}let f=await t(i,s==="codex"?["login","status"]:["auth","status"]),p=f.code===0?"ready":f.code===1?"needs_login":"error";return[{...d,command:i,status:p,message:p==="needs_login"?`\u8BF7\u5728\u672C\u673A\u8FD0\u884C ${s} ${s==="codex"?"login":"auth login"}`:p==="error"?"\u767B\u5F55\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C":""}]}))).flat()}async function wr(e,t){let r=`${e}.${process.pid}.tmp`;await hs(r,JSON.stringify(t),{mode:384}),await ms(r,e)}function ue(e){let t=new URL(e);if(t.username||t.password||t.search||t.hash||t.protocol!=="https:"&&!(t.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(t.hostname)))throw new Error("\u8FDE\u63A5\u5730\u5740\u5FC5\u987B\u4F7F\u7528 HTTPS\uFF1B\u4EC5\u672C\u673A\u5F00\u53D1\u5141\u8BB8 HTTP");let r=yr(gs(),".orcha","devices"),n=yr(r,Rr("sha256").update(t.toString()).digest("hex").slice(0,20));return{address:t,root:r,profile:`${n}.json`,pidFile:`${n}.pid`,logFile:`${n}.log`}}async function It(e,{url:t,pairCode:r}){let{address:n,root:s,profile:i}=ue(t||e.orchaUrl);await fs(s,{recursive:!0,mode:448});let o;if(r){let c=await fetch(new URL("api/agent-devices/pairings/exchange",`${n.toString().replace(/\/+$/,"")}/`),{method:"POST",redirect:"error",headers:{"content-type":"application/json"},signal:AbortSignal.timeout(15e3),body:JSON.stringify({code:r,name:_s()})}),u=await c.json();if(!c.ok||!u.success)throw new Error(u.message||u.detail||"\u8BBE\u5907\u8FDE\u63A5\u5931\u8D25");o={...u.data,targets:{}},await wr(i,o)}else try{o=JSON.parse(await ps(i,"utf8"))}catch{throw new Error("\u6CA1\u6709\u5DF2\u8FDE\u63A5\u8BBE\u5907\uFF0C\u8BF7\u4ECE\u667A\u80FD\u4F53\u9875\u9762\u751F\u6210\u8FDE\u63A5\u7801")}e.orchaUrl=n.toString().replace(/\/+$/,""),e.mode="node",e.nodeId=o.nodeCode,e.nodeName=o.nodeName,e.nodeToken=o.token,e.targets=o.targets,e.defaultTargetCode="",e.deviceConnection=new ce(e,o,async()=>wr(i,o))}var ce=class{constructor(t,r,n,s=Tr){this.config=t,this.profile=r,this.persist=n,this.discover=s}async candidates(){return{candidates:(await this.discover()).map(({command:r,localAgentId:n,...s})=>s)}}async configure(t,r){if(!Array.isArray(t.selections)||!t.selections.length||t.selections.length>32)throw new Error("\u6DFB\u52A0\u9879\u65E0\u6548");let n=new Map((await this.discover()).map(u=>[u.id,u])),s={...r.targets},i=[],o=new Set;for(let u of t.selections){let d=n.get(u.candidateId);if(!d||d.status!=="ready"||o.has(d.id))throw new Error("\u53D1\u73B0\u7ED3\u679C\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u6D4B");o.add(d.id);let f=String(u.name||"").trim();if(!f||f.length>128)throw new Error("\u667A\u80FD\u4F53\u540D\u79F0\u65E0\u6548");let p=await ae(String(u.workspace||""));if(d.managed&&p!==await ae(d.workspace))throw new Error("\u5DF2\u6709\u667A\u80FD\u4F53\u5FC5\u987B\u6CBF\u7528\u672C\u673A\u5DE5\u4F5C\u76EE\u5F55");let h=`${this.config.nodeId}:${Rr("sha256").update(d.id).digest("hex").slice(0,20)}`;if([...r.sessions.values()].some(m=>m.targetCode===h))throw new Error("\u6B64\u667A\u80FD\u4F53\u4ECD\u6709\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u7ED3\u675F\u4F1A\u8BDD\u518D\u4FEE\u6539\u63A5\u5165");s[h]={name:f,workspace:p,command:d.command,type:d.managed?"openclaw":"cli",...d.managed?{openclawAgentId:d.localAgentId}:d.framework==="codex"?{terminalProtocol:"codex",args:["exec","--skip-git-repo-check","--json"],promptMode:"stdin",outputMode:"json-lines",captureLastMessage:!0}:{terminalProtocol:"claude",args:["-p","--output-format","json","--no-session-persistence"],promptMode:"args",outputMode:"json-lines"}},i.push({candidateId:d.id,name:f,workspace:p,targetCode:h,framework:d.framework})}let c=this.profile.targets;this.profile.targets=s;try{await this.persist()}catch(u){throw this.profile.targets=c,u}return r.targets=s,this.config.targets=s,r.notifyCapacityChanged(),{agents:i}}};import{createHash as Po,randomUUID as Jt}from"node:crypto";var et="0.1.42";function pt(){return new Date().toISOString()}function U(e,t=2){return String(e).padStart(t,"0")}function Er(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${U(Math.floor(r/60))}:${U(r%60)}`}function Ts(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${U(e.getMonth()+1)}-${U(e.getDate())}`,`T${U(e.getHours())}:${U(e.getMinutes())}:${U(e.getSeconds())}.${U(e.getMilliseconds(),3)}`,Er(t)].join("")}function ys(e,t){let r=new Intl.DateTimeFormat("en-US",{timeZone:t,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}),n={};for(let s of r.formatToParts(e))s.type!=="literal"&&(n[s.type]=Number(s.value));return n}function ws(e,t){let r=ys(e,t),n=Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second,e.getMilliseconds()),s=Math.round((n-e.getTime())/6e4);return[`${r.year}-${U(r.month)}-${U(r.day)}`,`T${U(r.hour)}:${U(r.minute)}:${U(r.second)}.${U(e.getMilliseconds(),3)}`,Er(s)].join("")}function Rs(e=new Date){let t=a(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return ws(e,t)}catch{return Ts(e)}}function l(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function a(e){return String(e??"").trim()}function _(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)?r:t}function x(e){return Array.isArray(e)?e.map(String):[]}function rt(e,t,r=process.cwd()){let n=l(e)?e:{};return a(n.cwd)||a(n.workspace)||a(t)||a(r)||process.cwd()}var Ct="[redacted]",Es=/(authorization|api[_-]?key|credential|password|secret|token)/i;function At(e){return Es.test(a(e))}function Sr(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(Ct))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${Ct}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${Ct}`)}function W(e,t=new WeakSet){if(e==null)return e;if(typeof e=="bigint")return e.toString();if(typeof e!="object")return e;if(e instanceof Date)return e.toISOString();if(e instanceof Error){if(t.has(e))return"[circular]";t.add(e);let s={name:e.name,message:e.message};e.stack&&(s.stack=e.stack);for(let i of Object.keys(e))s[i]=W(e[i],t);return t.delete(e),s}if(t.has(e))return"[circular]";if(t.add(e),Array.isArray(e)){let s=e.map(i=>W(i,t));return t.delete(e),s}let r={},n=At(e.name||e.key);for(let[s,i]of Object.entries(e))r[s]=At(s)||n&&s.toLowerCase()==="value"?Ct:W(i,t);return t.delete(e),r}function Or(e,t=4e3){let r=JSON.stringify(W(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function g(e,t,r,n={}){let s={ts:Rs(),level:e,module:t,msg:r,...l(n)?W(n):{}};console.error(JSON.stringify(s))}function xt(e){return Array.isArray(e)?e.map(t=>l(t)?t.type==="text"?a(t.text):t.type==="file"?a(t.uri):t.type==="image"?a(t.uri):"":"").filter(Boolean).join(`
|
|
3
|
-
`)
|
|
2
|
+
import{spawn as Ja}from"node:child_process";import{closeSync as Xa,existsSync as gr,mkdirSync as Ya,openSync as Qa,readFileSync as pr,rmSync as Za,statSync as Qn,writeFileSync as ns}from"node:fs";import{dirname as ss,resolve as dt}from"node:path";import{fileURLToPath as tc}from"node:url";import{createHash as Cr}from"node:crypto";import{mkdir as Ts,readFile as ws,writeFile as Rs,rename as Es}from"node:fs/promises";import{join as Or}from"node:path";import{homedir as Ss,hostname as Os}from"node:os";import{execFile as ps}from"node:child_process";import{access as hs,realpath as ms}from"node:fs/promises";import{constants as gs}from"node:fs";import{delimiter as _s,join as Rr,isAbsolute as Er}from"node:path";import{homedir as wr}from"node:os";async function ue(e,t=process.env){let r=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let n of(t.PATH||"").split(_s).filter(Er))for(let s of r){let i=Rr(n,`${e}${s}`);try{return await hs(i,gs.X_OK),i}catch{}}return null}function ys(e,t){return new Promise(r=>ps(e,t,{timeout:8e3,maxBuffer:1024*1024,windowsHide:!0},(n,s)=>r({code:n?n.code:0,stdout:String(s||"")})))}async function le(e){let t=e==="~"?wr():e.startsWith("~/")?Rr(wr(),e.slice(2)):e;if(!Er(t))throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u5FC5\u987B\u662F\u8BBE\u5907\u4E0A\u7684\u7EDD\u5BF9\u8DEF\u5F84\u6216 ~/ \u5F00\u5934\u7684\u8DEF\u5F84");let r=await ms(t),{stat:n}=await import("node:fs/promises");if(!(await n(r)).isDirectory())throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u662F\u6587\u4EF6\u5939");return r}async function Sr({find:e=ue,run:t=ys,cwd:r=process.cwd()}={}){return(await Promise.all(["codex","claude","openclaw"].map(async s=>{let i=await e(s);if(!i)return[];let o={codex:"Codex",claude:"Claude Code",openclaw:"OpenClaw"}[s],c=await t(i,["--version"]),u=c.code===0&&c.stdout.match(/\d+\.\d+\.\d+[^\s]*/)?.[0]||"",d={id:s,name:o,framework:s,version:u,workspace:r,managed:!1};if(c.code!==0)return[{...d,status:"error",message:"\u7A0B\u5E8F\u65E0\u6CD5\u542F\u52A8\uFF0C\u8BF7\u5728\u672C\u673A\u68C0\u67E5\u5B89\u88C5"}];if(s==="openclaw"){let h=await t(i,["agents","list","--json"]),m;try{m=JSON.parse(h.stdout)}catch{}if(h.code!==0||!Array.isArray(m))return[{...d,status:"error",message:"\u65E0\u6CD5\u8BFB\u53D6 OpenClaw \u667A\u80FD\u4F53\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u914D\u7F6E"}];let y=await t(i,["health","--json"]);return m.filter(R=>typeof R.id=="string"&&typeof R.workspace=="string").slice(0,32).map(R=>({...d,id:`openclaw:${R.id}`,name:R.name||R.identityName||R.id,workspace:R.workspace,managed:!0,localAgentId:R.id,command:i,status:y.code===0?"ready":"needs_setup",message:y.code===0?"":"\u8BF7\u5148\u5728\u672C\u673A\u542F\u52A8\u5E76\u914D\u7F6E OpenClaw Gateway"}))}let f=await t(i,s==="codex"?["login","status"]:["auth","status"]),p=f.code===0?"ready":f.code===1?"needs_login":"error";return[{...d,command:i,status:p,message:p==="needs_login"?`\u8BF7\u5728\u672C\u673A\u8FD0\u884C ${s} ${s==="codex"?"login":"auth login"}`:p==="error"?"\u767B\u5F55\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C":""}]}))).flat()}async function Ir(e,t){let r=`${e}.${process.pid}.tmp`;await Rs(r,JSON.stringify(t),{mode:384}),await Es(r,e)}function fe(e){let t=new URL(e);if(t.username||t.password||t.search||t.hash||t.protocol!=="https:"&&!(t.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(t.hostname)))throw new Error("\u8FDE\u63A5\u5730\u5740\u5FC5\u987B\u4F7F\u7528 HTTPS\uFF1B\u4EC5\u672C\u673A\u5F00\u53D1\u5141\u8BB8 HTTP");let r=Or(Ss(),".orcha","devices"),n=Or(r,Cr("sha256").update(t.toString()).digest("hex").slice(0,20));return{address:t,root:r,profile:`${n}.json`,pidFile:`${n}.pid`,logFile:`${n}.log`}}async function At(e,{url:t,pairCode:r}){let{address:n,root:s,profile:i}=fe(t||e.orchaUrl);await Ts(s,{recursive:!0,mode:448});let o;if(r){let c=await fetch(new URL("api/agent-devices/pairings/exchange",`${n.toString().replace(/\/+$/,"")}/`),{method:"POST",redirect:"error",headers:{"content-type":"application/json"},signal:AbortSignal.timeout(15e3),body:JSON.stringify({code:r,name:Os()})}),u=await c.json();if(!c.ok||!u.success)throw new Error(u.message||u.detail||"\u8BBE\u5907\u8FDE\u63A5\u5931\u8D25");o={...u.data,targets:{}},await Ir(i,o)}else try{o=JSON.parse(await ws(i,"utf8"))}catch{throw new Error("\u6CA1\u6709\u5DF2\u8FDE\u63A5\u8BBE\u5907\uFF0C\u8BF7\u4ECE\u667A\u80FD\u4F53\u9875\u9762\u751F\u6210\u8FDE\u63A5\u7801")}e.orchaUrl=n.toString().replace(/\/+$/,""),e.mode="node",e.nodeId=o.nodeCode,e.nodeName=o.nodeName,e.nodeToken=o.token,e.targets=o.targets,e.defaultTargetCode="",e.deviceConnection=new de(e,o,async()=>Ir(i,o))}var de=class{constructor(t,r,n,s=Sr){this.config=t,this.profile=r,this.persist=n,this.discover=s}async candidates(){return{candidates:(await this.discover()).map(({command:r,localAgentId:n,...s})=>s)}}async configure(t,r){if(!Array.isArray(t.selections)||!t.selections.length||t.selections.length>32)throw new Error("\u6DFB\u52A0\u9879\u65E0\u6548");let n=new Map((await this.discover()).map(u=>[u.id,u])),s={...r.targets},i=[],o=new Set;for(let u of t.selections){let d=n.get(u.candidateId);if(!d||d.status!=="ready"||o.has(d.id))throw new Error("\u53D1\u73B0\u7ED3\u679C\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u6D4B");o.add(d.id);let f=String(u.name||"").trim();if(!f||f.length>128)throw new Error("\u667A\u80FD\u4F53\u540D\u79F0\u65E0\u6548");let p=await le(String(u.workspace||""));if(d.managed&&p!==await le(d.workspace))throw new Error("\u5DF2\u6709\u667A\u80FD\u4F53\u5FC5\u987B\u6CBF\u7528\u672C\u673A\u5DE5\u4F5C\u76EE\u5F55");let h=`${this.config.nodeId}:${Cr("sha256").update(d.id).digest("hex").slice(0,20)}`;if([...r.sessions.values()].some(m=>m.targetCode===h))throw new Error("\u6B64\u667A\u80FD\u4F53\u4ECD\u6709\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u7ED3\u675F\u4F1A\u8BDD\u518D\u4FEE\u6539\u63A5\u5165");s[h]={name:f,workspace:p,command:d.command,type:d.managed?"openclaw":"cli",...d.managed?{openclawAgentId:d.localAgentId}:d.framework==="codex"?{terminalProtocol:"codex",args:["exec","--skip-git-repo-check","--json"],promptMode:"stdin",outputMode:"json-lines",captureLastMessage:!0}:{terminalProtocol:"claude",args:["-p","--output-format","json","--no-session-persistence"],promptMode:"args",outputMode:"json-lines"}},i.push({candidateId:d.id,name:f,workspace:p,targetCode:h,framework:d.framework})}let c=this.profile.targets;this.profile.targets=s;try{await this.persist()}catch(u){throw this.profile.targets=c,u}return r.targets=s,this.config.targets=s,r.notifyCapacityChanged(),{agents:i}}};import{execFile as Hs}from"node:child_process";import{constants as Fs}from"node:fs";import{access as kr,readFile as vr,realpath as $s}from"node:fs/promises";import{join as pe}from"node:path";import{promisify as Bs}from"node:util";var z="0.1.43";function gt(){return new Date().toISOString()}function P(e,t=2){return String(e).padStart(t,"0")}function Ar(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${P(Math.floor(r/60))}:${P(r%60)}`}function Is(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${P(e.getMonth()+1)}-${P(e.getDate())}`,`T${P(e.getHours())}:${P(e.getMinutes())}:${P(e.getSeconds())}.${P(e.getMilliseconds(),3)}`,Ar(t)].join("")}function Cs(e,t){let r=new Intl.DateTimeFormat("en-US",{timeZone:t,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}),n={};for(let s of r.formatToParts(e))s.type!=="literal"&&(n[s.type]=Number(s.value));return n}function As(e,t){let r=Cs(e,t),n=Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second,e.getMilliseconds()),s=Math.round((n-e.getTime())/6e4);return[`${r.year}-${P(r.month)}-${P(r.day)}`,`T${P(r.hour)}:${P(r.minute)}:${P(r.second)}.${P(e.getMilliseconds(),3)}`,Ar(s)].join("")}function xs(e=new Date){let t=a(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return As(e,t)}catch{return Is(e)}}function l(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function a(e){return String(e??"").trim()}function _(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)?r:t}function x(e){return Array.isArray(e)?e.map(String):[]}function it(e,t,r=process.cwd()){let n=l(e)?e:{};return a(n.cwd)||a(n.workspace)||a(t)||a(r)||process.cwd()}var xt="[redacted]",Ns=/(authorization|api[_-]?key|credential|password|secret|token)/i;function st(e){return Ns.test(a(e))}function Nt(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(xt))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${xt}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${xt}`)}function X(e,t=new WeakSet){if(e==null)return e;if(typeof e=="bigint")return e.toString();if(typeof e!="object")return e;if(e instanceof Date)return e.toISOString();if(e instanceof Error){if(t.has(e))return"[circular]";t.add(e);let s={name:e.name,message:e.message};e.stack&&(s.stack=e.stack);for(let i of Object.keys(e))s[i]=X(e[i],t);return t.delete(e),s}if(t.has(e))return"[circular]";if(t.add(e),Array.isArray(e)){let s=e.map(i=>X(i,t));return t.delete(e),s}let r={},n=st(e.name||e.key);for(let[s,i]of Object.entries(e))r[s]=st(s)||n&&s.toLowerCase()==="value"?xt:X(i,t);return t.delete(e),r}function xr(e,t=4e3){let r=JSON.stringify(X(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function g(e,t,r,n={}){let s={ts:xs(),level:e,module:t,msg:r,...l(n)?X(n):{}};console.error(JSON.stringify(s))}var Y="application/x-orcha-channel-events-v2+ndjson";function U(e,t){return Object.assign(new Error(t||(["run_timeout","RUNTIME_NODE_TIMEOUT"].includes(e)?"OpenClaw \u539F\u751F IM \u6267\u884C\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002":e==="OPENCLAW_CHANNEL_PROTOCOL_MISMATCH"?"OpenClaw \u63D2\u4EF6\u4E0E Bridge \u7684\u539F\u751F IM \u534F\u8BAE\u4E0D\u517C\u5BB9\uFF0C\u8BF7\u914D\u5957\u5347\u7EA7\u3002":`OpenClaw \u539F\u751F IM \u6267\u884C\u5931\u8D25\uFF08${e}\uFF09`)),{code:e})}function Nr(e,t){let r=e.cause?.code||e.code;return t?.reason?.name==="TimeoutError"||e.name==="TimeoutError"||["UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT","UND_ERR_CONNECT_TIMEOUT","ETIMEDOUT"].includes(r)?Object.assign(U("RUNTIME_NODE_TIMEOUT","OpenClaw \u8FDE\u63A5\u6216\u7B49\u5F85\u54CD\u5E94\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002"),{detail:{causeCode:r||"REQUEST_TIMEOUT"}}):e}async function br(e,t){if(e.headers.get("content-type")!==Y)throw await e.body?.cancel(),U("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");let r=Buffer.alloc(0);for await(let n of e.body){r=Buffer.concat([r,n]);let s;for(;(s=r.indexOf(10))>=0;){if(s>2097152)throw U("OPENCLAW_CHANNEL_FRAME_TOO_LARGE");let i=r.subarray(0,s).toString("utf8");r=r.subarray(s+1);let o;try{o=JSON.parse(i)}catch{throw U("OPENCLAW_CHANNEL_INVALID_FRAME")}if(o.type!=="heartbeat")if(o.type==="update"&&o.payload?.update&&o.payload?._meta?.channelUpdateId)await t(o.payload);else{if(o.type==="result"&&o.result?.stopReason)return o.result;throw o.type==="error"&&typeof o.code=="string"?U(o.code):U("OPENCLAW_CHANNEL_INVALID_FRAME")}}if(r.length>2097152)throw U("OPENCLAW_CHANNEL_FRAME_TOO_LARGE")}throw U("OPENCLAW_CHANNEL_STREAM_INTERRUPTED","OpenClaw \u8FC7\u7A0B\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u4EFB\u52A1\u7EC8\u6001\uFF0C\u8BF7\u68C0\u67E5\u8282\u70B9\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002")}import{createServer as Ms}from"node:http";import{randomBytes as Us}from"node:crypto";var bt={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs"]};var Ps=Object.freeze([...bt.controlTools,...bt.residentTools]),Ls=new Set(Ps),ks=8*1024*1024;function Mt(e,t){if(!Array.isArray(e)||e.length!==1)throw new Error("one task-scoped Orcha MCP server is required");let r=e[0],n=new URL(r.url);if(r.name!=="orcha"||r.type!=="http"||!["http:","https:"].includes(n.protocol)||n.username||n.password||n.hash||t&&n.href!==new URL(t).href)throw new Error("Orcha MCP server does not match the trusted binding");let s=Object.fromEntries((r.headers||[]).map(({name:i,value:o})=>[i.toLowerCase(),o]));if(!String(s.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:n.href,headers:{...s,"content-type":"application/json",accept:"application/json"}}}async function Ur(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>ks)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function Pr(e,t,r){let n=await fetch(e.url,{method:"POST",headers:e.headers,body:JSON.stringify(t),redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(36e5),...r?[r]:[]])});if(!n.ok)throw new Error(`Orcha MCP request failed (${n.status})`);if(n.status===202||n.status===204)return null;let s=await Ur(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function Mr(e,t){let r=await Pr(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},t),n=r?.result?.tools;if(r?.error)throw new Error("Orcha MCP tool discovery failed");return vs(n)}function vs(e){if(!Array.isArray(e)||e.some(t=>!t||!Ls.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&bt.controlTools.some(t=>!e.some(r=>r.name===t)))throw new Error("Orcha MCP returned an unsupported or invalid authorized tool catalog");return e}function Ds(e,t){let r=s=>Array.isArray(s)?s.map(r):s&&typeof s=="object"?Object.fromEntries(Object.keys(s).sort().map(i=>[i,r(s[i])])):s,n=s=>s.map(({name:i,inputSchema:o})=>({name:i,inputSchema:o})).sort((i,o)=>i.name.localeCompare(o.name));return JSON.stringify(r(n(e)))===JSON.stringify(r(n(t)))}async function Lr(e){let t=Mt(e),r=new AbortController,n=await Mr(t,r.signal),s=Us(32).toString("hex"),i=Ms(async(o,c)=>{if(o.url!=="/mcp"||o.headers.authorization!==`Bearer ${s}`){c.writeHead(403).end();return}if(o.method!=="POST"){c.writeHead(405).end();return}try{let u=await Ur(o);if(!u||u.jsonrpc!=="2.0"||typeof u.method!="string")throw new Error("Invalid MCP request");if(u.method==="tools/call"&&!n.some(f=>f.name===u.params?.name))throw new Error("Tool is not authorized in this task binding");let d=await Pr(t,u,r.signal);c.writeHead(d===null?202:200,{"content-type":"application/json"}),c.end(d===null?"":JSON.stringify(d))}catch{c.writeHead(502,{"content-type":"application/json"}).end(JSON.stringify({error:"The task-scoped Orcha MCP connection failed"}))}});return await new Promise((o,c)=>{i.once("error",c),i.listen(0,"127.0.0.1",o)}),{url:`http://127.0.0.1:${i.address().port}/mcp`,token:s,async refresh(o){let c=Mt(o,t.url);if(!Ds(n,await Mr(c,r.signal)))throw new Error("The frozen MCP tool catalog changed; start a new task");t=c},async close(){r.abort(),i.closeAllConnections(),await new Promise(o=>i.close(o))}}}var V=class{constructor(t,r){this.target=t,this.identity=r,this.bound=!1}async request(t,r,n=!1,s="mcp-bindings",i=3e4,o=null){let c=a(this.target.mcpBridgeUrl),u=a(this.target.mcpBridgeTokenEnv),d=this.target.env?.[u]||process.env[u];if(!c||!u||!d)throw Object.assign(new Error("OpenClaw requires the Orcha tool plugin, mcpBridgeUrl and mcpBridgeTokenEnv"),{code:"OPENCLAW_MCP_NOT_CONFIGURED"});let f=new URL(c);if(!["http:","https:"].includes(f.protocol)||f.username||f.password||f.pathname!=="/plugins/orcha-runtime/mcp-bindings"||f.search||f.hash)throw new Error("OpenClaw MCP binding URL must be the trusted Gateway plugin route");if(!["mcp-bindings","deliveries","background"].includes(s))throw new Error("Unsupported Orcha plugin route");f.pathname=`/plugins/orcha-runtime/${s}`;let p=AbortSignal.timeout(i);try{let h=await fetch(f,{method:t,redirect:"error",signal:p,headers:{authorization:`Bearer ${d}`,"content-type":"application/json",...o?{accept:Y}:{},...n?{"if-match":this.identity.runId}:{}},...r!==void 0?{body:JSON.stringify(r)}:{}});if(t==="GET"&&s==="deliveries"&&[404,405].includes(h.status))throw await h.body?.cancel(),U("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");if(h.ok&&o)return await br(h,o);let m=await h.json();if(!h.ok)throw U(m.error||"OPENCLAW_MCP_BINDING_FAILED");return m}catch(h){throw Nr(h,p)}}async bind(t,r=!1){Mt(t),await this.request("PUT",{...this.identity,mcpServer:t[0]},r),this.bound=!0}async close(){this.bound&&(await this.request("DELETE",{runId:this.identity.runId,sessionKey:this.identity.sessionKey}),this.bound=!1)}};var js=Bs(Hs),qs=12e4;async function Dr(e,t){let r=new Map,n=[];for(let s of Object.values(e)){if(s.type!=="openclaw")continue;if(s.mcpBridgeUrl&&(n.push(s),!["localhost","127.0.0.1","[::1]"].includes(new URL(s.mcpBridgeUrl).hostname))){process.stderr.write(`\u8FDC\u7A0B OpenClaw Gateway \u7684\u914D\u5957\u63D2\u4EF6\u9700\u5728\u6240\u5728\u4E3B\u673A\u66F4\u65B0\uFF1Breload \u5C06\u68C0\u67E5\u5176\u534F\u8BAE\u3002
|
|
3
|
+
`);continue}let i={...process.env,...s.env},o=a(s.command)||"openclaw",c=o.includes("/")?o:await ue(o,i);if(!c)throw new Error("\u627E\u4E0D\u5230\u5DF2\u63A5\u5165\u7684 OpenClaw\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u5B89\u88C5\u540E\u91CD\u8BD5 reload");let u=await $s(c);await kr(u,Fs.X_OK);let d=JSON.stringify([u,Object.entries(i).sort(([f],[p])=>f.localeCompare(p))]);r.has(d)||r.set(d,{command:u,env:i})}if(r.size)try{let s=JSON.parse(await vr(pe(t,"openclaw.plugin.json"),"utf8")),i=JSON.parse(await vr(pe(t,"package.json"),"utf8"));if(await kr(pe(t,"index.js")),s.id!=="orcha-runtime"||i.version!==z)throw new Error("\u63D2\u4EF6\u6807\u8BC6\u6216\u7248\u672C\u4E0D\u5339\u914D")}catch(s){throw new Error("\u914D\u5957 OpenClaw \u63D2\u4EF6\u7F3A\u5931\u3001\u635F\u574F\u6216\u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u5B89\u88C5 Bridge\uFF1B\u6E90\u7801\u8FD0\u884C\u8BF7\u5148 npm run build",{cause:s})}return async()=>{for(let s of r.values()){process.stderr.write(`\u6B63\u5728\u5B89\u88C5\u914D\u5957 OpenClaw \u63D2\u4EF6\u5E76\u91CD\u542F Gateway\u2026
|
|
4
|
+
`),await he(s,["plugins","install",t,"--force"]),await he(s,["gateway","restart"]);let i=await he(s,["health","--json"]);if(JSON.parse(i).ok!==!0)throw new Error("OpenClaw Gateway \u5065\u5EB7\u68C0\u67E5\u5931\u8D25\uFF0CBridge \u672A\u542F\u52A8\uFF0C\u8BF7\u4FEE\u590D\u540E\u91CD\u8BD5 reload");process.stderr.write(`OpenClaw \u914D\u5957\u63D2\u4EF6\u5DF2\u66F4\u65B0\uFF0CGateway \u5065\u5EB7\u68C0\u67E5\u901A\u8FC7\u3002
|
|
5
|
+
`)}for(let s of n)if((await new V(s,{}).request("GET",void 0,!1,"deliveries")).streamType!==Y)throw U("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH")}}async function he(e,t){try{let{stdout:r}=await js(e.command,t,{env:e.env,timeout:qs,killSignal:"SIGKILL",maxBuffer:1048576,windowsHide:!0});return r}catch(r){let n=Object.entries(e.env).filter(([i])=>st(i)).map(([,i])=>i),s=Nt(r.stderr||r.message,n).trim();throw new Error(`OpenClaw ${t.slice(0,2).join(" ")} \u5931\u8D25\uFF0CBridge \u672A\u542F\u52A8\uFF0C\u8BF7\u4FEE\u590D\u540E\u91CD\u8BD5 reload\uFF1A${s}`)}}import{createHash as zo,randomUUID as Yt}from"node:crypto";function Ut(e){return Array.isArray(e)?e.map(t=>l(t)?t.type==="text"?a(t.text):t.type==="file"?a(t.uri):t.type==="image"?a(t.uri):"":"").filter(Boolean).join(`
|
|
6
|
+
`):""}var Pt=class{constructor(t){this.agent=t,this.sessionCounter=0}async sessionNew(){return this.sessionCounter+=1,{sessionId:`echo-${this.agent.agentId}-${this.sessionCounter}`}}async sessionPrompt(t,r){let n=Ut(t.prompt);return r({sessionId:t.sessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:n?`Echo runtime received: ${n}`:"Echo runtime received an empty prompt."}}}),{stopReason:"end_turn"}}async sessionCancel(){return{ok:!0}}};import{spawn as Gs}from"node:child_process";var _t="2.0",me=3e4,Ks=4e3;function Lt(e,t){let r=Object.entries(l(t)?t:{}).filter(([n])=>st(n)).map(([,n])=>n);return Nt(e,r)}function zs(e){return{code:Number.isInteger(e?.code)?e.code:-32e3,message:a(e?.message)||String(e),data:l(e?.data)?e.data:void 0}}function Vs(e){if(!l(e))return new Error(String(e||"runtime error"));let t=a(e.message)||"runtime error",r="data"in e?xr(e.data,4e3):"",n=new Error(r?`${t}; data=${r}`:t);return n.rpcCode=e.code,n.data=e.data,n}function Ws(e){return l(e)&&"id"in e&&!("method"in e)}function Js(e){return l(e)&&typeof e.method=="string"&&"id"in e}function Xs(e){return l(e)&&typeof e.method=="string"&&!("id"in e)}var kt=class{constructor({command:t,args:r=[],cwd:n,env:s,label:i,framing:o="line",detached:c=!0}){this.command=t,this.args=Array.isArray(r)?r.map(String):[],this.cwd=n||process.cwd(),this.env=l(s)?{...s}:{...process.env},this.label=i||t,this.framing=o==="content-length"?"content-length":"line",this.detached=c!==!1,this.child=null,this.exited=!1,this.exitCode=null,this.exitSignal=null,this.stopPromise=null,this.stderrTail="",this.spawnError=null,this.lineBuffer="",this.headerBuffer=Buffer.alloc(0),this.seq=0,this.pending=new Map,this.notificationHandlers=new Map,this.requestHandlers=new Map,this.exitHandlers=new Set}async start({initialize:t=!0,initializeParams:r={},initializeTimeoutMs:n=me}={}){if(!(this.child&&!this.exited)&&(this.exited=!1,this.exitCode=null,this.exitSignal=null,this.stderrTail="",this.spawnError=null,this.child=Gs(this.command,this.args,{cwd:this.cwd,env:this.env,stdio:["pipe","pipe","pipe"],detached:this.detached}),this.child.stdout.on("data",s=>this.onStdout(s)),this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",s=>{this.stderrTail=`${this.stderrTail}${s}`.slice(-Ks);let i=Lt(s.trimEnd(),this.env);i&&g("debug","runtime.stderr","runtime stderr",{target:this.label,text:i})}),this.child.on("exit",(s,i)=>this.handleExit(s,i)),this.child.on("error",s=>{this.spawnError=s,this.rejectAll(s)}),t)){let s=Math.max(1,_(n,me));try{await this.call("initialize",{protocolVersion:1,clientCapabilities:{},...r},s)}catch(i){let o=this.startupFailureDetail(),c=Lt(i?.message||i,this.env);g("warn","runtime.initialize","runtime initialize failed",{target:this.label,timeoutMs:s,cause:c,...o}),await this.stop("initialize failed",{termTimeoutMs:1e3,killTimeoutMs:1e3});let u=o.stderr?`; stderr: ${o.stderr}`:`; command=${o.command}; cwd=${o.cwd}`;throw Object.assign(new Error(`runtime initialize failed: ${c}${u}`,{cause:i}),{code:"RUNTIME_INITIALIZE_FAILED",detail:o})}}}startupFailureDetail(){return{command:this.command,cwd:this.cwd,exited:this.exited,exitCode:this.exitCode,exitSignal:this.exitSignal,...this.spawnError?{spawnError:Lt(this.spawnError.message,this.env)}:{},...this.stderrTail.trim()?{stderr:Lt(this.stderrTail.trim(),this.env)}:{}}}onStdout(t){if(this.framing==="content-length"){this.onContentLengthData(Buffer.isBuffer(t)?t:Buffer.from(t));return}this.onLineData(t.toString("utf8"))}onLineData(t){this.lineBuffer+=t;let r=this.lineBuffer.split(/\r?\n/);this.lineBuffer=r.pop()||"";for(let n of r){let s=n.trim();s&&this.dispatchRaw(s)}}onContentLengthData(t){for(this.headerBuffer=Buffer.concat([this.headerBuffer,t]);this.headerBuffer.length>0;){let r=this.headerBuffer.indexOf(`\r
|
|
4
7
|
\r
|
|
5
|
-
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){g("warn","runtime.protocol","missing Content-Length header",{target:this.label}),this.headerBuffer=Buffer.alloc(0);return}let i=Number.parseInt(s[1],10),o=r+4,c=o+i;if(this.headerBuffer.length<c)return;let u=this.headerBuffer.subarray(o,c).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(c),this.dispatchRaw(u)}}dispatchRaw(t){let r;try{r=JSON.parse(t)}catch(n){g("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(n)});return}this.dispatch(r)}dispatch(t){if(
|
|
8
|
+
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){g("warn","runtime.protocol","missing Content-Length header",{target:this.label}),this.headerBuffer=Buffer.alloc(0);return}let i=Number.parseInt(s[1],10),o=r+4,c=o+i;if(this.headerBuffer.length<c)return;let u=this.headerBuffer.subarray(o,c).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(c),this.dispatchRaw(u)}}dispatchRaw(t){let r;try{r=JSON.parse(t)}catch(n){g("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(n)});return}this.dispatch(r)}dispatch(t){if(Ws(t)){this.resolveResponse(t);return}if(Js(t)){this.handleRequest(t);return}Xs(t)&&this.handleNotification(t)}resolveResponse(t){let r=String(t.id),n=this.pending.get(r);n&&(clearTimeout(n.timer),this.pending.delete(r),t.error?(g("warn","runtime.protocol","runtime rpc error",{target:this.label,method:n.method,requestId:r,error:t.error}),n.reject(Vs(t.error))):n.resolve(t.result))}async handleRequest(t){let r=this.requestHandlers.get(t.method);if(!r){this.writeFrame({jsonrpc:_t,id:t.id,error:{code:-32601,message:`method not found: ${t.method}`}});return}try{let n=await r(l(t.params)?t.params:{},t);this.writeFrame({jsonrpc:_t,id:t.id,result:n??{}})}catch(n){this.writeFrame({jsonrpc:_t,id:t.id,error:zs(n)})}}handleNotification(t){let r=this.notificationHandlers.get(t.method);if(r)for(let n of r)n(l(t.params)?t.params:{},t)}call(t,r={},n=me){if(!this.child||!this.child.stdin||this.exited)return Promise.reject(new Error("runtime process is not running"));let s=`${t}_${++this.seq}`,i={jsonrpc:_t,id:s,method:t,params:r};return new Promise((o,c)=>{let u=setTimeout(()=>{this.pending.delete(s),c(new Error(`${t} timed out after ${n}ms`))},n);this.pending.set(s,{resolve:o,reject:c,timer:u,method:t}),this.writeFrame(i,d=>{d&&(clearTimeout(u),this.pending.delete(s),c(d))})})}notify(t,r={}){this.writeFrame({jsonrpc:_t,method:t,params:r})}writeFrame(t,r){if(!this.child?.stdin||this.exited){r?.(new Error("runtime process is not running"));return}let n=JSON.stringify(t),s=this.framing==="content-length"?`Content-Length: ${Buffer.byteLength(n,"utf8")}\r
|
|
6
9
|
\r
|
|
7
10
|
${n}`:`${n}
|
|
8
|
-
`;this.child.stdin.write(s,r)}onNotification(t,r){let n=this.notificationHandlers.get(t)||new Set;return n.add(r),this.notificationHandlers.set(t,n),()=>{n.delete(r),n.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,r){return this.requestHandlers.set(t,r),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let r of this.pending.values())clearTimeout(r.timer),r.reject(t);this.pending.clear()}handleExit(t,r){this.exited=!0,this.exitCode=t,this.exitSignal=r,this.rejectAll(new Error(`runtime exited before response (${t}/${r})`));for(let n of this.exitHandlers)n(t,r)}async waitForExit(t=5e3){return!this.child||this.exited?!0:await new Promise(r=>{let n=setTimeout(()=>{s(),r(!1)},t);n.unref?.();let s=()=>{clearTimeout(n),this.exitHandlers.delete(i)},i=()=>{s(),r(!0)};this.exitHandlers.add(i),this.exited&&i()})}signal(t){if(!this.child||this.exited)return!1;let r=this.child.pid;if(!r)return!1;try{return this.detached&&process.platform!=="win32"?process.kill(-r,t):this.child.kill(t),!0}catch(n){if(n?.code==="ESRCH")return this.exited=!0,!1;try{return this.child.kill(t),!0}catch(s){return s?.code!=="ESRCH"&&g("warn","runtime","runtime signal failed",{target:this.label,pid:r,signal:t,error:String(s)}),!1}}}async stop(t="stop",{termTimeoutMs:r=5e3,killTimeoutMs:n=2e3}={}){if(!(!this.child||this.exited)){if(this.stopPromise)return await this.stopPromise;this.stopPromise=(async()=>{if(!this.child||this.exited)return;let s=this.child.pid;g("info","runtime","stopping runtime",{target:this.label,reason:t,pid:s}),this.rejectAll(new Error(`runtime stopped: ${t}`)),this.signal("SIGTERM"),!await this.waitForExit(r)&&this.child&&!this.exited&&(g("warn","runtime","runtime did not exit after SIGTERM; force killing",{target:this.label,reason:t,pid:s}),this.signal("SIGKILL"),await this.waitForExit(n))})();try{await this.stopPromise}finally{this.stopPromise=null}}}};import{randomUUID as xr}from"node:crypto";import{existsSync as bs,readFileSync as Ms,realpathSync as Ir,statSync as Us}from"node:fs";import{basename as Nr,extname as br,isAbsolute as mt,join as Ps,relative as Mr,resolve as Cr}from"node:path";var Ls=25*1024*1024;function Ur(e,t=""){let r=a(t);if(r)return r;let n=br(a(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function Pr(e,t){let r=typeof e=="string"?e.trim():"";return!r||r==="<omitted>"?"":r.startsWith("data:")?r:`data:${t};base64,${r.replace(/\s+/g,"")}`}function Ut(e){if(Array.isArray(e))return e.map(a).filter(Boolean);let t=a(e);return t?[t]:[]}function ks(e,t){let r=Mr(t,e);return r===""||!!r&&!r.startsWith("..")&&!mt(r)}function Ds(e,t){let r=a(e);if(!r||!bs(r))return"";try{let n=Ir(r);for(let s of t)try{let i=Ir(s);if(ks(n,i))return n}catch{}}catch{return""}return""}function vs(e,t){let r=a(e);if(!r||!mt(r))return r;for(let n of Array.isArray(t)?t:[]){if(!l(n))continue;let s=a(n.runtimeRoot),i=a(n.hostRoot);if(!s||!i||!mt(s)||!mt(i))continue;let o=Mr(Cr(s),Cr(r));if(o===""||!o.startsWith("..")&&!mt(o))return o?Ps(i,o):i}return r}function de(e,t,r={}){let n=a(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:Hs(n,t,r)}function Hs(e,t,r={}){let n=[...Ut(r.trustedFileRoots),...Ut(r.trustedFileRoot),...Ut(r.artifactRoots),...Ut(r.artifactRoot)],s=Ds(vs(e,r.pathMappings),n);if(!s)return"";try{let i=Us(s);return!i.isFile()||i.size<=0||i.size>Ls?"":`data:${t};base64,${Ms(s).toString("base64")}`}catch{return""}}function A(...e){for(let t of e){let r=a(t);if(r)return r}return""}function Fs(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=A(n,e.previewUrl,e.fileUrl,e.imageUrl,e.dataUrl,e.url,e.uri,t.previewUrl,t.fileUrl,t.imageUrl,t.dataUrl,t.url,t.uri),o=br(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function pe(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!l(e))return null;let n=l(e.payload)?e.payload:{},s=a(e.type),i=a(n.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let o=A(n.call_id,n.id),c=A(n.saved_path,n.savedPath),u=A(n.revised_prompt,n.revisedPrompt),d=Ur(c,n.mimeType||n.mime_type),f=Pr(n.result,d)||de(c,d,t);if(!f)return null;let p=f.startsWith("data:")?f:"",h=c?Nr(c):`${o||xr()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:h||"Generated image",summary:u||"Generated image",content:{prompt:u||void 0,dataUrl:p||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:p||void 0,previewUrl:f,fileUrl:f,metadata:{source:r,eventType:i,callId:o||void 0,savedPath:c||void 0,filename:h,mimeType:d,revisedPrompt:u||void 0}}}function $s(e){let t=l(e)?e:{},r=[];for(let n of["_artifacts","artifacts"]){let s=t[n];Array.isArray(s)&&r.push(...s)}for(let n of["_artifact","artifact"]){let s=t[n];l(s)&&r.push(s)}return r}function Bs(e,t={}){let{source:r="runtime_artifact"}=t,n=l(e)?e:{};if(!Object.keys(n).length)return null;let s=l(n.content)?{...n.content}:{},i=l(n.metadata)?{...n.metadata}:{},o=A(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),c=A(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),u=A(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),d=Fs(n,s,u,o),f=d?Ur(o,c):c;if(d){let N=A(n.dataUrl,s.dataUrl),y=N.startsWith("data:")?N:"",w=A(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),E=Pr(n.result??s.result,f)||y||de(o,f,t)||de(w,f,t);E&&(E.startsWith("data:")&&(s.dataUrl||=E),s.imageUrl||=E,s.previewUrl||=E,s.fileUrl||=E,f&&(s.mimeType||=f))}for(let[N,y]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let w=n[N];w!=null&&w!==""&&!(y in s)&&(s[y]=w)}let p=A(n.fileUrl,n.downloadUrl,n.imageUrl,n.dataUrl,n.url,n.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),h=A(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),m=A(n.dataUrl,s.dataUrl,p.startsWith("data:")?p:"",h.startsWith("data:")?h:""),T=A(n.filename,i.filename,o?Nr(o):""),R=A(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:u,type:n.type||u,fieldKey:R,title:A(n.title,T,"Runtime artifact"),summary:A(n.summary,s.prompt,n.title,T,"Runtime artifact"),content:s,dataUrl:m||void 0,fileUrl:p||void 0,previewUrl:h||void 0,metadata:{...i,source:A(i.source,r),savedPath:o||i.savedPath,filename:T||i.filename,mimeType:f||i.mimeType}}}function Pt(e,t){if(!t||!e)return;let r=l(t.metadata)?t.metadata:{},n=A(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||xr(),s=e.get(n);if(!s){e.set(n,t);return}s.content={...l(s.content)?s.content:{},...l(t.content)?t.content:{}},s.metadata={...l(s.metadata)?s.metadata:{},...r},s.previewUrl=t.previewUrl||s.previewUrl,s.fileUrl=t.fileUrl||s.fileUrl,s.summary=t.summary||s.summary,s.title=t.title||s.title}function fe(e,t,r={}){for(let n of $s(e))Pt(t,Bs(n,r))}function he(e){if(!l(e)||!l(e.payload))return l(e)?e:{value:e};let t=a(e.payload.type);if(t!=="image_generation_end"&&t!=="image_generation_call")return e;let r={...e.payload};return typeof r.result=="string"&&r.result&&(r.result="<omitted>",r.resultLength=e.payload.result.length),{...e,payload:r}}function Ar(e,t,r){if(!l(e))return e;let n=l(e.event)?e.event:null;return n?(Pt(t,pe(n,r)),{...e,event:he(n)}):e}function Lr(e,t,r={}){if(!l(e))return e;fe(e,t,r);let n=Ar(e,t,r),s=l(n.update)?Ar(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function kr(e,t,r={}){let n=l(e)?{...e}:{};fe(n,t,r),fe(l(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function Dr(e,t){let r=_(e,t);return r>0?r:t}var nt=class{constructor(t,r,n={},s={}){this.agent=t,this.target=r,this.callbacks=n,this.options=s,this.proc=null,this.launch=null,this.launchCleanup=null,this.permissionHandlers=new Map}async ensureStarted(){if(this.proc)return;let t=a(this.target.command);if(!t)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let r={command:t,args:x(this.target.args),cwd:rt(this.target,this.agent.workspace),environment:l(this.target.env)?this.target.env:{}},n=this.options.prepareLaunch?await this.options.prepareLaunch(r):{...r,environment:{...process.env,...r.environment},cleanup:async()=>{}};this.launch=n,this.launchCleanup=n.cleanup,this.proc=new Mt({command:n.command,args:n.args,cwd:n.cwd,env:n.environment,label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:a(this.target.framing||"line")}),this.proc.onRequest("session/request_permission",s=>this.handlePermissionRequest(s)),this.proc.onRequest("session/requestPermission",s=>this.handlePermissionRequest(s));try{await this.proc.start({initialize:this.target.initialize!==!1,initializeTimeoutMs:Dr(this.target.initializeTimeoutMs,Dr(this.options.initializeTimeoutMs,3e4)),initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:et},...l(this.target.initializeParams)?this.target.initializeParams:{}}})}catch(s){throw await this.proc?.stop("runtime startup failed"),this.proc=null,await this.cleanupLaunch(),s}}async sessionNew(t={}){return await this.ensureStarted(),this.proc.call("session/new",this.sessionNewParams(t))}sessionNewParams(t={}){let r=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return{...t,mcpServers:r}}async sessionPrompt(t,r){await this.ensureStarted();let n=a(t.sessionId),s=new Map,i=this.artifactOptions(),o=this.proc.onNotification("session/update",u=>{let d=a(u.sessionId);(!d||d===n)&&r(Lr(u,s,i))}),c=async u=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:u,emitUpdate:r})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,c),this.permissionHandlers.set("*",c);try{let u=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return kr(u,s,i)}finally{o(),n&&this.permissionHandlers.delete(n),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let r=a(t.sessionId),n=this.permissionHandlers.get(r)||this.permissionHandlers.get("*");return n?n(t):{outcome:"denied",reason:"no active Orcha permission handler"}}artifactSource(){return a(this.target.type||"acp")==="openclaw"?"openclaw_image_generation":"acp_runtime_image_generation"}artifactOptions(){let t=l(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[a(this.launch?.artifactDirectory),a(this.launch?.homeDirectory),a(this.target.artifactRoot),a(this.target.artifactDir),a(this.target.runtimeArtifactRoot),a(t.ORCHA_RUNTIME_ARTIFACT_DIR),...x(this.target.trustedArtifactRoots),...x(this.target.trustedFileRoots),...x(this.target.artifactRoots),...x(this.target.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(this.launch?.pathMappings)?this.launch.pathMappings:[]}}async stop(t){try{await this.proc?.stop(t)}finally{this.proc=null,await this.cleanupLaunch()}}async cleanupLaunch(){let t=this.launchCleanup;this.launchCleanup=null,this.launch=null,await t?.()}};import{createServer as qs}from"node:http";import{randomBytes as Ks}from"node:crypto";var Lt={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs"]};var Gs=Object.freeze([...Lt.controlTools,...Lt.residentTools]),zs=new Set(Gs),Vs=8*1024*1024;function kt(e,t){if(!Array.isArray(e)||e.length!==1)throw new Error("one task-scoped Orcha MCP server is required");let r=e[0],n=new URL(r.url);if(r.name!=="orcha"||r.type!=="http"||!["http:","https:"].includes(n.protocol)||n.username||n.password||n.hash||t&&n.href!==new URL(t).href)throw new Error("Orcha MCP server does not match the trusted binding");let s=Object.fromEntries((r.headers||[]).map(({name:i,value:o})=>[i.toLowerCase(),o]));if(!String(s.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:n.href,headers:{...s,"content-type":"application/json",accept:"application/json"}}}async function Hr(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>Vs)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function Fr(e,t,r){let n=await fetch(e.url,{method:"POST",headers:e.headers,body:JSON.stringify(t),redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(36e5),...r?[r]:[]])});if(!n.ok)throw new Error(`Orcha MCP request failed (${n.status})`);if(n.status===202||n.status===204)return null;let s=await Hr(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function vr(e,t){let r=await Fr(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},t),n=r?.result?.tools;if(r?.error)throw new Error("Orcha MCP tool discovery failed");return Ws(n)}function Ws(e){if(!Array.isArray(e)||e.some(t=>!t||!zs.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&Lt.controlTools.some(t=>!e.some(r=>r.name===t)))throw new Error("Orcha MCP returned an unsupported or invalid authorized tool catalog");return e}function Js(e,t){let r=s=>Array.isArray(s)?s.map(r):s&&typeof s=="object"?Object.fromEntries(Object.keys(s).sort().map(i=>[i,r(s[i])])):s,n=s=>s.map(({name:i,inputSchema:o})=>({name:i,inputSchema:o})).sort((i,o)=>i.name.localeCompare(o.name));return JSON.stringify(r(n(e)))===JSON.stringify(r(n(t)))}async function $r(e){let t=kt(e),r=new AbortController,n=await vr(t,r.signal),s=Ks(32).toString("hex"),i=qs(async(o,c)=>{if(o.url!=="/mcp"||o.headers.authorization!==`Bearer ${s}`){c.writeHead(403).end();return}if(o.method!=="POST"){c.writeHead(405).end();return}try{let u=await Hr(o);if(!u||u.jsonrpc!=="2.0"||typeof u.method!="string")throw new Error("Invalid MCP request");if(u.method==="tools/call"&&!n.some(f=>f.name===u.params?.name))throw new Error("Tool is not authorized in this task binding");let d=await Fr(t,u,r.signal);c.writeHead(d===null?202:200,{"content-type":"application/json"}),c.end(d===null?"":JSON.stringify(d))}catch{c.writeHead(502,{"content-type":"application/json"}).end(JSON.stringify({error:"The task-scoped Orcha MCP connection failed"}))}});return await new Promise((o,c)=>{i.once("error",c),i.listen(0,"127.0.0.1",o)}),{url:`http://127.0.0.1:${i.address().port}/mcp`,token:s,async refresh(o){let c=kt(o,t.url);if(!Js(n,await vr(c,r.signal)))throw new Error("The frozen MCP tool catalog changed; start a new task");t=c},async close(){r.abort(),i.closeAllConnections(),await new Promise(o=>i.close(o))}}}var gt="application/x-orcha-channel-events-v2+ndjson";function L(e,t){return Object.assign(new Error(t||(["run_timeout","RUNTIME_NODE_TIMEOUT"].includes(e)?"OpenClaw \u539F\u751F IM \u6267\u884C\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002":e==="OPENCLAW_CHANNEL_PROTOCOL_MISMATCH"?"OpenClaw \u63D2\u4EF6\u4E0E Bridge \u7684\u539F\u751F IM \u534F\u8BAE\u4E0D\u517C\u5BB9\uFF0C\u8BF7\u914D\u5957\u5347\u7EA7\u3002":`OpenClaw \u539F\u751F IM \u6267\u884C\u5931\u8D25\uFF08${e}\uFF09`)),{code:e})}function Br(e,t){let r=e.cause?.code||e.code;return t?.reason?.name==="TimeoutError"||e.name==="TimeoutError"||["UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT","UND_ERR_CONNECT_TIMEOUT","ETIMEDOUT"].includes(r)?Object.assign(L("RUNTIME_NODE_TIMEOUT","OpenClaw \u8FDE\u63A5\u6216\u7B49\u5F85\u54CD\u5E94\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002"),{detail:{causeCode:r||"REQUEST_TIMEOUT"}}):e}async function jr(e,t){if(e.headers.get("content-type")!==gt)throw await e.body?.cancel(),L("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");let r=Buffer.alloc(0);for await(let n of e.body){r=Buffer.concat([r,n]);let s;for(;(s=r.indexOf(10))>=0;){if(s>2097152)throw L("OPENCLAW_CHANNEL_FRAME_TOO_LARGE");let i=r.subarray(0,s).toString("utf8");r=r.subarray(s+1);let o;try{o=JSON.parse(i)}catch{throw L("OPENCLAW_CHANNEL_INVALID_FRAME")}if(o.type!=="heartbeat")if(o.type==="update"&&o.payload?.update&&o.payload?._meta?.channelUpdateId)await t(o.payload);else{if(o.type==="result"&&o.result?.stopReason)return o.result;throw o.type==="error"&&typeof o.code=="string"?L(o.code):L("OPENCLAW_CHANNEL_INVALID_FRAME")}}if(r.length>2097152)throw L("OPENCLAW_CHANNEL_FRAME_TOO_LARGE")}throw L("OPENCLAW_CHANNEL_STREAM_INTERRUPTED","OpenClaw \u8FC7\u7A0B\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u4EFB\u52A1\u7EC8\u6001\uFF0C\u8BF7\u68C0\u67E5\u8282\u70B9\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002")}var st=class{constructor(t,r){this.target=t,this.identity=r,this.bound=!1}async request(t,r,n=!1,s="mcp-bindings",i=3e4,o=null){let c=a(this.target.mcpBridgeUrl),u=a(this.target.mcpBridgeTokenEnv),d=this.target.env?.[u]||process.env[u];if(!c||!u||!d)throw Object.assign(new Error("OpenClaw requires the Orcha tool plugin, mcpBridgeUrl and mcpBridgeTokenEnv"),{code:"OPENCLAW_MCP_NOT_CONFIGURED"});let f=new URL(c);if(!["http:","https:"].includes(f.protocol)||f.username||f.password||f.pathname!=="/plugins/orcha-runtime/mcp-bindings"||f.search||f.hash)throw new Error("OpenClaw MCP binding URL must be the trusted Gateway plugin route");if(!["mcp-bindings","deliveries","background"].includes(s))throw new Error("Unsupported Orcha plugin route");f.pathname=`/plugins/orcha-runtime/${s}`;let p=AbortSignal.timeout(i);try{let h=await fetch(f,{method:t,redirect:"error",signal:p,headers:{authorization:`Bearer ${d}`,"content-type":"application/json",...o?{accept:gt}:{},...n?{"if-match":this.identity.runId}:{}},...r!==void 0?{body:JSON.stringify(r)}:{}});if(t==="GET"&&s==="deliveries"&&[404,405].includes(h.status))throw await h.body?.cancel(),L("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");if(h.ok&&o)return await jr(h,o);let m=await h.json();if(!h.ok)throw L(m.error||"OPENCLAW_MCP_BINDING_FAILED");return m}catch(h){throw Br(h,p)}}async bind(t,r=!1){kt(t),await this.request("PUT",{...this.identity,mcpServer:t[0]},r),this.bound=!0}async close(){this.bound&&(await this.request("DELETE",{runId:this.identity.runId,sessionKey:this.identity.sessionKey}),this.bound=!1)}};var Dt=class{constructor(t,r,n,s,i={}){this.agent=t,this.target=r,this.options=i,this.sessionKey=n,this.mcp=null,this.metadata=null,this.finished=!1,this.transport=new st(r,{runId:i.runId}),this.expiresAt=new Date(Date.now()+Number(i.sandboxPolicy?.maxRuntimeSeconds||i.sessionPromptTimeoutMs/1e3||3600)*1e3).toISOString()}async sessionNew({mcpServers:t,metadata:r}){if(r?.source!=="channel_message"||r.delivery?.dispatchMode!=="bridge")throw new Error("Invalid native Channel dispatch");return this.mcp=t[0],this.metadata=r,{sessionId:this.sessionKey}}async refreshMcpServers(t){this.mcp=t[0],this.promptBody&&await this.transport.request("PATCH",{...this.promptBody,mcpServer:this.mcp,attachOnly:!0},!1,"deliveries")}async sessionPrompt({prompt:t},r){if((await this.transport.request("GET",void 0,!1,"deliveries")).streamType!==gt)throw L("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");this.promptBody={runId:this.options.runId,agentCode:this.target.openclawAgentId||this.metadata.agentCode,delivery:this.metadata.delivery,expiresAt:this.expiresAt,mcpServer:this.mcp,attachOnly:this.options.attachOnly===!0,prompt:t};let s=await this.transport.request("POST",this.promptBody,!1,"deliveries",Number(this.options.sessionPromptTimeoutMs||36e5),i=>r?.(i));return this.finished=!0,s}async stop(){!this.finished&&this.promptBody&&await this.transport.request("DELETE",{runId:this.options.runId},!1,"deliveries")}};function me(e){let t=l(e.metadata)?e.metadata:{};return a(t.agentCode)}function qr(e,t,r){let n=a(r?.openclawAgentId)||me(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var vt=class extends nt{constructor(t,r,n,s={},i={}){if(i.source==="channel_message")return new Dt(t,r,n,s,i);let o=a(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",c=a(r.command)||"openclaw",u=Array.isArray(r.args)?r.args.map(String):[],d=u.length>0?u:["acp","--session",qr(t,o,r)];super(t,{...r,command:c,args:d},s,i),this.boundSessionKey=qr(t,o,r),this.binding=null}async sessionNew(t={}){if(t.mcpServers?.length){let r=[...this.target.args],n=r.indexOf("--session"),s=r.find(u=>u.startsWith("--session=")),i=s?s.slice(10):n<0?null:r[n+1];if(i&&i!==this.boundSessionKey)throw Object.assign(new Error("OpenClaw --session must match this Orcha task's private session"),{code:"OPENCLAW_SESSION_BINDING_CONFLICT"});i===null&&r.push("--session",this.boundSessionKey),this.target.args=r;let o=a(this.options.runId),c=Number(this.options.sandboxPolicy?.maxRuntimeSeconds||this.options.sessionPromptTimeoutMs/1e3||3600);if(!o||!me(this.agent))throw new Error("OpenClaw MCP requires a trusted task and Agent identity");this.binding=new st(this.target,{runId:o,sessionKey:this.boundSessionKey,agentCode:a(this.target.openclawAgentId)||me(this.agent),expiresAt:new Date(Date.now()+c*1e3).toISOString()}),await this.binding.bind(t.mcpServers)}try{return await super.sessionNew(t)}catch(r){throw await this.binding?.close(),r}}async refreshMcpServers(t){if(!this.binding)throw Object.assign(new Error("The original OpenClaw task binding is unavailable"),{code:"RUNTIME_OPERATION_NOT_FOUND"});await this.binding.bind(t,!0)}async stop(t){try{await super.stop(t)}finally{await this.binding?.close()}}sessionNewParams(t={}){return{...t,mcpServers:[]}}};import{spawn as Yr}from"node:child_process";import{randomUUID as it}from"node:crypto";import{existsSync as Qr,mkdirSync as Xs,readdirSync as Zr,readFileSync as tn,realpathSync as Tt,rmSync as Ys,rmdirSync as Qs,statSync as Zs,unlinkSync as ti}from"node:fs";import{homedir as ei,tmpdir as en}from"node:os";import{basename as we,dirname as ri,join as $,resolve as Gr}from"node:path";async function Kr(e){let t=await $r(e),r="ORCHA_TASK_MCP_TOKEN";return{args:["-c",`mcp_servers.orcha={url=${JSON.stringify(t.url)},bearer_token_env_var=${JSON.stringify(r)},required=true}`],environment:{[r]:t.token},refresh:n=>t.refresh(n),close:()=>t.close()}}var ni=36e5,rn=5e3,si=2*60*1e3,ii=2*60*1e3,oi=12,ai=1e3,ci=1500,ui=1e3,Ht=24*60*60*1e3,_t=new Set(["final_answer","final","complete","completed","done"]),li=new Set(["function_call","function_call_output","custom_tool_call","custom_tool_call_output","local_shell_call","local_shell_call_output","mcp_tool_call","mcp_tool_call_output","web_search_call","image_generation_call","image_generation_end"]),di=new Set(["context_compacted","context_compaction","context_compressed"]);function $t(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{Yr("taskkill",r,{stdio:"ignore",windowsHide:!0}).unref?.()}catch{try{e.kill(t)}catch{}}return}try{process.kill(-e.pid,t)}catch(r){if(r?.code==="ESRCH")return;try{e.kill(t)}catch{}}}}function ge(e){$t(e,"SIGTERM");let t=setTimeout(()=>$t(e,"SIGKILL"),rn);return t.unref?.(),t}function v(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>v(t)).join("");if(!l(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let r=v(e[t]);if(r)return r}return""}function nn(e){if(!l(e))return"";let t=l(e.payload)?e.payload:{};if(a(e.type)==="event_msg"){if(a(t.type)==="agent_message")return a(t.message);if(a(t.type)==="task_complete")return a(t.last_agent_message)}if(a(e.type)==="response_item"&&a(t.type)==="message"&&a(t.role)==="assistant")return v(t.content)||v(t.message);if(a(e.type)==="result")return v(e.result);let r=v(e.delta)||v(e.text)||v(e.content);if(r)return r;let n=l(e.item)?e.item:{};return["message","agent_message"].includes(a(n.type))||a(n.role)==="assistant"?v(n.content)||v(n.text)||v(n.message):""}function sn(e,t={}){return pe(e,{source:"codex_cli_image_generation",...t})}function on(e,t){Pt(e.artifacts,t)}function an(e){return W(he(e))}function Re(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);if(r==="event_msg"&&n==="task_complete")return!0;let s=a(t.phase||t.status||t.stage).toLowerCase();if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return _t.has(s);let i=l(e.item)?e.item:{};return r==="item.completed"&&a(i.type)==="agent_message"?!0:r==="result"&&e.is_error!==!0?a(e.result).length>0:!1}function zr(e){let t=a(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=we(a(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function Vr(e,t,r){let n=l(t.error)?t.error:{},s=a(n.message)||v(t.error)||a(t.result)||a(t.message)||r;return Object.assign(new Error(s),{code:e})}function fi(e,t){if(!l(e))return null;let r=a(e.type).toLowerCase();if(t==="codex")return r==="turn.completed"?{status:"completed",result:{stopReason:"end_turn"}}:r==="turn.failed"?{status:"failed",error:Vr("RUNTIME_CODEX_TURN_FAILED",e,"Codex turn failed")}:null;if(t==="claude"&&r==="result"){let n=a(e.subtype).toLowerCase();return e.is_error===!0||n.startsWith("error")||["failed","failure"].includes(n)?{status:"failed",error:Vr("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...a(e.result)?{output:a(e.result)}:{}}}}return null}function Wr(e){return l(e)?a(e.phase||e.status||e.stage).toLowerCase():""}function pi(e){if(!l(e)||Re(e))return!1;let t=l(e.payload)?e.payload:{},r=a(e.type),n=a(t.type),s=Wr(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return!!(s&&!_t.has(s));let i=l(e.item)?e.item:{},o=Wr(i);return a(i.role)==="assistant"||a(i.type)==="message"?!!(o&&!_t.has(o)):!1}function hi(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:we(e)==="codex"}function mi(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:we(e)==="codex"}function cn(e){return Math.max(20,_(e.codexTranscriptPollMs||e.transcriptPollMs,ai))}function gi(e){return Math.max(0,_(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,ci))}function Bt(e){if(typeof e=="boolean")return e;let t=a(e).toLowerCase();return["true","1","yes","y","on"].includes(t)?!0:["false","0","no","n","off"].includes(t)?!1:null}function Ee(e){let t=l(e?.metadata)?e.metadata:{};return l(t._runtimeBridge)?t._runtimeBridge:{}}function _e(e){return a(Ee(e).promptKind).toLowerCase()}function _i(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=Bt(r);if(n!=null)return n}return _e(t)==="chat"}function Ti(e,t){let r=Ee(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=Bt(s);if(i!=null)return i}let n=_e(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=Bt(s);if(i!=null)return i}return _e(e)==="chat"}function yi(e){let t=Ee(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=Bt(r);if(n!=null)return n}return null}function wi(e,t){let r=yi(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function Ri(e,t){return!e.finalTextOnly||t}function un(e,t,r,n,s=n){return!n||e.emittedTexts.has(s)?!1:(e.emittedTexts.add(s),r({sessionId:t,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:n}}}),!0)}function ln(e,t,r,n){return!n||e.emittedThoughtTexts.has(n)?!1:(e.emittedThoughtTexts.add(n),r({sessionId:t,update:{sessionUpdate:"agent_thought_chunk",content:{type:"text",text:n}}}),!0)}function Ei(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function Si(e,t){let r=l(e.env)?e.env:{},n=a(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||$(en(),"orcha-runtime-artifacts"),s=a(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||it(),i=$(n,s),o=$(i,it());return Xs(o,{recursive:!0}),{root:o,realRoot:Tt(o),sessionRoot:i,realSessionRoot:Tt(i)}}function Oi(e){let t=a(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:Tt(t),sessionRoot:"",realSessionRoot:""}}function dn(e){return a(l(e)?e.root:e)}function Jr(e){let t=dn(e),r=a(l(e)?e.sessionRoot:ri(t)),n=a(l(e)?e.realSessionRoot:"");if(r)try{if(n&&Tt(r)!==n)return;Qs(r)}catch{}}function Ii(e,t={}){let r=dn(e),n=a(l(e)?e.realRoot:"");if(r){try{if(n&&Tt(r)!==n){g("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{Jr(e);return}try{Ys(r,{recursive:!0,force:!0})}catch(s){g("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:r,error:String(s?.message||s)});return}Jr(e)}}function Ci(e,t,r=null){return{trustedFileRoots:[t,a(r?.artifactDirectory),a(r?.homeDirectory),...x(e.trustedArtifactRoots),...x(e.trustedFileRoots),...x(e.artifactRoots),...x(e.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(r?.pathMappings)?r.pathMappings:[]}}function fn(e){let t=a(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let r=l(e.env)?e.env:{},n=a(e.codexHome||r.CODEX_HOME||process.env.CODEX_HOME)||$(ei(),".codex");return $(n,"sessions")}function Ai(e,t){let r=new Date(t),n=String(r.getFullYear()),s=String(r.getMonth()+1).padStart(2,"0"),i=String(r.getDate()).padStart(2,"0");return $(e,n,s,i)}function pn(e,t,r){let n=new Set;for(let s of[t-Ht,t,t+Ht,r-Ht,r,r+Ht])n.add(Ai(e,s));return[...n].filter(s=>Qr(s))}function xi(e,t,r){let n=fn(e),s=t-si,i=r+ii,o=[];for(let c of pn(n,t,r)){let u=[];try{u=Zr(c)}catch{continue}for(let d of u){if(!d.endsWith(".jsonl"))continue;let f=$(c,d);try{let p=Zs(f);if(!p.isFile()||p.mtimeMs<s||p.mtimeMs>i)continue;o.push({path:f,mtimeMs:p.mtimeMs})}catch{}}}return o.sort((c,u)=>u.mtimeMs-c.mtimeMs).slice(0,oi)}function Ni(e,t,r=t){let n=fn(e),s=new Set;for(let i of pn(n,t,r)){let o=[];try{o=Zr(i)}catch{continue}for(let c of o)c.endsWith(".jsonl")&&s.add($(i,c))}return s}function Te(e,t,r=0){if(!(r>8||e===null||e===void 0)){if(typeof e=="string"){e&&t.push(e);return}if(Array.isArray(e)){for(let n of e)Te(n,t,r+1);return}if(l(e))for(let n of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])n in e&&Te(e[n],t,r+1)}}function hn(e){return a(e).replace(/\s+/g," ")}function bi(e){let t=hn(e);if(!t)return[];if(t.length<=200)return[t];let r=160,n=[0,Math.floor((t.length-r)/2),t.length-r],s=new Set,i=[];for(let o of n){let c=t.slice(Math.max(0,o),Math.max(0,o)+r).trim();c.length>=40&&!s.has(c)&&(s.add(c),i.push(c))}return i}function Mi(e,t){let r=bi(t);if(!r.length)return!1;let n=[];for(let i of e)Te(i,n);let s=hn(n.join(" "));return r.every(i=>s.includes(i))}function Ui(e){return e.find(t=>l(t)&&a(t.type)==="session_meta"&&l(t.payload))||null}function Pi(e){let t=l(e?.payload)?e.payload:{},r=a(e?.timestamp||t.timestamp),n=Date.parse(r);return Number.isFinite(n)?n:Number.NaN}function Li(e){let t=a(e.originator),r=a(e.source);if(t!=="codex_exec"&&r!=="exec"||a(e.parent_thread_id))return!1;let n=a(e.thread_source);if(n&&n!=="user")return!1;let s=a(e.session_id),i=a(e.id);return!(s&&i&&s!==i)}function ki(e,t,r){if(!Mi(e,t.promptText))return!1;let n=Ui(e);if(!n)return!1;let s=n.payload;if(!Li(s))return!1;let i=Pi(n);if(!Number.isFinite(i)||i<t.startedAtMs-5e3||i>r+5e3)return!1;let o=a(t.target.cwd),c=a(s.cwd);return!(o&&c&&Gr(o)!==Gr(c))}function Xr(e){try{return vi(tn(e,"utf8"))}catch{return null}}function Di(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=Xr(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of xi(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=Xr(s.path);!i||!ki(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,g("warn","runtime.cli","codex transcript fallback disabled; multiple matching transcripts",{target:e.target.targetCode,sessionId:t,transcriptCount:n.length})),null):(e.matchedPath=n[0].path,g("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function vi(e){let t=[];for(let r of e.split(/\r?\n/)){let n=r.trim();if(n)try{t.push(JSON.parse(n))}catch{}}return t}function Hi(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);return r==="event_msg"&&n==="image_generation_end"||r==="response_item"&&n==="image_generation_call"}function Fi(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return a(e.type)==="response_item"&&li.has(a(t.type))}function $i(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return di.has(a(t.type))}function Bi(e,t,r,n){let s=nn(e),i=Re(e),o=0,c=0,u=0;if(s&&!i&&t.emitThoughtChunks&&ln(t,r,n,s)&&(u=1),s&&i){let d=t.emittedTexts.size?`
|
|
11
|
+
`;this.child.stdin.write(s,r)}onNotification(t,r){let n=this.notificationHandlers.get(t)||new Set;return n.add(r),this.notificationHandlers.set(t,n),()=>{n.delete(r),n.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,r){return this.requestHandlers.set(t,r),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let r of this.pending.values())clearTimeout(r.timer),r.reject(t);this.pending.clear()}handleExit(t,r){this.exited=!0,this.exitCode=t,this.exitSignal=r,this.rejectAll(new Error(`runtime exited before response (${t}/${r})`));for(let n of this.exitHandlers)n(t,r)}async waitForExit(t=5e3){return!this.child||this.exited?!0:await new Promise(r=>{let n=setTimeout(()=>{s(),r(!1)},t);n.unref?.();let s=()=>{clearTimeout(n),this.exitHandlers.delete(i)},i=()=>{s(),r(!0)};this.exitHandlers.add(i),this.exited&&i()})}signal(t){if(!this.child||this.exited)return!1;let r=this.child.pid;if(!r)return!1;try{return this.detached&&process.platform!=="win32"?process.kill(-r,t):this.child.kill(t),!0}catch(n){if(n?.code==="ESRCH")return this.exited=!0,!1;try{return this.child.kill(t),!0}catch(s){return s?.code!=="ESRCH"&&g("warn","runtime","runtime signal failed",{target:this.label,pid:r,signal:t,error:String(s)}),!1}}}async stop(t="stop",{termTimeoutMs:r=5e3,killTimeoutMs:n=2e3}={}){if(!(!this.child||this.exited)){if(this.stopPromise)return await this.stopPromise;this.stopPromise=(async()=>{if(!this.child||this.exited)return;let s=this.child.pid;g("info","runtime","stopping runtime",{target:this.label,reason:t,pid:s}),this.rejectAll(new Error(`runtime stopped: ${t}`)),this.signal("SIGTERM"),!await this.waitForExit(r)&&this.child&&!this.exited&&(g("warn","runtime","runtime did not exit after SIGTERM; force killing",{target:this.label,reason:t,pid:s}),this.signal("SIGKILL"),await this.waitForExit(n))})();try{await this.stopPromise}finally{this.stopPromise=null}}}};import{randomUUID as Br}from"node:crypto";import{existsSync as Ys,readFileSync as Qs,realpathSync as Hr,statSync as Zs}from"node:fs";import{basename as jr,extname as qr,isAbsolute as yt,join as ti,relative as Gr,resolve as Fr}from"node:path";var ei=25*1024*1024;function Kr(e,t=""){let r=a(t);if(r)return r;let n=qr(a(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function zr(e,t){let r=typeof e=="string"?e.trim():"";return!r||r==="<omitted>"?"":r.startsWith("data:")?r:`data:${t};base64,${r.replace(/\s+/g,"")}`}function vt(e){if(Array.isArray(e))return e.map(a).filter(Boolean);let t=a(e);return t?[t]:[]}function ri(e,t){let r=Gr(t,e);return r===""||!!r&&!r.startsWith("..")&&!yt(r)}function ni(e,t){let r=a(e);if(!r||!Ys(r))return"";try{let n=Hr(r);for(let s of t)try{let i=Hr(s);if(ri(n,i))return n}catch{}}catch{return""}return""}function si(e,t){let r=a(e);if(!r||!yt(r))return r;for(let n of Array.isArray(t)?t:[]){if(!l(n))continue;let s=a(n.runtimeRoot),i=a(n.hostRoot);if(!s||!i||!yt(s)||!yt(i))continue;let o=Gr(Fr(s),Fr(r));if(o===""||!o.startsWith("..")&&!yt(o))return o?ti(i,o):i}return r}function ge(e,t,r={}){let n=a(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:ii(n,t,r)}function ii(e,t,r={}){let n=[...vt(r.trustedFileRoots),...vt(r.trustedFileRoot),...vt(r.artifactRoots),...vt(r.artifactRoot)],s=ni(si(e,r.pathMappings),n);if(!s)return"";try{let i=Zs(s);return!i.isFile()||i.size<=0||i.size>ei?"":`data:${t};base64,${Qs(s).toString("base64")}`}catch{return""}}function A(...e){for(let t of e){let r=a(t);if(r)return r}return""}function oi(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=A(n,e.previewUrl,e.fileUrl,e.imageUrl,e.dataUrl,e.url,e.uri,t.previewUrl,t.fileUrl,t.imageUrl,t.dataUrl,t.url,t.uri),o=qr(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function ye(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!l(e))return null;let n=l(e.payload)?e.payload:{},s=a(e.type),i=a(n.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let o=A(n.call_id,n.id),c=A(n.saved_path,n.savedPath),u=A(n.revised_prompt,n.revisedPrompt),d=Kr(c,n.mimeType||n.mime_type),f=zr(n.result,d)||ge(c,d,t);if(!f)return null;let p=f.startsWith("data:")?f:"",h=c?jr(c):`${o||Br()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:h||"Generated image",summary:u||"Generated image",content:{prompt:u||void 0,dataUrl:p||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:p||void 0,previewUrl:f,fileUrl:f,metadata:{source:r,eventType:i,callId:o||void 0,savedPath:c||void 0,filename:h,mimeType:d,revisedPrompt:u||void 0}}}function ai(e){let t=l(e)?e:{},r=[];for(let n of["_artifacts","artifacts"]){let s=t[n];Array.isArray(s)&&r.push(...s)}for(let n of["_artifact","artifact"]){let s=t[n];l(s)&&r.push(s)}return r}function ci(e,t={}){let{source:r="runtime_artifact"}=t,n=l(e)?e:{};if(!Object.keys(n).length)return null;let s=l(n.content)?{...n.content}:{},i=l(n.metadata)?{...n.metadata}:{},o=A(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),c=A(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),u=A(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),d=oi(n,s,u,o),f=d?Kr(o,c):c;if(d){let N=A(n.dataUrl,s.dataUrl),T=N.startsWith("data:")?N:"",w=A(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),E=zr(n.result??s.result,f)||T||ge(o,f,t)||ge(w,f,t);E&&(E.startsWith("data:")&&(s.dataUrl||=E),s.imageUrl||=E,s.previewUrl||=E,s.fileUrl||=E,f&&(s.mimeType||=f))}for(let[N,T]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let w=n[N];w!=null&&w!==""&&!(T in s)&&(s[T]=w)}let p=A(n.fileUrl,n.downloadUrl,n.imageUrl,n.dataUrl,n.url,n.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),h=A(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),m=A(n.dataUrl,s.dataUrl,p.startsWith("data:")?p:"",h.startsWith("data:")?h:""),y=A(n.filename,i.filename,o?jr(o):""),R=A(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:u,type:n.type||u,fieldKey:R,title:A(n.title,y,"Runtime artifact"),summary:A(n.summary,s.prompt,n.title,y,"Runtime artifact"),content:s,dataUrl:m||void 0,fileUrl:p||void 0,previewUrl:h||void 0,metadata:{...i,source:A(i.source,r),savedPath:o||i.savedPath,filename:y||i.filename,mimeType:f||i.mimeType}}}function Dt(e,t){if(!t||!e)return;let r=l(t.metadata)?t.metadata:{},n=A(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||Br(),s=e.get(n);if(!s){e.set(n,t);return}s.content={...l(s.content)?s.content:{},...l(t.content)?t.content:{}},s.metadata={...l(s.metadata)?s.metadata:{},...r},s.previewUrl=t.previewUrl||s.previewUrl,s.fileUrl=t.fileUrl||s.fileUrl,s.summary=t.summary||s.summary,s.title=t.title||s.title}function _e(e,t,r={}){for(let n of ai(e))Dt(t,ci(n,r))}function Te(e){if(!l(e)||!l(e.payload))return l(e)?e:{value:e};let t=a(e.payload.type);if(t!=="image_generation_end"&&t!=="image_generation_call")return e;let r={...e.payload};return typeof r.result=="string"&&r.result&&(r.result="<omitted>",r.resultLength=e.payload.result.length),{...e,payload:r}}function $r(e,t,r){if(!l(e))return e;let n=l(e.event)?e.event:null;return n?(Dt(t,ye(n,r)),{...e,event:Te(n)}):e}function Vr(e,t,r={}){if(!l(e))return e;_e(e,t,r);let n=$r(e,t,r),s=l(n.update)?$r(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function Wr(e,t,r={}){let n=l(e)?{...e}:{};_e(n,t,r),_e(l(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function Jr(e,t){let r=_(e,t);return r>0?r:t}var ot=class{constructor(t,r,n={},s={}){this.agent=t,this.target=r,this.callbacks=n,this.options=s,this.proc=null,this.launch=null,this.launchCleanup=null,this.permissionHandlers=new Map}async ensureStarted(){if(this.proc)return;let t=a(this.target.command);if(!t)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let r={command:t,args:x(this.target.args),cwd:it(this.target,this.agent.workspace),environment:l(this.target.env)?this.target.env:{}},n=this.options.prepareLaunch?await this.options.prepareLaunch(r):{...r,environment:{...process.env,...r.environment},cleanup:async()=>{}};this.launch=n,this.launchCleanup=n.cleanup,this.proc=new kt({command:n.command,args:n.args,cwd:n.cwd,env:n.environment,label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:a(this.target.framing||"line")}),this.proc.onRequest("session/request_permission",s=>this.handlePermissionRequest(s)),this.proc.onRequest("session/requestPermission",s=>this.handlePermissionRequest(s));try{await this.proc.start({initialize:this.target.initialize!==!1,initializeTimeoutMs:Jr(this.target.initializeTimeoutMs,Jr(this.options.initializeTimeoutMs,3e4)),initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:z},...l(this.target.initializeParams)?this.target.initializeParams:{}}})}catch(s){throw await this.proc?.stop("runtime startup failed"),this.proc=null,await this.cleanupLaunch(),s}}async sessionNew(t={}){return await this.ensureStarted(),this.proc.call("session/new",this.sessionNewParams(t))}sessionNewParams(t={}){let r=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return{...t,mcpServers:r}}async sessionPrompt(t,r){await this.ensureStarted();let n=a(t.sessionId),s=new Map,i=this.artifactOptions(),o=this.proc.onNotification("session/update",u=>{let d=a(u.sessionId);(!d||d===n)&&r(Vr(u,s,i))}),c=async u=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:u,emitUpdate:r})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,c),this.permissionHandlers.set("*",c);try{let u=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return Wr(u,s,i)}finally{o(),n&&this.permissionHandlers.delete(n),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let r=a(t.sessionId),n=this.permissionHandlers.get(r)||this.permissionHandlers.get("*");return n?n(t):{outcome:"denied",reason:"no active Orcha permission handler"}}artifactSource(){return a(this.target.type||"acp")==="openclaw"?"openclaw_image_generation":"acp_runtime_image_generation"}artifactOptions(){let t=l(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[a(this.launch?.artifactDirectory),a(this.launch?.homeDirectory),a(this.target.artifactRoot),a(this.target.artifactDir),a(this.target.runtimeArtifactRoot),a(t.ORCHA_RUNTIME_ARTIFACT_DIR),...x(this.target.trustedArtifactRoots),...x(this.target.trustedFileRoots),...x(this.target.artifactRoots),...x(this.target.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(this.launch?.pathMappings)?this.launch.pathMappings:[]}}async stop(t){try{await this.proc?.stop(t)}finally{this.proc=null,await this.cleanupLaunch()}}async cleanupLaunch(){let t=this.launchCleanup;this.launchCleanup=null,this.launch=null,await t?.()}};var Ht=class{constructor(t,r,n,s,i={}){this.agent=t,this.target=r,this.options=i,this.sessionKey=n,this.mcp=null,this.metadata=null,this.finished=!1,this.transport=new V(r,{runId:i.runId}),this.expiresAt=new Date(Date.now()+Number(i.sandboxPolicy?.maxRuntimeSeconds||i.sessionPromptTimeoutMs/1e3||3600)*1e3).toISOString()}async sessionNew({mcpServers:t,metadata:r}){if(r?.source!=="channel_message"||r.delivery?.dispatchMode!=="bridge")throw new Error("Invalid native Channel dispatch");return this.mcp=t[0],this.metadata=r,{sessionId:this.sessionKey}}async refreshMcpServers(t){this.mcp=t[0],this.promptBody&&await this.transport.request("PATCH",{...this.promptBody,mcpServer:this.mcp,attachOnly:!0},!1,"deliveries")}async sessionPrompt({prompt:t},r){if((await this.transport.request("GET",void 0,!1,"deliveries")).streamType!==Y)throw U("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");this.promptBody={runId:this.options.runId,agentCode:this.target.openclawAgentId||this.metadata.agentCode,delivery:this.metadata.delivery,expiresAt:this.expiresAt,mcpServer:this.mcp,attachOnly:this.options.attachOnly===!0,prompt:t};let s=await this.transport.request("POST",this.promptBody,!1,"deliveries",Number(this.options.sessionPromptTimeoutMs||36e5),i=>r?.(i));return this.finished=!0,s}async stop(){!this.finished&&this.promptBody&&await this.transport.request("DELETE",{runId:this.options.runId},!1,"deliveries")}};function we(e){let t=l(e.metadata)?e.metadata:{};return a(t.agentCode)}function Xr(e,t,r){let n=a(r?.openclawAgentId)||we(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var Ft=class extends ot{constructor(t,r,n,s={},i={}){if(i.source==="channel_message")return new Ht(t,r,n,s,i);let o=a(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",c=a(r.command)||"openclaw",u=Array.isArray(r.args)?r.args.map(String):[],d=u.length>0?u:["acp","--session",Xr(t,o,r)];super(t,{...r,command:c,args:d},s,i),this.boundSessionKey=Xr(t,o,r),this.binding=null}async sessionNew(t={}){if(t.mcpServers?.length){let r=[...this.target.args],n=r.indexOf("--session"),s=r.find(u=>u.startsWith("--session=")),i=s?s.slice(10):n<0?null:r[n+1];if(i&&i!==this.boundSessionKey)throw Object.assign(new Error("OpenClaw --session must match this Orcha task's private session"),{code:"OPENCLAW_SESSION_BINDING_CONFLICT"});i===null&&r.push("--session",this.boundSessionKey),this.target.args=r;let o=a(this.options.runId),c=Number(this.options.sandboxPolicy?.maxRuntimeSeconds||this.options.sessionPromptTimeoutMs/1e3||3600);if(!o||!we(this.agent))throw new Error("OpenClaw MCP requires a trusted task and Agent identity");this.binding=new V(this.target,{runId:o,sessionKey:this.boundSessionKey,agentCode:a(this.target.openclawAgentId)||we(this.agent),expiresAt:new Date(Date.now()+c*1e3).toISOString()}),await this.binding.bind(t.mcpServers)}try{return await super.sessionNew(t)}catch(r){throw await this.binding?.close(),r}}async refreshMcpServers(t){if(!this.binding)throw Object.assign(new Error("The original OpenClaw task binding is unavailable"),{code:"RUNTIME_OPERATION_NOT_FOUND"});await this.binding.bind(t,!0)}async stop(t){try{await super.stop(t)}finally{await this.binding?.close()}}sessionNewParams(t={}){return{...t,mcpServers:[]}}};import{spawn as sn}from"node:child_process";import{randomUUID as at}from"node:crypto";import{existsSync as on,mkdirSync as ui,readdirSync as an,readFileSync as cn,realpathSync as wt,rmSync as li,rmdirSync as di,statSync as fi,unlinkSync as pi}from"node:fs";import{homedir as hi,tmpdir as un}from"node:os";import{basename as Ie,dirname as mi,join as $,resolve as Qr}from"node:path";async function Yr(e){let t=await Lr(e),r="ORCHA_TASK_MCP_TOKEN";return{args:["-c",`mcp_servers.orcha={url=${JSON.stringify(t.url)},bearer_token_env_var=${JSON.stringify(r)},required=true}`],environment:{[r]:t.token},refresh:n=>t.refresh(n),close:()=>t.close()}}var gi=36e5,ln=5e3,_i=2*60*1e3,yi=2*60*1e3,Ti=12,wi=1e3,Ri=1500,Ei=1e3,$t=24*60*60*1e3,Tt=new Set(["final_answer","final","complete","completed","done"]),Si=new Set(["function_call","function_call_output","custom_tool_call","custom_tool_call_output","local_shell_call","local_shell_call_output","mcp_tool_call","mcp_tool_call_output","web_search_call","image_generation_call","image_generation_end"]),Oi=new Set(["context_compacted","context_compaction","context_compressed"]);function jt(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{sn("taskkill",r,{stdio:"ignore",windowsHide:!0}).unref?.()}catch{try{e.kill(t)}catch{}}return}try{process.kill(-e.pid,t)}catch(r){if(r?.code==="ESRCH")return;try{e.kill(t)}catch{}}}}function Re(e){jt(e,"SIGTERM");let t=setTimeout(()=>jt(e,"SIGKILL"),ln);return t.unref?.(),t}function D(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>D(t)).join("");if(!l(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let r=D(e[t]);if(r)return r}return""}function dn(e){if(!l(e))return"";let t=l(e.payload)?e.payload:{};if(a(e.type)==="event_msg"){if(a(t.type)==="agent_message")return a(t.message);if(a(t.type)==="task_complete")return a(t.last_agent_message)}if(a(e.type)==="response_item"&&a(t.type)==="message"&&a(t.role)==="assistant")return D(t.content)||D(t.message);if(a(e.type)==="result")return D(e.result);let r=D(e.delta)||D(e.text)||D(e.content);if(r)return r;let n=l(e.item)?e.item:{};return["message","agent_message"].includes(a(n.type))||a(n.role)==="assistant"?D(n.content)||D(n.text)||D(n.message):""}function fn(e,t={}){return ye(e,{source:"codex_cli_image_generation",...t})}function pn(e,t){Dt(e.artifacts,t)}function hn(e){return X(Te(e))}function Ce(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);if(r==="event_msg"&&n==="task_complete")return!0;let s=a(t.phase||t.status||t.stage).toLowerCase();if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return Tt.has(s);let i=l(e.item)?e.item:{};return r==="item.completed"&&a(i.type)==="agent_message"?!0:r==="result"&&e.is_error!==!0?a(e.result).length>0:!1}function Zr(e){let t=a(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=Ie(a(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function tn(e,t,r){let n=l(t.error)?t.error:{},s=a(n.message)||D(t.error)||a(t.result)||a(t.message)||r;return Object.assign(new Error(s),{code:e})}function Ii(e,t){if(!l(e))return null;let r=a(e.type).toLowerCase();if(t==="codex")return r==="turn.completed"?{status:"completed",result:{stopReason:"end_turn"}}:r==="turn.failed"?{status:"failed",error:tn("RUNTIME_CODEX_TURN_FAILED",e,"Codex turn failed")}:null;if(t==="claude"&&r==="result"){let n=a(e.subtype).toLowerCase();return e.is_error===!0||n.startsWith("error")||["failed","failure"].includes(n)?{status:"failed",error:tn("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...a(e.result)?{output:a(e.result)}:{}}}}return null}function en(e){return l(e)?a(e.phase||e.status||e.stage).toLowerCase():""}function Ci(e){if(!l(e)||Ce(e))return!1;let t=l(e.payload)?e.payload:{},r=a(e.type),n=a(t.type),s=en(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return!!(s&&!Tt.has(s));let i=l(e.item)?e.item:{},o=en(i);return a(i.role)==="assistant"||a(i.type)==="message"?!!(o&&!Tt.has(o)):!1}function Ai(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:Ie(e)==="codex"}function xi(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:Ie(e)==="codex"}function mn(e){return Math.max(20,_(e.codexTranscriptPollMs||e.transcriptPollMs,wi))}function Ni(e){return Math.max(0,_(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,Ri))}function qt(e){if(typeof e=="boolean")return e;let t=a(e).toLowerCase();return["true","1","yes","y","on"].includes(t)?!0:["false","0","no","n","off"].includes(t)?!1:null}function Ae(e){let t=l(e?.metadata)?e.metadata:{};return l(t._runtimeBridge)?t._runtimeBridge:{}}function Ee(e){return a(Ae(e).promptKind).toLowerCase()}function bi(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=qt(r);if(n!=null)return n}return Ee(t)==="chat"}function Mi(e,t){let r=Ae(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=qt(s);if(i!=null)return i}let n=Ee(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=qt(s);if(i!=null)return i}return Ee(e)==="chat"}function Ui(e){let t=Ae(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=qt(r);if(n!=null)return n}return null}function Pi(e,t){let r=Ui(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function Li(e,t){return!e.finalTextOnly||t}function gn(e,t,r,n,s=n){return!n||e.emittedTexts.has(s)?!1:(e.emittedTexts.add(s),r({sessionId:t,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:n}}}),!0)}function _n(e,t,r,n){return!n||e.emittedThoughtTexts.has(n)?!1:(e.emittedThoughtTexts.add(n),r({sessionId:t,update:{sessionUpdate:"agent_thought_chunk",content:{type:"text",text:n}}}),!0)}function ki(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function vi(e,t){let r=l(e.env)?e.env:{},n=a(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||$(un(),"orcha-runtime-artifacts"),s=a(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||at(),i=$(n,s),o=$(i,at());return ui(o,{recursive:!0}),{root:o,realRoot:wt(o),sessionRoot:i,realSessionRoot:wt(i)}}function Di(e){let t=a(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:wt(t),sessionRoot:"",realSessionRoot:""}}function yn(e){return a(l(e)?e.root:e)}function rn(e){let t=yn(e),r=a(l(e)?e.sessionRoot:mi(t)),n=a(l(e)?e.realSessionRoot:"");if(r)try{if(n&&wt(r)!==n)return;di(r)}catch{}}function Hi(e,t={}){let r=yn(e),n=a(l(e)?e.realRoot:"");if(r){try{if(n&&wt(r)!==n){g("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{rn(e);return}try{li(r,{recursive:!0,force:!0})}catch(s){g("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:r,error:String(s?.message||s)});return}rn(e)}}function Fi(e,t,r=null){return{trustedFileRoots:[t,a(r?.artifactDirectory),a(r?.homeDirectory),...x(e.trustedArtifactRoots),...x(e.trustedFileRoots),...x(e.artifactRoots),...x(e.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(r?.pathMappings)?r.pathMappings:[]}}function Tn(e){let t=a(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let r=l(e.env)?e.env:{},n=a(e.codexHome||r.CODEX_HOME||process.env.CODEX_HOME)||$(hi(),".codex");return $(n,"sessions")}function $i(e,t){let r=new Date(t),n=String(r.getFullYear()),s=String(r.getMonth()+1).padStart(2,"0"),i=String(r.getDate()).padStart(2,"0");return $(e,n,s,i)}function wn(e,t,r){let n=new Set;for(let s of[t-$t,t,t+$t,r-$t,r,r+$t])n.add($i(e,s));return[...n].filter(s=>on(s))}function Bi(e,t,r){let n=Tn(e),s=t-_i,i=r+yi,o=[];for(let c of wn(n,t,r)){let u=[];try{u=an(c)}catch{continue}for(let d of u){if(!d.endsWith(".jsonl"))continue;let f=$(c,d);try{let p=fi(f);if(!p.isFile()||p.mtimeMs<s||p.mtimeMs>i)continue;o.push({path:f,mtimeMs:p.mtimeMs})}catch{}}}return o.sort((c,u)=>u.mtimeMs-c.mtimeMs).slice(0,Ti)}function ji(e,t,r=t){let n=Tn(e),s=new Set;for(let i of wn(n,t,r)){let o=[];try{o=an(i)}catch{continue}for(let c of o)c.endsWith(".jsonl")&&s.add($(i,c))}return s}function Se(e,t,r=0){if(!(r>8||e===null||e===void 0)){if(typeof e=="string"){e&&t.push(e);return}if(Array.isArray(e)){for(let n of e)Se(n,t,r+1);return}if(l(e))for(let n of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])n in e&&Se(e[n],t,r+1)}}function Rn(e){return a(e).replace(/\s+/g," ")}function qi(e){let t=Rn(e);if(!t)return[];if(t.length<=200)return[t];let r=160,n=[0,Math.floor((t.length-r)/2),t.length-r],s=new Set,i=[];for(let o of n){let c=t.slice(Math.max(0,o),Math.max(0,o)+r).trim();c.length>=40&&!s.has(c)&&(s.add(c),i.push(c))}return i}function Gi(e,t){let r=qi(t);if(!r.length)return!1;let n=[];for(let i of e)Se(i,n);let s=Rn(n.join(" "));return r.every(i=>s.includes(i))}function Ki(e){return e.find(t=>l(t)&&a(t.type)==="session_meta"&&l(t.payload))||null}function zi(e){let t=l(e?.payload)?e.payload:{},r=a(e?.timestamp||t.timestamp),n=Date.parse(r);return Number.isFinite(n)?n:Number.NaN}function Vi(e){let t=a(e.originator),r=a(e.source);if(t!=="codex_exec"&&r!=="exec"||a(e.parent_thread_id))return!1;let n=a(e.thread_source);if(n&&n!=="user")return!1;let s=a(e.session_id),i=a(e.id);return!(s&&i&&s!==i)}function Wi(e,t,r){if(!Gi(e,t.promptText))return!1;let n=Ki(e);if(!n)return!1;let s=n.payload;if(!Vi(s))return!1;let i=zi(n);if(!Number.isFinite(i)||i<t.startedAtMs-5e3||i>r+5e3)return!1;let o=a(t.target.cwd),c=a(s.cwd);return!(o&&c&&Qr(o)!==Qr(c))}function nn(e){try{return Xi(cn(e,"utf8"))}catch{return null}}function Ji(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=nn(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of Bi(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=nn(s.path);!i||!Wi(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,g("warn","runtime.cli","codex transcript fallback disabled; multiple matching transcripts",{target:e.target.targetCode,sessionId:t,transcriptCount:n.length})),null):(e.matchedPath=n[0].path,g("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function Xi(e){let t=[];for(let r of e.split(/\r?\n/)){let n=r.trim();if(n)try{t.push(JSON.parse(n))}catch{}}return t}function Yi(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);return r==="event_msg"&&n==="image_generation_end"||r==="response_item"&&n==="image_generation_call"}function Qi(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return a(e.type)==="response_item"&&Si.has(a(t.type))}function Zi(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return Oi.has(a(t.type))}function to(e,t,r,n){let s=dn(e),i=Ce(e),o=0,c=0,u=0;if(s&&!i&&t.emitThoughtChunks&&_n(t,r,n,s)&&(u=1),s&&i){let d=t.emittedTexts.size?`
|
|
9
12
|
|
|
10
|
-
${s}`:s;
|
|
11
|
-
`,
|
|
12
|
-
`}}})}}}async sessionCancel(t){let r=a(t.sessionId),n=this.active.get(r);return n?(g("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),
|
|
13
|
-
`)}function yn(e,t,r=""){if(!wn(e))return e==null?null:{required:!0,status:"failed",outcome:a(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=De(e),s=e.verificationPlan.required===!0;if(a(r)&&a(r)!==n)return{required:s,status:"failed",outcome:e.outcome,goalContractHash:n,checks:[],errorCode:"goal_contract_hash_mismatch"};if(!s)return{required:!1,status:"not_required",outcome:e.outcome,goalContractHash:n,checks:[]};let i=ro(t),o=e.verificationPlan.checks.map(u=>uo(u,i));return{required:!0,status:o.some(u=>u.status==="failed")?"failed":o.some(u=>u.status==="missing")?"missing":"passed",outcome:e.outcome,goalContractHash:n,checks:o}}function wn(e){if(!l(e)||e.schemaVersion!==Qi||!a(e.outcome))return!1;let t=e.verificationPlan;if(!l(t)||typeof t.required!="boolean"||!Array.isArray(t.checks)||t.required&&t.checks.length===0)return!1;let r=new Set;for(let n of t.checks)if(!l(n)||!a(n.id)||r.has(a(n.id))||(r.add(a(n.id)),!Array.isArray(n.toolNames)||n.toolNames.length===0||n.toolNames.some(s=>!a(s)))||!Number.isSafeInteger(n.requiredMatches)||n.requiredMatches<1||n.arguments!==void 0&&!l(n.arguments))return!1;return!0}function ro(e){let t=new Map,r=[];for(let n of Array.isArray(e)?e:[]){let s=l(n?.update)?n.update:{},i=a(s.sessionUpdate);if(i==="runtime_event"){no(s.event,t,r);continue}if(i==="tool_call"){let o=Kt(s)||`tool-${r.length+1}`,c=qt(t,r,o),u=Le(s,s.name||s.toolName||s.kind);c.toolName=u.toolName,c.arguments=u.arguments,c.status=yt(s.status),c.evidence=zt(s);continue}if(i==="tool_call_update"){let o=Kt(s);if(!o)continue;let c=qt(t,r,o),u=Le(s,s.name||s.toolName||s.kind);c.toolName||=u.toolName,Object.keys(c.arguments).length===0&&(c.arguments=u.arguments),c.status=yt(s.status),c.evidence.push(...zt(s))}}return r}function no(e,t,r){let n=l(e)&&l(e.payload)?e.payload:l(e)?e:{},s=a(n.type);if(["function_call","custom_tool_call","local_shell_call","mcp_tool_call"].includes(s)){let c=Kt(n)||`runtime-${r.length+1}`,u=qt(t,r,c),d=Le(n,n.name||n.tool||s,s);u.toolName=d.toolName,u.arguments=d.arguments,u.status=yt(n.status),u.evidence.push(...zt(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=Kt(n);if(!i)return;let o=qt(t,r,i);o.status=ao(n,o.toolName),o.evidence.push(...zt(n))}function qt(e,t,r){let n=e.get(r);return n||(n={toolCallId:r,toolName:"",arguments:{},status:"unknown",evidence:[]},e.set(r,n),t.push(n)),n}function so(e){let t=a(e).toLowerCase();return eo.get(t)||t}function Le(e,t,r=""){let n=io(e),s=a(r)==="mcp_tool_call"||a(e?.kind).toLowerCase()==="mcp",i=l(e?._meta)?e._meta:{},o=a(e?.server||e?.serverName||e?.server_name||e?.mcpServer||i.server||i.serverName).toLowerCase();if(s&&o==="orcha"){let c=a(e?.tool||e?.toolName||e?.name||t);return{toolName:"plugin_operation",arguments:{...n,...c?{operationCode:c}:{}}}}return{toolName:so(t),arguments:n}}function Kt(e){return l(e)?a(e.call_id||e.callId||e.toolCallId||e.id):""}function io(e){if(!l(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=oo(e[r]);if(n)return n}let t={};for(let r of["cmd","command","cwd","operationCode","path","query","url"])e[r]!==void 0&&(t[r]=e[r]);return t}function oo(e){if(l(e))return structuredClone(e);if(typeof e!="string")return null;try{let t=JSON.parse(e);return l(t)?t:null}catch{return null}}function ao(e,t){if(!l(e))return"unknown";let r=Gt(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function Gt(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return co(e,t,r);if(Array.isArray(e))return e.flatMap(o=>Gt(o,t+1,r));if(!l(e))return[];let n=[];typeof e.isError=="boolean"&&n.push(e.isError?"failed":"success"),typeof e.ok=="boolean"&&n.push(e.ok?"success":"failed"),typeof e.success=="boolean"&&n.push(e.success?"success":"failed");let s=yt(e.status);s!=="unknown"&&n.push(s);let i=e.exitCode??e.exit_code;typeof i=="number"&&Number.isFinite(i)&&n.push(i===0?"success":"failed");for(let o of["output","result","structuredContent","content"])e[o]!==void 0&&n.push(...Gt(e[o],t+1,r));return n}function co(e,t,r){let n=e.trim();if(!n)return[];try{return Gt(JSON.parse(n),t+1,r)}catch{}if(r.parseCliExitCode!==!0)return[];let s=[];for(let i of n.matchAll(/(?:process\s+exited\s+with\s+code|exit\s+code\s*:?)\s*(-?\d+)/gi))s.push(Number(i[1])===0?"success":"failed");return s}function yt(e){let t=a(e).toLowerCase();return Zi.has(t)?"success":to.has(t)?"failed":"unknown"}function zt(e){if(!l(e))return[];let t=l(e.output)?e.output:{},r=[e.verificationEvidence,l(e.verification)?e.verification.evidence:null,t.verificationEvidence,l(t.verification)?t.verification.evidence:null],n=[];for(let s of r)for(let i of Array.isArray(s)?s:s?[s]:[])!l(i)||!a(i.id)||n.push({id:a(i.id),status:yt(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...a(i.message)?{message:a(i.message)}:{}});return n}function uo(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&ke(e.arguments||{},o.arguments)),n=a(e.evidenceId),s=r.filter(o=>o.status==="success"&&(!n||o.evidence.some(c=>c.id===n&&c.status==="success")));if(s.length>=e.requiredMatches)return Pe(e,"passed",s,`Runtime tool evidence passed ${s.length} times.`);let i=r.filter(o=>o.status==="failed"||n&&o.evidence.some(c=>c.id===n&&c.status==="failed"));return s.length===0&&i.length?Pe(e,"failed",i,"Runtime tool evidence failed."):Pe(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function Pe(e,t,r,n){let s=r.map(i=>i.toolCallId).filter(Boolean);return{id:e.id,status:t,message:n,...a(e.description)?{description:a(e.description)}:{},toolNames:e.toolNames,requiredMatches:e.requiredMatches,observedMatches:s.length,toolCallIds:s,...l(e.arguments)?{arguments:e.arguments}:{},...a(e.evidenceId)?{evidenceId:a(e.evidenceId)}:{}}}function ke(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>ke(r,t[n])):l(e)?l(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&ke(n,t[r])):!1:Object.is(e,t)}function q(e){if(e===null||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="string")return _n(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new Error("invalid_jcs_number");return JSON.stringify(Object.is(e,-0)?0:e)}if(Array.isArray(e))return`[${Array.from({length:e.length},(t,r)=>{if(!Object.hasOwn(e,r))throw new Error("invalid_jcs_json_value");return q(e[r])}).join(",")}]`;if(l(e))return`{${Object.keys(e).sort().map(t=>`${_n(t)}:${q(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function _n(e){return lo(e),JSON.stringify(e)}function lo(e){for(let t=0;t<e.length;t+=1){let r=e.charCodeAt(t);if(r>=55296&&r<=56319){let n=e.charCodeAt(t+1);if(!(n>=56320&&n<=57343))throw new Error("invalid_jcs_unicode");t+=1}else if(r>=56320&&r<=57343)throw new Error("invalid_jcs_unicode")}}import{spawn as fo}from"node:child_process";import{createHash as po,randomUUID as ho}from"node:crypto";import{constants as mo}from"node:fs";import{access as go,mkdir as ve,readdir as _o,realpath as wt,rm as To,stat as yo}from"node:fs/promises";import wo from"node:http";import{tmpdir as Ro}from"node:os";import{isAbsolute as Rt,join as ot,relative as Rn,resolve as Fe}from"node:path";var $e=1,Eo="orcha.process-isolation/v1",Be="orcha.egress-proxy/v1",So="--disable-wasm-trap-handler",Vt={read_only:0,workspace_write:1,workspace_network:2},He={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},Oo=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function J(e){if(!l(e))throw S("RUNTIME_SANDBOX_POLICY_REQUIRED","sandboxPolicy is required");let t=structuredClone(e),r=a(t.accessMode),n=a(t.accessModeCeiling);if(!(r in He)||!(n in He))throw S("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if(Vt[r]>Vt[n])throw S("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=He[r];if(t.filesystemMode!==s||t.networkMode!==i)throw S("RUNTIME_SANDBOX_POLICY_INVALID","runtime access profile does not match its mode");if(Number(t.policySchemaVersion)!==$e||!Number.isInteger(Number(t.policyRevision))||Number(t.policyRevision)<1)throw S("RUNTIME_SANDBOX_POLICY_INVALID","unsupported sandbox policy schema or revision");for(let[c,u]of Object.entries({outsideWorkspaceAccess:"denied",hostAccess:"denied",hostEnvironmentAccess:"denied",dockerSocketAccess:"denied",environmentMode:"allowlist"}))if(t[c]!==u)throw S("RUNTIME_SANDBOX_POLICY_INVALID",`${c} cannot be relaxed`);let o=l(t.processIsolation)?t.processIsolation:{};if(o.mode!=="required"||o.backend==="direct")throw S("RUNTIME_SANDBOX_POLICY_INVALID","strong process isolation is required");if(Array.isArray(t.alwaysApprovedApprovalKeys)&&t.alwaysApprovedApprovalKeys.length)throw S("RUNTIME_SANDBOX_POLICY_INVALID","persistent runtime approvals are forbidden");return t}function En(e,t){let r=J(e),n=J(t);return Vt[n.accessMode]<Vt[r.accessMode]}async function Sn(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[$e],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await In(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await No(t,x(e.sandboxBrokerArguments),e.sandboxProbeTimeoutMs);if(r.enforced!==!0||a(r.protocolVersion)!=="orcha.runtime-sandbox-broker/v1"||!["bubblewrap","broker"].includes(a(r.backend)))throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker did not report enforced isolation");let n=l(r.probes)?r.probes:{};for(let s of["emptyRoot","outsideWorkspaceDenied","hostFilesystemDenied","sensitiveFilesDenied","environmentAllowlist","dockerSocketDenied","networkNamespace","workspaceReadOnly","workspaceWrite","resourceLimits"])if(n[s]!==!0)throw S("RUNTIME_SANDBOX_UNAVAILABLE",`sandbox broker probe failed: ${s}`);return e.egressProxyRequired&&await Uo(e),{dispatchable:!0,enforced:!0,backend:a(r.backend),daemonStatus:"ok",daemonProtocolVersion:a(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[$e],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function je(e,t,r){let n=a(t.workspace||t.cwd),s=a(r),i=n||(t.allowRequestWorkspace===!0?s:"");if(!i||!Rt(i))throw S("RUNTIME_WORKSPACE_NOT_CONFIGURED","runtime target must configure an absolute trusted workspace");let o=await wt(i);if(!(await yo(o)).isDirectory())throw S("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>wt(d))):[o]).some(d=>Ke(d,o)))throw S("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function On({config:e,target:t,command:r,args:n,cwd:s,environment:i,runId:o,agentId:c,sessionId:u,sandboxPolicy:d}){if(!e.sandboxRequired)return{command:r,args:[...n],cwd:s,environment:{...process.env,...i},tempDirectory:"",isolation:{enforced:!1,backend:"development_direct"},cleanup:async()=>{}};let f=J(d),p=await je(e,t,s),h=await wt(s);if(!Ke(p,h))throw S("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let m=await In(e.sandboxBrokerCommand,process.env.PATH||"");if(!m)throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let T=`runtime-${po("sha256").update(String(o)).digest("hex").slice(0,32)}`,R=Fe(e.sandboxTempRoot||ot(Ro(),"orcha-runtime-sandboxes"));await ve(R,{recursive:!0,mode:448});let N=ot(R,`${T}-${ho()}`),y=ot(N,"home"),w=ot(N,"artifacts");await ve(y,{recursive:!0,mode:448}),await ve(w,{recursive:!0,mode:448});let E=f.networkMode==="restricted"?await bo(e,{runId:String(o),instanceId:T,policyRevision:Number(f.policyRevision),ttlMs:Math.min(_(f.maxRuntimeSeconds,900)*1e3,e.egressGrantMaxTtlMs),maxTransferBytes:_(f.maxNetworkBytes,64*1024*1024)}):null,I={PATH:a(i.PATH||process.env.PATH),LANG:a(i.LANG||process.env.LANG||"C.UTF-8"),HOME:"/tmp/home",TMPDIR:"/tmp",USER:"orcha",LOGNAME:"orcha",SHELL:"/bin/sh",ORCHA_AGENT_ID:String(c),ORCHA_SESSION_ID:String(u),ORCHA_RUN_ID:String(o),ORCHA_RUNTIME_ARTIFACT_DIR:"/tmp/artifacts",...Co(t,i)};I.HOME="/tmp/home",I.TMPDIR="/tmp",I.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",I.NODE_OPTIONS=So;let P={schemaVersion:Eo,runId:String(o),instanceId:T,workspace:p,cwd:h,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await Ao(p),temporaryDirectory:N,egressProxy:E,environment:I,resourceLimits:xo(f),readOnlyToolchainRoots:await Io(e,t)},H=!1,b=async()=>{if(!H){H=!0;try{E&&await Mo(e,E,{runId:String(o),instanceId:T})}finally{await To(N,{recursive:!0,force:!0})}}};return{command:m,args:[...x(e.sandboxBrokerArguments),"--",r,...n],cwd:h,environment:{PATH:process.env.PATH||"",LANG:process.env.LANG||"C.UTF-8",ORCHA_PROCESS_ISOLATION_REQUEST:JSON.stringify(P)},tempDirectory:N,homeDirectory:y,artifactDirectory:w,pathMappings:[{runtimeRoot:"/tmp/artifacts",hostRoot:w},{runtimeRoot:"/tmp/home",hostRoot:y}],isolation:{enforced:!0,backend:"broker",instanceId:T,policyRevision:f.policyRevision},cleanup:b}}async function Io(e,t){let r=x(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(x(e.trustedToolchainRoots).map(i=>wt(i)));if(!n.length)throw S("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","target toolchain roots require ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS");let s=[];for(let i of r){if(!Rt(i))throw S("RUNTIME_TOOLCHAIN_ROOT_INVALID","toolchain roots must be absolute");let o=await wt(i);if(!n.some(c=>Ke(c,o)))throw S("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function Co(e,t){let r=l(e.env)?e.env:{},n={};for(let[s,i]of Object.entries(r))/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&i!=null&&(n[s]=String(i));for(let s of["ORCHA_RUNTIME_PROMPT","ORCHA_RUNTIME_ARTIFACT_DIR"])t[s]!=null&&(n[s]=String(t[s]));return n}async function Ao(e){let t=[],r=0,n=async s=>{let i;try{i=await _o(s,{withFileTypes:!0})}catch(o){if(s===e)throw o;return}for(let o of i){if(r+=1,r>1e4)throw S("RUNTIME_WORKSPACE_SCAN_LIMIT_EXCEEDED","workspace contains more than 10000 entries");let c=ot(s,o.name),u=Rn(e,c),d=o.name.toLowerCase();(Oo.has(d)||d.startsWith(".env."))&&t.push(u),o.isDirectory()&&!o.isSymbolicLink()&&await n(c)}};return await n(e),t.sort()}function xo(e){return{maxCpuSeconds:Math.max(1,_(e.maxRuntimeSeconds,900)),maxMemoryBytes:_(e.maxMemoryBytes,2*1024*1024*1024),maxProcesses:_(e.maxProcesses,128),maxOpenFiles:_(e.maxOpenFiles,1024),maxFileBytes:_(e.maxFileBytes,64*1024*1024)}}async function No(e,t,r){return await new Promise((n,s)=>{let i=fo(e,[...t,"--probe"],{env:{PATH:process.env.PATH||"",LANG:"C.UTF-8"},stdio:["ignore","pipe","pipe"],windowsHide:!0}),o=[],c=[];i.stdout.on("data",d=>o.push(Buffer.from(d))),i.stderr.on("data",d=>c.push(Buffer.from(d)));let u=setTimeout(()=>i.kill("SIGKILL"),Math.max(1e3,r));i.once("error",s),i.once("close",d=>{if(clearTimeout(u),d!==0){s(S("RUNTIME_SANDBOX_UNAVAILABLE",Buffer.concat(c).toString("utf8").trim()||`sandbox probe exited with ${d}`));return}try{n(JSON.parse(Buffer.concat(o).toString("utf8")))}catch{s(S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox probe returned invalid JSON"))}})})}async function In(e,t){let r=a(e);if(!r)return"";let n=Rt(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>ot(s,r));for(let s of n)try{return await go(s,mo.X_OK),s}catch{}return""}async function bo(e,t){if(!e.egressProxyRequired)throw S("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await qe(e,"POST","/v1/grants",{protocolVersion:Be,...t}),n={socketPath:e.egressProxySocket,grantId:a(r.grantId),credential:a(r.credential)};if(!n.grantId||!n.credential)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy returned an invalid grant");return n}async function Mo(e,t,r){await qe(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:Be,...r}).catch(()=>{})}async function Uo(e){let t=await qe(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==Be)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function qe(e,t,r,n){if(!Rt(e.egressProxySocket)||!e.egressProxyToken)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy socket and token are required");return await new Promise((s,i)=>{let o=wo.request({socketPath:e.egressProxySocket,path:r,method:t,headers:{Authorization:`Bearer ${e.egressProxyToken}`,Accept:"application/json",...n?{"Content-Type":"application/json"}:{}}},c=>{let u=[],d=0;c.on("data",f=>{d+=f.length,d>1048576?o.destroy(new Error("egress response is too large")):u.push(Buffer.from(f))}),c.once("end",()=>{try{let f=JSON.parse(Buffer.concat(u).toString("utf8")||"{}");(c.statusCode||500)>=400?i(S("RUNTIME_EGRESS_UNAVAILABLE",a(f.error)||"Egress Proxy rejected the request")):s(f)}catch(f){i(f)}})});o.once("error",i),o.setTimeout(3e3,()=>o.destroy(new Error("Egress Proxy request timed out"))),n?o.end(JSON.stringify(n)):o.end()})}function Ke(e,t){let r=Rn(Fe(e),Fe(t));return r===""||!r.startsWith("..")&&!Rt(r)}function S(e,t){return Object.assign(new Error(t),{code:e})}var Ge=24e3,ze=8,Ve=50,We=6e3,Lo=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),ko=10*60*1e3,Do=60*1e3,vo=8,Ho=30*60*1e3,Fo=60*1e3,$o=1,Nn=2400,Bo=new Set(["max_tokens","max_output_tokens","length"]),jo=new Set(["agent_message_chunk","tool_call","tool_call_update"]),qo=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),Ko=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function Go(e){if(!l(e))return{};let t={};for(let r of["name","code","serverName","serverCode","type","transport","url","command","protocolVersion"]){let n=a(e[r]);n&&(t[r]=n)}return t}function zo(e){return(Array.isArray(e)?e:[]).map(Go).sort((t,r)=>{let n=q(t),s=q(r);return n<s?-1:n>s?1:0})}function Vo(e){return!l(e)||e.verificationPlan?.required!==!0?!1:(Array.isArray(e.verificationPlan.checks)?e.verificationPlan.checks:[]).some(r=>l(r)&&Array.isArray(r.toolNames)&&r.toolNames.some(n=>a(n)==="plugin_operation"))}function Wo(e,t,r){let n=l(e?._meta)?e._meta:{};return{...l(e)?e:{},sessionId:t,update:l(e?.update)?e.update:{},_meta:{...n,orchaAgentId:r.agentId,runtimeSessionId:r.runtimeSessionId,bridgeUpdateId:Jt()}}}function D(e){return e==null||e===""?!1:typeof e=="string"?a(e)!=="":Array.isArray(e)?e.length>0:l(e)?Object.keys(e).length>0:!0}function bn(e){let t=a(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return Lo.has(t)}function z(e,t){let r=_(e,t);return Number.isFinite(r)&&r>0?r:t}function Et(e,t=!1){if(typeof e=="boolean")return e;let r=a(e).toLowerCase();return["true","1","yes","y","on"].includes(r)?!0:["false","0","no","n","off"].includes(r)?!1:t}function G(e){return a(e?.type||"echo")}function Mn(e){let t=G(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function Ye(e){if(l(e)){if(Object.prototype.hasOwnProperty.call(e,"releaseAfterPrompt"))return e.releaseAfterPrompt;if(Object.prototype.hasOwnProperty.call(e,"disposeAfterPrompt"))return e.disposeAfterPrompt}}function Jo(e){let t=String(e||"");if(Ko.test(t))return!0;let r=t.replace(/[^a-z0-9]/gi,"").toLowerCase();return r.endsWith("token")||r.endsWith("secret")||r.endsWith("password")||r.endsWith("apikey")||r.endsWith("privatekey")||r==="authorization"||r==="cookie"||r==="jwt"||r.includes("credential")}function Qe(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=We)return e;let r=e.length-We;return`${e.slice(0,We)}... [truncated ${r} characters]`}if(t>=ze)return Array.isArray(e)?`[array truncated at depth ${ze}, items=${e.length}]`:l(e)?`[object truncated at depth ${ze}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,Ve).map(n=>Qe(n,t+1));return e.length>Ve&&r.push(`[truncated ${e.length-Ve} items]`),r}if(l(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=Jo(n)?"[REDACTED]":Qe(s,t+1);return r}return String(e)}var Xo=new Set(["type","executionId","taskId","task","traceId","requestId","agentCode","stage","phase","nodeId","nodeType","capabilityCode","operationCode","outputType","artifactType","input","inputs","rejection","previous","artifactRefs","outputSchema","executionPolicy","resultContract"]);function Yo(e){if(!l(e))return e;let t={};for(let r of Xo)D(e[r])&&(t[r]=e[r]);return t}function Qo(e){if(!l(e))return e;let t={...e};return l(t.renderedPayload)&&(t.renderedPayload=Yo(t.renderedPayload)),t}function Zo(e){let t=l(e)?e:{},r={};D(t.metadata)&&(r.metadata=Qo(t.metadata));for(let[n,s]of Object.entries(t))qo.has(n)||n==="metadata"||D(s)&&(r[n]=s);return r}function ta(e){let t=l(e)?e:{},r=l(t.metadata)?t.metadata:{},n=l(r.renderedPayload)?r.renderedPayload:{};return l(t.resultContract)?t.resultContract:l(n.resultContract)?n.resultContract:{}}function Un(e){return a(ta(e).kind).toLowerCase()==="decision"}function ea(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:G(e)==="cli"}function Cn(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return Et(t,Mn(e))}function ra(e,t){let r=l(e?.metadata)?{...e.metadata}:{},n=l(r._runtimeBridge)?{...r._runtimeBridge}:{},s=Ye(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:ea(t),releaseAfterPrompt:s===void 0?Cn(t):Et(s,Cn(t)),requiresRuntimeResult:Un(e)},r}function na(e){let t=Zo(e);if(!D(t))return"";let r=JSON.stringify(Qe(t),null,2);if(r.length<=Ge)return r;let n=r.length-Ge;return`${r.slice(0,Ge)}
|
|
14
|
-
... [truncated ${n} characters]`}function
|
|
15
|
-
`:"";t+=`${s}${n}`}}return t.trim()}function
|
|
16
|
-
`?1:0)).trim()}function
|
|
17
|
-
`)}function ma(e,t){let r=l(t)?{...t}:{},n=kn(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function ga(e,t){return{...e,_meta:{...l(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:rr(t)||"max_tokens"}}}}function _a(e,t){let r=typeof e?.output=="string"?e.output:er(t),n=new k("runtime_output_truncated","Runtime Result \u8FBE\u5230\u6700\u5927\u8F93\u51FA\u957F\u5EA6\uFF0C\u7D27\u51D1\u91CD\u8BD5\u540E\u4ECD\u672A\u5B8C\u6574\u8FD4\u56DE",r);return n.detail={...n.detail,stopReason:rr(e)||"max_tokens",retryAttempted:!0},n}var Yt=class{constructor(t){this.config=t,this.targets=t.targets||{},this.agents=new Map,this.sessions=new Map,this.startingSessions=new Set,this.targetReservations=new Map,this.runtimeSessionIndex=new Map,this.pendingPermissions=new Map,this.operations=new Map,this.startedAt=pt(),this.sandboxCapabilities={dispatchable:t.sandboxRequired!==!0,enforced:!1,backend:t.sandboxRequired?"unavailable":"direct",daemonStatus:t.sandboxRequired?"pending":"not_required",policySchemaVersions:[1],runtimePolicyUpdates:t.sandboxRequired===!0,workspaceSync:!1,egressProxy:!1},this.cleanupTimer=null,this.onCapacityChanged=null,this.startSessionCleanup()}async start(){try{this.sandboxCapabilities=await Sn(this.config)}catch(t){this.sandboxCapabilities={...this.sandboxCapabilities,dispatchable:!1,enforced:!1,backend:"unavailable",daemonStatus:"unavailable",reason:a(t?.code||t?.message||t)||"sandbox_probe_failed"},g("error","runtime-bridge","runtime node sandbox probe failed; node will not accept work",{reason:this.sandboxCapabilities.reason})}return this.sandboxCapabilities}assertDispatchable(){if(this.config.sandboxRequired&&!(this.sandboxCapabilities.dispatchable===!0&&this.sandboxCapabilities.enforced===!0))throw Object.assign(new Error("runtime node strong sandbox is unavailable"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"})}operationIdentity(t,r,n){let s=l(t.goalContract)?De(t.goalContract):a(t.goalContractHash),i=Po("sha256").update(q({prompt:Array.isArray(t.prompt)?t.prompt:[],mcpServers:zo(t.mcpServers),metadata:l(t.metadata)?t.metadata:{}})).digest("hex");return{agentId:r,runId:a(t.runId),sessionId:n,targetCode:a(t.targetCode||t.framework),workspace:a(t.workspace),goalContractHash:s,requestHash:i}}assertOperationIdentity(t,r,n,s){let i=this.operationIdentity(r,n,s),o=Object.keys(t.identity).find(c=>t.identity[c]!==i[c]);if(o)throw Object.assign(new Error(`runtime operation correlation conflict: ${t.correlationId}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT",field:o})}createOperation(t,r,n,s){let i={correlationId:t,agentId:n,sessionId:s,identity:this.operationIdentity(r,n,s),sandboxPolicy:l(r.sandboxPolicy)?structuredClone(r.sandboxPolicy):null,status:"running",updates:[],listeners:new Set,waiters:[],response:null,error:null,mcpServers:r.mcpServers,createdAtMs:Date.now(),completedAtMs:null};return this.operations.set(t,i),i}async attachOperation(t,r={}){let n=()=>{if(r.onUpdate)for(let s of t.updates)r.onUpdate(s)};if(t.status==="completed")return n(),t.response;if(t.status==="failed")throw n(),t.error;r.onUpdate&&t.listeners.add(r.onUpdate);try{return n(),await new Promise((s,i)=>t.waiters.push({resolve:s,reject:i}))}finally{r.onUpdate&&t.listeners.delete(r.onUpdate)}}completeOperation(t,r){if(t.status==="running"){t.status="completed",t.response=r,t.mcpServers=null,t.completedAtMs=Date.now();for(let n of t.waiters.splice(0))n.resolve(r);t.listeners.clear()}}promptResponse(t,r,n,s,i,o=s){let c=l(t.metadata)?t.metadata:{},u=l(c._runtimeBridge)?c._runtimeBridge:{},d=Dn(i,o,u),f=yn(t.goalContract,s,t.goalContractHash);return{sessionId:n,runtimeSessionId:r.runtimeSessionId,result:d,updates:s,...f?{verification:f}:{}}}failOperation(t,r){if(t.status!=="running")return;let n=r instanceof Error?r:Object.assign(new Error(String(r||"runtime operation failed")),{code:"RUNTIME_NODE_ERROR"});t.status="failed",t.error=n,t.mcpServers=null,t.completedAtMs=Date.now();for(let s of t.waiters.splice(0))s.reject(n);t.listeners.clear()}cleanupOperations(t=Date.now()){let r=z(this.config.operationTtlMs,Ho);for(let[n,s]of this.operations)s.status!=="running"&&t-(s.completedAtMs||s.createdAtMs)>r&&this.operations.delete(n)}targetFor(t){let r=a(t)||this.config.defaultTargetCode,n=this.targets[r];if(!r||!l(n)){let s=new Error(`runtime target is not configured: ${r||"<empty>"}`);throw s.code="RUNTIME_TARGET_NOT_FOUND",s}return{code:r,target:n}}targetIdleTtlMs(t){let n=G(t)==="openclaw"?z(this.config.openClawSessionIdleTtlMs,Fo):z(this.config.sessionIdleTtlMs,ko);return z(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=G(t)==="openclaw"?z(this.config.openClawMaxSessions,$o):z(this.config.maxSessionsPerTarget,vo);return z(t?.maxSessions,n)}targetReservationCount(t){return Number(this.targetReservations.get(t)||0)}notifyCapacityChanged(){try{this.onCapacityChanged?.()}catch(t){g("warn","runtime-bridge","capacity heartbeat callback failed",{error:String(t)})}}targetCapacitySnapshot(t=!0){return Object.entries(this.targets).map(([r,n])=>{let s=[...this.sessions.values()].filter(f=>f.targetCode===r),i=s.filter(f=>f.busy).length,o=s.length-i,c=this.targetReservationCount(r),u=this.targetMaxSessions(n),d=t?Math.max(0,u-i-c):0;return{targetCode:r,targetName:a(n?.name||n?.targetName||r),targetType:a(n?.type||"echo"),status:t?d>0?"available":"busy":"unavailable",maxSessions:u,busySessions:i,idleSessions:o,reservedSessions:c,availableSessions:d}})}targetReleaseAfterPrompt(t,r={}){let n=G(t),s=l(r?._runtimeBridge)?r._runtimeBridge:{},i=Ye(s);return i!==void 0?Et(i,!1):Et(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=l(r?._runtimeBridge)?r._runtimeBridge:{},s=Ye(n);return s!==void 0?Et(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=z(this.config.sessionCleanupIntervalMs,Do);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(r=>{g("warn","runtime-bridge","runtime session cleanup failed",{error:String(r)})})},t),this.cleanupTimer.unref?.())}sessionCountForTarget(t){let r=0;for(let n of this.sessions.values())n.targetCode===t&&(r+=1);return r}idleTargetSessions(t){return[...this.sessions.entries()].filter(([,r])=>r.targetCode===t&&!r.busy).sort((r,n)=>(r[1].lastUsedAtMs||0)-(n[1].lastUsedAtMs||0))}async closeSession(t,r="session_closed"){let n=this.sessions.get(t);if(!n)return!1;try{await n.runtime?.stop?.(r)}catch(s){g("warn","runtime-bridge","runtime session stop failed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,error:String(s)})}return this.sessions.delete(t),this.runtimeSessionIndex.delete(`${n.agentId}:${n.runtimeSessionId}`),this.notifyCapacityChanged(),g("info","runtime-bridge","runtime session closed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,reason:r}),!0}async closeAllSessions(t="bridge_shutdown"){for(let r of[...this.sessions.keys()])await this.closeSession(r,t)}async stop(t="bridge_stop"){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=null,await this.closeAllSessions(t)}async cleanupExpiredSessions(t=Date.now()){for(let[r,n]of[...this.sessions.entries()])n.busy||t-(n.lastUsedAtMs||n.createdAtMs||t)>n.idleTtlMs&&await this.closeSession(r,"idle_timeout")}async reserveTargetSlot(t,r){let n=this.targetMaxSessions(r);for(;this.sessionCountForTarget(t)+this.targetReservationCount(t)>=n;){let s=this.idleTargetSessions(t);if(!s.length){let i=new Error(`runtime target session limit reached: ${t}`);throw i.code="RUNTIME_TARGET_SESSION_LIMIT",i}await this.closeSession(s[0][0],"target_session_limit")}this.targetReservations.set(t,this.targetReservationCount(t)+1),this.notifyCapacityChanged()}releaseTargetSlot(t){let r=Math.max(0,this.targetReservationCount(t)-1);r>0?this.targetReservations.set(t,r):this.targetReservations.delete(t),this.notifyCapacityChanged()}async createAgent(t){let r=a(t.agentId);if(!r)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let{code:n,target:s}=this.targetFor(t.targetCode||t.framework),i=this.agents.get(r);if(i&&i.targetCode!==n)throw Object.assign(new Error(`runtime agent target conflict: ${r}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});let o=this.config.sandboxRequired?await je(this.config,s,t.workspace):a(t.workspace),c={agentId:r,targetCode:n,framework:a(t.framework||n),workspace:o,metadata:l(t.metadata)?t.metadata:{},createdAt:pt(),runtimeKind:G(s)};return this.agents.set(r,c),{agent:c}}runtimeFor(t,r,n={}){let{target:s}=this.targetFor(t.targetCode),i=G(s),o={onPermissionRequest:u=>n.source==="conversation_delegation"?{outcome:"denied",reason:"External group member permission continuation is not supported"}:this.requestPermission(u)},c={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs,initializeTimeoutMs:this.config.initializeTimeoutMs,sandboxRequired:this.config.sandboxRequired,runId:n.runId,source:n.source,attachOnly:n.attachOnly,sandboxPolicy:n.sandboxPolicy,...this.config.sandboxRequired?{prepareLaunch:u=>On({config:this.config,target:s,...u,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new nt(t,s,o,c):i==="openclaw"?new vt(t,s,r,o,c):i==="cli"?new jt(t,s,c):new Nt(t)}async prompt(t,r={}){if(this.assertDispatchable(),this.config.sandboxRequired){let c=a(t.runId);if(!c)throw Object.assign(new Error("runId is required"),{code:"BAD_REQUEST"});t={...t,runId:c,sandboxPolicy:J(t.sandboxPolicy)}}let n=a(t.agentId),s=a(t.sessionId)||Jt(),i=a(t.correlationId);if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});if(this.cleanupOperations(),i){let c=this.operations.get(i);if(c){if(this.assertOperationIdentity(c,t,n,s),c.status==="running"&&["conversation_delegation","channel_message"].includes(t.metadata?.source)){c.mcpServers=t.mcpServers;let u=this.sessions.get(`${n}:${s}`);if(u){if(!u.runtime.refreshMcpServers)throw Object.assign(new Error("This runtime cannot refresh task MCP credentials"),{code:"unsupported_dynamic_mcp"});await u.runtime.refreshMcpServers(t.mcpServers)}}return this.attachOperation(c,r)}if(t.attachOnly===!0&&!(t.metadata?.source==="channel_message"&&this.targetFor(t.targetCode||t.framework).target.type==="openclaw"))throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"})}else if(t.attachOnly===!0)throw Object.assign(new Error("correlationId is required for attachOnly"),{code:"BAD_REQUEST"});let o=i?this.createOperation(i,t,n,s):null;if(o){let c=this.attachOperation(o,r);return(async()=>{try{await this._promptOwned(t,{},o,n,s)}catch(u){let d=o.status==="completed";this.failOperation(o,u),d&&g("warn","runtime-bridge","runtime cleanup failed after operation completion",{correlationId:o.correlationId,error:String(u)})}})(),await c}return await this._promptOwned(t,r,o,n,s)}async _promptOwned(t,r,n,s,i){let o=a(t.runId),c=this.config.sandboxRequired?J(n?.sandboxPolicy||t.sandboxPolicy):null,u=this.agents.get(s),d=this.targetFor(t.targetCode||t.framework||u?.targetCode);if(u&&u.targetCode!==d.code)throw Object.assign(new Error(`runtime agent target conflict: ${s}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});if(G(d.target)==="cli"&&Vo(t.goalContract))throw Object.assign(new Error("CLI runtimes do not support per-run dynamic MCP required by plugin_operation"),{code:"unsupported_dynamic_mcp"});let f=u||(await this.createAgent({agentId:s,targetCode:d.code,framework:t.framework,workspace:t.workspace,metadata:t.metadata})).agent;if(!this.config.sandboxRequired){let y=a(t.workspace);y&&y!==f.workspace&&(f.workspace=y)}let p=`${s}:${i}`;await this.cleanupExpiredSessions();let h=this.sessions.get(p),m=null;if(h&&h.targetCode!==d.code)throw Object.assign(new Error(`runtime session target conflict: ${i}`),{code:"RUNTIME_SESSION_TARGET_CONFLICT"});if(h&&this.config.sandboxRequired&&h.runId!==o)throw Object.assign(new Error(`runtime session cannot be shared across runs: ${i}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});if(!h){if(this.startingSessions.has(p))throw Object.assign(new Error(`runtime session is already starting: ${i}`),{code:"RUNTIME_SESSION_BUSY"});this.startingSessions.add(p);let{code:y,target:w}=d,E;try{await this.reserveTargetSlot(y,w),m=y;let I=this.runtimeFor(f,i,{runId:o,sandboxPolicy:c,source:t.metadata?.source,attachOnly:t.attachOnly});E=I;let P=n?.mcpServers||t.mcpServers||[],H=await I.sessionNew({cwd:rt(w,f.workspace),mcpServers:P,metadata:l(t.metadata)?t.metadata:{}});if(n&&n.status!=="running")throw Object.assign(new Error("Runtime operation was cancelled before prompt dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"});let b=Date.now();h={agentId:s,sessionId:i,runtime:I,targetCode:y,runtimeKind:G(w),runId:o,sandboxPolicy:c?structuredClone(c):null,runtimeSessionId:a(l(H)?H.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(w),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(w,t.metadata),createdAtMs:b,lastUsedAtMs:b,busy:!1,createdAt:pt()},this.sessions.set(p,h),this.runtimeSessionIndex.set(`${s}:${h.runtimeSessionId}`,h),n?.mcpServers!==P&&n?.mcpServers&&I.refreshMcpServers&&await I.refreshMcpServers(n.mcpServers)}catch(I){throw this.sessions.get(p)?.runtime===E?await this.closeSession(p,"session_start_failed"):await E?.stop("session_start_failed"),m&&(this.releaseTargetSlot(m),m=null),I}finally{this.startingSessions.delete(p)}}if(h.busy){let y=new Error(`runtime session is already running: ${i}`);throw y.code="RUNTIME_SESSION_BUSY",y}h.busy=!0,m&&this.releaseTargetSlot(m),this.notifyCapacityChanged(),h.operationCorrelationId=n?.correlationId||null,h.lastUsedAtMs=Date.now();let T=n?.updates||[],R=y=>{let w=Wo(y,i,h);if(T.push(w),n)for(let E of n.listeners)try{E?.(w)}catch(I){g("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(I)})}else r.onUpdate?.(w)},N=y=>{if(!(!n||n.status!=="running"||!l(y))){if(y.status==="failed"){let w=y.error;if(w instanceof Error){this.failOperation(n,w);return}let E=l(w)?w:{},I=Object.assign(new Error(a(E.message||y.message)||"runtime terminal failure"),{code:a(E.code||y.code)||"RUNTIME_TERMINAL_FAILED"});this.failOperation(n,I);return}this.completeOperation(n,this.promptResponse(t,h,i,T,l(y.result)?y.result:{stopReason:"end_turn"}))}};try{let y=Tn(t.goalContract),w=Array.isArray(t.prompt)?[...t.prompt]:[];y&&w.unshift({type:"text",text:y,metadata:{source:"orcha_goal_contract"}});let E=l(t.metadata)?t.metadata:{},I=l(E._runtimeBridge)?E._runtimeBridge:{},P=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:w,metadata:E},R,N),H=T,b=null;if(Mn({type:h.runtimeKind})&&pa(P,T,I)){b=P;let Z=T.length,ut=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:[{type:"text",text:ha()}],metadata:E,_meta:{thinking:"off"}},R,N);P=ma(b,ut),H=T.slice(Z)}let O;try{O=this.promptResponse(t,h,i,T,P,H)}catch(Z){throw b&&vn(P)?_a(P,H):Z}return b&&(O.result=ga(O.result,b)),n&&this.completeOperation(n,O),O}finally{h.busy=!1,this.notifyCapacityChanged(),h.operationCorrelationId===n?.correlationId&&(h.operationCorrelationId=null),h.lastUsedAtMs=Date.now(),this.promptReleaseAfterPrompt(h,l(t.metadata)?t.metadata:{})&&await this.closeSession(p,"release_after_prompt"),n&&(n.mcpServers=null)}}async updatePolicy(t){if(this.assertDispatchable(),!this.config.sandboxRequired)throw Object.assign(new Error("runtime sandbox policy updates require an enforced sandbox"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"});let r=a(t.agentId),n=a(t.runId),s=a(t.sessionId),i=a(t.correlationId);if(!r||!n||!s||!i)throw Object.assign(new Error("agentId, runId, sessionId and correlationId are required"),{code:"BAD_REQUEST"});let o=J(t.sandboxPolicy),c=this.operations.get(i);if(c&&(c.agentId!==r||c.sessionId!==s||c.identity.runId!==n))throw Object.assign(new Error(`runtime operation policy identity conflict: ${i}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let u=`${r}:${s}`,d=this.sessions.get(u);if(d&&d.runId!==n)throw Object.assign(new Error(`runtime session policy identity conflict: ${s}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});let f=d?.sandboxPolicy||c?.sandboxPolicy;if(!f)throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"});let p=Number(f.policyRevision),h=Number(o.policyRevision);if(h<p)throw Object.assign(new Error("runtime sandbox policy revision is stale"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});if(h===p){if(q(f)!==q(o))throw Object.assign(new Error("runtime sandbox policy revision payload conflicts"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});return{updated:!1,idempotent:!0,policyRevision:p,accessMode:f.accessMode}}let m=En(f,o);c&&(c.sandboxPolicy=structuredClone(o)),d&&(d.sandboxPolicy=structuredClone(o));let T=!1;return m&&d?.busy===!0&&(await d.runtime.sessionCancel({sessionId:d.runtimeSessionId}),T=await this.closeSession(u,"sandbox_policy_downgrade")),{updated:!0,policyRevision:h,accessMode:o.accessMode,activeCommandCancelled:T,deferredToNextLaunch:!m&&d?.busy===!0}}async cancel(t){let r=a(t.agentId),n=a(t.sessionId),s=a(t.correlationId);if(s){let c=this.operations.get(s);if(!c||c.status!=="running")return{cancelled:!1,correlationId:s,reason:"operation_not_running"};if(c.agentId!==r||c.sessionId!==n)throw Object.assign(new Error(`runtime operation cancellation identity conflict: ${s}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let u=this.sessions.get(`${r}:${n}`);return!u||u.busy!==!0||u.operationCorrelationId!==s?(this.failOperation(c,Object.assign(new Error("Runtime operation cancelled before dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"})),{cancelled:!0,correlationId:s,reason:"cancelled_before_dispatch"}):(await u.runtime.sessionCancel({sessionId:u.runtimeSessionId}),await this.closeSession(`${r}:${n}`,"cancelled"),{cancelled:!0,correlationId:s})}let i=`${r}:${n}`,o=this.sessions.get(i);return o?(await o.runtime.sessionCancel({sessionId:o.runtimeSessionId}),await this.closeSession(i,"cancelled"),{cancelled:!0}):{cancelled:!1}}async dispatch(t,r={}){let n=a(t.agentId),s=a(t.taskId),i=a(t.executionId);if(!n||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let o=a(t.sessionId)||`dispatch-${i||s}`,c=a(t.instructions),u=na(t),d=Un(t),{target:f}=this.targetFor(t.targetCode||t.framework),p=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",c?`instructions: ${c}`:"",u?"orchaContext:":"",u,u?"Use orchaContext as the source of truth for upstream outputs, review reports, artifacts, and workflow metadata.":"","Follow the execution protocol in instructions exactly.","When embedding a generated artifact in final Markdown, use the Orcha artifact placeholder as the link target: orcha-artifact://<fieldKey>/<index>.","Example: use  for the first generated image artifact.","Do not use local filesystem paths, file:// URLs, or data: URLs in final Markdown; Orcha replaces artifact placeholders after ingestion.",d?`For decision results, put the raw report between ${Ae} and ${xe}.`:"",d?`Then put a JSON object containing _decision between ${Ne} and ${be}.`:"",d?"Do not JSON-escape the report. Keep output out of the CONTROL JSON, and put every protocol marker on its own line.":"",d?`Keep the report within ${Nn} Unicode characters so the CONTROL block fits before the output limit.`:"","Return only the final answer required by that protocol.","Do not include process notes, logs, or explanations."].filter(Boolean).join(`
|
|
18
|
-
`)}];return this.prompt({...t,agentId:n,sessionId:o,prompt:p,metadata:ra(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=Jt(),c=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||Jt(),u={permissionId:i,agentId:t.agentId,sessionId:c,runtimeSessionId:r,request:l(n)?n:{},status:"pending",createdAt:pt()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:u}}),await new Promise(d=>{let f=_(n?.timeoutMs,this.config.permissionRequestTimeoutMs),p=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:p,resolve:d,permission:u})})}async respondPermission(t){let r=a(t.permissionId),n=this.pendingPermissions.get(r),s=a(t.outcome||"approved")||"approved";return n?(clearTimeout(n.timer),this.pendingPermissions.delete(r),n.resolve({permissionId:r,outcome:s,response:l(t.response)?t.response:{},userId:a(t.userId),metadata:l(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:r,outcome:s}):{accepted:!1,permissionId:r,outcome:s}}health(){return{status:this.config.sandboxRequired&&!this.sandboxCapabilities.dispatchable?"unavailable":"ok",bridgeVersion:et,startedAt:this.startedAt,agents:[...this.agents.values()].map(t=>({agentId:t.agentId,targetCode:t.targetCode,framework:t.framework,runtimeKind:t.runtimeKind})),sessions:this.sessions.size,pendingPermissions:this.pendingPermissions.size,targets:Object.keys(this.targets),sandboxCapabilities:this.sandboxCapabilities}}};import Ta from"node:http";import ya from"node:https";import{randomBytes as Hn}from"node:crypto";var ct=1,X=3,wa=1e4,Qt=class{constructor(t,r={}){this.url=t,this.readyState=0,this.socket=null,this.request=null,this.buffer=Buffer.alloc(0),this.listeners=new Map,this.connectTimeoutMs=Ra(r.connectTimeoutMs,wa),this.connectTimer=null,this.connect()}addEventListener(t,r){let n=this.listeners.get(t)||new Set;n.add(r),this.listeners.set(t,n)}emit(t,r={}){let n=this.listeners.get(t);if(n)for(let s of n)s(r)}connect(){let t=new URL(this.url),r=t.protocol==="wss:"?ya:Ta,n=Hn(16).toString("base64"),s=r.request({protocol:t.protocol==="wss:"?"https:":"http:",hostname:t.hostname,port:t.port||(t.protocol==="wss:"?443:80),path:`${t.pathname}${t.search}`,method:"GET",headers:{Connection:"Upgrade",Upgrade:"websocket","Sec-WebSocket-Key":n,"Sec-WebSocket-Version":"13"}});this.request=s,this.startConnectTimer(s),s.on("upgrade",(i,o,c)=>{if(this.clearConnectTimer(),this.readyState===X){o.destroy();return}this.socket=o,this.readyState=ct,o.on("data",u=>this.onData(u)),o.on("close",()=>this.onClose()),o.on("error",u=>{this.readyState!==X&&this.emit("error",{error:u,message:u.message,type:"error"}),this.onClose()}),c?.length&&this.onData(c),this.emit("open")}),s.on("response",i=>{this.clearConnectTimer(),this.emit("error",{message:`websocket upgrade failed: HTTP ${i.statusCode}`,type:"error"}),i.resume(),this.onClose()}),s.on("error",i=>{this.clearConnectTimer(),this.readyState!==X&&this.emit("error",{error:i,message:i.message,type:"error"}),this.onClose()}),s.end()}startConnectTimer(t){this.connectTimeoutMs<=0||(this.connectTimer=setTimeout(()=>{if(this.readyState===ct||this.readyState===X)return;let r=`websocket connect timeout after ${this.connectTimeoutMs}ms`;this.emit("error",{message:r,type:"timeout"}),this.onClose(),t.destroy(new Error(r))},this.connectTimeoutMs),this.connectTimer.unref?.())}clearConnectTimer(){this.connectTimer&&(clearTimeout(this.connectTimer),this.connectTimer=null)}send(t){!this.socket||this.readyState!==ct||this.socket.write(nr(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==X){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===ct&&this.socket.write(nr(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==X&&(this.clearConnectTimer(),this.readyState=X,this.request=null,this.emit("close"))}onData(t){for(this.buffer=Buffer.concat([this.buffer,t]);this.buffer.length>=2;){let r=this.buffer[0],n=this.buffer[1],s=r&15,i=(n&128)!==0,o=n&127,c=2;if(o===126){if(this.buffer.length<c+2)return;o=this.buffer.readUInt16BE(c),c+=2}else if(o===127){if(this.buffer.length<c+8)return;let f=this.buffer.readUInt32BE(c),p=this.buffer.readUInt32BE(c+4);o=f*2**32+p,c+=8}let u=c;if(i&&(c+=4),this.buffer.length<c+o)return;let d=this.buffer.subarray(c,c+o);if(i){let f=this.buffer.subarray(u,u+4);d=Buffer.from(d.map((p,h)=>p^f[h%4]))}this.buffer=this.buffer.subarray(c+o),s===1?this.emit("message",{data:d.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(nr(10,d))}}};function Ra(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function nr(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=Hn(4),i=Buffer.alloc(n+4+r);i[0]=128|e;let o=2;r<126?i[1]=128|r:r<=65535?(i[1]=254,i.writeUInt16BE(r,o),o+=2):(i[1]=255,i.writeUInt32BE(Math.floor(r/2**32),o),i.writeUInt32BE(r>>>0,o+4),o+=8),s.copy(i,o),o+=4;for(let c=0;c<r;c+=1)i[o+c]=t[c]^s[c%4];return i}function Ea(e){let t=new URL(e);if(t.protocol==="http:")t.protocol="ws:";else if(t.protocol==="https:")t.protocol="wss:";else if(t.protocol!=="ws:"&&t.protocol!=="wss:")throw new Error(`unsupported ORCHA_RUNTIME_ORCHA_URL protocol: ${t.protocol}`);return t.pathname=`${t.pathname.replace(/\/+$/,"")}/api/agent-runtime-bridge/ws`,t.search="",t.toString()}function Sa(e,t=!0){return Object.entries(e||{}).map(([r,n])=>({targetCode:r,targetName:a(n?.name||n?.targetName||r),targetType:a(n?.type||"echo"),status:t?"available":"unavailable"}))}var Oa=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),Zt=class{constructor(t,r){this.config=t,this.bridge=r,this.ws=null,this.stopped=!1,this.connected=!1,this.reconnectTimer=null,this.heartbeatTimer=null,this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=()=>this.scheduleCapacityHeartbeat()}sandboxCapabilities(){return this.bridge.sandboxCapabilities||{dispatchable:this.config.sandboxRequired!==!0,enforced:!1,backend:"development_direct",daemonStatus:"development_only",policySchemaVersions:[1],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:!1}}supportedMethods(){return[...Oa,...this.config.deviceConnection?["devices/discover","devices/configure"]:[]]}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):Sa(this.config.targets,t)}start(){this.connect()}stop(){this.stopped=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=null,this.ws?.close()}connect(){if(this.stopped)return;let t=Ea(this.config.orchaUrl),r=new Qt(t,{connectTimeoutMs:this.config.connectTimeoutMs});this.ws=r,r.addEventListener("open",()=>{if(this.ws!==r||this.stopped){r.close();return}this.authenticate(r)}),r.addEventListener("message",n=>this.handleMessage(n.data,r)),r.addEventListener("close",()=>this.scheduleReconnect("close",r)),r.addEventListener("error",n=>{g("warn","orcha-client","runtime node websocket error",{error:String(n?.message||n?.type||n)})})}authenticate(t=this.ws){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:et,protocolVersion:"orcha-runtime-node.v2",defaultTargetCode:this.config.defaultTargetCode,supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t)}scheduleReconnect(t,r=this.ws){r&&this.ws!==r||(this.connected=!1,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,r&&this.ws===r&&(this.ws=null),!this.stopped&&(this.reconnectTimer||(g("info","orcha-client","runtime node disconnected; reconnect scheduled",{reason:t,reconnectMs:this.config.reconnectMs}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.config.reconnectMs))))}async handleMessage(t,r=this.ws){if(r&&this.ws!==r)return;let n;try{n=JSON.parse(String(t))}catch(s){g("warn","orcha-client","invalid Orcha websocket frame",{error:String(s)});return}if(l(n)){if(n.type==="runtime_node.authenticated"){if(r&&this.ws!==r)return;this.connected=!0,this.startHeartbeat(r),g("info","orcha-client","runtime node authenticated",{nodeId:this.config.nodeId,connectionId:n.connectionId});return}if(n.type==="orcha.runtime.request"){await this.handleRequest(n);return}n.type==="runtime_node.ping"&&this.send({type:"runtime_node.pong",ts:new Date().toISOString(),supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()})}}startHeartbeat(t){this.heartbeatTimer&&clearInterval(this.heartbeatTimer);let r=Math.max(1e3,Number(this.config.heartbeatIntervalMs||15e3)),n=()=>this.sendCapacityHeartbeat(t);n(),this.heartbeatTimer=setInterval(n,r),this.heartbeatTimer.unref?.()}scheduleCapacityHeartbeat(){if(!this.connected||this.capacityHeartbeatTimer)return;let t=Math.max(25,Math.min(1e3,Number(this.config.capacityHeartbeatDebounceMs||100)));this.capacityHeartbeatTimer=setTimeout(()=>{this.capacityHeartbeatTimer=null,this.sendCapacityHeartbeat()},t),this.capacityHeartbeatTimer.unref?.()}sendCapacityHeartbeat(t=this.ws){return this.connected?this.send({type:"runtime_node.heartbeat",ts:new Date().toISOString(),supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t):!1}async handleRequest(t){let r=a(t.id),n=a(t.method),s=l(t.params)?t.params:{};try{let i=await this.invoke(n,s,r);this.send({type:"orcha.runtime.response",id:r,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:r,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i),...i.detail===void 0?{}:{detail:i.detail}}})}}async invoke(t,r,n){if(t==="devices/discover"&&this.config.deviceConnection)return this.config.deviceConnection.candidates();if(t==="devices/configure"&&this.config.deviceConnection)return this.config.deviceConnection.configure(r,this.bridge);if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(r);if(t==="agents/dispatch")return this.bridge.dispatch(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/prompt")return this.bridge.prompt(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/policy")return this.bridge.updatePolicy(r);if(t==="sessions/cancel")return this.bridge.cancel(r);if(t==="permissions/respond")return this.bridge.respondPermission(r);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,r){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:r})}send(t,r=this.ws){return!r||r!==this.ws||r.readyState!==ct?!1:(r.send(JSON.stringify(t)),!0)}};import{existsSync as Fn,readFileSync as Ia}from"node:fs";import{dirname as Ca,resolve as te}from"node:path";import{fileURLToPath as Aa}from"node:url";var xa=/^[A-Za-z_][A-Za-z0-9_]*$/;function $n(e=process.env,t=process.cwd()){let r=a(e.ORCHA_RUNTIME_ENV_FILE),n=r?te(t,r):te(t,".env");if(!Fn(n))return r&&g("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Ia(n,"utf8");for(let o of i.split(/\r?\n/)){let c=Ma(o);if(!c)continue;let[u,d]=c;Object.prototype.hasOwnProperty.call(e,u)||(e[u]=d,s.push(u))}return g("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function Bn(e=process.env){let t=a(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),r=a(e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1"),n=!1,s=Ca(Aa(import.meta.url)),i=te(s,"sandbox","broker.js"),o=te(s,"orcha-runtime-sandbox-broker.js"),c=Fn(i)?i:o,u=a(e.ORCHA_RUNTIME_SANDBOX_BROKER_COMMAND);return{mode:t,host:r,port:_(e.ORCHA_RUNTIME_BRIDGE_PORT,5588),token:e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",orchaUrl:a(e.ORCHA_RUNTIME_ORCHA_URL),nodeToken:e.ORCHA_RUNTIME_NODE_TOKEN||e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",nodeId:a(e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"local-runtime-node"),nodeName:a(e.ORCHA_RUNTIME_NODE_NAME||e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"Local Runtime Node"),reconnectMs:_(e.ORCHA_RUNTIME_RECONNECT_MS,3e3),connectTimeoutMs:_(e.ORCHA_RUNTIME_CONNECT_TIMEOUT_MS||e.ORCHA_RUNTIME_WS_CONNECT_TIMEOUT_MS,1e4),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:_(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),initializeTimeoutMs:_(e.ORCHA_RUNTIME_INITIALIZE_TIMEOUT_MS,3e4),sessionPromptTimeoutMs:_(e.ORCHA_RUNTIME_SESSION_PROMPT_TIMEOUT_MS,36e5),permissionRequestTimeoutMs:_(e.ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS,3e5),sessionIdleTtlMs:_(e.ORCHA_RUNTIME_SESSION_IDLE_TTL_MS,6e5),sessionCleanupIntervalMs:_(e.ORCHA_RUNTIME_SESSION_CLEANUP_INTERVAL_MS,6e4),maxSessionsPerTarget:_(e.ORCHA_RUNTIME_MAX_SESSIONS_PER_TARGET,8),openClawSessionIdleTtlMs:_(e.ORCHA_RUNTIME_OPENCLAW_SESSION_IDLE_TTL_MS,6e4),openClawMaxSessions:_(e.ORCHA_RUNTIME_OPENCLAW_MAX_SESSIONS,1),heartbeatIntervalMs:_(e.ORCHA_RUNTIME_HEARTBEAT_INTERVAL_MS,15e3),sandboxRequired:n,sandboxBrokerCommand:u||process.execPath,sandboxBrokerArguments:sr(e.ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS,"ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS",u?[]:[c]),sandboxProbeTimeoutMs:_(e.ORCHA_RUNTIME_SANDBOX_PROBE_TIMEOUT_MS,1e4),sandboxTempRoot:a(e.ORCHA_RUNTIME_SANDBOX_TEMP_ROOT),trustedWorkspaceRoots:sr(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:sr(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:ba(e.ORCHA_RUNTIME_EGRESS_PROXY_REQUIRED,t==="node"),egressProxySocket:a(e.ORCHA_RUNTIME_EGRESS_PROXY_SOCKET),egressProxyToken:a(e.ORCHA_RUNTIME_EGRESS_PROXY_TOKEN),egressGrantMaxTtlMs:_(e.ORCHA_RUNTIME_EGRESS_GRANT_MAX_TTL_MS,9e5),targets:Na(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Na(e){if(!a(e))return{};try{let t=JSON.parse(e);if(l(t))return t}catch(t){g("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function ba(e,t){let r=a(e).toLowerCase();if(!r)return t;if(["true","1","yes","on"].includes(r))return!0;if(["false","0","no","off"].includes(r))return!1;throw new Error(`invalid boolean configuration value: ${r}`)}function sr(e,t,r=[]){let n=a(e);if(!n)return[...r];let s;try{s=JSON.parse(n)}catch{throw new Error(`${t} must be a JSON string array`)}if(!Array.isArray(s)||s.some(i=>typeof i!="string"))throw new Error(`${t} must be a JSON string array`);return s.map(i=>i.trim()).filter(Boolean)}function Ma(e){let t=e.trim();if(!t||t.startsWith("#"))return null;let r=t.startsWith("export ")?t.slice(7).trimStart():t,n=r.indexOf("=");if(n<=0)return null;let s=r.slice(0,n).trim();if(!xa.test(s))return null;let i=Ua(r.slice(n+1).trim());return[s,i]}function Ua(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?Pa(r):r}return La(e).trim()}function Pa(e){return e.replaceAll("\\n",`
|
|
19
|
-
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function
|
|
20
|
-
`),console.log(JSON.stringify({status:"started",pid:o.pid,pidFile:t,logFile:r}))}async function
|
|
21
|
-
`);
|
|
22
|
-
`:""),g("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:c})}catch(d){g("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function
|
|
13
|
+
${s}`:s;gn(t,r,n,d,s)&&(o=1,c=1)}return s&&i&&(t.finalTextSeen=!0),pn(t,fn(e,t.artifactOptions)),(Yi(e)||Qi(e)||Zi(e)||i)&&n({sessionId:r,update:{sessionUpdate:"runtime_event",event:hn(e)}}),{textCount:o,finalTextCount:c,thoughtCount:u}}function Oe(e,t,r,n,s=Date.now()){if(!t)return{artifactCount:0,transcriptCount:0,textCount:0,finalTextCount:0,thoughtCount:0};let i=e.artifacts.size,o=0,c=0,u=0,d=0,f=Ji(t,r,s);if(f){let p=Math.min(t.processedLines.get(f.path)||0,f.events.length),h=e.artifacts.size;for(let m of f.events.slice(p)){let y=to(m,e,r,n);c+=y.textCount,u+=y.finalTextCount,d+=y.thoughtCount}t.processedLines.set(f.path,f.events.length),(f.events.length>p||e.artifacts.size>h)&&(o=1)}return{artifactCount:e.artifacts.size-i,transcriptCount:o,textCount:c,finalTextCount:u,thoughtCount:d}}function eo(e,{remove:t=!0}={}){if(!e||!on(e))return"";try{return cn(e,"utf8").trim()}catch{return""}finally{t&&Bt(e)}}function Bt(e){if(e)try{pi(e)}catch{}}function ro(e,t){return{artifactCount:(e?.artifactCount||0)+(t?.artifactCount||0),transcriptCount:(e?.transcriptCount||0)+(t?.transcriptCount||0),textCount:(e?.textCount||0)+(t?.textCount||0),finalTextCount:(e?.finalTextCount||0)+(t?.finalTextCount||0),thoughtCount:(e?.thoughtCount||0)+(t?.thoughtCount||0)}}function no(e){return new Promise(t=>setTimeout(t,e))}function so(e,t,r,n){return n?(e.finalTextSeen=!0,e.emittedTexts.has(n)||(e.emittedTexts.add(n),r({sessionId:t,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:n}}})),!0):!1}async function io(e,t,r,n,s,i){let o=Oe(e,t,r,n,Date.now()),c=()=>so(e,r,n,eo(s,{remove:!1}));if(c()||e.finalTextSeen)return Bt(s),o;let u=Ni(i);if(u<=0||!t&&!s)return Bt(s),o;let d=Date.now()+u,f=Math.min(mn(i),100);for(;!e.finalTextSeen&&Date.now()<d&&(await no(Math.min(f,Math.max(0,d-Date.now()))),o=ro(o,Oe(e,t,r,n,Date.now())),!c()););return Bt(s),o}var Gt=class{constructor(t,r,n={}){this.agent=t,this.target=r,this.options=n,this.active=new Map}async sessionNew(t={}){let r=t.mcpServers||[];if(r.length&&t.metadata?.source==="conversation_delegation"&&Zr(this.target)==="codex"){if(this.options.prepareLaunch)throw Object.assign(new Error("Codex task MCP requires a reachable node-local transport; this sandbox launcher does not provide one"),{code:"unsupported_dynamic_mcp"});this.taskMcp=await Yr(r)}else if(r.length&&t.metadata?.source==="conversation_delegation")throw Object.assign(new Error("This CLI adapter does not support task-scoped MCP"),{code:"unsupported_dynamic_mcp"});return{sessionId:`cli-${this.agent.agentId}-${at()}`}}async refreshMcpServers(t){if(!this.taskMcp)throw Object.assign(new Error("The original Codex MCP binding is unavailable"),{code:"RUNTIME_OPERATION_NOT_FOUND"});await this.taskMcp.refresh(t)}async sessionPrompt(t,r,n){let s=Date.now(),i=a(this.target.command);if(!i)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let o=a(t.sessionId)||at(),c=Ut(t.prompt),u=a(this.target.promptMode||"stdin"),d=[...this.taskMcp?.args||[],...this.buildArgs(u,c)],f=it(this.target,this.agent.workspace),p=typeof this.options.prepareLaunch=="function",m=Ai(i,d,this.target)?p?`/tmp/orcha-runtime-last-message-${at()}.txt`:$(un(),`orcha-runtime-last-message-${at()}.txt`):"";m&&d.push("--output-last-message",m);let y={...l(this.target.env)?this.target.env:{},...this.taskMcp?.environment||{},...u==="env"?{ORCHA_RUNTIME_PROMPT:c}:{},ORCHA_AGENT_ID:this.agent.agentId,ORCHA_SESSION_ID:o},R=p?await this.options.prepareLaunch({command:i,args:d,cwd:f,environment:y}):{command:i,args:d,cwd:f,environment:{...process.env,...y},cleanup:async()=>{}},N=p?Di(R):vi(this.target,o),T=N.root,w=Fi(this.target,T,R),E=xi(i,this.target),I={...this.target,targetCode:this.agent.targetCode,cwd:f,...p?{codexHome:$(R.homeDirectory,".codex")}:{}},L=E?ji(I,s):new Set,H=p&&m?$(R.tempDirectory,m.slice(5)):m,b=_(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,_(this.options.sessionPromptTimeoutMs,gi));p||(R.environment.ORCHA_RUNTIME_ARTIFACT_DIR=T);let O=sn(R.command,R.args,{cwd:R.cwd,env:R.environment,stdio:["pipe","pipe","pipe"],detached:process.platform!=="win32",windowsHide:!0});this.active.set(o,O),g("info","runtime.cli","runtime prompt started",{target:this.agent.targetCode,sessionId:o,pid:O.pid,timeoutMs:b,isolation:R.isolation});let rt="",ft=a(this.target.outputMode||"text"),M={artifacts:new Map,emittedTexts:new Set,emittedThoughtTexts:new Set,value:"",artifactOptions:w,finalTextSeen:!1,finalTextOnly:Pi(t,this.target),emitThoughtChunks:Mi(t,this.target),terminalOutcome:null,terminalProtocol:Zr(this.target),emitTerminal:null},oe=E?ki(I,c,s,L):null;return O.stdout.setEncoding("utf8"),O.stdout.on("data",nt=>this.handleStdout(nt,ft,M,o,r)),O.stderr.setEncoding("utf8"),O.stderr.on("data",nt=>{rt+=nt,this.target.emitStderr===!0&&r({sessionId:o,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:nt}}})}),u==="stdin"?O.stdin.end(c):O.stdin.end(),await new Promise((nt,ae)=>{let pt=!1,_r=!1,Ct=null,ht=null,ce=oe&&bi(this.target,t)?setInterval(()=>{try{Oe(M,oe,o,r)}catch(C){g("warn","runtime.cli","codex transcript stream poll failed",{target:this.agent.targetCode,sessionId:o,error:String(C?.message||C)})}},mn(this.target)):null;ce?.unref?.();let yr=setTimeout(()=>{_r=!0,g("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:o,pid:O.pid,timeoutMs:b}),jt(O,"SIGTERM"),Ct=setTimeout(()=>{g("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:o,pid:O.pid}),jt(O,"SIGKILL")},ln),Ct.unref?.(),mt(Object.assign(new Error(`runtime CLI timed out after ${b}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},b);yr.unref?.();let Tr=async()=>{clearTimeout(yr),ht&&clearTimeout(ht),ce&&clearInterval(ce),Ct&&!_r&&clearTimeout(Ct),Hi(N,{target:this.agent.targetCode,sessionId:o}),this.active.delete(o),M.emitTerminal=null,await R.cleanup?.()},ds=C=>{pt||(pt=!0,Tr().then(()=>nt(C),ae))},mt=C=>{pt||(pt=!0,Tr().then(()=>ae(C),B=>{g("warn","runtime.cli","sandbox launch cleanup failed",{target:this.agent.targetCode,sessionId:o,error:String(B?.message||B)}),ae(C)}))};M.emitTerminal=C=>{let B={...l(C.result)?C.result:{},_artifacts:[...M.artifacts.values()]};try{n?.({...C,result:B})}catch(J){g("warn","runtime.cli","runtime terminal listener failed",{target:this.agent.targetCode,sessionId:o,error:String(J?.message||J)})}let F=Math.max(0,_(this.target.terminalExitGraceMs,Ei));ht=setTimeout(()=>{ht=null,!(pt||this.active.get(o)!==O)&&(g("warn","runtime.cli","runtime stayed alive after terminal event; terminating child",{target:this.agent.targetCode,sessionId:o,pid:O.pid,terminalProtocol:M.terminalProtocol,graceMs:F}),Re(O))},F),ht.unref?.()},O.on("error",C=>{g("warn","runtime.cli","runtime child error",{target:this.agent.targetCode,sessionId:o,pid:O.pid,error:String(C?.message||C)}),mt(C)}),O.on("exit",(C,B)=>{(async()=>{ft==="json-lines"&&M.value.trim()&&this.handleStdout(`
|
|
14
|
+
`,ft,M,o,r);let F=await io(M,oe,o,r,H,this.target);(F.artifactCount>0||F.textCount>0||F.thoughtCount>0)&&g("info","runtime.cli","codex transcript updates collected",{target:this.agent.targetCode,sessionId:o,artifactCount:F.artifactCount,textCount:F.textCount,finalTextCount:F.finalTextCount,thoughtCount:F.thoughtCount,transcriptCount:F.transcriptCount});let J=rt.trim();if(J&&g("debug","runtime.cli","runtime stderr",{target:this.agent.targetCode,sessionId:o,stderr:J}),g("info","runtime.cli","runtime prompt finished",{target:this.agent.targetCode,sessionId:o,pid:O.pid,exitCode:C,signal:B,artifactCount:M.artifacts.size,finalTextSeen:M.finalTextSeen}),M.terminalOutcome?.status==="failed"){mt(M.terminalOutcome.error);return}if(C!==0&&M.terminalOutcome?.status!=="completed"){let fs=Object.assign(new Error(`runtime CLI exited with code ${C??"unknown"}${B?` (${B})`:""}`),{code:"RUNTIME_CLI_EXIT_NONZERO",exitCode:C,signal:B});mt(fs);return}ds({stopReason:"end_turn",exitCode:C,signal:B,_artifacts:[...M.artifacts.values()],...J?{stderr:J}:{}})})().catch(mt)})})}buildArgs(t,r){let n=x(this.target.args);return t==="args"?[...n,r]:n}handleStdout(t,r,n,s,i){if(r!=="json-lines"){i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:t}}});return}n.value+=t;let o=n.value.split(/\r?\n/);n.value=o.pop()||"";for(let c of o){let u=c.trim();if(u)try{let d=JSON.parse(u);pn(n,fn(d,n.artifactOptions)),i({sessionId:s,update:{sessionUpdate:"runtime_event",event:hn(d)}});let f=dn(d),p=Ce(d);f&&n.emitThoughtChunks&&!p&&Ci(d)?_n(n,s,i,f):f&&Li(n,p)&&gn(n,s,i,f),f&&p&&(n.finalTextSeen=!0);let h=Ii(d,n.terminalProtocol);h&&!n.terminalOutcome&&(h.status==="failed"||n.finalTextSeen||n.artifacts.size>0)&&(n.terminalOutcome=h,n.emitTerminal?.(h))}catch{i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`${c}
|
|
15
|
+
`}}})}}}async sessionCancel(t){let r=a(t.sessionId),n=this.active.get(r);return n?(g("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),Re(n),{ok:!0,cancelled:!0}):{ok:!0,cancelled:!1}}async stop(t="stop"){for(let[r,n]of this.active.entries())g("info","runtime.cli","stopping runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid,reason:t}),Re(n);this.active.clear(),await this.taskMcp?.close(),this.taskMcp=null}};var xe="ORCHA_RUNTIME_OUTPUT_START",Ne="ORCHA_RUNTIME_OUTPUT_END",be="ORCHA_RUNTIME_CONTROL_START",Me="ORCHA_RUNTIME_CONTROL_END",Ue=xe,Pe=Ne,Le=be,ke=Me,ve=[xe,Ne,be,Me],oo=new Set(["_artifacts","_decision","_meta"]),ao=new RegExp(`(?:^|(?<=[\\r\\n]))[ \\t]*(?<marker>${ve.join("|")})[ \\t]*(?=\\r\\n?|\\n|$)`,"g"),k=class extends Error{constructor(t,r,n){super(r),this.name="RuntimeResultProtocolError",this.code=t,this.detail={rawOutput:n}}};function Sn(e){let t=typeof e=="string"?e.trimStart():"";return ve.some(r=>t.startsWith(r))}function De(e){if(typeof e!="string")return null;let t=e,r=co(t);if(![...r.values()].some(m=>m.length>0))return null;let n=[],s=[];for(let[m,y]of r)y.length===0?n.push(m):y.length>1&&s.push(m);if(n.length>0||s.length>0){let m=[];throw n.length>0&&m.push(`\u7F3A\u5C11 ${n.join(", ")}`),s.length>0&&m.push(`\u91CD\u590D ${s.join(", ")}`),new k("invalid_markers",`Runtime Result \u534F\u8BAE\u6807\u8BB0\u4E0D\u5B8C\u6574\uFF1A${m.join("\uFF1B")}`,t)}let i=r.get(xe)[0],o=r.get(Ne)[0],c=r.get(be)[0],u=r.get(Me)[0];if(!(i.end<=o.start&&o.end<=c.start&&c.end<=u.start))throw new k("invalid_marker_order","Runtime Result \u534F\u8BAE\u6807\u8BB0\u987A\u5E8F\u9519\u8BEF\uFF1A\u5FC5\u987B\u5148\u8F93\u51FA OUTPUT \u5757\uFF0C\u518D\u8F93\u51FA CONTROL \u5757",t);let d=uo(t.slice(i.end,o.start));if(!d.trim())throw new k("empty_output","Runtime Result OUTPUT \u5757\u4E0D\u80FD\u4E3A\u7A7A",t);let f=t.slice(c.end,u.start).trim();if(!f)throw new k("empty_control","Runtime Result CONTROL \u5757\u4E0D\u80FD\u4E3A\u7A7A",t);let p;try{p=JSON.parse(f)}catch(m){throw new k("invalid_control_json",`Runtime Result CONTROL \u5757\u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${String(m?.message||m)}`,t)}if(!En(p))throw new k("invalid_control_type","Runtime Result CONTROL \u5757\u5FC5\u987B\u662F JSON \u5BF9\u8C61",t);let h=Object.keys(p).filter(m=>!oo.has(m)).sort();if(h.length>0)throw new k("invalid_control_keys",`Runtime Result CONTROL \u5757\u5305\u542B\u975E\u6807\u51C6\u5B57\u6BB5\uFF1A${h.join(", ")}`,t);if("_artifacts"in p&&!Array.isArray(p._artifacts))throw new k("invalid_control_field_type","Runtime Result CONTROL \u5757\u7684 _artifacts \u5FC5\u987B\u662F JSON \u6570\u7EC4",t);for(let m of["_decision","_meta"])if(m in p&&!En(p[m]))throw new k("invalid_control_field_type",`Runtime Result CONTROL \u5757\u7684 ${m} \u5FC5\u987B\u662F JSON \u5BF9\u8C61`,t);return{output:d,...p}}function co(e){let t=new Map(ve.map(r=>[r,[]]));for(let r of e.matchAll(ao))t.get(r.groups.marker).push({start:r.index,end:r.index+r[0].length});return t}function uo(e){let t=e.match(/^(?:\r\n|\r|\n)/)?.[0]||"",r=t?e.slice(t.length):e;return t&&r.endsWith(t)?r.slice(0,-t.length):r}function En(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}import{createHash as lo}from"node:crypto";var fo="orcha.goal-contract/v1",po=new Set(["complete","completed","done","ok","passed","success","succeeded"]),ho=new Set(["aborted","blocked","cancelled","canceled","denied","error","failed","failure","timeout","timed_out"]),mo=new Map([["exec_command","run_command"],["local_shell_call","run_command"],["run_command","run_command"],["apply_patch","apply_patch"],["read_file","read_file"],["list_files","list_files"],["plugin_operation","plugin_operation"]]);function Be(e){return lo("sha256").update(q(e)).digest("hex")}function In(e){if(!An(e))return"";let t=["The following Orcha goal contract is immutable for this turn. Do not narrow its outcome or constraints.",`<goal_contract>${JSON.stringify(e)}</goal_contract>`];return e.verificationPlan?.required===!0&&t.push("Every verification check must be satisfied by a real successful tool call from one of its toolNames.","Each check requires requiredMatches distinct successful tool call IDs; repeated updates for one call count once.","A final text claim is not verification; missing or failed tool evidence prevents completion."),t.join(`
|
|
16
|
+
`)}function Cn(e,t,r=""){if(!An(e))return e==null?null:{required:!0,status:"failed",outcome:a(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=Be(e),s=e.verificationPlan.required===!0;if(a(r)&&a(r)!==n)return{required:s,status:"failed",outcome:e.outcome,goalContractHash:n,checks:[],errorCode:"goal_contract_hash_mismatch"};if(!s)return{required:!1,status:"not_required",outcome:e.outcome,goalContractHash:n,checks:[]};let i=go(t),o=e.verificationPlan.checks.map(u=>So(u,i));return{required:!0,status:o.some(u=>u.status==="failed")?"failed":o.some(u=>u.status==="missing")?"missing":"passed",outcome:e.outcome,goalContractHash:n,checks:o}}function An(e){if(!l(e)||e.schemaVersion!==fo||!a(e.outcome))return!1;let t=e.verificationPlan;if(!l(t)||typeof t.required!="boolean"||!Array.isArray(t.checks)||t.required&&t.checks.length===0)return!1;let r=new Set;for(let n of t.checks)if(!l(n)||!a(n.id)||r.has(a(n.id))||(r.add(a(n.id)),!Array.isArray(n.toolNames)||n.toolNames.length===0||n.toolNames.some(s=>!a(s)))||!Number.isSafeInteger(n.requiredMatches)||n.requiredMatches<1||n.arguments!==void 0&&!l(n.arguments))return!1;return!0}function go(e){let t=new Map,r=[];for(let n of Array.isArray(e)?e:[]){let s=l(n?.update)?n.update:{},i=a(s.sessionUpdate);if(i==="runtime_event"){_o(s.event,t,r);continue}if(i==="tool_call"){let o=zt(s)||`tool-${r.length+1}`,c=Kt(t,r,o),u=Fe(s,s.name||s.toolName||s.kind);c.toolName=u.toolName,c.arguments=u.arguments,c.status=Rt(s.status),c.evidence=Wt(s);continue}if(i==="tool_call_update"){let o=zt(s);if(!o)continue;let c=Kt(t,r,o),u=Fe(s,s.name||s.toolName||s.kind);c.toolName||=u.toolName,Object.keys(c.arguments).length===0&&(c.arguments=u.arguments),c.status=Rt(s.status),c.evidence.push(...Wt(s))}}return r}function _o(e,t,r){let n=l(e)&&l(e.payload)?e.payload:l(e)?e:{},s=a(n.type);if(["function_call","custom_tool_call","local_shell_call","mcp_tool_call"].includes(s)){let c=zt(n)||`runtime-${r.length+1}`,u=Kt(t,r,c),d=Fe(n,n.name||n.tool||s,s);u.toolName=d.toolName,u.arguments=d.arguments,u.status=Rt(n.status),u.evidence.push(...Wt(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=zt(n);if(!i)return;let o=Kt(t,r,i);o.status=Ro(n,o.toolName),o.evidence.push(...Wt(n))}function Kt(e,t,r){let n=e.get(r);return n||(n={toolCallId:r,toolName:"",arguments:{},status:"unknown",evidence:[]},e.set(r,n),t.push(n)),n}function yo(e){let t=a(e).toLowerCase();return mo.get(t)||t}function Fe(e,t,r=""){let n=To(e),s=a(r)==="mcp_tool_call"||a(e?.kind).toLowerCase()==="mcp",i=l(e?._meta)?e._meta:{},o=a(e?.server||e?.serverName||e?.server_name||e?.mcpServer||i.server||i.serverName).toLowerCase();if(s&&o==="orcha"){let c=a(e?.tool||e?.toolName||e?.name||t);return{toolName:"plugin_operation",arguments:{...n,...c?{operationCode:c}:{}}}}return{toolName:yo(t),arguments:n}}function zt(e){return l(e)?a(e.call_id||e.callId||e.toolCallId||e.id):""}function To(e){if(!l(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=wo(e[r]);if(n)return n}let t={};for(let r of["cmd","command","cwd","operationCode","path","query","url"])e[r]!==void 0&&(t[r]=e[r]);return t}function wo(e){if(l(e))return structuredClone(e);if(typeof e!="string")return null;try{let t=JSON.parse(e);return l(t)?t:null}catch{return null}}function Ro(e,t){if(!l(e))return"unknown";let r=Vt(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function Vt(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return Eo(e,t,r);if(Array.isArray(e))return e.flatMap(o=>Vt(o,t+1,r));if(!l(e))return[];let n=[];typeof e.isError=="boolean"&&n.push(e.isError?"failed":"success"),typeof e.ok=="boolean"&&n.push(e.ok?"success":"failed"),typeof e.success=="boolean"&&n.push(e.success?"success":"failed");let s=Rt(e.status);s!=="unknown"&&n.push(s);let i=e.exitCode??e.exit_code;typeof i=="number"&&Number.isFinite(i)&&n.push(i===0?"success":"failed");for(let o of["output","result","structuredContent","content"])e[o]!==void 0&&n.push(...Vt(e[o],t+1,r));return n}function Eo(e,t,r){let n=e.trim();if(!n)return[];try{return Vt(JSON.parse(n),t+1,r)}catch{}if(r.parseCliExitCode!==!0)return[];let s=[];for(let i of n.matchAll(/(?:process\s+exited\s+with\s+code|exit\s+code\s*:?)\s*(-?\d+)/gi))s.push(Number(i[1])===0?"success":"failed");return s}function Rt(e){let t=a(e).toLowerCase();return po.has(t)?"success":ho.has(t)?"failed":"unknown"}function Wt(e){if(!l(e))return[];let t=l(e.output)?e.output:{},r=[e.verificationEvidence,l(e.verification)?e.verification.evidence:null,t.verificationEvidence,l(t.verification)?t.verification.evidence:null],n=[];for(let s of r)for(let i of Array.isArray(s)?s:s?[s]:[])!l(i)||!a(i.id)||n.push({id:a(i.id),status:Rt(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...a(i.message)?{message:a(i.message)}:{}});return n}function So(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&$e(e.arguments||{},o.arguments)),n=a(e.evidenceId),s=r.filter(o=>o.status==="success"&&(!n||o.evidence.some(c=>c.id===n&&c.status==="success")));if(s.length>=e.requiredMatches)return He(e,"passed",s,`Runtime tool evidence passed ${s.length} times.`);let i=r.filter(o=>o.status==="failed"||n&&o.evidence.some(c=>c.id===n&&c.status==="failed"));return s.length===0&&i.length?He(e,"failed",i,"Runtime tool evidence failed."):He(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function He(e,t,r,n){let s=r.map(i=>i.toolCallId).filter(Boolean);return{id:e.id,status:t,message:n,...a(e.description)?{description:a(e.description)}:{},toolNames:e.toolNames,requiredMatches:e.requiredMatches,observedMatches:s.length,toolCallIds:s,...l(e.arguments)?{arguments:e.arguments}:{},...a(e.evidenceId)?{evidenceId:a(e.evidenceId)}:{}}}function $e(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>$e(r,t[n])):l(e)?l(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&$e(n,t[r])):!1:Object.is(e,t)}function q(e){if(e===null||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="string")return On(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new Error("invalid_jcs_number");return JSON.stringify(Object.is(e,-0)?0:e)}if(Array.isArray(e))return`[${Array.from({length:e.length},(t,r)=>{if(!Object.hasOwn(e,r))throw new Error("invalid_jcs_json_value");return q(e[r])}).join(",")}]`;if(l(e))return`{${Object.keys(e).sort().map(t=>`${On(t)}:${q(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function On(e){return Oo(e),JSON.stringify(e)}function Oo(e){for(let t=0;t<e.length;t+=1){let r=e.charCodeAt(t);if(r>=55296&&r<=56319){let n=e.charCodeAt(t+1);if(!(n>=56320&&n<=57343))throw new Error("invalid_jcs_unicode");t+=1}else if(r>=56320&&r<=57343)throw new Error("invalid_jcs_unicode")}}import{spawn as Io}from"node:child_process";import{createHash as Co,randomUUID as Ao}from"node:crypto";import{constants as xo}from"node:fs";import{access as No,mkdir as je,readdir as bo,realpath as Et,rm as Mo,stat as Uo}from"node:fs/promises";import Po from"node:http";import{tmpdir as Lo}from"node:os";import{isAbsolute as St,join as ct,relative as xn,resolve as Ge}from"node:path";var Ke=1,ko="orcha.process-isolation/v1",ze="orcha.egress-proxy/v1",vo="--disable-wasm-trap-handler",Jt={read_only:0,workspace_write:1,workspace_network:2},qe={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},Do=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function Q(e){if(!l(e))throw S("RUNTIME_SANDBOX_POLICY_REQUIRED","sandboxPolicy is required");let t=structuredClone(e),r=a(t.accessMode),n=a(t.accessModeCeiling);if(!(r in qe)||!(n in qe))throw S("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if(Jt[r]>Jt[n])throw S("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=qe[r];if(t.filesystemMode!==s||t.networkMode!==i)throw S("RUNTIME_SANDBOX_POLICY_INVALID","runtime access profile does not match its mode");if(Number(t.policySchemaVersion)!==Ke||!Number.isInteger(Number(t.policyRevision))||Number(t.policyRevision)<1)throw S("RUNTIME_SANDBOX_POLICY_INVALID","unsupported sandbox policy schema or revision");for(let[c,u]of Object.entries({outsideWorkspaceAccess:"denied",hostAccess:"denied",hostEnvironmentAccess:"denied",dockerSocketAccess:"denied",environmentMode:"allowlist"}))if(t[c]!==u)throw S("RUNTIME_SANDBOX_POLICY_INVALID",`${c} cannot be relaxed`);let o=l(t.processIsolation)?t.processIsolation:{};if(o.mode!=="required"||o.backend==="direct")throw S("RUNTIME_SANDBOX_POLICY_INVALID","strong process isolation is required");if(Array.isArray(t.alwaysApprovedApprovalKeys)&&t.alwaysApprovedApprovalKeys.length)throw S("RUNTIME_SANDBOX_POLICY_INVALID","persistent runtime approvals are forbidden");return t}function Nn(e,t){let r=Q(e),n=Q(t);return Jt[n.accessMode]<Jt[r.accessMode]}async function bn(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[Ke],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await Un(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await jo(t,x(e.sandboxBrokerArguments),e.sandboxProbeTimeoutMs);if(r.enforced!==!0||a(r.protocolVersion)!=="orcha.runtime-sandbox-broker/v1"||!["bubblewrap","broker"].includes(a(r.backend)))throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker did not report enforced isolation");let n=l(r.probes)?r.probes:{};for(let s of["emptyRoot","outsideWorkspaceDenied","hostFilesystemDenied","sensitiveFilesDenied","environmentAllowlist","dockerSocketDenied","networkNamespace","workspaceReadOnly","workspaceWrite","resourceLimits"])if(n[s]!==!0)throw S("RUNTIME_SANDBOX_UNAVAILABLE",`sandbox broker probe failed: ${s}`);return e.egressProxyRequired&&await Ko(e),{dispatchable:!0,enforced:!0,backend:a(r.backend),daemonStatus:"ok",daemonProtocolVersion:a(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[Ke],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function Ve(e,t,r){let n=a(t.workspace||t.cwd),s=a(r),i=n||(t.allowRequestWorkspace===!0?s:"");if(!i||!St(i))throw S("RUNTIME_WORKSPACE_NOT_CONFIGURED","runtime target must configure an absolute trusted workspace");let o=await Et(i);if(!(await Uo(o)).isDirectory())throw S("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>Et(d))):[o]).some(d=>Je(d,o)))throw S("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function Mn({config:e,target:t,command:r,args:n,cwd:s,environment:i,runId:o,agentId:c,sessionId:u,sandboxPolicy:d}){if(!e.sandboxRequired)return{command:r,args:[...n],cwd:s,environment:{...process.env,...i},tempDirectory:"",isolation:{enforced:!1,backend:"development_direct"},cleanup:async()=>{}};let f=Q(d),p=await Ve(e,t,s),h=await Et(s);if(!Je(p,h))throw S("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let m=await Un(e.sandboxBrokerCommand,process.env.PATH||"");if(!m)throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let y=`runtime-${Co("sha256").update(String(o)).digest("hex").slice(0,32)}`,R=Ge(e.sandboxTempRoot||ct(Lo(),"orcha-runtime-sandboxes"));await je(R,{recursive:!0,mode:448});let N=ct(R,`${y}-${Ao()}`),T=ct(N,"home"),w=ct(N,"artifacts");await je(T,{recursive:!0,mode:448}),await je(w,{recursive:!0,mode:448});let E=f.networkMode==="restricted"?await qo(e,{runId:String(o),instanceId:y,policyRevision:Number(f.policyRevision),ttlMs:Math.min(_(f.maxRuntimeSeconds,900)*1e3,e.egressGrantMaxTtlMs),maxTransferBytes:_(f.maxNetworkBytes,64*1024*1024)}):null,I={PATH:a(i.PATH||process.env.PATH),LANG:a(i.LANG||process.env.LANG||"C.UTF-8"),HOME:"/tmp/home",TMPDIR:"/tmp",USER:"orcha",LOGNAME:"orcha",SHELL:"/bin/sh",ORCHA_AGENT_ID:String(c),ORCHA_SESSION_ID:String(u),ORCHA_RUN_ID:String(o),ORCHA_RUNTIME_ARTIFACT_DIR:"/tmp/artifacts",...Fo(t,i)};I.HOME="/tmp/home",I.TMPDIR="/tmp",I.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",I.NODE_OPTIONS=vo;let L={schemaVersion:ko,runId:String(o),instanceId:y,workspace:p,cwd:h,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await $o(p),temporaryDirectory:N,egressProxy:E,environment:I,resourceLimits:Bo(f),readOnlyToolchainRoots:await Ho(e,t)},H=!1,b=async()=>{if(!H){H=!0;try{E&&await Go(e,E,{runId:String(o),instanceId:y})}finally{await Mo(N,{recursive:!0,force:!0})}}};return{command:m,args:[...x(e.sandboxBrokerArguments),"--",r,...n],cwd:h,environment:{PATH:process.env.PATH||"",LANG:process.env.LANG||"C.UTF-8",ORCHA_PROCESS_ISOLATION_REQUEST:JSON.stringify(L)},tempDirectory:N,homeDirectory:T,artifactDirectory:w,pathMappings:[{runtimeRoot:"/tmp/artifacts",hostRoot:w},{runtimeRoot:"/tmp/home",hostRoot:T}],isolation:{enforced:!0,backend:"broker",instanceId:y,policyRevision:f.policyRevision},cleanup:b}}async function Ho(e,t){let r=x(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(x(e.trustedToolchainRoots).map(i=>Et(i)));if(!n.length)throw S("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","target toolchain roots require ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS");let s=[];for(let i of r){if(!St(i))throw S("RUNTIME_TOOLCHAIN_ROOT_INVALID","toolchain roots must be absolute");let o=await Et(i);if(!n.some(c=>Je(c,o)))throw S("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function Fo(e,t){let r=l(e.env)?e.env:{},n={};for(let[s,i]of Object.entries(r))/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&i!=null&&(n[s]=String(i));for(let s of["ORCHA_RUNTIME_PROMPT","ORCHA_RUNTIME_ARTIFACT_DIR"])t[s]!=null&&(n[s]=String(t[s]));return n}async function $o(e){let t=[],r=0,n=async s=>{let i;try{i=await bo(s,{withFileTypes:!0})}catch(o){if(s===e)throw o;return}for(let o of i){if(r+=1,r>1e4)throw S("RUNTIME_WORKSPACE_SCAN_LIMIT_EXCEEDED","workspace contains more than 10000 entries");let c=ct(s,o.name),u=xn(e,c),d=o.name.toLowerCase();(Do.has(d)||d.startsWith(".env."))&&t.push(u),o.isDirectory()&&!o.isSymbolicLink()&&await n(c)}};return await n(e),t.sort()}function Bo(e){return{maxCpuSeconds:Math.max(1,_(e.maxRuntimeSeconds,900)),maxMemoryBytes:_(e.maxMemoryBytes,2*1024*1024*1024),maxProcesses:_(e.maxProcesses,128),maxOpenFiles:_(e.maxOpenFiles,1024),maxFileBytes:_(e.maxFileBytes,64*1024*1024)}}async function jo(e,t,r){return await new Promise((n,s)=>{let i=Io(e,[...t,"--probe"],{env:{PATH:process.env.PATH||"",LANG:"C.UTF-8"},stdio:["ignore","pipe","pipe"],windowsHide:!0}),o=[],c=[];i.stdout.on("data",d=>o.push(Buffer.from(d))),i.stderr.on("data",d=>c.push(Buffer.from(d)));let u=setTimeout(()=>i.kill("SIGKILL"),Math.max(1e3,r));i.once("error",s),i.once("close",d=>{if(clearTimeout(u),d!==0){s(S("RUNTIME_SANDBOX_UNAVAILABLE",Buffer.concat(c).toString("utf8").trim()||`sandbox probe exited with ${d}`));return}try{n(JSON.parse(Buffer.concat(o).toString("utf8")))}catch{s(S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox probe returned invalid JSON"))}})})}async function Un(e,t){let r=a(e);if(!r)return"";let n=St(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>ct(s,r));for(let s of n)try{return await No(s,xo.X_OK),s}catch{}return""}async function qo(e,t){if(!e.egressProxyRequired)throw S("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await We(e,"POST","/v1/grants",{protocolVersion:ze,...t}),n={socketPath:e.egressProxySocket,grantId:a(r.grantId),credential:a(r.credential)};if(!n.grantId||!n.credential)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy returned an invalid grant");return n}async function Go(e,t,r){await We(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:ze,...r}).catch(()=>{})}async function Ko(e){let t=await We(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==ze)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function We(e,t,r,n){if(!St(e.egressProxySocket)||!e.egressProxyToken)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy socket and token are required");return await new Promise((s,i)=>{let o=Po.request({socketPath:e.egressProxySocket,path:r,method:t,headers:{Authorization:`Bearer ${e.egressProxyToken}`,Accept:"application/json",...n?{"Content-Type":"application/json"}:{}}},c=>{let u=[],d=0;c.on("data",f=>{d+=f.length,d>1048576?o.destroy(new Error("egress response is too large")):u.push(Buffer.from(f))}),c.once("end",()=>{try{let f=JSON.parse(Buffer.concat(u).toString("utf8")||"{}");(c.statusCode||500)>=400?i(S("RUNTIME_EGRESS_UNAVAILABLE",a(f.error)||"Egress Proxy rejected the request")):s(f)}catch(f){i(f)}})});o.once("error",i),o.setTimeout(3e3,()=>o.destroy(new Error("Egress Proxy request timed out"))),n?o.end(JSON.stringify(n)):o.end()})}function Je(e,t){let r=xn(Ge(e),Ge(t));return r===""||!r.startsWith("..")&&!St(r)}function S(e,t){return Object.assign(new Error(t),{code:e})}var Xe=24e3,Ye=8,Qe=50,Ze=6e3,Vo=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),Wo=10*60*1e3,Jo=60*1e3,Xo=8,Yo=30*60*1e3,Qo=60*1e3,Zo=1,vn=2400,ta=new Set(["max_tokens","max_output_tokens","length"]),ea=new Set(["agent_message_chunk","tool_call","tool_call_update"]),ra=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),na=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function sa(e){if(!l(e))return{};let t={};for(let r of["name","code","serverName","serverCode","type","transport","url","command","protocolVersion"]){let n=a(e[r]);n&&(t[r]=n)}return t}function ia(e){return(Array.isArray(e)?e:[]).map(sa).sort((t,r)=>{let n=q(t),s=q(r);return n<s?-1:n>s?1:0})}function oa(e){return!l(e)||e.verificationPlan?.required!==!0?!1:(Array.isArray(e.verificationPlan.checks)?e.verificationPlan.checks:[]).some(r=>l(r)&&Array.isArray(r.toolNames)&&r.toolNames.some(n=>a(n)==="plugin_operation"))}function aa(e,t,r){let n=l(e?._meta)?e._meta:{};return{...l(e)?e:{},sessionId:t,update:l(e?.update)?e.update:{},_meta:{...n,orchaAgentId:r.agentId,runtimeSessionId:r.runtimeSessionId,bridgeUpdateId:Yt()}}}function v(e){return e==null||e===""?!1:typeof e=="string"?a(e)!=="":Array.isArray(e)?e.length>0:l(e)?Object.keys(e).length>0:!0}function Dn(e){let t=a(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return Vo.has(t)}function W(e,t){let r=_(e,t);return Number.isFinite(r)&&r>0?r:t}function Ot(e,t=!1){if(typeof e=="boolean")return e;let r=a(e).toLowerCase();return["true","1","yes","y","on"].includes(r)?!0:["false","0","no","n","off"].includes(r)?!1:t}function K(e){return a(e?.type||"echo")}function Hn(e){let t=K(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function rr(e){if(l(e)){if(Object.prototype.hasOwnProperty.call(e,"releaseAfterPrompt"))return e.releaseAfterPrompt;if(Object.prototype.hasOwnProperty.call(e,"disposeAfterPrompt"))return e.disposeAfterPrompt}}function ca(e){let t=String(e||"");if(na.test(t))return!0;let r=t.replace(/[^a-z0-9]/gi,"").toLowerCase();return r.endsWith("token")||r.endsWith("secret")||r.endsWith("password")||r.endsWith("apikey")||r.endsWith("privatekey")||r==="authorization"||r==="cookie"||r==="jwt"||r.includes("credential")}function nr(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=Ze)return e;let r=e.length-Ze;return`${e.slice(0,Ze)}... [truncated ${r} characters]`}if(t>=Ye)return Array.isArray(e)?`[array truncated at depth ${Ye}, items=${e.length}]`:l(e)?`[object truncated at depth ${Ye}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,Qe).map(n=>nr(n,t+1));return e.length>Qe&&r.push(`[truncated ${e.length-Qe} items]`),r}if(l(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=ca(n)?"[REDACTED]":nr(s,t+1);return r}return String(e)}var ua=new Set(["type","executionId","taskId","task","traceId","requestId","agentCode","stage","phase","nodeId","nodeType","capabilityCode","operationCode","outputType","artifactType","input","inputs","rejection","previous","artifactRefs","outputSchema","executionPolicy","resultContract"]);function la(e){if(!l(e))return e;let t={};for(let r of ua)v(e[r])&&(t[r]=e[r]);return t}function da(e){if(!l(e))return e;let t={...e};return l(t.renderedPayload)&&(t.renderedPayload=la(t.renderedPayload)),t}function fa(e){let t=l(e)?e:{},r={};v(t.metadata)&&(r.metadata=da(t.metadata));for(let[n,s]of Object.entries(t))ra.has(n)||n==="metadata"||v(s)&&(r[n]=s);return r}function pa(e){let t=l(e)?e:{},r=l(t.metadata)?t.metadata:{},n=l(r.renderedPayload)?r.renderedPayload:{};return l(t.resultContract)?t.resultContract:l(n.resultContract)?n.resultContract:{}}function Fn(e){return a(pa(e).kind).toLowerCase()==="decision"}function ha(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:K(e)==="cli"}function Pn(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return Ot(t,Hn(e))}function ma(e,t){let r=l(e?.metadata)?{...e.metadata}:{},n=l(r._runtimeBridge)?{...r._runtimeBridge}:{},s=rr(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:ha(t),releaseAfterPrompt:s===void 0?Pn(t):Ot(s,Pn(t)),requiresRuntimeResult:Fn(e)},r}function ga(e){let t=fa(e);if(!v(t))return"";let r=JSON.stringify(nr(t),null,2);if(r.length<=Xe)return r;let n=r.length-Xe;return`${r.slice(0,Xe)}
|
|
17
|
+
... [truncated ${n} characters]`}function ir(e){if(!l(e))return"";let t=l(e.update)?e.update:e,n=(l(t.content)?t.content:{}).text??t.text;return n==null?"":String(n)}function sr(e){if(!l(e))return"";let t=l(e.update)?e.update:e;return a(t.sessionUpdate)}function or(e){if(!Array.isArray(e))return"";let t=!1,r=[],n=[],s=[],i=()=>{r.length>0&&(n.push(r),r=[])};for(let c of e){let u=sr(c),d=ir(c);if(!u){d&&s.push(d);continue}if(t=!0,u==="agent_message_chunk"){d&&r.push(d);continue}(u==="agent_thought_chunk"||u==="user_message_chunk"||u==="tool_call"||u==="tool_call_update"||u==="plan")&&i()}if(i(),!t)return ut(s);let o=n[n.length-1]||[];return ut(o)}function _a(e){return Array.isArray(e)?e.map(ir).filter(t=>t!==""):[]}function Qt(e){return Array.isArray(e)?e.some(r=>sr(r))?e.filter(r=>ea.has(sr(r))).map(ir).filter(r=>r!==""):_a(e):[]}function ya(e){if(!l(e))return null;let t=l(e.update)?e.update:e;return a(t.sessionUpdate)!=="runtime_event"?null:l(t.event)?t.event:null}function Ta(e){if(!l(e))return"";let t=l(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);if(r==="event_msg"){if(n==="task_complete")return a(t.last_agent_message||t.message||t.output);if(n==="agent_message"){let s=a(t.phase||t.status||t.stage).toLowerCase();if(["final_answer","final","complete","completed","done"].includes(s))return a(t.message||t.text||t.content)}}return""}function wa(e){if(!Array.isArray(e))return"";for(let t=e.length-1;t>=0;t-=1){let r=Ta(ya(e[t]));if(r)return r}return""}function ut(e){let t="";for(let r of e){let n=String(r||"");if(n)if(!t)t=n;else if(n.length>t.length&&n.startsWith(t))t=n;else{let s=Sn(n)&&!/[\r\n]$/.test(t)?`
|
|
18
|
+
`:"";t+=`${s}${n}`}}return t.trim()}function Ra(e){let t=String(e||"").trim();if(!t)return"";let r=t.match(/(?:^|\n)#{1,3}\s+\S/);return!r||r.index===0?t:t.slice(r.index+(t[r.index]===`
|
|
19
|
+
`?1:0)).trim()}function Ln(e){let t=String(e||"").trim();if(!t)return null;try{let r=JSON.parse(t);if(l(r)&&($n(r)||v(r._artifacts)||v(r.artifacts)||v(r._decision)||v(r._meta)))return r}catch{}return null}function It(e){try{return De(e)}catch{return null}}function Xt(...e){let t=null;for(let r of e)try{if(De(r))return}catch(n){t||=n}if(t)throw t}function tr(e){let t=String(e||"").trim();if(!t)return null;let r=It(t);if(r)return r;let n=[...t.matchAll(/```(?:json)?\s*([\s\S]*?)```/gi)];for(let s=n.length-1;s>=0;s-=1){let i=Ln(n[s][1]);if(i)return i}if(!t.endsWith("}"))return null;for(let s=t.lastIndexOf("{");s>=0;s=t.lastIndexOf("{",s-1)){let i=Ln(t.slice(s));if(i)return i}return null}function Ea(e){let t=It(or(e));if(t)return t;let r=Qt(e);for(let n=r.length-1;n>=0;n-=1){let s=It(r[n]);if(s)return s}return It(ut(r))}function $n(e){if(!l(e))return!1;if(v(e.output))return!0;for(let t of["content","text","message","summary"])if(a(e[t]))return!0;return!!(Dn(e.status)||a(e.error)||a(e.errorMessage))}function j(e){let t=l(e)?{...e}:{};return(!Array.isArray(t._artifacts)||t._artifacts.length===0)&&Array.isArray(t.artifacts)&&t.artifacts.length>0&&(t._artifacts=t.artifacts),delete t.artifacts,t}function Sa(e){return l(e)?typeof(l(e._decision)?e._decision:l(e.decision)?e.decision:e).passed=="boolean":!1}function Bn(e){return l(e)?l(e._decision)&&typeof e._decision.passed=="boolean"?!0:Sa(e.output):!1}function er(e,t,r){let n=l(e)?{...e}:{};if(!v(n.output)){for(let s of["summary","message","content","text"])if(a(n[s])){n.output=a(n[s]);break}}return!v(n.output)&&a(r)&&(n.output=a(r)),{...n,_meta:{...l(n._meta)?n._meta:{},runtimeOutputSource:t,requiredRuntimeResult:!0,finalMessagePreview:a(r).slice(0,1e3)}}}var Oa=["dataUrl","dataURL","contentDataUrl","contentDataURL","contentBase64","base64","data"];function kn(e){if(!l(e))return"";let t=l(e.content)?e.content:{},r=l(e.metadata)?e.metadata:{};return a(e.fieldKey||e.field_key||t.fieldKey||r.fieldKey)}function Ia(e,t){let r=l(e.content)?e.content:{},n=l(t.content)?t.content:{},s={...e,...t,content:{...r,...n},metadata:{...l(e.metadata)?e.metadata:{},...l(t.metadata)?t.metadata:{}}};for(let i of Oa)v(e[i])&&(s[i]=e[i]),v(r[i])&&(s.content[i]=r[i]);return s}function jn(e,t){let r=Array.isArray(e)?e.filter(l):[],n=Array.isArray(t)?t.filter(l):[];if(!r.length)return n;if(!n.length)return r;let s=[...r],i=new Map;for(let c=0;c<r.length;c+=1){let u=kn(r[c]),d=i.get(u)||[];d.push(c),i.set(u,d)}let o=new Map;for(let c of n){let u=kn(c),d=o.get(u)||0;o.set(u,d+1);let f=i.get(u)?.[d];f===void 0?s.push(c):s[f]=Ia(s[f],c)}return s}function G(e,t,r){let n={...e,...t,_meta:{...l(e._meta)?e._meta:{},...l(t._meta)?t._meta:{},runtimeOutputSource:r}};return(Array.isArray(e._artifacts)||Array.isArray(t._artifacts))&&(n._artifacts=jn(e._artifacts,t._artifacts)),n}function qn(e,t,r={}){let n=a(r.promptKind),s=r.requiresRuntimeResult===!0,i=s||n==="dispatch",o=j(e),c=typeof o.output=="string"?It(o.output):null;if(c)return G(o,j(c),"result_block");let u=wa(t),d=u?tr(u):null,f=i?Ea(t):null;if($n(o))return Dn(o.status)||a(o.error)||a(o.errorMessage)?o:n==="dispatch"&&d?G(o,j(d),"final_event"):n==="dispatch"&&f?G(o,j(f),"updates"):!s||Bn(o)?o:d?G(o,j(d),"final_event"):f?G(o,j(f),"updates"):(Xt(o.output,u,ut(Qt(t))),er(o,"result",o.output));if(d)return G(o,j(d),"final_event");if(f)return G(o,j(f),"updates");if(u)return s?(Xt(u,ut(Qt(t))),er(o,"final_event",u)):{...o,output:u,_meta:{...l(o._meta)?o._meta:{},runtimeOutputSource:"final_event"}};let p=or(t),h=tr(p);if(h)return G(o,j(h),"updates");let m=Ra(p);if(!m)return s&&Xt(ut(Qt(t))),o;let y=tr(m);return y?G(o,j(y),"updates"):s?(Xt(p,m),er(o,"updates",m)):{...o,output:m,_meta:{...l(o._meta)?o._meta:{},runtimeOutputSource:"updates"}}}function ar(e){return l(e)?a(e.stopReason||e.stop_reason).toLowerCase():""}function Gn(e){return ta.has(ar(e))}function Ca(e,t,r){if(r.promptKind!=="dispatch"||r.requiresRuntimeResult!==!0||!Gn(e))return!1;try{return!Bn(qn(e,t,r))}catch{return!0}}function Aa(){return["Your previous final response reached the output limit before the Runtime Result protocol was complete.","Re-emit the complete final Runtime Result from scratch using the conclusion you already reached.","Do not repeat analysis, process notes, tool calls, or task work.",`Keep the OUTPUT report within ${vn} Unicode characters.`,`Output ${Ue}, ${Pe}, ${Le}, and ${ke} on their own lines.`,"The CONTROL block must be valid JSON containing _decision and must be fully closed.","Return only the two protocol blocks."].join(`
|
|
20
|
+
`)}function xa(e,t){let r=l(t)?{...t}:{},n=jn(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function Na(e,t){return{...e,_meta:{...l(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:ar(t)||"max_tokens"}}}}function ba(e,t){let r=typeof e?.output=="string"?e.output:or(t),n=new k("runtime_output_truncated","Runtime Result \u8FBE\u5230\u6700\u5927\u8F93\u51FA\u957F\u5EA6\uFF0C\u7D27\u51D1\u91CD\u8BD5\u540E\u4ECD\u672A\u5B8C\u6574\u8FD4\u56DE",r);return n.detail={...n.detail,stopReason:ar(e)||"max_tokens",retryAttempted:!0},n}var Zt=class{constructor(t){this.config=t,this.targets=t.targets||{},this.agents=new Map,this.sessions=new Map,this.startingSessions=new Set,this.targetReservations=new Map,this.runtimeSessionIndex=new Map,this.pendingPermissions=new Map,this.operations=new Map,this.startedAt=gt(),this.sandboxCapabilities={dispatchable:t.sandboxRequired!==!0,enforced:!1,backend:t.sandboxRequired?"unavailable":"direct",daemonStatus:t.sandboxRequired?"pending":"not_required",policySchemaVersions:[1],runtimePolicyUpdates:t.sandboxRequired===!0,workspaceSync:!1,egressProxy:!1},this.cleanupTimer=null,this.onCapacityChanged=null,this.startSessionCleanup()}async start(){try{this.sandboxCapabilities=await bn(this.config)}catch(t){this.sandboxCapabilities={...this.sandboxCapabilities,dispatchable:!1,enforced:!1,backend:"unavailable",daemonStatus:"unavailable",reason:a(t?.code||t?.message||t)||"sandbox_probe_failed"},g("error","runtime-bridge","runtime node sandbox probe failed; node will not accept work",{reason:this.sandboxCapabilities.reason})}return this.sandboxCapabilities}assertDispatchable(){if(this.config.sandboxRequired&&!(this.sandboxCapabilities.dispatchable===!0&&this.sandboxCapabilities.enforced===!0))throw Object.assign(new Error("runtime node strong sandbox is unavailable"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"})}operationIdentity(t,r,n){let s=l(t.goalContract)?Be(t.goalContract):a(t.goalContractHash),i=zo("sha256").update(q({prompt:Array.isArray(t.prompt)?t.prompt:[],mcpServers:ia(t.mcpServers),metadata:l(t.metadata)?t.metadata:{}})).digest("hex");return{agentId:r,runId:a(t.runId),sessionId:n,targetCode:a(t.targetCode||t.framework),workspace:a(t.workspace),goalContractHash:s,requestHash:i}}assertOperationIdentity(t,r,n,s){let i=this.operationIdentity(r,n,s),o=Object.keys(t.identity).find(c=>t.identity[c]!==i[c]);if(o)throw Object.assign(new Error(`runtime operation correlation conflict: ${t.correlationId}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT",field:o})}createOperation(t,r,n,s){let i={correlationId:t,agentId:n,sessionId:s,identity:this.operationIdentity(r,n,s),sandboxPolicy:l(r.sandboxPolicy)?structuredClone(r.sandboxPolicy):null,status:"running",updates:[],listeners:new Set,waiters:[],response:null,error:null,mcpServers:r.mcpServers,createdAtMs:Date.now(),completedAtMs:null};return this.operations.set(t,i),i}async attachOperation(t,r={}){let n=()=>{if(r.onUpdate)for(let s of t.updates)r.onUpdate(s)};if(t.status==="completed")return n(),t.response;if(t.status==="failed")throw n(),t.error;r.onUpdate&&t.listeners.add(r.onUpdate);try{return n(),await new Promise((s,i)=>t.waiters.push({resolve:s,reject:i}))}finally{r.onUpdate&&t.listeners.delete(r.onUpdate)}}completeOperation(t,r){if(t.status==="running"){t.status="completed",t.response=r,t.mcpServers=null,t.completedAtMs=Date.now();for(let n of t.waiters.splice(0))n.resolve(r);t.listeners.clear()}}promptResponse(t,r,n,s,i,o=s){let c=l(t.metadata)?t.metadata:{},u=l(c._runtimeBridge)?c._runtimeBridge:{},d=qn(i,o,u),f=Cn(t.goalContract,s,t.goalContractHash);return{sessionId:n,runtimeSessionId:r.runtimeSessionId,result:d,updates:s,...f?{verification:f}:{}}}failOperation(t,r){if(t.status!=="running")return;let n=r instanceof Error?r:Object.assign(new Error(String(r||"runtime operation failed")),{code:"RUNTIME_NODE_ERROR"});t.status="failed",t.error=n,t.mcpServers=null,t.completedAtMs=Date.now();for(let s of t.waiters.splice(0))s.reject(n);t.listeners.clear()}cleanupOperations(t=Date.now()){let r=W(this.config.operationTtlMs,Yo);for(let[n,s]of this.operations)s.status!=="running"&&t-(s.completedAtMs||s.createdAtMs)>r&&this.operations.delete(n)}targetFor(t){let r=a(t)||this.config.defaultTargetCode,n=this.targets[r];if(!r||!l(n)){let s=new Error(`runtime target is not configured: ${r||"<empty>"}`);throw s.code="RUNTIME_TARGET_NOT_FOUND",s}return{code:r,target:n}}targetIdleTtlMs(t){let n=K(t)==="openclaw"?W(this.config.openClawSessionIdleTtlMs,Qo):W(this.config.sessionIdleTtlMs,Wo);return W(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=K(t)==="openclaw"?W(this.config.openClawMaxSessions,Zo):W(this.config.maxSessionsPerTarget,Xo);return W(t?.maxSessions,n)}targetReservationCount(t){return Number(this.targetReservations.get(t)||0)}notifyCapacityChanged(){try{this.onCapacityChanged?.()}catch(t){g("warn","runtime-bridge","capacity heartbeat callback failed",{error:String(t)})}}targetCapacitySnapshot(t=!0){return Object.entries(this.targets).map(([r,n])=>{let s=[...this.sessions.values()].filter(f=>f.targetCode===r),i=s.filter(f=>f.busy).length,o=s.length-i,c=this.targetReservationCount(r),u=this.targetMaxSessions(n),d=t?Math.max(0,u-i-c):0;return{targetCode:r,targetName:a(n?.name||n?.targetName||r),targetType:a(n?.type||"echo"),status:t?d>0?"available":"busy":"unavailable",maxSessions:u,busySessions:i,idleSessions:o,reservedSessions:c,availableSessions:d}})}targetReleaseAfterPrompt(t,r={}){let n=K(t),s=l(r?._runtimeBridge)?r._runtimeBridge:{},i=rr(s);return i!==void 0?Ot(i,!1):Ot(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=l(r?._runtimeBridge)?r._runtimeBridge:{},s=rr(n);return s!==void 0?Ot(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=W(this.config.sessionCleanupIntervalMs,Jo);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(r=>{g("warn","runtime-bridge","runtime session cleanup failed",{error:String(r)})})},t),this.cleanupTimer.unref?.())}sessionCountForTarget(t){let r=0;for(let n of this.sessions.values())n.targetCode===t&&(r+=1);return r}idleTargetSessions(t){return[...this.sessions.entries()].filter(([,r])=>r.targetCode===t&&!r.busy).sort((r,n)=>(r[1].lastUsedAtMs||0)-(n[1].lastUsedAtMs||0))}async closeSession(t,r="session_closed"){let n=this.sessions.get(t);if(!n)return!1;try{await n.runtime?.stop?.(r)}catch(s){g("warn","runtime-bridge","runtime session stop failed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,error:String(s)})}return this.sessions.delete(t),this.runtimeSessionIndex.delete(`${n.agentId}:${n.runtimeSessionId}`),this.notifyCapacityChanged(),g("info","runtime-bridge","runtime session closed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,reason:r}),!0}async closeAllSessions(t="bridge_shutdown"){for(let r of[...this.sessions.keys()])await this.closeSession(r,t)}async stop(t="bridge_stop"){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=null,await this.closeAllSessions(t)}async cleanupExpiredSessions(t=Date.now()){for(let[r,n]of[...this.sessions.entries()])n.busy||t-(n.lastUsedAtMs||n.createdAtMs||t)>n.idleTtlMs&&await this.closeSession(r,"idle_timeout")}async reserveTargetSlot(t,r){let n=this.targetMaxSessions(r);for(;this.sessionCountForTarget(t)+this.targetReservationCount(t)>=n;){let s=this.idleTargetSessions(t);if(!s.length){let i=new Error(`runtime target session limit reached: ${t}`);throw i.code="RUNTIME_TARGET_SESSION_LIMIT",i}await this.closeSession(s[0][0],"target_session_limit")}this.targetReservations.set(t,this.targetReservationCount(t)+1),this.notifyCapacityChanged()}releaseTargetSlot(t){let r=Math.max(0,this.targetReservationCount(t)-1);r>0?this.targetReservations.set(t,r):this.targetReservations.delete(t),this.notifyCapacityChanged()}async createAgent(t){let r=a(t.agentId);if(!r)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let{code:n,target:s}=this.targetFor(t.targetCode||t.framework),i=this.agents.get(r);if(i&&i.targetCode!==n)throw Object.assign(new Error(`runtime agent target conflict: ${r}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});let o=this.config.sandboxRequired?await Ve(this.config,s,t.workspace):a(t.workspace),c={agentId:r,targetCode:n,framework:a(t.framework||n),workspace:o,metadata:l(t.metadata)?t.metadata:{},createdAt:gt(),runtimeKind:K(s)};return this.agents.set(r,c),{agent:c}}runtimeFor(t,r,n={}){let{target:s}=this.targetFor(t.targetCode),i=K(s),o={onPermissionRequest:u=>n.source==="conversation_delegation"?{outcome:"denied",reason:"External group member permission continuation is not supported"}:this.requestPermission(u)},c={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs,initializeTimeoutMs:this.config.initializeTimeoutMs,sandboxRequired:this.config.sandboxRequired,runId:n.runId,source:n.source,attachOnly:n.attachOnly,sandboxPolicy:n.sandboxPolicy,...this.config.sandboxRequired?{prepareLaunch:u=>Mn({config:this.config,target:s,...u,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new ot(t,s,o,c):i==="openclaw"?new Ft(t,s,r,o,c):i==="cli"?new Gt(t,s,c):new Pt(t)}async prompt(t,r={}){if(this.assertDispatchable(),this.config.sandboxRequired){let c=a(t.runId);if(!c)throw Object.assign(new Error("runId is required"),{code:"BAD_REQUEST"});t={...t,runId:c,sandboxPolicy:Q(t.sandboxPolicy)}}let n=a(t.agentId),s=a(t.sessionId)||Yt(),i=a(t.correlationId);if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});if(this.cleanupOperations(),i){let c=this.operations.get(i);if(c){if(this.assertOperationIdentity(c,t,n,s),c.status==="running"&&["conversation_delegation","channel_message"].includes(t.metadata?.source)){c.mcpServers=t.mcpServers;let u=this.sessions.get(`${n}:${s}`);if(u){if(!u.runtime.refreshMcpServers)throw Object.assign(new Error("This runtime cannot refresh task MCP credentials"),{code:"unsupported_dynamic_mcp"});await u.runtime.refreshMcpServers(t.mcpServers)}}return this.attachOperation(c,r)}if(t.attachOnly===!0&&!(t.metadata?.source==="channel_message"&&this.targetFor(t.targetCode||t.framework).target.type==="openclaw"))throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"})}else if(t.attachOnly===!0)throw Object.assign(new Error("correlationId is required for attachOnly"),{code:"BAD_REQUEST"});let o=i?this.createOperation(i,t,n,s):null;if(o){let c=this.attachOperation(o,r);return(async()=>{try{await this._promptOwned(t,{},o,n,s)}catch(u){let d=o.status==="completed";this.failOperation(o,u),d&&g("warn","runtime-bridge","runtime cleanup failed after operation completion",{correlationId:o.correlationId,error:String(u)})}})(),await c}return await this._promptOwned(t,r,o,n,s)}async _promptOwned(t,r,n,s,i){let o=a(t.runId),c=this.config.sandboxRequired?Q(n?.sandboxPolicy||t.sandboxPolicy):null,u=this.agents.get(s),d=this.targetFor(t.targetCode||t.framework||u?.targetCode);if(u&&u.targetCode!==d.code)throw Object.assign(new Error(`runtime agent target conflict: ${s}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});if(K(d.target)==="cli"&&oa(t.goalContract))throw Object.assign(new Error("CLI runtimes do not support per-run dynamic MCP required by plugin_operation"),{code:"unsupported_dynamic_mcp"});let f=u||(await this.createAgent({agentId:s,targetCode:d.code,framework:t.framework,workspace:t.workspace,metadata:t.metadata})).agent;if(!this.config.sandboxRequired){let T=a(t.workspace);T&&T!==f.workspace&&(f.workspace=T)}let p=`${s}:${i}`;await this.cleanupExpiredSessions();let h=this.sessions.get(p),m=null;if(h&&h.targetCode!==d.code)throw Object.assign(new Error(`runtime session target conflict: ${i}`),{code:"RUNTIME_SESSION_TARGET_CONFLICT"});if(h&&this.config.sandboxRequired&&h.runId!==o)throw Object.assign(new Error(`runtime session cannot be shared across runs: ${i}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});if(!h){if(this.startingSessions.has(p))throw Object.assign(new Error(`runtime session is already starting: ${i}`),{code:"RUNTIME_SESSION_BUSY"});this.startingSessions.add(p);let{code:T,target:w}=d,E;try{await this.reserveTargetSlot(T,w),m=T;let I=this.runtimeFor(f,i,{runId:o,sandboxPolicy:c,source:t.metadata?.source,attachOnly:t.attachOnly});E=I;let L=n?.mcpServers||t.mcpServers||[],H=await I.sessionNew({cwd:it(w,f.workspace),mcpServers:L,metadata:l(t.metadata)?t.metadata:{}});if(n&&n.status!=="running")throw Object.assign(new Error("Runtime operation was cancelled before prompt dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"});let b=Date.now();h={agentId:s,sessionId:i,runtime:I,targetCode:T,runtimeKind:K(w),runId:o,sandboxPolicy:c?structuredClone(c):null,runtimeSessionId:a(l(H)?H.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(w),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(w,t.metadata),createdAtMs:b,lastUsedAtMs:b,busy:!1,createdAt:gt()},this.sessions.set(p,h),this.runtimeSessionIndex.set(`${s}:${h.runtimeSessionId}`,h),n?.mcpServers!==L&&n?.mcpServers&&I.refreshMcpServers&&await I.refreshMcpServers(n.mcpServers)}catch(I){throw this.sessions.get(p)?.runtime===E?await this.closeSession(p,"session_start_failed"):await E?.stop("session_start_failed"),m&&(this.releaseTargetSlot(m),m=null),I}finally{this.startingSessions.delete(p)}}if(h.busy){let T=new Error(`runtime session is already running: ${i}`);throw T.code="RUNTIME_SESSION_BUSY",T}h.busy=!0,m&&this.releaseTargetSlot(m),this.notifyCapacityChanged(),h.operationCorrelationId=n?.correlationId||null,h.lastUsedAtMs=Date.now();let y=n?.updates||[],R=T=>{let w=aa(T,i,h);if(y.push(w),n)for(let E of n.listeners)try{E?.(w)}catch(I){g("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(I)})}else r.onUpdate?.(w)},N=T=>{if(!(!n||n.status!=="running"||!l(T))){if(T.status==="failed"){let w=T.error;if(w instanceof Error){this.failOperation(n,w);return}let E=l(w)?w:{},I=Object.assign(new Error(a(E.message||T.message)||"runtime terminal failure"),{code:a(E.code||T.code)||"RUNTIME_TERMINAL_FAILED"});this.failOperation(n,I);return}this.completeOperation(n,this.promptResponse(t,h,i,y,l(T.result)?T.result:{stopReason:"end_turn"}))}};try{let T=In(t.goalContract),w=Array.isArray(t.prompt)?[...t.prompt]:[];T&&w.unshift({type:"text",text:T,metadata:{source:"orcha_goal_contract"}});let E=l(t.metadata)?t.metadata:{},I=l(E._runtimeBridge)?E._runtimeBridge:{},L=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:w,metadata:E},R,N),H=y,b=null;if(Hn({type:h.runtimeKind})&&Ca(L,y,I)){b=L;let rt=y.length,ft=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:[{type:"text",text:Aa()}],metadata:E,_meta:{thinking:"off"}},R,N);L=xa(b,ft),H=y.slice(rt)}let O;try{O=this.promptResponse(t,h,i,y,L,H)}catch(rt){throw b&&Gn(L)?ba(L,H):rt}return b&&(O.result=Na(O.result,b)),n&&this.completeOperation(n,O),O}finally{h.busy=!1,this.notifyCapacityChanged(),h.operationCorrelationId===n?.correlationId&&(h.operationCorrelationId=null),h.lastUsedAtMs=Date.now(),this.promptReleaseAfterPrompt(h,l(t.metadata)?t.metadata:{})&&await this.closeSession(p,"release_after_prompt"),n&&(n.mcpServers=null)}}async updatePolicy(t){if(this.assertDispatchable(),!this.config.sandboxRequired)throw Object.assign(new Error("runtime sandbox policy updates require an enforced sandbox"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"});let r=a(t.agentId),n=a(t.runId),s=a(t.sessionId),i=a(t.correlationId);if(!r||!n||!s||!i)throw Object.assign(new Error("agentId, runId, sessionId and correlationId are required"),{code:"BAD_REQUEST"});let o=Q(t.sandboxPolicy),c=this.operations.get(i);if(c&&(c.agentId!==r||c.sessionId!==s||c.identity.runId!==n))throw Object.assign(new Error(`runtime operation policy identity conflict: ${i}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let u=`${r}:${s}`,d=this.sessions.get(u);if(d&&d.runId!==n)throw Object.assign(new Error(`runtime session policy identity conflict: ${s}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});let f=d?.sandboxPolicy||c?.sandboxPolicy;if(!f)throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"});let p=Number(f.policyRevision),h=Number(o.policyRevision);if(h<p)throw Object.assign(new Error("runtime sandbox policy revision is stale"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});if(h===p){if(q(f)!==q(o))throw Object.assign(new Error("runtime sandbox policy revision payload conflicts"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});return{updated:!1,idempotent:!0,policyRevision:p,accessMode:f.accessMode}}let m=Nn(f,o);c&&(c.sandboxPolicy=structuredClone(o)),d&&(d.sandboxPolicy=structuredClone(o));let y=!1;return m&&d?.busy===!0&&(await d.runtime.sessionCancel({sessionId:d.runtimeSessionId}),y=await this.closeSession(u,"sandbox_policy_downgrade")),{updated:!0,policyRevision:h,accessMode:o.accessMode,activeCommandCancelled:y,deferredToNextLaunch:!m&&d?.busy===!0}}async cancel(t){let r=a(t.agentId),n=a(t.sessionId),s=a(t.correlationId);if(s){let c=this.operations.get(s);if(!c||c.status!=="running")return{cancelled:!1,correlationId:s,reason:"operation_not_running"};if(c.agentId!==r||c.sessionId!==n)throw Object.assign(new Error(`runtime operation cancellation identity conflict: ${s}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let u=this.sessions.get(`${r}:${n}`);return!u||u.busy!==!0||u.operationCorrelationId!==s?(this.failOperation(c,Object.assign(new Error("Runtime operation cancelled before dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"})),{cancelled:!0,correlationId:s,reason:"cancelled_before_dispatch"}):(await u.runtime.sessionCancel({sessionId:u.runtimeSessionId}),await this.closeSession(`${r}:${n}`,"cancelled"),{cancelled:!0,correlationId:s})}let i=`${r}:${n}`,o=this.sessions.get(i);return o?(await o.runtime.sessionCancel({sessionId:o.runtimeSessionId}),await this.closeSession(i,"cancelled"),{cancelled:!0}):{cancelled:!1}}async dispatch(t,r={}){let n=a(t.agentId),s=a(t.taskId),i=a(t.executionId);if(!n||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let o=a(t.sessionId)||`dispatch-${i||s}`,c=a(t.instructions),u=ga(t),d=Fn(t),{target:f}=this.targetFor(t.targetCode||t.framework),p=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",c?`instructions: ${c}`:"",u?"orchaContext:":"",u,u?"Use orchaContext as the source of truth for upstream outputs, review reports, artifacts, and workflow metadata.":"","Follow the execution protocol in instructions exactly.","When embedding a generated artifact in final Markdown, use the Orcha artifact placeholder as the link target: orcha-artifact://<fieldKey>/<index>.","Example: use  for the first generated image artifact.","Do not use local filesystem paths, file:// URLs, or data: URLs in final Markdown; Orcha replaces artifact placeholders after ingestion.",d?`For decision results, put the raw report between ${Ue} and ${Pe}.`:"",d?`Then put a JSON object containing _decision between ${Le} and ${ke}.`:"",d?"Do not JSON-escape the report. Keep output out of the CONTROL JSON, and put every protocol marker on its own line.":"",d?`Keep the report within ${vn} Unicode characters so the CONTROL block fits before the output limit.`:"","Return only the final answer required by that protocol.","Do not include process notes, logs, or explanations."].filter(Boolean).join(`
|
|
21
|
+
`)}];return this.prompt({...t,agentId:n,sessionId:o,prompt:p,metadata:ma(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=Yt(),c=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||Yt(),u={permissionId:i,agentId:t.agentId,sessionId:c,runtimeSessionId:r,request:l(n)?n:{},status:"pending",createdAt:gt()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:u}}),await new Promise(d=>{let f=_(n?.timeoutMs,this.config.permissionRequestTimeoutMs),p=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:p,resolve:d,permission:u})})}async respondPermission(t){let r=a(t.permissionId),n=this.pendingPermissions.get(r),s=a(t.outcome||"approved")||"approved";return n?(clearTimeout(n.timer),this.pendingPermissions.delete(r),n.resolve({permissionId:r,outcome:s,response:l(t.response)?t.response:{},userId:a(t.userId),metadata:l(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:r,outcome:s}):{accepted:!1,permissionId:r,outcome:s}}health(){return{status:this.config.sandboxRequired&&!this.sandboxCapabilities.dispatchable?"unavailable":"ok",bridgeVersion:z,startedAt:this.startedAt,agents:[...this.agents.values()].map(t=>({agentId:t.agentId,targetCode:t.targetCode,framework:t.framework,runtimeKind:t.runtimeKind})),sessions:this.sessions.size,pendingPermissions:this.pendingPermissions.size,targets:Object.keys(this.targets),sandboxCapabilities:this.sandboxCapabilities}}};import Ma from"node:http";import Ua from"node:https";import{randomBytes as Kn}from"node:crypto";var lt=1,Z=3,Pa=1e4,te=class{constructor(t,r={}){this.url=t,this.readyState=0,this.socket=null,this.request=null,this.buffer=Buffer.alloc(0),this.listeners=new Map,this.connectTimeoutMs=La(r.connectTimeoutMs,Pa),this.connectTimer=null,this.connect()}addEventListener(t,r){let n=this.listeners.get(t)||new Set;n.add(r),this.listeners.set(t,n)}emit(t,r={}){let n=this.listeners.get(t);if(n)for(let s of n)s(r)}connect(){let t=new URL(this.url),r=t.protocol==="wss:"?Ua:Ma,n=Kn(16).toString("base64"),s=r.request({protocol:t.protocol==="wss:"?"https:":"http:",hostname:t.hostname,port:t.port||(t.protocol==="wss:"?443:80),path:`${t.pathname}${t.search}`,method:"GET",headers:{Connection:"Upgrade",Upgrade:"websocket","Sec-WebSocket-Key":n,"Sec-WebSocket-Version":"13"}});this.request=s,this.startConnectTimer(s),s.on("upgrade",(i,o,c)=>{if(this.clearConnectTimer(),this.readyState===Z){o.destroy();return}this.socket=o,this.readyState=lt,o.on("data",u=>this.onData(u)),o.on("close",()=>this.onClose()),o.on("error",u=>{this.readyState!==Z&&this.emit("error",{error:u,message:u.message,type:"error"}),this.onClose()}),c?.length&&this.onData(c),this.emit("open")}),s.on("response",i=>{this.clearConnectTimer(),this.emit("error",{message:`websocket upgrade failed: HTTP ${i.statusCode}`,type:"error"}),i.resume(),this.onClose()}),s.on("error",i=>{this.clearConnectTimer(),this.readyState!==Z&&this.emit("error",{error:i,message:i.message,type:"error"}),this.onClose()}),s.end()}startConnectTimer(t){this.connectTimeoutMs<=0||(this.connectTimer=setTimeout(()=>{if(this.readyState===lt||this.readyState===Z)return;let r=`websocket connect timeout after ${this.connectTimeoutMs}ms`;this.emit("error",{message:r,type:"timeout"}),this.onClose(),t.destroy(new Error(r))},this.connectTimeoutMs),this.connectTimer.unref?.())}clearConnectTimer(){this.connectTimer&&(clearTimeout(this.connectTimer),this.connectTimer=null)}send(t){!this.socket||this.readyState!==lt||this.socket.write(cr(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==Z){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===lt&&this.socket.write(cr(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==Z&&(this.clearConnectTimer(),this.readyState=Z,this.request=null,this.emit("close"))}onData(t){for(this.buffer=Buffer.concat([this.buffer,t]);this.buffer.length>=2;){let r=this.buffer[0],n=this.buffer[1],s=r&15,i=(n&128)!==0,o=n&127,c=2;if(o===126){if(this.buffer.length<c+2)return;o=this.buffer.readUInt16BE(c),c+=2}else if(o===127){if(this.buffer.length<c+8)return;let f=this.buffer.readUInt32BE(c),p=this.buffer.readUInt32BE(c+4);o=f*2**32+p,c+=8}let u=c;if(i&&(c+=4),this.buffer.length<c+o)return;let d=this.buffer.subarray(c,c+o);if(i){let f=this.buffer.subarray(u,u+4);d=Buffer.from(d.map((p,h)=>p^f[h%4]))}this.buffer=this.buffer.subarray(c+o),s===1?this.emit("message",{data:d.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(cr(10,d))}}};function La(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function cr(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=Kn(4),i=Buffer.alloc(n+4+r);i[0]=128|e;let o=2;r<126?i[1]=128|r:r<=65535?(i[1]=254,i.writeUInt16BE(r,o),o+=2):(i[1]=255,i.writeUInt32BE(Math.floor(r/2**32),o),i.writeUInt32BE(r>>>0,o+4),o+=8),s.copy(i,o),o+=4;for(let c=0;c<r;c+=1)i[o+c]=t[c]^s[c%4];return i}function ka(e){let t=new URL(e);if(t.protocol==="http:")t.protocol="ws:";else if(t.protocol==="https:")t.protocol="wss:";else if(t.protocol!=="ws:"&&t.protocol!=="wss:")throw new Error(`unsupported ORCHA_RUNTIME_ORCHA_URL protocol: ${t.protocol}`);return t.pathname=`${t.pathname.replace(/\/+$/,"")}/api/agent-runtime-bridge/ws`,t.search="",t.toString()}function va(e,t=!0){return Object.entries(e||{}).map(([r,n])=>({targetCode:r,targetName:a(n?.name||n?.targetName||r),targetType:a(n?.type||"echo"),status:t?"available":"unavailable"}))}var Da=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),ee=class{constructor(t,r){this.config=t,this.bridge=r,this.ws=null,this.stopped=!1,this.connected=!1,this.reconnectTimer=null,this.heartbeatTimer=null,this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=()=>this.scheduleCapacityHeartbeat()}sandboxCapabilities(){return this.bridge.sandboxCapabilities||{dispatchable:this.config.sandboxRequired!==!0,enforced:!1,backend:"development_direct",daemonStatus:"development_only",policySchemaVersions:[1],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:!1}}supportedMethods(){return[...Da,...this.config.deviceConnection?["devices/discover","devices/configure"]:[]]}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):va(this.config.targets,t)}start(){this.connect()}stop(){this.stopped=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=null,this.ws?.close()}connect(){if(this.stopped)return;let t=ka(this.config.orchaUrl),r=new te(t,{connectTimeoutMs:this.config.connectTimeoutMs});this.ws=r,r.addEventListener("open",()=>{if(this.ws!==r||this.stopped){r.close();return}this.authenticate(r)}),r.addEventListener("message",n=>this.handleMessage(n.data,r)),r.addEventListener("close",()=>this.scheduleReconnect("close",r)),r.addEventListener("error",n=>{g("warn","orcha-client","runtime node websocket error",{error:String(n?.message||n?.type||n)})})}authenticate(t=this.ws){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:z,protocolVersion:"orcha-runtime-node.v2",defaultTargetCode:this.config.defaultTargetCode,supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t)}scheduleReconnect(t,r=this.ws){r&&this.ws!==r||(this.connected=!1,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,r&&this.ws===r&&(this.ws=null),!this.stopped&&(this.reconnectTimer||(g("info","orcha-client","runtime node disconnected; reconnect scheduled",{reason:t,reconnectMs:this.config.reconnectMs}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.config.reconnectMs))))}async handleMessage(t,r=this.ws){if(r&&this.ws!==r)return;let n;try{n=JSON.parse(String(t))}catch(s){g("warn","orcha-client","invalid Orcha websocket frame",{error:String(s)});return}if(l(n)){if(n.type==="runtime_node.authenticated"){if(r&&this.ws!==r)return;this.connected=!0,this.startHeartbeat(r),g("info","orcha-client","runtime node authenticated",{nodeId:this.config.nodeId,connectionId:n.connectionId});return}if(n.type==="orcha.runtime.request"){await this.handleRequest(n);return}n.type==="runtime_node.ping"&&this.send({type:"runtime_node.pong",ts:new Date().toISOString(),supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()})}}startHeartbeat(t){this.heartbeatTimer&&clearInterval(this.heartbeatTimer);let r=Math.max(1e3,Number(this.config.heartbeatIntervalMs||15e3)),n=()=>this.sendCapacityHeartbeat(t);n(),this.heartbeatTimer=setInterval(n,r),this.heartbeatTimer.unref?.()}scheduleCapacityHeartbeat(){if(!this.connected||this.capacityHeartbeatTimer)return;let t=Math.max(25,Math.min(1e3,Number(this.config.capacityHeartbeatDebounceMs||100)));this.capacityHeartbeatTimer=setTimeout(()=>{this.capacityHeartbeatTimer=null,this.sendCapacityHeartbeat()},t),this.capacityHeartbeatTimer.unref?.()}sendCapacityHeartbeat(t=this.ws){return this.connected?this.send({type:"runtime_node.heartbeat",ts:new Date().toISOString(),supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t):!1}async handleRequest(t){let r=a(t.id),n=a(t.method),s=l(t.params)?t.params:{};try{let i=await this.invoke(n,s,r);this.send({type:"orcha.runtime.response",id:r,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:r,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i),...i.detail===void 0?{}:{detail:i.detail}}})}}async invoke(t,r,n){if(t==="devices/discover"&&this.config.deviceConnection)return this.config.deviceConnection.candidates();if(t==="devices/configure"&&this.config.deviceConnection)return this.config.deviceConnection.configure(r,this.bridge);if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(r);if(t==="agents/dispatch")return this.bridge.dispatch(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/prompt")return this.bridge.prompt(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/policy")return this.bridge.updatePolicy(r);if(t==="sessions/cancel")return this.bridge.cancel(r);if(t==="permissions/respond")return this.bridge.respondPermission(r);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,r){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:r})}send(t,r=this.ws){return!r||r!==this.ws||r.readyState!==lt?!1:(r.send(JSON.stringify(t)),!0)}};import{existsSync as zn,readFileSync as Ha}from"node:fs";import{dirname as Fa,resolve as re}from"node:path";import{fileURLToPath as $a}from"node:url";var Ba=/^[A-Za-z_][A-Za-z0-9_]*$/;function Vn(e=process.env,t=process.cwd()){let r=a(e.ORCHA_RUNTIME_ENV_FILE),n=r?re(t,r):re(t,".env");if(!zn(n))return r&&g("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Ha(n,"utf8");for(let o of i.split(/\r?\n/)){let c=Ga(o);if(!c)continue;let[u,d]=c;Object.prototype.hasOwnProperty.call(e,u)||(e[u]=d,s.push(u))}return g("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function Wn(e=process.env){let t=a(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),r=a(e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1"),n=!1,s=Fa($a(import.meta.url)),i=re(s,"sandbox","broker.js"),o=re(s,"orcha-runtime-sandbox-broker.js"),c=zn(i)?i:o,u=a(e.ORCHA_RUNTIME_SANDBOX_BROKER_COMMAND);return{mode:t,host:r,port:_(e.ORCHA_RUNTIME_BRIDGE_PORT,5588),token:e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",orchaUrl:a(e.ORCHA_RUNTIME_ORCHA_URL),nodeToken:e.ORCHA_RUNTIME_NODE_TOKEN||e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",nodeId:a(e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"local-runtime-node"),nodeName:a(e.ORCHA_RUNTIME_NODE_NAME||e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"Local Runtime Node"),reconnectMs:_(e.ORCHA_RUNTIME_RECONNECT_MS,3e3),connectTimeoutMs:_(e.ORCHA_RUNTIME_CONNECT_TIMEOUT_MS||e.ORCHA_RUNTIME_WS_CONNECT_TIMEOUT_MS,1e4),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:_(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),initializeTimeoutMs:_(e.ORCHA_RUNTIME_INITIALIZE_TIMEOUT_MS,3e4),sessionPromptTimeoutMs:_(e.ORCHA_RUNTIME_SESSION_PROMPT_TIMEOUT_MS,36e5),permissionRequestTimeoutMs:_(e.ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS,3e5),sessionIdleTtlMs:_(e.ORCHA_RUNTIME_SESSION_IDLE_TTL_MS,6e5),sessionCleanupIntervalMs:_(e.ORCHA_RUNTIME_SESSION_CLEANUP_INTERVAL_MS,6e4),maxSessionsPerTarget:_(e.ORCHA_RUNTIME_MAX_SESSIONS_PER_TARGET,8),openClawSessionIdleTtlMs:_(e.ORCHA_RUNTIME_OPENCLAW_SESSION_IDLE_TTL_MS,6e4),openClawMaxSessions:_(e.ORCHA_RUNTIME_OPENCLAW_MAX_SESSIONS,1),heartbeatIntervalMs:_(e.ORCHA_RUNTIME_HEARTBEAT_INTERVAL_MS,15e3),sandboxRequired:n,sandboxBrokerCommand:u||process.execPath,sandboxBrokerArguments:ur(e.ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS,"ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS",u?[]:[c]),sandboxProbeTimeoutMs:_(e.ORCHA_RUNTIME_SANDBOX_PROBE_TIMEOUT_MS,1e4),sandboxTempRoot:a(e.ORCHA_RUNTIME_SANDBOX_TEMP_ROOT),trustedWorkspaceRoots:ur(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:ur(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:qa(e.ORCHA_RUNTIME_EGRESS_PROXY_REQUIRED,t==="node"),egressProxySocket:a(e.ORCHA_RUNTIME_EGRESS_PROXY_SOCKET),egressProxyToken:a(e.ORCHA_RUNTIME_EGRESS_PROXY_TOKEN),egressGrantMaxTtlMs:_(e.ORCHA_RUNTIME_EGRESS_GRANT_MAX_TTL_MS,9e5),targets:ja(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function ja(e){if(!a(e))return{};try{let t=JSON.parse(e);if(l(t))return t}catch(t){g("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function qa(e,t){let r=a(e).toLowerCase();if(!r)return t;if(["true","1","yes","on"].includes(r))return!0;if(["false","0","no","off"].includes(r))return!1;throw new Error(`invalid boolean configuration value: ${r}`)}function ur(e,t,r=[]){let n=a(e);if(!n)return[...r];let s;try{s=JSON.parse(n)}catch{throw new Error(`${t} must be a JSON string array`)}if(!Array.isArray(s)||s.some(i=>typeof i!="string"))throw new Error(`${t} must be a JSON string array`);return s.map(i=>i.trim()).filter(Boolean)}function Ga(e){let t=e.trim();if(!t||t.startsWith("#"))return null;let r=t.startsWith("export ")?t.slice(7).trimStart():t,n=r.indexOf("=");if(n<=0)return null;let s=r.slice(0,n).trim();if(!Ba.test(s))return null;let i=Ka(r.slice(n+1).trim());return[s,i]}function Ka(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?za(r):r}return Va(e).trim()}function za(e){return e.replaceAll("\\n",`
|
|
22
|
+
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function Va(e){let t=!1,r=!1;for(let n=0;n<e.length;n+=1){let s=e[n],i=e[n-1];if(s==="'"&&!r)t=!t;else if(s==='"'&&!t&&i!=="\\")r=!r;else if(s==="#"&&!t&&!r&&/\s/.test(i||""))return e.slice(0,n)}return e}import{createServer as Wa}from"node:http";function ne(e,t,r){let n=JSON.stringify(r);e.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(n)}),e.end(n)}function tt(e={}){return{ok:!0,...e}}function lr(e,t,r){return{ok:!1,error:{code:e,message:t,...r===void 0?{}:{detail:r}}}}async function Jn(e,t){let r=[],n=0;for await(let i of e){if(n+=i.length,n>t)throw Object.assign(new Error("request body too large"),{status:413,code:"REQUEST_TOO_LARGE"});r.push(i)}if(r.length===0)return{};let s=Buffer.concat(r).toString("utf8");if(!s.trim())return{};try{let i=JSON.parse(s);if(!l(i))throw Object.assign(new Error("JSON body must be an object"),{status:400,code:"BAD_JSON"});return i}catch(i){throw i.status?i:Object.assign(new Error(`invalid JSON body: ${i.message}`),{status:400,code:"BAD_JSON"})}}function Xn(e,t){if(!t)return;if((e.headers.authorization||"")!==`Bearer ${t}`)throw Object.assign(new Error("runtime bridge token is invalid"),{status:401,code:"UNAUTHORIZED"})}function Yn(e,t){let r={"GET /health":async()=>tt(t.health()),"POST /agents/create":async n=>tt(await t.createAgent(n)),"POST /agents/dispatch":async n=>tt(await t.dispatch(n)),"POST /sessions/prompt":async n=>tt(await t.prompt(n)),"POST /sessions/cancel":async n=>tt(await t.cancel(n)),"POST /permissions/respond":async n=>tt(await t.respondPermission(n))};return Wa(async(n,s)=>{let i=new URL(n.url||"/",`http://${n.headers.host||`${e.host}:${e.port}`}`),o=`${n.method||"GET"} ${i.pathname}`,c=r[o];if(!c){ne(s,404,lr("NOT_FOUND",`No route for ${o}`));return}try{Xn(n,e.token);let u=n.method==="GET"?{}:await Jn(n,e.requestLimitBytes);ne(s,200,await c(u))}catch(u){let d=u.status||500,f=u.code||"BRIDGE_INTERNAL";ne(s,d,lr(f,u.message||String(u),u.detail))}})}var is=tc(import.meta.url),ec=".orcha-runtime-bridge.pid",rc=".orcha-runtime-bridge.log",nc=3,sc=36e5,{command:ic,options:os}=cc(process.argv.slice(2));uc(os);Vn();var oc=Wn();await as(ic,oc,os);async function as(e,t,r){if(r.url){let s=fe(r.url);r.pidFile||(process.env.ORCHA_RUNTIME_PID_FILE=s.pidFile),r.logFile||(process.env.ORCHA_RUNTIME_LOG_FILE=s.logFile)}let n=()=>["connect","--url",t.orchaUrl,"--foreground"];switch(e){case"connect":if(r.pairCode&&et(ie(se())))throw new Error("\u8BBE\u5907\u8FDE\u63A5\u4ECD\u5728\u540E\u53F0\u8FD0\u884C\uFF0C\u8BF7\u5148\u6267\u884C stop --url \u540E\u91CD\u65B0\u914D\u5BF9");await At(t,r),r.foreground?await dr(t):fr(n());return;case"run":case"foreground":r.url&&await At(t,r),await dr(t);return;case"start":if(r.url)return as("connect",t,r);if(r.foreground){await dr(t);return}fr();return;case"reload":case"restart":{r.url&&await At(t,{url:r.url});let s=dt(ss(is),".."),i=dt(s,...gr(dt(s,"src","index.js"))?["dist","package"]:[],"openclaw-plugin"),o=await Dr(t.targets,i);await ts({quiet:!0}),await o(),fr(r.url?n():void 0);return}case"stop":await ts();return;case"status":ac();return;case"help":case"--help":case"-h":pc();return;default:throw new Error(`Unknown command: ${e}`)}}async function dr(e){lc();let t=new Zt(e);if(await t.start(),e.mode==="server"){let n=Yn(e,t);Zn({bridge:t,server:n}),n.listen(e.port,e.host,()=>{g("info","runtime-bridge","Orcha runtime bridge HTTP server started",{host:e.host,port:e.port,targets:Object.keys(t.targets)})});return}if(!e.orchaUrl)throw new Error("ORCHA_RUNTIME_ORCHA_URL is required in runtime node mode");let r=new ee(e,t);Zn({bridge:t,client:r}),r.start(),g("info","runtime-bridge","Orcha runtime node started",{nodeId:e.nodeId,nodeName:e.nodeName,orchaUrl:e.orchaUrl,targets:Object.keys(t.targets)})}function Zn({bridge:e,client:t,server:r}){let n=!1,s=i=>{if(n)return;n=!0;let o=Number(e?.sessions?.size||0)>0;g("info","runtime-bridge","runtime bridge shutting down",{signal:i});try{t?.stop?.()}catch(c){g("warn","runtime-bridge","runtime client stop failed",{error:String(c)})}Promise.resolve(e?.stop?.(`process_${String(i||"shutdown").toLowerCase()}`)).catch(c=>{g("warn","runtime-bridge","runtime bridge stop failed",{error:String(c)})}).finally(()=>{try{r?.close?.()}catch(c){g("warn","runtime-bridge","runtime server close failed",{error:String(c)})}}),setTimeout(()=>process.exit(0),o?8500:200)};process.once("SIGTERM",()=>s("SIGTERM")),process.once("SIGINT",()=>s("SIGINT"))}function fr(e=["run"]){let t=se(),r=cs(),n=ie(t);if(n&&et(n)){console.log(JSON.stringify({status:"already_running",pid:n,pidFile:t,logFile:r}));return}n&&mr(t),rs(t),rs(r),hr(r);let s=Qa(r,"a"),i={...process.env,ORCHA_RUNTIME_PID_FILE:t,ORCHA_RUNTIME_LOG_FILE:r},o=Ja(process.execPath,[is,...e,"--pid-file",t,"--log-file",r],{cwd:process.cwd(),detached:!0,env:i,stdio:["ignore",s,s]});o.unref(),Xa(s),ns(t,`${o.pid}
|
|
23
|
+
`),console.log(JSON.stringify({status:"started",pid:o.pid,pidFile:t,logFile:r}))}async function ts({quiet:e=!1}={}){let t=se(),r=ie(t);if(!r){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!et(r)){mr(t),e||console.log(JSON.stringify({status:"not_running",pid:r,pidFile:t}));return}process.kill(r,"SIGTERM"),!await es(r,1e4)&&et(r)&&(process.kill(r,"SIGKILL"),await es(r,3e3)),mr(t),e||console.log(JSON.stringify({status:"stopped",pid:r,pidFile:t}))}function ac(){let e=se(),t=cs(),r=ie(e),n=!!(r&&et(r));console.log(JSON.stringify({status:n?"running":"not_running",running:n,pid:n?r:null,pidFile:e,logFile:t}))}function cc(e){let t=[],r={};for(let s=0;s<e.length;s+=1){let i=e[s];i==="--url"?r.url=e[++s]:i==="--pair-code"?r.pairCode=e[++s]:i==="--daemon"?r.daemon=!0:i==="--foreground"?r.foreground=!0:i==="--env-file"?r.envFile=e[++s]:i==="--pid-file"?r.pidFile=e[++s]:i==="--log-file"?r.logFile=e[++s]:t.push(i)}return{command:t[0]||"run",options:r}}function uc(e){e.envFile&&(process.env.ORCHA_RUNTIME_ENV_FILE=e.envFile),e.pidFile&&(process.env.ORCHA_RUNTIME_PID_FILE=e.pidFile),e.logFile&&(process.env.ORCHA_RUNTIME_LOG_FILE=e.logFile)}function se(){return dt(process.cwd(),process.env.ORCHA_RUNTIME_PID_FILE||ec)}function cs(){return dt(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||rc)}function lc(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=us();if(t<=0)return;let r=dt(process.cwd(),e);hr(r,t);let n=fc();n<=0||setInterval(()=>hr(r,t),n).unref()}function hr(e,t=us()){if(t<=0||!gr(e))return;let r=0,n="";try{if(r=Qn(e).size,r<=0)return;n=pr(e,"utf8")}catch(d){g("warn","runtime-bridge","runtime log cleanup skipped",{logFile:e,error:String(d)});return}let s=Date.now()-t*24*60*60*1e3,i=n.split(/\r?\n/),o=[],c=0;for(let d of i)d&&(dc(d,s)?o.push(d):c+=1);if(c===0)return;let u="";try{Qn(e).size>r&&(u=pr(e,"utf8").slice(n.length));let f=[...o,...u.split(/\r?\n/).filter(Boolean)].join(`
|
|
24
|
+
`);ns(e,f?`${f}
|
|
25
|
+
`:""),g("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:c})}catch(d){g("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function dc(e,t){try{let r=JSON.parse(e);if(!r||typeof r!="object")return!0;let n=typeof r.ts=="string"?Date.parse(r.ts):Number.NaN;return!Number.isFinite(n)||n>=t}catch{return!0}}function us(){return ls(process.env.ORCHA_RUNTIME_LOG_RETENTION_DAYS,nc)}function fc(){return ls(process.env.ORCHA_RUNTIME_LOG_CLEANUP_INTERVAL_MS,sc)}function ls(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function ie(e){if(!gr(e))return null;let t=Number.parseInt(pr(e,"utf8").trim(),10);return Number.isInteger(t)&&t>0?t:null}function et(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function es(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!et(e))return!0;await new Promise(n=>setTimeout(n,100))}return!et(e)}function rs(e){Ya(ss(e),{recursive:!0})}function mr(e){try{Za(e,{force:!0})}catch{}}function pc(){console.log(`Usage: orcha-runtime-bridge [command] [options]
|
|
23
26
|
|
|
24
27
|
Commands:
|
|
25
28
|
connect Pair or reconnect this device, then run in the background.
|
|
26
29
|
run, foreground Run in the foreground. This is the default.
|
|
27
30
|
start Start in the background and write a pid file.
|
|
28
|
-
reload, restart
|
|
31
|
+
reload, restart Update connected OpenClaw plugins/restart Gateway, then restart Bridge.
|
|
29
32
|
stop Stop the background process.
|
|
30
33
|
status Print background process status as JSON.
|
|
31
34
|
|