@orcha-ai/runtime-bridge 0.1.39 → 0.1.41
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
CHANGED
|
@@ -76,17 +76,21 @@ 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.41 fixes native Channel reply classification against the OpenClaw 2026.7.1 SDK and propagates delivery failures through the HTTP request instead of throwing from the host queue's error observer. It retains the native Channel adapter, active messages/files and authorized background runs from 0.1.40. Bridge and the bundled plugin share the release version; `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.41.tgz --access public --registry=https://registry.npmjs.org
|
|
84
84
|
```
|
|
85
85
|
|
|
86
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.
|
|
87
87
|
|
|
88
|
+
For native OpenClaw Channel use, also update the bundled OpenClaw plugin using the host's supported plugin update/reload procedure; updating Bridge alone does not update an installed Gateway plugin. 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. Existing ACP/CLI targets without a native binding continue using their configured execution path. Native Channel progress is currently final-result-only; real OpenClaw host/model acceptance remains required before production use.
|
|
89
|
+
|
|
88
90
|
Tests cover discovery errors, paths, public-field filtering, immutable commands, exact OpenClaw IDs, atomic configuration, capacity, reconnect, MCP lifecycle and cancellation. The live Codex model test is opt-in; fixtures do not certify a real vendor account or OpenClaw Gateway version.
|
|
89
91
|
|
|
92
|
+
To check reply classification against the real SDK without installing or starting a Gateway, extract the official `openclaw@2026.7.1` npm tarball and run `npm run test:openclaw-sdk -- /absolute/path/to/extracted/package`. This check imports the actual SDK functions, covering final text/media, reasoning, commentary, status/progress notices and TTS supplements; it does not replace a live host/model acceptance test.
|
|
93
|
+
|
|
90
94
|
## Delegated group member tools
|
|
91
95
|
|
|
92
96
|
Codex supports task-scoped Orcha MCP through the existing local transport adapter. OpenClaw additionally requires the bundled Gateway plugin, a trusted binding endpoint and Gateway authentication. Discovery/import does not install the plugin or configure these credentials. Claude Code's delegated dynamic MCP adapter remains unsupported and returns an explicit error.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawn as
|
|
3
|
-
`):""}var
|
|
2
|
+
import{spawn as Ua}from"node:child_process";import{closeSync as Pa,existsSync as zn,mkdirSync as ka,openSync as La,readFileSync as or,rmSync as va,statSync as Bn,writeFileSync as Vn}from"node:fs";import{dirname as Da,resolve as ur}from"node:path";import{fileURLToPath as Ha}from"node:url";import{createHash as Tr}from"node:crypto";import{mkdir as cs,readFile as us,writeFile as ls,rename as ds}from"node:fs/promises";import{join as _r}from"node:path";import{homedir as fs,hostname as ps}from"node:os";import{execFile as es}from"node:child_process";import{access as rs,realpath as ns}from"node:fs/promises";import{constants as ss}from"node:fs";import{delimiter as is,join as hr,isAbsolute as mr}from"node:path";import{homedir as pr}from"node:os";async function os(e,t=process.env){let r=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let n of(t.PATH||"").split(is).filter(mr))for(let s of r){let i=hr(n,`${e}${s}`);try{return await rs(i,ss.X_OK),i}catch{}}return null}function as(e,t){return new Promise(r=>es(e,t,{timeout:8e3,maxBuffer:1024*1024,windowsHide:!0},(n,s)=>r({code:n?n.code:0,stdout:String(s||"")})))}async function ie(e){let t=e==="~"?pr():e.startsWith("~/")?hr(pr(),e.slice(2)):e;if(!mr(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 ns(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 gr({find:e=os,run:t=as,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"]),g;try{g=JSON.parse(h.stdout)}catch{}if(h.code!==0||!Array.isArray(g))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 g.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 yr(e,t){let r=`${e}.${process.pid}.tmp`;await ls(r,JSON.stringify(t),{mode:384}),await ds(r,e)}function ae(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=_r(fs(),".orcha","devices"),n=_r(r,Tr("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 Et(e,{url:t,pairCode:r}){let{address:n,root:s,profile:i}=ae(t||e.orchaUrl);await cs(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:ps()})}),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 yr(i,o)}else try{o=JSON.parse(await us(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 oe(e,o,async()=>yr(i,o))}var oe=class{constructor(t,r,n,s=gr){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 ie(String(u.workspace||""));if(d.managed&&p!==await ie(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}:${Tr("sha256").update(d.id).digest("hex").slice(0,20)}`;if([...r.sessions.values()].some(g=>g.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 Ao,randomUUID as Vt}from"node:crypto";var tt="0.1.41";function ft(){return new Date().toISOString()}function U(e,t=2){return String(e).padStart(t,"0")}function wr(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${U(Math.floor(r/60))}:${U(r%60)}`}function hs(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)}`,wr(t)].join("")}function ms(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 gs(e,t){let r=ms(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)}`,wr(s)].join("")}function _s(e=new Date){let t=a(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return gs(e,t)}catch{return hs(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 b(e){return Array.isArray(e)?e.map(String):[]}function et(e,t,r=process.cwd()){let n=l(e)?e:{};return a(n.cwd)||a(n.workspace)||a(t)||a(r)||process.cwd()}var Ot="[redacted]",ys=/(authorization|api[_-]?key|credential|password|secret|token)/i;function It(e){return ys.test(a(e))}function Rr(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(Ot))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${Ot}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${Ot}`)}function V(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]=V(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=>V(i,t));return t.delete(e),s}let r={},n=It(e.name||e.key);for(let[s,i]of Object.entries(e))r[s]=It(s)||n&&s.toLowerCase()==="value"?Ot:V(i,t);return t.delete(e),r}function Sr(e,t=4e3){let r=JSON.stringify(V(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function m(e,t,r,n={}){let s={ts:_s(),level:e,module:t,msg:r,...l(n)?V(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
|
+
`):""}var Ct=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=xt(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 Ts}from"node:child_process";var pt="2.0",ce=3e4,ws=4e3;function bt(e,t){let r=Object.entries(l(t)?t:{}).filter(([n])=>It(n)).map(([,n])=>n);return Rr(e,r)}function Rs(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 Ss(e){if(!l(e))return new Error(String(e||"runtime error"));let t=a(e.message)||"runtime error",r="data"in e?Sr(e.data,4e3):"",n=new Error(r?`${t}; data=${r}`:t);return n.rpcCode=e.code,n.data=e.data,n}function Es(e){return l(e)&&"id"in e&&!("method"in e)}function Os(e){return l(e)&&typeof e.method=="string"&&"id"in e}function Is(e){return l(e)&&typeof e.method=="string"&&!("id"in e)}var At=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=ce}={}){if(!(this.child&&!this.exited)&&(this.exited=!1,this.exitCode=null,this.exitSignal=null,this.stderrTail="",this.spawnError=null,this.child=Ts(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(-ws);let i=bt(s.trimEnd(),this.env);i&&m("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,ce));try{await this.call("initialize",{protocolVersion:1,clientCapabilities:{},...r},s)}catch(i){let o=this.startupFailureDetail(),c=bt(i?.message||i,this.env);m("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:bt(this.spawnError.message,this.env)}:{},...this.stderrTail.trim()?{stderr:bt(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
4
|
\r
|
|
5
|
-
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){m("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
|
|
5
|
+
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){m("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){m("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(n)});return}this.dispatch(r)}dispatch(t){if(Es(t)){this.resolveResponse(t);return}if(Os(t)){this.handleRequest(t);return}Is(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?(m("warn","runtime.protocol","runtime rpc error",{target:this.label,method:n.method,requestId:r,error:t.error}),n.reject(Ss(t.error))):n.resolve(t.result))}async handleRequest(t){let r=this.requestHandlers.get(t.method);if(!r){this.writeFrame({jsonrpc:pt,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:pt,id:t.id,result:n??{}})}catch(n){this.writeFrame({jsonrpc:pt,id:t.id,error:Rs(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=ce){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:pt,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:pt,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
6
|
\r
|
|
7
7
|
${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"&&m("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;m("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&&(m("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 Or}from"node:crypto";import{existsSync as Is,readFileSync as xs,realpathSync as Rr,statSync as Cs}from"node:fs";import{basename as Ir,extname as xr,isAbsolute as pt,join as bs,relative as Cr,resolve as Sr}from"node:path";var As=25*1024*1024;function br(e,t=""){let r=a(t);if(r)return r;let n=xr(a(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function Ar(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 At(e){if(Array.isArray(e))return e.map(a).filter(Boolean);let t=a(e);return t?[t]:[]}function Ns(e,t){let r=Cr(t,e);return r===""||!!r&&!r.startsWith("..")&&!pt(r)}function Ms(e,t){let r=a(e);if(!r||!Is(r))return"";try{let n=Rr(r);for(let s of t)try{let i=Rr(s);if(Ns(n,i))return n}catch{}}catch{return""}return""}function Us(e,t){let r=a(e);if(!r||!pt(r))return r;for(let n of Array.isArray(t)?t:[]){if(!u(n))continue;let s=a(n.runtimeRoot),i=a(n.hostRoot);if(!s||!i||!pt(s)||!pt(i))continue;let o=Cr(Sr(s),Sr(r));if(o===""||!o.startsWith("..")&&!pt(o))return o?bs(i,o):i}return r}function ae(e,t,r={}){let n=a(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:Ps(n,t,r)}function Ps(e,t,r={}){let n=[...At(r.trustedFileRoots),...At(r.trustedFileRoot),...At(r.artifactRoots),...At(r.artifactRoot)],s=Ms(Us(e,r.pathMappings),n);if(!s)return"";try{let i=Cs(s);return!i.isFile()||i.size<=0||i.size>As?"":`data:${t};base64,${xs(s).toString("base64")}`}catch{return""}}function C(...e){for(let t of e){let r=a(t);if(r)return r}return""}function ks(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=C(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=xr(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function ue(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!u(e))return null;let n=u(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=C(n.call_id,n.id),c=C(n.saved_path,n.savedPath),l=C(n.revised_prompt,n.revisedPrompt),d=br(c,n.mimeType||n.mime_type),f=Ar(n.result,d)||ae(c,d,t);if(!f)return null;let p=f.startsWith("data:")?f:"",h=c?Ir(c):`${o||Or()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:h||"Generated image",summary:l||"Generated image",content:{prompt:l||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:l||void 0}}}function Ls(e){let t=u(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];u(s)&&r.push(s)}return r}function Ds(e,t={}){let{source:r="runtime_artifact"}=t,n=u(e)?e:{};if(!Object.keys(n).length)return null;let s=u(n.content)?{...n.content}:{},i=u(n.metadata)?{...n.metadata}:{},o=C(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),c=C(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),l=C(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),d=ks(n,s,l,o),f=d?br(o,c):c;if(d){let A=C(n.dataUrl,s.dataUrl),T=A.startsWith("data:")?A:"",w=C(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),S=Ar(n.result??s.result,f)||T||ae(o,f,t)||ae(w,f,t);S&&(S.startsWith("data:")&&(s.dataUrl||=S),s.imageUrl||=S,s.previewUrl||=S,s.fileUrl||=S,f&&(s.mimeType||=f))}for(let[A,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[A];w!=null&&w!==""&&!(T in s)&&(s[T]=w)}let p=C(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=C(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),g=C(n.dataUrl,s.dataUrl,p.startsWith("data:")?p:"",h.startsWith("data:")?h:""),y=C(n.filename,i.filename,o?Ir(o):""),R=C(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:l,type:n.type||l,fieldKey:R,title:C(n.title,y,"Runtime artifact"),summary:C(n.summary,s.prompt,n.title,y,"Runtime artifact"),content:s,dataUrl:g||void 0,fileUrl:p||void 0,previewUrl:h||void 0,metadata:{...i,source:C(i.source,r),savedPath:o||i.savedPath,filename:y||i.filename,mimeType:f||i.mimeType}}}function Nt(e,t){if(!t||!e)return;let r=u(t.metadata)?t.metadata:{},n=C(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||Or(),s=e.get(n);if(!s){e.set(n,t);return}s.content={...u(s.content)?s.content:{},...u(t.content)?t.content:{}},s.metadata={...u(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 ce(e,t,r={}){for(let n of Ls(e))Nt(t,Ds(n,r))}function le(e){if(!u(e)||!u(e.payload))return u(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 Er(e,t,r){if(!u(e))return e;let n=u(e.event)?e.event:null;return n?(Nt(t,ue(n,r)),{...e,event:le(n)}):e}function Nr(e,t,r={}){if(!u(e))return e;ce(e,t,r);let n=Er(e,t,r),s=u(n.update)?Er(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function Mr(e,t,r={}){let n=u(e)?{...e}:{};ce(n,t,r),ce(u(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function Ur(e,t){let r=_(e,t);return r>0?r:t}var rt=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:b(this.target.args),cwd:et(this.target,this.agent.workspace),environment:u(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 bt({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:Ur(this.target.initializeTimeoutMs,Ur(this.options.initializeTimeoutMs,3e4)),initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:tt},...u(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",l=>{let d=a(l.sessionId);(!d||d===n)&&r(Nr(l,s,i))}),c=async l=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:l,emitUpdate:r})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,c),this.permissionHandlers.set("*",c);try{let l=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return Mr(l,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=u(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),...b(this.target.trustedArtifactRoots),...b(this.target.trustedFileRoots),...b(this.target.artifactRoots),...b(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 vs}from"node:http";import{randomBytes as Hs}from"node:crypto";var Pr=["find_capabilities","describe_capability","execute_capability","inspect_result"],$s=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 Lr(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>$s)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function Dr(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 Lr(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function kr(e,t){let r=await Dr(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},t),n=r?.result?.tools;if(r?.error||!Array.isArray(n)||n.length!==Pr.length||Pr.some(s=>!n.some(i=>i.name===s&&i.inputSchema?.type==="object")))throw new Error("Orcha MCP did not expose its four authorized control tools");return n}async function vr(e){let t=Mt(e),r=new AbortController;await kr(t,r.signal);let n=Hs(32).toString("hex"),s=vs(async(i,o)=>{if(i.url!=="/mcp"||i.headers.authorization!==`Bearer ${n}`){o.writeHead(403).end();return}if(i.method!=="POST"){o.writeHead(405).end();return}try{let c=await Lr(i);if(!c||c.jsonrpc!=="2.0"||typeof c.method!="string")throw new Error("Invalid MCP request");let l=await Dr(t,c,r.signal);o.writeHead(l===null?202:200,{"content-type":"application/json"}),o.end(l===null?"":JSON.stringify(l))}catch{o.writeHead(502,{"content-type":"application/json"}).end(JSON.stringify({error:"The task-scoped Orcha MCP connection failed"}))}});return await new Promise((i,o)=>{s.once("error",o),s.listen(0,"127.0.0.1",i)}),{url:`http://127.0.0.1:${s.address().port}/mcp`,token:n,async refresh(i){let o=Mt(i,t.url);await kr(o,r.signal),t=o},async close(){r.abort(),s.closeAllConnections(),await new Promise(i=>s.close(i))}}}var Ut=class{constructor(t,r){this.target=t,this.identity=r,this.bound=!1}async request(t,r,n=!1){let s=a(this.target.mcpBridgeUrl),i=a(this.target.mcpBridgeTokenEnv),o=this.target.env?.[i]||process.env[i];if(!s||!i||!o)throw Object.assign(new Error("OpenClaw requires the Orcha tool plugin, mcpBridgeUrl and mcpBridgeTokenEnv"),{code:"OPENCLAW_MCP_NOT_CONFIGURED"});let c=new URL(s);if(!["http:","https:"].includes(c.protocol)||c.username||c.password||c.pathname!=="/plugins/orcha-runtime/mcp-bindings"||c.search||c.hash)throw new Error("OpenClaw MCP binding URL must be the trusted Gateway plugin route");let l=await fetch(c,{method:t,redirect:"error",signal:AbortSignal.timeout(3e4),headers:{authorization:`Bearer ${o}`,"content-type":"application/json",...n?{"if-match":this.identity.runId}:{}},body:JSON.stringify(r)});if(!l.ok)throw Object.assign(new Error(`OpenClaw Orcha tool binding failed (${l.status})`),{code:"OPENCLAW_MCP_BINDING_FAILED"})}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)}};function de(e){let t=u(e.metadata)?e.metadata:{};return a(t.agentCode)}function Hr(e,t,r){let n=a(r?.openclawAgentId)||de(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var Pt=class extends rt{constructor(t,r,n,s={},i={}){let o=a(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",c=a(r.command)||"openclaw",l=Array.isArray(r.args)?r.args.map(String):[],d=l.length>0?l:["acp","--session",Hr(t,o,r)];super(t,{...r,command:c,args:d},s,i),this.boundSessionKey=Hr(t,o,r),this.binding=null}async sessionNew(t={}){if(t.mcpServers?.length&&t.metadata?.source==="conversation_delegation"){let r=[...this.target.args],n=r.indexOf("--session"),s=r.find(l=>l.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||!de(this.agent))throw new Error("OpenClaw MCP requires a trusted task and Agent identity");this.binding=new Ut(this.target,{runId:o,sessionKey:this.boundSessionKey,agentCode:a(this.target.openclawAgentId)||de(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 zr}from"node:child_process";import{randomUUID as nt}from"node:crypto";import{existsSync as Vr,mkdirSync as Fs,readdirSync as Jr,readFileSync as Wr,realpathSync as mt,rmSync as Bs,rmdirSync as qs,statSync as js,unlinkSync as Ks}from"node:fs";import{homedir as Gs,tmpdir as Xr}from"node:os";import{basename as ge,dirname as zs,join as $,resolve as Fr}from"node:path";async function $r(e){let t=await vr(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 Vs=36e5,Yr=5e3,Js=2*60*1e3,Ws=2*60*1e3,Xs=12,Ys=1e3,Zs=1500,Qs=1e3,kt=24*60*60*1e3,ht=new Set(["final_answer","final","complete","completed","done"]),ti=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"]),ei=new Set(["context_compacted","context_compaction","context_compressed"]);function Dt(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{zr("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 fe(e){Dt(e,"SIGTERM");let t=setTimeout(()=>Dt(e,"SIGKILL"),Yr);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(!u(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let r=D(e[t]);if(r)return r}return""}function Zr(e){if(!u(e))return"";let t=u(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=u(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 Qr(e,t={}){return ue(e,{source:"codex_cli_image_generation",...t})}function tn(e,t){Nt(e.artifacts,t)}function en(e){return V(le(e))}function _e(e){if(!u(e))return!1;let t=u(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 ht.has(s);let i=u(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 Br(e){let t=a(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=ge(a(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function qr(e,t,r){let n=u(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 ri(e,t){if(!u(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:qr("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:qr("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...a(e.result)?{output:a(e.result)}:{}}}}return null}function jr(e){return u(e)?a(e.phase||e.status||e.stage).toLowerCase():""}function ni(e){if(!u(e)||_e(e))return!1;let t=u(e.payload)?e.payload:{},r=a(e.type),n=a(t.type),s=jr(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return!!(s&&!ht.has(s));let i=u(e.item)?e.item:{},o=jr(i);return a(i.role)==="assistant"||a(i.type)==="message"?!!(o&&!ht.has(o)):!1}function si(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:ge(e)==="codex"}function ii(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:ge(e)==="codex"}function rn(e){return Math.max(20,_(e.codexTranscriptPollMs||e.transcriptPollMs,Ys))}function oi(e){return Math.max(0,_(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,Zs))}function vt(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 ye(e){let t=u(e?.metadata)?e.metadata:{};return u(t._runtimeBridge)?t._runtimeBridge:{}}function pe(e){return a(ye(e).promptKind).toLowerCase()}function ai(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=vt(r);if(n!=null)return n}return pe(t)==="chat"}function ci(e,t){let r=ye(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=vt(s);if(i!=null)return i}let n=pe(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=vt(s);if(i!=null)return i}return pe(e)==="chat"}function ui(e){let t=ye(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=vt(r);if(n!=null)return n}return null}function li(e,t){let r=ui(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function di(e,t){return!e.finalTextOnly||t}function nn(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 sn(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 fi(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function pi(e,t){let r=u(e.env)?e.env:{},n=a(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||$(Xr(),"orcha-runtime-artifacts"),s=a(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||nt(),i=$(n,s),o=$(i,nt());return Fs(o,{recursive:!0}),{root:o,realRoot:mt(o),sessionRoot:i,realSessionRoot:mt(i)}}function hi(e){let t=a(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:mt(t),sessionRoot:"",realSessionRoot:""}}function on(e){return a(u(e)?e.root:e)}function Kr(e){let t=on(e),r=a(u(e)?e.sessionRoot:zs(t)),n=a(u(e)?e.realSessionRoot:"");if(r)try{if(n&&mt(r)!==n)return;qs(r)}catch{}}function mi(e,t={}){let r=on(e),n=a(u(e)?e.realRoot:"");if(r){try{if(n&&mt(r)!==n){m("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{Kr(e);return}try{Bs(r,{recursive:!0,force:!0})}catch(s){m("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:r,error:String(s?.message||s)});return}Kr(e)}}function gi(e,t,r=null){return{trustedFileRoots:[t,a(r?.artifactDirectory),a(r?.homeDirectory),...b(e.trustedArtifactRoots),...b(e.trustedFileRoots),...b(e.artifactRoots),...b(e.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(r?.pathMappings)?r.pathMappings:[]}}function an(e){let t=a(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let r=u(e.env)?e.env:{},n=a(e.codexHome||r.CODEX_HOME||process.env.CODEX_HOME)||$(Gs(),".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 cn(e,t,r){let n=new Set;for(let s of[t-kt,t,t+kt,r-kt,r,r+kt])n.add(_i(e,s));return[...n].filter(s=>Vr(s))}function yi(e,t,r){let n=an(e),s=t-Js,i=r+Ws,o=[];for(let c of cn(n,t,r)){let l=[];try{l=Jr(c)}catch{continue}for(let d of l){if(!d.endsWith(".jsonl"))continue;let f=$(c,d);try{let p=js(f);if(!p.isFile()||p.mtimeMs<s||p.mtimeMs>i)continue;o.push({path:f,mtimeMs:p.mtimeMs})}catch{}}}return o.sort((c,l)=>l.mtimeMs-c.mtimeMs).slice(0,Xs)}function Ti(e,t,r=t){let n=an(e),s=new Set;for(let i of cn(n,t,r)){let o=[];try{o=Jr(i)}catch{continue}for(let c of o)c.endsWith(".jsonl")&&s.add($(i,c))}return s}function he(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)he(n,t,r+1);return}if(u(e))for(let n of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])n in e&&he(e[n],t,r+1)}}function un(e){return a(e).replace(/\s+/g," ")}function wi(e){let t=un(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 Ri(e,t){let r=wi(t);if(!r.length)return!1;let n=[];for(let i of e)he(i,n);let s=un(n.join(" "));return r.every(i=>s.includes(i))}function Si(e){return e.find(t=>u(t)&&a(t.type)==="session_meta"&&u(t.payload))||null}function Ei(e){let t=u(e?.payload)?e.payload:{},r=a(e?.timestamp||t.timestamp),n=Date.parse(r);return Number.isFinite(n)?n:Number.NaN}function Oi(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 Ii(e,t,r){if(!Ri(e,t.promptText))return!1;let n=Si(e);if(!n)return!1;let s=n.payload;if(!Oi(s))return!1;let i=Ei(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&&Fr(o)!==Fr(c))}function Gr(e){try{return Ci(Wr(e,"utf8"))}catch{return null}}function xi(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=Gr(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of yi(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=Gr(s.path);!i||!Ii(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,m("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,m("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function Ci(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 bi(e){if(!u(e))return!1;let t=u(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 Ai(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{};return a(e.type)==="response_item"&&ti.has(a(t.type))}function Ni(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{};return ei.has(a(t.type))}function Mi(e,t,r,n){let s=Zr(e),i=_e(e),o=0,c=0,l=0;if(s&&!i&&t.emitThoughtChunks&&sn(t,r,n,s)&&(l=1),s&&i){let d=t.emittedTexts.size?`
|
|
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"&&m("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;m("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&&(m("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 xs,readFileSync as Cs,realpathSync as Er,statSync as bs}from"node:fs";import{basename as Cr,extname as br,isAbsolute as ht,join as As,relative as Ar,resolve as Or}from"node:path";var Ns=25*1024*1024;function Nr(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 Mr(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 Nt(e){if(Array.isArray(e))return e.map(a).filter(Boolean);let t=a(e);return t?[t]:[]}function Ms(e,t){let r=Ar(t,e);return r===""||!!r&&!r.startsWith("..")&&!ht(r)}function Us(e,t){let r=a(e);if(!r||!xs(r))return"";try{let n=Er(r);for(let s of t)try{let i=Er(s);if(Ms(n,i))return n}catch{}}catch{return""}return""}function Ps(e,t){let r=a(e);if(!r||!ht(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||!ht(s)||!ht(i))continue;let o=Ar(Or(s),Or(r));if(o===""||!o.startsWith("..")&&!ht(o))return o?As(i,o):i}return r}function ue(e,t,r={}){let n=a(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:ks(n,t,r)}function ks(e,t,r={}){let n=[...Nt(r.trustedFileRoots),...Nt(r.trustedFileRoot),...Nt(r.artifactRoots),...Nt(r.artifactRoot)],s=Us(Ps(e,r.pathMappings),n);if(!s)return"";try{let i=bs(s);return!i.isFile()||i.size<=0||i.size>Ns?"":`data:${t};base64,${Cs(s).toString("base64")}`}catch{return""}}function C(...e){for(let t of e){let r=a(t);if(r)return r}return""}function Ls(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=C(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 de(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=C(n.call_id,n.id),c=C(n.saved_path,n.savedPath),u=C(n.revised_prompt,n.revisedPrompt),d=Nr(c,n.mimeType||n.mime_type),f=Mr(n.result,d)||ue(c,d,t);if(!f)return null;let p=f.startsWith("data:")?f:"",h=c?Cr(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 vs(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 Ds(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=C(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),c=C(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),u=C(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),d=Ls(n,s,u,o),f=d?Nr(o,c):c;if(d){let A=C(n.dataUrl,s.dataUrl),T=A.startsWith("data:")?A:"",w=C(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),S=Mr(n.result??s.result,f)||T||ue(o,f,t)||ue(w,f,t);S&&(S.startsWith("data:")&&(s.dataUrl||=S),s.imageUrl||=S,s.previewUrl||=S,s.fileUrl||=S,f&&(s.mimeType||=f))}for(let[A,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[A];w!=null&&w!==""&&!(T in s)&&(s[T]=w)}let p=C(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=C(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),g=C(n.dataUrl,s.dataUrl,p.startsWith("data:")?p:"",h.startsWith("data:")?h:""),y=C(n.filename,i.filename,o?Cr(o):""),R=C(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:u,type:n.type||u,fieldKey:R,title:C(n.title,y,"Runtime artifact"),summary:C(n.summary,s.prompt,n.title,y,"Runtime artifact"),content:s,dataUrl:g||void 0,fileUrl:p||void 0,previewUrl:h||void 0,metadata:{...i,source:C(i.source,r),savedPath:o||i.savedPath,filename:y||i.filename,mimeType:f||i.mimeType}}}function Mt(e,t){if(!t||!e)return;let r=l(t.metadata)?t.metadata:{},n=C(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 le(e,t,r={}){for(let n of vs(e))Mt(t,Ds(n,r))}function fe(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 Ir(e,t,r){if(!l(e))return e;let n=l(e.event)?e.event:null;return n?(Mt(t,de(n,r)),{...e,event:fe(n)}):e}function Ur(e,t,r={}){if(!l(e))return e;le(e,t,r);let n=Ir(e,t,r),s=l(n.update)?Ir(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function Pr(e,t,r={}){let n=l(e)?{...e}:{};le(n,t,r),le(l(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function kr(e,t){let r=_(e,t);return r>0?r:t}var rt=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:b(this.target.args),cwd:et(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 At({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:kr(this.target.initializeTimeoutMs,kr(this.options.initializeTimeoutMs,3e4)),initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:tt},...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(Ur(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 Pr(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),...b(this.target.trustedArtifactRoots),...b(this.target.trustedFileRoots),...b(this.target.artifactRoots),...b(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 $s}from"node:http";import{randomBytes as Fs}from"node:crypto";var Ut={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs"]};var Bs=Object.freeze([...Ut.controlTools,...Ut.residentTools]),js=new Set(Bs),qs=8*1024*1024;function Pt(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 vr(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>qs)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function Dr(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 vr(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function Lr(e,t){let r=await Dr(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 Ks(n)}function Ks(e){if(!Array.isArray(e)||e.some(t=>!t||!js.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&Ut.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 Gs(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 Hr(e){let t=Pt(e),r=new AbortController,n=await Lr(t,r.signal),s=Fs(32).toString("hex"),i=$s(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 vr(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 Dr(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=Pt(o,t.url);if(!Gs(n,await Lr(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 nt=class{constructor(t,r){this.target=t,this.identity=r,this.bound=!1}async request(t,r,n=!1,s="mcp-bindings",i=3e4){let o=a(this.target.mcpBridgeUrl),c=a(this.target.mcpBridgeTokenEnv),u=this.target.env?.[c]||process.env[c];if(!o||!c||!u)throw Object.assign(new Error("OpenClaw requires the Orcha tool plugin, mcpBridgeUrl and mcpBridgeTokenEnv"),{code:"OPENCLAW_MCP_NOT_CONFIGURED"});let d=new URL(o);if(!["http:","https:"].includes(d.protocol)||d.username||d.password||d.pathname!=="/plugins/orcha-runtime/mcp-bindings"||d.search||d.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");d.pathname=`/plugins/orcha-runtime/${s}`;let f=await fetch(d,{method:t,redirect:"error",signal:AbortSignal.timeout(i),headers:{authorization:`Bearer ${u}`,"content-type":"application/json",...n?{"if-match":this.identity.runId}:{}},body:JSON.stringify(r)}),p=await f.json();if(!f.ok)throw Object.assign(new Error(`OpenClaw Orcha plugin failed (${p.error||f.status})`),{code:p.error||"OPENCLAW_MCP_BINDING_FAILED"});return p}async bind(t,r=!1){Pt(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 kt=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 nt(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}){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 r=await this.transport.request("POST",this.promptBody,!1,"deliveries",Number(this.options.sessionPromptTimeoutMs||36e5));return this.finished=!0,r}async stop(){!this.finished&&this.promptBody&&await this.transport.request("DELETE",{runId:this.options.runId},!1,"deliveries")}};function pe(e){let t=l(e.metadata)?e.metadata:{};return a(t.agentCode)}function $r(e,t,r){let n=a(r?.openclawAgentId)||pe(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var Lt=class extends rt{constructor(t,r,n,s={},i={}){if(i.source==="channel_message")return new kt(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",$r(t,o,r)];super(t,{...r,command:c,args:d},s,i),this.boundSessionKey=$r(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||!pe(this.agent))throw new Error("OpenClaw MCP requires a trusted task and Agent identity");this.binding=new nt(this.target,{runId:o,sessionKey:this.boundSessionKey,agentCode:a(this.target.openclawAgentId)||pe(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 Vr}from"node:child_process";import{randomUUID as st}from"node:crypto";import{existsSync as Jr,mkdirSync as zs,readdirSync as Wr,readFileSync as Xr,realpathSync as gt,rmSync as Vs,rmdirSync as Js,statSync as Ws,unlinkSync as Xs}from"node:fs";import{homedir as Ys,tmpdir as Yr}from"node:os";import{basename as ye,dirname as Zs,join as $,resolve as Br}from"node:path";async function Fr(e){let t=await Hr(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 Qs=36e5,Zr=5e3,ti=2*60*1e3,ei=2*60*1e3,ri=12,ni=1e3,si=1500,ii=1e3,vt=24*60*60*1e3,mt=new Set(["final_answer","final","complete","completed","done"]),oi=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"]),ai=new Set(["context_compacted","context_compaction","context_compressed"]);function Ht(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{Vr("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 he(e){Ht(e,"SIGTERM");let t=setTimeout(()=>Ht(e,"SIGKILL"),Zr);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 Qr(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 tn(e,t={}){return de(e,{source:"codex_cli_image_generation",...t})}function en(e,t){Mt(e.artifacts,t)}function rn(e){return V(fe(e))}function Te(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 mt.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 jr(e){let t=a(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=ye(a(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function qr(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 ci(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:qr("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:qr("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...a(e.result)?{output:a(e.result)}:{}}}}return null}function Kr(e){return l(e)?a(e.phase||e.status||e.stage).toLowerCase():""}function ui(e){if(!l(e)||Te(e))return!1;let t=l(e.payload)?e.payload:{},r=a(e.type),n=a(t.type),s=Kr(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return!!(s&&!mt.has(s));let i=l(e.item)?e.item:{},o=Kr(i);return a(i.role)==="assistant"||a(i.type)==="message"?!!(o&&!mt.has(o)):!1}function li(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:ye(e)==="codex"}function di(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:ye(e)==="codex"}function nn(e){return Math.max(20,_(e.codexTranscriptPollMs||e.transcriptPollMs,ni))}function fi(e){return Math.max(0,_(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,si))}function $t(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 we(e){let t=l(e?.metadata)?e.metadata:{};return l(t._runtimeBridge)?t._runtimeBridge:{}}function me(e){return a(we(e).promptKind).toLowerCase()}function pi(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=$t(r);if(n!=null)return n}return me(t)==="chat"}function hi(e,t){let r=we(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=$t(s);if(i!=null)return i}let n=me(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=$t(s);if(i!=null)return i}return me(e)==="chat"}function mi(e){let t=we(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=$t(r);if(n!=null)return n}return null}function gi(e,t){let r=mi(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function _i(e,t){return!e.finalTextOnly||t}function sn(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 on(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 yi(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function Ti(e,t){let r=l(e.env)?e.env:{},n=a(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||$(Yr(),"orcha-runtime-artifacts"),s=a(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||st(),i=$(n,s),o=$(i,st());return zs(o,{recursive:!0}),{root:o,realRoot:gt(o),sessionRoot:i,realSessionRoot:gt(i)}}function wi(e){let t=a(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:gt(t),sessionRoot:"",realSessionRoot:""}}function an(e){return a(l(e)?e.root:e)}function Gr(e){let t=an(e),r=a(l(e)?e.sessionRoot:Zs(t)),n=a(l(e)?e.realSessionRoot:"");if(r)try{if(n&>(r)!==n)return;Js(r)}catch{}}function Ri(e,t={}){let r=an(e),n=a(l(e)?e.realRoot:"");if(r){try{if(n&>(r)!==n){m("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{Gr(e);return}try{Vs(r,{recursive:!0,force:!0})}catch(s){m("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:r,error:String(s?.message||s)});return}Gr(e)}}function Si(e,t,r=null){return{trustedFileRoots:[t,a(r?.artifactDirectory),a(r?.homeDirectory),...b(e.trustedArtifactRoots),...b(e.trustedFileRoots),...b(e.artifactRoots),...b(e.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(r?.pathMappings)?r.pathMappings:[]}}function cn(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)||$(Ys(),".codex");return $(n,"sessions")}function Ei(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 un(e,t,r){let n=new Set;for(let s of[t-vt,t,t+vt,r-vt,r,r+vt])n.add(Ei(e,s));return[...n].filter(s=>Jr(s))}function Oi(e,t,r){let n=cn(e),s=t-ti,i=r+ei,o=[];for(let c of un(n,t,r)){let u=[];try{u=Wr(c)}catch{continue}for(let d of u){if(!d.endsWith(".jsonl"))continue;let f=$(c,d);try{let p=Ws(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,ri)}function Ii(e,t,r=t){let n=cn(e),s=new Set;for(let i of un(n,t,r)){let o=[];try{o=Wr(i)}catch{continue}for(let c of o)c.endsWith(".jsonl")&&s.add($(i,c))}return s}function ge(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)ge(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&&ge(e[n],t,r+1)}}function ln(e){return a(e).replace(/\s+/g," ")}function xi(e){let t=ln(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 Ci(e,t){let r=xi(t);if(!r.length)return!1;let n=[];for(let i of e)ge(i,n);let s=ln(n.join(" "));return r.every(i=>s.includes(i))}function bi(e){return e.find(t=>l(t)&&a(t.type)==="session_meta"&&l(t.payload))||null}function Ai(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 Ni(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 Mi(e,t,r){if(!Ci(e,t.promptText))return!1;let n=bi(e);if(!n)return!1;let s=n.payload;if(!Ni(s))return!1;let i=Ai(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&&Br(o)!==Br(c))}function zr(e){try{return Pi(Xr(e,"utf8"))}catch{return null}}function Ui(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=zr(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of Oi(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=zr(s.path);!i||!Mi(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,m("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,m("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function Pi(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 ki(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 Li(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return a(e.type)==="response_item"&&oi.has(a(t.type))}function vi(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return ai.has(a(t.type))}function Di(e,t,r,n){let s=Qr(e),i=Te(e),o=0,c=0,u=0;if(s&&!i&&t.emitThoughtChunks&&on(t,r,n,s)&&(u=1),s&&i){let d=t.emittedTexts.size?`
|
|
9
9
|
|
|
10
|
-
${s}`:s;
|
|
11
|
-
`,
|
|
12
|
-
`}}})}}}async sessionCancel(t){let r=a(t.sessionId),n=this.active.get(r);return n?(m("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),
|
|
13
|
-
`)}function hn(e,t,r=""){if(!mn(e))return e==null?null:{required:!0,status:"failed",outcome:a(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=Ue(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=zi(t),o=e.verificationPlan.checks.map(l=>Qi(l,i));return{required:!0,status:o.some(l=>l.status==="failed")?"failed":o.some(l=>l.status==="missing")?"missing":"passed",outcome:e.outcome,goalContractHash:n,checks:o}}function mn(e){if(!u(e)||e.schemaVersion!==qi||!a(e.outcome))return!1;let t=e.verificationPlan;if(!u(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(!u(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&&!u(n.arguments))return!1;return!0}function zi(e){let t=new Map,r=[];for(let n of Array.isArray(e)?e:[]){let s=u(n?.update)?n.update:{},i=a(s.sessionUpdate);if(i==="runtime_event"){Vi(s.event,t,r);continue}if(i==="tool_call"){let o=Ft(s)||`tool-${r.length+1}`,c=$t(t,r,o),l=Ne(s,s.name||s.toolName||s.kind);c.toolName=l.toolName,c.arguments=l.arguments,c.status=gt(s.status),c.evidence=qt(s);continue}if(i==="tool_call_update"){let o=Ft(s);if(!o)continue;let c=$t(t,r,o),l=Ne(s,s.name||s.toolName||s.kind);c.toolName||=l.toolName,Object.keys(c.arguments).length===0&&(c.arguments=l.arguments),c.status=gt(s.status),c.evidence.push(...qt(s))}}return r}function Vi(e,t,r){let n=u(e)&&u(e.payload)?e.payload:u(e)?e:{},s=a(n.type);if(["function_call","custom_tool_call","local_shell_call","mcp_tool_call"].includes(s)){let c=Ft(n)||`runtime-${r.length+1}`,l=$t(t,r,c),d=Ne(n,n.name||n.tool||s,s);l.toolName=d.toolName,l.arguments=d.arguments,l.status=gt(n.status),l.evidence.push(...qt(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=Ft(n);if(!i)return;let o=$t(t,r,i);o.status=Yi(n,o.toolName),o.evidence.push(...qt(n))}function $t(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 Ji(e){let t=a(e).toLowerCase();return Gi.get(t)||t}function Ne(e,t,r=""){let n=Wi(e),s=a(r)==="mcp_tool_call"||a(e?.kind).toLowerCase()==="mcp",i=u(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:Ji(t),arguments:n}}function Ft(e){return u(e)?a(e.call_id||e.callId||e.toolCallId||e.id):""}function Wi(e){if(!u(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=Xi(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 Xi(e){if(u(e))return structuredClone(e);if(typeof e!="string")return null;try{let t=JSON.parse(e);return u(t)?t:null}catch{return null}}function Yi(e,t){if(!u(e))return"unknown";let r=Bt(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function Bt(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return Zi(e,t,r);if(Array.isArray(e))return e.flatMap(o=>Bt(o,t+1,r));if(!u(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=gt(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(...Bt(e[o],t+1,r));return n}function Zi(e,t,r){let n=e.trim();if(!n)return[];try{return Bt(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 gt(e){let t=a(e).toLowerCase();return ji.has(t)?"success":Ki.has(t)?"failed":"unknown"}function qt(e){if(!u(e))return[];let t=u(e.output)?e.output:{},r=[e.verificationEvidence,u(e.verification)?e.verification.evidence:null,t.verificationEvidence,u(t.verification)?t.verification.evidence:null],n=[];for(let s of r)for(let i of Array.isArray(s)?s:s?[s]:[])!u(i)||!a(i.id)||n.push({id:a(i.id),status:gt(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...a(i.message)?{message:a(i.message)}:{}});return n}function Qi(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&Me(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 Ae(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?Ae(e,"failed",i,"Runtime tool evidence failed."):Ae(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function Ae(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,...u(e.arguments)?{arguments:e.arguments}:{},...a(e.evidenceId)?{evidenceId:a(e.evidenceId)}:{}}}function Me(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>Me(r,t[n])):u(e)?u(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&Me(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 fn(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(u(e))return`{${Object.keys(e).sort().map(t=>`${fn(t)}:${q(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function fn(e){return to(e),JSON.stringify(e)}function to(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 eo}from"node:child_process";import{createHash as ro,randomUUID as no}from"node:crypto";import{constants as so}from"node:fs";import{access as io,mkdir as Pe,readdir as oo,realpath as _t,rm as ao,stat as co}from"node:fs/promises";import uo from"node:http";import{tmpdir as lo}from"node:os";import{isAbsolute as yt,join as st,relative as gn,resolve as Le}from"node:path";var De=1,fo="orcha.process-isolation/v1",ve="orcha.egress-proxy/v1",po="--disable-wasm-trap-handler",jt={read_only:0,workspace_write:1,workspace_network:2},ke={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},ho=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function J(e){if(!u(e))throw E("RUNTIME_SANDBOX_POLICY_REQUIRED","sandboxPolicy is required");let t=structuredClone(e),r=a(t.accessMode),n=a(t.accessModeCeiling);if(!(r in ke)||!(n in ke))throw E("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if(jt[r]>jt[n])throw E("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=ke[r];if(t.filesystemMode!==s||t.networkMode!==i)throw E("RUNTIME_SANDBOX_POLICY_INVALID","runtime access profile does not match its mode");if(Number(t.policySchemaVersion)!==De||!Number.isInteger(Number(t.policyRevision))||Number(t.policyRevision)<1)throw E("RUNTIME_SANDBOX_POLICY_INVALID","unsupported sandbox policy schema or revision");for(let[c,l]of Object.entries({outsideWorkspaceAccess:"denied",hostAccess:"denied",hostEnvironmentAccess:"denied",dockerSocketAccess:"denied",environmentMode:"allowlist"}))if(t[c]!==l)throw E("RUNTIME_SANDBOX_POLICY_INVALID",`${c} cannot be relaxed`);let o=u(t.processIsolation)?t.processIsolation:{};if(o.mode!=="required"||o.backend==="direct")throw E("RUNTIME_SANDBOX_POLICY_INVALID","strong process isolation is required");if(Array.isArray(t.alwaysApprovedApprovalKeys)&&t.alwaysApprovedApprovalKeys.length)throw E("RUNTIME_SANDBOX_POLICY_INVALID","persistent runtime approvals are forbidden");return t}function _n(e,t){let r=J(e),n=J(t);return jt[n.accessMode]<jt[r.accessMode]}async function yn(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[De],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await wn(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await To(t,b(e.sandboxBrokerArguments),e.sandboxProbeTimeoutMs);if(r.enforced!==!0||a(r.protocolVersion)!=="orcha.runtime-sandbox-broker/v1"||!["bubblewrap","broker"].includes(a(r.backend)))throw E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker did not report enforced isolation");let n=u(r.probes)?r.probes:{};for(let s of["emptyRoot","outsideWorkspaceDenied","hostFilesystemDenied","sensitiveFilesDenied","environmentAllowlist","dockerSocketDenied","networkNamespace","workspaceReadOnly","workspaceWrite","resourceLimits"])if(n[s]!==!0)throw E("RUNTIME_SANDBOX_UNAVAILABLE",`sandbox broker probe failed: ${s}`);return e.egressProxyRequired&&await So(e),{dispatchable:!0,enforced:!0,backend:a(r.backend),daemonStatus:"ok",daemonProtocolVersion:a(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[De],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function He(e,t,r){let n=a(t.workspace||t.cwd),s=a(r),i=n||(t.allowRequestWorkspace===!0?s:"");if(!i||!yt(i))throw E("RUNTIME_WORKSPACE_NOT_CONFIGURED","runtime target must configure an absolute trusted workspace");let o=await _t(i);if(!(await co(o)).isDirectory())throw E("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>_t(d))):[o]).some(d=>Fe(d,o)))throw E("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function Tn({config:e,target:t,command:r,args:n,cwd:s,environment:i,runId:o,agentId:c,sessionId:l,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 He(e,t,s),h=await _t(s);if(!Fe(p,h))throw E("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let g=await wn(e.sandboxBrokerCommand,process.env.PATH||"");if(!g)throw E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let y=`runtime-${ro("sha256").update(String(o)).digest("hex").slice(0,32)}`,R=Le(e.sandboxTempRoot||st(lo(),"orcha-runtime-sandboxes"));await Pe(R,{recursive:!0,mode:448});let A=st(R,`${y}-${no()}`),T=st(A,"home"),w=st(A,"artifacts");await Pe(T,{recursive:!0,mode:448}),await Pe(w,{recursive:!0,mode:448});let S=f.networkMode==="restricted"?await wo(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(l),ORCHA_RUN_ID:String(o),ORCHA_RUNTIME_ARTIFACT_DIR:"/tmp/artifacts",...go(t,i)};I.HOME="/tmp/home",I.TMPDIR="/tmp",I.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",I.NODE_OPTIONS=po;let P={schemaVersion:fo,runId:String(o),instanceId:y,workspace:p,cwd:h,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await _o(p),temporaryDirectory:A,egressProxy:S,environment:I,resourceLimits:yo(f),readOnlyToolchainRoots:await mo(e,t)},v=!1,N=async()=>{if(!v){v=!0;try{S&&await Ro(e,S,{runId:String(o),instanceId:y})}finally{await ao(A,{recursive:!0,force:!0})}}};return{command:g,args:[...b(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:A,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:N}}async function mo(e,t){let r=b(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(b(e.trustedToolchainRoots).map(i=>_t(i)));if(!n.length)throw E("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","target toolchain roots require ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS");let s=[];for(let i of r){if(!yt(i))throw E("RUNTIME_TOOLCHAIN_ROOT_INVALID","toolchain roots must be absolute");let o=await _t(i);if(!n.some(c=>Fe(c,o)))throw E("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function go(e,t){let r=u(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 oo(s,{withFileTypes:!0})}catch(o){if(s===e)throw o;return}for(let o of i){if(r+=1,r>1e4)throw E("RUNTIME_WORKSPACE_SCAN_LIMIT_EXCEEDED","workspace contains more than 10000 entries");let c=st(s,o.name),l=gn(e,c),d=o.name.toLowerCase();(ho.has(d)||d.startsWith(".env."))&&t.push(l),o.isDirectory()&&!o.isSymbolicLink()&&await n(c)}};return await n(e),t.sort()}function yo(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 To(e,t,r){return await new Promise((n,s)=>{let i=eo(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 l=setTimeout(()=>i.kill("SIGKILL"),Math.max(1e3,r));i.once("error",s),i.once("close",d=>{if(clearTimeout(l),d!==0){s(E("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(E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox probe returned invalid JSON"))}})})}async function wn(e,t){let r=a(e);if(!r)return"";let n=yt(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>st(s,r));for(let s of n)try{return await io(s,so.X_OK),s}catch{}return""}async function wo(e,t){if(!e.egressProxyRequired)throw E("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await $e(e,"POST","/v1/grants",{protocolVersion:ve,...t}),n={socketPath:e.egressProxySocket,grantId:a(r.grantId),credential:a(r.credential)};if(!n.grantId||!n.credential)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy returned an invalid grant");return n}async function Ro(e,t,r){await $e(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:ve,...r}).catch(()=>{})}async function So(e){let t=await $e(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==ve)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function $e(e,t,r,n){if(!yt(e.egressProxySocket)||!e.egressProxyToken)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy socket and token are required");return await new Promise((s,i)=>{let o=uo.request({socketPath:e.egressProxySocket,path:r,method:t,headers:{Authorization:`Bearer ${e.egressProxyToken}`,Accept:"application/json",...n?{"Content-Type":"application/json"}:{}}},c=>{let l=[],d=0;c.on("data",f=>{d+=f.length,d>1048576?o.destroy(new Error("egress response is too large")):l.push(Buffer.from(f))}),c.once("end",()=>{try{let f=JSON.parse(Buffer.concat(l).toString("utf8")||"{}");(c.statusCode||500)>=400?i(E("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 Fe(e,t){let r=gn(Le(e),Le(t));return r===""||!r.startsWith("..")&&!yt(r)}function E(e,t){return Object.assign(new Error(t),{code:e})}var Be=24e3,qe=8,je=50,Ke=6e3,Oo=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),Io=10*60*1e3,xo=60*1e3,Co=8,bo=30*60*1e3,Ao=60*1e3,No=1,On=2400,Mo=new Set(["max_tokens","max_output_tokens","length"]),Uo=new Set(["agent_message_chunk","tool_call","tool_call_update"]),Po=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 Lo(e){if(!u(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 Do(e){return(Array.isArray(e)?e:[]).map(Lo).sort((t,r)=>{let n=q(t),s=q(r);return n<s?-1:n>s?1:0})}function vo(e){return!u(e)||e.verificationPlan?.required!==!0?!1:(Array.isArray(e.verificationPlan.checks)?e.verificationPlan.checks:[]).some(r=>u(r)&&Array.isArray(r.toolNames)&&r.toolNames.some(n=>a(n)==="plugin_operation"))}function Ho(e,t,r){let n=u(e?._meta)?e._meta:{};return{...u(e)?e:{},sessionId:t,update:u(e?.update)?e.update:{},_meta:{...n,orchaAgentId:r.agentId,runtimeSessionId:r.runtimeSessionId,bridgeUpdateId:Gt()}}}function L(e){return e==null||e===""?!1:typeof e=="string"?a(e)!=="":Array.isArray(e)?e.length>0:u(e)?Object.keys(e).length>0:!0}function In(e){let t=a(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return Oo.has(t)}function G(e,t){let r=_(e,t);return Number.isFinite(r)&&r>0?r:t}function Tt(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 xn(e){let t=K(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function Ve(e){if(u(e)){if(Object.prototype.hasOwnProperty.call(e,"releaseAfterPrompt"))return e.releaseAfterPrompt;if(Object.prototype.hasOwnProperty.call(e,"disposeAfterPrompt"))return e.disposeAfterPrompt}}function $o(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 Je(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=Ke)return e;let r=e.length-Ke;return`${e.slice(0,Ke)}... [truncated ${r} characters]`}if(t>=qe)return Array.isArray(e)?`[array truncated at depth ${qe}, items=${e.length}]`:u(e)?`[object truncated at depth ${qe}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,je).map(n=>Je(n,t+1));return e.length>je&&r.push(`[truncated ${e.length-je} items]`),r}if(u(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=$o(n)?"[REDACTED]":Je(s,t+1);return r}return String(e)}var Fo=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 Bo(e){if(!u(e))return e;let t={};for(let r of Fo)L(e[r])&&(t[r]=e[r]);return t}function qo(e){if(!u(e))return e;let t={...e};return u(t.renderedPayload)&&(t.renderedPayload=Bo(t.renderedPayload)),t}function jo(e){let t=u(e)?e:{},r={};L(t.metadata)&&(r.metadata=qo(t.metadata));for(let[n,s]of Object.entries(t))Po.has(n)||n==="metadata"||L(s)&&(r[n]=s);return r}function Ko(e){let t=u(e)?e:{},r=u(t.metadata)?t.metadata:{},n=u(r.renderedPayload)?r.renderedPayload:{};return u(t.resultContract)?t.resultContract:u(n.resultContract)?n.resultContract:{}}function Cn(e){return a(Ko(e).kind).toLowerCase()==="decision"}function Go(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:K(e)==="cli"}function Rn(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return Tt(t,xn(e))}function zo(e,t){let r=u(e?.metadata)?{...e.metadata}:{},n=u(r._runtimeBridge)?{...r._runtimeBridge}:{},s=Ve(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:Go(t),releaseAfterPrompt:s===void 0?Rn(t):Tt(s,Rn(t)),requiresRuntimeResult:Cn(e)},r}function Vo(e){let t=jo(e);if(!L(t))return"";let r=JSON.stringify(Je(t),null,2);if(r.length<=Be)return r;let n=r.length-Be;return`${r.slice(0,Be)}
|
|
14
|
-
... [truncated ${n} characters]`}function
|
|
15
|
-
`:"";t+=`${s}${n}`}}return t.trim()}function
|
|
16
|
-
`?1:0)).trim()}function
|
|
17
|
-
`)}function ia(e,t){let r=u(t)?{...t}:{},n=Nn(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function oa(e,t){return{...e,_meta:{...u(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:Ze(t)||"max_tokens"}}}}function aa(e,t){let r=typeof e?.output=="string"?e.output:Ye(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:Ze(e)||"max_tokens",retryAttempted:!0},n}var Vt=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=dt(),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 yn(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"},m("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=u(t.goalContract)?Ue(t.goalContract):a(t.goalContractHash),i=Eo("sha256").update(q({prompt:Array.isArray(t.prompt)?t.prompt:[],mcpServers:Do(t.mcpServers),metadata:u(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:u(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=u(t.metadata)?t.metadata:{},l=u(c._runtimeBridge)?c._runtimeBridge:{},d=Mn(i,o,l),f=hn(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=G(this.config.operationTtlMs,bo);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||!u(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"?G(this.config.openClawSessionIdleTtlMs,Ao):G(this.config.sessionIdleTtlMs,Io);return G(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=K(t)==="openclaw"?G(this.config.openClawMaxSessions,No):G(this.config.maxSessionsPerTarget,Co);return G(t?.maxSessions,n)}targetReservationCount(t){return Number(this.targetReservations.get(t)||0)}notifyCapacityChanged(){try{this.onCapacityChanged?.()}catch(t){m("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),l=this.targetMaxSessions(n),d=t?Math.max(0,l-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:l,busySessions:i,idleSessions:o,reservedSessions:c,availableSessions:d}})}targetReleaseAfterPrompt(t,r={}){let n=K(t),s=u(r?._runtimeBridge)?r._runtimeBridge:{},i=Ve(s);return i!==void 0?Tt(i,!1):Tt(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=u(r?._runtimeBridge)?r._runtimeBridge:{},s=Ve(n);return s!==void 0?Tt(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=G(this.config.sessionCleanupIntervalMs,xo);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(r=>{m("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){m("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(),m("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 He(this.config,s,t.workspace):a(t.workspace),c={agentId:r,targetCode:n,framework:a(t.framework||n),workspace:o,metadata:u(t.metadata)?t.metadata:{},createdAt:dt(),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:l=>n.source==="conversation_delegation"?{outcome:"denied",reason:"External group member permission continuation is not supported"}:this.requestPermission(l)},c={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs,initializeTimeoutMs:this.config.initializeTimeoutMs,sandboxRequired:this.config.sandboxRequired,runId:n.runId,sandboxPolicy:n.sandboxPolicy,...this.config.sandboxRequired?{prepareLaunch:l=>Tn({config:this.config,target:s,...l,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new rt(t,s,o,c):i==="openclaw"?new Pt(t,s,r,o,c):i==="cli"?new Ht(t,s,c):new xt(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)||Gt(),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"&&t.metadata?.source==="conversation_delegation"){c.mcpServers=t.mcpServers;let l=this.sessions.get(`${n}:${s}`);if(l){if(!l.runtime.refreshMcpServers)throw Object.assign(new Error("This runtime cannot refresh task MCP credentials"),{code:"unsupported_dynamic_mcp"});await l.runtime.refreshMcpServers(t.mcpServers)}}return this.attachOperation(c,r)}if(t.attachOnly===!0)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(l){let d=o.status==="completed";this.failOperation(o,l),d&&m("warn","runtime-bridge","runtime cleanup failed after operation completion",{correlationId:o.correlationId,error:String(l)})}})(),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,l=this.agents.get(s),d=this.targetFor(t.targetCode||t.framework||l?.targetCode);if(l&&l.targetCode!==d.code)throw Object.assign(new Error(`runtime agent target conflict: ${s}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});if(K(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=l||(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),g=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,S;try{await this.reserveTargetSlot(T,w),g=T;let I=this.runtimeFor(f,i,{runId:o,sandboxPolicy:c,source:t.metadata?.source});S=I;let P=n?.mcpServers||t.mcpServers||[],v=await I.sessionNew({cwd:et(w,f.workspace),mcpServers:P,metadata:u(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 N=Date.now();h={agentId:s,sessionId:i,runtime:I,targetCode:T,runtimeKind:K(w),runId:o,sandboxPolicy:c?structuredClone(c):null,runtimeSessionId:a(u(v)?v.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(w),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(w,t.metadata),createdAtMs:N,lastUsedAtMs:N,busy:!1,createdAt:dt()},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===S?await this.closeSession(p,"session_start_failed"):await S?.stop("session_start_failed"),g&&(this.releaseTargetSlot(g),g=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,g&&this.releaseTargetSlot(g),this.notifyCapacityChanged(),h.operationCorrelationId=n?.correlationId||null,h.lastUsedAtMs=Date.now();let y=n?.updates||[],R=T=>{let w=Ho(T,i,h);if(y.push(w),n)for(let S of n.listeners)try{S?.(w)}catch(I){m("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(I)})}else r.onUpdate?.(w)},A=T=>{if(!(!n||n.status!=="running"||!u(T))){if(T.status==="failed"){let w=T.error;if(w instanceof Error){this.failOperation(n,w);return}let S=u(w)?w:{},I=Object.assign(new Error(a(S.message||T.message)||"runtime terminal failure"),{code:a(S.code||T.code)||"RUNTIME_TERMINAL_FAILED"});this.failOperation(n,I);return}this.completeOperation(n,this.promptResponse(t,h,i,y,u(T.result)?T.result:{stopReason:"end_turn"}))}};try{let T=pn(t.goalContract),w=Array.isArray(t.prompt)?[...t.prompt]:[];T&&w.unshift({type:"text",text:T,metadata:{source:"orcha_goal_contract"}});let S=u(t.metadata)?t.metadata:{},I=u(S._runtimeBridge)?S._runtimeBridge:{},P=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:w,metadata:S},R,A),v=y,N=null;if(xn({type:h.runtimeKind})&&na(P,y,I)){N=P;let Z=y.length,at=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:[{type:"text",text:sa()}],metadata:S,_meta:{thinking:"off"}},R,A);P=ia(N,at),v=y.slice(Z)}let O;try{O=this.promptResponse(t,h,i,y,P,v)}catch(Z){throw N&&Un(P)?aa(P,v):Z}return N&&(O.result=oa(O.result,N)),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,u(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 l=`${r}:${s}`,d=this.sessions.get(l);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 g=_n(f,o);c&&(c.sandboxPolicy=structuredClone(o)),d&&(d.sandboxPolicy=structuredClone(o));let y=!1;return g&&d?.busy===!0&&(await d.runtime.sessionCancel({sessionId:d.runtimeSessionId}),y=await this.closeSession(l,"sandbox_policy_downgrade")),{updated:!0,policyRevision:h,accessMode:o.accessMode,activeCommandCancelled:y,deferredToNextLaunch:!g&&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 l=this.sessions.get(`${r}:${n}`);return!l||l.busy!==!0||l.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 l.runtime.sessionCancel({sessionId:l.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),l=Vo(t),d=Cn(t),{target:f}=this.targetFor(t.targetCode||t.framework),p=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",c?`instructions: ${c}`:"",l?"orchaContext:":"",l,l?"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 ${Ee} and ${Oe}.`:"",d?`Then put a JSON object containing _decision between ${Ie} and ${xe}.`:"",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 ${On} 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:zo(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=Gt(),c=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||Gt(),l={permissionId:i,agentId:t.agentId,sessionId:c,runtimeSessionId:r,request:u(n)?n:{},status:"pending",createdAt:dt()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:l}}),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:l})})}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:u(t.response)?t.response:{},userId:a(t.userId),metadata:u(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:tt,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 ca from"node:http";import ua from"node:https";import{randomBytes as Pn}from"node:crypto";var ot=1,W=3,la=1e4,Jt=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=da(r.connectTimeoutMs,la),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:ca,n=Pn(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===W){o.destroy();return}this.socket=o,this.readyState=ot,o.on("data",l=>this.onData(l)),o.on("close",()=>this.onClose()),o.on("error",l=>{this.readyState!==W&&this.emit("error",{error:l,message:l.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!==W&&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===ot||this.readyState===W)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!==ot||this.socket.write(Qe(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==W){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===ot&&this.socket.write(Qe(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==W&&(this.clearConnectTimer(),this.readyState=W,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 l=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(l,l+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(Qe(10,d))}}};function da(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function Qe(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=Pn(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 fa(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 pa(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 ha=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),Wt=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[...ha,...this.config.deviceConnection?["devices/discover","devices/configure"]:[]]}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):pa(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=fa(this.config.orchaUrl),r=new Jt(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=>{m("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:tt,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||(m("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){m("warn","orcha-client","invalid Orcha websocket frame",{error:String(s)});return}if(u(n)){if(n.type==="runtime_node.authenticated"){if(r&&this.ws!==r)return;this.connected=!0,this.startHeartbeat(r),m("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=u(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!==ot?!1:(r.send(JSON.stringify(t)),!0)}};import{existsSync as kn,readFileSync as ma}from"node:fs";import{dirname as ga,resolve as Xt}from"node:path";import{fileURLToPath as _a}from"node:url";var ya=/^[A-Za-z_][A-Za-z0-9_]*$/;function Ln(e=process.env,t=process.cwd()){let r=a(e.ORCHA_RUNTIME_ENV_FILE),n=r?Xt(t,r):Xt(t,".env");if(!kn(n))return r&&m("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=ma(n,"utf8");for(let o of i.split(/\r?\n/)){let c=Ra(o);if(!c)continue;let[l,d]=c;Object.prototype.hasOwnProperty.call(e,l)||(e[l]=d,s.push(l))}return m("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function Dn(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=ga(_a(import.meta.url)),i=Xt(s,"sandbox","broker.js"),o=Xt(s,"orcha-runtime-sandbox-broker.js"),c=kn(i)?i:o,l=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:l||process.execPath,sandboxBrokerArguments:tr(e.ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS,"ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS",l?[]:[c]),sandboxProbeTimeoutMs:_(e.ORCHA_RUNTIME_SANDBOX_PROBE_TIMEOUT_MS,1e4),sandboxTempRoot:a(e.ORCHA_RUNTIME_SANDBOX_TEMP_ROOT),trustedWorkspaceRoots:tr(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:tr(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:wa(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:Ta(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Ta(e){if(!a(e))return{};try{let t=JSON.parse(e);if(u(t))return t}catch(t){m("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function wa(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 tr(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 Ra(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(!ya.test(s))return null;let i=Sa(r.slice(n+1).trim());return[s,i]}function Sa(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?Ea(r):r}return Oa(e).trim()}function Ea(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 qn({quiet:e=!1}={}){let t=
|
|
21
|
-
`);
|
|
22
|
-
`:""),m("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:c})}catch(d){m("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function
|
|
10
|
+
${s}`:s;sn(t,r,n,d,s)&&(o=1,c=1)}return s&&i&&(t.finalTextSeen=!0),en(t,tn(e,t.artifactOptions)),(ki(e)||Li(e)||vi(e)||i)&&n({sessionId:r,update:{sessionUpdate:"runtime_event",event:rn(e)}}),{textCount:o,finalTextCount:c,thoughtCount:u}}function _e(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=Ui(t,r,s);if(f){let p=Math.min(t.processedLines.get(f.path)||0,f.events.length),h=e.artifacts.size;for(let g of f.events.slice(p)){let y=Di(g,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 Hi(e,{remove:t=!0}={}){if(!e||!Jr(e))return"";try{return Xr(e,"utf8").trim()}catch{return""}finally{t&&Dt(e)}}function Dt(e){if(e)try{Xs(e)}catch{}}function $i(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 Fi(e){return new Promise(t=>setTimeout(t,e))}function Bi(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 ji(e,t,r,n,s,i){let o=_e(e,t,r,n,Date.now()),c=()=>Bi(e,r,n,Hi(s,{remove:!1}));if(c()||e.finalTextSeen)return Dt(s),o;let u=fi(i);if(u<=0||!t&&!s)return Dt(s),o;let d=Date.now()+u,f=Math.min(nn(i),100);for(;!e.finalTextSeen&&Date.now()<d&&(await Fi(Math.min(f,Math.max(0,d-Date.now()))),o=$i(o,_e(e,t,r,n,Date.now())),!c()););return Dt(s),o}var Ft=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"&&jr(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 Fr(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}-${st()}`}}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)||st(),c=xt(t.prompt),u=a(this.target.promptMode||"stdin"),d=[...this.taskMcp?.args||[],...this.buildArgs(u,c)],f=et(this.target,this.agent.workspace),p=typeof this.options.prepareLaunch=="function",g=li(i,d,this.target)?p?`/tmp/orcha-runtime-last-message-${st()}.txt`:$(Yr(),`orcha-runtime-last-message-${st()}.txt`):"";g&&d.push("--output-last-message",g);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()=>{}},A=p?wi(R):Ti(this.target,o),T=A.root,w=Si(this.target,T,R),S=di(i,this.target),I={...this.target,targetCode:this.agent.targetCode,cwd:f,...p?{codexHome:$(R.homeDirectory,".codex")}:{}},P=S?Ii(I,s):new Set,D=p&&g?$(R.tempDirectory,g.slice(5)):g,N=_(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,_(this.options.sessionPromptTimeoutMs,Qs));p||(R.environment.ORCHA_RUNTIME_ARTIFACT_DIR=T);let O=Vr(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),m("info","runtime.cli","runtime prompt started",{target:this.agent.targetCode,sessionId:o,pid:O.pid,timeoutMs:N,isolation:R.isolation});let Z="",ct=a(this.target.outputMode||"text"),M={artifacts:new Map,emittedTexts:new Set,emittedThoughtTexts:new Set,value:"",artifactOptions:w,finalTextSeen:!1,finalTextOnly:gi(t,this.target),emitThoughtChunks:hi(t,this.target),terminalOutcome:null,terminalProtocol:jr(this.target),emitTerminal:null},re=S?yi(I,c,s,P):null;return O.stdout.setEncoding("utf8"),O.stdout.on("data",Q=>this.handleStdout(Q,ct,M,o,r)),O.stderr.setEncoding("utf8"),O.stderr.on("data",Q=>{Z+=Q,this.target.emitStderr===!0&&r({sessionId:o,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:Q}}})}),u==="stdin"?O.stdin.end(c):O.stdin.end(),await new Promise((Q,ne)=>{let ut=!1,lr=!1,St=null,lt=null,se=re&&pi(this.target,t)?setInterval(()=>{try{_e(M,re,o,r)}catch(x){m("warn","runtime.cli","codex transcript stream poll failed",{target:this.agent.targetCode,sessionId:o,error:String(x?.message||x)})}},nn(this.target)):null;se?.unref?.();let dr=setTimeout(()=>{lr=!0,m("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:o,pid:O.pid,timeoutMs:N}),Ht(O,"SIGTERM"),St=setTimeout(()=>{m("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:o,pid:O.pid}),Ht(O,"SIGKILL")},Zr),St.unref?.(),dt(Object.assign(new Error(`runtime CLI timed out after ${N}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},N);dr.unref?.();let fr=async()=>{clearTimeout(dr),lt&&clearTimeout(lt),se&&clearInterval(se),St&&!lr&&clearTimeout(St),Ri(A,{target:this.agent.targetCode,sessionId:o}),this.active.delete(o),M.emitTerminal=null,await R.cleanup?.()},Qn=x=>{ut||(ut=!0,fr().then(()=>Q(x),ne))},dt=x=>{ut||(ut=!0,fr().then(()=>ne(x),F=>{m("warn","runtime.cli","sandbox launch cleanup failed",{target:this.agent.targetCode,sessionId:o,error:String(F?.message||F)}),ne(x)}))};M.emitTerminal=x=>{let F={...l(x.result)?x.result:{},_artifacts:[...M.artifacts.values()]};try{n?.({...x,result:F})}catch(z){m("warn","runtime.cli","runtime terminal listener failed",{target:this.agent.targetCode,sessionId:o,error:String(z?.message||z)})}let H=Math.max(0,_(this.target.terminalExitGraceMs,ii));lt=setTimeout(()=>{lt=null,!(ut||this.active.get(o)!==O)&&(m("warn","runtime.cli","runtime stayed alive after terminal event; terminating child",{target:this.agent.targetCode,sessionId:o,pid:O.pid,terminalProtocol:M.terminalProtocol,graceMs:H}),he(O))},H),lt.unref?.()},O.on("error",x=>{m("warn","runtime.cli","runtime child error",{target:this.agent.targetCode,sessionId:o,pid:O.pid,error:String(x?.message||x)}),dt(x)}),O.on("exit",(x,F)=>{(async()=>{ct==="json-lines"&&M.value.trim()&&this.handleStdout(`
|
|
11
|
+
`,ct,M,o,r);let H=await ji(M,re,o,r,D,this.target);(H.artifactCount>0||H.textCount>0||H.thoughtCount>0)&&m("info","runtime.cli","codex transcript updates collected",{target:this.agent.targetCode,sessionId:o,artifactCount:H.artifactCount,textCount:H.textCount,finalTextCount:H.finalTextCount,thoughtCount:H.thoughtCount,transcriptCount:H.transcriptCount});let z=Z.trim();if(z&&m("debug","runtime.cli","runtime stderr",{target:this.agent.targetCode,sessionId:o,stderr:z}),m("info","runtime.cli","runtime prompt finished",{target:this.agent.targetCode,sessionId:o,pid:O.pid,exitCode:x,signal:F,artifactCount:M.artifacts.size,finalTextSeen:M.finalTextSeen}),M.terminalOutcome?.status==="failed"){dt(M.terminalOutcome.error);return}if(x!==0&&M.terminalOutcome?.status!=="completed"){let ts=Object.assign(new Error(`runtime CLI exited with code ${x??"unknown"}${F?` (${F})`:""}`),{code:"RUNTIME_CLI_EXIT_NONZERO",exitCode:x,signal:F});dt(ts);return}Qn({stopReason:"end_turn",exitCode:x,signal:F,_artifacts:[...M.artifacts.values()],...z?{stderr:z}:{}})})().catch(dt)})})}buildArgs(t,r){let n=b(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);en(n,tn(d,n.artifactOptions)),i({sessionId:s,update:{sessionUpdate:"runtime_event",event:rn(d)}});let f=Qr(d),p=Te(d);f&&n.emitThoughtChunks&&!p&&ui(d)?on(n,s,i,f):f&&_i(n,p)&&sn(n,s,i,f),f&&p&&(n.finalTextSeen=!0);let h=ci(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}
|
|
12
|
+
`}}})}}}async sessionCancel(t){let r=a(t.sessionId),n=this.active.get(r);return n?(m("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),he(n),{ok:!0,cancelled:!0}):{ok:!0,cancelled:!1}}async stop(t="stop"){for(let[r,n]of this.active.entries())m("info","runtime.cli","stopping runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid,reason:t}),he(n);this.active.clear(),await this.taskMcp?.close(),this.taskMcp=null}};var Re="ORCHA_RUNTIME_OUTPUT_START",Se="ORCHA_RUNTIME_OUTPUT_END",Ee="ORCHA_RUNTIME_CONTROL_START",Oe="ORCHA_RUNTIME_CONTROL_END",Ie=Re,xe=Se,Ce=Ee,be=Oe,Ae=[Re,Se,Ee,Oe],qi=new Set(["_artifacts","_decision","_meta"]),Ki=new RegExp(`(?:^|(?<=[\\r\\n]))[ \\t]*(?<marker>${Ae.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 fn(e){let t=typeof e=="string"?e.trimStart():"";return Ae.some(r=>t.startsWith(r))}function Ne(e){if(typeof e!="string")return null;let t=e,r=Gi(t);if(![...r.values()].some(g=>g.length>0))return null;let n=[],s=[];for(let[g,y]of r)y.length===0?n.push(g):y.length>1&&s.push(g);if(n.length>0||s.length>0){let g=[];throw n.length>0&&g.push(`\u7F3A\u5C11 ${n.join(", ")}`),s.length>0&&g.push(`\u91CD\u590D ${s.join(", ")}`),new k("invalid_markers",`Runtime Result \u534F\u8BAE\u6807\u8BB0\u4E0D\u5B8C\u6574\uFF1A${g.join("\uFF1B")}`,t)}let i=r.get(Re)[0],o=r.get(Se)[0],c=r.get(Ee)[0],u=r.get(Oe)[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=zi(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(g){throw new k("invalid_control_json",`Runtime Result CONTROL \u5757\u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${String(g?.message||g)}`,t)}if(!dn(p))throw new k("invalid_control_type","Runtime Result CONTROL \u5757\u5FC5\u987B\u662F JSON \u5BF9\u8C61",t);let h=Object.keys(p).filter(g=>!qi.has(g)).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 g of["_decision","_meta"])if(g in p&&!dn(p[g]))throw new k("invalid_control_field_type",`Runtime Result CONTROL \u5757\u7684 ${g} \u5FC5\u987B\u662F JSON \u5BF9\u8C61`,t);return{output:d,...p}}function Gi(e){let t=new Map(Ae.map(r=>[r,[]]));for(let r of e.matchAll(Ki))t.get(r.groups.marker).push({start:r.index,end:r.index+r[0].length});return t}function zi(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 dn(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}import{createHash as Vi}from"node:crypto";var Ji="orcha.goal-contract/v1",Wi=new Set(["complete","completed","done","ok","passed","success","succeeded"]),Xi=new Set(["aborted","blocked","cancelled","canceled","denied","error","failed","failure","timeout","timed_out"]),Yi=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 ke(e){return Vi("sha256").update(j(e)).digest("hex")}function hn(e){if(!gn(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(`
|
|
13
|
+
`)}function mn(e,t,r=""){if(!gn(e))return e==null?null:{required:!0,status:"failed",outcome:a(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=ke(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=Zi(t),o=e.verificationPlan.checks.map(u=>io(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 gn(e){if(!l(e)||e.schemaVersion!==Ji||!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 Zi(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"){Qi(s.event,t,r);continue}if(i==="tool_call"){let o=jt(s)||`tool-${r.length+1}`,c=Bt(t,r,o),u=Ue(s,s.name||s.toolName||s.kind);c.toolName=u.toolName,c.arguments=u.arguments,c.status=_t(s.status),c.evidence=Kt(s);continue}if(i==="tool_call_update"){let o=jt(s);if(!o)continue;let c=Bt(t,r,o),u=Ue(s,s.name||s.toolName||s.kind);c.toolName||=u.toolName,Object.keys(c.arguments).length===0&&(c.arguments=u.arguments),c.status=_t(s.status),c.evidence.push(...Kt(s))}}return r}function Qi(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=jt(n)||`runtime-${r.length+1}`,u=Bt(t,r,c),d=Ue(n,n.name||n.tool||s,s);u.toolName=d.toolName,u.arguments=d.arguments,u.status=_t(n.status),u.evidence.push(...Kt(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=jt(n);if(!i)return;let o=Bt(t,r,i);o.status=no(n,o.toolName),o.evidence.push(...Kt(n))}function Bt(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 to(e){let t=a(e).toLowerCase();return Yi.get(t)||t}function Ue(e,t,r=""){let n=eo(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:to(t),arguments:n}}function jt(e){return l(e)?a(e.call_id||e.callId||e.toolCallId||e.id):""}function eo(e){if(!l(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=ro(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 ro(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 no(e,t){if(!l(e))return"unknown";let r=qt(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function qt(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return so(e,t,r);if(Array.isArray(e))return e.flatMap(o=>qt(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=_t(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(...qt(e[o],t+1,r));return n}function so(e,t,r){let n=e.trim();if(!n)return[];try{return qt(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 _t(e){let t=a(e).toLowerCase();return Wi.has(t)?"success":Xi.has(t)?"failed":"unknown"}function Kt(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:_t(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...a(i.message)?{message:a(i.message)}:{}});return n}function io(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&Pe(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 Me(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?Me(e,"failed",i,"Runtime tool evidence failed."):Me(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function Me(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 Pe(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>Pe(r,t[n])):l(e)?l(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&Pe(n,t[r])):!1:Object.is(e,t)}function j(e){if(e===null||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="string")return pn(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 j(e[r])}).join(",")}]`;if(l(e))return`{${Object.keys(e).sort().map(t=>`${pn(t)}:${j(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function pn(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 ao}from"node:child_process";import{createHash as co,randomUUID as uo}from"node:crypto";import{constants as lo}from"node:fs";import{access as fo,mkdir as Le,readdir as po,realpath as yt,rm as ho,stat as mo}from"node:fs/promises";import go from"node:http";import{tmpdir as _o}from"node:os";import{isAbsolute as Tt,join as it,relative as _n,resolve as De}from"node:path";var He=1,yo="orcha.process-isolation/v1",$e="orcha.egress-proxy/v1",To="--disable-wasm-trap-handler",Gt={read_only:0,workspace_write:1,workspace_network:2},ve={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},wo=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function J(e){if(!l(e))throw E("RUNTIME_SANDBOX_POLICY_REQUIRED","sandboxPolicy is required");let t=structuredClone(e),r=a(t.accessMode),n=a(t.accessModeCeiling);if(!(r in ve)||!(n in ve))throw E("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if(Gt[r]>Gt[n])throw E("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=ve[r];if(t.filesystemMode!==s||t.networkMode!==i)throw E("RUNTIME_SANDBOX_POLICY_INVALID","runtime access profile does not match its mode");if(Number(t.policySchemaVersion)!==He||!Number.isInteger(Number(t.policyRevision))||Number(t.policyRevision)<1)throw E("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 E("RUNTIME_SANDBOX_POLICY_INVALID",`${c} cannot be relaxed`);let o=l(t.processIsolation)?t.processIsolation:{};if(o.mode!=="required"||o.backend==="direct")throw E("RUNTIME_SANDBOX_POLICY_INVALID","strong process isolation is required");if(Array.isArray(t.alwaysApprovedApprovalKeys)&&t.alwaysApprovedApprovalKeys.length)throw E("RUNTIME_SANDBOX_POLICY_INVALID","persistent runtime approvals are forbidden");return t}function yn(e,t){let r=J(e),n=J(t);return Gt[n.accessMode]<Gt[r.accessMode]}async function Tn(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[He],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await Rn(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await Io(t,b(e.sandboxBrokerArguments),e.sandboxProbeTimeoutMs);if(r.enforced!==!0||a(r.protocolVersion)!=="orcha.runtime-sandbox-broker/v1"||!["bubblewrap","broker"].includes(a(r.backend)))throw E("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 E("RUNTIME_SANDBOX_UNAVAILABLE",`sandbox broker probe failed: ${s}`);return e.egressProxyRequired&&await bo(e),{dispatchable:!0,enforced:!0,backend:a(r.backend),daemonStatus:"ok",daemonProtocolVersion:a(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[He],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function Fe(e,t,r){let n=a(t.workspace||t.cwd),s=a(r),i=n||(t.allowRequestWorkspace===!0?s:"");if(!i||!Tt(i))throw E("RUNTIME_WORKSPACE_NOT_CONFIGURED","runtime target must configure an absolute trusted workspace");let o=await yt(i);if(!(await mo(o)).isDirectory())throw E("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>yt(d))):[o]).some(d=>je(d,o)))throw E("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function wn({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 Fe(e,t,s),h=await yt(s);if(!je(p,h))throw E("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let g=await Rn(e.sandboxBrokerCommand,process.env.PATH||"");if(!g)throw E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let y=`runtime-${co("sha256").update(String(o)).digest("hex").slice(0,32)}`,R=De(e.sandboxTempRoot||it(_o(),"orcha-runtime-sandboxes"));await Le(R,{recursive:!0,mode:448});let A=it(R,`${y}-${uo()}`),T=it(A,"home"),w=it(A,"artifacts");await Le(T,{recursive:!0,mode:448}),await Le(w,{recursive:!0,mode:448});let S=f.networkMode==="restricted"?await xo(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",...So(t,i)};I.HOME="/tmp/home",I.TMPDIR="/tmp",I.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",I.NODE_OPTIONS=To;let P={schemaVersion:yo,runId:String(o),instanceId:y,workspace:p,cwd:h,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await Eo(p),temporaryDirectory:A,egressProxy:S,environment:I,resourceLimits:Oo(f),readOnlyToolchainRoots:await Ro(e,t)},D=!1,N=async()=>{if(!D){D=!0;try{S&&await Co(e,S,{runId:String(o),instanceId:y})}finally{await ho(A,{recursive:!0,force:!0})}}};return{command:g,args:[...b(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:A,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:N}}async function Ro(e,t){let r=b(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(b(e.trustedToolchainRoots).map(i=>yt(i)));if(!n.length)throw E("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","target toolchain roots require ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS");let s=[];for(let i of r){if(!Tt(i))throw E("RUNTIME_TOOLCHAIN_ROOT_INVALID","toolchain roots must be absolute");let o=await yt(i);if(!n.some(c=>je(c,o)))throw E("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function So(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 Eo(e){let t=[],r=0,n=async s=>{let i;try{i=await po(s,{withFileTypes:!0})}catch(o){if(s===e)throw o;return}for(let o of i){if(r+=1,r>1e4)throw E("RUNTIME_WORKSPACE_SCAN_LIMIT_EXCEEDED","workspace contains more than 10000 entries");let c=it(s,o.name),u=_n(e,c),d=o.name.toLowerCase();(wo.has(d)||d.startsWith(".env."))&&t.push(u),o.isDirectory()&&!o.isSymbolicLink()&&await n(c)}};return await n(e),t.sort()}function Oo(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 Io(e,t,r){return await new Promise((n,s)=>{let i=ao(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(E("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(E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox probe returned invalid JSON"))}})})}async function Rn(e,t){let r=a(e);if(!r)return"";let n=Tt(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>it(s,r));for(let s of n)try{return await fo(s,lo.X_OK),s}catch{}return""}async function xo(e,t){if(!e.egressProxyRequired)throw E("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await Be(e,"POST","/v1/grants",{protocolVersion:$e,...t}),n={socketPath:e.egressProxySocket,grantId:a(r.grantId),credential:a(r.credential)};if(!n.grantId||!n.credential)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy returned an invalid grant");return n}async function Co(e,t,r){await Be(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:$e,...r}).catch(()=>{})}async function bo(e){let t=await Be(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==$e)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function Be(e,t,r,n){if(!Tt(e.egressProxySocket)||!e.egressProxyToken)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy socket and token are required");return await new Promise((s,i)=>{let o=go.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(E("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=_n(De(e),De(t));return r===""||!r.startsWith("..")&&!Tt(r)}function E(e,t){return Object.assign(new Error(t),{code:e})}var qe=24e3,Ke=8,Ge=50,ze=6e3,No=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),Mo=10*60*1e3,Uo=60*1e3,Po=8,ko=30*60*1e3,Lo=60*1e3,vo=1,In=2400,Do=new Set(["max_tokens","max_output_tokens","length"]),Ho=new Set(["agent_message_chunk","tool_call","tool_call_update"]),$o=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),Fo=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function Bo(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 jo(e){return(Array.isArray(e)?e:[]).map(Bo).sort((t,r)=>{let n=j(t),s=j(r);return n<s?-1:n>s?1:0})}function qo(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 Ko(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:Vt()}}}function L(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 xn(e){let t=a(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return No.has(t)}function G(e,t){let r=_(e,t);return Number.isFinite(r)&&r>0?r:t}function wt(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 Cn(e){let t=K(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function We(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 Go(e){let t=String(e||"");if(Fo.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 Xe(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>=Ke)return Array.isArray(e)?`[array truncated at depth ${Ke}, items=${e.length}]`:l(e)?`[object truncated at depth ${Ke}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,Ge).map(n=>Xe(n,t+1));return e.length>Ge&&r.push(`[truncated ${e.length-Ge} items]`),r}if(l(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=Go(n)?"[REDACTED]":Xe(s,t+1);return r}return String(e)}var zo=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 Vo(e){if(!l(e))return e;let t={};for(let r of zo)L(e[r])&&(t[r]=e[r]);return t}function Jo(e){if(!l(e))return e;let t={...e};return l(t.renderedPayload)&&(t.renderedPayload=Vo(t.renderedPayload)),t}function Wo(e){let t=l(e)?e:{},r={};L(t.metadata)&&(r.metadata=Jo(t.metadata));for(let[n,s]of Object.entries(t))$o.has(n)||n==="metadata"||L(s)&&(r[n]=s);return r}function Xo(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 bn(e){return a(Xo(e).kind).toLowerCase()==="decision"}function Yo(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:K(e)==="cli"}function Sn(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return wt(t,Cn(e))}function Zo(e,t){let r=l(e?.metadata)?{...e.metadata}:{},n=l(r._runtimeBridge)?{...r._runtimeBridge}:{},s=We(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:Yo(t),releaseAfterPrompt:s===void 0?Sn(t):wt(s,Sn(t)),requiresRuntimeResult:bn(e)},r}function Qo(e){let t=Wo(e);if(!L(t))return"";let r=JSON.stringify(Xe(t),null,2);if(r.length<=qe)return r;let n=r.length-qe;return`${r.slice(0,qe)}
|
|
14
|
+
... [truncated ${n} characters]`}function Ze(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 Ye(e){if(!l(e))return"";let t=l(e.update)?e.update:e;return a(t.sessionUpdate)}function Qe(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=Ye(c),d=Ze(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 ot(s);let o=n[n.length-1]||[];return ot(o)}function ta(e){return Array.isArray(e)?e.map(Ze).filter(t=>t!==""):[]}function Jt(e){return Array.isArray(e)?e.some(r=>Ye(r))?e.filter(r=>Ho.has(Ye(r))).map(Ze).filter(r=>r!==""):ta(e):[]}function ea(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 ra(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 na(e){if(!Array.isArray(e))return"";for(let t=e.length-1;t>=0;t-=1){let r=ra(ea(e[t]));if(r)return r}return""}function ot(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=fn(n)&&!/[\r\n]$/.test(t)?`
|
|
15
|
+
`:"";t+=`${s}${n}`}}return t.trim()}function sa(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]===`
|
|
16
|
+
`?1:0)).trim()}function En(e){let t=String(e||"").trim();if(!t)return null;try{let r=JSON.parse(t);if(l(r)&&(An(r)||L(r._artifacts)||L(r.artifacts)||L(r._decision)||L(r._meta)))return r}catch{}return null}function Rt(e){try{return Ne(e)}catch{return null}}function zt(...e){let t=null;for(let r of e)try{if(Ne(r))return}catch(n){t||=n}if(t)throw t}function Ve(e){let t=String(e||"").trim();if(!t)return null;let r=Rt(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=En(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=En(t.slice(s));if(i)return i}return null}function ia(e){let t=Rt(Qe(e));if(t)return t;let r=Jt(e);for(let n=r.length-1;n>=0;n-=1){let s=Rt(r[n]);if(s)return s}return Rt(ot(r))}function An(e){if(!l(e))return!1;if(L(e.output))return!0;for(let t of["content","text","message","summary"])if(a(e[t]))return!0;return!!(xn(e.status)||a(e.error)||a(e.errorMessage))}function B(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 oa(e){return l(e)?typeof(l(e._decision)?e._decision:l(e.decision)?e.decision:e).passed=="boolean":!1}function Nn(e){return l(e)?l(e._decision)&&typeof e._decision.passed=="boolean"?!0:oa(e.output):!1}function Je(e,t,r){let n=l(e)?{...e}:{};if(!L(n.output)){for(let s of["summary","message","content","text"])if(a(n[s])){n.output=a(n[s]);break}}return!L(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 aa=["dataUrl","dataURL","contentDataUrl","contentDataURL","contentBase64","base64","data"];function On(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 ca(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 aa)L(e[i])&&(s[i]=e[i]),L(r[i])&&(s.content[i]=r[i]);return s}function Mn(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=On(r[c]),d=i.get(u)||[];d.push(c),i.set(u,d)}let o=new Map;for(let c of n){let u=On(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]=ca(s[f],c)}return s}function q(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=Mn(e._artifacts,t._artifacts)),n}function Un(e,t,r={}){let n=a(r.promptKind),s=r.requiresRuntimeResult===!0,i=s||n==="dispatch",o=B(e),c=typeof o.output=="string"?Rt(o.output):null;if(c)return q(o,B(c),"result_block");let u=na(t),d=u?Ve(u):null,f=i?ia(t):null;if(An(o))return xn(o.status)||a(o.error)||a(o.errorMessage)?o:n==="dispatch"&&d?q(o,B(d),"final_event"):n==="dispatch"&&f?q(o,B(f),"updates"):!s||Nn(o)?o:d?q(o,B(d),"final_event"):f?q(o,B(f),"updates"):(zt(o.output,u,ot(Jt(t))),Je(o,"result",o.output));if(d)return q(o,B(d),"final_event");if(f)return q(o,B(f),"updates");if(u)return s?(zt(u,ot(Jt(t))),Je(o,"final_event",u)):{...o,output:u,_meta:{...l(o._meta)?o._meta:{},runtimeOutputSource:"final_event"}};let p=Qe(t),h=Ve(p);if(h)return q(o,B(h),"updates");let g=sa(p);if(!g)return s&&zt(ot(Jt(t))),o;let y=Ve(g);return y?q(o,B(y),"updates"):s?(zt(p,g),Je(o,"updates",g)):{...o,output:g,_meta:{...l(o._meta)?o._meta:{},runtimeOutputSource:"updates"}}}function tr(e){return l(e)?a(e.stopReason||e.stop_reason).toLowerCase():""}function Pn(e){return Do.has(tr(e))}function ua(e,t,r){if(r.promptKind!=="dispatch"||r.requiresRuntimeResult!==!0||!Pn(e))return!1;try{return!Nn(Un(e,t,r))}catch{return!0}}function la(){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 ${In} Unicode characters.`,`Output ${Ie}, ${xe}, ${Ce}, and ${be} 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(`
|
|
17
|
+
`)}function da(e,t){let r=l(t)?{...t}:{},n=Mn(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function fa(e,t){return{...e,_meta:{...l(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:tr(t)||"max_tokens"}}}}function pa(e,t){let r=typeof e?.output=="string"?e.output:Qe(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:tr(e)||"max_tokens",retryAttempted:!0},n}var Wt=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=ft(),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 Tn(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"},m("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)?ke(t.goalContract):a(t.goalContractHash),i=Ao("sha256").update(j({prompt:Array.isArray(t.prompt)?t.prompt:[],mcpServers:jo(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=Un(i,o,u),f=mn(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=G(this.config.operationTtlMs,ko);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"?G(this.config.openClawSessionIdleTtlMs,Lo):G(this.config.sessionIdleTtlMs,Mo);return G(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=K(t)==="openclaw"?G(this.config.openClawMaxSessions,vo):G(this.config.maxSessionsPerTarget,Po);return G(t?.maxSessions,n)}targetReservationCount(t){return Number(this.targetReservations.get(t)||0)}notifyCapacityChanged(){try{this.onCapacityChanged?.()}catch(t){m("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=We(s);return i!==void 0?wt(i,!1):wt(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=l(r?._runtimeBridge)?r._runtimeBridge:{},s=We(n);return s!==void 0?wt(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=G(this.config.sessionCleanupIntervalMs,Uo);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(r=>{m("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){m("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(),m("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 Fe(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:ft(),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=>wn({config:this.config,target:s,...u,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new rt(t,s,o,c):i==="openclaw"?new Lt(t,s,r,o,c):i==="cli"?new Ft(t,s,c):new Ct(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)||Vt(),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&&m("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(K(d.target)==="cli"&&qo(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),g=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,S;try{await this.reserveTargetSlot(T,w),g=T;let I=this.runtimeFor(f,i,{runId:o,sandboxPolicy:c,source:t.metadata?.source,attachOnly:t.attachOnly});S=I;let P=n?.mcpServers||t.mcpServers||[],D=await I.sessionNew({cwd:et(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 N=Date.now();h={agentId:s,sessionId:i,runtime:I,targetCode:T,runtimeKind:K(w),runId:o,sandboxPolicy:c?structuredClone(c):null,runtimeSessionId:a(l(D)?D.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(w),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(w,t.metadata),createdAtMs:N,lastUsedAtMs:N,busy:!1,createdAt:ft()},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===S?await this.closeSession(p,"session_start_failed"):await S?.stop("session_start_failed"),g&&(this.releaseTargetSlot(g),g=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,g&&this.releaseTargetSlot(g),this.notifyCapacityChanged(),h.operationCorrelationId=n?.correlationId||null,h.lastUsedAtMs=Date.now();let y=n?.updates||[],R=T=>{let w=Ko(T,i,h);if(y.push(w),n)for(let S of n.listeners)try{S?.(w)}catch(I){m("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(I)})}else r.onUpdate?.(w)},A=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 S=l(w)?w:{},I=Object.assign(new Error(a(S.message||T.message)||"runtime terminal failure"),{code:a(S.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=hn(t.goalContract),w=Array.isArray(t.prompt)?[...t.prompt]:[];T&&w.unshift({type:"text",text:T,metadata:{source:"orcha_goal_contract"}});let S=l(t.metadata)?t.metadata:{},I=l(S._runtimeBridge)?S._runtimeBridge:{},P=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:w,metadata:S},R,A),D=y,N=null;if(Cn({type:h.runtimeKind})&&ua(P,y,I)){N=P;let Z=y.length,ct=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:[{type:"text",text:la()}],metadata:S,_meta:{thinking:"off"}},R,A);P=da(N,ct),D=y.slice(Z)}let O;try{O=this.promptResponse(t,h,i,y,P,D)}catch(Z){throw N&&Pn(P)?pa(P,D):Z}return N&&(O.result=fa(O.result,N)),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(j(f)!==j(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 g=yn(f,o);c&&(c.sandboxPolicy=structuredClone(o)),d&&(d.sandboxPolicy=structuredClone(o));let y=!1;return g&&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:!g&&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=Qo(t),d=bn(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 ${Ie} and ${xe}.`:"",d?`Then put a JSON object containing _decision between ${Ce} 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 ${In} 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:Zo(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=Vt(),c=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||Vt(),u={permissionId:i,agentId:t.agentId,sessionId:c,runtimeSessionId:r,request:l(n)?n:{},status:"pending",createdAt:ft()};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:tt,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 ha from"node:http";import ma from"node:https";import{randomBytes as kn}from"node:crypto";var at=1,W=3,ga=1e4,Xt=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=_a(r.connectTimeoutMs,ga),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:"?ma:ha,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===W){o.destroy();return}this.socket=o,this.readyState=at,o.on("data",u=>this.onData(u)),o.on("close",()=>this.onClose()),o.on("error",u=>{this.readyState!==W&&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!==W&&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===at||this.readyState===W)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!==at||this.socket.write(er(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==W){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===at&&this.socket.write(er(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==W&&(this.clearConnectTimer(),this.readyState=W,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(er(10,d))}}};function _a(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function er(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 ya(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 Ta(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 wa=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),Yt=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[...wa,...this.config.deviceConnection?["devices/discover","devices/configure"]:[]]}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):Ta(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=ya(this.config.orchaUrl),r=new Xt(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=>{m("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:tt,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||(m("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){m("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),m("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!==at?!1:(r.send(JSON.stringify(t)),!0)}};import{existsSync as Ln,readFileSync as Ra}from"node:fs";import{dirname as Sa,resolve as Zt}from"node:path";import{fileURLToPath as Ea}from"node:url";var Oa=/^[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?Zt(t,r):Zt(t,".env");if(!Ln(n))return r&&m("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Ra(n,"utf8");for(let o of i.split(/\r?\n/)){let c=Ca(o);if(!c)continue;let[u,d]=c;Object.prototype.hasOwnProperty.call(e,u)||(e[u]=d,s.push(u))}return m("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function Dn(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=Sa(Ea(import.meta.url)),i=Zt(s,"sandbox","broker.js"),o=Zt(s,"orcha-runtime-sandbox-broker.js"),c=Ln(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:rr(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:rr(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:rr(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:xa(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:Ia(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Ia(e){if(!a(e))return{};try{let t=JSON.parse(e);if(l(t))return t}catch(t){m("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function xa(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 rr(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 Ca(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(!Oa.test(s))return null;let i=ba(r.slice(n+1).trim());return[s,i]}function ba(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?Aa(r):r}return Na(e).trim()}function Aa(e){return e.replaceAll("\\n",`
|
|
19
|
+
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function Na(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 Ma}from"node:http";function Qt(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 X(e={}){return{ok:!0,...e}}function nr(e,t,r){return{ok:!1,error:{code:e,message:t,...r===void 0?{}:{detail:r}}}}async function Hn(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 $n(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 Fn(e,t){let r={"GET /health":async()=>X(t.health()),"POST /agents/create":async n=>X(await t.createAgent(n)),"POST /agents/dispatch":async n=>X(await t.dispatch(n)),"POST /sessions/prompt":async n=>X(await t.prompt(n)),"POST /sessions/cancel":async n=>X(await t.cancel(n)),"POST /permissions/respond":async n=>X(await t.respondPermission(n))};return Ma(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){Qt(s,404,nr("NOT_FOUND",`No route for ${o}`));return}try{$n(n,e.token);let u=n.method==="GET"?{}:await Hn(n,e.requestLimitBytes);Qt(s,200,await c(u))}catch(u){let d=u.status||500,f=u.code||"BRIDGE_INTERNAL";Qt(s,d,nr(f,u.message||String(u),u.detail))}})}var $a=Ha(import.meta.url),Fa=".orcha-runtime-bridge.pid",Ba=".orcha-runtime-bridge.log",ja=3,qa=36e5,{command:Ka,options:Jn}=Va(process.argv.slice(2));Ja(Jn);vn();var Ga=Dn();await Wn(Ka,Ga,Jn);async function Wn(e,t,r){if(r.url){let s=ae(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&&Y(ee(te())))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 Et(t,r),r.foreground?await sr(t):ir(n());return;case"run":case"foreground":r.url&&await Et(t,r),await sr(t);return;case"start":if(r.url)return Wn("connect",t,r);if(r.foreground){await sr(t);return}ir();return;case"reload":case"restart":r.url&&await Et(t,{url:r.url}),await qn({quiet:!0}),ir(r.url?n():void 0);return;case"stop":await qn();return;case"status":za();return;case"help":case"--help":case"-h":Za();return;default:throw new Error(`Unknown command: ${e}`)}}async function sr(e){Wa();let t=new Wt(e);if(await t.start(),e.mode==="server"){let n=Fn(e,t);jn({bridge:t,server:n}),n.listen(e.port,e.host,()=>{m("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 Yt(e,t);jn({bridge:t,client:r}),r.start(),m("info","runtime-bridge","Orcha runtime node started",{nodeId:e.nodeId,nodeName:e.nodeName,orchaUrl:e.orchaUrl,targets:Object.keys(t.targets)})}function jn({bridge:e,client:t,server:r}){let n=!1,s=i=>{if(n)return;n=!0;let o=Number(e?.sessions?.size||0)>0;m("info","runtime-bridge","runtime bridge shutting down",{signal:i});try{t?.stop?.()}catch(c){m("warn","runtime-bridge","runtime client stop failed",{error:String(c)})}Promise.resolve(e?.stop?.(`process_${String(i||"shutdown").toLowerCase()}`)).catch(c=>{m("warn","runtime-bridge","runtime bridge stop failed",{error:String(c)})}).finally(()=>{try{r?.close?.()}catch(c){m("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 ir(e=["run"]){let t=te(),r=Xn(),n=ee(t);if(n&&Y(n)){console.log(JSON.stringify({status:"already_running",pid:n,pidFile:t,logFile:r}));return}n&&cr(t),Gn(t),Gn(r),ar(r);let s=La(r,"a"),i={...process.env,ORCHA_RUNTIME_PID_FILE:t,ORCHA_RUNTIME_LOG_FILE:r},o=Ua(process.execPath,[$a,...e,"--pid-file",t,"--log-file",r],{cwd:process.cwd(),detached:!0,env:i,stdio:["ignore",s,s]});o.unref(),Pa(s),Vn(t,`${o.pid}
|
|
20
|
+
`),console.log(JSON.stringify({status:"started",pid:o.pid,pidFile:t,logFile:r}))}async function qn({quiet:e=!1}={}){let t=te(),r=ee(t);if(!r){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!Y(r)){cr(t),e||console.log(JSON.stringify({status:"not_running",pid:r,pidFile:t}));return}process.kill(r,"SIGTERM"),!await Kn(r,1e4)&&Y(r)&&(process.kill(r,"SIGKILL"),await Kn(r,3e3)),cr(t),e||console.log(JSON.stringify({status:"stopped",pid:r,pidFile:t}))}function za(){let e=te(),t=Xn(),r=ee(e),n=!!(r&&Y(r));console.log(JSON.stringify({status:n?"running":"not_running",running:n,pid:n?r:null,pidFile:e,logFile:t}))}function Va(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 Ja(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 te(){return ur(process.cwd(),process.env.ORCHA_RUNTIME_PID_FILE||Fa)}function Xn(){return ur(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||Ba)}function Wa(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=Yn();if(t<=0)return;let r=ur(process.cwd(),e);ar(r,t);let n=Ya();n<=0||setInterval(()=>ar(r,t),n).unref()}function ar(e,t=Yn()){if(t<=0||!zn(e))return;let r=0,n="";try{if(r=Bn(e).size,r<=0)return;n=or(e,"utf8")}catch(d){m("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&&(Xa(d,s)?o.push(d):c+=1);if(c===0)return;let u="";try{Bn(e).size>r&&(u=or(e,"utf8").slice(n.length));let f=[...o,...u.split(/\r?\n/).filter(Boolean)].join(`
|
|
21
|
+
`);Vn(e,f?`${f}
|
|
22
|
+
`:""),m("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:c})}catch(d){m("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function Xa(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 Yn(){return Zn(process.env.ORCHA_RUNTIME_LOG_RETENTION_DAYS,ja)}function Ya(){return Zn(process.env.ORCHA_RUNTIME_LOG_CLEANUP_INTERVAL_MS,qa)}function Zn(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function ee(e){if(!zn(e))return null;let t=Number.parseInt(or(e,"utf8").trim(),10);return Number.isInteger(t)&&t>0?t:null}function Y(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function Kn(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!Y(e))return!0;await new Promise(n=>setTimeout(n,100))}return!Y(e)}function Gn(e){ka(Da(e),{recursive:!0})}function cr(e){try{va(e,{force:!0})}catch{}}function Za(){console.log(`Usage: orcha-runtime-bridge [command] [options]
|
|
23
23
|
|
|
24
24
|
Commands:
|
|
25
25
|
connect Pair or reconnect this device, then run in the background.
|
package/openclaw-plugin/index.js
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
var
|
|
1
|
+
import{getPluginRuntimeGatewayRequestScope as Oe}from"openclaw/plugin-sdk/plugin-runtime";import{loadOutboundMediaFromUrl as Te}from"openclaw/plugin-sdk/outbound-media";var L={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs"]};var J=Object.freeze([...L.controlTools,...L.residentTools]),ce=new Set(J),le=8*1024*1024;function V(t,r){if(!Array.isArray(t)||t.length!==1)throw new Error("one task-scoped Orcha MCP server is required");let p=t[0],d=new URL(p.url);if(p.name!=="orcha"||p.type!=="http"||!["http:","https:"].includes(d.protocol)||d.username||d.password||d.hash||r&&d.href!==new URL(r).href)throw new Error("Orcha MCP server does not match the trusted binding");let u=Object.fromEntries((p.headers||[]).map(({name:m,value:h})=>[m.toLowerCase(),h]));if(!String(u.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:d.href,headers:{...u,"content-type":"application/json",accept:"application/json"}}}async function R(t){let r=0,p=[];for await(let d of t){if(r+=d.length,r>le)throw new Error("MCP payload exceeds the size limit");p.push(Buffer.from(d))}return JSON.parse(Buffer.concat(p).toString("utf8"))}async function F(t,r,p){let d=await fetch(t.url,{method:"POST",headers:t.headers,body:JSON.stringify(r),redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(36e5),...p?[p]:[]])});if(!d.ok)throw new Error(`Orcha MCP request failed (${d.status})`);if(d.status===202||d.status===204)return null;let u=await R(d.body);if(!u||u.jsonrpc!=="2.0"||u.id!==r.id)throw new Error("Orcha MCP response identity mismatch");return u}async function Y(t,r){let p=await F(t,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},r),d=p?.result?.tools;if(p?.error)throw new Error("Orcha MCP tool discovery failed");return de(d)}function de(t){if(!Array.isArray(t)||t.some(r=>!r||!ce.has(r.name)||r.inputSchema?.type!=="object"||typeof r.description!="string")||new Set(t.map(r=>r.name)).size!==t.length||t.length&&L.controlTools.some(r=>!t.some(p=>p.name===r)))throw new Error("Orcha MCP returned an unsupported or invalid authorized tool catalog");return t}function X(t,r){let p=u=>Array.isArray(u)?u.map(p):u&&typeof u=="object"?Object.fromEntries(Object.keys(u).sort().map(m=>[m,p(u[m])])):u,d=u=>u.map(({name:m,inputSchema:h})=>({name:m,inputSchema:h})).sort((m,h)=>m.name.localeCompare(h.name));return JSON.stringify(p(d(t)))===JSON.stringify(p(d(r)))}var z=t=>Object.assign(new Error(t),{status:409});function Z(t){let r=new Map,p=t.pluginConfig?.allowedOrchaMcpUrl;if(!p)throw new Error("Orcha plugin requires allowedOrchaMcpUrl");function d(h,l=r.get(h)){!l||r.get(h)!==l||(l.lifetime.abort(),clearTimeout(l.timer),r.delete(h))}function u(h){let l=r.get(h);return l&&l.deadline<=Date.now()?(d(h,l),null):l}async function m(h,{refresh:l=!1}={}){let{runId:c,sessionKey:g,agentCode:v,expiresAt:M,mcpServer:E}=h,S=Date.parse(M);if(typeof c!="string"||!c||typeof g!="string"||!g||typeof v!="string"||!v||!g.startsWith(`agent:${v}:`)||!Number.isFinite(S)||S<=Date.now()||S>Date.now()+24*36e5)throw new Error("invalid_binding_scope");let b=u(g);if(l&&!b||b&&(b.runId!==c||b.agentCode!==v||b.deadline!==S))throw z("original_binding_unavailable_or_changed");let N=V([E],p),D=b?.lifetime||new AbortController,e=await Y(N,D.signal);if(u(g)!==b)throw z("binding_changed");if(b){if(!X(b.tools,e))throw z("frozen_tool_catalog_changed");b.upstream=N}else{let o={runId:c,agentCode:v,deadline:S,upstream:N,tools:e,lifetime:D};o.timer=setTimeout(()=>d(g,o),S-Date.now()),o.timer.unref?.(),r.set(g,o)}}return t.registerTool(h=>{let l=u(h.sessionKey);return!l||h.agentId!==l.agentCode?null:l.tools.map(c=>({name:`orcha_${c.name}`,label:`Orcha ${c.name}`,description:c.description,parameters:c.inputSchema,async execute(g,v,M){if(u(h.sessionKey)!==l||h.agentId!==l.agentCode||!g||!l.tools.some(S=>S.name===c.name))throw new Error("Orcha task binding expired or changed");let E=await F(l.upstream,{jsonrpc:"2.0",id:g,method:"tools/call",params:{name:c.name,arguments:v}},AbortSignal.any([l.lifetime.signal,...M?[M]:[]]));if(E?.error||!E?.result)throw new Error("Orcha rejected this task-scoped tool call");return{content:E.result.content,details:E.result.structuredContent,isError:E.result.isError===!0}}}))},{names:J.map(h=>`orcha_${h}`)}),{bind:m,active:u,release:d,allowedUrl:p}}import{createHash as ue}from"node:crypto";import{mkdirSync as pe,readFileSync as he,renameSync as me,writeFileSync as fe}from"node:fs";import{join as q}from"node:path";var K=t=>ue("sha256").update(JSON.stringify(t)).digest("hex"),I=(t,r=409)=>Object.assign(new Error(t),{status:r,code:t}),k=t=>typeof t=="string"&&/^[1-9]\d{0,18}$/.test(t),ge=t=>new Promise(r=>setTimeout(r,t));function ee(t,r,p,d,u){let m=new Map,h=new Map,l=()=>t.config;function c(e,o=l()){let n=o?.channels?.orcha?.accounts?.[e];if(!k(e)||!n||n.enabled===!1||!n.serviceToken||!n.agentId)throw I("orcha_channel_account_unavailable",403);return{...n,accountId:e}}async function g(e,o,n,{cfg:a,signal:i,method:f="POST"}={}){let s=c(e,a),T=new URL(`/api/agent-channels${o}`,r.allowedUrl),_=n instanceof FormData,w=await fetch(T,{method:f,redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(3e4),...i?[i]:[]]),headers:{authorization:`Bearer ${s.serviceToken}`,..._?{}:{"content-type":"application/json"}},...n!==void 0?{body:_?n:JSON.stringify(n)}:{}}),A=await R(w.body);if(!w.ok||A.success!==!0)throw I(`orcha_channel_request_${w.status}`,w.status);return A.data}function v(e,o="runs"){if(!/^[a-zA-Z0-9_-]{1,128}$/.test(e))throw I("invalid_record_identity",422);let n=q(t.runtime.state.resolveStateDir(),"plugins","orcha-runtime",o);return pe(n,{recursive:!0,mode:448}),q(n,`${e}.json`)}function M(e,o){try{return JSON.parse(he(v(e,o),"utf8"))}catch(n){if(n.code==="ENOENT")return null;throw n}}function E(e,o,n){let a=v(e,n),i=`${a}.pending`;fe(i,JSON.stringify(o),{mode:384}),me(i,a)}async function S(e,o=!1){let n=c(e.delivery?.bindingId),{runId:a,delivery:i}=e;if(!k(a)||!k(i.sessionId)||!k(i.taskContextId)||i.mode!=="channel"||e.agentCode!==n.agentId)throw I("invalid_channel_delivery",422);if(!Array.isArray(e.prompt)||e.prompt.some(y=>!["text","image","file"].includes(y.type)||(y.type==="text"?typeof y.text!="string":typeof y.uri!="string")))throw I("invalid_channel_prompt",422);let f=K({agentCode:e.agentCode,delivery:i,prompt:e.prompt}),s=M(a);if(s&&s.requestHash!==f)throw I("channel_delivery_conflict");if(s?.status==="completed")return s.result;if(s?.status==="failed")throw I(s.error);let T=m.get(a),_=s?.expiresAt||e.expiresAt,w=`agent:${n.agentId}:orcha:${i.bindingId}:${a}`,A=s?.hostRunId||`orcha-${a}`;if(s&&!T||e.attachOnly&&!T&&!s)throw I("RUNTIME_OPERATION_NOT_FOUND");if(T)return await r.bind({runId:a,sessionKey:w,agentCode:n.agentId,expiresAt:_,mcpServer:e.mcpServer},{refresh:!0}),o?{refreshed:!0}:T.promise;if(o)throw I("RUNTIME_OPERATION_NOT_FOUND");let C=new AbortController,P={controller:C,promise:null};return m.set(a,P),P.promise=(async()=>{await r.bind({runId:a,sessionKey:w,agentCode:n.agentId,expiresAt:_,mcpServer:e.mcpServer}),E(a,{requestHash:f,status:"running",sessionKey:w,hostRunId:A,expiresAt:_});let y=[],$=[],j,ne=setTimeout(()=>C.abort(I("run_timeout")),Date.parse(_)-Date.now());try{let B=t.runtime.channel.reply;if(typeof B?.dispatchReplyWithBufferedBlockDispatcher!="function")throw I("OPENCLAW_CHANNEL_RUNTIME_UNAVAILABLE");let x=e.prompt.filter(O=>O.type==="text").map(O=>O.text).join(`
|
|
2
|
+
|
|
3
|
+
`),W=e.prompt.filter(O=>O.type!=="text"),oe={Body:x,BodyForAgent:x,RawBody:x,From:`orcha:${i.memberId}`,To:`orcha:${i.sessionId}`,SessionKey:w,AccountId:i.bindingId,Provider:"orcha",Surface:"orcha",ChatType:"direct",OriginatingChannel:"orcha",OriginatingTo:i.sessionId,MessageSid:a,MediaUrls:W.map(O=>O.uri),MediaTypes:W.map(O=>O.mimeType||"application/octet-stream"),CommandAuthorized:!1,CommandInterpretationSuppressed:!0,WasMentioned:!0};if(await B.dispatchReplyWithBufferedBlockDispatcher({ctx:oe,cfg:l(),replyOptions:{runId:A,abortSignal:C.signal,suppressTyping:!0},dispatcherOptions:{deliver:async(O,ae)=>{if(C.signal.throwIfAborted(),ae.kind==="final"&&d(O)){let ie=O.mediaUrls||(O.mediaUrl?[O.mediaUrl]:[]),U=l(),G=U?.agents?.list?.find(H=>H.id===n.agentId)?.workspace||U?.agents?.defaults?.workspace;for(let H of ie)$.push(await b(i.bindingId,i.sessionId,H,{cfg:U,signal:C.signal,mediaLocalRoots:G?[G]:void 0}));O.text&&y.push(O.text)}},onError:O=>{j??=O}}}),j)throw j;if(C.signal.throwIfAborted(),!y.length&&!$.length)throw I("runtime_node_empty_result");let Q={stopReason:"end_turn",content:y.join(`
|
|
4
|
+
|
|
5
|
+
`)||"\u5DF2\u751F\u6210\u9644\u4EF6",inputParts:$,sessionId:w};return E(a,{requestHash:f,status:"completed",sessionKey:w,hostRunId:A,expiresAt:_,result:Q}),Q}catch(B){throw E(a,{requestHash:f,status:"failed",sessionKey:w,hostRunId:A,expiresAt:_,error:B.code||"channel_host_failed"}),B}finally{clearTimeout(ne),r.release(w),m.delete(a)}})().catch(y=>{throw r.release(w),m.delete(a),y}),P.promise}async function b(e,o,n,a){let i=await u(n,{maxBytes:33554432,mediaAccess:a.mediaAccess,mediaReadFile:a.mediaReadFile,mediaLocalRoots:a.mediaLocalRoots});a.signal?.throwIfAborted();let f=new FormData;return f.set("sessionId",o),f.set("file",new Blob([i.buffer],{type:i.contentType||"application/octet-stream"}),i.fileName||"attachment"),(await g(e,"/files",f,{cfg:a.cfg,signal:a.signal})).inputPart}async function N(e){e.signal?.throwIfAborted();let o=e.to.replace(/^orcha:/,"");if(!k(o))throw I("invalid_conversation",422);let n=e.preparedMessageId||e.deliveryQueueId&&`${e.deliveryQueueId}:${e.deliveryPartIndex||0}`;if(!n)throw I("OPENCLAW_DURABLE_DELIVERY_ID_REQUIRED");let a=K([e.accountId,n]),i=K([o,e.text,e.mediaUrl,e.replyToId]),f=M(a,"sends");if(f&&f.requestHash!==i)throw I("channel_send_conflict");let s=h.get(a);if(s){if(s.requestHash!==i)throw I("channel_send_conflict");return s.promise}let T=(async()=>{let _=f?.payload;if(!_){let A=e.mediaUrl?[await b(e.accountId,o,e.mediaUrl,e)]:[];_={sourceMessageId:`openclaw:${a}`,sessionId:o,content:e.text||"",inputParts:A,...e.replyToId?{replyToMessageId:e.replyToId}:{}},E(a,{requestHash:i,payload:_},"sends")}return await e.onPlatformSendDispatch?.(),e.assertDirectAdapterHandoff?.(),e.signal?.throwIfAborted(),{channel:"orcha",messageId:(await g(e.accountId,"/messages",_,{cfg:e.cfg,signal:e.signal})).messageId,chatId:o}})().finally(()=>h.delete(a));return h.set(a,{requestHash:i,promise:T}),T}t.registerChannel({plugin:{id:"orcha",meta:{id:"orcha",label:"Orcha",selectionLabel:"Orcha",docsPath:"/channels/orcha",blurb:"Enterprise people and Agent conversations"},capabilities:{chatTypes:["direct","group"],media:!0},config:{listAccountIds:e=>Object.keys(e?.channels?.orcha?.accounts||{}),inspectAccount:(e,o)=>{let n=e?.channels?.orcha?.accounts?.[o];return{enabled:!!(n&&n.enabled!==!1),configured:!!(n?.serviceToken&&n?.agentId),tokenStatus:n?.serviceToken?"available":"missing"}},resolveAccount:(e,o)=>c(o,e),isEnabled:e=>e.enabled!==!1,isConfigured:e=>!!(e.serviceToken&&e.agentId)},outbound:{deliveryMode:"direct",textChunkLimit:1e5,sendText:N,sendMedia:N}}});async function D(e){let{accountId:o,grantId:n,externalInvocationId:a}=e;c(o);let i=await g(o,"/runs",{grantId:n,externalInvocationId:a,input:e.input||{}}),f=i.agentRunId;if(["completed","failed","cancelled","expired"].includes(i.status))return i;let s;do s=await g(o,`/runs/${f}/claim`,{}),s.attemptId||await ge(Math.max(1,s.retryAfterSeconds||2)*1e3);while(!s.attemptId);let T=`agent:${c(o).agentId}:orcha:${o}:${f}`,_,w=!1,A=setInterval(async()=>{if(!w){w=!0;try{let y=await g(o,`/runs/${f}/heartbeat`,{attemptId:s.attemptId});r.active(T)&&await r.bind({runId:f,sessionKey:T,agentCode:c(o).agentId,expiresAt:s.expiresAt,mcpServer:y.mcpServer},{refresh:!0})}catch(y){_=y,m.get(f)?.controller.abort(y),r.release(T)}finally{w=!1}}},Math.max(1,s.heartbeatIntervalSeconds)*1e3),C,P;try{let y;try{y=await S({runId:f,agentCode:c(o).agentId,delivery:s.delivery,prompt:[{type:"text",text:JSON.stringify({task:s.prompt,eventInput:s.input})}],mcpServer:s.mcpServer,expiresAt:s.expiresAt,attachOnly:s.recovery})}catch(j){P=j}if(_)throw _;C=P?{attemptId:s.attemptId,result:P.code||"channel_host_failed",artifacts:[],status:"failed"}:{attemptId:s.attemptId,result:y.content,artifacts:y.inputParts||[],status:"completed"};let $=await g(o,`/runs/${f}/complete`,C);if(P)throw P;return $}finally{clearInterval(A),r.release(T)}}for(let[e,o]of[["deliveries",S],["background",D]])t.registerHttpRoute({path:`/plugins/orcha-runtime/${e}`,auth:"gateway",match:"exact",async handler(n,a){try{if(!["POST","PATCH","DELETE"].includes(n.method))throw I("method_not_allowed",405);let i=await R(n);if(await p(),n.method==="DELETE"){let s=m.get(i.runId);s?.controller.abort(I("RUNTIME_OPERATION_CANCELLED")),a.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify({cancelled:!!s}));return}if(n.method==="PATCH"&&e!=="deliveries")throw I("method_not_allowed",405);let f=await o(i,n.method==="PATCH");await p(),a.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify(f))}catch(i){a.writableEnded||a.writeHead(i.status||500,{"content-type":"application/json"}).end(JSON.stringify({error:i.code||i.message}))}}})}function te(t,r,p){return{id:"orcha-runtime",name:"Orcha Channel and authorized tools",register(d){let u=Z(d);d.registerHttpRoute({path:"/plugins/orcha-runtime/mcp-bindings",auth:"gateway",match:"exact",async handler(m,h){let l=(c,g)=>{h.writeHead(c,{"content-type":"application/json"}),h.end(JSON.stringify(g))};try{if(m.method==="GET"){l(200,{ready:!0});return}if(!["PUT","DELETE"].includes(m.method)){l(405,{error:"method_not_allowed"});return}let c=await R(m);if(await t(),typeof c.runId!="string"||!c.runId||typeof c.sessionKey!="string"||!c.sessionKey){l(422,{error:"invalid_binding_identity"});return}let g=u.active(c.sessionKey);if(m.headers["if-match"]&&m.headers["if-match"]!==c.runId){l(409,{error:"binding_run_conflict"});return}if(g&&g.runId!==c.runId){l(409,{error:"session_already_bound"});return}m.method==="DELETE"?u.release(c.sessionKey):await u.bind(c,{refresh:!!m.headers["if-match"]}),l(200,{[m.method==="DELETE"?"released":"bound"]:!0})}catch(c){h.writableEnded||l(c.status||422,{error:c.message})}}}),ee(d,u,t,r,p)}}}import{isFastModeAutoProgressPayload as we,isReasoningReplyPayload as ye,isReplyPayloadNonTerminalToolErrorWarning as Ie,isReplyPayloadTtsSupplement as _e}from"openclaw/plugin-sdk/reply-payload";function re(t){return!ye(t)&&!t.isCommentary&&!t.isCompactionNotice&&!t.isFallbackNotice&&!t.isStatusNotice&&!we(t)&&!Ie(t)&&!_e(t)}var ze=te(async()=>{await Oe()?.revalidate?.()},re,Te);export{ze as default};
|
|
@@ -1,14 +1,75 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "orcha-runtime",
|
|
3
|
-
"name": "Orcha
|
|
4
|
-
"description": "
|
|
5
|
-
"categories": [
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
"name": "Orcha Channel and authorized tools",
|
|
4
|
+
"description": "Enterprise IM Channel, proactive messages and task-scoped Orcha tools",
|
|
5
|
+
"categories": [
|
|
6
|
+
"developer-tools"
|
|
7
|
+
],
|
|
8
|
+
"contracts": {
|
|
9
|
+
"tools": [
|
|
10
|
+
"orcha_find_capabilities_and_skills",
|
|
11
|
+
"orcha_describe_capability",
|
|
12
|
+
"orcha_inspect_result",
|
|
13
|
+
"orcha_execute_capability",
|
|
14
|
+
"orcha_search_orcha_docs"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"activation": {
|
|
18
|
+
"onStartup": true
|
|
19
|
+
},
|
|
8
20
|
"configSchema": {
|
|
9
21
|
"type": "object",
|
|
10
22
|
"additionalProperties": false,
|
|
11
|
-
"required": [
|
|
12
|
-
|
|
23
|
+
"required": [
|
|
24
|
+
"allowedOrchaMcpUrl"
|
|
25
|
+
],
|
|
26
|
+
"properties": {
|
|
27
|
+
"allowedOrchaMcpUrl": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"minLength": 1
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"channels": [
|
|
34
|
+
"orcha"
|
|
35
|
+
],
|
|
36
|
+
"channelConfigs": {
|
|
37
|
+
"orcha": {
|
|
38
|
+
"schema": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"additionalProperties": false,
|
|
41
|
+
"properties": {
|
|
42
|
+
"accounts": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"additionalProperties": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"additionalProperties": false,
|
|
47
|
+
"required": [
|
|
48
|
+
"agentId",
|
|
49
|
+
"serviceToken"
|
|
50
|
+
],
|
|
51
|
+
"properties": {
|
|
52
|
+
"agentId": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"minLength": 1
|
|
55
|
+
},
|
|
56
|
+
"serviceToken": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"minLength": 1
|
|
59
|
+
},
|
|
60
|
+
"enabled": {
|
|
61
|
+
"type": "boolean"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"uiHints": {
|
|
69
|
+
"accounts.*.serviceToken": {
|
|
70
|
+
"sensitive": true
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
13
74
|
}
|
|
14
75
|
}
|