@orcha-ai/runtime-bridge 0.1.3 → 0.1.4
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/bin/orcha-runtime-bridge.js +14 -12
- package/package.json +1 -1
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawn as
|
|
3
|
-
`):""}var
|
|
2
|
+
import{spawn as rn}from"node:child_process";import{closeSync as nn,existsSync as Te,mkdirSync as sn,openSync as on,readFileSync as Rt,rmSync as an,statSync as pe,writeFileSync as we}from"node:fs";import{dirname as cn,resolve as xt}from"node:path";import{fileURLToPath as un}from"node:url";import{randomUUID as Z}from"node:crypto";var k="0.1.4";function F(){return new Date().toISOString()}function _(e,t=2){return String(e).padStart(t,"0")}function Pt(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${_(Math.floor(r/60))}:${_(r%60)}`}function Ae(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${_(e.getMonth()+1)}-${_(e.getDate())}`,`T${_(e.getHours())}:${_(e.getMinutes())}:${_(e.getSeconds())}.${_(e.getMilliseconds(),3)}`,Pt(t)].join("")}function Ue(e,t){let r=new Intl.DateTimeFormat("en-US",{timeZone:t,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}),n={};for(let s of r.formatToParts(e))s.type!=="literal"&&(n[s.type]=Number(s.value));return n}function Ce(e,t){let r=Ue(e,t),n=Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second,e.getMilliseconds()),s=Math.round((n-e.getTime())/6e4);return[`${r.year}-${_(r.month)}-${_(r.day)}`,`T${_(r.hour)}:${_(r.minute)}:${_(r.second)}.${_(e.getMilliseconds(),3)}`,Pt(s)].join("")}function Ne(e=new Date){let t=o(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return Ce(e,t)}catch{return Ae(e)}}function u(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function o(e){return String(e??"").trim()}function w(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)?r:t}function I(e){return Array.isArray(e)?e.map(String):[]}var Me="[redacted]",be=/(authorization|api[_-]?key|credential|password|secret|token)/i;function L(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 n={name:e.name,message:e.message};e.stack&&(n.stack=e.stack);for(let s of Object.keys(e))n[s]=L(e[s],t);return t.delete(e),n}if(t.has(e))return"[circular]";if(t.add(e),Array.isArray(e)){let n=e.map(s=>L(s,t));return t.delete(e),n}let r={};for(let[n,s]of Object.entries(e))r[n]=be.test(n)?Me:L(s,t);return t.delete(e),r}function Dt(e,t=4e3){let r=JSON.stringify(L(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function p(e,t,r,n={}){let s={ts:Ne(),level:e,module:t,msg:r,...u(n)?L(n):{}};console.error(JSON.stringify(s))}function j(e){return Array.isArray(e)?e.map(t=>u(t)?t.type==="text"?o(t.text):t.type==="file"?o(t.uri):t.type==="image"?o(t.uri):"":"").filter(Boolean).join(`
|
|
3
|
+
`):""}var G=class{constructor(t){this.agent=t,this.sessionCounter=0}async sessionNew(){return this.sessionCounter+=1,{sessionId:`echo-${this.agent.agentId}-${this.sessionCounter}`}}async sessionPrompt(t,r){let n=j(t.prompt);return r({sessionId:t.sessionId,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:n?`Echo runtime received: ${n}`:"Echo runtime received an empty prompt."}}}),{stopReason:"end_turn"}}async sessionCancel(){return{ok:!0}}};import{spawn as ke}from"node:child_process";var $="2.0",Pe=3e4;function De(e){return{code:Number.isInteger(e?.code)?e.code:-32e3,message:o(e?.message)||String(e),data:u(e?.data)?e.data:void 0}}function Le(e){if(!u(e))return new Error(String(e||"runtime error"));let t=o(e.message)||"runtime error",r="data"in e?Dt(e.data,4e3):"",n=new Error(r?`${t}; data=${r}`:t);return n.rpcCode=e.code,n.data=e.data,n}function Fe(e){return u(e)&&"id"in e&&!("method"in e)}function $e(e){return u(e)&&typeof e.method=="string"&&"id"in e}function ve(e){return u(e)&&typeof e.method=="string"&&!("id"in e)}var J=class{constructor({command:t,args:r=[],cwd:n,env:s,label:i,framing:c="line"}){this.command=t,this.args=Array.isArray(r)?r.map(String):[],this.cwd=n||process.cwd(),this.env={...process.env,...u(s)?s:{}},this.label=i||t,this.framing=c==="content-length"?"content-length":"line",this.child=null,this.lineBuffer="",this.headerBuffer=Buffer.alloc(0),this.seq=0,this.pending=new Map,this.notificationHandlers=new Map,this.requestHandlers=new Map,this.exitHandlers=new Set}async start({initialize:t=!0,initializeParams:r={}}={}){this.child&&!this.child.killed||(this.child=ke(this.command,this.args,{cwd:this.cwd,env:this.env,stdio:["pipe","pipe","pipe"]}),this.child.stdout.on("data",n=>this.onStdout(n)),this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",n=>{let s=n.trimEnd();s&&p("debug","runtime.stderr","runtime stderr",{target:this.label,text:s})}),this.child.on("exit",(n,s)=>this.handleExit(n,s)),this.child.on("error",n=>this.rejectAll(n)),t&&await this.call("initialize",{protocolVersion:1,clientCapabilities:{},...r}).catch(n=>{throw Object.assign(new Error(`runtime initialize failed: ${n.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 r=this.lineBuffer.split(/\r?\n/);this.lineBuffer=r.pop()||"";for(let n of r){let s=n.trim();s&&this.dispatchRaw(s)}}onContentLengthData(t){for(this.headerBuffer=Buffer.concat([this.headerBuffer,t]);this.headerBuffer.length>0;){let r=this.headerBuffer.indexOf(`\r
|
|
4
4
|
\r
|
|
5
|
-
`);if(
|
|
5
|
+
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).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),c=r+4,a=c+i;if(this.headerBuffer.length<a)return;let d=this.headerBuffer.subarray(c,a).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(a),this.dispatchRaw(d)}}dispatchRaw(t){let r;try{r=JSON.parse(t)}catch(n){p("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(n)});return}this.dispatch(r)}dispatch(t){if(Fe(t)){this.resolveResponse(t);return}if($e(t)){this.handleRequest(t);return}ve(t)&&this.handleNotification(t)}resolveResponse(t){let r=String(t.id),n=this.pending.get(r);n&&(clearTimeout(n.timer),this.pending.delete(r),t.error?(p("warn","runtime.protocol","runtime rpc error",{target:this.label,method:n.method,requestId:r,error:t.error}),n.reject(Le(t.error))):n.resolve(t.result))}async handleRequest(t){let r=this.requestHandlers.get(t.method);if(!r){this.writeFrame({jsonrpc:$,id:t.id,error:{code:-32601,message:`method not found: ${t.method}`}});return}try{let n=await r(u(t.params)?t.params:{},t);this.writeFrame({jsonrpc:$,id:t.id,result:n??{}})}catch(n){this.writeFrame({jsonrpc:$,id:t.id,error:De(n)})}}handleNotification(t){let r=this.notificationHandlers.get(t.method);if(r)for(let n of r)n(u(t.params)?t.params:{},t)}call(t,r={},n=Pe){if(!this.child||!this.child.stdin||this.child.killed)return Promise.reject(new Error("runtime process is not running"));let s=`${t}_${++this.seq}`,i={jsonrpc:$,id:s,method:t,params:r};return new Promise((c,a)=>{let d=setTimeout(()=>{this.pending.delete(s),a(new Error(`${t} timed out after ${n}ms`))},n);this.pending.set(s,{resolve:c,reject:a,timer:d,method:t}),this.writeFrame(i,l=>{l&&(clearTimeout(d),this.pending.delete(s),a(l))})})}notify(t,r={}){this.writeFrame({jsonrpc:$,method:t,params:r})}writeFrame(t,r){if(!this.child?.stdin||this.child.killed){r?.(new Error("runtime process is not running"));return}let n=JSON.stringify(t),s=this.framing==="content-length"?`Content-Length: ${Buffer.byteLength(n,"utf8")}\r
|
|
6
6
|
\r
|
|
7
7
|
${n}`:`${n}
|
|
8
|
-
`;this.child.stdin.write(s,e)}onNotification(t,e){let n=this.notificationHandlers.get(t)||new Set;return n.add(e),this.notificationHandlers.set(t,n),()=>{n.delete(e),n.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,e){return this.requestHandlers.set(t,e),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let e of this.pending.values())clearTimeout(e.timer),e.reject(t);this.pending.clear()}handleExit(t,e){this.rejectAll(new Error(`runtime exited before response (${t}/${e})`));for(let n of this.exitHandlers)n(t,e)}stop(t="stop"){!this.child||this.child.killed||(f("info","runtime","stopping runtime",{target:this.label,reason:t}),this.child.kill("SIGTERM"),setTimeout(()=>{this.child&&!this.child.killed&&this.child.kill("SIGKILL")},5e3).unref())}};import{randomUUID as Ot}from"node:crypto";import{existsSync as Re,readFileSync as xe,statSync as Ue}from"node:fs";import{basename as At,extname as Nt}from"node:path";var Oe=25*1024*1024;function Mt(r,t=""){let e=c(t);if(e)return e;let n=Nt(c(r)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function Ct(r,t){let e=typeof r=="string"?r.trim():"";return!e||e==="<omitted>"?"":e.startsWith("data:")?e:`data:${t};base64,${e.replace(/\s+/g,"")}`}function rt(r,t){let e=c(r);if(!e||!Re(e))return"";try{let n=Ue(e);return!n.isFile()||n.size<=0||n.size>Oe?"":`data:${t};base64,${xe(e).toString("base64")}`}catch{return""}}function y(...r){for(let t of r){let e=c(t);if(e)return e}return""}function Ae(r,t){let e=c(r);return!e||e.startsWith("data:")||/^https?:\/\//i.test(e)?e:rt(e,t)||e}function Ne(r,t,e,n){let s=e.toLowerCase();if(s==="image"||s==="picture")return!0;let i=y(n,r.previewUrl,r.fileUrl,r.imageUrl,r.dataUrl,r.url,r.uri,t.previewUrl,t.fileUrl,t.imageUrl,t.dataUrl,t.url,t.uri),a=Nt(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(a)}function nt(r,{source:t="runtime_image_generation_event"}={}){if(!d(r))return null;let e=d(r.payload)?r.payload:{},n=c(r.type),s=c(e.type);if(!(n==="event_msg"&&s==="image_generation_end"||n==="response_item"&&s==="image_generation_call"))return null;let i=y(e.call_id,e.id),a=y(e.saved_path,e.savedPath),o=y(e.revised_prompt,e.revisedPrompt),u=Mt(a,e.mimeType||e.mime_type),p=Ct(e.result,u)||rt(a,u)||a;if(!p)return null;let h=a?At(a):`${i||Ot()}.png`;return{artifactType:"image",type:"image",title:h||"Generated image",summary:o||"Generated image",content:{prompt:o||void 0,imageUrl:p,previewUrl:p,fileUrl:p,mimeType:u},previewUrl:p,fileUrl:p,metadata:{source:t,eventType:s,callId:i||void 0,savedPath:a||void 0,filename:h,mimeType:u,revisedPrompt:o||void 0}}}function Me(r){let t=d(r)?r:{},e=[];for(let n of["_artifacts","artifacts"]){let s=t[n];Array.isArray(s)&&e.push(...s)}for(let n of["_artifact","artifact"]){let s=t[n];d(s)&&e.push(s)}return e}function Ce(r,{source:t="runtime_artifact"}={}){let e=d(r)?r:{};if(!Object.keys(e).length)return null;let n=d(e.content)?{...e.content}:{},s=d(e.metadata)?{...e.metadata}:{},i=y(e.saved_path,e.savedPath,n.saved_path,n.savedPath,s.savedPath),a=y(e.mimeType,e.mime_type,n.mimeType,n.mime_type,s.mimeType),o=y(e.artifactType,e.artifact_type,e.type,e.kind,n.type,i?"image":"file"),u=Ne(e,n,o,i),l=u?Mt(i,a):a;if(u){let T=y(e.dataUrl,n.dataUrl),S=y(e.imageUrl,e.previewUrl,e.fileUrl,e.downloadUrl,e.url,e.uri,n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri),g=Ct(e.result??n.result,l)||T||rt(i,l)||Ae(S,l)||i;g&&(n.imageUrl||=g,n.previewUrl||=g,n.fileUrl||=g,l&&(n.mimeType||=l))}for(let[T,S]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let g=e[T];g!=null&&g!==""&&!(S in n)&&(n[S]=g)}let p=y(e.fileUrl,e.downloadUrl,e.imageUrl,e.dataUrl,e.url,e.uri,n.fileUrl,n.downloadUrl,n.imageUrl,n.dataUrl,n.url,n.uri),h=y(e.previewUrl,e.imageUrl,e.dataUrl,e.url,e.fileUrl,e.uri,n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri),m=y(e.filename,s.filename,i?At(i):"");return{...e,artifactType:o,type:e.type||o,title:y(e.title,m,"Runtime artifact"),summary:y(e.summary,n.prompt,e.title,m,"Runtime artifact"),content:n,fileUrl:p||void 0,previewUrl:h||void 0,metadata:{...s,source:y(s.source,t),savedPath:i||s.savedPath,filename:m||s.filename,mimeType:l||s.mimeType}}}function B(r,t){if(!t||!r)return;let e=d(t.metadata)?t.metadata:{},n=y(e.savedPath,e.callId,t.previewUrl,t.fileUrl)||Ot(),s=r.get(n);if(!s){r.set(n,t);return}s.content={...d(s.content)?s.content:{},...d(t.content)?t.content:{}},s.metadata={...d(s.metadata)?s.metadata:{},...e},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 et(r,t,e={}){for(let n of Me(r))B(t,Ce(n,e))}function st(r){if(!d(r)||!d(r.payload))return d(r)?r:{value:r};let t=c(r.payload.type);if(t!=="image_generation_end"&&t!=="image_generation_call")return r;let e={...r.payload};return typeof e.result=="string"&&e.result&&(e.result="<omitted>",e.resultLength=r.payload.result.length),{...r,payload:e}}function Ut(r,t,e){if(!d(r))return r;let n=d(r.event)?r.event:null;return n?(B(t,nt(n,e)),{...r,event:st(n)}):r}function bt(r,t,e={}){if(!d(r))return r;et(r,t,e);let n=Ut(r,t,e),s=d(n.update)?Ut(n.update,t,e):null;return s&&s!==n.update&&(n={...n,update:s}),n}function kt(r,t,e={}){let n=d(r)?{...r}:{};et(n,t,e),et(d(n.output)?n.output:{},t,e);let s=[...t?.values?.()||[]];return s.length&&(n.artifacts=s),n}var A=class{constructor(t,e,n={},s={}){this.agent=t,this.target=e,this.callbacks=n,this.options=s,this.proc=null,this.permissionHandlers=new Map}async ensureStarted(){if(this.proc)return;let t=c(this.target.command);if(!t)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);this.proc=new H({command:t,args:D(this.target.args),cwd:c(this.target.cwd)||this.agent.workspace||process.cwd(),env:d(this.target.env)?this.target.env:{},label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:c(this.target.framing||"line")}),this.proc.onRequest("session/request_permission",e=>this.handlePermissionRequest(e)),this.proc.onRequest("session/requestPermission",e=>this.handlePermissionRequest(e)),await this.proc.start({initialize:this.target.initialize!==!1,initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:O},...d(this.target.initializeParams)?this.target.initializeParams:{}}})}async sessionNew(t={}){await this.ensureStarted();let e=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return this.proc.call("session/new",{...t,mcpServers:e})}async sessionPrompt(t,e){await this.ensureStarted();let n=c(t.sessionId),s=new Map,i={source:this.artifactSource()},a=this.proc.onNotification("session/update",u=>{let l=c(u.sessionId);(!l||l===n)&&e(bt(u,s,i))}),o=async u=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:u,emitUpdate:e})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,o),this.permissionHandlers.set("*",o);try{let u=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return kt(u,s,i)}finally{a(),n&&this.permissionHandlers.delete(n),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let e=c(t.sessionId),n=this.permissionHandlers.get(e)||this.permissionHandlers.get("*");return n?n(t):{outcome:"denied",reason:"no active Orcha permission handler"}}artifactSource(){return c(this.target.type||"acp")==="openclaw"?"openclaw_image_generation":"acp_runtime_image_generation"}stop(t){this.proc?.stop(t)}};function be(r){let t=d(r.metadata)?r.metadata:{};return c(t.agentCode)}function ke(r,t){let e=be(r);return e?`agent:${e}:${t}`:`orcha-${t}`}var z=class extends A{constructor(t,e,n,s={},i={}){let a=c(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",o=c(e.command)||"openclaw",u=Array.isArray(e.args)?e.args.map(String):[],l=u.length>0?u:["acp","--session",ke(t,a)];super(t,{...e,command:o,args:l},s,i)}};import{spawn as Le}from"node:child_process";import{randomUUID as it}from"node:crypto";import{existsSync as vt,readdirSync as Pe,readFileSync as at,statSync as ve,unlinkSync as De}from"node:fs";import{homedir as Fe,tmpdir as $e}from"node:os";import{basename as Dt,join as k}from"node:path";var He=36e5,Be=5e3,ze=2*60*1e3,Ge=2*60*1e3,je=12,qe=1e3,G=24*60*60*1e3;function j(r,t){try{r.kill(t)}catch{}}function E(r){if(typeof r=="string")return r;if(Array.isArray(r))return r.map(t=>E(t)).join("");if(!d(r))return"";for(let t of["text","delta","output_text","content","message","output"]){let e=E(r[t]);if(e)return e}return""}function Ft(r){if(!d(r))return"";let t=d(r.payload)?r.payload:{};if(c(r.type)==="event_msg"){if(c(t.type)==="agent_message")return c(t.message);if(c(t.type)==="task_complete")return c(t.last_agent_message)}if(c(r.type)==="response_item"&&c(t.type)==="message"&&c(t.role)==="assistant")return E(t.content)||E(t.message);let e=E(r.delta)||E(r.text)||E(r.content);if(e)return e;let n=d(r.item)?r.item:{};return c(n.role)==="assistant"||c(n.type)==="message"?E(n.content)||E(n.text)||E(n.message):""}function ct(r){return nt(r,{source:"codex_cli_image_generation"})}function ut(r,t){B(r.artifacts,t)}function $t(r){return st(r)}function Je(r,t,e){return e.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:e.captureLastMessage===!0?!0:Dt(r)==="codex"}function Lt(r,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:Dt(r)==="codex"}function Ke(r){return Math.max(20,I(r.codexTranscriptPollMs||r.transcriptPollMs,qe))}function Ve(r,t,e){return{target:r,promptText:t,startedAtMs:e,matchedPaths:new Set,processedLines:new Map}}function We(r){let t=c(r.codexSessionsRoot||r.codexSessionRoot);if(t)return t;let e=d(r.env)?r.env:{},n=c(r.codexHome||e.CODEX_HOME||process.env.CODEX_HOME)||k(Fe(),".codex");return k(n,"sessions")}function Ye(r,t){let e=new Date(t),n=String(e.getFullYear()),s=String(e.getMonth()+1).padStart(2,"0"),i=String(e.getDate()).padStart(2,"0");return k(r,n,s,i)}function Ze(r,t,e){let n=new Set;for(let s of[t-G,t,t+G,e-G,e,e+G])n.add(Ye(r,s));return[...n].filter(s=>vt(s))}function Ht(r,t,e){let n=We(r),s=t-ze,i=e+Ge,a=[];for(let o of Ze(n,t,e)){let u=[];try{u=Pe(o)}catch{continue}for(let l of u){if(!l.endsWith(".jsonl"))continue;let p=k(o,l);try{let h=ve(p);if(!h.isFile()||h.mtimeMs<s||h.mtimeMs>i)continue;a.push({path:p,mtimeMs:h.mtimeMs})}catch{}}}return a.sort((o,u)=>u.mtimeMs-o.mtimeMs).slice(0,je)}function ot(r,t,e=0){if(!(e>8||r===null||r===void 0)){if(typeof r=="string"){r&&t.push(r);return}if(Array.isArray(r)){for(let n of r)ot(n,t,e+1);return}if(d(r))for(let n of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])n in r&&ot(r[n],t,e+1)}}function Bt(r){return c(r).replace(/\s+/g," ")}function Xe(r){let t=Bt(r);if(!t)return[];if(t.length<=200)return[t];let e=160,n=[0,Math.floor((t.length-e)/2),t.length-e],s=new Set,i=[];for(let a of n){let o=t.slice(Math.max(0,a),Math.max(0,a)+e).trim();o.length>=40&&!s.has(o)&&(s.add(o),i.push(o))}return i}function zt(r,t){let e=Xe(t);if(!e.length)return!1;let n=[];for(let i of r)ot(i,n);let s=Bt(n.join(" "));return e.every(i=>s.includes(i))}function Gt(r){let t=[];for(let e of r.split(/\r?\n/)){let n=e.trim();if(n)try{t.push(JSON.parse(n))}catch{}}return t}function Qe(r){if(!d(r))return!1;let t=d(r.payload)?r.payload:{},e=c(r.type),n=c(t.type);return e==="event_msg"&&n==="image_generation_end"||e==="response_item"&&n==="image_generation_call"}function tr(r,t,e,n){let s=Ft(r);if(s&&!t.emittedTexts.has(s)){let i=t.emittedTexts.size?`
|
|
8
|
+
`;this.child.stdin.write(s,r)}onNotification(t,r){let n=this.notificationHandlers.get(t)||new Set;return n.add(r),this.notificationHandlers.set(t,n),()=>{n.delete(r),n.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,r){return this.requestHandlers.set(t,r),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let r of this.pending.values())clearTimeout(r.timer),r.reject(t);this.pending.clear()}handleExit(t,r){this.rejectAll(new Error(`runtime exited before response (${t}/${r})`));for(let n of this.exitHandlers)n(t,r)}stop(t="stop"){!this.child||this.child.killed||(p("info","runtime","stopping runtime",{target:this.label,reason:t}),this.child.kill("SIGTERM"),setTimeout(()=>{this.child&&!this.child.killed&&this.child.kill("SIGKILL")},5e3).unref())}};import{randomUUID as $t}from"node:crypto";import{existsSync as He,readFileSync as Be,realpathSync as Lt,statSync as ze}from"node:fs";import{basename as vt,extname as Ht,isAbsolute as je,relative as Ge}from"node:path";var Je=25*1024*1024;function Bt(e,t=""){let r=o(t);if(r)return r;let n=Ht(o(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function zt(e,t){let r=typeof e=="string"?e.trim():"";return!r||r==="<omitted>"?"":r.startsWith("data:")?r:`data:${t};base64,${r.replace(/\s+/g,"")}`}function q(e){if(Array.isArray(e))return e.map(o).filter(Boolean);let t=o(e);return t?[t]:[]}function qe(e,t){let r=Ge(t,e);return r===""||!!r&&!r.startsWith("..")&&!je(r)}function Ke(e,t){let r=o(e);if(!r||!He(r))return"";try{let n=Lt(r);for(let s of t)try{let i=Lt(s);if(qe(n,i))return n}catch{}}catch{return""}return""}function ut(e,t,r={}){let n=o(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:We(n,t,r)}function We(e,t,r={}){let n=[...q(r.trustedFileRoots),...q(r.trustedFileRoot),...q(r.artifactRoots),...q(r.artifactRoot)],s=Ke(e,n);if(!s)return"";try{let i=ze(s);return!i.isFile()||i.size<=0||i.size>Je?"":`data:${t};base64,${Be(s).toString("base64")}`}catch{return""}}function g(...e){for(let t of e){let r=o(t);if(r)return r}return""}function Ve(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=g(n,e.previewUrl,e.fileUrl,e.imageUrl,e.dataUrl,e.url,e.uri,t.previewUrl,t.fileUrl,t.imageUrl,t.dataUrl,t.url,t.uri),c=Ht(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(c)}function lt(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!u(e))return null;let n=u(e.payload)?e.payload:{},s=o(e.type),i=o(n.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let c=g(n.call_id,n.id),a=g(n.saved_path,n.savedPath),d=g(n.revised_prompt,n.revisedPrompt),l=Bt(a,n.mimeType||n.mime_type),f=zt(n.result,l)||ut(a,l,t);if(!f)return null;let h=a?vt(a):`${c||$t()}.png`;return{artifactType:"image",type:"image",title:h||"Generated image",summary:d||"Generated image",content:{prompt:d||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:l},previewUrl:f,fileUrl:f,metadata:{source:r,eventType:i,callId:c||void 0,savedPath:a||void 0,filename:h,mimeType:l,revisedPrompt:d||void 0}}}function Xe(e){let t=u(e)?e:{},r=[];for(let n of["_artifacts","artifacts"]){let s=t[n];Array.isArray(s)&&r.push(...s)}for(let n of["_artifact","artifact"]){let s=t[n];u(s)&&r.push(s)}return r}function Ye(e,t={}){let{source:r="runtime_artifact"}=t,n=u(e)?e:{};if(!Object.keys(n).length)return null;let s=u(n.content)?{...n.content}:{},i=u(n.metadata)?{...n.metadata}:{},c=g(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),a=g(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),d=g(n.artifactType,n.artifact_type,n.type,n.kind,s.type,c?"image":"file"),l=Ve(n,s,d,c),f=l?Bt(c,a):a;if(l){let T=g(n.dataUrl,s.dataUrl),A=T.startsWith("data:")?T:"",E=g(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),M=zt(n.result??s.result,f)||A||ut(c,f,t)||ut(E,f,t);M&&(s.imageUrl||=M,s.previewUrl||=M,s.fileUrl||=M,f&&(s.mimeType||=f))}for(let[T,A]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let E=n[T];E!=null&&E!==""&&!(A in s)&&(s[A]=E)}let h=g(n.fileUrl,n.downloadUrl,n.imageUrl,n.dataUrl,n.url,n.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),O=g(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),R=g(n.filename,i.filename,c?vt(c):"");return{...n,artifactType:d,type:n.type||d,title:g(n.title,R,"Runtime artifact"),summary:g(n.summary,s.prompt,n.title,R,"Runtime artifact"),content:s,fileUrl:h||void 0,previewUrl:O||void 0,metadata:{...i,source:g(i.source,r),savedPath:c||i.savedPath,filename:R||i.filename,mimeType:f||i.mimeType}}}function K(e,t){if(!t||!e)return;let r=u(t.metadata)?t.metadata:{},n=g(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||$t(),s=e.get(n);if(!s){e.set(n,t);return}s.content={...u(s.content)?s.content:{},...u(t.content)?t.content:{}},s.metadata={...u(s.metadata)?s.metadata:{},...r},s.previewUrl=t.previewUrl||s.previewUrl,s.fileUrl=t.fileUrl||s.fileUrl,s.summary=t.summary||s.summary,s.title=t.title||s.title}function dt(e,t,r={}){for(let n of Xe(e))K(t,Ye(n,r))}function ft(e){if(!u(e)||!u(e.payload))return u(e)?e:{value:e};let t=o(e.payload.type);if(t!=="image_generation_end"&&t!=="image_generation_call")return e;let r={...e.payload};return typeof r.result=="string"&&r.result&&(r.result="<omitted>",r.resultLength=e.payload.result.length),{...e,payload:r}}function Ft(e,t,r){if(!u(e))return e;let n=u(e.event)?e.event:null;return n?(K(t,lt(n,r)),{...e,event:ft(n)}):e}function jt(e,t,r={}){if(!u(e))return e;dt(e,t,r);let n=Ft(e,t,r),s=u(n.update)?Ft(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function Gt(e,t,r={}){let n=u(e)?{...e}:{};dt(n,t,r),dt(u(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n.artifacts=s),n}var P=class{constructor(t,r,n={},s={}){this.agent=t,this.target=r,this.callbacks=n,this.options=s,this.proc=null,this.permissionHandlers=new Map}async ensureStarted(){if(this.proc)return;let t=o(this.target.command);if(!t)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);this.proc=new J({command:t,args:I(this.target.args),cwd:o(this.target.cwd)||this.agent.workspace||process.cwd(),env:u(this.target.env)?this.target.env:{},label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:o(this.target.framing||"line")}),this.proc.onRequest("session/request_permission",r=>this.handlePermissionRequest(r)),this.proc.onRequest("session/requestPermission",r=>this.handlePermissionRequest(r)),await this.proc.start({initialize:this.target.initialize!==!1,initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:k},...u(this.target.initializeParams)?this.target.initializeParams:{}}})}async sessionNew(t={}){await this.ensureStarted();let r=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return this.proc.call("session/new",{...t,mcpServers:r})}async sessionPrompt(t,r){await this.ensureStarted();let n=o(t.sessionId),s=new Map,i=this.artifactOptions(),c=this.proc.onNotification("session/update",d=>{let l=o(d.sessionId);(!l||l===n)&&r(jt(d,s,i))}),a=async d=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:d,emitUpdate:r})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,a),this.permissionHandlers.set("*",a);try{let d=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return Gt(d,s,i)}finally{c(),n&&this.permissionHandlers.delete(n),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let r=o(t.sessionId),n=this.permissionHandlers.get(r)||this.permissionHandlers.get("*");return n?n(t):{outcome:"denied",reason:"no active Orcha permission handler"}}artifactSource(){return o(this.target.type||"acp")==="openclaw"?"openclaw_image_generation":"acp_runtime_image_generation"}artifactOptions(){let t=u(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[o(this.target.artifactRoot),o(this.target.artifactDir),o(this.target.runtimeArtifactRoot),o(t.ORCHA_RUNTIME_ARTIFACT_DIR),...I(this.target.trustedArtifactRoots),...I(this.target.trustedFileRoots),...I(this.target.artifactRoots),...I(this.target.artifactFileRoots)].filter(Boolean)}}stop(t){this.proc?.stop(t)}};function Ze(e){let t=u(e.metadata)?e.metadata:{};return o(t.agentCode)}function Qe(e,t){let r=Ze(e);return r?`agent:${r}:${t}`:`orcha-${t}`}var W=class extends P{constructor(t,r,n,s={},i={}){let c=o(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",a=o(r.command)||"openclaw",d=Array.isArray(r.args)?r.args.map(String):[],l=d.length>0?d:["acp","--session",Qe(t,c)];super(t,{...r,command:a,args:l},s,i)}};import{spawn as tr}from"node:child_process";import{randomUUID as v}from"node:crypto";import{existsSync as Wt,mkdirSync as er,readdirSync as Vt,readFileSync as Xt,statSync as rr,unlinkSync as nr}from"node:fs";import{homedir as sr,tmpdir as Yt}from"node:os";import{basename as Zt,join as U,resolve as Jt}from"node:path";var ir=36e5,or=5e3,ar=2*60*1e3,cr=2*60*1e3,ur=12,dr=1e3,V=24*60*60*1e3;function X(e,t){try{e.kill(t)}catch{}}function S(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>S(t)).join("");if(!u(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let r=S(e[t]);if(r)return r}return""}function Qt(e){if(!u(e))return"";let t=u(e.payload)?e.payload:{};if(o(e.type)==="event_msg"){if(o(t.type)==="agent_message")return o(t.message);if(o(t.type)==="task_complete")return o(t.last_agent_message)}if(o(e.type)==="response_item"&&o(t.type)==="message"&&o(t.role)==="assistant")return S(t.content)||S(t.message);let r=S(e.delta)||S(e.text)||S(e.content);if(r)return r;let n=u(e.item)?e.item:{};return o(n.role)==="assistant"||o(n.type)==="message"?S(n.content)||S(n.text)||S(n.message):""}function te(e,t={}){return lt(e,{source:"codex_cli_image_generation",...t})}function ee(e,t){K(e.artifacts,t)}function re(e){return ft(e)}function lr(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:Zt(e)==="codex"}function fr(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:Zt(e)==="codex"}function pr(e){return Math.max(20,w(e.codexTranscriptPollMs||e.transcriptPollMs,dr))}function hr(e){return e.codexTranscriptStreaming===!0||e.streamCodexTranscript===!0}function mr(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function gr(e,t){let r=u(e.env)?e.env:{},n=o(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||U(Yt(),"orcha-runtime-artifacts"),s=o(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||v(),i=U(n,s,v());return er(i,{recursive:!0}),i}function yr(e,t){return{trustedFileRoots:[t,...I(e.trustedArtifactRoots),...I(e.trustedFileRoots),...I(e.artifactRoots),...I(e.artifactFileRoots)].filter(Boolean)}}function ne(e){let t=o(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let r=u(e.env)?e.env:{},n=o(e.codexHome||r.CODEX_HOME||process.env.CODEX_HOME)||U(sr(),".codex");return U(n,"sessions")}function _r(e,t){let r=new Date(t),n=String(r.getFullYear()),s=String(r.getMonth()+1).padStart(2,"0"),i=String(r.getDate()).padStart(2,"0");return U(e,n,s,i)}function se(e,t,r){let n=new Set;for(let s of[t-V,t,t+V,r-V,r,r+V])n.add(_r(e,s));return[...n].filter(s=>Wt(s))}function Tr(e,t,r){let n=ne(e),s=t-ar,i=r+cr,c=[];for(let a of se(n,t,r)){let d=[];try{d=Vt(a)}catch{continue}for(let l of d){if(!l.endsWith(".jsonl"))continue;let f=U(a,l);try{let h=rr(f);if(!h.isFile()||h.mtimeMs<s||h.mtimeMs>i)continue;c.push({path:f,mtimeMs:h.mtimeMs})}catch{}}}return c.sort((a,d)=>d.mtimeMs-a.mtimeMs).slice(0,ur)}function wr(e,t,r=t){let n=ne(e),s=new Set;for(let i of se(n,t,r)){let c=[];try{c=Vt(i)}catch{continue}for(let a of c)a.endsWith(".jsonl")&&s.add(U(i,a))}return s}function pt(e,t,r=0){if(!(r>8||e===null||e===void 0)){if(typeof e=="string"){e&&t.push(e);return}if(Array.isArray(e)){for(let n of e)pt(n,t,r+1);return}if(u(e))for(let n of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])n in e&&pt(e[n],t,r+1)}}function ie(e){return o(e).replace(/\s+/g," ")}function Ir(e){let t=ie(e);if(!t)return[];if(t.length<=200)return[t];let r=160,n=[0,Math.floor((t.length-r)/2),t.length-r],s=new Set,i=[];for(let c of n){let a=t.slice(Math.max(0,c),Math.max(0,c)+r).trim();a.length>=40&&!s.has(a)&&(s.add(a),i.push(a))}return i}function Rr(e,t){let r=Ir(t);if(!r.length)return!1;let n=[];for(let i of e)pt(i,n);let s=ie(n.join(" "));return r.every(i=>s.includes(i))}function Er(e){return e.find(t=>u(t)&&o(t.type)==="session_meta"&&u(t.payload))||null}function Sr(e){let t=u(e?.payload)?e.payload:{},r=o(e?.timestamp||t.timestamp),n=Date.parse(r);return Number.isFinite(n)?n:Number.NaN}function xr(e,t,r){if(!Rr(e,t.promptText))return!1;let n=Er(e);if(!n)return!1;let s=n.payload,i=o(s.originator),c=o(s.source);if(i!=="codex_exec"&&c!=="exec")return!1;let a=Sr(n);if(!Number.isFinite(a)||a<t.startedAtMs-5e3||a>r+5e3)return!1;let d=o(t.target.cwd),l=o(s.cwd);return!(d&&l&&Jt(d)!==Jt(l))}function qt(e){try{return Ar(Xt(e,"utf8"))}catch{return null}}function Or(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=qt(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of Tr(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=qt(s.path);!i||!xr(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,p("warn","runtime.cli","codex transcript fallback disabled; multiple matching transcripts",{target:e.target.targetCode,sessionId:t,transcriptCount:n.length})),null):(e.matchedPath=n[0].path,p("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function Ar(e){let t=[];for(let r of e.split(/\r?\n/)){let n=r.trim();if(n)try{t.push(JSON.parse(n))}catch{}}return t}function Ur(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{},r=o(e.type),n=o(t.type);return r==="event_msg"&&n==="image_generation_end"||r==="response_item"&&n==="image_generation_call"}function Cr(e,t,r,n){let s=Qt(e);if(s&&!t.emittedTexts.has(s)){let i=t.emittedTexts.size?`
|
|
9
9
|
|
|
10
|
-
${s}`:s;t.emittedTexts.add(s),n({sessionId:
|
|
11
|
-
`,
|
|
12
|
-
`}}})}}}async sessionCancel(t){let
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`),
|
|
16
|
-
`);
|
|
17
|
-
|
|
10
|
+
${s}`:s;t.emittedTexts.add(s),n({sessionId:r,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:i}}})}ee(t,te(e,t.artifactOptions)),Ur(e)&&n({sessionId:r,update:{sessionUpdate:"runtime_event",event:re(e)}})}function Kt(e,t,r,n,s=Date.now()){if(!t)return{artifactCount:0,transcriptCount:0};let i=e.artifacts.size,c=0,a=Or(t,r,s);if(a){let d=Math.min(t.processedLines.get(a.path)||0,a.events.length),l=e.artifacts.size;for(let f of a.events.slice(d))Cr(f,e,r,n);t.processedLines.set(a.path,a.events.length),(a.events.length>d||e.artifacts.size>l)&&(c=1)}return{artifactCount:e.artifacts.size-i,transcriptCount:c}}function Nr(e){if(!e||!Wt(e))return"";try{return Xt(e,"utf8").trim()}catch{return""}finally{try{nr(e)}catch{}}}var Y=class{constructor(t,r,n={}){this.agent=t,this.target=r,this.options=n,this.active=new Map}async sessionNew(){return{sessionId:`cli-${this.agent.agentId}-${v()}`}}async sessionPrompt(t,r){let n=Date.now(),s=o(this.target.command);if(!s)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let i=o(t.sessionId)||v(),c=j(t.prompt),a=o(this.target.promptMode||"stdin"),d=this.buildArgs(a,c),l=o(this.target.cwd)||this.agent.workspace||process.cwd(),f=gr(this.target,i),h=yr(this.target,f),O=fr(s,this.target),R={...this.target,targetCode:this.agent.targetCode,cwd:l},T=O?wr(R,n):new Set,A=lr(s,d,this.target)?U(Yt(),`orcha-runtime-last-message-${v()}.txt`):"";A&&d.push("--output-last-message",A);let E=w(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,w(this.options.sessionPromptTimeoutMs,ir)),M={...process.env,...u(this.target.env)?this.target.env:{},...a==="env"?{ORCHA_RUNTIME_PROMPT:c}:{},ORCHA_AGENT_ID:this.agent.agentId,ORCHA_SESSION_ID:i,ORCHA_RUNTIME_ARTIFACT_DIR:f},m=tr(s,d,{cwd:l,env:M,stdio:["pipe","pipe","pipe"]});this.active.set(i,m),p("info","runtime.cli","runtime prompt started",{target:this.agent.targetCode,sessionId:i,pid:m.pid,timeoutMs:E});let Ut="",it=o(this.target.outputMode||"text"),x={artifacts:new Map,emittedTexts:new Set,value:"",artifactOptions:h},ot=O?mr(R,c,n,T):null;return m.stdout.setEncoding("utf8"),m.stdout.on("data",b=>this.handleStdout(b,it,x,i,r)),m.stderr.setEncoding("utf8"),m.stderr.on("data",b=>{Ut+=b,this.target.emitStderr===!0&&r({sessionId:i,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:b}}})}),a==="stdin"?m.stdin.end(c):m.stdin.end(),await new Promise((b,xe)=>{let H=!1,Ct=!1,C=null,at=ot&&hr(this.target)?setInterval(()=>{try{Kt(x,ot,i,r)}catch(y){p("warn","runtime.cli","codex transcript stream poll failed",{target:this.agent.targetCode,sessionId:i,error:String(y?.message||y)})}},pr(this.target)):null;at?.unref?.();let Nt=setTimeout(()=>{Ct=!0,p("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:i,pid:m.pid,timeoutMs:E}),X(m,"SIGTERM"),C=setTimeout(()=>{p("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:i,pid:m.pid}),X(m,"SIGKILL")},or),C.unref?.(),bt(Object.assign(new Error(`runtime CLI timed out after ${E}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},E);Nt.unref?.();let Mt=()=>{clearTimeout(Nt),at&&clearInterval(at),C&&!Ct&&clearTimeout(C),this.active.delete(i)},Oe=y=>{H||(H=!0,Mt(),b(y))},bt=y=>{H||(H=!0,Mt(),xe(y))};m.on("error",y=>{p("warn","runtime.cli","runtime child error",{target:this.agent.targetCode,sessionId:i,pid:m.pid,error:String(y?.message||y)}),bt(y)}),m.on("exit",(y,kt)=>{C&&(clearTimeout(C),C=null),it==="json-lines"&&x.value.trim()&&this.handleStdout(`
|
|
11
|
+
`,it,x,i,r);let ct=Kt(x,ot,i,r,Date.now());ct.artifactCount>0&&p("info","runtime.cli","codex transcript artifacts collected",{target:this.agent.targetCode,sessionId:i,artifactCount:ct.artifactCount,transcriptCount:ct.transcriptCount});let B=Nr(A);B&&!x.emittedTexts.has(B)&&(x.emittedTexts.add(B),r({sessionId:i,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:B}}}));let z=Ut.trim();z&&p("debug","runtime.cli","runtime stderr",{target:this.agent.targetCode,sessionId:i,stderr:z}),p("info","runtime.cli","runtime prompt finished",{target:this.agent.targetCode,sessionId:i,pid:m.pid,exitCode:y,signal:kt,artifactCount:x.artifacts.size}),Oe({stopReason:y===0?"end_turn":"error",exitCode:y,signal:kt,artifacts:[...x.artifacts.values()],...z?{stderr:z}:{}})})})}buildArgs(t,r){let n=I(this.target.args);return t==="args"?[...n,r]:n}handleStdout(t,r,n,s,i){if(r!=="json-lines"){i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:t}}});return}n.value+=t;let c=n.value.split(/\r?\n/);n.value=c.pop()||"";for(let a of c){let d=a.trim();if(d)try{let l=JSON.parse(d);ee(n,te(l,n.artifactOptions)),i({sessionId:s,update:{sessionUpdate:"runtime_event",event:re(l)}});let f=Qt(l);f&&!n.emittedTexts.has(f)&&(n.emittedTexts.add(f),i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:f}}}))}catch{i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`${a}
|
|
12
|
+
`}}})}}}async sessionCancel(t){let r=o(t.sessionId),n=this.active.get(r);return n?(p("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),X(n,"SIGTERM"),this.active.delete(r),{ok:!0,cancelled:!0}):{ok:!0,cancelled:!1}}stop(t="stop"){for(let[r,n]of this.active.entries())p("info","runtime.cli","stopping runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid,reason:t}),X(n,"SIGTERM");this.active.clear()}};var ht=24e3,mt=8,gt=50,yt=6e3,Mr=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),br=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function kr(e,t,r){let n=u(e?._meta)?e._meta:{};return{...u(e)?e:{},sessionId:t,update:u(e?.update)?e.update:{},_meta:{...n,orchaAgentId:r.agentId,runtimeSessionId:r.runtimeSessionId,bridgeUpdateId:Z()}}}function Q(e){return e==null||e===""?!1:Array.isArray(e)?e.length>0:u(e)?Object.keys(e).length>0:!0}function Pr(e){let t=String(e||"");if(br.test(t))return!0;let r=t.replace(/[^a-z0-9]/gi,"").toLowerCase();return r.endsWith("token")||r.endsWith("secret")||r.endsWith("password")||r.endsWith("apikey")||r.endsWith("privatekey")||r==="authorization"||r==="cookie"||r==="jwt"||r.includes("credential")}function _t(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=yt)return e;let r=e.length-yt;return`${e.slice(0,yt)}... [truncated ${r} characters]`}if(t>=mt)return Array.isArray(e)?`[array truncated at depth ${mt}, items=${e.length}]`:u(e)?`[object truncated at depth ${mt}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,gt).map(n=>_t(n,t+1));return e.length>gt&&r.push(`[truncated ${e.length-gt} items]`),r}if(u(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=Pr(n)?"[REDACTED]":_t(s,t+1);return r}return String(e)}function Dr(e){let t=u(e)?e:{},r={};Q(t.metadata)&&(r.metadata=t.metadata);for(let[n,s]of Object.entries(t))Mr.has(n)||n==="metadata"||Q(s)&&(r[n]=s);return r}function Lr(e){let t=Dr(e);if(!Q(t))return"";let r=JSON.stringify(_t(t),null,2);if(r.length<=ht)return r;let n=r.length-ht;return`${r.slice(0,ht)}
|
|
13
|
+
... [truncated ${n} characters]`}function Fr(e){if(!u(e))return"";let t=u(e.update)?e.update:e,n=(u(t.content)?t.content:{}).text??t.text;return n==null?"":String(n)}function $r(e){let t="";for(let r of e){let n=String(r||"");n&&(t?n.startsWith(t)?t=n:t.endsWith(n)||(t+=n):t=n)}return t.trim()}function vr(e){let t=String(e||"").trim();if(!t)return"";let r=t.match(/(?:^|\n)#{1,3}\s+\S/);return!r||r.index===0?t:t.slice(r.index+(t[r.index]===`
|
|
14
|
+
`?1:0)).trim()}function Hr(e){let t=String(e||"").trim();if(!t.endsWith("}"))return"";for(let r=t.lastIndexOf("{");r>=0;r=t.lastIndexOf("{",r-1)){let n=t.slice(r);try{let s=JSON.parse(n);if(u(s))return n}catch{}}return""}function Br(e){if(!u(e))return!1;if(Q(e.output))return!0;for(let t of["content","text","message","summary"])if(o(e[t]))return!0;return!!(Array.isArray(e._artifacts)&&e._artifacts.length>0||Array.isArray(e.artifacts)&&e.artifacts.length>0||o(e.status)||o(e.error)||o(e.errorMessage))}function zr(e,t){let r=u(e)?{...e}:{};if(Br(r))return r;let n=vr($r((Array.isArray(t)?t:[]).map(Fr))),s=Hr(n)||n;return s?{...r,output:s,_meta:{...u(r._meta)?r._meta:{},runtimeOutputSource:"updates"}}:r}var tt=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=F()}targetFor(t){let r=o(t)||this.config.defaultTargetCode,n=this.targets[r];return{code:r,target:u(n)?n:{type:"echo"}}}async createAgent(t){let r=o(t.agentId);if(!r)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let{code:n,target:s}=this.targetFor(t.targetCode||t.framework),i={agentId:r,targetCode:n,framework:o(t.framework||n),workspace:o(t.workspace),metadata:u(t.metadata)?t.metadata:{},createdAt:F(),runtimeKind:o(s.type||"echo")};return this.agents.set(r,i),{agent:i}}runtimeFor(t,r){let{target:n}=this.targetFor(t.targetCode),s=o(n.type||"echo"),i={onPermissionRequest:a=>this.requestPermission(a)},c={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs};return s==="stdio-acp"||s==="acp"?new P(t,n,i,c):s==="openclaw"?new W(t,n,r,i,c):s==="cli"?new Y(t,n,c):new G(t)}async prompt(t,r={}){let n=o(t.agentId),s=o(t.sessionId)||Z();if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let i=this.agents.get(n)||(await this.createAgent({agentId:n,targetCode:t.targetCode,framework:t.framework,workspace:t.workspace,metadata:t.metadata})).agent,c=o(t.workspace);c&&c!==i.workspace&&(i.workspace=c);let a=`${n}:${s}`,d=this.sessions.get(a);if(!d){let R=this.runtimeFor(i,s),T=await R.sessionNew({cwd:i.workspace||process.cwd(),metadata:u(t.metadata)?t.metadata:{}});d={agentId:n,sessionId:s,runtime:R,runtimeSessionId:o(u(T)?T.sessionId:"")||s,createdAt:F()},this.sessions.set(a,d),this.runtimeSessionIndex.set(`${n}:${d.runtimeSessionId}`,d)}let l=[],f=R=>{let T=kr(R,s,d);l.push(T),r.onUpdate?.(T)},h=await d.runtime.sessionPrompt({sessionId:d.runtimeSessionId,prompt:Array.isArray(t.prompt)?t.prompt:[],metadata:u(t.metadata)?t.metadata:{}},f),O=zr(h,l);return{sessionId:s,runtimeSessionId:d.runtimeSessionId,result:O,updates:l}}async cancel(t){let r=o(t.agentId),n=o(t.sessionId),s=this.sessions.get(`${r}:${n}`);return s?(await s.runtime.sessionCancel({sessionId:s.runtimeSessionId}),{cancelled:!0}):{cancelled:!1}}async dispatch(t,r={}){let n=o(t.agentId),s=o(t.taskId),i=o(t.executionId);if(!n||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let c=o(t.sessionId)||`dispatch-${i||s}`,a=o(t.instructions),d=Lr(t),l=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",a?`instructions: ${a}`:"",d?"orchaContext:":"",d,d?"Use orchaContext as the source of truth for upstream outputs, review reports, artifacts, and workflow metadata.":"","Return only the final task result. Do not include process notes, logs, or explanations. Orcha will wrap the result into its runtime protocol."].filter(Boolean).join(`
|
|
15
|
+
`)}];return this.prompt({...t,agentId:n,sessionId:c,prompt:l},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=Z(),a=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||Z(),d={permissionId:i,agentId:t.agentId,sessionId:a,runtimeSessionId:r,request:u(n)?n:{},status:"pending",createdAt:F()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:d}}),await new Promise(l=>{let f=w(n?.timeoutMs,this.config.permissionRequestTimeoutMs),h=setTimeout(()=>{this.pendingPermissions.delete(i),l({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:h,resolve:l,permission:d})})}async respondPermission(t){let r=o(t.permissionId),n=this.pendingPermissions.get(r),s=o(t.outcome||"approved")||"approved";return n?(clearTimeout(n.timer),this.pendingPermissions.delete(r),n.resolve({permissionId:r,outcome:s,response:u(t.response)?t.response:{},userId:o(t.userId),metadata:u(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:r,outcome:s}):{accepted:!1,permissionId:r,outcome:s}}health(){return{status:"ok",bridgeVersion:k,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 jr from"node:http";import Gr from"node:https";import{randomBytes as oe}from"node:crypto";var et=1,Tt=3,rt=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,r){let n=this.listeners.get(t)||new Set;n.add(r),this.listeners.set(t,n)}emit(t,r={}){let n=this.listeners.get(t);if(n)for(let s of n)s(r)}connect(){let t=new URL(this.url),r=t.protocol==="wss:"?Gr:jr,n=oe(16).toString("base64"),s=r.request({protocol:t.protocol==="wss:"?"https:":"http:",hostname:t.hostname,port:t.port||(t.protocol==="wss:"?443:80),path:`${t.pathname}${t.search}`,method:"GET",headers:{Connection:"Upgrade",Upgrade:"websocket","Sec-WebSocket-Key":n,"Sec-WebSocket-Version":"13"}});s.on("upgrade",(i,c,a)=>{this.socket=c,this.readyState=et,c.on("data",d=>this.onData(d)),c.on("close",()=>this.onClose()),c.on("error",d=>{this.emit("error",{error:d,message:d.message,type:"error"}),this.onClose()}),a?.length&&this.onData(a),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!==et||this.socket.write(wt(1,Buffer.from(String(t),"utf8")))}close(){!this.socket||this.readyState===Tt||(this.socket.write(wt(8,Buffer.alloc(0))),this.socket.end(),this.onClose())}onClose(){this.readyState!==Tt&&(this.readyState=Tt,this.emit("close"))}onData(t){for(this.buffer=Buffer.concat([this.buffer,t]);this.buffer.length>=2;){let r=this.buffer[0],n=this.buffer[1],s=r&15,i=(n&128)!==0,c=n&127,a=2;if(c===126){if(this.buffer.length<a+2)return;c=this.buffer.readUInt16BE(a),a+=2}else if(c===127){if(this.buffer.length<a+8)return;let f=this.buffer.readUInt32BE(a),h=this.buffer.readUInt32BE(a+4);c=f*2**32+h,a+=8}let d=a;if(i&&(a+=4),this.buffer.length<a+c)return;let l=this.buffer.subarray(a,a+c);if(i){let f=this.buffer.subarray(d,d+4);l=Buffer.from(l.map((h,O)=>h^f[O%4]))}this.buffer=this.buffer.subarray(a+c),s===1?this.emit("message",{data:l.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(wt(10,l))}}};function wt(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=oe(4),i=Buffer.alloc(n+4+r);i[0]=128|e;let c=2;r<126?i[1]=128|r:r<=65535?(i[1]=254,i.writeUInt16BE(r,c),c+=2):(i[1]=255,i.writeUInt32BE(Math.floor(r/2**32),c),i.writeUInt32BE(r>>>0,c+4),c+=8),s.copy(i,c),c+=4;for(let a=0;a<r;a+=1)i[c+a]=t[a]^s[a%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 qr(e){return Object.entries(e||{}).map(([t,r])=>({targetCode:t,targetName:o(r?.name||r?.targetName||t),targetType:o(r?.type||"echo"),status:"available",metadata:u(r)?r:{}}))}var nt=class{constructor(t,r){this.config=t,this.bridge=r,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),r=new rt(t);this.ws=r,r.addEventListener("open",()=>this.authenticate()),r.addEventListener("message",n=>this.handleMessage(n.data)),r.addEventListener("close",()=>this.scheduleReconnect("close")),r.addEventListener("error",n=>{p("warn","orcha-client","runtime node websocket error",{error:String(n?.message||n?.type||n)})})}authenticate(){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:k,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 r;try{r=JSON.parse(String(t))}catch(n){p("warn","orcha-client","invalid Orcha websocket frame",{error:String(n)});return}if(u(r)){if(r.type==="runtime_node.authenticated"){this.connected=!0,p("info","orcha-client","runtime node authenticated",{nodeId:this.config.nodeId,connectionId:r.connectionId});return}if(r.type==="orcha.runtime.request"){await this.handleRequest(r);return}r.type==="runtime_node.ping"&&this.send({type:"runtime_node.pong",ts:new Date().toISOString()})}}async handleRequest(t){let r=o(t.id),n=o(t.method),s=u(t.params)?t.params:{};try{let i=await this.invoke(n,s,r);this.send({type:"orcha.runtime.response",id:r,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:r,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i)}})}}async invoke(t,r,n){if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(r);if(t==="agents/dispatch")return this.bridge.dispatch(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/prompt")return this.bridge.prompt(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/cancel")return this.bridge.cancel(r);if(t==="permissions/respond")return this.bridge.respondPermission(r);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,r){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:r})}send(t){return!this.ws||this.ws.readyState!==et?!1:(this.ws.send(JSON.stringify(t)),!0)}};import{existsSync as Kr,readFileSync as Wr}from"node:fs";import{resolve as ae}from"node:path";var Vr=/^[A-Za-z_][A-Za-z0-9_]*$/;function ce(e=process.env,t=process.cwd()){let r=o(e.ORCHA_RUNTIME_ENV_FILE),n=r?ae(t,r):ae(t,".env");if(!Kr(n))return r&&p("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Wr(n,"utf8");for(let c of i.split(/\r?\n/)){let a=Yr(c);if(!a)continue;let[d,l]=a;Object.prototype.hasOwnProperty.call(e,d)||(e[d]=l,s.push(d))}return p("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function ue(e=process.env){return{mode:o(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),host:e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1",port:w(e.ORCHA_RUNTIME_BRIDGE_PORT,5588),token:e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",orchaUrl:o(e.ORCHA_RUNTIME_ORCHA_URL),nodeToken:e.ORCHA_RUNTIME_NODE_TOKEN||e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",nodeId:o(e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"local-runtime-node"),nodeName:o(e.ORCHA_RUNTIME_NODE_NAME||e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"Local Runtime Node"),reconnectMs:w(e.ORCHA_RUNTIME_RECONNECT_MS,3e3),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:w(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),sessionPromptTimeoutMs:w(e.ORCHA_RUNTIME_SESSION_PROMPT_TIMEOUT_MS,36e5),permissionRequestTimeoutMs:w(e.ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS,3e5),targets:Xr(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Xr(e){if(!o(e))return{};try{let t=JSON.parse(e);if(u(t))return t}catch(t){p("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function Yr(e){let t=e.trim();if(!t||t.startsWith("#"))return null;let r=t.startsWith("export ")?t.slice(7).trimStart():t,n=r.indexOf("=");if(n<=0)return null;let s=r.slice(0,n).trim();if(!Vr.test(s))return null;let i=Zr(r.slice(n+1).trim());return[s,i]}function Zr(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?Qr(r):r}return tn(e).trim()}function Qr(e){return e.replaceAll("\\n",`
|
|
16
|
+
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function tn(e){let t=!1,r=!1;for(let n=0;n<e.length;n+=1){let s=e[n],i=e[n-1];if(s==="'"&&!r)t=!t;else if(s==='"'&&!t&&i!=="\\")r=!r;else if(s==="#"&&!t&&!r&&/\s/.test(i||""))return e.slice(0,n)}return e}import{createServer as en}from"node:http";function st(e,t,r){let n=JSON.stringify(r);e.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(n)}),e.end(n)}function N(e={}){return{ok:!0,...e}}function It(e,t,r){return{ok:!1,error:{code:e,message:t,...r===void 0?{}:{detail:r}}}}async function de(e,t){let r=[],n=0;for await(let i of e){if(n+=i.length,n>t)throw Object.assign(new Error("request body too large"),{status:413,code:"REQUEST_TOO_LARGE"});r.push(i)}if(r.length===0)return{};let s=Buffer.concat(r).toString("utf8");if(!s.trim())return{};try{let i=JSON.parse(s);if(!u(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 le(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 fe(e,t){let r={"GET /health":async()=>N(t.health()),"POST /agents/create":async n=>N(await t.createAgent(n)),"POST /agents/dispatch":async n=>N(await t.dispatch(n)),"POST /sessions/prompt":async n=>N(await t.prompt(n)),"POST /sessions/cancel":async n=>N(await t.cancel(n)),"POST /permissions/respond":async n=>N(await t.respondPermission(n))};return en(async(n,s)=>{let i=new URL(n.url||"/",`http://${n.headers.host||`${e.host}:${e.port}`}`),c=`${n.method||"GET"} ${i.pathname}`,a=r[c];if(!a){st(s,404,It("NOT_FOUND",`No route for ${c}`));return}try{le(n,e.token);let d=n.method==="GET"?{}:await de(n,e.requestLimitBytes);st(s,200,await a(d))}catch(d){let l=d.status||500,f=d.code||"BRIDGE_INTERNAL";st(s,l,It(f,d.message||String(d)))}})}var dn=un(import.meta.url),ln=".orcha-runtime-bridge.pid",fn=".orcha-runtime-bridge.log",pn=3,hn=36e5,{command:mn,options:Ie}=Tn(process.argv.slice(2));wn(Ie);ce();var gn=ue();await yn(mn,gn,Ie);async function yn(e,t,r){switch(e){case"run":case"foreground":he(t);return;case"start":if(r.foreground){he(t);return}me();return;case"reload":case"restart":await ge({quiet:!0}),me();return;case"stop":await ge();return;case"status":_n();return;case"help":case"--help":case"-h":Sn();return;default:throw new Error(`Unknown command: ${e}`)}}function he(e){In();let t=new tt(e);if(e.mode==="server"){fe(e,t).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");new nt(e,t).start(),p("info","runtime-bridge","Orcha runtime node started",{nodeId:e.nodeId,nodeName:e.nodeName,orchaUrl:e.orchaUrl,targets:Object.keys(t.targets)})}function me(){let e=Ot(),t=Re(),r=At(e);if(r&&D(r)){console.log(JSON.stringify({status:"already_running",pid:r,pidFile:e,logFile:t}));return}r&&St(e),_e(e),_e(t),Et(t);let n=on(t,"a"),s={...process.env,ORCHA_RUNTIME_PID_FILE:e,ORCHA_RUNTIME_LOG_FILE:t},i=rn(process.execPath,[dn,"run"],{cwd:process.cwd(),detached:!0,env:s,stdio:["ignore",n,n]});i.unref(),nn(n),we(e,`${i.pid}
|
|
17
|
+
`),console.log(JSON.stringify({status:"started",pid:i.pid,pidFile:e,logFile:t}))}async function ge({quiet:e=!1}={}){let t=Ot(),r=At(t);if(!r){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!D(r)){St(t),e||console.log(JSON.stringify({status:"not_running",pid:r,pidFile:t}));return}process.kill(r,"SIGTERM"),!await ye(r,1e4)&&D(r)&&(process.kill(r,"SIGKILL"),await ye(r,3e3)),St(t),e||console.log(JSON.stringify({status:"stopped",pid:r,pidFile:t}))}function _n(){let e=Ot(),t=Re(),r=At(e),n=!!(r&&D(r));console.log(JSON.stringify({status:n?"running":"not_running",running:n,pid:n?r:null,pidFile:e,logFile:t}))}function Tn(e){let t=[],r={};for(let s=0;s<e.length;s+=1){let i=e[s];i==="--daemon"?r.daemon=!0:i==="--foreground"?r.foreground=!0:i==="--env-file"?r.envFile=e[++s]:i==="--pid-file"?r.pidFile=e[++s]:i==="--log-file"?r.logFile=e[++s]:t.push(i)}return{command:t[0]||"run",options:r}}function wn(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 Ot(){return xt(process.cwd(),process.env.ORCHA_RUNTIME_PID_FILE||ln)}function Re(){return xt(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||fn)}function In(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=Ee();if(t<=0)return;let r=xt(process.cwd(),e);Et(r,t);let n=En();n<=0||setInterval(()=>Et(r,t),n).unref()}function Et(e,t=Ee()){if(t<=0||!Te(e))return;let r=0,n="";try{if(r=pe(e).size,r<=0)return;n=Rt(e,"utf8")}catch(l){p("warn","runtime-bridge","runtime log cleanup skipped",{logFile:e,error:String(l)});return}let s=Date.now()-t*24*60*60*1e3,i=n.split(/\r?\n/),c=[],a=0;for(let l of i)l&&(Rn(l,s)?c.push(l):a+=1);if(a===0)return;let d="";try{pe(e).size>r&&(d=Rt(e,"utf8").slice(n.length));let f=[...c,...d.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:a})}catch(l){p("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(l)})}}function Rn(e,t){try{let r=JSON.parse(e);if(!r||typeof r!="object")return!0;let n=typeof r.ts=="string"?Date.parse(r.ts):Number.NaN;return!Number.isFinite(n)||n>=t}catch{return!0}}function Ee(){return Se(process.env.ORCHA_RUNTIME_LOG_RETENTION_DAYS,pn)}function En(){return Se(process.env.ORCHA_RUNTIME_LOG_CLEANUP_INTERVAL_MS,hn)}function Se(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function At(e){if(!Te(e))return null;let t=Number.parseInt(Rt(e,"utf8").trim(),10);return Number.isInteger(t)&&t>0?t:null}function D(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function ye(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!D(e))return!0;await new Promise(n=>setTimeout(n,100))}return!D(e)}function _e(e){sn(cn(e),{recursive:!0})}function St(e){try{an(e,{force:!0})}catch{}}function Sn(){console.log(`Usage: orcha-runtime-bridge [command] [options]
|
|
18
20
|
|
|
19
21
|
Commands:
|
|
20
22
|
run, foreground Run in the foreground. This is the default.
|