@orcha-ai/runtime-bridge 0.1.17 → 0.1.19

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
@@ -156,6 +156,12 @@ streaming text for interactive chat. Set `"dispatchFinalTextOnly": false` on a
156
156
  target to opt out for task execution, or `"finalTextOnly": true` as the target
157
157
  default when a request does not provide its own text-streaming policy.
158
158
 
159
+ For ACP-compatible targets (`stdio-acp`, `acp`, and `openclaw`), task dispatch
160
+ is treated as one-shot execution and releases the runtime process after each
161
+ completed prompt by default. Direct `sessions/prompt` requests keep the normal
162
+ target lifecycle. Set `"dispatchReleaseAfterPrompt": false` on a target only
163
+ when task dispatch should intentionally reuse the same ACP process.
164
+
159
165
  ACP-compatible targets receive `mcpServers` in `session/new`. When omitted in
160
166
  target config, the bridge sends an empty array.
161
167
 
@@ -171,6 +177,11 @@ stricter defaults for this target type:
171
177
  process after each prompt.
172
178
  - `sessionIdleTtlMs`: defaults to `60000` for OpenClaw.
173
179
 
180
+ When Orcha Core sends `runtimeMaxSessions` with a prompt or dispatch request,
181
+ the bridge uses that value from the agent concurrency setting to raise the
182
+ target session cap for that request and to limit simultaneous sessions for the
183
+ same agent.
184
+
174
185
  Global lifecycle knobs:
175
186
 
176
187
  ```bash
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
- import{spawn as ss}from"node:child_process";import{closeSync as is,existsSync as ze,mkdirSync as os,openSync as as,readFileSync as Pt,rmSync as cs,statSync as Pe,writeFileSync as Ge}from"node:fs";import{dirname as us,resolve as $t}from"node:path";import{fileURLToPath as ls}from"node:url";import{randomUUID as ot}from"node:crypto";var v="0.1.16";function j(){return new Date().toISOString()}function S(e,t=2){return String(e).padStart(t,"0")}function Kt(e){let t=e>=0?"+":"-",n=Math.abs(e);return`${t}${S(Math.floor(n/60))}:${S(n%60)}`}function Ve(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${S(e.getMonth()+1)}-${S(e.getDate())}`,`T${S(e.getHours())}:${S(e.getMinutes())}:${S(e.getSeconds())}.${S(e.getMilliseconds(),3)}`,Kt(t)].join("")}function Ye(e,t){let n=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"}),r={};for(let s of n.formatToParts(e))s.type!=="literal"&&(r[s.type]=Number(s.value));return r}function Ze(e,t){let n=Ye(e,t),r=Date.UTC(n.year,n.month-1,n.day,n.hour,n.minute,n.second,e.getMilliseconds()),s=Math.round((r-e.getTime())/6e4);return[`${n.year}-${S(n.month)}-${S(n.day)}`,`T${S(n.hour)}:${S(n.minute)}:${S(n.second)}.${S(e.getMilliseconds(),3)}`,Kt(s)].join("")}function Qe(e=new Date){let t=a(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return Ze(e,t)}catch{return Ve(e)}}function c(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function a(e){return String(e??"").trim()}function _(e,t){let n=Number.parseInt(String(e??""),10);return Number.isFinite(n)?n:t}function w(e){return Array.isArray(e)?e.map(String):[]}var tn="[redacted]",en=/(authorization|api[_-]?key|credential|password|secret|token)/i;function G(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 r={name:e.name,message:e.message};e.stack&&(r.stack=e.stack);for(let s of Object.keys(e))r[s]=G(e[s],t);return t.delete(e),r}if(t.has(e))return"[circular]";if(t.add(e),Array.isArray(e)){let r=e.map(s=>G(s,t));return t.delete(e),r}let n={};for(let[r,s]of Object.entries(e))n[r]=en.test(r)?tn:G(s,t);return t.delete(e),n}function Jt(e,t=4e3){let n=JSON.stringify(G(e))??String(e);return!Number.isFinite(t)||n.length<=t?n:`${n.slice(0,t)}...`}function p(e,t,n,r={}){let s={ts:Qe(),level:e,module:t,msg:n,...c(r)?G(r):{}};console.error(JSON.stringify(s))}function X(e){return Array.isArray(e)?e.map(t=>c(t)?t.type==="text"?a(t.text):t.type==="file"?a(t.uri):t.type==="image"?a(t.uri):"":"").filter(Boolean).join(`
3
- `):""}var V=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,n){let r=X(t.prompt);return n({sessionId:t.sessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:r?`Echo runtime received: ${r}`:"Echo runtime received an empty prompt."}}}),{stopReason:"end_turn"}}async sessionCancel(){return{ok:!0}}};import{spawn as nn}from"node:child_process";var q="2.0",rn=3e4;function sn(e){return{code:Number.isInteger(e?.code)?e.code:-32e3,message:a(e?.message)||String(e),data:c(e?.data)?e.data:void 0}}function on(e){if(!c(e))return new Error(String(e||"runtime error"));let t=a(e.message)||"runtime error",n="data"in e?Jt(e.data,4e3):"",r=new Error(n?`${t}; data=${n}`:t);return r.rpcCode=e.code,r.data=e.data,r}function an(e){return c(e)&&"id"in e&&!("method"in e)}function cn(e){return c(e)&&typeof e.method=="string"&&"id"in e}function un(e){return c(e)&&typeof e.method=="string"&&!("id"in e)}var Y=class{constructor({command:t,args:n=[],cwd:r,env:s,label:i,framing:o="line",detached:u=!0}){this.command=t,this.args=Array.isArray(n)?n.map(String):[],this.cwd=r||process.cwd(),this.env={...process.env,...c(s)?s:{}},this.label=i||t,this.framing=o==="content-length"?"content-length":"line",this.detached=u!==!1,this.child=null,this.exited=!1,this.exitCode=null,this.exitSignal=null,this.stopPromise=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:n={}}={}){this.child&&!this.exited||(this.exited=!1,this.exitCode=null,this.exitSignal=null,this.child=nn(this.command,this.args,{cwd:this.cwd,env:this.env,stdio:["pipe","pipe","pipe"],detached:this.detached}),this.child.stdout.on("data",r=>this.onStdout(r)),this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",r=>{let s=r.trimEnd();s&&p("debug","runtime.stderr","runtime stderr",{target:this.label,text:s})}),this.child.on("exit",(r,s)=>this.handleExit(r,s)),this.child.on("error",r=>this.rejectAll(r)),t&&await this.call("initialize",{protocolVersion:1,clientCapabilities:{},...n}).catch(r=>{throw Object.assign(new Error(`runtime initialize failed: ${r.message}`),{code:"RUNTIME_INITIALIZE_FAILED"})}))}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 n=this.lineBuffer.split(/\r?\n/);this.lineBuffer=n.pop()||"";for(let r of n){let s=r.trim();s&&this.dispatchRaw(s)}}onContentLengthData(t){for(this.headerBuffer=Buffer.concat([this.headerBuffer,t]);this.headerBuffer.length>0;){let n=this.headerBuffer.indexOf(`\r
2
+ import{spawn as us}from"node:child_process";import{closeSync as ls,existsSync as Je,mkdirSync as ds,openSync as fs,readFileSync as $t,rmSync as ps,statSync as ve,writeFileSync as We}from"node:fs";import{dirname as ms,resolve as Bt}from"node:path";import{fileURLToPath as hs}from"node:url";import{randomUUID as at}from"node:crypto";var v="0.1.19";function j(){return new Date().toISOString()}function x(e,t=2){return String(e).padStart(t,"0")}function Xt(e){let t=e>=0?"+":"-",n=Math.abs(e);return`${t}${x(Math.floor(n/60))}:${x(n%60)}`}function en(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${x(e.getMonth()+1)}-${x(e.getDate())}`,`T${x(e.getHours())}:${x(e.getMinutes())}:${x(e.getSeconds())}.${x(e.getMilliseconds(),3)}`,Xt(t)].join("")}function nn(e,t){let n=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"}),r={};for(let s of n.formatToParts(e))s.type!=="literal"&&(r[s.type]=Number(s.value));return r}function rn(e,t){let n=nn(e,t),r=Date.UTC(n.year,n.month-1,n.day,n.hour,n.minute,n.second,e.getMilliseconds()),s=Math.round((r-e.getTime())/6e4);return[`${n.year}-${x(n.month)}-${x(n.day)}`,`T${x(n.hour)}:${x(n.minute)}:${x(n.second)}.${x(e.getMilliseconds(),3)}`,Xt(s)].join("")}function sn(e=new Date){let t=a(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return rn(e,t)}catch{return en(e)}}function c(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function a(e){return String(e??"").trim()}function _(e,t){let n=Number.parseInt(String(e??""),10);return Number.isFinite(n)?n:t}function R(e){return Array.isArray(e)?e.map(String):[]}var on="[redacted]",an=/(authorization|api[_-]?key|credential|password|secret|token)/i;function G(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 r={name:e.name,message:e.message};e.stack&&(r.stack=e.stack);for(let s of Object.keys(e))r[s]=G(e[s],t);return t.delete(e),r}if(t.has(e))return"[circular]";if(t.add(e),Array.isArray(e)){let r=e.map(s=>G(s,t));return t.delete(e),r}let n={};for(let[r,s]of Object.entries(e))n[r]=an.test(r)?on:G(s,t);return t.delete(e),n}function Vt(e,t=4e3){let n=JSON.stringify(G(e))??String(e);return!Number.isFinite(t)||n.length<=t?n:`${n.slice(0,t)}...`}function p(e,t,n,r={}){let s={ts:sn(),level:e,module:t,msg:n,...c(r)?G(r):{}};console.error(JSON.stringify(s))}function V(e){return Array.isArray(e)?e.map(t=>c(t)?t.type==="text"?a(t.text):t.type==="file"?a(t.uri):t.type==="image"?a(t.uri):"":"").filter(Boolean).join(`
3
+ `):""}var Y=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,n){let r=V(t.prompt);return n({sessionId:t.sessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:r?`Echo runtime received: ${r}`:"Echo runtime received an empty prompt."}}}),{stopReason:"end_turn"}}async sessionCancel(){return{ok:!0}}};import{spawn as cn}from"node:child_process";var K="2.0",un=3e4;function ln(e){return{code:Number.isInteger(e?.code)?e.code:-32e3,message:a(e?.message)||String(e),data:c(e?.data)?e.data:void 0}}function dn(e){if(!c(e))return new Error(String(e||"runtime error"));let t=a(e.message)||"runtime error",n="data"in e?Vt(e.data,4e3):"",r=new Error(n?`${t}; data=${n}`:t);return r.rpcCode=e.code,r.data=e.data,r}function fn(e){return c(e)&&"id"in e&&!("method"in e)}function pn(e){return c(e)&&typeof e.method=="string"&&"id"in e}function mn(e){return c(e)&&typeof e.method=="string"&&!("id"in e)}var Z=class{constructor({command:t,args:n=[],cwd:r,env:s,label:i,framing:o="line",detached:u=!0}){this.command=t,this.args=Array.isArray(n)?n.map(String):[],this.cwd=r||process.cwd(),this.env={...process.env,...c(s)?s:{}},this.label=i||t,this.framing=o==="content-length"?"content-length":"line",this.detached=u!==!1,this.child=null,this.exited=!1,this.exitCode=null,this.exitSignal=null,this.stopPromise=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:n={}}={}){this.child&&!this.exited||(this.exited=!1,this.exitCode=null,this.exitSignal=null,this.child=cn(this.command,this.args,{cwd:this.cwd,env:this.env,stdio:["pipe","pipe","pipe"],detached:this.detached}),this.child.stdout.on("data",r=>this.onStdout(r)),this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",r=>{let s=r.trimEnd();s&&p("debug","runtime.stderr","runtime stderr",{target:this.label,text:s})}),this.child.on("exit",(r,s)=>this.handleExit(r,s)),this.child.on("error",r=>this.rejectAll(r)),t&&await this.call("initialize",{protocolVersion:1,clientCapabilities:{},...n}).catch(r=>{throw Object.assign(new Error(`runtime initialize failed: ${r.message}`),{code:"RUNTIME_INITIALIZE_FAILED"})}))}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 n=this.lineBuffer.split(/\r?\n/);this.lineBuffer=n.pop()||"";for(let r of n){let s=r.trim();s&&this.dispatchRaw(s)}}onContentLengthData(t){for(this.headerBuffer=Buffer.concat([this.headerBuffer,t]);this.headerBuffer.length>0;){let n=this.headerBuffer.indexOf(`\r
4
4
  \r
5
- `);if(n<0)return;let s=this.headerBuffer.subarray(0,n).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){p("warn","runtime.protocol","missing Content-Length header",{target:this.label}),this.headerBuffer=Buffer.alloc(0);return}let i=Number.parseInt(s[1],10),o=n+4,u=o+i;if(this.headerBuffer.length<u)return;let l=this.headerBuffer.subarray(o,u).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(u),this.dispatchRaw(l)}}dispatchRaw(t){let n;try{n=JSON.parse(t)}catch(r){p("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(r)});return}this.dispatch(n)}dispatch(t){if(an(t)){this.resolveResponse(t);return}if(cn(t)){this.handleRequest(t);return}un(t)&&this.handleNotification(t)}resolveResponse(t){let n=String(t.id),r=this.pending.get(n);r&&(clearTimeout(r.timer),this.pending.delete(n),t.error?(p("warn","runtime.protocol","runtime rpc error",{target:this.label,method:r.method,requestId:n,error:t.error}),r.reject(on(t.error))):r.resolve(t.result))}async handleRequest(t){let n=this.requestHandlers.get(t.method);if(!n){this.writeFrame({jsonrpc:q,id:t.id,error:{code:-32601,message:`method not found: ${t.method}`}});return}try{let r=await n(c(t.params)?t.params:{},t);this.writeFrame({jsonrpc:q,id:t.id,result:r??{}})}catch(r){this.writeFrame({jsonrpc:q,id:t.id,error:sn(r)})}}handleNotification(t){let n=this.notificationHandlers.get(t.method);if(n)for(let r of n)r(c(t.params)?t.params:{},t)}call(t,n={},r=rn){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:q,id:s,method:t,params:n};return new Promise((o,u)=>{let l=setTimeout(()=>{this.pending.delete(s),u(new Error(`${t} timed out after ${r}ms`))},r);this.pending.set(s,{resolve:o,reject:u,timer:l,method:t}),this.writeFrame(i,d=>{d&&(clearTimeout(l),this.pending.delete(s),u(d))})})}notify(t,n={}){this.writeFrame({jsonrpc:q,method:t,params:n})}writeFrame(t,n){if(!this.child?.stdin||this.exited){n?.(new Error("runtime process is not running"));return}let r=JSON.stringify(t),s=this.framing==="content-length"?`Content-Length: ${Buffer.byteLength(r,"utf8")}\r
5
+ `);if(n<0)return;let s=this.headerBuffer.subarray(0,n).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){p("warn","runtime.protocol","missing Content-Length header",{target:this.label}),this.headerBuffer=Buffer.alloc(0);return}let i=Number.parseInt(s[1],10),o=n+4,u=o+i;if(this.headerBuffer.length<u)return;let l=this.headerBuffer.subarray(o,u).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(u),this.dispatchRaw(l)}}dispatchRaw(t){let n;try{n=JSON.parse(t)}catch(r){p("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(r)});return}this.dispatch(n)}dispatch(t){if(fn(t)){this.resolveResponse(t);return}if(pn(t)){this.handleRequest(t);return}mn(t)&&this.handleNotification(t)}resolveResponse(t){let n=String(t.id),r=this.pending.get(n);r&&(clearTimeout(r.timer),this.pending.delete(n),t.error?(p("warn","runtime.protocol","runtime rpc error",{target:this.label,method:r.method,requestId:n,error:t.error}),r.reject(dn(t.error))):r.resolve(t.result))}async handleRequest(t){let n=this.requestHandlers.get(t.method);if(!n){this.writeFrame({jsonrpc:K,id:t.id,error:{code:-32601,message:`method not found: ${t.method}`}});return}try{let r=await n(c(t.params)?t.params:{},t);this.writeFrame({jsonrpc:K,id:t.id,result:r??{}})}catch(r){this.writeFrame({jsonrpc:K,id:t.id,error:ln(r)})}}handleNotification(t){let n=this.notificationHandlers.get(t.method);if(n)for(let r of n)r(c(t.params)?t.params:{},t)}call(t,n={},r=un){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:K,id:s,method:t,params:n};return new Promise((o,u)=>{let l=setTimeout(()=>{this.pending.delete(s),u(new Error(`${t} timed out after ${r}ms`))},r);this.pending.set(s,{resolve:o,reject:u,timer:l,method:t}),this.writeFrame(i,d=>{d&&(clearTimeout(l),this.pending.delete(s),u(d))})})}notify(t,n={}){this.writeFrame({jsonrpc:K,method:t,params:n})}writeFrame(t,n){if(!this.child?.stdin||this.exited){n?.(new Error("runtime process is not running"));return}let r=JSON.stringify(t),s=this.framing==="content-length"?`Content-Length: ${Buffer.byteLength(r,"utf8")}\r
6
6
  \r
7
7
  ${r}`:`${r}
8
- `;this.child.stdin.write(s,n)}onNotification(t,n){let r=this.notificationHandlers.get(t)||new Set;return r.add(n),this.notificationHandlers.set(t,r),()=>{r.delete(n),r.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,n){return this.requestHandlers.set(t,n),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let n of this.pending.values())clearTimeout(n.timer),n.reject(t);this.pending.clear()}handleExit(t,n){this.exited=!0,this.exitCode=t,this.exitSignal=n,this.rejectAll(new Error(`runtime exited before response (${t}/${n})`));for(let r of this.exitHandlers)r(t,n)}async waitForExit(t=5e3){return!this.child||this.exited?!0:await new Promise(n=>{let r=setTimeout(()=>{s(),n(!1)},t);r.unref?.();let s=()=>{clearTimeout(r),this.exitHandlers.delete(i)},i=()=>{s(),n(!0)};this.exitHandlers.add(i),this.exited&&i()})}signal(t){if(!this.child||this.exited)return!1;let n=this.child.pid;if(!n)return!1;try{return this.detached&&process.platform!=="win32"?process.kill(-n,t):this.child.kill(t),!0}catch(r){if(r?.code==="ESRCH")return this.exited=!0,!1;try{return this.child.kill(t),!0}catch(s){return s?.code!=="ESRCH"&&p("warn","runtime","runtime signal failed",{target:this.label,pid:n,signal:t,error:String(s)}),!1}}}async stop(t="stop",{termTimeoutMs:n=5e3,killTimeoutMs:r=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;p("info","runtime","stopping runtime",{target:this.label,reason:t,pid:s}),this.rejectAll(new Error(`runtime stopped: ${t}`)),this.signal("SIGTERM"),!await this.waitForExit(n)&&this.child&&!this.exited&&(p("warn","runtime","runtime did not exit after SIGTERM; force killing",{target:this.label,reason:t,pid:s}),this.signal("SIGKILL"),await this.waitForExit(r))})();try{await this.stopPromise}finally{this.stopPromise=null}}}};import{randomUUID as Vt}from"node:crypto";import{existsSync as ln,readFileSync as dn,realpathSync as Wt,statSync as fn}from"node:fs";import{basename as Yt,extname as Zt,isAbsolute as pn,relative as mn}from"node:path";var hn=25*1024*1024;function Qt(e,t=""){let n=a(t);if(n)return n;let r=Zt(a(e)).toLowerCase();return r===".jpg"||r===".jpeg"?"image/jpeg":r===".webp"?"image/webp":r===".gif"?"image/gif":"image/png"}function te(e,t){let n=typeof e=="string"?e.trim():"";return!n||n==="<omitted>"?"":n.startsWith("data:")?n:`data:${t};base64,${n.replace(/\s+/g,"")}`}function Z(e){if(Array.isArray(e))return e.map(a).filter(Boolean);let t=a(e);return t?[t]:[]}function gn(e,t){let n=mn(t,e);return n===""||!!n&&!n.startsWith("..")&&!pn(n)}function _n(e,t){let n=a(e);if(!n||!ln(n))return"";try{let r=Wt(n);for(let s of t)try{let i=Wt(s);if(gn(r,i))return r}catch{}}catch{return""}return""}function Tt(e,t,n={}){let r=a(e);return!r||r.startsWith("data:")||/^https?:\/\//i.test(r)?r:yn(r,t,n)}function yn(e,t,n={}){let r=[...Z(n.trustedFileRoots),...Z(n.trustedFileRoot),...Z(n.artifactRoots),...Z(n.artifactRoot)],s=_n(e,r);if(!s)return"";try{let i=fn(s);return!i.isFile()||i.size<=0||i.size>hn?"":`data:${t};base64,${dn(s).toString("base64")}`}catch{return""}}function y(...e){for(let t of e){let n=a(t);if(n)return n}return""}function Tn(e,t,n,r){let s=n.toLowerCase();if(s==="image"||s==="picture")return!0;let i=y(r,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=Zt(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function Rt(e,t={}){let{source:n="runtime_image_generation_event"}=t;if(!c(e))return null;let r=c(e.payload)?e.payload:{},s=a(e.type),i=a(r.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let o=y(r.call_id,r.id),u=y(r.saved_path,r.savedPath),l=y(r.revised_prompt,r.revisedPrompt),d=Qt(u,r.mimeType||r.mime_type),f=te(r.result,d)||Tt(u,d,t);if(!f)return null;let m=f.startsWith("data:")?f:"",h=u?Yt(u):`${o||Vt()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:h||"Generated image",summary:l||"Generated image",content:{prompt:l||void 0,dataUrl:m||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:m||void 0,previewUrl:f,fileUrl:f,metadata:{source:n,eventType:i,callId:o||void 0,savedPath:u||void 0,filename:h,mimeType:d,revisedPrompt:l||void 0}}}function Sn(e){let t=c(e)?e:{},n=[];for(let r of["_artifacts","artifacts"]){let s=t[r];Array.isArray(s)&&n.push(...s)}for(let r of["_artifact","artifact"]){let s=t[r];c(s)&&n.push(s)}return n}function Rn(e,t={}){let{source:n="runtime_artifact"}=t,r=c(e)?e:{};if(!Object.keys(r).length)return null;let s=c(r.content)?{...r.content}:{},i=c(r.metadata)?{...r.metadata}:{},o=y(r.saved_path,r.savedPath,s.saved_path,s.savedPath,i.savedPath),u=y(r.mimeType,r.mime_type,s.mimeType,s.mime_type,i.mimeType),l=y(r.artifactType,r.artifact_type,r.type,r.kind,s.type,o?"image":"file"),d=Tn(r,s,l,o),f=d?Qt(o,u):u;if(d){let U=y(r.dataUrl,s.dataUrl),I=U.startsWith("data:")?U:"",M=y(r.imageUrl,r.previewUrl,r.fileUrl,r.downloadUrl,r.url,r.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),g=te(r.result??s.result,f)||I||Tt(o,f,t)||Tt(M,f,t);g&&(g.startsWith("data:")&&(s.dataUrl||=g),s.imageUrl||=g,s.previewUrl||=g,s.fileUrl||=g,f&&(s.mimeType||=f))}for(let[U,I]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let M=r[U];M!=null&&M!==""&&!(I in s)&&(s[I]=M)}let m=y(r.fileUrl,r.downloadUrl,r.imageUrl,r.dataUrl,r.url,r.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),h=y(r.previewUrl,r.imageUrl,r.dataUrl,r.url,r.fileUrl,r.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),R=y(r.dataUrl,s.dataUrl,m.startsWith("data:")?m:"",h.startsWith("data:")?h:""),x=y(r.filename,i.filename,o?Yt(o):""),F=y(r.fieldKey,r.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...r,artifactType:l,type:r.type||l,fieldKey:F,title:y(r.title,x,"Runtime artifact"),summary:y(r.summary,s.prompt,r.title,x,"Runtime artifact"),content:s,dataUrl:R||void 0,fileUrl:m||void 0,previewUrl:h||void 0,metadata:{...i,source:y(i.source,n),savedPath:o||i.savedPath,filename:x||i.filename,mimeType:f||i.mimeType}}}function Q(e,t){if(!t||!e)return;let n=c(t.metadata)?t.metadata:{},r=y(n.savedPath,n.callId,t.previewUrl,t.fileUrl)||Vt(),s=e.get(r);if(!s){e.set(r,t);return}s.content={...c(s.content)?s.content:{},...c(t.content)?t.content:{}},s.metadata={...c(s.metadata)?s.metadata:{},...n},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 St(e,t,n={}){for(let r of Sn(e))Q(t,Rn(r,n))}function wt(e){if(!c(e)||!c(e.payload))return c(e)?e:{value:e};let t=a(e.payload.type);if(t!=="image_generation_end"&&t!=="image_generation_call")return e;let n={...e.payload};return typeof n.result=="string"&&n.result&&(n.result="<omitted>",n.resultLength=e.payload.result.length),{...e,payload:n}}function Xt(e,t,n){if(!c(e))return e;let r=c(e.event)?e.event:null;return r?(Q(t,Rt(r,n)),{...e,event:wt(r)}):e}function ee(e,t,n={}){if(!c(e))return e;St(e,t,n);let r=Xt(e,t,n),s=c(r.update)?Xt(r.update,t,n):null;return s&&s!==r.update&&(r={...r,update:s}),r}function ne(e,t,n={}){let r=c(e)?{...e}:{};St(r,t,n),St(c(r.output)?r.output:{},t,n);let s=[...t?.values?.()||[]];return s.length&&(r._artifacts=s),delete r.artifacts,r}var B=class{constructor(t,n,r={},s={}){this.agent=t,this.target=n,this.callbacks=r,this.options=s,this.proc=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`);this.proc=new Y({command:t,args:w(this.target.args),cwd:a(this.target.cwd)||this.agent.workspace||process.cwd(),env:c(this.target.env)?this.target.env:{},label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:a(this.target.framing||"line")}),this.proc.onRequest("session/request_permission",n=>this.handlePermissionRequest(n)),this.proc.onRequest("session/requestPermission",n=>this.handlePermissionRequest(n)),await this.proc.start({initialize:this.target.initialize!==!1,initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:v},...c(this.target.initializeParams)?this.target.initializeParams:{}}})}async sessionNew(t={}){await this.ensureStarted();let n=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return this.proc.call("session/new",{...t,mcpServers:n})}async sessionPrompt(t,n){await this.ensureStarted();let r=a(t.sessionId),s=new Map,i=this.artifactOptions(),o=this.proc.onNotification("session/update",l=>{let d=a(l.sessionId);(!d||d===r)&&n(ee(l,s,i))}),u=async l=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:r,request:l,emitUpdate:n})||{outcome:"denied",reason:"permission handler is not configured"};r&&this.permissionHandlers.set(r,u),this.permissionHandlers.set("*",u);try{let l=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return ne(l,s,i)}finally{o(),r&&this.permissionHandlers.delete(r),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let n=a(t.sessionId),r=this.permissionHandlers.get(n)||this.permissionHandlers.get("*");return r?r(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=c(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[a(this.target.artifactRoot),a(this.target.artifactDir),a(this.target.runtimeArtifactRoot),a(t.ORCHA_RUNTIME_ARTIFACT_DIR),...w(this.target.trustedArtifactRoots),...w(this.target.trustedFileRoots),...w(this.target.artifactRoots),...w(this.target.artifactFileRoots)].filter(Boolean)}}async stop(t){await this.proc?.stop(t)}};function wn(e){let t=c(e.metadata)?e.metadata:{};return a(t.agentCode)}function xn(e,t){let n=wn(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var tt=class extends B{constructor(t,n,r,s={},i={}){let o=a(r).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",u=a(n.command)||"openclaw",l=Array.isArray(n.args)?n.args.map(String):[],d=l.length>0?l:["acp","--session",xn(t,o)];super(t,{...n,command:u,args:d},s,i)}};import{spawn as En}from"node:child_process";import{randomUUID as K}from"node:crypto";import{existsSync as ae,mkdirSync as In,readdirSync as ce,readFileSync as ue,realpathSync as st,rmSync as On,rmdirSync as Cn,statSync as An,unlinkSync as Un}from"node:fs";import{homedir as Mn,tmpdir as le}from"node:os";import{basename as de,dirname as Nn,join as O,resolve as re}from"node:path";var bn=36e5,kn=5e3,Ln=2*60*1e3,Pn=2*60*1e3,Dn=12,Fn=1e3,$n=1500,et=24*60*60*1e3,se=new Set(["final_answer","final","complete","completed","done"]);function nt(e,t){try{e.kill(t)}catch{}}function E(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>E(t)).join("");if(!c(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let n=E(e[t]);if(n)return n}return""}function fe(e){if(!c(e))return"";let t=c(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 E(t.content)||E(t.message);let n=E(e.delta)||E(e.text)||E(e.content);if(n)return n;let r=c(e.item)?e.item:{};return a(r.role)==="assistant"||a(r.type)==="message"?E(r.content)||E(r.text)||E(r.message):""}function pe(e,t={}){return Rt(e,{source:"codex_cli_image_generation",...t})}function me(e,t){Q(e.artifacts,t)}function he(e){return wt(e)}function ge(e){if(!c(e))return!1;let t=c(e.payload)?e.payload:{},n=a(e.type),r=a(t.type);if(n==="event_msg"&&r==="task_complete")return!0;let s=a(t.phase||t.status||t.stage).toLowerCase();return n==="event_msg"&&r==="agent_message"||n==="response_item"&&r==="message"&&a(t.role)==="assistant"?se.has(s):!1}function Hn(e,t,n){return n.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:n.captureLastMessage===!0?!0:de(e)==="codex"}function vn(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:de(e)==="codex"}function _e(e){return Math.max(20,_(e.codexTranscriptPollMs||e.transcriptPollMs,Fn))}function Bn(e){return Math.max(0,_(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,$n))}function zn(e){return e.codexTranscriptStreaming===!0||e.streamCodexTranscript===!0}function Gn(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 jn(e){let t=c(e?.metadata)?e.metadata:{},n=c(t._runtimeBridge)?t._runtimeBridge:{};for(let r of[n.finalTextOnly,n.finalOutputOnly]){let s=Gn(r);if(s!=null)return s}return null}function qn(e,t){let n=jn(e);return n??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function Kn(e,t){return!e.finalTextOnly||t}function Jn(e,t,n,r=new Set){return{target:e,promptText:t,startedAtMs:n,baselinePaths:r,matchedPath:"",disabled:!1,processedLines:new Map}}function Wn(e,t){let n=c(e.env)?e.env:{},r=a(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||n.ORCHA_RUNTIME_ARTIFACT_DIR)||O(le(),"orcha-runtime-artifacts"),s=a(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||K(),i=O(r,s),o=O(i,K());return In(o,{recursive:!0}),{root:o,realRoot:st(o),sessionRoot:i,realSessionRoot:st(i)}}function ye(e){return a(c(e)?e.root:e)}function ie(e){let t=ye(e),n=a(c(e)?e.sessionRoot:Nn(t)),r=a(c(e)?e.realSessionRoot:"");if(n)try{if(r&&st(n)!==r)return;Cn(n)}catch{}}function Xn(e,t={}){let n=ye(e),r=a(c(e)?e.realRoot:"");if(n){try{if(r&&st(n)!==r){p("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:n});return}}catch{ie(e);return}try{On(n,{recursive:!0,force:!0})}catch(s){p("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:n,error:String(s?.message||s)});return}ie(e)}}function Vn(e,t){return{trustedFileRoots:[t,...w(e.trustedArtifactRoots),...w(e.trustedFileRoots),...w(e.artifactRoots),...w(e.artifactFileRoots)].filter(Boolean)}}function Te(e){let t=a(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let n=c(e.env)?e.env:{},r=a(e.codexHome||n.CODEX_HOME||process.env.CODEX_HOME)||O(Mn(),".codex");return O(r,"sessions")}function Yn(e,t){let n=new Date(t),r=String(n.getFullYear()),s=String(n.getMonth()+1).padStart(2,"0"),i=String(n.getDate()).padStart(2,"0");return O(e,r,s,i)}function Se(e,t,n){let r=new Set;for(let s of[t-et,t,t+et,n-et,n,n+et])r.add(Yn(e,s));return[...r].filter(s=>ae(s))}function Zn(e,t,n){let r=Te(e),s=t-Ln,i=n+Pn,o=[];for(let u of Se(r,t,n)){let l=[];try{l=ce(u)}catch{continue}for(let d of l){if(!d.endsWith(".jsonl"))continue;let f=O(u,d);try{let m=An(f);if(!m.isFile()||m.mtimeMs<s||m.mtimeMs>i)continue;o.push({path:f,mtimeMs:m.mtimeMs})}catch{}}}return o.sort((u,l)=>l.mtimeMs-u.mtimeMs).slice(0,Dn)}function Qn(e,t,n=t){let r=Te(e),s=new Set;for(let i of Se(r,t,n)){let o=[];try{o=ce(i)}catch{continue}for(let u of o)u.endsWith(".jsonl")&&s.add(O(i,u))}return s}function xt(e,t,n=0){if(!(n>8||e===null||e===void 0)){if(typeof e=="string"){e&&t.push(e);return}if(Array.isArray(e)){for(let r of e)xt(r,t,n+1);return}if(c(e))for(let r of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])r in e&&xt(e[r],t,n+1)}}function Re(e){return a(e).replace(/\s+/g," ")}function tr(e){let t=Re(e);if(!t)return[];if(t.length<=200)return[t];let n=160,r=[0,Math.floor((t.length-n)/2),t.length-n],s=new Set,i=[];for(let o of r){let u=t.slice(Math.max(0,o),Math.max(0,o)+n).trim();u.length>=40&&!s.has(u)&&(s.add(u),i.push(u))}return i}function er(e,t){let n=tr(t);if(!n.length)return!1;let r=[];for(let i of e)xt(i,r);let s=Re(r.join(" "));return n.every(i=>s.includes(i))}function nr(e){return e.find(t=>c(t)&&a(t.type)==="session_meta"&&c(t.payload))||null}function rr(e){let t=c(e?.payload)?e.payload:{},n=a(e?.timestamp||t.timestamp),r=Date.parse(n);return Number.isFinite(r)?r:Number.NaN}function sr(e,t,n){if(!er(e,t.promptText))return!1;let r=nr(e);if(!r)return!1;let s=r.payload,i=a(s.originator),o=a(s.source);if(i!=="codex_exec"&&o!=="exec")return!1;let u=rr(r);if(!Number.isFinite(u)||u<t.startedAtMs-5e3||u>n+5e3)return!1;let l=a(t.target.cwd),d=a(s.cwd);return!(l&&d&&re(l)!==re(d))}function oe(e){try{return or(ue(e,"utf8"))}catch{return null}}function ir(e,t,n){if(!e||e.disabled)return null;if(e.matchedPath){let s=oe(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let r=[];for(let s of Zn(e.target,e.startedAtMs,n)){if(e.baselinePaths.has(s.path))continue;let i=oe(s.path);!i||!sr(i,e,n)||r.push({path:s.path,events:i})}return r.length!==1?(r.length>1&&(e.disabled=!0,p("warn","runtime.cli","codex transcript fallback disabled; multiple matching transcripts",{target:e.target.targetCode,sessionId:t,transcriptCount:r.length})),null):(e.matchedPath=r[0].path,p("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),r[0])}function or(e){let t=[];for(let n of e.split(/\r?\n/)){let r=n.trim();if(r)try{t.push(JSON.parse(r))}catch{}}return t}function ar(e){if(!c(e))return!1;let t=c(e.payload)?e.payload:{},n=a(e.type),r=a(t.type);return n==="event_msg"&&r==="image_generation_end"||n==="response_item"&&r==="image_generation_call"}function cr(e,t,n,r){let s=fe(e),i=ge(e),o=0,u=0;if(s&&i&&!t.emittedTexts.has(s)){let l=t.emittedTexts.size?`
8
+ `;this.child.stdin.write(s,n)}onNotification(t,n){let r=this.notificationHandlers.get(t)||new Set;return r.add(n),this.notificationHandlers.set(t,r),()=>{r.delete(n),r.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,n){return this.requestHandlers.set(t,n),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let n of this.pending.values())clearTimeout(n.timer),n.reject(t);this.pending.clear()}handleExit(t,n){this.exited=!0,this.exitCode=t,this.exitSignal=n,this.rejectAll(new Error(`runtime exited before response (${t}/${n})`));for(let r of this.exitHandlers)r(t,n)}async waitForExit(t=5e3){return!this.child||this.exited?!0:await new Promise(n=>{let r=setTimeout(()=>{s(),n(!1)},t);r.unref?.();let s=()=>{clearTimeout(r),this.exitHandlers.delete(i)},i=()=>{s(),n(!0)};this.exitHandlers.add(i),this.exited&&i()})}signal(t){if(!this.child||this.exited)return!1;let n=this.child.pid;if(!n)return!1;try{return this.detached&&process.platform!=="win32"?process.kill(-n,t):this.child.kill(t),!0}catch(r){if(r?.code==="ESRCH")return this.exited=!0,!1;try{return this.child.kill(t),!0}catch(s){return s?.code!=="ESRCH"&&p("warn","runtime","runtime signal failed",{target:this.label,pid:n,signal:t,error:String(s)}),!1}}}async stop(t="stop",{termTimeoutMs:n=5e3,killTimeoutMs:r=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;p("info","runtime","stopping runtime",{target:this.label,reason:t,pid:s}),this.rejectAll(new Error(`runtime stopped: ${t}`)),this.signal("SIGTERM"),!await this.waitForExit(n)&&this.child&&!this.exited&&(p("warn","runtime","runtime did not exit after SIGTERM; force killing",{target:this.label,reason:t,pid:s}),this.signal("SIGKILL"),await this.waitForExit(r))})();try{await this.stopPromise}finally{this.stopPromise=null}}}};import{randomUUID as Qt}from"node:crypto";import{existsSync as hn,readFileSync as gn,realpathSync as Yt,statSync as _n}from"node:fs";import{basename as te,extname as ee,isAbsolute as Tn,relative as yn}from"node:path";var Sn=25*1024*1024;function ne(e,t=""){let n=a(t);if(n)return n;let r=ee(a(e)).toLowerCase();return r===".jpg"||r===".jpeg"?"image/jpeg":r===".webp"?"image/webp":r===".gif"?"image/gif":"image/png"}function re(e,t){let n=typeof e=="string"?e.trim():"";return!n||n==="<omitted>"?"":n.startsWith("data:")?n:`data:${t};base64,${n.replace(/\s+/g,"")}`}function Q(e){if(Array.isArray(e))return e.map(a).filter(Boolean);let t=a(e);return t?[t]:[]}function xn(e,t){let n=yn(t,e);return n===""||!!n&&!n.startsWith("..")&&!Tn(n)}function Rn(e,t){let n=a(e);if(!n||!hn(n))return"";try{let r=Yt(n);for(let s of t)try{let i=Yt(s);if(xn(r,i))return r}catch{}}catch{return""}return""}function St(e,t,n={}){let r=a(e);return!r||r.startsWith("data:")||/^https?:\/\//i.test(r)?r:wn(r,t,n)}function wn(e,t,n={}){let r=[...Q(n.trustedFileRoots),...Q(n.trustedFileRoot),...Q(n.artifactRoots),...Q(n.artifactRoot)],s=Rn(e,r);if(!s)return"";try{let i=_n(s);return!i.isFile()||i.size<=0||i.size>Sn?"":`data:${t};base64,${gn(s).toString("base64")}`}catch{return""}}function y(...e){for(let t of e){let n=a(t);if(n)return n}return""}function En(e,t,n,r){let s=n.toLowerCase();if(s==="image"||s==="picture")return!0;let i=y(r,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=ee(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function Rt(e,t={}){let{source:n="runtime_image_generation_event"}=t;if(!c(e))return null;let r=c(e.payload)?e.payload:{},s=a(e.type),i=a(r.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let o=y(r.call_id,r.id),u=y(r.saved_path,r.savedPath),l=y(r.revised_prompt,r.revisedPrompt),d=ne(u,r.mimeType||r.mime_type),f=re(r.result,d)||St(u,d,t);if(!f)return null;let m=f.startsWith("data:")?f:"",h=u?te(u):`${o||Qt()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:h||"Generated image",summary:l||"Generated image",content:{prompt:l||void 0,dataUrl:m||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:m||void 0,previewUrl:f,fileUrl:f,metadata:{source:n,eventType:i,callId:o||void 0,savedPath:u||void 0,filename:h,mimeType:d,revisedPrompt:l||void 0}}}function In(e){let t=c(e)?e:{},n=[];for(let r of["_artifacts","artifacts"]){let s=t[r];Array.isArray(s)&&n.push(...s)}for(let r of["_artifact","artifact"]){let s=t[r];c(s)&&n.push(s)}return n}function On(e,t={}){let{source:n="runtime_artifact"}=t,r=c(e)?e:{};if(!Object.keys(r).length)return null;let s=c(r.content)?{...r.content}:{},i=c(r.metadata)?{...r.metadata}:{},o=y(r.saved_path,r.savedPath,s.saved_path,s.savedPath,i.savedPath),u=y(r.mimeType,r.mime_type,s.mimeType,s.mime_type,i.mimeType),l=y(r.artifactType,r.artifact_type,r.type,r.kind,s.type,o?"image":"file"),d=En(r,s,l,o),f=d?ne(o,u):u;if(d){let E=y(r.dataUrl,s.dataUrl),A=E.startsWith("data:")?E:"",N=y(r.imageUrl,r.previewUrl,r.fileUrl,r.downloadUrl,r.url,r.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),g=re(r.result??s.result,f)||A||St(o,f,t)||St(N,f,t);g&&(g.startsWith("data:")&&(s.dataUrl||=g),s.imageUrl||=g,s.previewUrl||=g,s.fileUrl||=g,f&&(s.mimeType||=f))}for(let[E,A]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let N=r[E];N!=null&&N!==""&&!(A in s)&&(s[A]=N)}let m=y(r.fileUrl,r.downloadUrl,r.imageUrl,r.dataUrl,r.url,r.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),h=y(r.previewUrl,r.imageUrl,r.dataUrl,r.url,r.fileUrl,r.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),T=y(r.dataUrl,s.dataUrl,m.startsWith("data:")?m:"",h.startsWith("data:")?h:""),w=y(r.filename,i.filename,o?te(o):""),U=y(r.fieldKey,r.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...r,artifactType:l,type:r.type||l,fieldKey:U,title:y(r.title,w,"Runtime artifact"),summary:y(r.summary,s.prompt,r.title,w,"Runtime artifact"),content:s,dataUrl:T||void 0,fileUrl:m||void 0,previewUrl:h||void 0,metadata:{...i,source:y(i.source,n),savedPath:o||i.savedPath,filename:w||i.filename,mimeType:f||i.mimeType}}}function tt(e,t){if(!t||!e)return;let n=c(t.metadata)?t.metadata:{},r=y(n.savedPath,n.callId,t.previewUrl,t.fileUrl)||Qt(),s=e.get(r);if(!s){e.set(r,t);return}s.content={...c(s.content)?s.content:{},...c(t.content)?t.content:{}},s.metadata={...c(s.metadata)?s.metadata:{},...n},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 xt(e,t,n={}){for(let r of In(e))tt(t,On(r,n))}function wt(e){if(!c(e)||!c(e.payload))return c(e)?e:{value:e};let t=a(e.payload.type);if(t!=="image_generation_end"&&t!=="image_generation_call")return e;let n={...e.payload};return typeof n.result=="string"&&n.result&&(n.result="<omitted>",n.resultLength=e.payload.result.length),{...e,payload:n}}function Zt(e,t,n){if(!c(e))return e;let r=c(e.event)?e.event:null;return r?(tt(t,Rt(r,n)),{...e,event:wt(r)}):e}function se(e,t,n={}){if(!c(e))return e;xt(e,t,n);let r=Zt(e,t,n),s=c(r.update)?Zt(r.update,t,n):null;return s&&s!==r.update&&(r={...r,update:s}),r}function ie(e,t,n={}){let r=c(e)?{...e}:{};xt(r,t,n),xt(c(r.output)?r.output:{},t,n);let s=[...t?.values?.()||[]];return s.length&&(r._artifacts=s),delete r.artifacts,r}var B=class{constructor(t,n,r={},s={}){this.agent=t,this.target=n,this.callbacks=r,this.options=s,this.proc=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`);this.proc=new Z({command:t,args:R(this.target.args),cwd:a(this.target.cwd)||this.agent.workspace||process.cwd(),env:c(this.target.env)?this.target.env:{},label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:a(this.target.framing||"line")}),this.proc.onRequest("session/request_permission",n=>this.handlePermissionRequest(n)),this.proc.onRequest("session/requestPermission",n=>this.handlePermissionRequest(n)),await this.proc.start({initialize:this.target.initialize!==!1,initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:v},...c(this.target.initializeParams)?this.target.initializeParams:{}}})}async sessionNew(t={}){await this.ensureStarted();let n=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return this.proc.call("session/new",{...t,mcpServers:n})}async sessionPrompt(t,n){await this.ensureStarted();let r=a(t.sessionId),s=new Map,i=this.artifactOptions(),o=this.proc.onNotification("session/update",l=>{let d=a(l.sessionId);(!d||d===r)&&n(se(l,s,i))}),u=async l=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:r,request:l,emitUpdate:n})||{outcome:"denied",reason:"permission handler is not configured"};r&&this.permissionHandlers.set(r,u),this.permissionHandlers.set("*",u);try{let l=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return ie(l,s,i)}finally{o(),r&&this.permissionHandlers.delete(r),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let n=a(t.sessionId),r=this.permissionHandlers.get(n)||this.permissionHandlers.get("*");return r?r(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=c(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[a(this.target.artifactRoot),a(this.target.artifactDir),a(this.target.runtimeArtifactRoot),a(t.ORCHA_RUNTIME_ARTIFACT_DIR),...R(this.target.trustedArtifactRoots),...R(this.target.trustedFileRoots),...R(this.target.artifactRoots),...R(this.target.artifactFileRoots)].filter(Boolean)}}async stop(t){await this.proc?.stop(t)}};function An(e){let t=c(e.metadata)?e.metadata:{};return a(t.agentCode)}function Cn(e,t){let n=An(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var et=class extends B{constructor(t,n,r,s={},i={}){let o=a(r).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",u=a(n.command)||"openclaw",l=Array.isArray(n.args)?n.args.map(String):[],d=l.length>0?l:["acp","--session",Cn(t,o)];super(t,{...n,command:u,args:d},s,i)}};import{spawn as Mn}from"node:child_process";import{randomUUID as q}from"node:crypto";import{existsSync as le,mkdirSync as Un,readdirSync as de,readFileSync as fe,realpathSync as it,rmSync as Nn,rmdirSync as bn,statSync as kn,unlinkSync as Pn}from"node:fs";import{homedir as Ln,tmpdir as pe}from"node:os";import{basename as me,dirname as Dn,join as C,resolve as oe}from"node:path";var Fn=36e5,$n=5e3,Hn=2*60*1e3,vn=2*60*1e3,Bn=12,zn=1e3,Gn=1500,nt=24*60*60*1e3,ae=new Set(["final_answer","final","complete","completed","done"]);function rt(e,t){try{e.kill(t)}catch{}}function O(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>O(t)).join("");if(!c(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let n=O(e[t]);if(n)return n}return""}function he(e){if(!c(e))return"";let t=c(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 O(t.content)||O(t.message);let n=O(e.delta)||O(e.text)||O(e.content);if(n)return n;let r=c(e.item)?e.item:{};return a(r.role)==="assistant"||a(r.type)==="message"?O(r.content)||O(r.text)||O(r.message):""}function ge(e,t={}){return Rt(e,{source:"codex_cli_image_generation",...t})}function _e(e,t){tt(e.artifacts,t)}function Te(e){return wt(e)}function ye(e){if(!c(e))return!1;let t=c(e.payload)?e.payload:{},n=a(e.type),r=a(t.type);if(n==="event_msg"&&r==="task_complete")return!0;let s=a(t.phase||t.status||t.stage).toLowerCase();return n==="event_msg"&&r==="agent_message"||n==="response_item"&&r==="message"&&a(t.role)==="assistant"?ae.has(s):!1}function jn(e,t,n){return n.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:n.captureLastMessage===!0?!0:me(e)==="codex"}function Kn(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:me(e)==="codex"}function Se(e){return Math.max(20,_(e.codexTranscriptPollMs||e.transcriptPollMs,zn))}function qn(e){return Math.max(0,_(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,Gn))}function Jn(e){return e.codexTranscriptStreaming===!0||e.streamCodexTranscript===!0}function Wn(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 Xn(e){let t=c(e?.metadata)?e.metadata:{},n=c(t._runtimeBridge)?t._runtimeBridge:{};for(let r of[n.finalTextOnly,n.finalOutputOnly]){let s=Wn(r);if(s!=null)return s}return null}function Vn(e,t){let n=Xn(e);return n??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function Yn(e,t){return!e.finalTextOnly||t}function Zn(e,t,n,r=new Set){return{target:e,promptText:t,startedAtMs:n,baselinePaths:r,matchedPath:"",disabled:!1,processedLines:new Map}}function Qn(e,t){let n=c(e.env)?e.env:{},r=a(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||n.ORCHA_RUNTIME_ARTIFACT_DIR)||C(pe(),"orcha-runtime-artifacts"),s=a(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||q(),i=C(r,s),o=C(i,q());return Un(o,{recursive:!0}),{root:o,realRoot:it(o),sessionRoot:i,realSessionRoot:it(i)}}function xe(e){return a(c(e)?e.root:e)}function ce(e){let t=xe(e),n=a(c(e)?e.sessionRoot:Dn(t)),r=a(c(e)?e.realSessionRoot:"");if(n)try{if(r&&it(n)!==r)return;bn(n)}catch{}}function tr(e,t={}){let n=xe(e),r=a(c(e)?e.realRoot:"");if(n){try{if(r&&it(n)!==r){p("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:n});return}}catch{ce(e);return}try{Nn(n,{recursive:!0,force:!0})}catch(s){p("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:n,error:String(s?.message||s)});return}ce(e)}}function er(e,t){return{trustedFileRoots:[t,...R(e.trustedArtifactRoots),...R(e.trustedFileRoots),...R(e.artifactRoots),...R(e.artifactFileRoots)].filter(Boolean)}}function Re(e){let t=a(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let n=c(e.env)?e.env:{},r=a(e.codexHome||n.CODEX_HOME||process.env.CODEX_HOME)||C(Ln(),".codex");return C(r,"sessions")}function nr(e,t){let n=new Date(t),r=String(n.getFullYear()),s=String(n.getMonth()+1).padStart(2,"0"),i=String(n.getDate()).padStart(2,"0");return C(e,r,s,i)}function we(e,t,n){let r=new Set;for(let s of[t-nt,t,t+nt,n-nt,n,n+nt])r.add(nr(e,s));return[...r].filter(s=>le(s))}function rr(e,t,n){let r=Re(e),s=t-Hn,i=n+vn,o=[];for(let u of we(r,t,n)){let l=[];try{l=de(u)}catch{continue}for(let d of l){if(!d.endsWith(".jsonl"))continue;let f=C(u,d);try{let m=kn(f);if(!m.isFile()||m.mtimeMs<s||m.mtimeMs>i)continue;o.push({path:f,mtimeMs:m.mtimeMs})}catch{}}}return o.sort((u,l)=>l.mtimeMs-u.mtimeMs).slice(0,Bn)}function sr(e,t,n=t){let r=Re(e),s=new Set;for(let i of we(r,t,n)){let o=[];try{o=de(i)}catch{continue}for(let u of o)u.endsWith(".jsonl")&&s.add(C(i,u))}return s}function Et(e,t,n=0){if(!(n>8||e===null||e===void 0)){if(typeof e=="string"){e&&t.push(e);return}if(Array.isArray(e)){for(let r of e)Et(r,t,n+1);return}if(c(e))for(let r of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])r in e&&Et(e[r],t,n+1)}}function Ee(e){return a(e).replace(/\s+/g," ")}function ir(e){let t=Ee(e);if(!t)return[];if(t.length<=200)return[t];let n=160,r=[0,Math.floor((t.length-n)/2),t.length-n],s=new Set,i=[];for(let o of r){let u=t.slice(Math.max(0,o),Math.max(0,o)+n).trim();u.length>=40&&!s.has(u)&&(s.add(u),i.push(u))}return i}function or(e,t){let n=ir(t);if(!n.length)return!1;let r=[];for(let i of e)Et(i,r);let s=Ee(r.join(" "));return n.every(i=>s.includes(i))}function ar(e){return e.find(t=>c(t)&&a(t.type)==="session_meta"&&c(t.payload))||null}function cr(e){let t=c(e?.payload)?e.payload:{},n=a(e?.timestamp||t.timestamp),r=Date.parse(n);return Number.isFinite(r)?r:Number.NaN}function ur(e,t,n){if(!or(e,t.promptText))return!1;let r=ar(e);if(!r)return!1;let s=r.payload,i=a(s.originator),o=a(s.source);if(i!=="codex_exec"&&o!=="exec")return!1;let u=cr(r);if(!Number.isFinite(u)||u<t.startedAtMs-5e3||u>n+5e3)return!1;let l=a(t.target.cwd),d=a(s.cwd);return!(l&&d&&oe(l)!==oe(d))}function ue(e){try{return dr(fe(e,"utf8"))}catch{return null}}function lr(e,t,n){if(!e||e.disabled)return null;if(e.matchedPath){let s=ue(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let r=[];for(let s of rr(e.target,e.startedAtMs,n)){if(e.baselinePaths.has(s.path))continue;let i=ue(s.path);!i||!ur(i,e,n)||r.push({path:s.path,events:i})}return r.length!==1?(r.length>1&&(e.disabled=!0,p("warn","runtime.cli","codex transcript fallback disabled; multiple matching transcripts",{target:e.target.targetCode,sessionId:t,transcriptCount:r.length})),null):(e.matchedPath=r[0].path,p("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),r[0])}function dr(e){let t=[];for(let n of e.split(/\r?\n/)){let r=n.trim();if(r)try{t.push(JSON.parse(r))}catch{}}return t}function fr(e){if(!c(e))return!1;let t=c(e.payload)?e.payload:{},n=a(e.type),r=a(t.type);return n==="event_msg"&&r==="image_generation_end"||n==="response_item"&&r==="image_generation_call"}function pr(e,t,n,r){let s=he(e),i=ye(e),o=0,u=0;if(s&&i&&!t.emittedTexts.has(s)){let l=t.emittedTexts.size?`
9
9
 
10
- ${s}`:s;t.emittedTexts.add(s),o=1,u=1,r({sessionId:n,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:l}}})}return s&&i&&(t.finalTextSeen=!0),me(t,pe(e,t.artifactOptions)),(ar(e)||i)&&r({sessionId:n,update:{sessionUpdate:"runtime_event",event:he(e)}}),{textCount:o,finalTextCount:u}}function Et(e,t,n,r,s=Date.now()){if(!t)return{artifactCount:0,transcriptCount:0,textCount:0,finalTextCount:0};let i=e.artifacts.size,o=0,u=0,l=0,d=ir(t,n,s);if(d){let f=Math.min(t.processedLines.get(d.path)||0,d.events.length),m=e.artifacts.size;for(let h of d.events.slice(f)){let R=cr(h,e,n,r);u+=R.textCount,l+=R.finalTextCount}t.processedLines.set(d.path,d.events.length),(d.events.length>f||e.artifacts.size>m)&&(o=1)}return{artifactCount:e.artifacts.size-i,transcriptCount:o,textCount:u,finalTextCount:l}}function ur(e,{remove:t=!0}={}){if(!e||!ae(e))return"";try{return ue(e,"utf8").trim()}catch{return""}finally{t&&rt(e)}}function rt(e){if(e)try{Un(e)}catch{}}function lr(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)}}function dr(e){return new Promise(t=>setTimeout(t,e))}function fr(e,t,n,r){return r?(e.finalTextSeen=!0,e.emittedTexts.has(r)||(e.emittedTexts.add(r),n({sessionId:t,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:r}}})),!0):!1}async function pr(e,t,n,r,s,i){let o=Et(e,t,n,r,Date.now()),u=()=>fr(e,n,r,ur(s,{remove:!1}));if(u()||e.finalTextSeen)return rt(s),o;let l=Bn(i);if(l<=0||!t&&!s)return rt(s),o;let d=Date.now()+l,f=Math.min(_e(i),100);for(;!e.finalTextSeen&&Date.now()<d&&(await dr(Math.min(f,Math.max(0,d-Date.now()))),o=lr(o,Et(e,t,n,r,Date.now())),!u()););return rt(s),o}var it=class{constructor(t,n,r={}){this.agent=t,this.target=n,this.options=r,this.active=new Map}async sessionNew(){return{sessionId:`cli-${this.agent.agentId}-${K()}`}}async sessionPrompt(t,n){let r=Date.now(),s=a(this.target.command);if(!s)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let i=a(t.sessionId)||K(),o=X(t.prompt),u=a(this.target.promptMode||"stdin"),l=this.buildArgs(u,o),d=a(this.target.cwd)||this.agent.workspace||process.cwd(),f=Wn(this.target,i),m=f.root,h=Vn(this.target,m),R=vn(s,this.target),x={...this.target,targetCode:this.agent.targetCode,cwd:d},F=R?Qn(x,r):new Set,U=Hn(s,l,this.target)?O(le(),`orcha-runtime-last-message-${K()}.txt`):"";U&&l.push("--output-last-message",U);let I=_(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,_(this.options.sessionPromptTimeoutMs,bn)),M={...process.env,...c(this.target.env)?this.target.env:{},...u==="env"?{ORCHA_RUNTIME_PROMPT:o}:{},ORCHA_AGENT_ID:this.agent.agentId,ORCHA_SESSION_ID:i,ORCHA_RUNTIME_ARTIFACT_DIR:m},g=En(s,l,{cwd:d,env:M,stdio:["pipe","pipe","pipe"]});this.active.set(i,g),p("info","runtime.cli","runtime prompt started",{target:this.agent.targetCode,sessionId:i,pid:g.pid,timeoutMs:I});let Bt="",ht=a(this.target.outputMode||"text"),N={artifacts:new Map,emittedTexts:new Set,value:"",artifactOptions:h,finalTextSeen:!1,finalTextOnly:qn(t,this.target)},gt=R?Jn(x,o,r,F):null;return g.stdout.setEncoding("utf8"),g.stdout.on("data",$=>this.handleStdout($,ht,N,i,n)),g.stderr.setEncoding("utf8"),g.stderr.on("data",$=>{Bt+=$,this.target.emitStderr===!0&&n({sessionId:i,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:$}}})}),u==="stdin"?g.stdin.end(o):g.stdin.end(),await new Promise(($,We)=>{let J=!1,zt=!1,k=null,_t=gt&&zn(this.target)?setInterval(()=>{try{Et(N,gt,i,n)}catch(T){p("warn","runtime.cli","codex transcript stream poll failed",{target:this.agent.targetCode,sessionId:i,error:String(T?.message||T)})}},_e(this.target)):null;_t?.unref?.();let Gt=setTimeout(()=>{zt=!0,p("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:i,pid:g.pid,timeoutMs:I}),nt(g,"SIGTERM"),k=setTimeout(()=>{p("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:i,pid:g.pid}),nt(g,"SIGKILL")},kn),k.unref?.(),yt(Object.assign(new Error(`runtime CLI timed out after ${I}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},I);Gt.unref?.();let jt=()=>{clearTimeout(Gt),_t&&clearInterval(_t),k&&!zt&&clearTimeout(k),Xn(f,{target:this.agent.targetCode,sessionId:i}),this.active.delete(i)},Xe=T=>{J||(J=!0,jt(),$(T))},yt=T=>{J||(J=!0,jt(),We(T))};g.on("error",T=>{p("warn","runtime.cli","runtime child error",{target:this.agent.targetCode,sessionId:i,pid:g.pid,error:String(T?.message||T)}),yt(T)}),g.on("exit",(T,qt)=>{(async()=>{k&&(clearTimeout(k),k=null),ht==="json-lines"&&N.value.trim()&&this.handleStdout(`
11
- `,ht,N,i,n);let H=await pr(N,gt,i,n,U,this.target);(H.artifactCount>0||H.textCount>0)&&p("info","runtime.cli","codex transcript updates collected",{target:this.agent.targetCode,sessionId:i,artifactCount:H.artifactCount,textCount:H.textCount,finalTextCount:H.finalTextCount,transcriptCount:H.transcriptCount});let W=Bt.trim();W&&p("debug","runtime.cli","runtime stderr",{target:this.agent.targetCode,sessionId:i,stderr:W}),p("info","runtime.cli","runtime prompt finished",{target:this.agent.targetCode,sessionId:i,pid:g.pid,exitCode:T,signal:qt,artifactCount:N.artifacts.size,finalTextSeen:N.finalTextSeen}),Xe({stopReason:T===0?"end_turn":"error",exitCode:T,signal:qt,_artifacts:[...N.artifacts.values()],...W?{stderr:W}:{}})})().catch(yt)})})}buildArgs(t,n){let r=w(this.target.args);return t==="args"?[...r,n]:r}handleStdout(t,n,r,s,i){if(n!=="json-lines"){i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:t}}});return}r.value+=t;let o=r.value.split(/\r?\n/);r.value=o.pop()||"";for(let u of o){let l=u.trim();if(l)try{let d=JSON.parse(l);me(r,pe(d,r.artifactOptions)),i({sessionId:s,update:{sessionUpdate:"runtime_event",event:he(d)}});let f=fe(d),m=ge(d);f&&Kn(r,m)&&!r.emittedTexts.has(f)&&(r.emittedTexts.add(f),i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:f}}})),f&&m&&(r.finalTextSeen=!0)}catch{i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`${u}
12
- `}}})}}}async sessionCancel(t){let n=a(t.sessionId),r=this.active.get(n);return r?(p("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:n,pid:r.pid}),nt(r,"SIGTERM"),this.active.delete(n),{ok:!0,cancelled:!0}):{ok:!0,cancelled:!1}}stop(t="stop"){for(let[n,r]of this.active.entries())p("info","runtime.cli","stopping runtime child",{target:this.agent.targetCode,sessionId:n,pid:r.pid,reason:t}),nt(r,"SIGTERM");this.active.clear()}};var It=24e3,Ot=8,Ct=50,At=6e3,mr=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),hr=10*60*1e3,gr=60*1e3,_r=8,yr=60*1e3,Tr=1,at="ORCHA_RUNTIME_RESULT_START",xe="ORCHA_RUNTIME_RESULT_END",Sr=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),Rr=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function wr(e,t,n){let r=c(e?._meta)?e._meta:{};return{...c(e)?e:{},sessionId:t,update:c(e?.update)?e.update:{},_meta:{...r,orchaAgentId:n.agentId,runtimeSessionId:n.runtimeSessionId,bridgeUpdateId:ot()}}}function A(e){return e==null||e===""?!1:typeof e=="string"?a(e)!=="":Array.isArray(e)?e.length>0:c(e)?Object.keys(e).length>0:!0}function Ee(e){let t=a(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return mr.has(t)}function L(e,t){let n=_(e,t);return Number.isFinite(n)&&n>0?n:t}function xr(e,t=!1){if(typeof e=="boolean")return e;let n=a(e).toLowerCase();return["true","1","yes","y","on"].includes(n)?!0:["false","0","no","n","off"].includes(n)?!1:t}function P(e){return a(e?.type||"echo")}function Er(e){let t=String(e||"");if(Rr.test(t))return!0;let n=t.replace(/[^a-z0-9]/gi,"").toLowerCase();return n.endsWith("token")||n.endsWith("secret")||n.endsWith("password")||n.endsWith("apikey")||n.endsWith("privatekey")||n==="authorization"||n==="cookie"||n==="jwt"||n.includes("credential")}function Mt(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=At)return e;let n=e.length-At;return`${e.slice(0,At)}... [truncated ${n} characters]`}if(t>=Ot)return Array.isArray(e)?`[array truncated at depth ${Ot}, items=${e.length}]`:c(e)?`[object truncated at depth ${Ot}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let n=e.slice(0,Ct).map(r=>Mt(r,t+1));return e.length>Ct&&n.push(`[truncated ${e.length-Ct} items]`),n}if(c(e)){let n={};for(let[r,s]of Object.entries(e))n[r]=Er(r)?"[REDACTED]":Mt(s,t+1);return n}return String(e)}var Ir=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 Or(e){if(!c(e))return e;let t={};for(let n of Ir)A(e[n])&&(t[n]=e[n]);return t}function Cr(e){if(!c(e))return e;let t={...e};return c(t.renderedPayload)&&(t.renderedPayload=Or(t.renderedPayload)),t}function Ar(e){let t=c(e)?e:{},n={};A(t.metadata)&&(n.metadata=Cr(t.metadata));for(let[r,s]of Object.entries(t))Sr.has(r)||r==="metadata"||A(s)&&(n[r]=s);return n}function Ur(e){let t=c(e)?e:{},n=c(t.metadata)?t.metadata:{},r=c(n.renderedPayload)?n.renderedPayload:{};return c(t.resultContract)?t.resultContract:c(r.resultContract)?r.resultContract:{}}function Ie(e){return a(Ur(e).kind).toLowerCase()==="decision"}function Mr(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:P(e)==="cli"}function Nr(e,t){let n=c(e?.metadata)?{...e.metadata}:{},r=c(n._runtimeBridge)?{...n._runtimeBridge}:{};return n._runtimeBridge={...r,promptKind:"dispatch",finalTextOnly:Mr(t),requiresRuntimeResult:Ie(e)},n}function br(e){let t=Ar(e);if(!A(t))return"";let n=JSON.stringify(Mt(t),null,2);if(n.length<=It)return n;let r=n.length-It;return`${n.slice(0,It)}
13
- ... [truncated ${r} characters]`}function Oe(e){if(!c(e))return"";let t=c(e.update)?e.update:e,r=(c(t.content)?t.content:{}).text??t.text;return r==null?"":String(r)}function kr(e){if(!c(e))return"";let t=c(e.update)?e.update:e;return a(t.sessionUpdate)}function Lr(e){if(!Array.isArray(e))return"";let t=!1,n=[],r=[],s=[],i=()=>{n.length>0&&(r.push(n),n=[])};for(let u of e){let l=kr(u),d=Oe(u);if(!l){d&&s.push(d);continue}if(t=!0,l==="agent_message_chunk"){d&&n.push(d);continue}(l==="agent_thought_chunk"||l==="user_message_chunk"||l==="tool_call"||l==="tool_call_update"||l==="plan")&&i()}if(i(),!t)return Nt(s);let o=r[r.length-1]||[];return Nt(o)}function Pr(e){return Array.isArray(e)?e.map(Oe).filter(t=>a(t)):[]}function Dr(e){if(!c(e))return null;let t=c(e.update)?e.update:e;return a(t.sessionUpdate)!=="runtime_event"?null:c(t.event)?t.event:null}function Fr(e){if(!c(e))return"";let t=c(e.payload)?e.payload:{},n=a(e.type),r=a(t.type);if(n==="event_msg"){if(r==="task_complete")return a(t.last_agent_message||t.message||t.output);if(r==="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 $r(e){if(!Array.isArray(e))return"";for(let t=e.length-1;t>=0;t-=1){let n=Fr(Dr(e[t]));if(n)return n}return""}function Nt(e){let t="";for(let n of e){let r=String(n||"");r&&(t?r.startsWith(t)?t=r:t.endsWith(r)||(t+=r):t=r)}return t.trim()}function Hr(e){let t=String(e||"").trim();if(!t)return"";let n=t.match(/(?:^|\n)#{1,3}\s+\S/);return!n||n.index===0?t:t.slice(n.index+(t[n.index]===`
14
- `?1:0)).trim()}function ct(e){let t=String(e||"").trim();if(!t)return null;try{let n=JSON.parse(t);if(c(n)&&(Ce(n)||A(n._artifacts)||A(n.artifacts)||A(n._decision)||A(n._meta)))return n}catch{}return null}function vr(e){let t=String(e||"");if(!t)return"";let n=t.lastIndexOf(xe);if(n<0)return"";for(let r=t.lastIndexOf(at,n);r>=0;r=t.lastIndexOf(at,r-1)){let s=t.slice(r+at.length,n).trim();if(ct(s))return s}return""}function ut(e){let t=vr(e);return t?ct(t):null}function we(e){let t=String(e||"").trim();if(!t)return null;let n=ut(t);if(n)return n;let r=[...t.matchAll(/```(?:json)?\s*([\s\S]*?)```/gi)];for(let s=r.length-1;s>=0;s-=1){let i=ct(r[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=ct(t.slice(s));if(i)return i}return null}function Br(e){let t=Pr(e);for(let n=t.length-1;n>=0;n-=1){let r=ut(t[n]);if(r)return r}return ut(Nt(t))}function Ce(e){if(!c(e))return!1;if(A(e.output))return!0;for(let t of["content","text","message","summary"])if(a(e[t]))return!0;return!!(Ee(e.status)||a(e.error)||a(e.errorMessage))}function C(e){let t=c(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 zr(e){return c(e)?typeof(c(e._decision)?e._decision:c(e.decision)?e.decision:e).passed=="boolean":!1}function Gr(e){return c(e)?c(e._decision)&&typeof e._decision.passed=="boolean"?!0:zr(e.output):!1}function Ut(e,t,n){let{output:r,...s}=c(e)?e:{};return{...s,status:"failed",errorMessage:"Runtime Result missing required structured result for resultContract",_meta:{...c(s._meta)?s._meta:{},runtimeOutputSource:t,requiredRuntimeResult:!0,finalMessagePreview:a(n).slice(0,1e3)}}}function b(e,t,n){return{...e,...t,_meta:{...c(e._meta)?e._meta:{},...c(t._meta)?t._meta:{},runtimeOutputSource:n}}}function jr(e,t,n={}){let r=a(n.promptKind),s=n.requiresRuntimeResult===!0,i=s||r==="dispatch",o=C(e),u=typeof o.output=="string"?ut(o.output):null;if(u)return b(o,C(u),"result_block");let l=$r(t),d=l?we(l):null,f=i?Br(t):null;if(Ce(o))return Ee(o.status)||a(o.error)||a(o.errorMessage)?o:r==="dispatch"&&d?b(o,C(d),"final_event"):r==="dispatch"&&f?b(o,C(f),"updates"):!s||Gr(o)?o:d?b(o,C(d),"final_event"):f?b(o,C(f),"updates"):Ut(o,"result",o.output);if(d)return b(o,C(d),"final_event");if(f)return b(o,C(f),"updates");if(l)return s?Ut(o,"final_event",l):{...o,output:l,_meta:{...c(o._meta)?o._meta:{},runtimeOutputSource:"final_event"}};let m=Hr(Lr(t));if(!m)return o;let h=we(m);return h?b(o,C(h),"updates"):s?Ut(o,"updates",m):{...o,output:m,_meta:{...c(o._meta)?o._meta:{},runtimeOutputSource:"updates"}}}var lt=class{constructor(t){this.config=t,this.targets=t.targets||{},this.agents=new Map,this.sessions=new Map,this.runtimeSessionIndex=new Map,this.pendingPermissions=new Map,this.startedAt=j(),this.cleanupTimer=null,this.startSessionCleanup()}targetFor(t){let n=a(t)||this.config.defaultTargetCode,r=this.targets[n];if(!n||!c(r)){let s=new Error(`runtime target is not configured: ${n||"<empty>"}`);throw s.code="RUNTIME_TARGET_NOT_FOUND",s}return{code:n,target:r}}targetIdleTtlMs(t){let r=P(t)==="openclaw"?L(this.config.openClawSessionIdleTtlMs,yr):L(this.config.sessionIdleTtlMs,hr);return L(t?.sessionIdleTtlMs??t?.idleTtlMs,r)}targetMaxSessions(t){let r=P(t)==="openclaw"?L(this.config.openClawMaxSessions,Tr):L(this.config.maxSessionsPerTarget,_r);return L(t?.maxSessions,r)}targetReleaseAfterPrompt(t){let n=P(t);return xr(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}startSessionCleanup(){let t=L(this.config.sessionCleanupIntervalMs,gr);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(n=>{p("warn","runtime-bridge","runtime session cleanup failed",{error:String(n)})})},t),this.cleanupTimer.unref?.())}sessionCountForTarget(t){let n=0;for(let r of this.sessions.values())r.targetCode===t&&(n+=1);return n}idleTargetSessions(t){return[...this.sessions.entries()].filter(([,n])=>n.targetCode===t&&!n.busy).sort((n,r)=>(n[1].lastUsedAtMs||0)-(r[1].lastUsedAtMs||0))}async closeSession(t,n="session_closed"){let r=this.sessions.get(t);if(!r)return!1;try{await r.runtime?.stop?.(n)}catch(s){p("warn","runtime-bridge","runtime session stop failed",{sessionId:r.sessionId,runtimeSessionId:r.runtimeSessionId,targetCode:r.targetCode,runtimeKind:r.runtimeKind,error:String(s)})}return this.sessions.delete(t),this.runtimeSessionIndex.delete(`${r.agentId}:${r.runtimeSessionId}`),p("info","runtime-bridge","runtime session closed",{sessionId:r.sessionId,runtimeSessionId:r.runtimeSessionId,targetCode:r.targetCode,runtimeKind:r.runtimeKind,reason:n}),!0}async closeAllSessions(t="bridge_shutdown"){for(let n of[...this.sessions.keys()])await this.closeSession(n,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[n,r]of[...this.sessions.entries()])r.busy||t-(r.lastUsedAtMs||r.createdAtMs||t)>r.idleTtlMs&&await this.closeSession(n,"idle_timeout")}async reserveTargetSlot(t,n){let r=this.targetMaxSessions(n);for(;this.sessionCountForTarget(t)>=r;){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")}}async createAgent(t){let n=a(t.agentId);if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let{code:r,target:s}=this.targetFor(t.targetCode||t.framework),i={agentId:n,targetCode:r,framework:a(t.framework||r),workspace:a(t.workspace),metadata:c(t.metadata)?t.metadata:{},createdAt:j(),runtimeKind:P(s)};return this.agents.set(n,i),{agent:i}}runtimeFor(t,n){let{target:r}=this.targetFor(t.targetCode),s=P(r),i={onPermissionRequest:u=>this.requestPermission(u)},o={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs};return s==="stdio-acp"||s==="acp"?new B(t,r,i,o):s==="openclaw"?new tt(t,r,n,i,o):s==="cli"?new it(t,r,o):new V(t)}async prompt(t,n={}){let r=a(t.agentId),s=a(t.sessionId)||ot();if(!r)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let i=this.agents.get(r)||(await this.createAgent({agentId:r,targetCode:t.targetCode,framework:t.framework,workspace:t.workspace,metadata:t.metadata})).agent,o=a(t.workspace);o&&o!==i.workspace&&(i.workspace=o);let u=`${r}:${s}`;await this.cleanupExpiredSessions();let l=this.sessions.get(u);if(!l){let{code:m,target:h}=this.targetFor(i.targetCode);await this.reserveTargetSlot(m,h);let R=this.runtimeFor(i,s),x=await R.sessionNew({cwd:i.workspace||process.cwd(),metadata:c(t.metadata)?t.metadata:{}}),F=Date.now();l={agentId:r,sessionId:s,runtime:R,targetCode:m,runtimeKind:P(h),runtimeSessionId:a(c(x)?x.sessionId:"")||s,idleTtlMs:this.targetIdleTtlMs(h),releaseAfterPrompt:this.targetReleaseAfterPrompt(h),createdAtMs:F,lastUsedAtMs:F,busy:!1,createdAt:j()},this.sessions.set(u,l),this.runtimeSessionIndex.set(`${r}:${l.runtimeSessionId}`,l)}if(l.busy){let m=new Error(`runtime session is already running: ${s}`);throw m.code="RUNTIME_SESSION_BUSY",m}l.busy=!0,l.lastUsedAtMs=Date.now();let d=[],f=m=>{let h=wr(m,s,l);d.push(h),n.onUpdate?.(h)};try{let m=await l.runtime.sessionPrompt({sessionId:l.runtimeSessionId,prompt:Array.isArray(t.prompt)?t.prompt:[],metadata:c(t.metadata)?t.metadata:{}},f),h=c(t.metadata)?t.metadata:{},R=c(h._runtimeBridge)?h._runtimeBridge:{},x=jr(m,d,R);return{sessionId:s,runtimeSessionId:l.runtimeSessionId,result:x,updates:d}}finally{l.busy=!1,l.lastUsedAtMs=Date.now(),l.releaseAfterPrompt&&await this.closeSession(u,"release_after_prompt")}}async cancel(t){let n=a(t.agentId),r=a(t.sessionId),s=`${n}:${r}`,i=this.sessions.get(s);return i?(await i.runtime.sessionCancel({sessionId:i.runtimeSessionId}),await this.closeSession(s,"cancelled"),{cancelled:!0}):{cancelled:!1}}async dispatch(t,n={}){let r=a(t.agentId),s=a(t.taskId),i=a(t.executionId);if(!r||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let o=a(t.sessionId)||`dispatch-${i||s}`,u=a(t.instructions),l=br(t),d=Ie(t),{target:f}=this.targetFor(t.targetCode||t.framework),m=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",u?`instructions: ${u}`:"",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 ![illustration](orcha-artifact://image/0) 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, wrap the final Orcha Runtime Result JSON between ${at} and ${xe}.`:"",d?"The result block must contain exactly one valid JSON object with output and _decision; escape Markdown newlines inside JSON strings as \\n.":"",d?"Do not put process notes inside the result block; text outside the block is ignored by Orcha.":"","Return only the final answer required by that protocol.","Do not include process notes, logs, or explanations."].filter(Boolean).join(`
15
- `)}];return this.prompt({...t,agentId:r,sessionId:o,prompt:m,metadata:Nr(t,f)},n)}async requestPermission({agent:t,runtimeSessionId:n,request:r,emitUpdate:s}){let i=ot(),u=this.runtimeSessionIndex.get(`${t.agentId}:${n}`)?.sessionId||n||ot(),l={permissionId:i,agentId:t.agentId,sessionId:u,runtimeSessionId:n,request:c(r)?r:{},status:"pending",createdAt:j()};return s?.({sessionId:n,update:{sessionUpdate:"permission_request",permission:l}}),await new Promise(d=>{let f=_(r?.timeoutMs,this.config.permissionRequestTimeoutMs),m=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:m,resolve:d,permission:l})})}async respondPermission(t){let n=a(t.permissionId),r=this.pendingPermissions.get(n),s=a(t.outcome||"approved")||"approved";return r?(clearTimeout(r.timer),this.pendingPermissions.delete(n),r.resolve({permissionId:n,outcome:s,response:c(t.response)?t.response:{},userId:a(t.userId),metadata:c(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:n,outcome:s}):{accepted:!1,permissionId:n,outcome:s}}health(){return{status:"ok",bridgeVersion:v,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)}}};import qr from"node:http";import Kr from"node:https";import{randomBytes as Ae}from"node:crypto";var dt=1,bt=3,ft=class{constructor(t){this.url=t,this.readyState=0,this.socket=null,this.buffer=Buffer.alloc(0),this.listeners=new Map,this.connect()}addEventListener(t,n){let r=this.listeners.get(t)||new Set;r.add(n),this.listeners.set(t,r)}emit(t,n={}){let r=this.listeners.get(t);if(r)for(let s of r)s(n)}connect(){let t=new URL(this.url),n=t.protocol==="wss:"?Kr:qr,r=Ae(16).toString("base64"),s=n.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":r,"Sec-WebSocket-Version":"13"}});s.on("upgrade",(i,o,u)=>{this.socket=o,this.readyState=dt,o.on("data",l=>this.onData(l)),o.on("close",()=>this.onClose()),o.on("error",l=>{this.emit("error",{error:l,message:l.message,type:"error"}),this.onClose()}),u?.length&&this.onData(u),this.emit("open")}),s.on("response",i=>{this.emit("error",{message:`websocket upgrade failed: HTTP ${i.statusCode}`,type:"error"}),i.resume(),this.onClose()}),s.on("error",i=>{this.emit("error",{error:i,message:i.message,type:"error"}),this.onClose()}),s.end()}send(t){!this.socket||this.readyState!==dt||this.socket.write(kt(1,Buffer.from(String(t),"utf8")))}close(){!this.socket||this.readyState===bt||(this.socket.write(kt(8,Buffer.alloc(0))),this.socket.end(),this.onClose())}onClose(){this.readyState!==bt&&(this.readyState=bt,this.emit("close"))}onData(t){for(this.buffer=Buffer.concat([this.buffer,t]);this.buffer.length>=2;){let n=this.buffer[0],r=this.buffer[1],s=n&15,i=(r&128)!==0,o=r&127,u=2;if(o===126){if(this.buffer.length<u+2)return;o=this.buffer.readUInt16BE(u),u+=2}else if(o===127){if(this.buffer.length<u+8)return;let f=this.buffer.readUInt32BE(u),m=this.buffer.readUInt32BE(u+4);o=f*2**32+m,u+=8}let l=u;if(i&&(u+=4),this.buffer.length<u+o)return;let d=this.buffer.subarray(u,u+o);if(i){let f=this.buffer.subarray(l,l+4);d=Buffer.from(d.map((m,h)=>m^f[h%4]))}this.buffer=this.buffer.subarray(u+o),s===1?this.emit("message",{data:d.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(kt(10,d))}}};function kt(e,t){let n=t.length,r=2;n>=126&&n<=65535?r+=2:n>65535&&(r+=8);let s=Ae(4),i=Buffer.alloc(r+4+n);i[0]=128|e;let o=2;n<126?i[1]=128|n:n<=65535?(i[1]=254,i.writeUInt16BE(n,o),o+=2):(i[1]=255,i.writeUInt32BE(Math.floor(n/2**32),o),i.writeUInt32BE(n>>>0,o+4),o+=8),s.copy(i,o),o+=4;for(let u=0;u<n;u+=1)i[o+u]=t[u]^s[u%4];return i}function Jr(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 Wr(e){return Object.entries(e||{}).map(([t,n])=>({targetCode:t,targetName:a(n?.name||n?.targetName||t),targetType:a(n?.type||"echo"),status:"available",metadata:c(n)?n:{}}))}var pt=class{constructor(t,n){this.config=t,this.bridge=n,this.ws=null,this.stopped=!1,this.connected=!1,this.reconnectTimer=null}start(){this.connect()}stop(){this.stopped=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.ws?.close()}connect(){let t=Jr(this.config.orchaUrl),n=new ft(t);this.ws=n,n.addEventListener("open",()=>this.authenticate()),n.addEventListener("message",r=>this.handleMessage(r.data)),n.addEventListener("close",()=>this.scheduleReconnect("close")),n.addEventListener("error",r=>{p("warn","orcha-client","runtime node websocket error",{error:String(r?.message||r?.type||r)})})}authenticate(){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:v,protocolVersion:"orcha-runtime-node.v1",defaultTargetCode:this.config.defaultTargetCode,targets:Wr(this.config.targets)})}scheduleReconnect(t){this.connected=!1,!this.stopped&&(this.reconnectTimer||(p("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){let n;try{n=JSON.parse(String(t))}catch(r){p("warn","orcha-client","invalid Orcha websocket frame",{error:String(r)});return}if(c(n)){if(n.type==="runtime_node.authenticated"){this.connected=!0,p("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()})}}async handleRequest(t){let n=a(t.id),r=a(t.method),s=c(t.params)?t.params:{};try{let i=await this.invoke(r,s,n);this.send({type:"orcha.runtime.response",id:n,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:n,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i)}})}}async invoke(t,n,r){if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(n);if(t==="agents/dispatch")return this.bridge.dispatch(n,{onUpdate:s=>this.sendUpdate(r,s)});if(t==="sessions/prompt")return this.bridge.prompt(n,{onUpdate:s=>this.sendUpdate(r,s)});if(t==="sessions/cancel")return this.bridge.cancel(n);if(t==="permissions/respond")return this.bridge.respondPermission(n);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,n){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:n})}send(t){return!this.ws||this.ws.readyState!==dt?!1:(this.ws.send(JSON.stringify(t)),!0)}};import{existsSync as Xr,readFileSync as Vr}from"node:fs";import{resolve as Ue}from"node:path";var Yr=/^[A-Za-z_][A-Za-z0-9_]*$/;function Me(e=process.env,t=process.cwd()){let n=a(e.ORCHA_RUNTIME_ENV_FILE),r=n?Ue(t,n):Ue(t,".env");if(!Xr(r))return n&&p("warn","config","runtime env file not found",{path:r}),{loaded:!1,path:r,keys:[]};let s=[],i=Vr(r,"utf8");for(let o of i.split(/\r?\n/)){let u=Qr(o);if(!u)continue;let[l,d]=u;Object.prototype.hasOwnProperty.call(e,l)||(e[l]=d,s.push(l))}return p("info","config","runtime env file loaded",{path:r,keyCount:s.length}),{loaded:!0,path:r,keys:s}}function Ne(e=process.env){return{mode:a(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),host:e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1",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),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:_(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),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),targets:Zr(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Zr(e){if(!a(e))return{};try{let t=JSON.parse(e);if(c(t))return t}catch(t){p("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function Qr(e){let t=e.trim();if(!t||t.startsWith("#"))return null;let n=t.startsWith("export ")?t.slice(7).trimStart():t,r=n.indexOf("=");if(r<=0)return null;let s=n.slice(0,r).trim();if(!Yr.test(s))return null;let i=ts(n.slice(r+1).trim());return[s,i]}function ts(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let n=e.slice(1,-1);return t==='"'?es(n):n}return ns(e).trim()}function es(e){return e.replaceAll("\\n",`
16
- `).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function ns(e){let t=!1,n=!1;for(let r=0;r<e.length;r+=1){let s=e[r],i=e[r-1];if(s==="'"&&!n)t=!t;else if(s==='"'&&!t&&i!=="\\")n=!n;else if(s==="#"&&!t&&!n&&/\s/.test(i||""))return e.slice(0,r)}return e}import{createServer as rs}from"node:http";function mt(e,t,n){let r=JSON.stringify(n);e.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(r)}),e.end(r)}function D(e={}){return{ok:!0,...e}}function Lt(e,t,n){return{ok:!1,error:{code:e,message:t,...n===void 0?{}:{detail:n}}}}async function be(e,t){let n=[],r=0;for await(let i of e){if(r+=i.length,r>t)throw Object.assign(new Error("request body too large"),{status:413,code:"REQUEST_TOO_LARGE"});n.push(i)}if(n.length===0)return{};let s=Buffer.concat(n).toString("utf8");if(!s.trim())return{};try{let i=JSON.parse(s);if(!c(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 ke(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 Le(e,t){let n={"GET /health":async()=>D(t.health()),"POST /agents/create":async r=>D(await t.createAgent(r)),"POST /agents/dispatch":async r=>D(await t.dispatch(r)),"POST /sessions/prompt":async r=>D(await t.prompt(r)),"POST /sessions/cancel":async r=>D(await t.cancel(r)),"POST /permissions/respond":async r=>D(await t.respondPermission(r))};return rs(async(r,s)=>{let i=new URL(r.url||"/",`http://${r.headers.host||`${e.host}:${e.port}`}`),o=`${r.method||"GET"} ${i.pathname}`,u=n[o];if(!u){mt(s,404,Lt("NOT_FOUND",`No route for ${o}`));return}try{ke(r,e.token);let l=r.method==="GET"?{}:await be(r,e.requestLimitBytes);mt(s,200,await u(l))}catch(l){let d=l.status||500,f=l.code||"BRIDGE_INTERNAL";mt(s,d,Lt(f,l.message||String(l)))}})}var ds=ls(import.meta.url),fs=".orcha-runtime-bridge.pid",ps=".orcha-runtime-bridge.log",ms=3,hs=36e5,{command:gs,options:je}=Ss(process.argv.slice(2));Rs(je);Me();var _s=Ne();await ys(gs,_s,je);async function ys(e,t,n){switch(e){case"run":case"foreground":De(t);return;case"start":if(n.foreground){De(t);return}$e();return;case"reload":case"restart":await He({quiet:!0}),$e();return;case"stop":await He();return;case"status":Ts();return;case"help":case"--help":case"-h":Is();return;default:throw new Error(`Unknown command: ${e}`)}}function De(e){ws();let t=new lt(e);if(e.mode==="server"){let r=Le(e,t);Fe({bridge:t,server:r}),r.listen(e.port,e.host,()=>{p("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 n=new pt(e,t);Fe({bridge:t,client:n}),n.start(),p("info","runtime-bridge","Orcha runtime node started",{nodeId:e.nodeId,nodeName:e.nodeName,orchaUrl:e.orchaUrl,targets:Object.keys(t.targets)})}function Fe({bridge:e,client:t,server:n}){let r=!1,s=i=>{if(r)return;r=!0;let o=Number(e?.sessions?.size||0)>0;p("info","runtime-bridge","runtime bridge shutting down",{signal:i});try{t?.stop?.()}catch(u){p("warn","runtime-bridge","runtime client stop failed",{error:String(u)})}Promise.resolve(e?.stop?.(`process_${String(i||"shutdown").toLowerCase()}`)).catch(u=>{p("warn","runtime-bridge","runtime bridge stop failed",{error:String(u)})}).finally(()=>{try{n?.close?.()}catch(u){p("warn","runtime-bridge","runtime server close failed",{error:String(u)})}}),setTimeout(()=>process.exit(0),o?8500:200)};process.once("SIGTERM",()=>s("SIGTERM")),process.once("SIGINT",()=>s("SIGINT"))}function $e(){let e=Ht(),t=qe(),n=vt(e);if(n&&z(n)){console.log(JSON.stringify({status:"already_running",pid:n,pidFile:e,logFile:t}));return}n&&Ft(e),Be(e),Be(t),Dt(t);let r=as(t,"a"),s={...process.env,ORCHA_RUNTIME_PID_FILE:e,ORCHA_RUNTIME_LOG_FILE:t},i=ss(process.execPath,[ds,"run"],{cwd:process.cwd(),detached:!0,env:s,stdio:["ignore",r,r]});i.unref(),is(r),Ge(e,`${i.pid}
17
- `),console.log(JSON.stringify({status:"started",pid:i.pid,pidFile:e,logFile:t}))}async function He({quiet:e=!1}={}){let t=Ht(),n=vt(t);if(!n){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!z(n)){Ft(t),e||console.log(JSON.stringify({status:"not_running",pid:n,pidFile:t}));return}process.kill(n,"SIGTERM"),!await ve(n,1e4)&&z(n)&&(process.kill(n,"SIGKILL"),await ve(n,3e3)),Ft(t),e||console.log(JSON.stringify({status:"stopped",pid:n,pidFile:t}))}function Ts(){let e=Ht(),t=qe(),n=vt(e),r=!!(n&&z(n));console.log(JSON.stringify({status:r?"running":"not_running",running:r,pid:r?n:null,pidFile:e,logFile:t}))}function Ss(e){let t=[],n={};for(let s=0;s<e.length;s+=1){let i=e[s];i==="--daemon"?n.daemon=!0:i==="--foreground"?n.foreground=!0:i==="--env-file"?n.envFile=e[++s]:i==="--pid-file"?n.pidFile=e[++s]:i==="--log-file"?n.logFile=e[++s]:t.push(i)}return{command:t[0]||"run",options:n}}function Rs(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 Ht(){return $t(process.cwd(),process.env.ORCHA_RUNTIME_PID_FILE||fs)}function qe(){return $t(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||ps)}function ws(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=Ke();if(t<=0)return;let n=$t(process.cwd(),e);Dt(n,t);let r=Es();r<=0||setInterval(()=>Dt(n,t),r).unref()}function Dt(e,t=Ke()){if(t<=0||!ze(e))return;let n=0,r="";try{if(n=Pe(e).size,n<=0)return;r=Pt(e,"utf8")}catch(d){p("warn","runtime-bridge","runtime log cleanup skipped",{logFile:e,error:String(d)});return}let s=Date.now()-t*24*60*60*1e3,i=r.split(/\r?\n/),o=[],u=0;for(let d of i)d&&(xs(d,s)?o.push(d):u+=1);if(u===0)return;let l="";try{Pe(e).size>n&&(l=Pt(e,"utf8").slice(r.length));let f=[...o,...l.split(/\r?\n/).filter(Boolean)].join(`
18
- `);Ge(e,f?`${f}
19
- `:""),p("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:u})}catch(d){p("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function xs(e,t){try{let n=JSON.parse(e);if(!n||typeof n!="object")return!0;let r=typeof n.ts=="string"?Date.parse(n.ts):Number.NaN;return!Number.isFinite(r)||r>=t}catch{return!0}}function Ke(){return Je(process.env.ORCHA_RUNTIME_LOG_RETENTION_DAYS,ms)}function Es(){return Je(process.env.ORCHA_RUNTIME_LOG_CLEANUP_INTERVAL_MS,hs)}function Je(e,t){let n=Number.parseInt(String(e??""),10);return Number.isFinite(n)&&n>=0?n:t}function vt(e){if(!ze(e))return null;let t=Number.parseInt(Pt(e,"utf8").trim(),10);return Number.isInteger(t)&&t>0?t:null}function z(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function ve(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!z(e))return!0;await new Promise(r=>setTimeout(r,100))}return!z(e)}function Be(e){os(us(e),{recursive:!0})}function Ft(e){try{cs(e,{force:!0})}catch{}}function Is(){console.log(`Usage: orcha-runtime-bridge [command] [options]
10
+ ${s}`:s;t.emittedTexts.add(s),o=1,u=1,r({sessionId:n,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:l}}})}return s&&i&&(t.finalTextSeen=!0),_e(t,ge(e,t.artifactOptions)),(fr(e)||i)&&r({sessionId:n,update:{sessionUpdate:"runtime_event",event:Te(e)}}),{textCount:o,finalTextCount:u}}function It(e,t,n,r,s=Date.now()){if(!t)return{artifactCount:0,transcriptCount:0,textCount:0,finalTextCount:0};let i=e.artifacts.size,o=0,u=0,l=0,d=lr(t,n,s);if(d){let f=Math.min(t.processedLines.get(d.path)||0,d.events.length),m=e.artifacts.size;for(let h of d.events.slice(f)){let T=pr(h,e,n,r);u+=T.textCount,l+=T.finalTextCount}t.processedLines.set(d.path,d.events.length),(d.events.length>f||e.artifacts.size>m)&&(o=1)}return{artifactCount:e.artifacts.size-i,transcriptCount:o,textCount:u,finalTextCount:l}}function mr(e,{remove:t=!0}={}){if(!e||!le(e))return"";try{return fe(e,"utf8").trim()}catch{return""}finally{t&&st(e)}}function st(e){if(e)try{Pn(e)}catch{}}function hr(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)}}function gr(e){return new Promise(t=>setTimeout(t,e))}function _r(e,t,n,r){return r?(e.finalTextSeen=!0,e.emittedTexts.has(r)||(e.emittedTexts.add(r),n({sessionId:t,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:r}}})),!0):!1}async function Tr(e,t,n,r,s,i){let o=It(e,t,n,r,Date.now()),u=()=>_r(e,n,r,mr(s,{remove:!1}));if(u()||e.finalTextSeen)return st(s),o;let l=qn(i);if(l<=0||!t&&!s)return st(s),o;let d=Date.now()+l,f=Math.min(Se(i),100);for(;!e.finalTextSeen&&Date.now()<d&&(await gr(Math.min(f,Math.max(0,d-Date.now()))),o=hr(o,It(e,t,n,r,Date.now())),!u()););return st(s),o}var ot=class{constructor(t,n,r={}){this.agent=t,this.target=n,this.options=r,this.active=new Map}async sessionNew(){return{sessionId:`cli-${this.agent.agentId}-${q()}`}}async sessionPrompt(t,n){let r=Date.now(),s=a(this.target.command);if(!s)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let i=a(t.sessionId)||q(),o=V(t.prompt),u=a(this.target.promptMode||"stdin"),l=this.buildArgs(u,o),d=a(this.target.cwd)||this.agent.workspace||process.cwd(),f=Qn(this.target,i),m=f.root,h=er(this.target,m),T=Kn(s,this.target),w={...this.target,targetCode:this.agent.targetCode,cwd:d},U=T?sr(w,r):new Set,E=jn(s,l,this.target)?C(pe(),`orcha-runtime-last-message-${q()}.txt`):"";E&&l.push("--output-last-message",E);let A=_(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,_(this.options.sessionPromptTimeoutMs,Fn)),N={...process.env,...c(this.target.env)?this.target.env:{},...u==="env"?{ORCHA_RUNTIME_PROMPT:o}:{},ORCHA_AGENT_ID:this.agent.agentId,ORCHA_SESSION_ID:i,ORCHA_RUNTIME_ARTIFACT_DIR:m},g=Mn(s,l,{cwd:d,env:N,stdio:["pipe","pipe","pipe"]});this.active.set(i,g),p("info","runtime.cli","runtime prompt started",{target:this.agent.targetCode,sessionId:i,pid:g.pid,timeoutMs:A});let jt="",gt=a(this.target.outputMode||"text"),b={artifacts:new Map,emittedTexts:new Set,value:"",artifactOptions:h,finalTextSeen:!1,finalTextOnly:Vn(t,this.target)},_t=T?Zn(w,o,r,U):null;return g.stdout.setEncoding("utf8"),g.stdout.on("data",$=>this.handleStdout($,gt,b,i,n)),g.stderr.setEncoding("utf8"),g.stderr.on("data",$=>{jt+=$,this.target.emitStderr===!0&&n({sessionId:i,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:$}}})}),u==="stdin"?g.stdin.end(o):g.stdin.end(),await new Promise(($,Qe)=>{let W=!1,Kt=!1,L=null,Tt=_t&&Jn(this.target)?setInterval(()=>{try{It(b,_t,i,n)}catch(S){p("warn","runtime.cli","codex transcript stream poll failed",{target:this.agent.targetCode,sessionId:i,error:String(S?.message||S)})}},Se(this.target)):null;Tt?.unref?.();let qt=setTimeout(()=>{Kt=!0,p("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:i,pid:g.pid,timeoutMs:A}),rt(g,"SIGTERM"),L=setTimeout(()=>{p("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:i,pid:g.pid}),rt(g,"SIGKILL")},$n),L.unref?.(),yt(Object.assign(new Error(`runtime CLI timed out after ${A}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},A);qt.unref?.();let Jt=()=>{clearTimeout(qt),Tt&&clearInterval(Tt),L&&!Kt&&clearTimeout(L),tr(f,{target:this.agent.targetCode,sessionId:i}),this.active.delete(i)},tn=S=>{W||(W=!0,Jt(),$(S))},yt=S=>{W||(W=!0,Jt(),Qe(S))};g.on("error",S=>{p("warn","runtime.cli","runtime child error",{target:this.agent.targetCode,sessionId:i,pid:g.pid,error:String(S?.message||S)}),yt(S)}),g.on("exit",(S,Wt)=>{(async()=>{L&&(clearTimeout(L),L=null),gt==="json-lines"&&b.value.trim()&&this.handleStdout(`
11
+ `,gt,b,i,n);let H=await Tr(b,_t,i,n,E,this.target);(H.artifactCount>0||H.textCount>0)&&p("info","runtime.cli","codex transcript updates collected",{target:this.agent.targetCode,sessionId:i,artifactCount:H.artifactCount,textCount:H.textCount,finalTextCount:H.finalTextCount,transcriptCount:H.transcriptCount});let X=jt.trim();X&&p("debug","runtime.cli","runtime stderr",{target:this.agent.targetCode,sessionId:i,stderr:X}),p("info","runtime.cli","runtime prompt finished",{target:this.agent.targetCode,sessionId:i,pid:g.pid,exitCode:S,signal:Wt,artifactCount:b.artifacts.size,finalTextSeen:b.finalTextSeen}),tn({stopReason:S===0?"end_turn":"error",exitCode:S,signal:Wt,_artifacts:[...b.artifacts.values()],...X?{stderr:X}:{}})})().catch(yt)})})}buildArgs(t,n){let r=R(this.target.args);return t==="args"?[...r,n]:r}handleStdout(t,n,r,s,i){if(n!=="json-lines"){i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:t}}});return}r.value+=t;let o=r.value.split(/\r?\n/);r.value=o.pop()||"";for(let u of o){let l=u.trim();if(l)try{let d=JSON.parse(l);_e(r,ge(d,r.artifactOptions)),i({sessionId:s,update:{sessionUpdate:"runtime_event",event:Te(d)}});let f=he(d),m=ye(d);f&&Yn(r,m)&&!r.emittedTexts.has(f)&&(r.emittedTexts.add(f),i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:f}}})),f&&m&&(r.finalTextSeen=!0)}catch{i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`${u}
12
+ `}}})}}}async sessionCancel(t){let n=a(t.sessionId),r=this.active.get(n);return r?(p("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:n,pid:r.pid}),rt(r,"SIGTERM"),this.active.delete(n),{ok:!0,cancelled:!0}):{ok:!0,cancelled:!1}}stop(t="stop"){for(let[n,r]of this.active.entries())p("info","runtime.cli","stopping runtime child",{target:this.agent.targetCode,sessionId:n,pid:r.pid,reason:t}),rt(r,"SIGTERM");this.active.clear()}};var Ot=24e3,At=8,Ct=50,Mt=6e3,yr=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),Sr=10*60*1e3,xr=60*1e3,Rr=8,wr=60*1e3,Er=1,ct="ORCHA_RUNTIME_RESULT_START",Ce="ORCHA_RUNTIME_RESULT_END",Ir=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions","runtimeMaxSessions"]),Or=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function Ar(e,t,n){let r=c(e?._meta)?e._meta:{};return{...c(e)?e:{},sessionId:t,update:c(e?.update)?e.update:{},_meta:{...r,orchaAgentId:n.agentId,runtimeSessionId:n.runtimeSessionId,bridgeUpdateId:at()}}}function I(e){return e==null||e===""?!1:typeof e=="string"?a(e)!=="":Array.isArray(e)?e.length>0:c(e)?Object.keys(e).length>0:!0}function Me(e){let t=a(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return yr.has(t)}function D(e,t){let n=_(e,t);return Number.isFinite(n)&&n>0?n:t}function Nt(e){let t=_(e,null);return Number.isFinite(t)&&t>0?t:null}function J(e,t=!1){if(typeof e=="boolean")return e;let n=a(e).toLowerCase();return["true","1","yes","y","on"].includes(n)?!0:["false","0","no","n","off"].includes(n)?!1:t}function P(e){return a(e?.type||"echo")}function Cr(e){let t=P(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function bt(e){if(c(e)){if(Object.prototype.hasOwnProperty.call(e,"releaseAfterPrompt"))return e.releaseAfterPrompt;if(Object.prototype.hasOwnProperty.call(e,"disposeAfterPrompt"))return e.disposeAfterPrompt}}function Mr(e){let t=String(e||"");if(Or.test(t))return!0;let n=t.replace(/[^a-z0-9]/gi,"").toLowerCase();return n.endsWith("token")||n.endsWith("secret")||n.endsWith("password")||n.endsWith("apikey")||n.endsWith("privatekey")||n==="authorization"||n==="cookie"||n==="jwt"||n.includes("credential")}function kt(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=Mt)return e;let n=e.length-Mt;return`${e.slice(0,Mt)}... [truncated ${n} characters]`}if(t>=At)return Array.isArray(e)?`[array truncated at depth ${At}, items=${e.length}]`:c(e)?`[object truncated at depth ${At}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let n=e.slice(0,Ct).map(r=>kt(r,t+1));return e.length>Ct&&n.push(`[truncated ${e.length-Ct} items]`),n}if(c(e)){let n={};for(let[r,s]of Object.entries(e))n[r]=Mr(r)?"[REDACTED]":kt(s,t+1);return n}return String(e)}var Ur=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 Nr(e){if(!c(e))return e;let t={};for(let n of Ur)I(e[n])&&(t[n]=e[n]);return t}function br(e){if(!c(e))return e;let t={...e};return c(t.renderedPayload)&&(t.renderedPayload=Nr(t.renderedPayload)),t}function kr(e){let t=c(e)?e:{},n={};I(t.metadata)&&(n.metadata=br(t.metadata));for(let[r,s]of Object.entries(t))Ir.has(r)||r==="metadata"||I(s)&&(n[r]=s);return n}function Pr(e){let t=c(e)?e:{},n=c(t.metadata)?t.metadata:{},r=c(n.renderedPayload)?n.renderedPayload:{};return c(t.resultContract)?t.resultContract:c(r.resultContract)?r.resultContract:{}}function Ue(e){return a(Pr(e).kind).toLowerCase()==="decision"}function Ie(e){let t=c(e)?e:{},n=c(t.metadata)?t.metadata:{};return Nt(t.runtimeMaxSessions??n.runtimeMaxSessions)}function Lr(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:P(e)==="cli"}function Oe(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return J(t,Cr(e))}function Dr(e,t){let n=c(e?.metadata)?{...e.metadata}:{},r=c(n._runtimeBridge)?{...n._runtimeBridge}:{},s=bt(r);return n._runtimeBridge={...r,promptKind:"dispatch",finalTextOnly:Lr(t),releaseAfterPrompt:s===void 0?Oe(t):J(s,Oe(t)),requiresRuntimeResult:Ue(e)},n}function Fr(e){let t=kr(e);if(!I(t))return"";let n=JSON.stringify(kt(t),null,2);if(n.length<=Ot)return n;let r=n.length-Ot;return`${n.slice(0,Ot)}
13
+ ... [truncated ${r} characters]`}function Ne(e){if(!c(e))return"";let t=c(e.update)?e.update:e,r=(c(t.content)?t.content:{}).text??t.text;return r==null?"":String(r)}function $r(e){if(!c(e))return"";let t=c(e.update)?e.update:e;return a(t.sessionUpdate)}function Hr(e){if(!Array.isArray(e))return"";let t=!1,n=[],r=[],s=[],i=()=>{n.length>0&&(r.push(n),n=[])};for(let u of e){let l=$r(u),d=Ne(u);if(!l){d&&s.push(d);continue}if(t=!0,l==="agent_message_chunk"){d&&n.push(d);continue}(l==="agent_thought_chunk"||l==="user_message_chunk"||l==="tool_call"||l==="tool_call_update"||l==="plan")&&i()}if(i(),!t)return Pt(s);let o=r[r.length-1]||[];return Pt(o)}function vr(e){return Array.isArray(e)?e.map(Ne).filter(t=>a(t)):[]}function Br(e){if(!c(e))return null;let t=c(e.update)?e.update:e;return a(t.sessionUpdate)!=="runtime_event"?null:c(t.event)?t.event:null}function zr(e){if(!c(e))return"";let t=c(e.payload)?e.payload:{},n=a(e.type),r=a(t.type);if(n==="event_msg"){if(r==="task_complete")return a(t.last_agent_message||t.message||t.output);if(r==="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 Gr(e){if(!Array.isArray(e))return"";for(let t=e.length-1;t>=0;t-=1){let n=zr(Br(e[t]));if(n)return n}return""}function Pt(e){let t="";for(let n of e){let r=String(n||"");r&&(t?r.startsWith(t)?t=r:t.endsWith(r)||(t+=r):t=r)}return t.trim()}function jr(e){let t=String(e||"").trim();if(!t)return"";let n=t.match(/(?:^|\n)#{1,3}\s+\S/);return!n||n.index===0?t:t.slice(n.index+(t[n.index]===`
14
+ `?1:0)).trim()}function ut(e){let t=String(e||"").trim();if(!t)return null;try{let n=JSON.parse(t);if(c(n)&&(be(n)||I(n._artifacts)||I(n.artifacts)||I(n._decision)||I(n._meta)))return n}catch{}return null}function Kr(e){let t=String(e||"");if(!t)return"";let n=t.lastIndexOf(Ce);if(n<0)return"";for(let r=t.lastIndexOf(ct,n);r>=0;r=t.lastIndexOf(ct,r-1)){let s=t.slice(r+ct.length,n).trim();if(ut(s))return s}return""}function lt(e){let t=Kr(e);return t?ut(t):null}function Ae(e){let t=String(e||"").trim();if(!t)return null;let n=lt(t);if(n)return n;let r=[...t.matchAll(/```(?:json)?\s*([\s\S]*?)```/gi)];for(let s=r.length-1;s>=0;s-=1){let i=ut(r[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=ut(t.slice(s));if(i)return i}return null}function qr(e){let t=vr(e);for(let n=t.length-1;n>=0;n-=1){let r=lt(t[n]);if(r)return r}return lt(Pt(t))}function be(e){if(!c(e))return!1;if(I(e.output))return!0;for(let t of["content","text","message","summary"])if(a(e[t]))return!0;return!!(Me(e.status)||a(e.error)||a(e.errorMessage))}function M(e){let t=c(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 Jr(e){return c(e)?typeof(c(e._decision)?e._decision:c(e.decision)?e.decision:e).passed=="boolean":!1}function Wr(e){return c(e)?c(e._decision)&&typeof e._decision.passed=="boolean"?!0:Jr(e.output):!1}function Ut(e,t,n){let r=c(e)?{...e}:{};if(!I(r.output)){for(let s of["summary","message","content","text"])if(a(r[s])){r.output=a(r[s]);break}}return!I(r.output)&&a(n)&&(r.output=a(n)),{...r,_meta:{...c(r._meta)?r._meta:{},runtimeOutputSource:t,requiredRuntimeResult:!0,finalMessagePreview:a(n).slice(0,1e3)}}}function k(e,t,n){return{...e,...t,_meta:{...c(e._meta)?e._meta:{},...c(t._meta)?t._meta:{},runtimeOutputSource:n}}}function Xr(e,t,n={}){let r=a(n.promptKind),s=n.requiresRuntimeResult===!0,i=s||r==="dispatch",o=M(e),u=typeof o.output=="string"?lt(o.output):null;if(u)return k(o,M(u),"result_block");let l=Gr(t),d=l?Ae(l):null,f=i?qr(t):null;if(be(o))return Me(o.status)||a(o.error)||a(o.errorMessage)?o:r==="dispatch"&&d?k(o,M(d),"final_event"):r==="dispatch"&&f?k(o,M(f),"updates"):!s||Wr(o)?o:d?k(o,M(d),"final_event"):f?k(o,M(f),"updates"):Ut(o,"result",o.output);if(d)return k(o,M(d),"final_event");if(f)return k(o,M(f),"updates");if(l)return s?Ut(o,"final_event",l):{...o,output:l,_meta:{...c(o._meta)?o._meta:{},runtimeOutputSource:"final_event"}};let m=jr(Hr(t));if(!m)return o;let h=Ae(m);return h?k(o,M(h),"updates"):s?Ut(o,"updates",m):{...o,output:m,_meta:{...c(o._meta)?o._meta:{},runtimeOutputSource:"updates"}}}var dt=class{constructor(t){this.config=t,this.targets=t.targets||{},this.agents=new Map,this.sessions=new Map,this.runtimeSessionIndex=new Map,this.pendingPermissions=new Map,this.startedAt=j(),this.cleanupTimer=null,this.startSessionCleanup()}targetFor(t){let n=a(t)||this.config.defaultTargetCode,r=this.targets[n];if(!n||!c(r)){let s=new Error(`runtime target is not configured: ${n||"<empty>"}`);throw s.code="RUNTIME_TARGET_NOT_FOUND",s}return{code:n,target:r}}targetIdleTtlMs(t){let r=P(t)==="openclaw"?D(this.config.openClawSessionIdleTtlMs,wr):D(this.config.sessionIdleTtlMs,Sr);return D(t?.sessionIdleTtlMs??t?.idleTtlMs,r)}targetMaxSessions(t,n=null){let s=P(t)==="openclaw"?D(this.config.openClawMaxSessions,Er):D(this.config.maxSessionsPerTarget,Rr),i=D(t?.maxSessions,s),o=Nt(n);return o?Math.max(i,o):i}targetReleaseAfterPrompt(t,n={}){let r=P(t),s=c(n?._runtimeBridge)?n._runtimeBridge:{},i=bt(s);return i!==void 0?J(i,!1):J(t?.releaseAfterPrompt??t?.disposeAfterPrompt,r==="openclaw")}promptReleaseAfterPrompt(t,n={}){let r=c(n?._runtimeBridge)?n._runtimeBridge:{},s=bt(r);return s!==void 0?J(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=D(this.config.sessionCleanupIntervalMs,xr);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(n=>{p("warn","runtime-bridge","runtime session cleanup failed",{error:String(n)})})},t),this.cleanupTimer.unref?.())}sessionCountForTarget(t){let n=0;for(let r of this.sessions.values())r.targetCode===t&&(n+=1);return n}sessionCountForAgentTarget(t,n){let r=0;for(let s of this.sessions.values())s.agentId===t&&s.targetCode===n&&(r+=1);return r}idleTargetSessions(t){return[...this.sessions.entries()].filter(([,n])=>n.targetCode===t&&!n.busy).sort((n,r)=>(n[1].lastUsedAtMs||0)-(r[1].lastUsedAtMs||0))}idleAgentTargetSessions(t,n){return[...this.sessions.entries()].filter(([,r])=>r.agentId===t&&r.targetCode===n&&!r.busy).sort((r,s)=>(r[1].lastUsedAtMs||0)-(s[1].lastUsedAtMs||0))}async closeSession(t,n="session_closed"){let r=this.sessions.get(t);if(!r)return!1;try{await r.runtime?.stop?.(n)}catch(s){p("warn","runtime-bridge","runtime session stop failed",{sessionId:r.sessionId,runtimeSessionId:r.runtimeSessionId,targetCode:r.targetCode,runtimeKind:r.runtimeKind,error:String(s)})}return this.sessions.delete(t),this.runtimeSessionIndex.delete(`${r.agentId}:${r.runtimeSessionId}`),p("info","runtime-bridge","runtime session closed",{sessionId:r.sessionId,runtimeSessionId:r.runtimeSessionId,targetCode:r.targetCode,runtimeKind:r.runtimeKind,reason:n}),!0}async closeAllSessions(t="bridge_shutdown"){for(let n of[...this.sessions.keys()])await this.closeSession(n,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[n,r]of[...this.sessions.entries()])r.busy||t-(r.lastUsedAtMs||r.createdAtMs||t)>r.idleTtlMs&&await this.closeSession(n,"idle_timeout")}async reserveTargetSlot(t,n,r={}){let s=a(r.agentId),i=Nt(r.runtimeMaxSessions);if(s&&i)for(;this.sessionCountForAgentTarget(s,t)>=i;){let u=this.idleAgentTargetSessions(s,t);if(!u.length){let l=new Error(`runtime agent session limit reached: ${s}`);throw l.code="RUNTIME_AGENT_SESSION_LIMIT",l}await this.closeSession(u[0][0],"agent_session_limit")}let o=this.targetMaxSessions(n,i);for(;this.sessionCountForTarget(t)>=o;){let u=this.idleTargetSessions(t);if(!u.length){let l=new Error(`runtime target session limit reached: ${t}`);throw l.code="RUNTIME_TARGET_SESSION_LIMIT",l}await this.closeSession(u[0][0],"target_session_limit")}}async createAgent(t){let n=a(t.agentId);if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let{code:r,target:s}=this.targetFor(t.targetCode||t.framework),i={agentId:n,targetCode:r,framework:a(t.framework||r),workspace:a(t.workspace),metadata:c(t.metadata)?t.metadata:{},createdAt:j(),runtimeKind:P(s),runtimeMaxSessions:Ie(t)};return this.agents.set(n,i),{agent:i}}runtimeFor(t,n){let{target:r}=this.targetFor(t.targetCode),s=P(r),i={onPermissionRequest:u=>this.requestPermission(u)},o={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs};return s==="stdio-acp"||s==="acp"?new B(t,r,i,o):s==="openclaw"?new et(t,r,n,i,o):s==="cli"?new ot(t,r,o):new Y(t)}async prompt(t,n={}){let r=a(t.agentId),s=a(t.sessionId)||at();if(!r)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let i=this.agents.get(r)||(await this.createAgent({agentId:r,targetCode:t.targetCode,framework:t.framework,workspace:t.workspace,runtimeMaxSessions:t.runtimeMaxSessions,metadata:t.metadata})).agent,o=Ie(t);o&&(i.runtimeMaxSessions=o);let u=a(t.workspace);u&&u!==i.workspace&&(i.workspace=u);let l=`${r}:${s}`;await this.cleanupExpiredSessions();let d=this.sessions.get(l);if(!d){let{code:h,target:T}=this.targetFor(i.targetCode);await this.reserveTargetSlot(h,T,{agentId:r,runtimeMaxSessions:i.runtimeMaxSessions});let w=this.runtimeFor(i,s),U=await w.sessionNew({cwd:i.workspace||process.cwd(),metadata:c(t.metadata)?t.metadata:{}}),E=Date.now();d={agentId:r,sessionId:s,runtime:w,targetCode:h,runtimeKind:P(T),runtimeSessionId:a(c(U)?U.sessionId:"")||s,idleTtlMs:this.targetIdleTtlMs(T),releaseAfterPrompt:this.targetReleaseAfterPrompt(T,t.metadata),createdAtMs:E,lastUsedAtMs:E,busy:!1,createdAt:j()},this.sessions.set(l,d),this.runtimeSessionIndex.set(`${r}:${d.runtimeSessionId}`,d)}if(d.busy){let h=new Error(`runtime session is already running: ${s}`);throw h.code="RUNTIME_SESSION_BUSY",h}d.busy=!0,d.lastUsedAtMs=Date.now();let f=[],m=h=>{let T=Ar(h,s,d);f.push(T),n.onUpdate?.(T)};try{let h=await d.runtime.sessionPrompt({sessionId:d.runtimeSessionId,prompt:Array.isArray(t.prompt)?t.prompt:[],metadata:c(t.metadata)?t.metadata:{}},m),T=c(t.metadata)?t.metadata:{},w=c(T._runtimeBridge)?T._runtimeBridge:{},U=Xr(h,f,w);return{sessionId:s,runtimeSessionId:d.runtimeSessionId,result:U,updates:f}}finally{d.busy=!1,d.lastUsedAtMs=Date.now(),this.promptReleaseAfterPrompt(d,c(t.metadata)?t.metadata:{})&&await this.closeSession(l,"release_after_prompt")}}async cancel(t){let n=a(t.agentId),r=a(t.sessionId),s=`${n}:${r}`,i=this.sessions.get(s);return i?(await i.runtime.sessionCancel({sessionId:i.runtimeSessionId}),await this.closeSession(s,"cancelled"),{cancelled:!0}):{cancelled:!1}}async dispatch(t,n={}){let r=a(t.agentId),s=a(t.taskId),i=a(t.executionId);if(!r||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let o=a(t.sessionId)||`dispatch-${i||s}`,u=a(t.instructions),l=Fr(t),d=Ue(t),{target:f}=this.targetFor(t.targetCode||t.framework),m=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",u?`instructions: ${u}`:"",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 ![illustration](orcha-artifact://image/0) 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, wrap the final Orcha Runtime Result JSON between ${ct} and ${Ce}.`:"",d?"The result block must contain exactly one valid JSON object with output and _decision; escape Markdown newlines inside JSON strings as \\n.":"",d?"Do not put process notes inside the result block; text outside the block is ignored by Orcha.":"","Return only the final answer required by that protocol.","Do not include process notes, logs, or explanations."].filter(Boolean).join(`
15
+ `)}];return this.prompt({...t,agentId:r,sessionId:o,prompt:m,metadata:Dr(t,f)},n)}async requestPermission({agent:t,runtimeSessionId:n,request:r,emitUpdate:s}){let i=at(),u=this.runtimeSessionIndex.get(`${t.agentId}:${n}`)?.sessionId||n||at(),l={permissionId:i,agentId:t.agentId,sessionId:u,runtimeSessionId:n,request:c(r)?r:{},status:"pending",createdAt:j()};return s?.({sessionId:n,update:{sessionUpdate:"permission_request",permission:l}}),await new Promise(d=>{let f=_(r?.timeoutMs,this.config.permissionRequestTimeoutMs),m=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:m,resolve:d,permission:l})})}async respondPermission(t){let n=a(t.permissionId),r=this.pendingPermissions.get(n),s=a(t.outcome||"approved")||"approved";return r?(clearTimeout(r.timer),this.pendingPermissions.delete(n),r.resolve({permissionId:n,outcome:s,response:c(t.response)?t.response:{},userId:a(t.userId),metadata:c(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:n,outcome:s}):{accepted:!1,permissionId:n,outcome:s}}health(){return{status:"ok",bridgeVersion:v,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)}}};import Vr from"node:http";import Yr from"node:https";import{randomBytes as ke}from"node:crypto";var ft=1,Lt=3,pt=class{constructor(t){this.url=t,this.readyState=0,this.socket=null,this.buffer=Buffer.alloc(0),this.listeners=new Map,this.connect()}addEventListener(t,n){let r=this.listeners.get(t)||new Set;r.add(n),this.listeners.set(t,r)}emit(t,n={}){let r=this.listeners.get(t);if(r)for(let s of r)s(n)}connect(){let t=new URL(this.url),n=t.protocol==="wss:"?Yr:Vr,r=ke(16).toString("base64"),s=n.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":r,"Sec-WebSocket-Version":"13"}});s.on("upgrade",(i,o,u)=>{this.socket=o,this.readyState=ft,o.on("data",l=>this.onData(l)),o.on("close",()=>this.onClose()),o.on("error",l=>{this.emit("error",{error:l,message:l.message,type:"error"}),this.onClose()}),u?.length&&this.onData(u),this.emit("open")}),s.on("response",i=>{this.emit("error",{message:`websocket upgrade failed: HTTP ${i.statusCode}`,type:"error"}),i.resume(),this.onClose()}),s.on("error",i=>{this.emit("error",{error:i,message:i.message,type:"error"}),this.onClose()}),s.end()}send(t){!this.socket||this.readyState!==ft||this.socket.write(Dt(1,Buffer.from(String(t),"utf8")))}close(){!this.socket||this.readyState===Lt||(this.socket.write(Dt(8,Buffer.alloc(0))),this.socket.end(),this.onClose())}onClose(){this.readyState!==Lt&&(this.readyState=Lt,this.emit("close"))}onData(t){for(this.buffer=Buffer.concat([this.buffer,t]);this.buffer.length>=2;){let n=this.buffer[0],r=this.buffer[1],s=n&15,i=(r&128)!==0,o=r&127,u=2;if(o===126){if(this.buffer.length<u+2)return;o=this.buffer.readUInt16BE(u),u+=2}else if(o===127){if(this.buffer.length<u+8)return;let f=this.buffer.readUInt32BE(u),m=this.buffer.readUInt32BE(u+4);o=f*2**32+m,u+=8}let l=u;if(i&&(u+=4),this.buffer.length<u+o)return;let d=this.buffer.subarray(u,u+o);if(i){let f=this.buffer.subarray(l,l+4);d=Buffer.from(d.map((m,h)=>m^f[h%4]))}this.buffer=this.buffer.subarray(u+o),s===1?this.emit("message",{data:d.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(Dt(10,d))}}};function Dt(e,t){let n=t.length,r=2;n>=126&&n<=65535?r+=2:n>65535&&(r+=8);let s=ke(4),i=Buffer.alloc(r+4+n);i[0]=128|e;let o=2;n<126?i[1]=128|n:n<=65535?(i[1]=254,i.writeUInt16BE(n,o),o+=2):(i[1]=255,i.writeUInt32BE(Math.floor(n/2**32),o),i.writeUInt32BE(n>>>0,o+4),o+=8),s.copy(i,o),o+=4;for(let u=0;u<n;u+=1)i[o+u]=t[u]^s[u%4];return i}function Zr(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 Qr(e){return Object.entries(e||{}).map(([t,n])=>({targetCode:t,targetName:a(n?.name||n?.targetName||t),targetType:a(n?.type||"echo"),status:"available",metadata:c(n)?n:{}}))}var mt=class{constructor(t,n){this.config=t,this.bridge=n,this.ws=null,this.stopped=!1,this.connected=!1,this.reconnectTimer=null}start(){this.connect()}stop(){this.stopped=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.ws?.close()}connect(){let t=Zr(this.config.orchaUrl),n=new pt(t);this.ws=n,n.addEventListener("open",()=>this.authenticate()),n.addEventListener("message",r=>this.handleMessage(r.data)),n.addEventListener("close",()=>this.scheduleReconnect("close")),n.addEventListener("error",r=>{p("warn","orcha-client","runtime node websocket error",{error:String(r?.message||r?.type||r)})})}authenticate(){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:v,protocolVersion:"orcha-runtime-node.v1",defaultTargetCode:this.config.defaultTargetCode,targets:Qr(this.config.targets)})}scheduleReconnect(t){this.connected=!1,!this.stopped&&(this.reconnectTimer||(p("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){let n;try{n=JSON.parse(String(t))}catch(r){p("warn","orcha-client","invalid Orcha websocket frame",{error:String(r)});return}if(c(n)){if(n.type==="runtime_node.authenticated"){this.connected=!0,p("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()})}}async handleRequest(t){let n=a(t.id),r=a(t.method),s=c(t.params)?t.params:{};try{let i=await this.invoke(r,s,n);this.send({type:"orcha.runtime.response",id:n,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:n,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i)}})}}async invoke(t,n,r){if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(n);if(t==="agents/dispatch")return this.bridge.dispatch(n,{onUpdate:s=>this.sendUpdate(r,s)});if(t==="sessions/prompt")return this.bridge.prompt(n,{onUpdate:s=>this.sendUpdate(r,s)});if(t==="sessions/cancel")return this.bridge.cancel(n);if(t==="permissions/respond")return this.bridge.respondPermission(n);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,n){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:n})}send(t){return!this.ws||this.ws.readyState!==ft?!1:(this.ws.send(JSON.stringify(t)),!0)}};import{existsSync as ts,readFileSync as es}from"node:fs";import{resolve as Pe}from"node:path";var ns=/^[A-Za-z_][A-Za-z0-9_]*$/;function Le(e=process.env,t=process.cwd()){let n=a(e.ORCHA_RUNTIME_ENV_FILE),r=n?Pe(t,n):Pe(t,".env");if(!ts(r))return n&&p("warn","config","runtime env file not found",{path:r}),{loaded:!1,path:r,keys:[]};let s=[],i=es(r,"utf8");for(let o of i.split(/\r?\n/)){let u=ss(o);if(!u)continue;let[l,d]=u;Object.prototype.hasOwnProperty.call(e,l)||(e[l]=d,s.push(l))}return p("info","config","runtime env file loaded",{path:r,keyCount:s.length}),{loaded:!0,path:r,keys:s}}function De(e=process.env){return{mode:a(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),host:e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1",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),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:_(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),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),targets:rs(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function rs(e){if(!a(e))return{};try{let t=JSON.parse(e);if(c(t))return t}catch(t){p("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function ss(e){let t=e.trim();if(!t||t.startsWith("#"))return null;let n=t.startsWith("export ")?t.slice(7).trimStart():t,r=n.indexOf("=");if(r<=0)return null;let s=n.slice(0,r).trim();if(!ns.test(s))return null;let i=is(n.slice(r+1).trim());return[s,i]}function is(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let n=e.slice(1,-1);return t==='"'?os(n):n}return as(e).trim()}function os(e){return e.replaceAll("\\n",`
16
+ `).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function as(e){let t=!1,n=!1;for(let r=0;r<e.length;r+=1){let s=e[r],i=e[r-1];if(s==="'"&&!n)t=!t;else if(s==='"'&&!t&&i!=="\\")n=!n;else if(s==="#"&&!t&&!n&&/\s/.test(i||""))return e.slice(0,r)}return e}import{createServer as cs}from"node:http";function ht(e,t,n){let r=JSON.stringify(n);e.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(r)}),e.end(r)}function F(e={}){return{ok:!0,...e}}function Ft(e,t,n){return{ok:!1,error:{code:e,message:t,...n===void 0?{}:{detail:n}}}}async function Fe(e,t){let n=[],r=0;for await(let i of e){if(r+=i.length,r>t)throw Object.assign(new Error("request body too large"),{status:413,code:"REQUEST_TOO_LARGE"});n.push(i)}if(n.length===0)return{};let s=Buffer.concat(n).toString("utf8");if(!s.trim())return{};try{let i=JSON.parse(s);if(!c(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 $e(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 He(e,t){let n={"GET /health":async()=>F(t.health()),"POST /agents/create":async r=>F(await t.createAgent(r)),"POST /agents/dispatch":async r=>F(await t.dispatch(r)),"POST /sessions/prompt":async r=>F(await t.prompt(r)),"POST /sessions/cancel":async r=>F(await t.cancel(r)),"POST /permissions/respond":async r=>F(await t.respondPermission(r))};return cs(async(r,s)=>{let i=new URL(r.url||"/",`http://${r.headers.host||`${e.host}:${e.port}`}`),o=`${r.method||"GET"} ${i.pathname}`,u=n[o];if(!u){ht(s,404,Ft("NOT_FOUND",`No route for ${o}`));return}try{$e(r,e.token);let l=r.method==="GET"?{}:await Fe(r,e.requestLimitBytes);ht(s,200,await u(l))}catch(l){let d=l.status||500,f=l.code||"BRIDGE_INTERNAL";ht(s,d,Ft(f,l.message||String(l)))}})}var gs=hs(import.meta.url),_s=".orcha-runtime-bridge.pid",Ts=".orcha-runtime-bridge.log",ys=3,Ss=36e5,{command:xs,options:Xe}=Is(process.argv.slice(2));Os(Xe);Le();var Rs=De();await ws(xs,Rs,Xe);async function ws(e,t,n){switch(e){case"run":case"foreground":Be(t);return;case"start":if(n.foreground){Be(t);return}Ge();return;case"reload":case"restart":await je({quiet:!0}),Ge();return;case"stop":await je();return;case"status":Es();return;case"help":case"--help":case"-h":Us();return;default:throw new Error(`Unknown command: ${e}`)}}function Be(e){As();let t=new dt(e);if(e.mode==="server"){let r=He(e,t);ze({bridge:t,server:r}),r.listen(e.port,e.host,()=>{p("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 n=new mt(e,t);ze({bridge:t,client:n}),n.start(),p("info","runtime-bridge","Orcha runtime node started",{nodeId:e.nodeId,nodeName:e.nodeName,orchaUrl:e.orchaUrl,targets:Object.keys(t.targets)})}function ze({bridge:e,client:t,server:n}){let r=!1,s=i=>{if(r)return;r=!0;let o=Number(e?.sessions?.size||0)>0;p("info","runtime-bridge","runtime bridge shutting down",{signal:i});try{t?.stop?.()}catch(u){p("warn","runtime-bridge","runtime client stop failed",{error:String(u)})}Promise.resolve(e?.stop?.(`process_${String(i||"shutdown").toLowerCase()}`)).catch(u=>{p("warn","runtime-bridge","runtime bridge stop failed",{error:String(u)})}).finally(()=>{try{n?.close?.()}catch(u){p("warn","runtime-bridge","runtime server close failed",{error:String(u)})}}),setTimeout(()=>process.exit(0),o?8500:200)};process.once("SIGTERM",()=>s("SIGTERM")),process.once("SIGINT",()=>s("SIGINT"))}function Ge(){let e=zt(),t=Ve(),n=Gt(e);if(n&&z(n)){console.log(JSON.stringify({status:"already_running",pid:n,pidFile:e,logFile:t}));return}n&&vt(e),qe(e),qe(t),Ht(t);let r=fs(t,"a"),s={...process.env,ORCHA_RUNTIME_PID_FILE:e,ORCHA_RUNTIME_LOG_FILE:t},i=us(process.execPath,[gs,"run"],{cwd:process.cwd(),detached:!0,env:s,stdio:["ignore",r,r]});i.unref(),ls(r),We(e,`${i.pid}
17
+ `),console.log(JSON.stringify({status:"started",pid:i.pid,pidFile:e,logFile:t}))}async function je({quiet:e=!1}={}){let t=zt(),n=Gt(t);if(!n){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!z(n)){vt(t),e||console.log(JSON.stringify({status:"not_running",pid:n,pidFile:t}));return}process.kill(n,"SIGTERM"),!await Ke(n,1e4)&&z(n)&&(process.kill(n,"SIGKILL"),await Ke(n,3e3)),vt(t),e||console.log(JSON.stringify({status:"stopped",pid:n,pidFile:t}))}function Es(){let e=zt(),t=Ve(),n=Gt(e),r=!!(n&&z(n));console.log(JSON.stringify({status:r?"running":"not_running",running:r,pid:r?n:null,pidFile:e,logFile:t}))}function Is(e){let t=[],n={};for(let s=0;s<e.length;s+=1){let i=e[s];i==="--daemon"?n.daemon=!0:i==="--foreground"?n.foreground=!0:i==="--env-file"?n.envFile=e[++s]:i==="--pid-file"?n.pidFile=e[++s]:i==="--log-file"?n.logFile=e[++s]:t.push(i)}return{command:t[0]||"run",options:n}}function Os(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 zt(){return Bt(process.cwd(),process.env.ORCHA_RUNTIME_PID_FILE||_s)}function Ve(){return Bt(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||Ts)}function As(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=Ye();if(t<=0)return;let n=Bt(process.cwd(),e);Ht(n,t);let r=Ms();r<=0||setInterval(()=>Ht(n,t),r).unref()}function Ht(e,t=Ye()){if(t<=0||!Je(e))return;let n=0,r="";try{if(n=ve(e).size,n<=0)return;r=$t(e,"utf8")}catch(d){p("warn","runtime-bridge","runtime log cleanup skipped",{logFile:e,error:String(d)});return}let s=Date.now()-t*24*60*60*1e3,i=r.split(/\r?\n/),o=[],u=0;for(let d of i)d&&(Cs(d,s)?o.push(d):u+=1);if(u===0)return;let l="";try{ve(e).size>n&&(l=$t(e,"utf8").slice(r.length));let f=[...o,...l.split(/\r?\n/).filter(Boolean)].join(`
18
+ `);We(e,f?`${f}
19
+ `:""),p("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:u})}catch(d){p("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function Cs(e,t){try{let n=JSON.parse(e);if(!n||typeof n!="object")return!0;let r=typeof n.ts=="string"?Date.parse(n.ts):Number.NaN;return!Number.isFinite(r)||r>=t}catch{return!0}}function Ye(){return Ze(process.env.ORCHA_RUNTIME_LOG_RETENTION_DAYS,ys)}function Ms(){return Ze(process.env.ORCHA_RUNTIME_LOG_CLEANUP_INTERVAL_MS,Ss)}function Ze(e,t){let n=Number.parseInt(String(e??""),10);return Number.isFinite(n)&&n>=0?n:t}function Gt(e){if(!Je(e))return null;let t=Number.parseInt($t(e,"utf8").trim(),10);return Number.isInteger(t)&&t>0?t:null}function z(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function Ke(e,t){let n=Date.now();for(;Date.now()-n<t;){if(!z(e))return!0;await new Promise(r=>setTimeout(r,100))}return!z(e)}function qe(e){ds(ms(e),{recursive:!0})}function vt(e){try{ps(e,{force:!0})}catch{}}function Us(){console.log(`Usage: orcha-runtime-bridge [command] [options]
20
20
 
21
21
  Commands:
22
22
  run, foreground Run in the foreground. This is the default.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orcha-ai/runtime-bridge",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Local Orcha runtime bridge for ACP-compatible agent runtimes.",