@orcha-ai/runtime-bridge 0.1.36 → 0.1.37
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 +98 -11
- package/bin/orcha-runtime-bridge.js +17 -17
- package/openclaw-plugin/index.js +1 -0
- package/openclaw-plugin/openclaw.plugin.json +14 -0
- package/openclaw-plugin/package.json +7 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ runtime permission requests, and process lifecycle are implemented under
|
|
|
11
11
|
In production the Runtime Node actively connects to Orcha over WebSocket. The
|
|
12
12
|
computer running Codex/OpenClaw/Claude does not need to expose an inbound port.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Managed sandbox execution is fail-closed: before registering targets as available it
|
|
15
15
|
runs the bundled Linux Bubblewrap broker probe. Every prompt/dispatch is bound
|
|
16
16
|
to a control-plane `runId` and frozen sandbox policy, and the actual Runtime
|
|
17
17
|
process is started by the broker inside an empty-root namespace. Missing
|
|
@@ -31,8 +31,10 @@ exposing unrelated host installations or credentials.
|
|
|
31
31
|
npm install -g @orcha-ai/runtime-bridge
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
Bubblewrap, `prlimit`, `ip`, and `socat
|
|
34
|
+
Runtime Bridge requires Node.js 22.19 or newer. Managed sandbox execution also
|
|
35
|
+
requires Linux with Bubblewrap, `prlimit`, `ip`, and `socat`. External Runtime
|
|
36
|
+
Nodes execute operator-configured agents directly on Linux, macOS, or Windows.
|
|
37
|
+
An OpenClaw Gateway must separately satisfy its host version's requirements.
|
|
36
38
|
|
|
37
39
|
Run it with:
|
|
38
40
|
|
|
@@ -58,24 +60,33 @@ npm run pack:local
|
|
|
58
60
|
|
|
59
61
|
`npm run build` writes `dist/package`. `npm run pack:local` creates the local
|
|
60
62
|
npm tarball under `dist/`. The release package includes the minified `bin/`
|
|
61
|
-
runtime, `README.md`, and `.env.example`; it does not publish `src/`, build
|
|
63
|
+
runtime, the bundled `openclaw-plugin/`, `README.md`, and `.env.example`; it does not publish `src/`, build
|
|
62
64
|
scripts, test scripts, or the local `.env` file.
|
|
63
65
|
|
|
64
|
-
### 0.1.
|
|
66
|
+
### 0.1.37 Release
|
|
65
67
|
|
|
66
|
-
Packages
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
Packages task-scoped Orcha MCP access for delegated Codex and OpenClaw group
|
|
69
|
+
members, including credential refresh, operation reattachment, cancellation,
|
|
70
|
+
and session cleanup. The tarball includes the bundled OpenClaw Gateway plugin;
|
|
71
|
+
install and configure it as described in [Delegated group member tools](#delegated-group-member-tools).
|
|
72
|
+
Local adapter fixtures cover these integrations; a real OpenClaw Gateway has
|
|
73
|
+
not yet been verified.
|
|
71
74
|
|
|
72
75
|
After `npm run check`, `npm test`, and `npm run pack:local` succeed, publish the
|
|
73
76
|
prepared tarball from this directory:
|
|
74
77
|
|
|
75
78
|
```bash
|
|
76
|
-
npm publish ./dist/orcha-ai-runtime-bridge-0.1.
|
|
79
|
+
npm publish ./dist/orcha-ai-runtime-bridge-0.1.37.tgz --access public --registry=https://registry.npmjs.org
|
|
77
80
|
```
|
|
78
81
|
|
|
82
|
+
### 0.1.36 Release
|
|
83
|
+
|
|
84
|
+
Packages the goal-verification changes committed on August 25–26, 2026.
|
|
85
|
+
Each verification check requires a positive integer `requiredMatches` and
|
|
86
|
+
counts distinct successful tool call IDs. Results report `requiredMatches`,
|
|
87
|
+
`observedMatches`, and `toolCallIds` instead of the previous single `toolCallId`.
|
|
88
|
+
Callers and result consumers must use these fields when upgrading from 0.1.35.
|
|
89
|
+
|
|
79
90
|
## Configure
|
|
80
91
|
|
|
81
92
|
```bash
|
|
@@ -238,6 +249,82 @@ always receive an empty `mcpServers` array, because the field is required by the
|
|
|
238
249
|
ACP schema while OpenClaw bridge mode requires actual MCP servers to be
|
|
239
250
|
configured on the OpenClaw gateway or agent instead.
|
|
240
251
|
|
|
252
|
+
### Delegated group member tools
|
|
253
|
+
|
|
254
|
+
Group delegation uses one independent `runId`, session, and correlation for
|
|
255
|
+
each member task. Its task-scoped Orcha MCP credential grants only that member's
|
|
256
|
+
authorized capabilities. It is kept in memory and refreshed by attaching to the
|
|
257
|
+
existing operation. Lost operations fail explicitly; the Bridge never starts a
|
|
258
|
+
second prompt to simulate recovery. Permission changes cancel the old task;
|
|
259
|
+
native authorization or input pauses are not automatically approved or resumed.
|
|
260
|
+
|
|
261
|
+
For a Codex CLI target, the adapter adds a required HTTP MCP server through
|
|
262
|
+
per-process `-c` configuration and a private loopback proxy. Codex receives a
|
|
263
|
+
temporary proxy credential through `ORCHA_TASK_MCP_TOKEN`; upstream credentials
|
|
264
|
+
remain in Bridge memory. This does not edit the operator's Codex configuration.
|
|
265
|
+
This adapter requires a direct external Runtime Node; its loopback transport is
|
|
266
|
+
not supported inside a Bridge-managed sandbox. See [Codex MCP configuration](https://developers.openai.com/codex/mcp).
|
|
267
|
+
|
|
268
|
+
OpenClaw requires the bundled Gateway tool plugin. Build the Bridge, then install
|
|
269
|
+
the **built** plugin directory on the OpenClaw host:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
npm run build
|
|
273
|
+
openclaw plugins install /absolute/path/to/runtime-bridge/dist/package/openclaw-plugin
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Configure `plugins.entries.orcha-runtime` on that Gateway, preserving other
|
|
277
|
+
installed plugin entries and allowlists:
|
|
278
|
+
|
|
279
|
+
```json
|
|
280
|
+
{
|
|
281
|
+
"enabled": true,
|
|
282
|
+
"config": { "allowedOrchaMcpUrl": "https://orcha.example.com/api/mcp/orcha" }
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
If plugin or tool allowlists are configured, permit `orcha-runtime` and its four
|
|
287
|
+
`orcha_` tools for the intended OpenClaw Agent. The plugin binds tools only to
|
|
288
|
+
the trusted host `agentId` and task `sessionKey`; ordinary sessions receive none.
|
|
289
|
+
Its manifest declares all four tools and activates the binding route at startup.
|
|
290
|
+
Follow the host's [plugin installation](https://docs.openclaw.ai/cli/plugins/install)
|
|
291
|
+
and [runtime verification](https://docs.openclaw.ai/plugins/building-plugins) steps,
|
|
292
|
+
including loading the new code in the running Gateway. Pin and verify the actual
|
|
293
|
+
host version before enabling dispatch; this package does not claim a tested
|
|
294
|
+
OpenClaw version range yet.
|
|
295
|
+
|
|
296
|
+
Add these fields to the existing OpenClaw Runtime Target:
|
|
297
|
+
|
|
298
|
+
```json
|
|
299
|
+
{
|
|
300
|
+
"type": "openclaw",
|
|
301
|
+
"command": "openclaw",
|
|
302
|
+
"mcpBridgeUrl": "http://127.0.0.1:18789/plugins/orcha-runtime/mcp-bindings",
|
|
303
|
+
"mcpBridgeTokenEnv": "ORCHA_OPENCLAW_GATEWAY_TOKEN"
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Set `ORCHA_OPENCLAW_GATEWAY_TOKEN` in the Bridge host environment to the Gateway
|
|
308
|
+
authentication credential. The binding URL must reach that same Gateway. Orcha's
|
|
309
|
+
Agent code must match the OpenClaw Agent id. Do not configure a shared fixed
|
|
310
|
+
`--session`: delegated sessions use `agent:<agentCode>:delegation-<runId>`.
|
|
311
|
+
The Gateway credential authorizes binding management; each tool call uses the
|
|
312
|
+
separate, short-lived member credential supplied by Core. Missing configuration,
|
|
313
|
+
rejected credentials, or a lost binding produces an explicit task failure.
|
|
314
|
+
Bindings expire and are released on completion, failure, or cancellation.
|
|
315
|
+
|
|
316
|
+
`npm test` verifies both adapters with local protocol fixtures. An optional real
|
|
317
|
+
Codex check performs a model call using the installed CLI's login and a temporary
|
|
318
|
+
MCP server:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
ORCHA_TEST_REAL_CODEX=/absolute/path/to/codex node --test --test-name-pattern='installed Codex' scripts/check-group-members.js
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Fixture tests do not replace a real OpenClaw Gateway tool call or full group
|
|
325
|
+
acceptance on the configured nodes. This repository does not install the plugin
|
|
326
|
+
or change credentials on remote hosts.
|
|
327
|
+
|
|
241
328
|
OpenClaw targets use request metadata `agentCode` as the local OpenClaw agent
|
|
242
329
|
id, producing sessions like `agent:<agentCode>:<sessionId>`. When `agentCode`
|
|
243
330
|
is missing, the bridge falls back to a plain `orcha-<sessionId>` session.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawn as
|
|
3
|
-
`):""}var It=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=Ot(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
|
|
2
|
+
import{spawn as ea}from"node:child_process";import{closeSync as ra,existsSync as Ln,mkdirSync as na,openSync as sa,readFileSync as Ye,rmSync as ia,statSync as bn,writeFileSync as Dn}from"node:fs";import{dirname as oa,resolve as tr}from"node:path";import{fileURLToPath as aa}from"node:url";import{createHash as Zi,randomUUID as Kt}from"node:crypto";var Q="0.1.37";function dt(){return new Date().toISOString()}function U(e,t=2){return String(e).padStart(t,"0")}function or(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${U(Math.floor(r/60))}:${U(r%60)}`}function jn(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${U(e.getMonth()+1)}-${U(e.getDate())}`,`T${U(e.getHours())}:${U(e.getMinutes())}:${U(e.getSeconds())}.${U(e.getMilliseconds(),3)}`,or(t)].join("")}function Kn(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 Gn(e,t){let r=Kn(e,t),n=Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second,e.getMilliseconds()),s=Math.round((n-e.getTime())/6e4);return[`${r.year}-${U(r.month)}-${U(r.day)}`,`T${U(r.hour)}:${U(r.minute)}:${U(r.second)}.${U(e.getMilliseconds(),3)}`,or(s)].join("")}function zn(e=new Date){let t=a(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return Gn(e,t)}catch{return jn(e)}}function u(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function a(e){return String(e??"").trim()}function _(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)?r:t}function b(e){return Array.isArray(e)?e.map(String):[]}function tt(e,t,r=process.cwd()){let n=u(e)?e:{};return a(n.cwd)||a(n.workspace)||a(t)||a(r)||process.cwd()}var St="[redacted]",Vn=/(authorization|api[_-]?key|credential|password|secret|token)/i;function Et(e){return Vn.test(a(e))}function ar(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(St))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${St}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${St}`)}function V(e,t=new WeakSet){if(e==null)return e;if(typeof e=="bigint")return e.toString();if(typeof e!="object")return e;if(e instanceof Date)return e.toISOString();if(e instanceof Error){if(t.has(e))return"[circular]";t.add(e);let s={name:e.name,message:e.message};e.stack&&(s.stack=e.stack);for(let i of Object.keys(e))s[i]=V(e[i],t);return t.delete(e),s}if(t.has(e))return"[circular]";if(t.add(e),Array.isArray(e)){let s=e.map(i=>V(i,t));return t.delete(e),s}let r={},n=Et(e.name||e.key);for(let[s,i]of Object.entries(e))r[s]=Et(s)||n&&s.toLowerCase()==="value"?St:V(i,t);return t.delete(e),r}function cr(e,t=4e3){let r=JSON.stringify(V(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function h(e,t,r,n={}){let s={ts:zn(),level:e,module:t,msg:r,...u(n)?V(n):{}};console.error(JSON.stringify(s))}function Ot(e){return Array.isArray(e)?e.map(t=>u(t)?t.type==="text"?a(t.text):t.type==="file"?a(t.uri):t.type==="image"?a(t.uri):"":"").filter(Boolean).join(`
|
|
3
|
+
`):""}var It=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=Ot(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 Wn}from"node:child_process";var ft="2.0",te=3e4,Jn=4e3;function xt(e,t){let r=Object.entries(u(t)?t:{}).filter(([n])=>Et(n)).map(([,n])=>n);return ar(e,r)}function Xn(e){return{code:Number.isInteger(e?.code)?e.code:-32e3,message:a(e?.message)||String(e),data:u(e?.data)?e.data:void 0}}function Yn(e){if(!u(e))return new Error(String(e||"runtime error"));let t=a(e.message)||"runtime error",r="data"in e?cr(e.data,4e3):"",n=new Error(r?`${t}; data=${r}`:t);return n.rpcCode=e.code,n.data=e.data,n}function Zn(e){return u(e)&&"id"in e&&!("method"in e)}function Qn(e){return u(e)&&typeof e.method=="string"&&"id"in e}function ts(e){return u(e)&&typeof e.method=="string"&&!("id"in e)}var Ct=class{constructor({command:t,args:r=[],cwd:n,env:s,label:i,framing:o="line",detached:c=!0}){this.command=t,this.args=Array.isArray(r)?r.map(String):[],this.cwd=n||process.cwd(),this.env=u(s)?{...s}:{...process.env},this.label=i||t,this.framing=o==="content-length"?"content-length":"line",this.detached=c!==!1,this.child=null,this.exited=!1,this.exitCode=null,this.exitSignal=null,this.stopPromise=null,this.stderrTail="",this.spawnError=null,this.lineBuffer="",this.headerBuffer=Buffer.alloc(0),this.seq=0,this.pending=new Map,this.notificationHandlers=new Map,this.requestHandlers=new Map,this.exitHandlers=new Set}async start({initialize:t=!0,initializeParams:r={},initializeTimeoutMs:n=te}={}){if(!(this.child&&!this.exited)&&(this.exited=!1,this.exitCode=null,this.exitSignal=null,this.stderrTail="",this.spawnError=null,this.child=Wn(this.command,this.args,{cwd:this.cwd,env:this.env,stdio:["pipe","pipe","pipe"],detached:this.detached}),this.child.stdout.on("data",s=>this.onStdout(s)),this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",s=>{this.stderrTail=`${this.stderrTail}${s}`.slice(-Jn);let i=xt(s.trimEnd(),this.env);i&&h("debug","runtime.stderr","runtime stderr",{target:this.label,text:i})}),this.child.on("exit",(s,i)=>this.handleExit(s,i)),this.child.on("error",s=>{this.spawnError=s,this.rejectAll(s)}),t)){let s=Math.max(1,_(n,te));try{await this.call("initialize",{protocolVersion:1,clientCapabilities:{},...r},s)}catch(i){let o=this.startupFailureDetail(),c=xt(i?.message||i,this.env);h("warn","runtime.initialize","runtime initialize failed",{target:this.label,timeoutMs:s,cause:c,...o}),await this.stop("initialize failed",{termTimeoutMs:1e3,killTimeoutMs:1e3});let l=o.stderr?`; stderr: ${o.stderr}`:`; command=${o.command}; cwd=${o.cwd}`;throw Object.assign(new Error(`runtime initialize failed: ${c}${l}`,{cause:i}),{code:"RUNTIME_INITIALIZE_FAILED",detail:o})}}}startupFailureDetail(){return{command:this.command,cwd:this.cwd,exited:this.exited,exitCode:this.exitCode,exitSignal:this.exitSignal,...this.spawnError?{spawnError:xt(this.spawnError.message,this.env)}:{},...this.stderrTail.trim()?{stderr:xt(this.stderrTail.trim(),this.env)}:{}}}onStdout(t){if(this.framing==="content-length"){this.onContentLengthData(Buffer.isBuffer(t)?t:Buffer.from(t));return}this.onLineData(t.toString("utf8"))}onLineData(t){this.lineBuffer+=t;let r=this.lineBuffer.split(/\r?\n/);this.lineBuffer=r.pop()||"";for(let n of r){let s=n.trim();s&&this.dispatchRaw(s)}}onContentLengthData(t){for(this.headerBuffer=Buffer.concat([this.headerBuffer,t]);this.headerBuffer.length>0;){let r=this.headerBuffer.indexOf(`\r
|
|
4
4
|
\r
|
|
5
|
-
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){h("warn","runtime.protocol","missing Content-Length header",{target:this.label}),this.headerBuffer=Buffer.alloc(0);return}let i=Number.parseInt(s[1],10),o=r+4,c=o+i;if(this.headerBuffer.length<c)return;let l=this.headerBuffer.subarray(o,c).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(c),this.dispatchRaw(l)}}dispatchRaw(t){let r;try{r=JSON.parse(t)}catch(n){h("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(n)});return}this.dispatch(r)}dispatch(t){if(
|
|
5
|
+
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){h("warn","runtime.protocol","missing Content-Length header",{target:this.label}),this.headerBuffer=Buffer.alloc(0);return}let i=Number.parseInt(s[1],10),o=r+4,c=o+i;if(this.headerBuffer.length<c)return;let l=this.headerBuffer.subarray(o,c).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(c),this.dispatchRaw(l)}}dispatchRaw(t){let r;try{r=JSON.parse(t)}catch(n){h("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(n)});return}this.dispatch(r)}dispatch(t){if(Zn(t)){this.resolveResponse(t);return}if(Qn(t)){this.handleRequest(t);return}ts(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?(h("warn","runtime.protocol","runtime rpc error",{target:this.label,method:n.method,requestId:r,error:t.error}),n.reject(Yn(t.error))):n.resolve(t.result))}async handleRequest(t){let r=this.requestHandlers.get(t.method);if(!r){this.writeFrame({jsonrpc:ft,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:ft,id:t.id,result:n??{}})}catch(n){this.writeFrame({jsonrpc:ft,id:t.id,error:Xn(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=te){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:ft,id:s,method:t,params:r};return new Promise((o,c)=>{let l=setTimeout(()=>{this.pending.delete(s),c(new Error(`${t} timed out after ${n}ms`))},n);this.pending.set(s,{resolve:o,reject:c,timer:l,method:t}),this.writeFrame(i,d=>{d&&(clearTimeout(l),this.pending.delete(s),c(d))})})}notify(t,r={}){this.writeFrame({jsonrpc:ft,method:t,params:r})}writeFrame(t,r){if(!this.child?.stdin||this.exited){r?.(new Error("runtime process is not running"));return}let n=JSON.stringify(t),s=this.framing==="content-length"?`Content-Length: ${Buffer.byteLength(n,"utf8")}\r
|
|
6
6
|
\r
|
|
7
7
|
${n}`:`${n}
|
|
8
|
-
`;this.child.stdin.write(s,r)}onNotification(t,r){let n=this.notificationHandlers.get(t)||new Set;return n.add(r),this.notificationHandlers.set(t,n),()=>{n.delete(r),n.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,r){return this.requestHandlers.set(t,r),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let r of this.pending.values())clearTimeout(r.timer),r.reject(t);this.pending.clear()}handleExit(t,r){this.exited=!0,this.exitCode=t,this.exitSignal=r,this.rejectAll(new Error(`runtime exited before response (${t}/${r})`));for(let n of this.exitHandlers)n(t,r)}async waitForExit(t=5e3){return!this.child||this.exited?!0:await new Promise(r=>{let n=setTimeout(()=>{s(),r(!1)},t);n.unref?.();let s=()=>{clearTimeout(n),this.exitHandlers.delete(i)},i=()=>{s(),r(!0)};this.exitHandlers.add(i),this.exited&&i()})}signal(t){if(!this.child||this.exited)return!1;let r=this.child.pid;if(!r)return!1;try{return this.detached&&process.platform!=="win32"?process.kill(-r,t):this.child.kill(t),!0}catch(n){if(n?.code==="ESRCH")return this.exited=!0,!1;try{return this.child.kill(t),!0}catch(s){return s?.code!=="ESRCH"&&h("warn","runtime","runtime signal failed",{target:this.label,pid:r,signal:t,error:String(s)}),!1}}}async stop(t="stop",{termTimeoutMs:r=5e3,killTimeoutMs:n=2e3}={}){if(!(!this.child||this.exited)){if(this.stopPromise)return await this.stopPromise;this.stopPromise=(async()=>{if(!this.child||this.exited)return;let s=this.child.pid;h("info","runtime","stopping runtime",{target:this.label,reason:t,pid:s}),this.rejectAll(new Error(`runtime stopped: ${t}`)),this.signal("SIGTERM"),!await this.waitForExit(r)&&this.child&&!this.exited&&(h("warn","runtime","runtime did not exit after SIGTERM; force killing",{target:this.label,reason:t,pid:s}),this.signal("SIGKILL"),await this.waitForExit(n))})();try{await this.stopPromise}finally{this.stopPromise=null}}}};import{randomUUID as ur}from"node:crypto";import{existsSync as Kn,readFileSync as Gn,realpathSync as or,statSync as Vn}from"node:fs";import{basename as lr,extname as dr,isAbsolute as pt,join as zn,relative as fr,resolve as ar}from"node:path";var Wn=25*1024*1024;function pr(e,t=""){let r=a(t);if(r)return r;let n=dr(a(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function mr(e,t){let r=typeof e=="string"?e.trim():"";return!r||r==="<omitted>"?"":r.startsWith("data:")?r:`data:${t};base64,${r.replace(/\s+/g,"")}`}function Ct(e){if(Array.isArray(e))return e.map(a).filter(Boolean);let t=a(e);return t?[t]:[]}function Jn(e,t){let r=fr(t,e);return r===""||!!r&&!r.startsWith("..")&&!pt(r)}function Xn(e,t){let r=a(e);if(!r||!Kn(r))return"";try{let n=or(r);for(let s of t)try{let i=or(s);if(Jn(n,i))return n}catch{}}catch{return""}return""}function Yn(e,t){let r=a(e);if(!r||!pt(r))return r;for(let n of Array.isArray(t)?t:[]){if(!u(n))continue;let s=a(n.runtimeRoot),i=a(n.hostRoot);if(!s||!i||!pt(s)||!pt(i))continue;let o=fr(ar(s),ar(r));if(o===""||!o.startsWith("..")&&!pt(o))return o?zn(i,o):i}return r}function Qt(e,t,r={}){let n=a(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:Zn(n,t,r)}function Zn(e,t,r={}){let n=[...Ct(r.trustedFileRoots),...Ct(r.trustedFileRoot),...Ct(r.artifactRoots),...Ct(r.artifactRoot)],s=Xn(Yn(e,r.pathMappings),n);if(!s)return"";try{let i=Vn(s);return!i.isFile()||i.size<=0||i.size>Wn?"":`data:${t};base64,${Gn(s).toString("base64")}`}catch{return""}}function x(...e){for(let t of e){let r=a(t);if(r)return r}return""}function Qn(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=x(n,e.previewUrl,e.fileUrl,e.imageUrl,e.dataUrl,e.url,e.uri,t.previewUrl,t.fileUrl,t.imageUrl,t.dataUrl,t.url,t.uri),o=dr(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function ee(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!u(e))return null;let n=u(e.payload)?e.payload:{},s=a(e.type),i=a(n.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let o=x(n.call_id,n.id),c=x(n.saved_path,n.savedPath),l=x(n.revised_prompt,n.revisedPrompt),d=pr(c,n.mimeType||n.mime_type),f=mr(n.result,d)||Qt(c,d,t);if(!f)return null;let p=f.startsWith("data:")?f:"",m=c?lr(c):`${o||ur()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:m||"Generated image",summary:l||"Generated image",content:{prompt:l||void 0,dataUrl:p||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:p||void 0,previewUrl:f,fileUrl:f,metadata:{source:r,eventType:i,callId:o||void 0,savedPath:c||void 0,filename:m,mimeType:d,revisedPrompt:l||void 0}}}function ts(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 es(e,t={}){let{source:r="runtime_artifact"}=t,n=u(e)?e:{};if(!Object.keys(n).length)return null;let s=u(n.content)?{...n.content}:{},i=u(n.metadata)?{...n.metadata}:{},o=x(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),c=x(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),l=x(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),d=Qn(n,s,l,o),f=d?pr(o,c):c;if(d){let b=x(n.dataUrl,s.dataUrl),T=b.startsWith("data:")?b:"",R=x(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),S=mr(n.result??s.result,f)||T||Qt(o,f,t)||Qt(R,f,t);S&&(S.startsWith("data:")&&(s.dataUrl||=S),s.imageUrl||=S,s.previewUrl||=S,s.fileUrl||=S,f&&(s.mimeType||=f))}for(let[b,T]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let R=n[b];R!=null&&R!==""&&!(T in s)&&(s[T]=R)}let p=x(n.fileUrl,n.downloadUrl,n.imageUrl,n.dataUrl,n.url,n.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),m=x(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),g=x(n.dataUrl,s.dataUrl,p.startsWith("data:")?p:"",m.startsWith("data:")?m:""),y=x(n.filename,i.filename,o?lr(o):""),I=x(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:l,type:n.type||l,fieldKey:I,title:x(n.title,y,"Runtime artifact"),summary:x(n.summary,s.prompt,n.title,y,"Runtime artifact"),content:s,dataUrl:g||void 0,fileUrl:p||void 0,previewUrl:m||void 0,metadata:{...i,source:x(i.source,r),savedPath:o||i.savedPath,filename:y||i.filename,mimeType:f||i.mimeType}}}function bt(e,t){if(!t||!e)return;let r=u(t.metadata)?t.metadata:{},n=x(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||ur(),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 te(e,t,r={}){for(let n of ts(e))bt(t,es(n,r))}function re(e){if(!u(e)||!u(e.payload))return u(e)?e:{value:e};let t=a(e.payload.type);if(t!=="image_generation_end"&&t!=="image_generation_call")return e;let r={...e.payload};return typeof r.result=="string"&&r.result&&(r.result="<omitted>",r.resultLength=e.payload.result.length),{...e,payload:r}}function cr(e,t,r){if(!u(e))return e;let n=u(e.event)?e.event:null;return n?(bt(t,ee(n,r)),{...e,event:re(n)}):e}function hr(e,t,r={}){if(!u(e))return e;te(e,t,r);let n=cr(e,t,r),s=u(n.update)?cr(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function gr(e,t,r={}){let n=u(e)?{...e}:{};te(n,t,r),te(u(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function _r(e,t){let r=_(e,t);return r>0?r:t}var et=class{constructor(t,r,n={},s={}){this.agent=t,this.target=r,this.callbacks=n,this.options=s,this.proc=null,this.launch=null,this.launchCleanup=null,this.permissionHandlers=new Map}async ensureStarted(){if(this.proc)return;let t=a(this.target.command);if(!t)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let r={command:t,args:C(this.target.args),cwd:tt(this.target,this.agent.workspace),environment:u(this.target.env)?this.target.env:{}},n=this.options.prepareLaunch?await this.options.prepareLaunch(r):{...r,environment:{...process.env,...r.environment},cleanup:async()=>{}};this.launch=n,this.launchCleanup=n.cleanup,this.proc=new At({command:n.command,args:n.args,cwd:n.cwd,env:n.environment,label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:a(this.target.framing||"line")}),this.proc.onRequest("session/request_permission",s=>this.handlePermissionRequest(s)),this.proc.onRequest("session/requestPermission",s=>this.handlePermissionRequest(s));try{await this.proc.start({initialize:this.target.initialize!==!1,initializeTimeoutMs:_r(this.target.initializeTimeoutMs,_r(this.options.initializeTimeoutMs,3e4)),initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:Q},...u(this.target.initializeParams)?this.target.initializeParams:{}}})}catch(s){throw await this.proc?.stop("runtime startup failed"),this.proc=null,await this.cleanupLaunch(),s}}async sessionNew(t={}){return await this.ensureStarted(),this.proc.call("session/new",this.sessionNewParams(t))}sessionNewParams(t={}){let r=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return{...t,mcpServers:r}}async sessionPrompt(t,r){await this.ensureStarted();let n=a(t.sessionId),s=new Map,i=this.artifactOptions(),o=this.proc.onNotification("session/update",l=>{let d=a(l.sessionId);(!d||d===n)&&r(hr(l,s,i))}),c=async l=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:l,emitUpdate:r})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,c),this.permissionHandlers.set("*",c);try{let l=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return gr(l,s,i)}finally{o(),n&&this.permissionHandlers.delete(n),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let r=a(t.sessionId),n=this.permissionHandlers.get(r)||this.permissionHandlers.get("*");return n?n(t):{outcome:"denied",reason:"no active Orcha permission handler"}}artifactSource(){return a(this.target.type||"acp")==="openclaw"?"openclaw_image_generation":"acp_runtime_image_generation"}artifactOptions(){let t=u(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[a(this.launch?.artifactDirectory),a(this.launch?.homeDirectory),a(this.target.artifactRoot),a(this.target.artifactDir),a(this.target.runtimeArtifactRoot),a(t.ORCHA_RUNTIME_ARTIFACT_DIR),...C(this.target.trustedArtifactRoots),...C(this.target.trustedFileRoots),...C(this.target.artifactRoots),...C(this.target.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(this.launch?.pathMappings)?this.launch.pathMappings:[]}}async stop(t){try{await this.proc?.stop(t)}finally{this.proc=null,await this.cleanupLaunch()}}async cleanupLaunch(){let t=this.launchCleanup;this.launchCleanup=null,this.launch=null,await t?.()}};function rs(e){let t=u(e.metadata)?e.metadata:{};return a(t.agentCode)}function ns(e,t){let r=rs(e);return r?`agent:${r}:${t}`:`orcha-${t}`}var Nt=class extends et{constructor(t,r,n,s={},i={}){let o=a(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",c=a(r.command)||"openclaw",l=Array.isArray(r.args)?r.args.map(String):[],d=l.length>0?l:["acp","--session",ns(t,o)];super(t,{...r,command:c,args:d},s,i)}sessionNewParams(t={}){return{...t,mcpServers:[]}}};import{spawn as wr}from"node:child_process";import{randomUUID as rt}from"node:crypto";import{existsSync as Or,mkdirSync as ss,readdirSync as Ir,readFileSync as xr,realpathSync as ht,rmSync as is,rmdirSync as os,statSync as as,unlinkSync as cs}from"node:fs";import{homedir as us,tmpdir as Ar}from"node:os";import{basename as ae,dirname as ls,join as H,resolve as Tr}from"node:path";var ds=36e5,Cr=5e3,fs=2*60*1e3,ps=2*60*1e3,ms=12,hs=1e3,gs=1500,_s=1e3,Mt=24*60*60*1e3,mt=new Set(["final_answer","final","complete","completed","done"]),Ts=new Set(["function_call","function_call_output","custom_tool_call","custom_tool_call_output","local_shell_call","local_shell_call_output","mcp_tool_call","mcp_tool_call_output","web_search_call","image_generation_call","image_generation_end"]),ys=new Set(["context_compacted","context_compaction","context_compressed"]);function Pt(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{wr("taskkill",r,{stdio:"ignore",windowsHide:!0}).unref?.()}catch{try{e.kill(t)}catch{}}return}try{process.kill(-e.pid,t)}catch(r){if(r?.code==="ESRCH")return;try{e.kill(t)}catch{}}}}function ne(e){Pt(e,"SIGTERM");let t=setTimeout(()=>Pt(e,"SIGKILL"),Cr);return t.unref?.(),t}function D(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>D(t)).join("");if(!u(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let r=D(e[t]);if(r)return r}return""}function br(e){if(!u(e))return"";let t=u(e.payload)?e.payload:{};if(a(e.type)==="event_msg"){if(a(t.type)==="agent_message")return a(t.message);if(a(t.type)==="task_complete")return a(t.last_agent_message)}if(a(e.type)==="response_item"&&a(t.type)==="message"&&a(t.role)==="assistant")return D(t.content)||D(t.message);if(a(e.type)==="result")return D(e.result);let r=D(e.delta)||D(e.text)||D(e.content);if(r)return r;let n=u(e.item)?e.item:{};return["message","agent_message"].includes(a(n.type))||a(n.role)==="assistant"?D(n.content)||D(n.text)||D(n.message):""}function Nr(e,t={}){return ee(e,{source:"codex_cli_image_generation",...t})}function Mr(e,t){bt(e.artifacts,t)}function Ur(e){return z(re(e))}function ce(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);if(r==="event_msg"&&n==="task_complete")return!0;let s=a(t.phase||t.status||t.stage).toLowerCase();if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return mt.has(s);let i=u(e.item)?e.item:{};return r==="item.completed"&&a(i.type)==="agent_message"?!0:r==="result"&&e.is_error!==!0?a(e.result).length>0:!1}function Rs(e){let t=a(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=ae(a(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function yr(e,t,r){let n=u(t.error)?t.error:{},s=a(n.message)||D(t.error)||a(t.result)||a(t.message)||r;return Object.assign(new Error(s),{code:e})}function Ss(e,t){if(!u(e))return null;let r=a(e.type).toLowerCase();if(t==="codex")return r==="turn.completed"?{status:"completed",result:{stopReason:"end_turn"}}:r==="turn.failed"?{status:"failed",error:yr("RUNTIME_CODEX_TURN_FAILED",e,"Codex turn failed")}:null;if(t==="claude"&&r==="result"){let n=a(e.subtype).toLowerCase();return e.is_error===!0||n.startsWith("error")||["failed","failure"].includes(n)?{status:"failed",error:yr("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...a(e.result)?{output:a(e.result)}:{}}}}return null}function Rr(e){return u(e)?a(e.phase||e.status||e.stage).toLowerCase():""}function Es(e){if(!u(e)||ce(e))return!1;let t=u(e.payload)?e.payload:{},r=a(e.type),n=a(t.type),s=Rr(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return!!(s&&!mt.has(s));let i=u(e.item)?e.item:{},o=Rr(i);return a(i.role)==="assistant"||a(i.type)==="message"?!!(o&&!mt.has(o)):!1}function ws(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:ae(e)==="codex"}function Os(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:ae(e)==="codex"}function Pr(e){return Math.max(20,_(e.codexTranscriptPollMs||e.transcriptPollMs,hs))}function Is(e){return Math.max(0,_(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,gs))}function kt(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 ue(e){let t=u(e?.metadata)?e.metadata:{};return u(t._runtimeBridge)?t._runtimeBridge:{}}function se(e){return a(ue(e).promptKind).toLowerCase()}function xs(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=kt(r);if(n!=null)return n}return se(t)==="chat"}function As(e,t){let r=ue(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=kt(s);if(i!=null)return i}let n=se(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=kt(s);if(i!=null)return i}return se(e)==="chat"}function Cs(e){let t=ue(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=kt(r);if(n!=null)return n}return null}function bs(e,t){let r=Cs(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function Ns(e,t){return!e.finalTextOnly||t}function kr(e,t,r,n,s=n){return!n||e.emittedTexts.has(s)?!1:(e.emittedTexts.add(s),r({sessionId:t,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:n}}}),!0)}function Lr(e,t,r,n){return!n||e.emittedThoughtTexts.has(n)?!1:(e.emittedThoughtTexts.add(n),r({sessionId:t,update:{sessionUpdate:"agent_thought_chunk",content:{type:"text",text:n}}}),!0)}function Ms(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function Us(e,t){let r=u(e.env)?e.env:{},n=a(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||H(Ar(),"orcha-runtime-artifacts"),s=a(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||rt(),i=H(n,s),o=H(i,rt());return ss(o,{recursive:!0}),{root:o,realRoot:ht(o),sessionRoot:i,realSessionRoot:ht(i)}}function Ps(e){let t=a(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:ht(t),sessionRoot:"",realSessionRoot:""}}function Dr(e){return a(u(e)?e.root:e)}function Sr(e){let t=Dr(e),r=a(u(e)?e.sessionRoot:ls(t)),n=a(u(e)?e.realSessionRoot:"");if(r)try{if(n&&ht(r)!==n)return;os(r)}catch{}}function ks(e,t={}){let r=Dr(e),n=a(u(e)?e.realRoot:"");if(r){try{if(n&&ht(r)!==n){h("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{Sr(e);return}try{is(r,{recursive:!0,force:!0})}catch(s){h("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:r,error:String(s?.message||s)});return}Sr(e)}}function Ls(e,t,r=null){return{trustedFileRoots:[t,a(r?.artifactDirectory),a(r?.homeDirectory),...C(e.trustedArtifactRoots),...C(e.trustedFileRoots),...C(e.artifactRoots),...C(e.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(r?.pathMappings)?r.pathMappings:[]}}function vr(e){let t=a(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let r=u(e.env)?e.env:{},n=a(e.codexHome||r.CODEX_HOME||process.env.CODEX_HOME)||H(us(),".codex");return H(n,"sessions")}function Ds(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 H(e,n,s,i)}function Hr(e,t,r){let n=new Set;for(let s of[t-Mt,t,t+Mt,r-Mt,r,r+Mt])n.add(Ds(e,s));return[...n].filter(s=>Or(s))}function vs(e,t,r){let n=vr(e),s=t-fs,i=r+ps,o=[];for(let c of Hr(n,t,r)){let l=[];try{l=Ir(c)}catch{continue}for(let d of l){if(!d.endsWith(".jsonl"))continue;let f=H(c,d);try{let p=as(f);if(!p.isFile()||p.mtimeMs<s||p.mtimeMs>i)continue;o.push({path:f,mtimeMs:p.mtimeMs})}catch{}}}return o.sort((c,l)=>l.mtimeMs-c.mtimeMs).slice(0,ms)}function Hs(e,t,r=t){let n=vr(e),s=new Set;for(let i of Hr(n,t,r)){let o=[];try{o=Ir(i)}catch{continue}for(let c of o)c.endsWith(".jsonl")&&s.add(H(i,c))}return s}function ie(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)ie(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&&ie(e[n],t,r+1)}}function Fr(e){return a(e).replace(/\s+/g," ")}function Fs(e){let t=Fr(e);if(!t)return[];if(t.length<=200)return[t];let r=160,n=[0,Math.floor((t.length-r)/2),t.length-r],s=new Set,i=[];for(let o of n){let c=t.slice(Math.max(0,o),Math.max(0,o)+r).trim();c.length>=40&&!s.has(c)&&(s.add(c),i.push(c))}return i}function $s(e,t){let r=Fs(t);if(!r.length)return!1;let n=[];for(let i of e)ie(i,n);let s=Fr(n.join(" "));return r.every(i=>s.includes(i))}function Bs(e){return e.find(t=>u(t)&&a(t.type)==="session_meta"&&u(t.payload))||null}function qs(e){let t=u(e?.payload)?e.payload:{},r=a(e?.timestamp||t.timestamp),n=Date.parse(r);return Number.isFinite(n)?n:Number.NaN}function js(e){let t=a(e.originator),r=a(e.source);if(t!=="codex_exec"&&r!=="exec"||a(e.parent_thread_id))return!1;let n=a(e.thread_source);if(n&&n!=="user")return!1;let s=a(e.session_id),i=a(e.id);return!(s&&i&&s!==i)}function Ks(e,t,r){if(!$s(e,t.promptText))return!1;let n=Bs(e);if(!n)return!1;let s=n.payload;if(!js(s))return!1;let i=qs(n);if(!Number.isFinite(i)||i<t.startedAtMs-5e3||i>r+5e3)return!1;let o=a(t.target.cwd),c=a(s.cwd);return!(o&&c&&Tr(o)!==Tr(c))}function Er(e){try{return Vs(xr(e,"utf8"))}catch{return null}}function Gs(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=Er(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of vs(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=Er(s.path);!i||!Ks(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,h("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,h("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function Vs(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 zs(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);return r==="event_msg"&&n==="image_generation_end"||r==="response_item"&&n==="image_generation_call"}function Ws(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{};return a(e.type)==="response_item"&&Ts.has(a(t.type))}function Js(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{};return ys.has(a(t.type))}function Xs(e,t,r,n){let s=br(e),i=ce(e),o=0,c=0,l=0;if(s&&!i&&t.emitThoughtChunks&&Lr(t,r,n,s)&&(l=1),s&&i){let d=t.emittedTexts.size?`
|
|
8
|
+
`;this.child.stdin.write(s,r)}onNotification(t,r){let n=this.notificationHandlers.get(t)||new Set;return n.add(r),this.notificationHandlers.set(t,n),()=>{n.delete(r),n.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,r){return this.requestHandlers.set(t,r),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let r of this.pending.values())clearTimeout(r.timer),r.reject(t);this.pending.clear()}handleExit(t,r){this.exited=!0,this.exitCode=t,this.exitSignal=r,this.rejectAll(new Error(`runtime exited before response (${t}/${r})`));for(let n of this.exitHandlers)n(t,r)}async waitForExit(t=5e3){return!this.child||this.exited?!0:await new Promise(r=>{let n=setTimeout(()=>{s(),r(!1)},t);n.unref?.();let s=()=>{clearTimeout(n),this.exitHandlers.delete(i)},i=()=>{s(),r(!0)};this.exitHandlers.add(i),this.exited&&i()})}signal(t){if(!this.child||this.exited)return!1;let r=this.child.pid;if(!r)return!1;try{return this.detached&&process.platform!=="win32"?process.kill(-r,t):this.child.kill(t),!0}catch(n){if(n?.code==="ESRCH")return this.exited=!0,!1;try{return this.child.kill(t),!0}catch(s){return s?.code!=="ESRCH"&&h("warn","runtime","runtime signal failed",{target:this.label,pid:r,signal:t,error:String(s)}),!1}}}async stop(t="stop",{termTimeoutMs:r=5e3,killTimeoutMs:n=2e3}={}){if(!(!this.child||this.exited)){if(this.stopPromise)return await this.stopPromise;this.stopPromise=(async()=>{if(!this.child||this.exited)return;let s=this.child.pid;h("info","runtime","stopping runtime",{target:this.label,reason:t,pid:s}),this.rejectAll(new Error(`runtime stopped: ${t}`)),this.signal("SIGTERM"),!await this.waitForExit(r)&&this.child&&!this.exited&&(h("warn","runtime","runtime did not exit after SIGTERM; force killing",{target:this.label,reason:t,pid:s}),this.signal("SIGKILL"),await this.waitForExit(n))})();try{await this.stopPromise}finally{this.stopPromise=null}}}};import{randomUUID as fr}from"node:crypto";import{existsSync as es,readFileSync as rs,realpathSync as ur,statSync as ns}from"node:fs";import{basename as pr,extname as mr,isAbsolute as pt,join as ss,relative as hr,resolve as lr}from"node:path";var is=25*1024*1024;function gr(e,t=""){let r=a(t);if(r)return r;let n=mr(a(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function _r(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 bt(e){if(Array.isArray(e))return e.map(a).filter(Boolean);let t=a(e);return t?[t]:[]}function os(e,t){let r=hr(t,e);return r===""||!!r&&!r.startsWith("..")&&!pt(r)}function as(e,t){let r=a(e);if(!r||!es(r))return"";try{let n=ur(r);for(let s of t)try{let i=ur(s);if(os(n,i))return n}catch{}}catch{return""}return""}function cs(e,t){let r=a(e);if(!r||!pt(r))return r;for(let n of Array.isArray(t)?t:[]){if(!u(n))continue;let s=a(n.runtimeRoot),i=a(n.hostRoot);if(!s||!i||!pt(s)||!pt(i))continue;let o=hr(lr(s),lr(r));if(o===""||!o.startsWith("..")&&!pt(o))return o?ss(i,o):i}return r}function ee(e,t,r={}){let n=a(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:us(n,t,r)}function us(e,t,r={}){let n=[...bt(r.trustedFileRoots),...bt(r.trustedFileRoot),...bt(r.artifactRoots),...bt(r.artifactRoot)],s=as(cs(e,r.pathMappings),n);if(!s)return"";try{let i=ns(s);return!i.isFile()||i.size<=0||i.size>is?"":`data:${t};base64,${rs(s).toString("base64")}`}catch{return""}}function C(...e){for(let t of e){let r=a(t);if(r)return r}return""}function ls(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=C(n,e.previewUrl,e.fileUrl,e.imageUrl,e.dataUrl,e.url,e.uri,t.previewUrl,t.fileUrl,t.imageUrl,t.dataUrl,t.url,t.uri),o=mr(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function ne(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!u(e))return null;let n=u(e.payload)?e.payload:{},s=a(e.type),i=a(n.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let o=C(n.call_id,n.id),c=C(n.saved_path,n.savedPath),l=C(n.revised_prompt,n.revisedPrompt),d=gr(c,n.mimeType||n.mime_type),f=_r(n.result,d)||ee(c,d,t);if(!f)return null;let p=f.startsWith("data:")?f:"",m=c?pr(c):`${o||fr()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:m||"Generated image",summary:l||"Generated image",content:{prompt:l||void 0,dataUrl:p||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:p||void 0,previewUrl:f,fileUrl:f,metadata:{source:r,eventType:i,callId:o||void 0,savedPath:c||void 0,filename:m,mimeType:d,revisedPrompt:l||void 0}}}function ds(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 fs(e,t={}){let{source:r="runtime_artifact"}=t,n=u(e)?e:{};if(!Object.keys(n).length)return null;let s=u(n.content)?{...n.content}:{},i=u(n.metadata)?{...n.metadata}:{},o=C(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),c=C(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),l=C(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),d=ls(n,s,l,o),f=d?gr(o,c):c;if(d){let A=C(n.dataUrl,s.dataUrl),T=A.startsWith("data:")?A:"",R=C(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),w=_r(n.result??s.result,f)||T||ee(o,f,t)||ee(R,f,t);w&&(w.startsWith("data:")&&(s.dataUrl||=w),s.imageUrl||=w,s.previewUrl||=w,s.fileUrl||=w,f&&(s.mimeType||=f))}for(let[A,T]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let R=n[A];R!=null&&R!==""&&!(T in s)&&(s[T]=R)}let p=C(n.fileUrl,n.downloadUrl,n.imageUrl,n.dataUrl,n.url,n.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),m=C(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),g=C(n.dataUrl,s.dataUrl,p.startsWith("data:")?p:"",m.startsWith("data:")?m:""),y=C(n.filename,i.filename,o?pr(o):""),x=C(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:l,type:n.type||l,fieldKey:x,title:C(n.title,y,"Runtime artifact"),summary:C(n.summary,s.prompt,n.title,y,"Runtime artifact"),content:s,dataUrl:g||void 0,fileUrl:p||void 0,previewUrl:m||void 0,metadata:{...i,source:C(i.source,r),savedPath:o||i.savedPath,filename:y||i.filename,mimeType:f||i.mimeType}}}function At(e,t){if(!t||!e)return;let r=u(t.metadata)?t.metadata:{},n=C(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||fr(),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 re(e,t,r={}){for(let n of ds(e))At(t,fs(n,r))}function se(e){if(!u(e)||!u(e.payload))return u(e)?e:{value:e};let t=a(e.payload.type);if(t!=="image_generation_end"&&t!=="image_generation_call")return e;let r={...e.payload};return typeof r.result=="string"&&r.result&&(r.result="<omitted>",r.resultLength=e.payload.result.length),{...e,payload:r}}function dr(e,t,r){if(!u(e))return e;let n=u(e.event)?e.event:null;return n?(At(t,ne(n,r)),{...e,event:se(n)}):e}function Tr(e,t,r={}){if(!u(e))return e;re(e,t,r);let n=dr(e,t,r),s=u(n.update)?dr(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function yr(e,t,r={}){let n=u(e)?{...e}:{};re(n,t,r),re(u(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function Rr(e,t){let r=_(e,t);return r>0?r:t}var et=class{constructor(t,r,n={},s={}){this.agent=t,this.target=r,this.callbacks=n,this.options=s,this.proc=null,this.launch=null,this.launchCleanup=null,this.permissionHandlers=new Map}async ensureStarted(){if(this.proc)return;let t=a(this.target.command);if(!t)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let r={command:t,args:b(this.target.args),cwd:tt(this.target,this.agent.workspace),environment:u(this.target.env)?this.target.env:{}},n=this.options.prepareLaunch?await this.options.prepareLaunch(r):{...r,environment:{...process.env,...r.environment},cleanup:async()=>{}};this.launch=n,this.launchCleanup=n.cleanup,this.proc=new Ct({command:n.command,args:n.args,cwd:n.cwd,env:n.environment,label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:a(this.target.framing||"line")}),this.proc.onRequest("session/request_permission",s=>this.handlePermissionRequest(s)),this.proc.onRequest("session/requestPermission",s=>this.handlePermissionRequest(s));try{await this.proc.start({initialize:this.target.initialize!==!1,initializeTimeoutMs:Rr(this.target.initializeTimeoutMs,Rr(this.options.initializeTimeoutMs,3e4)),initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:Q},...u(this.target.initializeParams)?this.target.initializeParams:{}}})}catch(s){throw await this.proc?.stop("runtime startup failed"),this.proc=null,await this.cleanupLaunch(),s}}async sessionNew(t={}){return await this.ensureStarted(),this.proc.call("session/new",this.sessionNewParams(t))}sessionNewParams(t={}){let r=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return{...t,mcpServers:r}}async sessionPrompt(t,r){await this.ensureStarted();let n=a(t.sessionId),s=new Map,i=this.artifactOptions(),o=this.proc.onNotification("session/update",l=>{let d=a(l.sessionId);(!d||d===n)&&r(Tr(l,s,i))}),c=async l=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:l,emitUpdate:r})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,c),this.permissionHandlers.set("*",c);try{let l=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return yr(l,s,i)}finally{o(),n&&this.permissionHandlers.delete(n),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let r=a(t.sessionId),n=this.permissionHandlers.get(r)||this.permissionHandlers.get("*");return n?n(t):{outcome:"denied",reason:"no active Orcha permission handler"}}artifactSource(){return a(this.target.type||"acp")==="openclaw"?"openclaw_image_generation":"acp_runtime_image_generation"}artifactOptions(){let t=u(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[a(this.launch?.artifactDirectory),a(this.launch?.homeDirectory),a(this.target.artifactRoot),a(this.target.artifactDir),a(this.target.runtimeArtifactRoot),a(t.ORCHA_RUNTIME_ARTIFACT_DIR),...b(this.target.trustedArtifactRoots),...b(this.target.trustedFileRoots),...b(this.target.artifactRoots),...b(this.target.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(this.launch?.pathMappings)?this.launch.pathMappings:[]}}async stop(t){try{await this.proc?.stop(t)}finally{this.proc=null,await this.cleanupLaunch()}}async cleanupLaunch(){let t=this.launchCleanup;this.launchCleanup=null,this.launch=null,await t?.()}};import{createServer as ps}from"node:http";import{randomBytes as ms}from"node:crypto";var wr=["find_capabilities","describe_capability","execute_capability","inspect_result"],hs=8*1024*1024;function Nt(e,t){if(!Array.isArray(e)||e.length!==1)throw new Error("one task-scoped Orcha MCP server is required");let r=e[0],n=new URL(r.url);if(r.name!=="orcha"||r.type!=="http"||!["http:","https:"].includes(n.protocol)||n.username||n.password||n.hash||t&&n.href!==new URL(t).href)throw new Error("Orcha MCP server does not match the trusted binding");let s=Object.fromEntries((r.headers||[]).map(({name:i,value:o})=>[i.toLowerCase(),o]));if(!String(s.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:n.href,headers:{...s,"content-type":"application/json",accept:"application/json"}}}async function Er(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>hs)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function Or(e,t,r){let n=await fetch(e.url,{method:"POST",headers:e.headers,body:JSON.stringify(t),redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(36e5),...r?[r]:[]])});if(!n.ok)throw new Error(`Orcha MCP request failed (${n.status})`);if(n.status===202||n.status===204)return null;let s=await Er(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function Sr(e,t){let r=await Or(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},t),n=r?.result?.tools;if(r?.error||!Array.isArray(n)||n.length!==wr.length||wr.some(s=>!n.some(i=>i.name===s&&i.inputSchema?.type==="object")))throw new Error("Orcha MCP did not expose its four authorized control tools");return n}async function Ir(e){let t=Nt(e),r=new AbortController;await Sr(t,r.signal);let n=ms(32).toString("hex"),s=ps(async(i,o)=>{if(i.url!=="/mcp"||i.headers.authorization!==`Bearer ${n}`){o.writeHead(403).end();return}if(i.method!=="POST"){o.writeHead(405).end();return}try{let c=await Er(i);if(!c||c.jsonrpc!=="2.0"||typeof c.method!="string")throw new Error("Invalid MCP request");let l=await Or(t,c,r.signal);o.writeHead(l===null?202:200,{"content-type":"application/json"}),o.end(l===null?"":JSON.stringify(l))}catch{o.writeHead(502,{"content-type":"application/json"}).end(JSON.stringify({error:"The task-scoped Orcha MCP connection failed"}))}});return await new Promise((i,o)=>{s.once("error",o),s.listen(0,"127.0.0.1",i)}),{url:`http://127.0.0.1:${s.address().port}/mcp`,token:n,async refresh(i){let o=Nt(i,t.url);await Sr(o,r.signal),t=o},async close(){r.abort(),s.closeAllConnections(),await new Promise(i=>s.close(i))}}}var Mt=class{constructor(t,r){this.target=t,this.identity=r,this.bound=!1}async request(t,r,n=!1){let s=a(this.target.mcpBridgeUrl),i=a(this.target.mcpBridgeTokenEnv),o=this.target.env?.[i]||process.env[i];if(!s||!i||!o)throw Object.assign(new Error("OpenClaw requires the Orcha tool plugin, mcpBridgeUrl and mcpBridgeTokenEnv"),{code:"OPENCLAW_MCP_NOT_CONFIGURED"});let c=new URL(s);if(!["http:","https:"].includes(c.protocol)||c.username||c.password||c.pathname!=="/plugins/orcha-runtime/mcp-bindings"||c.search||c.hash)throw new Error("OpenClaw MCP binding URL must be the trusted Gateway plugin route");let l=await fetch(c,{method:t,redirect:"error",signal:AbortSignal.timeout(3e4),headers:{authorization:`Bearer ${o}`,"content-type":"application/json",...n?{"if-match":this.identity.runId}:{}},body:JSON.stringify(r)});if(!l.ok)throw Object.assign(new Error(`OpenClaw Orcha tool binding failed (${l.status})`),{code:"OPENCLAW_MCP_BINDING_FAILED"})}async bind(t,r=!1){Nt(t),await this.request("PUT",{...this.identity,mcpServer:t[0]},r),this.bound=!0}async close(){this.bound&&(await this.request("DELETE",{runId:this.identity.runId,sessionKey:this.identity.sessionKey}),this.bound=!1)}};function ie(e){let t=u(e.metadata)?e.metadata:{};return a(t.agentCode)}function xr(e,t){let r=ie(e);return r?`agent:${r}:${t}`:`orcha-${t}`}var Ut=class extends et{constructor(t,r,n,s={},i={}){let o=a(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",c=a(r.command)||"openclaw",l=Array.isArray(r.args)?r.args.map(String):[],d=l.length>0?l:["acp","--session",xr(t,o)];super(t,{...r,command:c,args:d},s,i),this.boundSessionKey=xr(t,o),this.binding=null}async sessionNew(t={}){if(t.mcpServers?.length&&t.metadata?.source==="conversation_delegation"){let r=[...this.target.args],n=r.indexOf("--session"),s=r.find(l=>l.startsWith("--session=")),i=s?s.slice(10):n<0?null:r[n+1];if(i&&i!==this.boundSessionKey)throw Object.assign(new Error("OpenClaw --session must match this Orcha task's private session"),{code:"OPENCLAW_SESSION_BINDING_CONFLICT"});i===null&&r.push("--session",this.boundSessionKey),this.target.args=r;let o=a(this.options.runId),c=Number(this.options.sandboxPolicy?.maxRuntimeSeconds||this.options.sessionPromptTimeoutMs/1e3||3600);if(!o||!ie(this.agent))throw new Error("OpenClaw MCP requires a trusted task and Agent identity");this.binding=new Mt(this.target,{runId:o,sessionKey:this.boundSessionKey,agentCode:ie(this.agent),expiresAt:new Date(Date.now()+c*1e3).toISOString()}),await this.binding.bind(t.mcpServers)}try{return await super.sessionNew(t)}catch(r){throw await this.binding?.close(),r}}async refreshMcpServers(t){if(!this.binding)throw Object.assign(new Error("The original OpenClaw task binding is unavailable"),{code:"RUNTIME_OPERATION_NOT_FOUND"});await this.binding.bind(t,!0)}async stop(t){try{await super.stop(t)}finally{await this.binding?.close()}}sessionNewParams(t={}){return{...t,mcpServers:[]}}};import{spawn as kr}from"node:child_process";import{randomUUID as rt}from"node:crypto";import{existsSync as Lr,mkdirSync as gs,readdirSync as Dr,readFileSync as vr,realpathSync as ht,rmSync as _s,rmdirSync as Ts,statSync as ys,unlinkSync as Rs}from"node:fs";import{homedir as ws,tmpdir as Hr}from"node:os";import{basename as le,dirname as Ss,join as $,resolve as br}from"node:path";async function Cr(e){let t=await Ir(e),r="ORCHA_TASK_MCP_TOKEN";return{args:["-c",`mcp_servers.orcha={url=${JSON.stringify(t.url)},bearer_token_env_var=${JSON.stringify(r)},required=true}`],environment:{[r]:t.token},refresh:n=>t.refresh(n),close:()=>t.close()}}var Es=36e5,$r=5e3,Os=2*60*1e3,Is=2*60*1e3,xs=12,Cs=1e3,bs=1500,As=1e3,Pt=24*60*60*1e3,mt=new Set(["final_answer","final","complete","completed","done"]),Ns=new Set(["function_call","function_call_output","custom_tool_call","custom_tool_call_output","local_shell_call","local_shell_call_output","mcp_tool_call","mcp_tool_call_output","web_search_call","image_generation_call","image_generation_end"]),Ms=new Set(["context_compacted","context_compaction","context_compressed"]);function Lt(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{kr("taskkill",r,{stdio:"ignore",windowsHide:!0}).unref?.()}catch{try{e.kill(t)}catch{}}return}try{process.kill(-e.pid,t)}catch(r){if(r?.code==="ESRCH")return;try{e.kill(t)}catch{}}}}function oe(e){Lt(e,"SIGTERM");let t=setTimeout(()=>Lt(e,"SIGKILL"),$r);return t.unref?.(),t}function D(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>D(t)).join("");if(!u(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let r=D(e[t]);if(r)return r}return""}function Fr(e){if(!u(e))return"";let t=u(e.payload)?e.payload:{};if(a(e.type)==="event_msg"){if(a(t.type)==="agent_message")return a(t.message);if(a(t.type)==="task_complete")return a(t.last_agent_message)}if(a(e.type)==="response_item"&&a(t.type)==="message"&&a(t.role)==="assistant")return D(t.content)||D(t.message);if(a(e.type)==="result")return D(e.result);let r=D(e.delta)||D(e.text)||D(e.content);if(r)return r;let n=u(e.item)?e.item:{};return["message","agent_message"].includes(a(n.type))||a(n.role)==="assistant"?D(n.content)||D(n.text)||D(n.message):""}function Br(e,t={}){return ne(e,{source:"codex_cli_image_generation",...t})}function qr(e,t){At(e.artifacts,t)}function jr(e){return V(se(e))}function de(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);if(r==="event_msg"&&n==="task_complete")return!0;let s=a(t.phase||t.status||t.stage).toLowerCase();if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return mt.has(s);let i=u(e.item)?e.item:{};return r==="item.completed"&&a(i.type)==="agent_message"?!0:r==="result"&&e.is_error!==!0?a(e.result).length>0:!1}function Ar(e){let t=a(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=le(a(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function Nr(e,t,r){let n=u(t.error)?t.error:{},s=a(n.message)||D(t.error)||a(t.result)||a(t.message)||r;return Object.assign(new Error(s),{code:e})}function Us(e,t){if(!u(e))return null;let r=a(e.type).toLowerCase();if(t==="codex")return r==="turn.completed"?{status:"completed",result:{stopReason:"end_turn"}}:r==="turn.failed"?{status:"failed",error:Nr("RUNTIME_CODEX_TURN_FAILED",e,"Codex turn failed")}:null;if(t==="claude"&&r==="result"){let n=a(e.subtype).toLowerCase();return e.is_error===!0||n.startsWith("error")||["failed","failure"].includes(n)?{status:"failed",error:Nr("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...a(e.result)?{output:a(e.result)}:{}}}}return null}function Mr(e){return u(e)?a(e.phase||e.status||e.stage).toLowerCase():""}function Ps(e){if(!u(e)||de(e))return!1;let t=u(e.payload)?e.payload:{},r=a(e.type),n=a(t.type),s=Mr(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&a(t.role)==="assistant")return!!(s&&!mt.has(s));let i=u(e.item)?e.item:{},o=Mr(i);return a(i.role)==="assistant"||a(i.type)==="message"?!!(o&&!mt.has(o)):!1}function ks(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:le(e)==="codex"}function Ls(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:le(e)==="codex"}function Kr(e){return Math.max(20,_(e.codexTranscriptPollMs||e.transcriptPollMs,Cs))}function Ds(e){return Math.max(0,_(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,bs))}function Dt(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 fe(e){let t=u(e?.metadata)?e.metadata:{};return u(t._runtimeBridge)?t._runtimeBridge:{}}function ae(e){return a(fe(e).promptKind).toLowerCase()}function vs(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=Dt(r);if(n!=null)return n}return ae(t)==="chat"}function Hs(e,t){let r=fe(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=Dt(s);if(i!=null)return i}let n=ae(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=Dt(s);if(i!=null)return i}return ae(e)==="chat"}function $s(e){let t=fe(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=Dt(r);if(n!=null)return n}return null}function Fs(e,t){let r=$s(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function Bs(e,t){return!e.finalTextOnly||t}function Gr(e,t,r,n,s=n){return!n||e.emittedTexts.has(s)?!1:(e.emittedTexts.add(s),r({sessionId:t,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:n}}}),!0)}function zr(e,t,r,n){return!n||e.emittedThoughtTexts.has(n)?!1:(e.emittedThoughtTexts.add(n),r({sessionId:t,update:{sessionUpdate:"agent_thought_chunk",content:{type:"text",text:n}}}),!0)}function qs(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function js(e,t){let r=u(e.env)?e.env:{},n=a(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||$(Hr(),"orcha-runtime-artifacts"),s=a(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||rt(),i=$(n,s),o=$(i,rt());return gs(o,{recursive:!0}),{root:o,realRoot:ht(o),sessionRoot:i,realSessionRoot:ht(i)}}function Ks(e){let t=a(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:ht(t),sessionRoot:"",realSessionRoot:""}}function Vr(e){return a(u(e)?e.root:e)}function Ur(e){let t=Vr(e),r=a(u(e)?e.sessionRoot:Ss(t)),n=a(u(e)?e.realSessionRoot:"");if(r)try{if(n&&ht(r)!==n)return;Ts(r)}catch{}}function Gs(e,t={}){let r=Vr(e),n=a(u(e)?e.realRoot:"");if(r){try{if(n&&ht(r)!==n){h("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{Ur(e);return}try{_s(r,{recursive:!0,force:!0})}catch(s){h("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:r,error:String(s?.message||s)});return}Ur(e)}}function zs(e,t,r=null){return{trustedFileRoots:[t,a(r?.artifactDirectory),a(r?.homeDirectory),...b(e.trustedArtifactRoots),...b(e.trustedFileRoots),...b(e.artifactRoots),...b(e.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(r?.pathMappings)?r.pathMappings:[]}}function Wr(e){let t=a(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let r=u(e.env)?e.env:{},n=a(e.codexHome||r.CODEX_HOME||process.env.CODEX_HOME)||$(ws(),".codex");return $(n,"sessions")}function Vs(e,t){let r=new Date(t),n=String(r.getFullYear()),s=String(r.getMonth()+1).padStart(2,"0"),i=String(r.getDate()).padStart(2,"0");return $(e,n,s,i)}function Jr(e,t,r){let n=new Set;for(let s of[t-Pt,t,t+Pt,r-Pt,r,r+Pt])n.add(Vs(e,s));return[...n].filter(s=>Lr(s))}function Ws(e,t,r){let n=Wr(e),s=t-Os,i=r+Is,o=[];for(let c of Jr(n,t,r)){let l=[];try{l=Dr(c)}catch{continue}for(let d of l){if(!d.endsWith(".jsonl"))continue;let f=$(c,d);try{let p=ys(f);if(!p.isFile()||p.mtimeMs<s||p.mtimeMs>i)continue;o.push({path:f,mtimeMs:p.mtimeMs})}catch{}}}return o.sort((c,l)=>l.mtimeMs-c.mtimeMs).slice(0,xs)}function Js(e,t,r=t){let n=Wr(e),s=new Set;for(let i of Jr(n,t,r)){let o=[];try{o=Dr(i)}catch{continue}for(let c of o)c.endsWith(".jsonl")&&s.add($(i,c))}return s}function ce(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)ce(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&&ce(e[n],t,r+1)}}function Xr(e){return a(e).replace(/\s+/g," ")}function Xs(e){let t=Xr(e);if(!t)return[];if(t.length<=200)return[t];let r=160,n=[0,Math.floor((t.length-r)/2),t.length-r],s=new Set,i=[];for(let o of n){let c=t.slice(Math.max(0,o),Math.max(0,o)+r).trim();c.length>=40&&!s.has(c)&&(s.add(c),i.push(c))}return i}function Ys(e,t){let r=Xs(t);if(!r.length)return!1;let n=[];for(let i of e)ce(i,n);let s=Xr(n.join(" "));return r.every(i=>s.includes(i))}function Zs(e){return e.find(t=>u(t)&&a(t.type)==="session_meta"&&u(t.payload))||null}function Qs(e){let t=u(e?.payload)?e.payload:{},r=a(e?.timestamp||t.timestamp),n=Date.parse(r);return Number.isFinite(n)?n:Number.NaN}function ti(e){let t=a(e.originator),r=a(e.source);if(t!=="codex_exec"&&r!=="exec"||a(e.parent_thread_id))return!1;let n=a(e.thread_source);if(n&&n!=="user")return!1;let s=a(e.session_id),i=a(e.id);return!(s&&i&&s!==i)}function ei(e,t,r){if(!Ys(e,t.promptText))return!1;let n=Zs(e);if(!n)return!1;let s=n.payload;if(!ti(s))return!1;let i=Qs(n);if(!Number.isFinite(i)||i<t.startedAtMs-5e3||i>r+5e3)return!1;let o=a(t.target.cwd),c=a(s.cwd);return!(o&&c&&br(o)!==br(c))}function Pr(e){try{return ni(vr(e,"utf8"))}catch{return null}}function ri(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=Pr(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of Ws(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=Pr(s.path);!i||!ei(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,h("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,h("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function ni(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 si(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);return r==="event_msg"&&n==="image_generation_end"||r==="response_item"&&n==="image_generation_call"}function ii(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{};return a(e.type)==="response_item"&&Ns.has(a(t.type))}function oi(e){if(!u(e))return!1;let t=u(e.payload)?e.payload:{};return Ms.has(a(t.type))}function ai(e,t,r,n){let s=Fr(e),i=de(e),o=0,c=0,l=0;if(s&&!i&&t.emitThoughtChunks&&zr(t,r,n,s)&&(l=1),s&&i){let d=t.emittedTexts.size?`
|
|
9
9
|
|
|
10
|
-
${s}`:s;
|
|
11
|
-
`,at,
|
|
12
|
-
`}}})}}}async sessionCancel(t){let r=a(t.sessionId),n=this.active.get(r);return n?(h("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),
|
|
13
|
-
`)}function Kr(e,t,r=""){if(!Gr(e))return e==null?null:{required:!0,status:"failed",outcome:a(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=we(e),s=e.verificationPlan.required===!0;if(a(r)&&a(r)!==n)return{required:s,status:"failed",outcome:e.outcome,goalContractHash:n,checks:[],errorCode:"goal_contract_hash_mismatch"};if(!s)return{required:!1,status:"not_required",outcome:e.outcome,goalContractHash:n,checks:[]};let i=di(t),o=e.verificationPlan.checks.map(l=>Ti(l,i));return{required:!0,status:o.some(l=>l.status==="failed")?"failed":o.some(l=>l.status==="missing")?"missing":"passed",outcome:e.outcome,goalContractHash:n,checks:o}}function Gr(e){if(!u(e)||e.schemaVersion!==ai||!a(e.outcome))return!1;let t=e.verificationPlan;if(!u(t)||typeof t.required!="boolean"||!Array.isArray(t.checks)||t.required&&t.checks.length===0)return!1;let r=new Set;for(let n of t.checks)if(!u(n)||!a(n.id)||r.has(a(n.id))||(r.add(a(n.id)),!Array.isArray(n.toolNames)||n.toolNames.length===0||n.toolNames.some(s=>!a(s)))||!Number.isSafeInteger(n.requiredMatches)||n.requiredMatches<1||n.arguments!==void 0&&!u(n.arguments))return!1;return!0}function di(e){let t=new Map,r=[];for(let n of Array.isArray(e)?e:[]){let s=u(n?.update)?n.update:{},i=a(s.sessionUpdate);if(i==="runtime_event"){fi(s.event,t,r);continue}if(i==="tool_call"){let o=vt(s)||`tool-${r.length+1}`,c=Dt(t,r,o),l=Se(s,s.name||s.toolName||s.kind);c.toolName=l.toolName,c.arguments=l.arguments,c.status=gt(s.status),c.evidence=Ft(s);continue}if(i==="tool_call_update"){let o=vt(s);if(!o)continue;let c=Dt(t,r,o),l=Se(s,s.name||s.toolName||s.kind);c.toolName||=l.toolName,Object.keys(c.arguments).length===0&&(c.arguments=l.arguments),c.status=gt(s.status),c.evidence.push(...Ft(s))}}return r}function fi(e,t,r){let n=u(e)&&u(e.payload)?e.payload:u(e)?e:{},s=a(n.type);if(["function_call","custom_tool_call","local_shell_call","mcp_tool_call"].includes(s)){let c=vt(n)||`runtime-${r.length+1}`,l=Dt(t,r,c),d=Se(n,n.name||n.tool||s,s);l.toolName=d.toolName,l.arguments=d.arguments,l.status=gt(n.status),l.evidence.push(...Ft(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=vt(n);if(!i)return;let o=Dt(t,r,i);o.status=gi(n,o.toolName),o.evidence.push(...Ft(n))}function Dt(e,t,r){let n=e.get(r);return n||(n={toolCallId:r,toolName:"",arguments:{},status:"unknown",evidence:[]},e.set(r,n),t.push(n)),n}function pi(e){let t=a(e).toLowerCase();return li.get(t)||t}function Se(e,t,r=""){let n=mi(e),s=a(r)==="mcp_tool_call"||a(e?.kind).toLowerCase()==="mcp",i=u(e?._meta)?e._meta:{},o=a(e?.server||e?.serverName||e?.server_name||e?.mcpServer||i.server||i.serverName).toLowerCase();if(s&&o==="orcha"){let c=a(e?.tool||e?.toolName||e?.name||t);return{toolName:"plugin_operation",arguments:{...n,...c?{operationCode:c}:{}}}}return{toolName:pi(t),arguments:n}}function vt(e){return u(e)?a(e.call_id||e.callId||e.toolCallId||e.id):""}function mi(e){if(!u(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=hi(e[r]);if(n)return n}let t={};for(let r of["cmd","command","cwd","operationCode","path","query","url"])e[r]!==void 0&&(t[r]=e[r]);return t}function hi(e){if(u(e))return structuredClone(e);if(typeof e!="string")return null;try{let t=JSON.parse(e);return u(t)?t:null}catch{return null}}function gi(e,t){if(!u(e))return"unknown";let r=Ht(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function Ht(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return _i(e,t,r);if(Array.isArray(e))return e.flatMap(o=>Ht(o,t+1,r));if(!u(e))return[];let n=[];typeof e.isError=="boolean"&&n.push(e.isError?"failed":"success"),typeof e.ok=="boolean"&&n.push(e.ok?"success":"failed"),typeof e.success=="boolean"&&n.push(e.success?"success":"failed");let s=gt(e.status);s!=="unknown"&&n.push(s);let i=e.exitCode??e.exit_code;typeof i=="number"&&Number.isFinite(i)&&n.push(i===0?"success":"failed");for(let o of["output","result","structuredContent","content"])e[o]!==void 0&&n.push(...Ht(e[o],t+1,r));return n}function _i(e,t,r){let n=e.trim();if(!n)return[];try{return Ht(JSON.parse(n),t+1,r)}catch{}if(r.parseCliExitCode!==!0)return[];let s=[];for(let i of n.matchAll(/(?:process\s+exited\s+with\s+code|exit\s+code\s*:?)\s*(-?\d+)/gi))s.push(Number(i[1])===0?"success":"failed");return s}function gt(e){let t=a(e).toLowerCase();return ci.has(t)?"success":ui.has(t)?"failed":"unknown"}function Ft(e){if(!u(e))return[];let t=u(e.output)?e.output:{},r=[e.verificationEvidence,u(e.verification)?e.verification.evidence:null,t.verificationEvidence,u(t.verification)?t.verification.evidence:null],n=[];for(let s of r)for(let i of Array.isArray(s)?s:s?[s]:[])!u(i)||!a(i.id)||n.push({id:a(i.id),status:gt(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...a(i.message)?{message:a(i.message)}:{}});return n}function Ti(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&Ee(e.arguments||{},o.arguments)),n=a(e.evidenceId),s=r.filter(o=>o.status==="success"&&(!n||o.evidence.some(c=>c.id===n&&c.status==="success")));if(s.length>=e.requiredMatches)return Re(e,"passed",s,`Runtime tool evidence passed ${s.length} times.`);let i=r.filter(o=>o.status==="failed"||n&&o.evidence.some(c=>c.id===n&&c.status==="failed"));return s.length===0&&i.length?Re(e,"failed",i,"Runtime tool evidence failed."):Re(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function Re(e,t,r,n){let s=r.map(i=>i.toolCallId).filter(Boolean);return{id:e.id,status:t,message:n,...a(e.description)?{description:a(e.description)}:{},toolNames:e.toolNames,requiredMatches:e.requiredMatches,observedMatches:s.length,toolCallIds:s,...u(e.arguments)?{arguments:e.arguments}:{},...a(e.evidenceId)?{evidenceId:a(e.evidenceId)}:{}}}function Ee(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>Ee(r,t[n])):u(e)?u(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&Ee(n,t[r])):!1:Object.is(e,t)}function B(e){if(e===null||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="string")return qr(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new Error("invalid_jcs_number");return JSON.stringify(Object.is(e,-0)?0:e)}if(Array.isArray(e))return`[${Array.from({length:e.length},(t,r)=>{if(!Object.hasOwn(e,r))throw new Error("invalid_jcs_json_value");return B(e[r])}).join(",")}]`;if(u(e))return`{${Object.keys(e).sort().map(t=>`${qr(t)}:${B(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function qr(e){return yi(e),JSON.stringify(e)}function yi(e){for(let t=0;t<e.length;t+=1){let r=e.charCodeAt(t);if(r>=55296&&r<=56319){let n=e.charCodeAt(t+1);if(!(n>=56320&&n<=57343))throw new Error("invalid_jcs_unicode");t+=1}else if(r>=56320&&r<=57343)throw new Error("invalid_jcs_unicode")}}import{spawn as Ri}from"node:child_process";import{createHash as Si,randomUUID as Ei}from"node:crypto";import{constants as wi}from"node:fs";import{access as Oi,mkdir as Oe,readdir as Ii,realpath as _t,rm as xi,stat as Ai}from"node:fs/promises";import Ci from"node:http";import{tmpdir as bi}from"node:os";import{isAbsolute as Tt,join as nt,relative as Vr,resolve as xe}from"node:path";var Ae=1,Ni="orcha.process-isolation/v1",Ce="orcha.egress-proxy/v1",Mi="--disable-wasm-trap-handler",$t={read_only:0,workspace_write:1,workspace_network:2},Ie={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},Ui=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function W(e){if(!u(e))throw E("RUNTIME_SANDBOX_POLICY_REQUIRED","sandboxPolicy is required");let t=structuredClone(e),r=a(t.accessMode),n=a(t.accessModeCeiling);if(!(r in Ie)||!(n in Ie))throw E("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if($t[r]>$t[n])throw E("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=Ie[r];if(t.filesystemMode!==s||t.networkMode!==i)throw E("RUNTIME_SANDBOX_POLICY_INVALID","runtime access profile does not match its mode");if(Number(t.policySchemaVersion)!==Ae||!Number.isInteger(Number(t.policyRevision))||Number(t.policyRevision)<1)throw E("RUNTIME_SANDBOX_POLICY_INVALID","unsupported sandbox policy schema or revision");for(let[c,l]of Object.entries({outsideWorkspaceAccess:"denied",hostAccess:"denied",hostEnvironmentAccess:"denied",dockerSocketAccess:"denied",environmentMode:"allowlist"}))if(t[c]!==l)throw E("RUNTIME_SANDBOX_POLICY_INVALID",`${c} cannot be relaxed`);let o=u(t.processIsolation)?t.processIsolation:{};if(o.mode!=="required"||o.backend==="direct")throw E("RUNTIME_SANDBOX_POLICY_INVALID","strong process isolation is required");if(Array.isArray(t.alwaysApprovedApprovalKeys)&&t.alwaysApprovedApprovalKeys.length)throw E("RUNTIME_SANDBOX_POLICY_INVALID","persistent runtime approvals are forbidden");return t}function zr(e,t){let r=W(e),n=W(t);return $t[n.accessMode]<$t[r.accessMode]}async function Wr(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[Ae],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await Xr(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await vi(t,C(e.sandboxBrokerArguments),e.sandboxProbeTimeoutMs);if(r.enforced!==!0||a(r.protocolVersion)!=="orcha.runtime-sandbox-broker/v1"||!["bubblewrap","broker"].includes(a(r.backend)))throw E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker did not report enforced isolation");let n=u(r.probes)?r.probes:{};for(let s of["emptyRoot","outsideWorkspaceDenied","hostFilesystemDenied","sensitiveFilesDenied","environmentAllowlist","dockerSocketDenied","networkNamespace","workspaceReadOnly","workspaceWrite","resourceLimits"])if(n[s]!==!0)throw E("RUNTIME_SANDBOX_UNAVAILABLE",`sandbox broker probe failed: ${s}`);return e.egressProxyRequired&&await $i(e),{dispatchable:!0,enforced:!0,backend:a(r.backend),daemonStatus:"ok",daemonProtocolVersion:a(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[Ae],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function be(e,t,r){let n=a(t.workspace||t.cwd),s=a(r),i=n||(t.allowRequestWorkspace===!0?s:"");if(!i||!Tt(i))throw E("RUNTIME_WORKSPACE_NOT_CONFIGURED","runtime target must configure an absolute trusted workspace");let o=await _t(i);if(!(await Ai(o)).isDirectory())throw E("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>_t(d))):[o]).some(d=>Me(d,o)))throw E("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function Jr({config:e,target:t,command:r,args:n,cwd:s,environment:i,runId:o,agentId:c,sessionId:l,sandboxPolicy:d}){if(!e.sandboxRequired)return{command:r,args:[...n],cwd:s,environment:{...process.env,...i},tempDirectory:"",isolation:{enforced:!1,backend:"development_direct"},cleanup:async()=>{}};let f=W(d),p=await be(e,t,s),m=await _t(s);if(!Me(p,m))throw E("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let g=await Xr(e.sandboxBrokerCommand,process.env.PATH||"");if(!g)throw E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let y=`runtime-${Si("sha256").update(String(o)).digest("hex").slice(0,32)}`,I=xe(e.sandboxTempRoot||nt(bi(),"orcha-runtime-sandboxes"));await Oe(I,{recursive:!0,mode:448});let b=nt(I,`${y}-${Ei()}`),T=nt(b,"home"),R=nt(b,"artifacts");await Oe(T,{recursive:!0,mode:448}),await Oe(R,{recursive:!0,mode:448});let S=f.networkMode==="restricted"?await Hi(e,{runId:String(o),instanceId:y,policyRevision:Number(f.policyRevision),ttlMs:Math.min(_(f.maxRuntimeSeconds,900)*1e3,e.egressGrantMaxTtlMs),maxTransferBytes:_(f.maxNetworkBytes,64*1024*1024)}):null,A={PATH:a(i.PATH||process.env.PATH),LANG:a(i.LANG||process.env.LANG||"C.UTF-8"),HOME:"/tmp/home",TMPDIR:"/tmp",USER:"orcha",LOGNAME:"orcha",SHELL:"/bin/sh",ORCHA_AGENT_ID:String(c),ORCHA_SESSION_ID:String(l),ORCHA_RUN_ID:String(o),ORCHA_RUNTIME_ARTIFACT_DIR:"/tmp/artifacts",...ki(t,i)};A.HOME="/tmp/home",A.TMPDIR="/tmp",A.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",A.NODE_OPTIONS=Mi;let U={schemaVersion:Ni,runId:String(o),instanceId:y,workspace:p,cwd:m,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await Li(p),temporaryDirectory:b,egressProxy:S,environment:A,resourceLimits:Di(f),readOnlyToolchainRoots:await Pi(e,t)},K=!1,L=async()=>{if(!K){K=!0;try{S&&await Fi(e,S,{runId:String(o),instanceId:y})}finally{await xi(b,{recursive:!0,force:!0})}}};return{command:g,args:[...C(e.sandboxBrokerArguments),"--",r,...n],cwd:m,environment:{PATH:process.env.PATH||"",LANG:process.env.LANG||"C.UTF-8",ORCHA_PROCESS_ISOLATION_REQUEST:JSON.stringify(U)},tempDirectory:b,homeDirectory:T,artifactDirectory:R,pathMappings:[{runtimeRoot:"/tmp/artifacts",hostRoot:R},{runtimeRoot:"/tmp/home",hostRoot:T}],isolation:{enforced:!0,backend:"broker",instanceId:y,policyRevision:f.policyRevision},cleanup:L}}async function Pi(e,t){let r=C(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(C(e.trustedToolchainRoots).map(i=>_t(i)));if(!n.length)throw E("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","target toolchain roots require ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS");let s=[];for(let i of r){if(!Tt(i))throw E("RUNTIME_TOOLCHAIN_ROOT_INVALID","toolchain roots must be absolute");let o=await _t(i);if(!n.some(c=>Me(c,o)))throw E("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function ki(e,t){let r=u(e.env)?e.env:{},n={};for(let[s,i]of Object.entries(r))/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&i!=null&&(n[s]=String(i));for(let s of["ORCHA_RUNTIME_PROMPT","ORCHA_RUNTIME_ARTIFACT_DIR"])t[s]!=null&&(n[s]=String(t[s]));return n}async function Li(e){let t=[],r=0,n=async s=>{let i;try{i=await Ii(s,{withFileTypes:!0})}catch(o){if(s===e)throw o;return}for(let o of i){if(r+=1,r>1e4)throw E("RUNTIME_WORKSPACE_SCAN_LIMIT_EXCEEDED","workspace contains more than 10000 entries");let c=nt(s,o.name),l=Vr(e,c),d=o.name.toLowerCase();(Ui.has(d)||d.startsWith(".env."))&&t.push(l),o.isDirectory()&&!o.isSymbolicLink()&&await n(c)}};return await n(e),t.sort()}function Di(e){return{maxCpuSeconds:Math.max(1,_(e.maxRuntimeSeconds,900)),maxMemoryBytes:_(e.maxMemoryBytes,2*1024*1024*1024),maxProcesses:_(e.maxProcesses,128),maxOpenFiles:_(e.maxOpenFiles,1024),maxFileBytes:_(e.maxFileBytes,64*1024*1024)}}async function vi(e,t,r){return await new Promise((n,s)=>{let i=Ri(e,[...t,"--probe"],{env:{PATH:process.env.PATH||"",LANG:"C.UTF-8"},stdio:["ignore","pipe","pipe"],windowsHide:!0}),o=[],c=[];i.stdout.on("data",d=>o.push(Buffer.from(d))),i.stderr.on("data",d=>c.push(Buffer.from(d)));let l=setTimeout(()=>i.kill("SIGKILL"),Math.max(1e3,r));i.once("error",s),i.once("close",d=>{if(clearTimeout(l),d!==0){s(E("RUNTIME_SANDBOX_UNAVAILABLE",Buffer.concat(c).toString("utf8").trim()||`sandbox probe exited with ${d}`));return}try{n(JSON.parse(Buffer.concat(o).toString("utf8")))}catch{s(E("RUNTIME_SANDBOX_UNAVAILABLE","sandbox probe returned invalid JSON"))}})})}async function Xr(e,t){let r=a(e);if(!r)return"";let n=Tt(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>nt(s,r));for(let s of n)try{return await Oi(s,wi.X_OK),s}catch{}return""}async function Hi(e,t){if(!e.egressProxyRequired)throw E("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await Ne(e,"POST","/v1/grants",{protocolVersion:Ce,...t}),n={socketPath:e.egressProxySocket,grantId:a(r.grantId),credential:a(r.credential)};if(!n.grantId||!n.credential)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy returned an invalid grant");return n}async function Fi(e,t,r){await Ne(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:Ce,...r}).catch(()=>{})}async function $i(e){let t=await Ne(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==Ce)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function Ne(e,t,r,n){if(!Tt(e.egressProxySocket)||!e.egressProxyToken)throw E("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy socket and token are required");return await new Promise((s,i)=>{let o=Ci.request({socketPath:e.egressProxySocket,path:r,method:t,headers:{Authorization:`Bearer ${e.egressProxyToken}`,Accept:"application/json",...n?{"Content-Type":"application/json"}:{}}},c=>{let l=[],d=0;c.on("data",f=>{d+=f.length,d>1048576?o.destroy(new Error("egress response is too large")):l.push(Buffer.from(f))}),c.once("end",()=>{try{let f=JSON.parse(Buffer.concat(l).toString("utf8")||"{}");(c.statusCode||500)>=400?i(E("RUNTIME_EGRESS_UNAVAILABLE",a(f.error)||"Egress Proxy rejected the request")):s(f)}catch(f){i(f)}})});o.once("error",i),o.setTimeout(3e3,()=>o.destroy(new Error("Egress Proxy request timed out"))),n?o.end(JSON.stringify(n)):o.end()})}function Me(e,t){let r=Vr(xe(e),xe(t));return r===""||!r.startsWith("..")&&!Tt(r)}function E(e,t){return Object.assign(new Error(t),{code:e})}var Ue=24e3,Pe=8,ke=50,Le=6e3,qi=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),ji=10*60*1e3,Ki=60*1e3,Gi=8,Vi=30*60*1e3,zi=60*1e3,Wi=1,tn=2400,Ji=new Set(["max_tokens","max_output_tokens","length"]),Xi=new Set(["agent_message_chunk","tool_call","tool_call_update"]),Yi=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),Zi=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function Qi(e){if(!u(e))return{};let t={};for(let r of["name","code","serverName","serverCode","type","transport","url","command","protocolVersion"]){let n=a(e[r]);n&&(t[r]=n)}return t}function to(e){return(Array.isArray(e)?e:[]).map(Qi).sort((t,r)=>{let n=B(t),s=B(r);return n<s?-1:n>s?1:0})}function eo(e){return!u(e)||e.verificationPlan?.required!==!0?!1:(Array.isArray(e.verificationPlan.checks)?e.verificationPlan.checks:[]).some(r=>u(r)&&Array.isArray(r.toolNames)&&r.toolNames.some(n=>a(n)==="plugin_operation"))}function ro(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:qt()}}}function k(e){return e==null||e===""?!1:typeof e=="string"?a(e)!=="":Array.isArray(e)?e.length>0:u(e)?Object.keys(e).length>0:!0}function en(e){let t=a(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return qi.has(t)}function G(e,t){let r=_(e,t);return Number.isFinite(r)&&r>0?r:t}function yt(e,t=!1){if(typeof e=="boolean")return e;let r=a(e).toLowerCase();return["true","1","yes","y","on"].includes(r)?!0:["false","0","no","n","off"].includes(r)?!1:t}function j(e){return a(e?.type||"echo")}function rn(e){let t=j(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function He(e){if(u(e)){if(Object.prototype.hasOwnProperty.call(e,"releaseAfterPrompt"))return e.releaseAfterPrompt;if(Object.prototype.hasOwnProperty.call(e,"disposeAfterPrompt"))return e.disposeAfterPrompt}}function no(e){let t=String(e||"");if(Zi.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 Fe(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=Le)return e;let r=e.length-Le;return`${e.slice(0,Le)}... [truncated ${r} characters]`}if(t>=Pe)return Array.isArray(e)?`[array truncated at depth ${Pe}, items=${e.length}]`:u(e)?`[object truncated at depth ${Pe}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,ke).map(n=>Fe(n,t+1));return e.length>ke&&r.push(`[truncated ${e.length-ke} items]`),r}if(u(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=no(n)?"[REDACTED]":Fe(s,t+1);return r}return String(e)}var so=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 io(e){if(!u(e))return e;let t={};for(let r of so)k(e[r])&&(t[r]=e[r]);return t}function oo(e){if(!u(e))return e;let t={...e};return u(t.renderedPayload)&&(t.renderedPayload=io(t.renderedPayload)),t}function ao(e){let t=u(e)?e:{},r={};k(t.metadata)&&(r.metadata=oo(t.metadata));for(let[n,s]of Object.entries(t))Yi.has(n)||n==="metadata"||k(s)&&(r[n]=s);return r}function co(e){let t=u(e)?e:{},r=u(t.metadata)?t.metadata:{},n=u(r.renderedPayload)?r.renderedPayload:{};return u(t.resultContract)?t.resultContract:u(n.resultContract)?n.resultContract:{}}function nn(e){return a(co(e).kind).toLowerCase()==="decision"}function uo(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:j(e)==="cli"}function Yr(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return yt(t,rn(e))}function lo(e,t){let r=u(e?.metadata)?{...e.metadata}:{},n=u(r._runtimeBridge)?{...r._runtimeBridge}:{},s=He(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:uo(t),releaseAfterPrompt:s===void 0?Yr(t):yt(s,Yr(t)),requiresRuntimeResult:nn(e)},r}function fo(e){let t=ao(e);if(!k(t))return"";let r=JSON.stringify(Fe(t),null,2);if(r.length<=Ue)return r;let n=r.length-Ue;return`${r.slice(0,Ue)}
|
|
14
|
-
... [truncated ${n} characters]`}function
|
|
15
|
-
`:"";t+=`${s}${n}`}}return t.trim()}function
|
|
16
|
-
`?1:0)).trim()}function
|
|
17
|
-
`)}function Oo(e,t){let r=u(t)?{...t}:{},n=an(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function Io(e,t){return{...e,_meta:{...u(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:je(t)||"max_tokens"}}}}function xo(e,t){let r=typeof e?.output=="string"?e.output:qe(t),n=new P("runtime_output_truncated","Runtime Result \u8FBE\u5230\u6700\u5927\u8F93\u51FA\u957F\u5EA6\uFF0C\u7D27\u51D1\u91CD\u8BD5\u540E\u4ECD\u672A\u5B8C\u6574\u8FD4\u56DE",r);return n.detail={...n.detail,stopReason:je(e)||"max_tokens",retryAttempted:!0},n}var Kt=class{constructor(t){this.config=t,this.targets=t.targets||{},this.agents=new Map,this.sessions=new Map,this.startingSessions=new Set,this.targetReservations=new Map,this.runtimeSessionIndex=new Map,this.pendingPermissions=new Map,this.operations=new Map,this.startedAt=dt(),this.sandboxCapabilities={dispatchable:t.sandboxRequired!==!0,enforced:!1,backend:t.sandboxRequired?"unavailable":"direct",daemonStatus:t.sandboxRequired?"pending":"not_required",policySchemaVersions:[1],runtimePolicyUpdates:t.sandboxRequired===!0,workspaceSync:!1,egressProxy:!1},this.cleanupTimer=null,this.onCapacityChanged=null,this.startSessionCleanup()}async start(){try{this.sandboxCapabilities=await Wr(this.config)}catch(t){this.sandboxCapabilities={...this.sandboxCapabilities,dispatchable:!1,enforced:!1,backend:"unavailable",daemonStatus:"unavailable",reason:a(t?.code||t?.message||t)||"sandbox_probe_failed"},h("error","runtime-bridge","runtime node sandbox probe failed; node will not accept work",{reason:this.sandboxCapabilities.reason})}return this.sandboxCapabilities}assertDispatchable(){if(this.config.sandboxRequired&&!(this.sandboxCapabilities.dispatchable===!0&&this.sandboxCapabilities.enforced===!0))throw Object.assign(new Error("runtime node strong sandbox is unavailable"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"})}operationIdentity(t,r,n){let s=u(t.goalContract)?we(t.goalContract):a(t.goalContractHash),i=Bi("sha256").update(B({prompt:Array.isArray(t.prompt)?t.prompt:[],mcpServers:to(t.mcpServers)})).digest("hex");return{agentId:r,runId:a(t.runId),sessionId:n,targetCode:a(t.targetCode||t.framework),workspace:a(t.workspace),goalContractHash:s,requestHash:i}}assertOperationIdentity(t,r,n,s){let i=this.operationIdentity(r,n,s),o=Object.keys(t.identity).find(c=>t.identity[c]!==i[c]);if(o)throw Object.assign(new Error(`runtime operation correlation conflict: ${t.correlationId}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT",field:o})}createOperation(t,r,n,s){let i={correlationId:t,agentId:n,sessionId:s,identity:this.operationIdentity(r,n,s),sandboxPolicy:u(r.sandboxPolicy)?structuredClone(r.sandboxPolicy):null,status:"running",updates:[],listeners:new Set,waiters:[],response:null,error:null,createdAtMs:Date.now(),completedAtMs:null};return this.operations.set(t,i),i}async attachOperation(t,r={}){let n=()=>{if(r.onUpdate)for(let s of t.updates)r.onUpdate(s)};if(t.status==="completed")return n(),t.response;if(t.status==="failed")throw n(),t.error;r.onUpdate&&t.listeners.add(r.onUpdate);try{return n(),await new Promise((s,i)=>t.waiters.push({resolve:s,reject:i}))}finally{r.onUpdate&&t.listeners.delete(r.onUpdate)}}completeOperation(t,r){if(t.status==="running"){t.status="completed",t.response=r,t.completedAtMs=Date.now();for(let n of t.waiters.splice(0))n.resolve(r);t.listeners.clear()}}promptResponse(t,r,n,s,i,o=s){let c=u(t.metadata)?t.metadata:{},l=u(c._runtimeBridge)?c._runtimeBridge:{},d=cn(i,o,l),f=Kr(t.goalContract,s,t.goalContractHash);return{sessionId:n,runtimeSessionId:r.runtimeSessionId,result:d,updates:s,...f?{verification:f}:{}}}failOperation(t,r){if(t.status!=="running")return;let n=r instanceof Error?r:Object.assign(new Error(String(r||"runtime operation failed")),{code:"RUNTIME_NODE_ERROR"});t.status="failed",t.error=n,t.completedAtMs=Date.now();for(let s of t.waiters.splice(0))s.reject(n);t.listeners.clear()}cleanupOperations(t=Date.now()){let r=G(this.config.operationTtlMs,Vi);for(let[n,s]of this.operations)s.status!=="running"&&t-(s.completedAtMs||s.createdAtMs)>r&&this.operations.delete(n)}targetFor(t){let r=a(t)||this.config.defaultTargetCode,n=this.targets[r];if(!r||!u(n)){let s=new Error(`runtime target is not configured: ${r||"<empty>"}`);throw s.code="RUNTIME_TARGET_NOT_FOUND",s}return{code:r,target:n}}targetIdleTtlMs(t){let n=j(t)==="openclaw"?G(this.config.openClawSessionIdleTtlMs,zi):G(this.config.sessionIdleTtlMs,ji);return G(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=j(t)==="openclaw"?G(this.config.openClawMaxSessions,Wi):G(this.config.maxSessionsPerTarget,Gi);return G(t?.maxSessions,n)}targetReservationCount(t){return Number(this.targetReservations.get(t)||0)}notifyCapacityChanged(){try{this.onCapacityChanged?.()}catch(t){h("warn","runtime-bridge","capacity heartbeat callback failed",{error:String(t)})}}targetCapacitySnapshot(t=!0){return Object.entries(this.targets).map(([r,n])=>{let s=[...this.sessions.values()].filter(f=>f.targetCode===r),i=s.filter(f=>f.busy).length,o=s.length-i,c=this.targetReservationCount(r),l=this.targetMaxSessions(n),d=t?Math.max(0,l-i-c):0;return{targetCode:r,targetName:a(n?.name||n?.targetName||r),targetType:a(n?.type||"echo"),status:t?d>0?"available":"busy":"unavailable",maxSessions:l,busySessions:i,idleSessions:o,reservedSessions:c,availableSessions:d}})}targetReleaseAfterPrompt(t,r={}){let n=j(t),s=u(r?._runtimeBridge)?r._runtimeBridge:{},i=He(s);return i!==void 0?yt(i,!1):yt(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=u(r?._runtimeBridge)?r._runtimeBridge:{},s=He(n);return s!==void 0?yt(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=G(this.config.sessionCleanupIntervalMs,Ki);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(r=>{h("warn","runtime-bridge","runtime session cleanup failed",{error:String(r)})})},t),this.cleanupTimer.unref?.())}sessionCountForTarget(t){let r=0;for(let n of this.sessions.values())n.targetCode===t&&(r+=1);return r}idleTargetSessions(t){return[...this.sessions.entries()].filter(([,r])=>r.targetCode===t&&!r.busy).sort((r,n)=>(r[1].lastUsedAtMs||0)-(n[1].lastUsedAtMs||0))}async closeSession(t,r="session_closed"){let n=this.sessions.get(t);if(!n)return!1;try{await n.runtime?.stop?.(r)}catch(s){h("warn","runtime-bridge","runtime session stop failed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,error:String(s)})}return this.sessions.delete(t),this.runtimeSessionIndex.delete(`${n.agentId}:${n.runtimeSessionId}`),this.notifyCapacityChanged(),h("info","runtime-bridge","runtime session closed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,reason:r}),!0}async closeAllSessions(t="bridge_shutdown"){for(let r of[...this.sessions.keys()])await this.closeSession(r,t)}async stop(t="bridge_stop"){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=null,await this.closeAllSessions(t)}async cleanupExpiredSessions(t=Date.now()){for(let[r,n]of[...this.sessions.entries()])n.busy||t-(n.lastUsedAtMs||n.createdAtMs||t)>n.idleTtlMs&&await this.closeSession(r,"idle_timeout")}async reserveTargetSlot(t,r){let n=this.targetMaxSessions(r);for(;this.sessionCountForTarget(t)+this.targetReservationCount(t)>=n;){let s=this.idleTargetSessions(t);if(!s.length){let i=new Error(`runtime target session limit reached: ${t}`);throw i.code="RUNTIME_TARGET_SESSION_LIMIT",i}await this.closeSession(s[0][0],"target_session_limit")}this.targetReservations.set(t,this.targetReservationCount(t)+1),this.notifyCapacityChanged()}releaseTargetSlot(t){let r=Math.max(0,this.targetReservationCount(t)-1);r>0?this.targetReservations.set(t,r):this.targetReservations.delete(t),this.notifyCapacityChanged()}async createAgent(t){let r=a(t.agentId);if(!r)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let{code:n,target:s}=this.targetFor(t.targetCode||t.framework),i=this.agents.get(r);if(i&&i.targetCode!==n)throw Object.assign(new Error(`runtime agent target conflict: ${r}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});let o=this.config.sandboxRequired?await be(this.config,s,t.workspace):a(t.workspace),c={agentId:r,targetCode:n,framework:a(t.framework||n),workspace:o,metadata:u(t.metadata)?t.metadata:{},createdAt:dt(),runtimeKind:j(s)};return this.agents.set(r,c),{agent:c}}runtimeFor(t,r,n={}){let{target:s}=this.targetFor(t.targetCode),i=j(s),o={onPermissionRequest:l=>this.requestPermission(l)},c={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs,initializeTimeoutMs:this.config.initializeTimeoutMs,sandboxRequired:this.config.sandboxRequired,...this.config.sandboxRequired?{prepareLaunch:l=>Jr({config:this.config,target:s,...l,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new et(t,s,o,c):i==="openclaw"?new Nt(t,s,r,o,c):i==="cli"?new Lt(t,s,c):new It(t)}async prompt(t,r={}){if(this.assertDispatchable(),this.config.sandboxRequired){let c=a(t.runId);if(!c)throw Object.assign(new Error("runId is required"),{code:"BAD_REQUEST"});t={...t,runId:c,sandboxPolicy:W(t.sandboxPolicy)}}let n=a(t.agentId),s=a(t.sessionId)||qt(),i=a(t.correlationId);if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});if(this.cleanupOperations(),i){let c=this.operations.get(i);if(c)return this.assertOperationIdentity(c,t,n,s),this.attachOperation(c,r);if(t.attachOnly===!0)throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"})}else if(t.attachOnly===!0)throw Object.assign(new Error("correlationId is required for attachOnly"),{code:"BAD_REQUEST"});let o=i?this.createOperation(i,t,n,s):null;if(o){let c=this.attachOperation(o,r);return(async()=>{try{await this._promptOwned(t,{},o,n,s)}catch(l){let d=o.status==="completed";this.failOperation(o,l),d&&h("warn","runtime-bridge","runtime cleanup failed after operation completion",{correlationId:o.correlationId,error:String(l)})}})(),await c}return await this._promptOwned(t,r,o,n,s)}async _promptOwned(t,r,n,s,i){let o=a(t.runId),c=this.config.sandboxRequired?W(n?.sandboxPolicy||t.sandboxPolicy):null,l=this.agents.get(s),d=this.targetFor(t.targetCode||t.framework||l?.targetCode);if(l&&l.targetCode!==d.code)throw Object.assign(new Error(`runtime agent target conflict: ${s}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});if(j(d.target)==="cli"&&eo(t.goalContract))throw Object.assign(new Error("CLI runtimes do not support per-run dynamic MCP required by plugin_operation"),{code:"unsupported_dynamic_mcp"});let f=l||(await this.createAgent({agentId:s,targetCode:d.code,framework:t.framework,workspace:t.workspace,metadata:t.metadata})).agent;if(!this.config.sandboxRequired){let T=a(t.workspace);T&&T!==f.workspace&&(f.workspace=T)}let p=`${s}:${i}`;await this.cleanupExpiredSessions();let m=this.sessions.get(p),g=null;if(m&&m.targetCode!==d.code)throw Object.assign(new Error(`runtime session target conflict: ${i}`),{code:"RUNTIME_SESSION_TARGET_CONFLICT"});if(m&&this.config.sandboxRequired&&m.runId!==o)throw Object.assign(new Error(`runtime session cannot be shared across runs: ${i}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});if(!m){if(this.startingSessions.has(p))throw Object.assign(new Error(`runtime session is already starting: ${i}`),{code:"RUNTIME_SESSION_BUSY"});this.startingSessions.add(p);let{code:T,target:R}=d;try{await this.reserveTargetSlot(T,R),g=T;let S=this.runtimeFor(f,i,{runId:o,sandboxPolicy:c}),A=await S.sessionNew({cwd:tt(R,f.workspace),mcpServers:Array.isArray(t.mcpServers)?t.mcpServers:[],metadata:u(t.metadata)?t.metadata:{}}),U=Date.now();m={agentId:s,sessionId:i,runtime:S,targetCode:T,runtimeKind:j(R),runId:o,sandboxPolicy:c?structuredClone(c):null,runtimeSessionId:a(u(A)?A.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(R),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(R,t.metadata),createdAtMs:U,lastUsedAtMs:U,busy:!1,createdAt:dt()},this.sessions.set(p,m),this.runtimeSessionIndex.set(`${s}:${m.runtimeSessionId}`,m)}catch(S){throw g&&(this.releaseTargetSlot(g),g=null),S}finally{this.startingSessions.delete(p)}}if(m.busy){let T=new Error(`runtime session is already running: ${i}`);throw T.code="RUNTIME_SESSION_BUSY",T}m.busy=!0,g&&this.releaseTargetSlot(g),this.notifyCapacityChanged(),m.operationCorrelationId=n?.correlationId||null,m.lastUsedAtMs=Date.now();let y=n?.updates||[],I=T=>{let R=ro(T,i,m);if(y.push(R),n)for(let S of n.listeners)try{S?.(R)}catch(A){h("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(A)})}else r.onUpdate?.(R)},b=T=>{if(!(!n||n.status!=="running"||!u(T))){if(T.status==="failed"){let R=T.error;if(R instanceof Error){this.failOperation(n,R);return}let S=u(R)?R:{},A=Object.assign(new Error(a(S.message||T.message)||"runtime terminal failure"),{code:a(S.code||T.code)||"RUNTIME_TERMINAL_FAILED"});this.failOperation(n,A);return}this.completeOperation(n,this.promptResponse(t,m,i,y,u(T.result)?T.result:{stopReason:"end_turn"}))}};try{let T=jr(t.goalContract),R=Array.isArray(t.prompt)?[...t.prompt]:[];T&&R.unshift({type:"text",text:T,metadata:{source:"orcha_goal_contract"}});let S=u(t.metadata)?t.metadata:{},A=u(S._runtimeBridge)?S._runtimeBridge:{},U=await m.runtime.sessionPrompt({sessionId:m.runtimeSessionId,prompt:R,metadata:S},I,b),K=y,L=null;if(rn({type:m.runtimeKind})&&Eo(U,y,A)){L=U;let Y=y.length,at=await m.runtime.sessionPrompt({sessionId:m.runtimeSessionId,prompt:[{type:"text",text:wo()}],metadata:S,_meta:{thinking:"off"}},I,b);U=Oo(L,at),K=y.slice(Y)}let w;try{w=this.promptResponse(t,m,i,y,U,K)}catch(Y){throw L&&un(U)?xo(U,K):Y}return L&&(w.result=Io(w.result,L)),n&&this.completeOperation(n,w),w}finally{m.busy=!1,this.notifyCapacityChanged(),m.operationCorrelationId===n?.correlationId&&(m.operationCorrelationId=null),m.lastUsedAtMs=Date.now(),this.promptReleaseAfterPrompt(m,u(t.metadata)?t.metadata:{})&&await this.closeSession(p,"release_after_prompt")}}async updatePolicy(t){if(this.assertDispatchable(),!this.config.sandboxRequired)throw Object.assign(new Error("runtime sandbox policy updates require an enforced sandbox"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"});let r=a(t.agentId),n=a(t.runId),s=a(t.sessionId),i=a(t.correlationId);if(!r||!n||!s||!i)throw Object.assign(new Error("agentId, runId, sessionId and correlationId are required"),{code:"BAD_REQUEST"});let o=W(t.sandboxPolicy),c=this.operations.get(i);if(c&&(c.agentId!==r||c.sessionId!==s||c.identity.runId!==n))throw Object.assign(new Error(`runtime operation policy identity conflict: ${i}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let l=`${r}:${s}`,d=this.sessions.get(l);if(d&&d.runId!==n)throw Object.assign(new Error(`runtime session policy identity conflict: ${s}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});let f=d?.sandboxPolicy||c?.sandboxPolicy;if(!f)throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"});let p=Number(f.policyRevision),m=Number(o.policyRevision);if(m<p)throw Object.assign(new Error("runtime sandbox policy revision is stale"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});if(m===p){if(B(f)!==B(o))throw Object.assign(new Error("runtime sandbox policy revision payload conflicts"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});return{updated:!1,idempotent:!0,policyRevision:p,accessMode:f.accessMode}}let g=zr(f,o);c&&(c.sandboxPolicy=structuredClone(o)),d&&(d.sandboxPolicy=structuredClone(o));let y=!1;return g&&d?.busy===!0&&(await d.runtime.sessionCancel({sessionId:d.runtimeSessionId}),y=await this.closeSession(l,"sandbox_policy_downgrade")),{updated:!0,policyRevision:m,accessMode:o.accessMode,activeCommandCancelled:y,deferredToNextLaunch:!g&&d?.busy===!0}}async cancel(t){let r=a(t.agentId),n=a(t.sessionId),s=a(t.correlationId);if(s){let c=this.operations.get(s);if(!c||c.status!=="running")return{cancelled:!1,correlationId:s,reason:"operation_not_running"};if(c.agentId!==r||c.sessionId!==n)throw Object.assign(new Error(`runtime operation cancellation identity conflict: ${s}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let l=this.sessions.get(`${r}:${n}`);return!l||l.busy!==!0||l.operationCorrelationId!==s?{cancelled:!1,correlationId:s,reason:"operation_not_running"}:(await l.runtime.sessionCancel({sessionId:l.runtimeSessionId}),await this.closeSession(`${r}:${n}`,"cancelled"),{cancelled:!0,correlationId:s})}let i=`${r}:${n}`,o=this.sessions.get(i);return o?(await o.runtime.sessionCancel({sessionId:o.runtimeSessionId}),await this.closeSession(i,"cancelled"),{cancelled:!0}):{cancelled:!1}}async dispatch(t,r={}){let n=a(t.agentId),s=a(t.taskId),i=a(t.executionId);if(!n||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let o=a(t.sessionId)||`dispatch-${i||s}`,c=a(t.instructions),l=fo(t),d=nn(t),{target:f}=this.targetFor(t.targetCode||t.framework),p=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",c?`instructions: ${c}`:"",l?"orchaContext:":"",l,l?"Use orchaContext as the source of truth for upstream outputs, review reports, artifacts, and workflow metadata.":"","Follow the execution protocol in instructions exactly.","When embedding a generated artifact in final Markdown, use the Orcha artifact placeholder as the link target: orcha-artifact://<fieldKey>/<index>.","Example: use  for the first generated image artifact.","Do not use local filesystem paths, file:// URLs, or data: URLs in final Markdown; Orcha replaces artifact placeholders after ingestion.",d?`For decision results, put the raw report between ${me} and ${he}.`:"",d?`Then put a JSON object containing _decision between ${ge} and ${_e}.`:"",d?"Do not JSON-escape the report. Keep output out of the CONTROL JSON, and put every protocol marker on its own line.":"",d?`Keep the report within ${tn} Unicode characters so the CONTROL block fits before the output limit.`:"","Return only the final answer required by that protocol.","Do not include process notes, logs, or explanations."].filter(Boolean).join(`
|
|
18
|
-
`)}];return this.prompt({...t,agentId:n,sessionId:o,prompt:p,metadata:lo(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=qt(),c=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||qt(),l={permissionId:i,agentId:t.agentId,sessionId:c,runtimeSessionId:r,request:u(n)?n:{},status:"pending",createdAt:dt()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:l}}),await new Promise(d=>{let f=_(n?.timeoutMs,this.config.permissionRequestTimeoutMs),p=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:p,resolve:d,permission:l})})}async respondPermission(t){let r=a(t.permissionId),n=this.pendingPermissions.get(r),s=a(t.outcome||"approved")||"approved";return n?(clearTimeout(n.timer),this.pendingPermissions.delete(r),n.resolve({permissionId:r,outcome:s,response:u(t.response)?t.response:{},userId:a(t.userId),metadata:u(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:r,outcome:s}):{accepted:!1,permissionId:r,outcome:s}}health(){return{status:this.config.sandboxRequired&&!this.sandboxCapabilities.dispatchable?"unavailable":"ok",bridgeVersion:Q,startedAt:this.startedAt,agents:[...this.agents.values()].map(t=>({agentId:t.agentId,targetCode:t.targetCode,framework:t.framework,runtimeKind:t.runtimeKind})),sessions:this.sessions.size,pendingPermissions:this.pendingPermissions.size,targets:Object.keys(this.targets),sandboxCapabilities:this.sandboxCapabilities}}};import Ao from"node:http";import Co from"node:https";import{randomBytes as ln}from"node:crypto";var it=1,J=3,bo=1e4,Gt=class{constructor(t,r={}){this.url=t,this.readyState=0,this.socket=null,this.request=null,this.buffer=Buffer.alloc(0),this.listeners=new Map,this.connectTimeoutMs=No(r.connectTimeoutMs,bo),this.connectTimer=null,this.connect()}addEventListener(t,r){let n=this.listeners.get(t)||new Set;n.add(r),this.listeners.set(t,n)}emit(t,r={}){let n=this.listeners.get(t);if(n)for(let s of n)s(r)}connect(){let t=new URL(this.url),r=t.protocol==="wss:"?Co:Ao,n=ln(16).toString("base64"),s=r.request({protocol:t.protocol==="wss:"?"https:":"http:",hostname:t.hostname,port:t.port||(t.protocol==="wss:"?443:80),path:`${t.pathname}${t.search}`,method:"GET",headers:{Connection:"Upgrade",Upgrade:"websocket","Sec-WebSocket-Key":n,"Sec-WebSocket-Version":"13"}});this.request=s,this.startConnectTimer(s),s.on("upgrade",(i,o,c)=>{if(this.clearConnectTimer(),this.readyState===J){o.destroy();return}this.socket=o,this.readyState=it,o.on("data",l=>this.onData(l)),o.on("close",()=>this.onClose()),o.on("error",l=>{this.readyState!==J&&this.emit("error",{error:l,message:l.message,type:"error"}),this.onClose()}),c?.length&&this.onData(c),this.emit("open")}),s.on("response",i=>{this.clearConnectTimer(),this.emit("error",{message:`websocket upgrade failed: HTTP ${i.statusCode}`,type:"error"}),i.resume(),this.onClose()}),s.on("error",i=>{this.clearConnectTimer(),this.readyState!==J&&this.emit("error",{error:i,message:i.message,type:"error"}),this.onClose()}),s.end()}startConnectTimer(t){this.connectTimeoutMs<=0||(this.connectTimer=setTimeout(()=>{if(this.readyState===it||this.readyState===J)return;let r=`websocket connect timeout after ${this.connectTimeoutMs}ms`;this.emit("error",{message:r,type:"timeout"}),this.onClose(),t.destroy(new Error(r))},this.connectTimeoutMs),this.connectTimer.unref?.())}clearConnectTimer(){this.connectTimer&&(clearTimeout(this.connectTimer),this.connectTimer=null)}send(t){!this.socket||this.readyState!==it||this.socket.write(Ke(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==J){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===it&&this.socket.write(Ke(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==J&&(this.clearConnectTimer(),this.readyState=J,this.request=null,this.emit("close"))}onData(t){for(this.buffer=Buffer.concat([this.buffer,t]);this.buffer.length>=2;){let r=this.buffer[0],n=this.buffer[1],s=r&15,i=(n&128)!==0,o=n&127,c=2;if(o===126){if(this.buffer.length<c+2)return;o=this.buffer.readUInt16BE(c),c+=2}else if(o===127){if(this.buffer.length<c+8)return;let f=this.buffer.readUInt32BE(c),p=this.buffer.readUInt32BE(c+4);o=f*2**32+p,c+=8}let l=c;if(i&&(c+=4),this.buffer.length<c+o)return;let d=this.buffer.subarray(c,c+o);if(i){let f=this.buffer.subarray(l,l+4);d=Buffer.from(d.map((p,m)=>p^f[m%4]))}this.buffer=this.buffer.subarray(c+o),s===1?this.emit("message",{data:d.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(Ke(10,d))}}};function No(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function Ke(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=ln(4),i=Buffer.alloc(n+4+r);i[0]=128|e;let o=2;r<126?i[1]=128|r:r<=65535?(i[1]=254,i.writeUInt16BE(r,o),o+=2):(i[1]=255,i.writeUInt32BE(Math.floor(r/2**32),o),i.writeUInt32BE(r>>>0,o+4),o+=8),s.copy(i,o),o+=4;for(let c=0;c<r;c+=1)i[o+c]=t[c]^s[c%4];return i}function Mo(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 Uo(e,t=!0){return Object.entries(e||{}).map(([r,n])=>({targetCode:r,targetName:a(n?.name||n?.targetName||r),targetType:a(n?.type||"echo"),status:t?"available":"unavailable"}))}var Ge=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),Vt=class{constructor(t,r){this.config=t,this.bridge=r,this.ws=null,this.stopped=!1,this.connected=!1,this.reconnectTimer=null,this.heartbeatTimer=null,this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=()=>this.scheduleCapacityHeartbeat()}sandboxCapabilities(){return this.bridge.sandboxCapabilities||{dispatchable:this.config.sandboxRequired!==!0,enforced:!1,backend:"development_direct",daemonStatus:"development_only",policySchemaVersions:[1],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:!1}}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):Uo(this.config.targets,t)}start(){this.connect()}stop(){this.stopped=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=null,this.ws?.close()}connect(){if(this.stopped)return;let t=Mo(this.config.orchaUrl),r=new Gt(t,{connectTimeoutMs:this.config.connectTimeoutMs});this.ws=r,r.addEventListener("open",()=>{if(this.ws!==r||this.stopped){r.close();return}this.authenticate(r)}),r.addEventListener("message",n=>this.handleMessage(n.data,r)),r.addEventListener("close",()=>this.scheduleReconnect("close",r)),r.addEventListener("error",n=>{h("warn","orcha-client","runtime node websocket error",{error:String(n?.message||n?.type||n)})})}authenticate(t=this.ws){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:Q,protocolVersion:"orcha-runtime-node.v1",defaultTargetCode:this.config.defaultTargetCode,supportedMethods:Ge,sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t)}scheduleReconnect(t,r=this.ws){r&&this.ws!==r||(this.connected=!1,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,r&&this.ws===r&&(this.ws=null),!this.stopped&&(this.reconnectTimer||(h("info","orcha-client","runtime node disconnected; reconnect scheduled",{reason:t,reconnectMs:this.config.reconnectMs}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.config.reconnectMs))))}async handleMessage(t,r=this.ws){if(r&&this.ws!==r)return;let n;try{n=JSON.parse(String(t))}catch(s){h("warn","orcha-client","invalid Orcha websocket frame",{error:String(s)});return}if(u(n)){if(n.type==="runtime_node.authenticated"){if(r&&this.ws!==r)return;this.connected=!0,this.startHeartbeat(r),h("info","orcha-client","runtime node authenticated",{nodeId:this.config.nodeId,connectionId:n.connectionId});return}if(n.type==="orcha.runtime.request"){await this.handleRequest(n);return}n.type==="runtime_node.ping"&&this.send({type:"runtime_node.pong",ts:new Date().toISOString(),supportedMethods:Ge,sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()})}}startHeartbeat(t){this.heartbeatTimer&&clearInterval(this.heartbeatTimer);let r=Math.max(1e3,Number(this.config.heartbeatIntervalMs||15e3)),n=()=>this.sendCapacityHeartbeat(t);n(),this.heartbeatTimer=setInterval(n,r),this.heartbeatTimer.unref?.()}scheduleCapacityHeartbeat(){if(!this.connected||this.capacityHeartbeatTimer)return;let t=Math.max(25,Math.min(1e3,Number(this.config.capacityHeartbeatDebounceMs||100)));this.capacityHeartbeatTimer=setTimeout(()=>{this.capacityHeartbeatTimer=null,this.sendCapacityHeartbeat()},t),this.capacityHeartbeatTimer.unref?.()}sendCapacityHeartbeat(t=this.ws){return this.connected?this.send({type:"runtime_node.heartbeat",ts:new Date().toISOString(),supportedMethods:Ge,sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t):!1}async handleRequest(t){let r=a(t.id),n=a(t.method),s=u(t.params)?t.params:{};try{let i=await this.invoke(n,s,r);this.send({type:"orcha.runtime.response",id:r,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:r,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i),...i.detail===void 0?{}:{detail:i.detail}}})}}async invoke(t,r,n){if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(r);if(t==="agents/dispatch")return this.bridge.dispatch(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/prompt")return this.bridge.prompt(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/policy")return this.bridge.updatePolicy(r);if(t==="sessions/cancel")return this.bridge.cancel(r);if(t==="permissions/respond")return this.bridge.respondPermission(r);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,r){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:r})}send(t,r=this.ws){return!r||r!==this.ws||r.readyState!==it?!1:(r.send(JSON.stringify(t)),!0)}};import{existsSync as dn,readFileSync as Po}from"node:fs";import{dirname as ko,resolve as zt}from"node:path";import{fileURLToPath as Lo}from"node:url";var Do=/^[A-Za-z_][A-Za-z0-9_]*$/;function fn(e=process.env,t=process.cwd()){let r=a(e.ORCHA_RUNTIME_ENV_FILE),n=r?zt(t,r):zt(t,".env");if(!dn(n))return r&&h("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Po(n,"utf8");for(let o of i.split(/\r?\n/)){let c=Fo(o);if(!c)continue;let[l,d]=c;Object.prototype.hasOwnProperty.call(e,l)||(e[l]=d,s.push(l))}return h("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function pn(e=process.env){let t=a(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),r=a(e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1"),n=!1,s=ko(Lo(import.meta.url)),i=zt(s,"sandbox","broker.js"),o=zt(s,"orcha-runtime-sandbox-broker.js"),c=dn(i)?i:o,l=a(e.ORCHA_RUNTIME_SANDBOX_BROKER_COMMAND);return{mode:t,host:r,port:_(e.ORCHA_RUNTIME_BRIDGE_PORT,5588),token:e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",orchaUrl:a(e.ORCHA_RUNTIME_ORCHA_URL),nodeToken:e.ORCHA_RUNTIME_NODE_TOKEN||e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",nodeId:a(e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"local-runtime-node"),nodeName:a(e.ORCHA_RUNTIME_NODE_NAME||e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"Local Runtime Node"),reconnectMs:_(e.ORCHA_RUNTIME_RECONNECT_MS,3e3),connectTimeoutMs:_(e.ORCHA_RUNTIME_CONNECT_TIMEOUT_MS||e.ORCHA_RUNTIME_WS_CONNECT_TIMEOUT_MS,1e4),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:_(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),initializeTimeoutMs:_(e.ORCHA_RUNTIME_INITIALIZE_TIMEOUT_MS,3e4),sessionPromptTimeoutMs:_(e.ORCHA_RUNTIME_SESSION_PROMPT_TIMEOUT_MS,36e5),permissionRequestTimeoutMs:_(e.ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS,3e5),sessionIdleTtlMs:_(e.ORCHA_RUNTIME_SESSION_IDLE_TTL_MS,6e5),sessionCleanupIntervalMs:_(e.ORCHA_RUNTIME_SESSION_CLEANUP_INTERVAL_MS,6e4),maxSessionsPerTarget:_(e.ORCHA_RUNTIME_MAX_SESSIONS_PER_TARGET,8),openClawSessionIdleTtlMs:_(e.ORCHA_RUNTIME_OPENCLAW_SESSION_IDLE_TTL_MS,6e4),openClawMaxSessions:_(e.ORCHA_RUNTIME_OPENCLAW_MAX_SESSIONS,1),heartbeatIntervalMs:_(e.ORCHA_RUNTIME_HEARTBEAT_INTERVAL_MS,15e3),sandboxRequired:n,sandboxBrokerCommand:l||process.execPath,sandboxBrokerArguments:Ve(e.ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS,"ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS",l?[]:[c]),sandboxProbeTimeoutMs:_(e.ORCHA_RUNTIME_SANDBOX_PROBE_TIMEOUT_MS,1e4),sandboxTempRoot:a(e.ORCHA_RUNTIME_SANDBOX_TEMP_ROOT),trustedWorkspaceRoots:Ve(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:Ve(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:Ho(e.ORCHA_RUNTIME_EGRESS_PROXY_REQUIRED,t==="node"),egressProxySocket:a(e.ORCHA_RUNTIME_EGRESS_PROXY_SOCKET),egressProxyToken:a(e.ORCHA_RUNTIME_EGRESS_PROXY_TOKEN),egressGrantMaxTtlMs:_(e.ORCHA_RUNTIME_EGRESS_GRANT_MAX_TTL_MS,9e5),targets:vo(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function vo(e){if(!a(e))return{};try{let t=JSON.parse(e);if(u(t))return t}catch(t){h("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function Ho(e,t){let r=a(e).toLowerCase();if(!r)return t;if(["true","1","yes","on"].includes(r))return!0;if(["false","0","no","off"].includes(r))return!1;throw new Error(`invalid boolean configuration value: ${r}`)}function Ve(e,t,r=[]){let n=a(e);if(!n)return[...r];let s;try{s=JSON.parse(n)}catch{throw new Error(`${t} must be a JSON string array`)}if(!Array.isArray(s)||s.some(i=>typeof i!="string"))throw new Error(`${t} must be a JSON string array`);return s.map(i=>i.trim()).filter(Boolean)}function Fo(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(!Do.test(s))return null;let i=$o(r.slice(n+1).trim());return[s,i]}function $o(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?Bo(r):r}return qo(e).trim()}function Bo(e){return e.replaceAll("\\n",`
|
|
19
|
-
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function
|
|
20
|
-
`),console.log(JSON.stringify({status:"started",pid:i.pid,pidFile:e,logFile:t}))}async function
|
|
21
|
-
`);
|
|
22
|
-
`:""),h("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:c})}catch(d){h("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function
|
|
10
|
+
${s}`:s;Gr(t,r,n,d,s)&&(o=1,c=1)}return s&&i&&(t.finalTextSeen=!0),qr(t,Br(e,t.artifactOptions)),(si(e)||ii(e)||oi(e)||i)&&n({sessionId:r,update:{sessionUpdate:"runtime_event",event:jr(e)}}),{textCount:o,finalTextCount:c,thoughtCount:l}}function ue(e,t,r,n,s=Date.now()){if(!t)return{artifactCount:0,transcriptCount:0,textCount:0,finalTextCount:0,thoughtCount:0};let i=e.artifacts.size,o=0,c=0,l=0,d=0,f=ri(t,r,s);if(f){let p=Math.min(t.processedLines.get(f.path)||0,f.events.length),m=e.artifacts.size;for(let g of f.events.slice(p)){let y=ai(g,e,r,n);c+=y.textCount,l+=y.finalTextCount,d+=y.thoughtCount}t.processedLines.set(f.path,f.events.length),(f.events.length>p||e.artifacts.size>m)&&(o=1)}return{artifactCount:e.artifacts.size-i,transcriptCount:o,textCount:c,finalTextCount:l,thoughtCount:d}}function ci(e,{remove:t=!0}={}){if(!e||!Lr(e))return"";try{return vr(e,"utf8").trim()}catch{return""}finally{t&&kt(e)}}function kt(e){if(e)try{Rs(e)}catch{}}function ui(e,t){return{artifactCount:(e?.artifactCount||0)+(t?.artifactCount||0),transcriptCount:(e?.transcriptCount||0)+(t?.transcriptCount||0),textCount:(e?.textCount||0)+(t?.textCount||0),finalTextCount:(e?.finalTextCount||0)+(t?.finalTextCount||0),thoughtCount:(e?.thoughtCount||0)+(t?.thoughtCount||0)}}function li(e){return new Promise(t=>setTimeout(t,e))}function di(e,t,r,n){return n?(e.finalTextSeen=!0,e.emittedTexts.has(n)||(e.emittedTexts.add(n),r({sessionId:t,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:n}}})),!0):!1}async function fi(e,t,r,n,s,i){let o=ue(e,t,r,n,Date.now()),c=()=>di(e,r,n,ci(s,{remove:!1}));if(c()||e.finalTextSeen)return kt(s),o;let l=Ds(i);if(l<=0||!t&&!s)return kt(s),o;let d=Date.now()+l,f=Math.min(Kr(i),100);for(;!e.finalTextSeen&&Date.now()<d&&(await li(Math.min(f,Math.max(0,d-Date.now()))),o=ui(o,ue(e,t,r,n,Date.now())),!c()););return kt(s),o}var vt=class{constructor(t,r,n={}){this.agent=t,this.target=r,this.options=n,this.active=new Map}async sessionNew(t={}){let r=t.mcpServers||[];if(r.length&&t.metadata?.source==="conversation_delegation"&&Ar(this.target)==="codex"){if(this.options.prepareLaunch)throw Object.assign(new Error("Codex task MCP requires a reachable node-local transport; this sandbox launcher does not provide one"),{code:"unsupported_dynamic_mcp"});this.taskMcp=await Cr(r)}else if(r.length&&t.metadata?.source==="conversation_delegation")throw Object.assign(new Error("This CLI adapter does not support task-scoped MCP"),{code:"unsupported_dynamic_mcp"});return{sessionId:`cli-${this.agent.agentId}-${rt()}`}}async refreshMcpServers(t){if(!this.taskMcp)throw Object.assign(new Error("The original Codex MCP binding is unavailable"),{code:"RUNTIME_OPERATION_NOT_FOUND"});await this.taskMcp.refresh(t)}async sessionPrompt(t,r,n){let s=Date.now(),i=a(this.target.command);if(!i)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let o=a(t.sessionId)||rt(),c=Ot(t.prompt),l=a(this.target.promptMode||"stdin"),d=[...this.taskMcp?.args||[],...this.buildArgs(l,c)],f=tt(this.target,this.agent.workspace),p=typeof this.options.prepareLaunch=="function",g=ks(i,d,this.target)?p?`/tmp/orcha-runtime-last-message-${rt()}.txt`:$(Hr(),`orcha-runtime-last-message-${rt()}.txt`):"";g&&d.push("--output-last-message",g);let y={...u(this.target.env)?this.target.env:{},...this.taskMcp?.environment||{},...l==="env"?{ORCHA_RUNTIME_PROMPT:c}:{},ORCHA_AGENT_ID:this.agent.agentId,ORCHA_SESSION_ID:o},x=p?await this.options.prepareLaunch({command:i,args:d,cwd:f,environment:y}):{command:i,args:d,cwd:f,environment:{...process.env,...y},cleanup:async()=>{}},A=p?Ks(x):js(this.target,o),T=A.root,R=zs(this.target,T,x),w=Ls(i,this.target),O={...this.target,targetCode:this.agent.targetCode,cwd:f,...p?{codexHome:$(x.homeDirectory,".codex")}:{}},P=w?Js(O,s):new Set,v=p&&g?$(x.tempDirectory,g.slice(5)):g,N=_(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,_(this.options.sessionPromptTimeoutMs,Es));p||(x.environment.ORCHA_RUNTIME_ARTIFACT_DIR=T);let E=kr(x.command,x.args,{cwd:x.cwd,env:x.environment,stdio:["pipe","pipe","pipe"],detached:process.platform!=="win32",windowsHide:!0});this.active.set(o,E),h("info","runtime.cli","runtime prompt started",{target:this.agent.targetCode,sessionId:o,pid:E.pid,timeoutMs:N,isolation:x.isolation});let Y="",at=a(this.target.outputMode||"text"),M={artifacts:new Map,emittedTexts:new Set,emittedThoughtTexts:new Set,value:"",artifactOptions:R,finalTextSeen:!1,finalTextOnly:Fs(t,this.target),emitThoughtChunks:Hs(t,this.target),terminalOutcome:null,terminalProtocol:Ar(this.target),emitTerminal:null},Yt=w?qs(O,c,s,P):null;return E.stdout.setEncoding("utf8"),E.stdout.on("data",Z=>this.handleStdout(Z,at,M,o,r)),E.stderr.setEncoding("utf8"),E.stderr.on("data",Z=>{Y+=Z,this.target.emitStderr===!0&&r({sessionId:o,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:Z}}})}),l==="stdin"?E.stdin.end(c):E.stdin.end(),await new Promise((Z,Zt)=>{let ct=!1,nr=!1,wt=null,ut=null,Qt=Yt&&vs(this.target,t)?setInterval(()=>{try{ue(M,Yt,o,r)}catch(I){h("warn","runtime.cli","codex transcript stream poll failed",{target:this.agent.targetCode,sessionId:o,error:String(I?.message||I)})}},Kr(this.target)):null;Qt?.unref?.();let sr=setTimeout(()=>{nr=!0,h("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:o,pid:E.pid,timeoutMs:N}),Lt(E,"SIGTERM"),wt=setTimeout(()=>{h("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:o,pid:E.pid}),Lt(E,"SIGKILL")},$r),wt.unref?.(),lt(Object.assign(new Error(`runtime CLI timed out after ${N}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},N);sr.unref?.();let ir=async()=>{clearTimeout(sr),ut&&clearTimeout(ut),Qt&&clearInterval(Qt),wt&&!nr&&clearTimeout(wt),Gs(A,{target:this.agent.targetCode,sessionId:o}),this.active.delete(o),M.emitTerminal=null,await x.cleanup?.()},Bn=I=>{ct||(ct=!0,ir().then(()=>Z(I),Zt))},lt=I=>{ct||(ct=!0,ir().then(()=>Zt(I),F=>{h("warn","runtime.cli","sandbox launch cleanup failed",{target:this.agent.targetCode,sessionId:o,error:String(F?.message||F)}),Zt(I)}))};M.emitTerminal=I=>{let F={...u(I.result)?I.result:{},_artifacts:[...M.artifacts.values()]};try{n?.({...I,result:F})}catch(z){h("warn","runtime.cli","runtime terminal listener failed",{target:this.agent.targetCode,sessionId:o,error:String(z?.message||z)})}let H=Math.max(0,_(this.target.terminalExitGraceMs,As));ut=setTimeout(()=>{ut=null,!(ct||this.active.get(o)!==E)&&(h("warn","runtime.cli","runtime stayed alive after terminal event; terminating child",{target:this.agent.targetCode,sessionId:o,pid:E.pid,terminalProtocol:M.terminalProtocol,graceMs:H}),oe(E))},H),ut.unref?.()},E.on("error",I=>{h("warn","runtime.cli","runtime child error",{target:this.agent.targetCode,sessionId:o,pid:E.pid,error:String(I?.message||I)}),lt(I)}),E.on("exit",(I,F)=>{(async()=>{at==="json-lines"&&M.value.trim()&&this.handleStdout(`
|
|
11
|
+
`,at,M,o,r);let H=await fi(M,Yt,o,r,v,this.target);(H.artifactCount>0||H.textCount>0||H.thoughtCount>0)&&h("info","runtime.cli","codex transcript updates collected",{target:this.agent.targetCode,sessionId:o,artifactCount:H.artifactCount,textCount:H.textCount,finalTextCount:H.finalTextCount,thoughtCount:H.thoughtCount,transcriptCount:H.transcriptCount});let z=Y.trim();if(z&&h("debug","runtime.cli","runtime stderr",{target:this.agent.targetCode,sessionId:o,stderr:z}),h("info","runtime.cli","runtime prompt finished",{target:this.agent.targetCode,sessionId:o,pid:E.pid,exitCode:I,signal:F,artifactCount:M.artifacts.size,finalTextSeen:M.finalTextSeen}),M.terminalOutcome?.status==="failed"){lt(M.terminalOutcome.error);return}if(I!==0&&M.terminalOutcome?.status!=="completed"){let qn=Object.assign(new Error(`runtime CLI exited with code ${I??"unknown"}${F?` (${F})`:""}`),{code:"RUNTIME_CLI_EXIT_NONZERO",exitCode:I,signal:F});lt(qn);return}Bn({stopReason:"end_turn",exitCode:I,signal:F,_artifacts:[...M.artifacts.values()],...z?{stderr:z}:{}})})().catch(lt)})})}buildArgs(t,r){let n=b(this.target.args);return t==="args"?[...n,r]:n}handleStdout(t,r,n,s,i){if(r!=="json-lines"){i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:t}}});return}n.value+=t;let o=n.value.split(/\r?\n/);n.value=o.pop()||"";for(let c of o){let l=c.trim();if(l)try{let d=JSON.parse(l);qr(n,Br(d,n.artifactOptions)),i({sessionId:s,update:{sessionUpdate:"runtime_event",event:jr(d)}});let f=Fr(d),p=de(d);f&&n.emitThoughtChunks&&!p&&Ps(d)?zr(n,s,i,f):f&&Bs(n,p)&&Gr(n,s,i,f),f&&p&&(n.finalTextSeen=!0);let m=Us(d,n.terminalProtocol);m&&!n.terminalOutcome&&(m.status==="failed"||n.finalTextSeen||n.artifacts.size>0)&&(n.terminalOutcome=m,n.emitTerminal?.(m))}catch{i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`${c}
|
|
12
|
+
`}}})}}}async sessionCancel(t){let r=a(t.sessionId),n=this.active.get(r);return n?(h("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),oe(n),{ok:!0,cancelled:!0}):{ok:!0,cancelled:!1}}async stop(t="stop"){for(let[r,n]of this.active.entries())h("info","runtime.cli","stopping runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid,reason:t}),oe(n);this.active.clear(),await this.taskMcp?.close(),this.taskMcp=null}};var pe="ORCHA_RUNTIME_OUTPUT_START",me="ORCHA_RUNTIME_OUTPUT_END",he="ORCHA_RUNTIME_CONTROL_START",ge="ORCHA_RUNTIME_CONTROL_END",_e=pe,Te=me,ye=he,Re=ge,we=[pe,me,he,ge],pi=new Set(["_artifacts","_decision","_meta"]),mi=new RegExp(`(?:^|(?<=[\\r\\n]))[ \\t]*(?<marker>${we.join("|")})[ \\t]*(?=\\r\\n?|\\n|$)`,"g"),k=class extends Error{constructor(t,r,n){super(r),this.name="RuntimeResultProtocolError",this.code=t,this.detail={rawOutput:n}}};function Zr(e){let t=typeof e=="string"?e.trimStart():"";return we.some(r=>t.startsWith(r))}function Se(e){if(typeof e!="string")return null;let t=e,r=hi(t);if(![...r.values()].some(g=>g.length>0))return null;let n=[],s=[];for(let[g,y]of r)y.length===0?n.push(g):y.length>1&&s.push(g);if(n.length>0||s.length>0){let g=[];throw n.length>0&&g.push(`\u7F3A\u5C11 ${n.join(", ")}`),s.length>0&&g.push(`\u91CD\u590D ${s.join(", ")}`),new k("invalid_markers",`Runtime Result \u534F\u8BAE\u6807\u8BB0\u4E0D\u5B8C\u6574\uFF1A${g.join("\uFF1B")}`,t)}let i=r.get(pe)[0],o=r.get(me)[0],c=r.get(he)[0],l=r.get(ge)[0];if(!(i.end<=o.start&&o.end<=c.start&&c.end<=l.start))throw new k("invalid_marker_order","Runtime Result \u534F\u8BAE\u6807\u8BB0\u987A\u5E8F\u9519\u8BEF\uFF1A\u5FC5\u987B\u5148\u8F93\u51FA OUTPUT \u5757\uFF0C\u518D\u8F93\u51FA CONTROL \u5757",t);let d=gi(t.slice(i.end,o.start));if(!d.trim())throw new k("empty_output","Runtime Result OUTPUT \u5757\u4E0D\u80FD\u4E3A\u7A7A",t);let f=t.slice(c.end,l.start).trim();if(!f)throw new k("empty_control","Runtime Result CONTROL \u5757\u4E0D\u80FD\u4E3A\u7A7A",t);let p;try{p=JSON.parse(f)}catch(g){throw new k("invalid_control_json",`Runtime Result CONTROL \u5757\u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${String(g?.message||g)}`,t)}if(!Yr(p))throw new k("invalid_control_type","Runtime Result CONTROL \u5757\u5FC5\u987B\u662F JSON \u5BF9\u8C61",t);let m=Object.keys(p).filter(g=>!pi.has(g)).sort();if(m.length>0)throw new k("invalid_control_keys",`Runtime Result CONTROL \u5757\u5305\u542B\u975E\u6807\u51C6\u5B57\u6BB5\uFF1A${m.join(", ")}`,t);if("_artifacts"in p&&!Array.isArray(p._artifacts))throw new k("invalid_control_field_type","Runtime Result CONTROL \u5757\u7684 _artifacts \u5FC5\u987B\u662F JSON \u6570\u7EC4",t);for(let g of["_decision","_meta"])if(g in p&&!Yr(p[g]))throw new k("invalid_control_field_type",`Runtime Result CONTROL \u5757\u7684 ${g} \u5FC5\u987B\u662F JSON \u5BF9\u8C61`,t);return{output:d,...p}}function hi(e){let t=new Map(we.map(r=>[r,[]]));for(let r of e.matchAll(mi))t.get(r.groups.marker).push({start:r.index,end:r.index+r[0].length});return t}function gi(e){let t=e.match(/^(?:\r\n|\r|\n)/)?.[0]||"",r=t?e.slice(t.length):e;return t&&r.endsWith(t)?r.slice(0,-t.length):r}function Yr(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}import{createHash as _i}from"node:crypto";var Ti="orcha.goal-contract/v1",yi=new Set(["complete","completed","done","ok","passed","success","succeeded"]),Ri=new Set(["aborted","blocked","cancelled","canceled","denied","error","failed","failure","timeout","timed_out"]),wi=new Map([["exec_command","run_command"],["local_shell_call","run_command"],["run_command","run_command"],["apply_patch","apply_patch"],["read_file","read_file"],["list_files","list_files"],["plugin_operation","plugin_operation"]]);function xe(e){return _i("sha256").update(q(e)).digest("hex")}function tn(e){if(!rn(e))return"";let t=["The following Orcha goal contract is immutable for this turn. Do not narrow its outcome or constraints.",`<goal_contract>${JSON.stringify(e)}</goal_contract>`];return e.verificationPlan?.required===!0&&t.push("Every verification check must be satisfied by a real successful tool call from one of its toolNames.","Each check requires requiredMatches distinct successful tool call IDs; repeated updates for one call count once.","A final text claim is not verification; missing or failed tool evidence prevents completion."),t.join(`
|
|
13
|
+
`)}function en(e,t,r=""){if(!rn(e))return e==null?null:{required:!0,status:"failed",outcome:a(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=xe(e),s=e.verificationPlan.required===!0;if(a(r)&&a(r)!==n)return{required:s,status:"failed",outcome:e.outcome,goalContractHash:n,checks:[],errorCode:"goal_contract_hash_mismatch"};if(!s)return{required:!1,status:"not_required",outcome:e.outcome,goalContractHash:n,checks:[]};let i=Si(t),o=e.verificationPlan.checks.map(l=>Ai(l,i));return{required:!0,status:o.some(l=>l.status==="failed")?"failed":o.some(l=>l.status==="missing")?"missing":"passed",outcome:e.outcome,goalContractHash:n,checks:o}}function rn(e){if(!u(e)||e.schemaVersion!==Ti||!a(e.outcome))return!1;let t=e.verificationPlan;if(!u(t)||typeof t.required!="boolean"||!Array.isArray(t.checks)||t.required&&t.checks.length===0)return!1;let r=new Set;for(let n of t.checks)if(!u(n)||!a(n.id)||r.has(a(n.id))||(r.add(a(n.id)),!Array.isArray(n.toolNames)||n.toolNames.length===0||n.toolNames.some(s=>!a(s)))||!Number.isSafeInteger(n.requiredMatches)||n.requiredMatches<1||n.arguments!==void 0&&!u(n.arguments))return!1;return!0}function Si(e){let t=new Map,r=[];for(let n of Array.isArray(e)?e:[]){let s=u(n?.update)?n.update:{},i=a(s.sessionUpdate);if(i==="runtime_event"){Ei(s.event,t,r);continue}if(i==="tool_call"){let o=$t(s)||`tool-${r.length+1}`,c=Ht(t,r,o),l=Oe(s,s.name||s.toolName||s.kind);c.toolName=l.toolName,c.arguments=l.arguments,c.status=gt(s.status),c.evidence=Bt(s);continue}if(i==="tool_call_update"){let o=$t(s);if(!o)continue;let c=Ht(t,r,o),l=Oe(s,s.name||s.toolName||s.kind);c.toolName||=l.toolName,Object.keys(c.arguments).length===0&&(c.arguments=l.arguments),c.status=gt(s.status),c.evidence.push(...Bt(s))}}return r}function Ei(e,t,r){let n=u(e)&&u(e.payload)?e.payload:u(e)?e:{},s=a(n.type);if(["function_call","custom_tool_call","local_shell_call","mcp_tool_call"].includes(s)){let c=$t(n)||`runtime-${r.length+1}`,l=Ht(t,r,c),d=Oe(n,n.name||n.tool||s,s);l.toolName=d.toolName,l.arguments=d.arguments,l.status=gt(n.status),l.evidence.push(...Bt(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=$t(n);if(!i)return;let o=Ht(t,r,i);o.status=Ci(n,o.toolName),o.evidence.push(...Bt(n))}function Ht(e,t,r){let n=e.get(r);return n||(n={toolCallId:r,toolName:"",arguments:{},status:"unknown",evidence:[]},e.set(r,n),t.push(n)),n}function Oi(e){let t=a(e).toLowerCase();return wi.get(t)||t}function Oe(e,t,r=""){let n=Ii(e),s=a(r)==="mcp_tool_call"||a(e?.kind).toLowerCase()==="mcp",i=u(e?._meta)?e._meta:{},o=a(e?.server||e?.serverName||e?.server_name||e?.mcpServer||i.server||i.serverName).toLowerCase();if(s&&o==="orcha"){let c=a(e?.tool||e?.toolName||e?.name||t);return{toolName:"plugin_operation",arguments:{...n,...c?{operationCode:c}:{}}}}return{toolName:Oi(t),arguments:n}}function $t(e){return u(e)?a(e.call_id||e.callId||e.toolCallId||e.id):""}function Ii(e){if(!u(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=xi(e[r]);if(n)return n}let t={};for(let r of["cmd","command","cwd","operationCode","path","query","url"])e[r]!==void 0&&(t[r]=e[r]);return t}function xi(e){if(u(e))return structuredClone(e);if(typeof e!="string")return null;try{let t=JSON.parse(e);return u(t)?t:null}catch{return null}}function Ci(e,t){if(!u(e))return"unknown";let r=Ft(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function Ft(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return bi(e,t,r);if(Array.isArray(e))return e.flatMap(o=>Ft(o,t+1,r));if(!u(e))return[];let n=[];typeof e.isError=="boolean"&&n.push(e.isError?"failed":"success"),typeof e.ok=="boolean"&&n.push(e.ok?"success":"failed"),typeof e.success=="boolean"&&n.push(e.success?"success":"failed");let s=gt(e.status);s!=="unknown"&&n.push(s);let i=e.exitCode??e.exit_code;typeof i=="number"&&Number.isFinite(i)&&n.push(i===0?"success":"failed");for(let o of["output","result","structuredContent","content"])e[o]!==void 0&&n.push(...Ft(e[o],t+1,r));return n}function bi(e,t,r){let n=e.trim();if(!n)return[];try{return Ft(JSON.parse(n),t+1,r)}catch{}if(r.parseCliExitCode!==!0)return[];let s=[];for(let i of n.matchAll(/(?:process\s+exited\s+with\s+code|exit\s+code\s*:?)\s*(-?\d+)/gi))s.push(Number(i[1])===0?"success":"failed");return s}function gt(e){let t=a(e).toLowerCase();return yi.has(t)?"success":Ri.has(t)?"failed":"unknown"}function Bt(e){if(!u(e))return[];let t=u(e.output)?e.output:{},r=[e.verificationEvidence,u(e.verification)?e.verification.evidence:null,t.verificationEvidence,u(t.verification)?t.verification.evidence:null],n=[];for(let s of r)for(let i of Array.isArray(s)?s:s?[s]:[])!u(i)||!a(i.id)||n.push({id:a(i.id),status:gt(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...a(i.message)?{message:a(i.message)}:{}});return n}function Ai(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&Ie(e.arguments||{},o.arguments)),n=a(e.evidenceId),s=r.filter(o=>o.status==="success"&&(!n||o.evidence.some(c=>c.id===n&&c.status==="success")));if(s.length>=e.requiredMatches)return Ee(e,"passed",s,`Runtime tool evidence passed ${s.length} times.`);let i=r.filter(o=>o.status==="failed"||n&&o.evidence.some(c=>c.id===n&&c.status==="failed"));return s.length===0&&i.length?Ee(e,"failed",i,"Runtime tool evidence failed."):Ee(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function Ee(e,t,r,n){let s=r.map(i=>i.toolCallId).filter(Boolean);return{id:e.id,status:t,message:n,...a(e.description)?{description:a(e.description)}:{},toolNames:e.toolNames,requiredMatches:e.requiredMatches,observedMatches:s.length,toolCallIds:s,...u(e.arguments)?{arguments:e.arguments}:{},...a(e.evidenceId)?{evidenceId:a(e.evidenceId)}:{}}}function Ie(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>Ie(r,t[n])):u(e)?u(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&Ie(n,t[r])):!1:Object.is(e,t)}function q(e){if(e===null||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="string")return Qr(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new Error("invalid_jcs_number");return JSON.stringify(Object.is(e,-0)?0:e)}if(Array.isArray(e))return`[${Array.from({length:e.length},(t,r)=>{if(!Object.hasOwn(e,r))throw new Error("invalid_jcs_json_value");return q(e[r])}).join(",")}]`;if(u(e))return`{${Object.keys(e).sort().map(t=>`${Qr(t)}:${q(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function Qr(e){return Ni(e),JSON.stringify(e)}function Ni(e){for(let t=0;t<e.length;t+=1){let r=e.charCodeAt(t);if(r>=55296&&r<=56319){let n=e.charCodeAt(t+1);if(!(n>=56320&&n<=57343))throw new Error("invalid_jcs_unicode");t+=1}else if(r>=56320&&r<=57343)throw new Error("invalid_jcs_unicode")}}import{spawn as Mi}from"node:child_process";import{createHash as Ui,randomUUID as Pi}from"node:crypto";import{constants as ki}from"node:fs";import{access as Li,mkdir as Ce,readdir as Di,realpath as _t,rm as vi,stat as Hi}from"node:fs/promises";import $i from"node:http";import{tmpdir as Fi}from"node:os";import{isAbsolute as Tt,join as nt,relative as nn,resolve as Ae}from"node:path";var Ne=1,Bi="orcha.process-isolation/v1",Me="orcha.egress-proxy/v1",qi="--disable-wasm-trap-handler",qt={read_only:0,workspace_write:1,workspace_network:2},be={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},ji=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function W(e){if(!u(e))throw S("RUNTIME_SANDBOX_POLICY_REQUIRED","sandboxPolicy is required");let t=structuredClone(e),r=a(t.accessMode),n=a(t.accessModeCeiling);if(!(r in be)||!(n in be))throw S("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if(qt[r]>qt[n])throw S("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=be[r];if(t.filesystemMode!==s||t.networkMode!==i)throw S("RUNTIME_SANDBOX_POLICY_INVALID","runtime access profile does not match its mode");if(Number(t.policySchemaVersion)!==Ne||!Number.isInteger(Number(t.policyRevision))||Number(t.policyRevision)<1)throw S("RUNTIME_SANDBOX_POLICY_INVALID","unsupported sandbox policy schema or revision");for(let[c,l]of Object.entries({outsideWorkspaceAccess:"denied",hostAccess:"denied",hostEnvironmentAccess:"denied",dockerSocketAccess:"denied",environmentMode:"allowlist"}))if(t[c]!==l)throw S("RUNTIME_SANDBOX_POLICY_INVALID",`${c} cannot be relaxed`);let o=u(t.processIsolation)?t.processIsolation:{};if(o.mode!=="required"||o.backend==="direct")throw S("RUNTIME_SANDBOX_POLICY_INVALID","strong process isolation is required");if(Array.isArray(t.alwaysApprovedApprovalKeys)&&t.alwaysApprovedApprovalKeys.length)throw S("RUNTIME_SANDBOX_POLICY_INVALID","persistent runtime approvals are forbidden");return t}function sn(e,t){let r=W(e),n=W(t);return qt[n.accessMode]<qt[r.accessMode]}async function on(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[Ne],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await cn(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await Wi(t,b(e.sandboxBrokerArguments),e.sandboxProbeTimeoutMs);if(r.enforced!==!0||a(r.protocolVersion)!=="orcha.runtime-sandbox-broker/v1"||!["bubblewrap","broker"].includes(a(r.backend)))throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker did not report enforced isolation");let n=u(r.probes)?r.probes:{};for(let s of["emptyRoot","outsideWorkspaceDenied","hostFilesystemDenied","sensitiveFilesDenied","environmentAllowlist","dockerSocketDenied","networkNamespace","workspaceReadOnly","workspaceWrite","resourceLimits"])if(n[s]!==!0)throw S("RUNTIME_SANDBOX_UNAVAILABLE",`sandbox broker probe failed: ${s}`);return e.egressProxyRequired&&await Yi(e),{dispatchable:!0,enforced:!0,backend:a(r.backend),daemonStatus:"ok",daemonProtocolVersion:a(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[Ne],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function Ue(e,t,r){let n=a(t.workspace||t.cwd),s=a(r),i=n||(t.allowRequestWorkspace===!0?s:"");if(!i||!Tt(i))throw S("RUNTIME_WORKSPACE_NOT_CONFIGURED","runtime target must configure an absolute trusted workspace");let o=await _t(i);if(!(await Hi(o)).isDirectory())throw S("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>_t(d))):[o]).some(d=>ke(d,o)))throw S("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function an({config:e,target:t,command:r,args:n,cwd:s,environment:i,runId:o,agentId:c,sessionId:l,sandboxPolicy:d}){if(!e.sandboxRequired)return{command:r,args:[...n],cwd:s,environment:{...process.env,...i},tempDirectory:"",isolation:{enforced:!1,backend:"development_direct"},cleanup:async()=>{}};let f=W(d),p=await Ue(e,t,s),m=await _t(s);if(!ke(p,m))throw S("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let g=await cn(e.sandboxBrokerCommand,process.env.PATH||"");if(!g)throw S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let y=`runtime-${Ui("sha256").update(String(o)).digest("hex").slice(0,32)}`,x=Ae(e.sandboxTempRoot||nt(Fi(),"orcha-runtime-sandboxes"));await Ce(x,{recursive:!0,mode:448});let A=nt(x,`${y}-${Pi()}`),T=nt(A,"home"),R=nt(A,"artifacts");await Ce(T,{recursive:!0,mode:448}),await Ce(R,{recursive:!0,mode:448});let w=f.networkMode==="restricted"?await Ji(e,{runId:String(o),instanceId:y,policyRevision:Number(f.policyRevision),ttlMs:Math.min(_(f.maxRuntimeSeconds,900)*1e3,e.egressGrantMaxTtlMs),maxTransferBytes:_(f.maxNetworkBytes,64*1024*1024)}):null,O={PATH:a(i.PATH||process.env.PATH),LANG:a(i.LANG||process.env.LANG||"C.UTF-8"),HOME:"/tmp/home",TMPDIR:"/tmp",USER:"orcha",LOGNAME:"orcha",SHELL:"/bin/sh",ORCHA_AGENT_ID:String(c),ORCHA_SESSION_ID:String(l),ORCHA_RUN_ID:String(o),ORCHA_RUNTIME_ARTIFACT_DIR:"/tmp/artifacts",...Gi(t,i)};O.HOME="/tmp/home",O.TMPDIR="/tmp",O.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",O.NODE_OPTIONS=qi;let P={schemaVersion:Bi,runId:String(o),instanceId:y,workspace:p,cwd:m,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await zi(p),temporaryDirectory:A,egressProxy:w,environment:O,resourceLimits:Vi(f),readOnlyToolchainRoots:await Ki(e,t)},v=!1,N=async()=>{if(!v){v=!0;try{w&&await Xi(e,w,{runId:String(o),instanceId:y})}finally{await vi(A,{recursive:!0,force:!0})}}};return{command:g,args:[...b(e.sandboxBrokerArguments),"--",r,...n],cwd:m,environment:{PATH:process.env.PATH||"",LANG:process.env.LANG||"C.UTF-8",ORCHA_PROCESS_ISOLATION_REQUEST:JSON.stringify(P)},tempDirectory:A,homeDirectory:T,artifactDirectory:R,pathMappings:[{runtimeRoot:"/tmp/artifacts",hostRoot:R},{runtimeRoot:"/tmp/home",hostRoot:T}],isolation:{enforced:!0,backend:"broker",instanceId:y,policyRevision:f.policyRevision},cleanup:N}}async function Ki(e,t){let r=b(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(b(e.trustedToolchainRoots).map(i=>_t(i)));if(!n.length)throw S("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","target toolchain roots require ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS");let s=[];for(let i of r){if(!Tt(i))throw S("RUNTIME_TOOLCHAIN_ROOT_INVALID","toolchain roots must be absolute");let o=await _t(i);if(!n.some(c=>ke(c,o)))throw S("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function Gi(e,t){let r=u(e.env)?e.env:{},n={};for(let[s,i]of Object.entries(r))/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&i!=null&&(n[s]=String(i));for(let s of["ORCHA_RUNTIME_PROMPT","ORCHA_RUNTIME_ARTIFACT_DIR"])t[s]!=null&&(n[s]=String(t[s]));return n}async function zi(e){let t=[],r=0,n=async s=>{let i;try{i=await Di(s,{withFileTypes:!0})}catch(o){if(s===e)throw o;return}for(let o of i){if(r+=1,r>1e4)throw S("RUNTIME_WORKSPACE_SCAN_LIMIT_EXCEEDED","workspace contains more than 10000 entries");let c=nt(s,o.name),l=nn(e,c),d=o.name.toLowerCase();(ji.has(d)||d.startsWith(".env."))&&t.push(l),o.isDirectory()&&!o.isSymbolicLink()&&await n(c)}};return await n(e),t.sort()}function Vi(e){return{maxCpuSeconds:Math.max(1,_(e.maxRuntimeSeconds,900)),maxMemoryBytes:_(e.maxMemoryBytes,2*1024*1024*1024),maxProcesses:_(e.maxProcesses,128),maxOpenFiles:_(e.maxOpenFiles,1024),maxFileBytes:_(e.maxFileBytes,64*1024*1024)}}async function Wi(e,t,r){return await new Promise((n,s)=>{let i=Mi(e,[...t,"--probe"],{env:{PATH:process.env.PATH||"",LANG:"C.UTF-8"},stdio:["ignore","pipe","pipe"],windowsHide:!0}),o=[],c=[];i.stdout.on("data",d=>o.push(Buffer.from(d))),i.stderr.on("data",d=>c.push(Buffer.from(d)));let l=setTimeout(()=>i.kill("SIGKILL"),Math.max(1e3,r));i.once("error",s),i.once("close",d=>{if(clearTimeout(l),d!==0){s(S("RUNTIME_SANDBOX_UNAVAILABLE",Buffer.concat(c).toString("utf8").trim()||`sandbox probe exited with ${d}`));return}try{n(JSON.parse(Buffer.concat(o).toString("utf8")))}catch{s(S("RUNTIME_SANDBOX_UNAVAILABLE","sandbox probe returned invalid JSON"))}})})}async function cn(e,t){let r=a(e);if(!r)return"";let n=Tt(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>nt(s,r));for(let s of n)try{return await Li(s,ki.X_OK),s}catch{}return""}async function Ji(e,t){if(!e.egressProxyRequired)throw S("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await Pe(e,"POST","/v1/grants",{protocolVersion:Me,...t}),n={socketPath:e.egressProxySocket,grantId:a(r.grantId),credential:a(r.credential)};if(!n.grantId||!n.credential)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy returned an invalid grant");return n}async function Xi(e,t,r){await Pe(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:Me,...r}).catch(()=>{})}async function Yi(e){let t=await Pe(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==Me)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function Pe(e,t,r,n){if(!Tt(e.egressProxySocket)||!e.egressProxyToken)throw S("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy socket and token are required");return await new Promise((s,i)=>{let o=$i.request({socketPath:e.egressProxySocket,path:r,method:t,headers:{Authorization:`Bearer ${e.egressProxyToken}`,Accept:"application/json",...n?{"Content-Type":"application/json"}:{}}},c=>{let l=[],d=0;c.on("data",f=>{d+=f.length,d>1048576?o.destroy(new Error("egress response is too large")):l.push(Buffer.from(f))}),c.once("end",()=>{try{let f=JSON.parse(Buffer.concat(l).toString("utf8")||"{}");(c.statusCode||500)>=400?i(S("RUNTIME_EGRESS_UNAVAILABLE",a(f.error)||"Egress Proxy rejected the request")):s(f)}catch(f){i(f)}})});o.once("error",i),o.setTimeout(3e3,()=>o.destroy(new Error("Egress Proxy request timed out"))),n?o.end(JSON.stringify(n)):o.end()})}function ke(e,t){let r=nn(Ae(e),Ae(t));return r===""||!r.startsWith("..")&&!Tt(r)}function S(e,t){return Object.assign(new Error(t),{code:e})}var Le=24e3,De=8,ve=50,He=6e3,Qi=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),to=10*60*1e3,eo=60*1e3,ro=8,no=30*60*1e3,so=60*1e3,io=1,fn=2400,oo=new Set(["max_tokens","max_output_tokens","length"]),ao=new Set(["agent_message_chunk","tool_call","tool_call_update"]),co=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),uo=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function lo(e){if(!u(e))return{};let t={};for(let r of["name","code","serverName","serverCode","type","transport","url","command","protocolVersion"]){let n=a(e[r]);n&&(t[r]=n)}return t}function fo(e){return(Array.isArray(e)?e:[]).map(lo).sort((t,r)=>{let n=q(t),s=q(r);return n<s?-1:n>s?1:0})}function po(e){return!u(e)||e.verificationPlan?.required!==!0?!1:(Array.isArray(e.verificationPlan.checks)?e.verificationPlan.checks:[]).some(r=>u(r)&&Array.isArray(r.toolNames)&&r.toolNames.some(n=>a(n)==="plugin_operation"))}function mo(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:Kt()}}}function L(e){return e==null||e===""?!1:typeof e=="string"?a(e)!=="":Array.isArray(e)?e.length>0:u(e)?Object.keys(e).length>0:!0}function pn(e){let t=a(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return Qi.has(t)}function G(e,t){let r=_(e,t);return Number.isFinite(r)&&r>0?r:t}function yt(e,t=!1){if(typeof e=="boolean")return e;let r=a(e).toLowerCase();return["true","1","yes","y","on"].includes(r)?!0:["false","0","no","n","off"].includes(r)?!1:t}function K(e){return a(e?.type||"echo")}function mn(e){let t=K(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function Be(e){if(u(e)){if(Object.prototype.hasOwnProperty.call(e,"releaseAfterPrompt"))return e.releaseAfterPrompt;if(Object.prototype.hasOwnProperty.call(e,"disposeAfterPrompt"))return e.disposeAfterPrompt}}function ho(e){let t=String(e||"");if(uo.test(t))return!0;let r=t.replace(/[^a-z0-9]/gi,"").toLowerCase();return r.endsWith("token")||r.endsWith("secret")||r.endsWith("password")||r.endsWith("apikey")||r.endsWith("privatekey")||r==="authorization"||r==="cookie"||r==="jwt"||r.includes("credential")}function qe(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=He)return e;let r=e.length-He;return`${e.slice(0,He)}... [truncated ${r} characters]`}if(t>=De)return Array.isArray(e)?`[array truncated at depth ${De}, items=${e.length}]`:u(e)?`[object truncated at depth ${De}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,ve).map(n=>qe(n,t+1));return e.length>ve&&r.push(`[truncated ${e.length-ve} items]`),r}if(u(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=ho(n)?"[REDACTED]":qe(s,t+1);return r}return String(e)}var go=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 _o(e){if(!u(e))return e;let t={};for(let r of go)L(e[r])&&(t[r]=e[r]);return t}function To(e){if(!u(e))return e;let t={...e};return u(t.renderedPayload)&&(t.renderedPayload=_o(t.renderedPayload)),t}function yo(e){let t=u(e)?e:{},r={};L(t.metadata)&&(r.metadata=To(t.metadata));for(let[n,s]of Object.entries(t))co.has(n)||n==="metadata"||L(s)&&(r[n]=s);return r}function Ro(e){let t=u(e)?e:{},r=u(t.metadata)?t.metadata:{},n=u(r.renderedPayload)?r.renderedPayload:{};return u(t.resultContract)?t.resultContract:u(n.resultContract)?n.resultContract:{}}function hn(e){return a(Ro(e).kind).toLowerCase()==="decision"}function wo(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:K(e)==="cli"}function un(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return yt(t,mn(e))}function So(e,t){let r=u(e?.metadata)?{...e.metadata}:{},n=u(r._runtimeBridge)?{...r._runtimeBridge}:{},s=Be(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:wo(t),releaseAfterPrompt:s===void 0?un(t):yt(s,un(t)),requiresRuntimeResult:hn(e)},r}function Eo(e){let t=yo(e);if(!L(t))return"";let r=JSON.stringify(qe(t),null,2);if(r.length<=Le)return r;let n=r.length-Le;return`${r.slice(0,Le)}
|
|
14
|
+
... [truncated ${n} characters]`}function Ke(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 je(e){if(!u(e))return"";let t=u(e.update)?e.update:e;return a(t.sessionUpdate)}function Ge(e){if(!Array.isArray(e))return"";let t=!1,r=[],n=[],s=[],i=()=>{r.length>0&&(n.push(r),r=[])};for(let c of e){let l=je(c),d=Ke(c);if(!l){d&&s.push(d);continue}if(t=!0,l==="agent_message_chunk"){d&&r.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 st(s);let o=n[n.length-1]||[];return st(o)}function Oo(e){return Array.isArray(e)?e.map(Ke).filter(t=>t!==""):[]}function Gt(e){return Array.isArray(e)?e.some(r=>je(r))?e.filter(r=>ao.has(je(r))).map(Ke).filter(r=>r!==""):Oo(e):[]}function Io(e){if(!u(e))return null;let t=u(e.update)?e.update:e;return a(t.sessionUpdate)!=="runtime_event"?null:u(t.event)?t.event:null}function xo(e){if(!u(e))return"";let t=u(e.payload)?e.payload:{},r=a(e.type),n=a(t.type);if(r==="event_msg"){if(n==="task_complete")return a(t.last_agent_message||t.message||t.output);if(n==="agent_message"){let s=a(t.phase||t.status||t.stage).toLowerCase();if(["final_answer","final","complete","completed","done"].includes(s))return a(t.message||t.text||t.content)}}return""}function Co(e){if(!Array.isArray(e))return"";for(let t=e.length-1;t>=0;t-=1){let r=xo(Io(e[t]));if(r)return r}return""}function st(e){let t="";for(let r of e){let n=String(r||"");if(n)if(!t)t=n;else if(n.length>t.length&&n.startsWith(t))t=n;else{let s=Zr(n)&&!/[\r\n]$/.test(t)?`
|
|
15
|
+
`:"";t+=`${s}${n}`}}return t.trim()}function bo(e){let t=String(e||"").trim();if(!t)return"";let r=t.match(/(?:^|\n)#{1,3}\s+\S/);return!r||r.index===0?t:t.slice(r.index+(t[r.index]===`
|
|
16
|
+
`?1:0)).trim()}function ln(e){let t=String(e||"").trim();if(!t)return null;try{let r=JSON.parse(t);if(u(r)&&(gn(r)||L(r._artifacts)||L(r.artifacts)||L(r._decision)||L(r._meta)))return r}catch{}return null}function Rt(e){try{return Se(e)}catch{return null}}function jt(...e){let t=null;for(let r of e)try{if(Se(r))return}catch(n){t||=n}if(t)throw t}function $e(e){let t=String(e||"").trim();if(!t)return null;let r=Rt(t);if(r)return r;let n=[...t.matchAll(/```(?:json)?\s*([\s\S]*?)```/gi)];for(let s=n.length-1;s>=0;s-=1){let i=ln(n[s][1]);if(i)return i}if(!t.endsWith("}"))return null;for(let s=t.lastIndexOf("{");s>=0;s=t.lastIndexOf("{",s-1)){let i=ln(t.slice(s));if(i)return i}return null}function Ao(e){let t=Rt(Ge(e));if(t)return t;let r=Gt(e);for(let n=r.length-1;n>=0;n-=1){let s=Rt(r[n]);if(s)return s}return Rt(st(r))}function gn(e){if(!u(e))return!1;if(L(e.output))return!0;for(let t of["content","text","message","summary"])if(a(e[t]))return!0;return!!(pn(e.status)||a(e.error)||a(e.errorMessage))}function B(e){let t=u(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 No(e){return u(e)?typeof(u(e._decision)?e._decision:u(e.decision)?e.decision:e).passed=="boolean":!1}function _n(e){return u(e)?u(e._decision)&&typeof e._decision.passed=="boolean"?!0:No(e.output):!1}function Fe(e,t,r){let n=u(e)?{...e}:{};if(!L(n.output)){for(let s of["summary","message","content","text"])if(a(n[s])){n.output=a(n[s]);break}}return!L(n.output)&&a(r)&&(n.output=a(r)),{...n,_meta:{...u(n._meta)?n._meta:{},runtimeOutputSource:t,requiredRuntimeResult:!0,finalMessagePreview:a(r).slice(0,1e3)}}}var Mo=["dataUrl","dataURL","contentDataUrl","contentDataURL","contentBase64","base64","data"];function dn(e){if(!u(e))return"";let t=u(e.content)?e.content:{},r=u(e.metadata)?e.metadata:{};return a(e.fieldKey||e.field_key||t.fieldKey||r.fieldKey)}function Uo(e,t){let r=u(e.content)?e.content:{},n=u(t.content)?t.content:{},s={...e,...t,content:{...r,...n},metadata:{...u(e.metadata)?e.metadata:{},...u(t.metadata)?t.metadata:{}}};for(let i of Mo)L(e[i])&&(s[i]=e[i]),L(r[i])&&(s.content[i]=r[i]);return s}function Tn(e,t){let r=Array.isArray(e)?e.filter(u):[],n=Array.isArray(t)?t.filter(u):[];if(!r.length)return n;if(!n.length)return r;let s=[...r],i=new Map;for(let c=0;c<r.length;c+=1){let l=dn(r[c]),d=i.get(l)||[];d.push(c),i.set(l,d)}let o=new Map;for(let c of n){let l=dn(c),d=o.get(l)||0;o.set(l,d+1);let f=i.get(l)?.[d];f===void 0?s.push(c):s[f]=Uo(s[f],c)}return s}function j(e,t,r){let n={...e,...t,_meta:{...u(e._meta)?e._meta:{},...u(t._meta)?t._meta:{},runtimeOutputSource:r}};return(Array.isArray(e._artifacts)||Array.isArray(t._artifacts))&&(n._artifacts=Tn(e._artifacts,t._artifacts)),n}function yn(e,t,r={}){let n=a(r.promptKind),s=r.requiresRuntimeResult===!0,i=s||n==="dispatch",o=B(e),c=typeof o.output=="string"?Rt(o.output):null;if(c)return j(o,B(c),"result_block");let l=Co(t),d=l?$e(l):null,f=i?Ao(t):null;if(gn(o))return pn(o.status)||a(o.error)||a(o.errorMessage)?o:n==="dispatch"&&d?j(o,B(d),"final_event"):n==="dispatch"&&f?j(o,B(f),"updates"):!s||_n(o)?o:d?j(o,B(d),"final_event"):f?j(o,B(f),"updates"):(jt(o.output,l,st(Gt(t))),Fe(o,"result",o.output));if(d)return j(o,B(d),"final_event");if(f)return j(o,B(f),"updates");if(l)return s?(jt(l,st(Gt(t))),Fe(o,"final_event",l)):{...o,output:l,_meta:{...u(o._meta)?o._meta:{},runtimeOutputSource:"final_event"}};let p=Ge(t),m=$e(p);if(m)return j(o,B(m),"updates");let g=bo(p);if(!g)return s&&jt(st(Gt(t))),o;let y=$e(g);return y?j(o,B(y),"updates"):s?(jt(p,g),Fe(o,"updates",g)):{...o,output:g,_meta:{...u(o._meta)?o._meta:{},runtimeOutputSource:"updates"}}}function ze(e){return u(e)?a(e.stopReason||e.stop_reason).toLowerCase():""}function Rn(e){return oo.has(ze(e))}function Po(e,t,r){if(r.promptKind!=="dispatch"||r.requiresRuntimeResult!==!0||!Rn(e))return!1;try{return!_n(yn(e,t,r))}catch{return!0}}function ko(){return["Your previous final response reached the output limit before the Runtime Result protocol was complete.","Re-emit the complete final Runtime Result from scratch using the conclusion you already reached.","Do not repeat analysis, process notes, tool calls, or task work.",`Keep the OUTPUT report within ${fn} Unicode characters.`,`Output ${_e}, ${Te}, ${ye}, and ${Re} on their own lines.`,"The CONTROL block must be valid JSON containing _decision and must be fully closed.","Return only the two protocol blocks."].join(`
|
|
17
|
+
`)}function Lo(e,t){let r=u(t)?{...t}:{},n=Tn(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function Do(e,t){return{...e,_meta:{...u(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:ze(t)||"max_tokens"}}}}function vo(e,t){let r=typeof e?.output=="string"?e.output:Ge(t),n=new k("runtime_output_truncated","Runtime Result \u8FBE\u5230\u6700\u5927\u8F93\u51FA\u957F\u5EA6\uFF0C\u7D27\u51D1\u91CD\u8BD5\u540E\u4ECD\u672A\u5B8C\u6574\u8FD4\u56DE",r);return n.detail={...n.detail,stopReason:ze(e)||"max_tokens",retryAttempted:!0},n}var zt=class{constructor(t){this.config=t,this.targets=t.targets||{},this.agents=new Map,this.sessions=new Map,this.startingSessions=new Set,this.targetReservations=new Map,this.runtimeSessionIndex=new Map,this.pendingPermissions=new Map,this.operations=new Map,this.startedAt=dt(),this.sandboxCapabilities={dispatchable:t.sandboxRequired!==!0,enforced:!1,backend:t.sandboxRequired?"unavailable":"direct",daemonStatus:t.sandboxRequired?"pending":"not_required",policySchemaVersions:[1],runtimePolicyUpdates:t.sandboxRequired===!0,workspaceSync:!1,egressProxy:!1},this.cleanupTimer=null,this.onCapacityChanged=null,this.startSessionCleanup()}async start(){try{this.sandboxCapabilities=await on(this.config)}catch(t){this.sandboxCapabilities={...this.sandboxCapabilities,dispatchable:!1,enforced:!1,backend:"unavailable",daemonStatus:"unavailable",reason:a(t?.code||t?.message||t)||"sandbox_probe_failed"},h("error","runtime-bridge","runtime node sandbox probe failed; node will not accept work",{reason:this.sandboxCapabilities.reason})}return this.sandboxCapabilities}assertDispatchable(){if(this.config.sandboxRequired&&!(this.sandboxCapabilities.dispatchable===!0&&this.sandboxCapabilities.enforced===!0))throw Object.assign(new Error("runtime node strong sandbox is unavailable"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"})}operationIdentity(t,r,n){let s=u(t.goalContract)?xe(t.goalContract):a(t.goalContractHash),i=Zi("sha256").update(q({prompt:Array.isArray(t.prompt)?t.prompt:[],mcpServers:fo(t.mcpServers),metadata:u(t.metadata)?t.metadata:{}})).digest("hex");return{agentId:r,runId:a(t.runId),sessionId:n,targetCode:a(t.targetCode||t.framework),workspace:a(t.workspace),goalContractHash:s,requestHash:i}}assertOperationIdentity(t,r,n,s){let i=this.operationIdentity(r,n,s),o=Object.keys(t.identity).find(c=>t.identity[c]!==i[c]);if(o)throw Object.assign(new Error(`runtime operation correlation conflict: ${t.correlationId}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT",field:o})}createOperation(t,r,n,s){let i={correlationId:t,agentId:n,sessionId:s,identity:this.operationIdentity(r,n,s),sandboxPolicy:u(r.sandboxPolicy)?structuredClone(r.sandboxPolicy):null,status:"running",updates:[],listeners:new Set,waiters:[],response:null,error:null,mcpServers:r.mcpServers,createdAtMs:Date.now(),completedAtMs:null};return this.operations.set(t,i),i}async attachOperation(t,r={}){let n=()=>{if(r.onUpdate)for(let s of t.updates)r.onUpdate(s)};if(t.status==="completed")return n(),t.response;if(t.status==="failed")throw n(),t.error;r.onUpdate&&t.listeners.add(r.onUpdate);try{return n(),await new Promise((s,i)=>t.waiters.push({resolve:s,reject:i}))}finally{r.onUpdate&&t.listeners.delete(r.onUpdate)}}completeOperation(t,r){if(t.status==="running"){t.status="completed",t.response=r,t.mcpServers=null,t.completedAtMs=Date.now();for(let n of t.waiters.splice(0))n.resolve(r);t.listeners.clear()}}promptResponse(t,r,n,s,i,o=s){let c=u(t.metadata)?t.metadata:{},l=u(c._runtimeBridge)?c._runtimeBridge:{},d=yn(i,o,l),f=en(t.goalContract,s,t.goalContractHash);return{sessionId:n,runtimeSessionId:r.runtimeSessionId,result:d,updates:s,...f?{verification:f}:{}}}failOperation(t,r){if(t.status!=="running")return;let n=r instanceof Error?r:Object.assign(new Error(String(r||"runtime operation failed")),{code:"RUNTIME_NODE_ERROR"});t.status="failed",t.error=n,t.mcpServers=null,t.completedAtMs=Date.now();for(let s of t.waiters.splice(0))s.reject(n);t.listeners.clear()}cleanupOperations(t=Date.now()){let r=G(this.config.operationTtlMs,no);for(let[n,s]of this.operations)s.status!=="running"&&t-(s.completedAtMs||s.createdAtMs)>r&&this.operations.delete(n)}targetFor(t){let r=a(t)||this.config.defaultTargetCode,n=this.targets[r];if(!r||!u(n)){let s=new Error(`runtime target is not configured: ${r||"<empty>"}`);throw s.code="RUNTIME_TARGET_NOT_FOUND",s}return{code:r,target:n}}targetIdleTtlMs(t){let n=K(t)==="openclaw"?G(this.config.openClawSessionIdleTtlMs,so):G(this.config.sessionIdleTtlMs,to);return G(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=K(t)==="openclaw"?G(this.config.openClawMaxSessions,io):G(this.config.maxSessionsPerTarget,ro);return G(t?.maxSessions,n)}targetReservationCount(t){return Number(this.targetReservations.get(t)||0)}notifyCapacityChanged(){try{this.onCapacityChanged?.()}catch(t){h("warn","runtime-bridge","capacity heartbeat callback failed",{error:String(t)})}}targetCapacitySnapshot(t=!0){return Object.entries(this.targets).map(([r,n])=>{let s=[...this.sessions.values()].filter(f=>f.targetCode===r),i=s.filter(f=>f.busy).length,o=s.length-i,c=this.targetReservationCount(r),l=this.targetMaxSessions(n),d=t?Math.max(0,l-i-c):0;return{targetCode:r,targetName:a(n?.name||n?.targetName||r),targetType:a(n?.type||"echo"),status:t?d>0?"available":"busy":"unavailable",maxSessions:l,busySessions:i,idleSessions:o,reservedSessions:c,availableSessions:d}})}targetReleaseAfterPrompt(t,r={}){let n=K(t),s=u(r?._runtimeBridge)?r._runtimeBridge:{},i=Be(s);return i!==void 0?yt(i,!1):yt(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=u(r?._runtimeBridge)?r._runtimeBridge:{},s=Be(n);return s!==void 0?yt(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=G(this.config.sessionCleanupIntervalMs,eo);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(r=>{h("warn","runtime-bridge","runtime session cleanup failed",{error:String(r)})})},t),this.cleanupTimer.unref?.())}sessionCountForTarget(t){let r=0;for(let n of this.sessions.values())n.targetCode===t&&(r+=1);return r}idleTargetSessions(t){return[...this.sessions.entries()].filter(([,r])=>r.targetCode===t&&!r.busy).sort((r,n)=>(r[1].lastUsedAtMs||0)-(n[1].lastUsedAtMs||0))}async closeSession(t,r="session_closed"){let n=this.sessions.get(t);if(!n)return!1;try{await n.runtime?.stop?.(r)}catch(s){h("warn","runtime-bridge","runtime session stop failed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,error:String(s)})}return this.sessions.delete(t),this.runtimeSessionIndex.delete(`${n.agentId}:${n.runtimeSessionId}`),this.notifyCapacityChanged(),h("info","runtime-bridge","runtime session closed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,reason:r}),!0}async closeAllSessions(t="bridge_shutdown"){for(let r of[...this.sessions.keys()])await this.closeSession(r,t)}async stop(t="bridge_stop"){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=null,await this.closeAllSessions(t)}async cleanupExpiredSessions(t=Date.now()){for(let[r,n]of[...this.sessions.entries()])n.busy||t-(n.lastUsedAtMs||n.createdAtMs||t)>n.idleTtlMs&&await this.closeSession(r,"idle_timeout")}async reserveTargetSlot(t,r){let n=this.targetMaxSessions(r);for(;this.sessionCountForTarget(t)+this.targetReservationCount(t)>=n;){let s=this.idleTargetSessions(t);if(!s.length){let i=new Error(`runtime target session limit reached: ${t}`);throw i.code="RUNTIME_TARGET_SESSION_LIMIT",i}await this.closeSession(s[0][0],"target_session_limit")}this.targetReservations.set(t,this.targetReservationCount(t)+1),this.notifyCapacityChanged()}releaseTargetSlot(t){let r=Math.max(0,this.targetReservationCount(t)-1);r>0?this.targetReservations.set(t,r):this.targetReservations.delete(t),this.notifyCapacityChanged()}async createAgent(t){let r=a(t.agentId);if(!r)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});let{code:n,target:s}=this.targetFor(t.targetCode||t.framework),i=this.agents.get(r);if(i&&i.targetCode!==n)throw Object.assign(new Error(`runtime agent target conflict: ${r}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});let o=this.config.sandboxRequired?await Ue(this.config,s,t.workspace):a(t.workspace),c={agentId:r,targetCode:n,framework:a(t.framework||n),workspace:o,metadata:u(t.metadata)?t.metadata:{},createdAt:dt(),runtimeKind:K(s)};return this.agents.set(r,c),{agent:c}}runtimeFor(t,r,n={}){let{target:s}=this.targetFor(t.targetCode),i=K(s),o={onPermissionRequest:l=>n.source==="conversation_delegation"?{outcome:"denied",reason:"External group member permission continuation is not supported"}:this.requestPermission(l)},c={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs,initializeTimeoutMs:this.config.initializeTimeoutMs,sandboxRequired:this.config.sandboxRequired,runId:n.runId,sandboxPolicy:n.sandboxPolicy,...this.config.sandboxRequired?{prepareLaunch:l=>an({config:this.config,target:s,...l,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new et(t,s,o,c):i==="openclaw"?new Ut(t,s,r,o,c):i==="cli"?new vt(t,s,c):new It(t)}async prompt(t,r={}){if(this.assertDispatchable(),this.config.sandboxRequired){let c=a(t.runId);if(!c)throw Object.assign(new Error("runId is required"),{code:"BAD_REQUEST"});t={...t,runId:c,sandboxPolicy:W(t.sandboxPolicy)}}let n=a(t.agentId),s=a(t.sessionId)||Kt(),i=a(t.correlationId);if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});if(this.cleanupOperations(),i){let c=this.operations.get(i);if(c){if(this.assertOperationIdentity(c,t,n,s),c.status==="running"&&t.metadata?.source==="conversation_delegation"){c.mcpServers=t.mcpServers;let l=this.sessions.get(`${n}:${s}`);if(l){if(!l.runtime.refreshMcpServers)throw Object.assign(new Error("This runtime cannot refresh task MCP credentials"),{code:"unsupported_dynamic_mcp"});await l.runtime.refreshMcpServers(t.mcpServers)}}return this.attachOperation(c,r)}if(t.attachOnly===!0)throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"})}else if(t.attachOnly===!0)throw Object.assign(new Error("correlationId is required for attachOnly"),{code:"BAD_REQUEST"});let o=i?this.createOperation(i,t,n,s):null;if(o){let c=this.attachOperation(o,r);return(async()=>{try{await this._promptOwned(t,{},o,n,s)}catch(l){let d=o.status==="completed";this.failOperation(o,l),d&&h("warn","runtime-bridge","runtime cleanup failed after operation completion",{correlationId:o.correlationId,error:String(l)})}})(),await c}return await this._promptOwned(t,r,o,n,s)}async _promptOwned(t,r,n,s,i){let o=a(t.runId),c=this.config.sandboxRequired?W(n?.sandboxPolicy||t.sandboxPolicy):null,l=this.agents.get(s),d=this.targetFor(t.targetCode||t.framework||l?.targetCode);if(l&&l.targetCode!==d.code)throw Object.assign(new Error(`runtime agent target conflict: ${s}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});if(K(d.target)==="cli"&&po(t.goalContract))throw Object.assign(new Error("CLI runtimes do not support per-run dynamic MCP required by plugin_operation"),{code:"unsupported_dynamic_mcp"});let f=l||(await this.createAgent({agentId:s,targetCode:d.code,framework:t.framework,workspace:t.workspace,metadata:t.metadata})).agent;if(!this.config.sandboxRequired){let T=a(t.workspace);T&&T!==f.workspace&&(f.workspace=T)}let p=`${s}:${i}`;await this.cleanupExpiredSessions();let m=this.sessions.get(p),g=null;if(m&&m.targetCode!==d.code)throw Object.assign(new Error(`runtime session target conflict: ${i}`),{code:"RUNTIME_SESSION_TARGET_CONFLICT"});if(m&&this.config.sandboxRequired&&m.runId!==o)throw Object.assign(new Error(`runtime session cannot be shared across runs: ${i}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});if(!m){if(this.startingSessions.has(p))throw Object.assign(new Error(`runtime session is already starting: ${i}`),{code:"RUNTIME_SESSION_BUSY"});this.startingSessions.add(p);let{code:T,target:R}=d,w;try{await this.reserveTargetSlot(T,R),g=T;let O=this.runtimeFor(f,i,{runId:o,sandboxPolicy:c,source:t.metadata?.source});w=O;let P=n?.mcpServers||t.mcpServers||[],v=await O.sessionNew({cwd:tt(R,f.workspace),mcpServers:P,metadata:u(t.metadata)?t.metadata:{}});if(n&&n.status!=="running")throw Object.assign(new Error("Runtime operation was cancelled before prompt dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"});let N=Date.now();m={agentId:s,sessionId:i,runtime:O,targetCode:T,runtimeKind:K(R),runId:o,sandboxPolicy:c?structuredClone(c):null,runtimeSessionId:a(u(v)?v.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(R),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(R,t.metadata),createdAtMs:N,lastUsedAtMs:N,busy:!1,createdAt:dt()},this.sessions.set(p,m),this.runtimeSessionIndex.set(`${s}:${m.runtimeSessionId}`,m),n?.mcpServers!==P&&n?.mcpServers&&O.refreshMcpServers&&await O.refreshMcpServers(n.mcpServers)}catch(O){throw this.sessions.get(p)?.runtime===w?await this.closeSession(p,"session_start_failed"):await w?.stop("session_start_failed"),g&&(this.releaseTargetSlot(g),g=null),O}finally{this.startingSessions.delete(p)}}if(m.busy){let T=new Error(`runtime session is already running: ${i}`);throw T.code="RUNTIME_SESSION_BUSY",T}m.busy=!0,g&&this.releaseTargetSlot(g),this.notifyCapacityChanged(),m.operationCorrelationId=n?.correlationId||null,m.lastUsedAtMs=Date.now();let y=n?.updates||[],x=T=>{let R=mo(T,i,m);if(y.push(R),n)for(let w of n.listeners)try{w?.(R)}catch(O){h("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(O)})}else r.onUpdate?.(R)},A=T=>{if(!(!n||n.status!=="running"||!u(T))){if(T.status==="failed"){let R=T.error;if(R instanceof Error){this.failOperation(n,R);return}let w=u(R)?R:{},O=Object.assign(new Error(a(w.message||T.message)||"runtime terminal failure"),{code:a(w.code||T.code)||"RUNTIME_TERMINAL_FAILED"});this.failOperation(n,O);return}this.completeOperation(n,this.promptResponse(t,m,i,y,u(T.result)?T.result:{stopReason:"end_turn"}))}};try{let T=tn(t.goalContract),R=Array.isArray(t.prompt)?[...t.prompt]:[];T&&R.unshift({type:"text",text:T,metadata:{source:"orcha_goal_contract"}});let w=u(t.metadata)?t.metadata:{},O=u(w._runtimeBridge)?w._runtimeBridge:{},P=await m.runtime.sessionPrompt({sessionId:m.runtimeSessionId,prompt:R,metadata:w},x,A),v=y,N=null;if(mn({type:m.runtimeKind})&&Po(P,y,O)){N=P;let Y=y.length,at=await m.runtime.sessionPrompt({sessionId:m.runtimeSessionId,prompt:[{type:"text",text:ko()}],metadata:w,_meta:{thinking:"off"}},x,A);P=Lo(N,at),v=y.slice(Y)}let E;try{E=this.promptResponse(t,m,i,y,P,v)}catch(Y){throw N&&Rn(P)?vo(P,v):Y}return N&&(E.result=Do(E.result,N)),n&&this.completeOperation(n,E),E}finally{m.busy=!1,this.notifyCapacityChanged(),m.operationCorrelationId===n?.correlationId&&(m.operationCorrelationId=null),m.lastUsedAtMs=Date.now(),this.promptReleaseAfterPrompt(m,u(t.metadata)?t.metadata:{})&&await this.closeSession(p,"release_after_prompt"),n&&(n.mcpServers=null)}}async updatePolicy(t){if(this.assertDispatchable(),!this.config.sandboxRequired)throw Object.assign(new Error("runtime sandbox policy updates require an enforced sandbox"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"});let r=a(t.agentId),n=a(t.runId),s=a(t.sessionId),i=a(t.correlationId);if(!r||!n||!s||!i)throw Object.assign(new Error("agentId, runId, sessionId and correlationId are required"),{code:"BAD_REQUEST"});let o=W(t.sandboxPolicy),c=this.operations.get(i);if(c&&(c.agentId!==r||c.sessionId!==s||c.identity.runId!==n))throw Object.assign(new Error(`runtime operation policy identity conflict: ${i}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let l=`${r}:${s}`,d=this.sessions.get(l);if(d&&d.runId!==n)throw Object.assign(new Error(`runtime session policy identity conflict: ${s}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});let f=d?.sandboxPolicy||c?.sandboxPolicy;if(!f)throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"});let p=Number(f.policyRevision),m=Number(o.policyRevision);if(m<p)throw Object.assign(new Error("runtime sandbox policy revision is stale"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});if(m===p){if(q(f)!==q(o))throw Object.assign(new Error("runtime sandbox policy revision payload conflicts"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});return{updated:!1,idempotent:!0,policyRevision:p,accessMode:f.accessMode}}let g=sn(f,o);c&&(c.sandboxPolicy=structuredClone(o)),d&&(d.sandboxPolicy=structuredClone(o));let y=!1;return g&&d?.busy===!0&&(await d.runtime.sessionCancel({sessionId:d.runtimeSessionId}),y=await this.closeSession(l,"sandbox_policy_downgrade")),{updated:!0,policyRevision:m,accessMode:o.accessMode,activeCommandCancelled:y,deferredToNextLaunch:!g&&d?.busy===!0}}async cancel(t){let r=a(t.agentId),n=a(t.sessionId),s=a(t.correlationId);if(s){let c=this.operations.get(s);if(!c||c.status!=="running")return{cancelled:!1,correlationId:s,reason:"operation_not_running"};if(c.agentId!==r||c.sessionId!==n)throw Object.assign(new Error(`runtime operation cancellation identity conflict: ${s}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let l=this.sessions.get(`${r}:${n}`);return!l||l.busy!==!0||l.operationCorrelationId!==s?(this.failOperation(c,Object.assign(new Error("Runtime operation cancelled before dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"})),{cancelled:!0,correlationId:s,reason:"cancelled_before_dispatch"}):(await l.runtime.sessionCancel({sessionId:l.runtimeSessionId}),await this.closeSession(`${r}:${n}`,"cancelled"),{cancelled:!0,correlationId:s})}let i=`${r}:${n}`,o=this.sessions.get(i);return o?(await o.runtime.sessionCancel({sessionId:o.runtimeSessionId}),await this.closeSession(i,"cancelled"),{cancelled:!0}):{cancelled:!1}}async dispatch(t,r={}){let n=a(t.agentId),s=a(t.taskId),i=a(t.executionId);if(!n||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let o=a(t.sessionId)||`dispatch-${i||s}`,c=a(t.instructions),l=Eo(t),d=hn(t),{target:f}=this.targetFor(t.targetCode||t.framework),p=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",c?`instructions: ${c}`:"",l?"orchaContext:":"",l,l?"Use orchaContext as the source of truth for upstream outputs, review reports, artifacts, and workflow metadata.":"","Follow the execution protocol in instructions exactly.","When embedding a generated artifact in final Markdown, use the Orcha artifact placeholder as the link target: orcha-artifact://<fieldKey>/<index>.","Example: use  for the first generated image artifact.","Do not use local filesystem paths, file:// URLs, or data: URLs in final Markdown; Orcha replaces artifact placeholders after ingestion.",d?`For decision results, put the raw report between ${_e} and ${Te}.`:"",d?`Then put a JSON object containing _decision between ${ye} and ${Re}.`:"",d?"Do not JSON-escape the report. Keep output out of the CONTROL JSON, and put every protocol marker on its own line.":"",d?`Keep the report within ${fn} Unicode characters so the CONTROL block fits before the output limit.`:"","Return only the final answer required by that protocol.","Do not include process notes, logs, or explanations."].filter(Boolean).join(`
|
|
18
|
+
`)}];return this.prompt({...t,agentId:n,sessionId:o,prompt:p,metadata:So(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=Kt(),c=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||Kt(),l={permissionId:i,agentId:t.agentId,sessionId:c,runtimeSessionId:r,request:u(n)?n:{},status:"pending",createdAt:dt()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:l}}),await new Promise(d=>{let f=_(n?.timeoutMs,this.config.permissionRequestTimeoutMs),p=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:p,resolve:d,permission:l})})}async respondPermission(t){let r=a(t.permissionId),n=this.pendingPermissions.get(r),s=a(t.outcome||"approved")||"approved";return n?(clearTimeout(n.timer),this.pendingPermissions.delete(r),n.resolve({permissionId:r,outcome:s,response:u(t.response)?t.response:{},userId:a(t.userId),metadata:u(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:r,outcome:s}):{accepted:!1,permissionId:r,outcome:s}}health(){return{status:this.config.sandboxRequired&&!this.sandboxCapabilities.dispatchable?"unavailable":"ok",bridgeVersion:Q,startedAt:this.startedAt,agents:[...this.agents.values()].map(t=>({agentId:t.agentId,targetCode:t.targetCode,framework:t.framework,runtimeKind:t.runtimeKind})),sessions:this.sessions.size,pendingPermissions:this.pendingPermissions.size,targets:Object.keys(this.targets),sandboxCapabilities:this.sandboxCapabilities}}};import Ho from"node:http";import $o from"node:https";import{randomBytes as wn}from"node:crypto";var it=1,J=3,Fo=1e4,Vt=class{constructor(t,r={}){this.url=t,this.readyState=0,this.socket=null,this.request=null,this.buffer=Buffer.alloc(0),this.listeners=new Map,this.connectTimeoutMs=Bo(r.connectTimeoutMs,Fo),this.connectTimer=null,this.connect()}addEventListener(t,r){let n=this.listeners.get(t)||new Set;n.add(r),this.listeners.set(t,n)}emit(t,r={}){let n=this.listeners.get(t);if(n)for(let s of n)s(r)}connect(){let t=new URL(this.url),r=t.protocol==="wss:"?$o:Ho,n=wn(16).toString("base64"),s=r.request({protocol:t.protocol==="wss:"?"https:":"http:",hostname:t.hostname,port:t.port||(t.protocol==="wss:"?443:80),path:`${t.pathname}${t.search}`,method:"GET",headers:{Connection:"Upgrade",Upgrade:"websocket","Sec-WebSocket-Key":n,"Sec-WebSocket-Version":"13"}});this.request=s,this.startConnectTimer(s),s.on("upgrade",(i,o,c)=>{if(this.clearConnectTimer(),this.readyState===J){o.destroy();return}this.socket=o,this.readyState=it,o.on("data",l=>this.onData(l)),o.on("close",()=>this.onClose()),o.on("error",l=>{this.readyState!==J&&this.emit("error",{error:l,message:l.message,type:"error"}),this.onClose()}),c?.length&&this.onData(c),this.emit("open")}),s.on("response",i=>{this.clearConnectTimer(),this.emit("error",{message:`websocket upgrade failed: HTTP ${i.statusCode}`,type:"error"}),i.resume(),this.onClose()}),s.on("error",i=>{this.clearConnectTimer(),this.readyState!==J&&this.emit("error",{error:i,message:i.message,type:"error"}),this.onClose()}),s.end()}startConnectTimer(t){this.connectTimeoutMs<=0||(this.connectTimer=setTimeout(()=>{if(this.readyState===it||this.readyState===J)return;let r=`websocket connect timeout after ${this.connectTimeoutMs}ms`;this.emit("error",{message:r,type:"timeout"}),this.onClose(),t.destroy(new Error(r))},this.connectTimeoutMs),this.connectTimer.unref?.())}clearConnectTimer(){this.connectTimer&&(clearTimeout(this.connectTimer),this.connectTimer=null)}send(t){!this.socket||this.readyState!==it||this.socket.write(Ve(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==J){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===it&&this.socket.write(Ve(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==J&&(this.clearConnectTimer(),this.readyState=J,this.request=null,this.emit("close"))}onData(t){for(this.buffer=Buffer.concat([this.buffer,t]);this.buffer.length>=2;){let r=this.buffer[0],n=this.buffer[1],s=r&15,i=(n&128)!==0,o=n&127,c=2;if(o===126){if(this.buffer.length<c+2)return;o=this.buffer.readUInt16BE(c),c+=2}else if(o===127){if(this.buffer.length<c+8)return;let f=this.buffer.readUInt32BE(c),p=this.buffer.readUInt32BE(c+4);o=f*2**32+p,c+=8}let l=c;if(i&&(c+=4),this.buffer.length<c+o)return;let d=this.buffer.subarray(c,c+o);if(i){let f=this.buffer.subarray(l,l+4);d=Buffer.from(d.map((p,m)=>p^f[m%4]))}this.buffer=this.buffer.subarray(c+o),s===1?this.emit("message",{data:d.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(Ve(10,d))}}};function Bo(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function Ve(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=wn(4),i=Buffer.alloc(n+4+r);i[0]=128|e;let o=2;r<126?i[1]=128|r:r<=65535?(i[1]=254,i.writeUInt16BE(r,o),o+=2):(i[1]=255,i.writeUInt32BE(Math.floor(r/2**32),o),i.writeUInt32BE(r>>>0,o+4),o+=8),s.copy(i,o),o+=4;for(let c=0;c<r;c+=1)i[o+c]=t[c]^s[c%4];return i}function qo(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 jo(e,t=!0){return Object.entries(e||{}).map(([r,n])=>({targetCode:r,targetName:a(n?.name||n?.targetName||r),targetType:a(n?.type||"echo"),status:t?"available":"unavailable"}))}var We=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),Wt=class{constructor(t,r){this.config=t,this.bridge=r,this.ws=null,this.stopped=!1,this.connected=!1,this.reconnectTimer=null,this.heartbeatTimer=null,this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=()=>this.scheduleCapacityHeartbeat()}sandboxCapabilities(){return this.bridge.sandboxCapabilities||{dispatchable:this.config.sandboxRequired!==!0,enforced:!1,backend:"development_direct",daemonStatus:"development_only",policySchemaVersions:[1],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:!1}}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):jo(this.config.targets,t)}start(){this.connect()}stop(){this.stopped=!0,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=null,this.ws?.close()}connect(){if(this.stopped)return;let t=qo(this.config.orchaUrl),r=new Vt(t,{connectTimeoutMs:this.config.connectTimeoutMs});this.ws=r,r.addEventListener("open",()=>{if(this.ws!==r||this.stopped){r.close();return}this.authenticate(r)}),r.addEventListener("message",n=>this.handleMessage(n.data,r)),r.addEventListener("close",()=>this.scheduleReconnect("close",r)),r.addEventListener("error",n=>{h("warn","orcha-client","runtime node websocket error",{error:String(n?.message||n?.type||n)})})}authenticate(t=this.ws){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:Q,protocolVersion:"orcha-runtime-node.v1",defaultTargetCode:this.config.defaultTargetCode,supportedMethods:We,sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t)}scheduleReconnect(t,r=this.ws){r&&this.ws!==r||(this.connected=!1,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,r&&this.ws===r&&(this.ws=null),!this.stopped&&(this.reconnectTimer||(h("info","orcha-client","runtime node disconnected; reconnect scheduled",{reason:t,reconnectMs:this.config.reconnectMs}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.config.reconnectMs))))}async handleMessage(t,r=this.ws){if(r&&this.ws!==r)return;let n;try{n=JSON.parse(String(t))}catch(s){h("warn","orcha-client","invalid Orcha websocket frame",{error:String(s)});return}if(u(n)){if(n.type==="runtime_node.authenticated"){if(r&&this.ws!==r)return;this.connected=!0,this.startHeartbeat(r),h("info","orcha-client","runtime node authenticated",{nodeId:this.config.nodeId,connectionId:n.connectionId});return}if(n.type==="orcha.runtime.request"){await this.handleRequest(n);return}n.type==="runtime_node.ping"&&this.send({type:"runtime_node.pong",ts:new Date().toISOString(),supportedMethods:We,sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()})}}startHeartbeat(t){this.heartbeatTimer&&clearInterval(this.heartbeatTimer);let r=Math.max(1e3,Number(this.config.heartbeatIntervalMs||15e3)),n=()=>this.sendCapacityHeartbeat(t);n(),this.heartbeatTimer=setInterval(n,r),this.heartbeatTimer.unref?.()}scheduleCapacityHeartbeat(){if(!this.connected||this.capacityHeartbeatTimer)return;let t=Math.max(25,Math.min(1e3,Number(this.config.capacityHeartbeatDebounceMs||100)));this.capacityHeartbeatTimer=setTimeout(()=>{this.capacityHeartbeatTimer=null,this.sendCapacityHeartbeat()},t),this.capacityHeartbeatTimer.unref?.()}sendCapacityHeartbeat(t=this.ws){return this.connected?this.send({type:"runtime_node.heartbeat",ts:new Date().toISOString(),supportedMethods:We,sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t):!1}async handleRequest(t){let r=a(t.id),n=a(t.method),s=u(t.params)?t.params:{};try{let i=await this.invoke(n,s,r);this.send({type:"orcha.runtime.response",id:r,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:r,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i),...i.detail===void 0?{}:{detail:i.detail}}})}}async invoke(t,r,n){if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(r);if(t==="agents/dispatch")return this.bridge.dispatch(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/prompt")return this.bridge.prompt(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/policy")return this.bridge.updatePolicy(r);if(t==="sessions/cancel")return this.bridge.cancel(r);if(t==="permissions/respond")return this.bridge.respondPermission(r);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,r){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:r})}send(t,r=this.ws){return!r||r!==this.ws||r.readyState!==it?!1:(r.send(JSON.stringify(t)),!0)}};import{existsSync as Sn,readFileSync as Ko}from"node:fs";import{dirname as Go,resolve as Jt}from"node:path";import{fileURLToPath as zo}from"node:url";var Vo=/^[A-Za-z_][A-Za-z0-9_]*$/;function En(e=process.env,t=process.cwd()){let r=a(e.ORCHA_RUNTIME_ENV_FILE),n=r?Jt(t,r):Jt(t,".env");if(!Sn(n))return r&&h("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Ko(n,"utf8");for(let o of i.split(/\r?\n/)){let c=Xo(o);if(!c)continue;let[l,d]=c;Object.prototype.hasOwnProperty.call(e,l)||(e[l]=d,s.push(l))}return h("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function On(e=process.env){let t=a(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),r=a(e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1"),n=!1,s=Go(zo(import.meta.url)),i=Jt(s,"sandbox","broker.js"),o=Jt(s,"orcha-runtime-sandbox-broker.js"),c=Sn(i)?i:o,l=a(e.ORCHA_RUNTIME_SANDBOX_BROKER_COMMAND);return{mode:t,host:r,port:_(e.ORCHA_RUNTIME_BRIDGE_PORT,5588),token:e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",orchaUrl:a(e.ORCHA_RUNTIME_ORCHA_URL),nodeToken:e.ORCHA_RUNTIME_NODE_TOKEN||e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",nodeId:a(e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"local-runtime-node"),nodeName:a(e.ORCHA_RUNTIME_NODE_NAME||e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"Local Runtime Node"),reconnectMs:_(e.ORCHA_RUNTIME_RECONNECT_MS,3e3),connectTimeoutMs:_(e.ORCHA_RUNTIME_CONNECT_TIMEOUT_MS||e.ORCHA_RUNTIME_WS_CONNECT_TIMEOUT_MS,1e4),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:_(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),initializeTimeoutMs:_(e.ORCHA_RUNTIME_INITIALIZE_TIMEOUT_MS,3e4),sessionPromptTimeoutMs:_(e.ORCHA_RUNTIME_SESSION_PROMPT_TIMEOUT_MS,36e5),permissionRequestTimeoutMs:_(e.ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS,3e5),sessionIdleTtlMs:_(e.ORCHA_RUNTIME_SESSION_IDLE_TTL_MS,6e5),sessionCleanupIntervalMs:_(e.ORCHA_RUNTIME_SESSION_CLEANUP_INTERVAL_MS,6e4),maxSessionsPerTarget:_(e.ORCHA_RUNTIME_MAX_SESSIONS_PER_TARGET,8),openClawSessionIdleTtlMs:_(e.ORCHA_RUNTIME_OPENCLAW_SESSION_IDLE_TTL_MS,6e4),openClawMaxSessions:_(e.ORCHA_RUNTIME_OPENCLAW_MAX_SESSIONS,1),heartbeatIntervalMs:_(e.ORCHA_RUNTIME_HEARTBEAT_INTERVAL_MS,15e3),sandboxRequired:n,sandboxBrokerCommand:l||process.execPath,sandboxBrokerArguments:Je(e.ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS,"ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS",l?[]:[c]),sandboxProbeTimeoutMs:_(e.ORCHA_RUNTIME_SANDBOX_PROBE_TIMEOUT_MS,1e4),sandboxTempRoot:a(e.ORCHA_RUNTIME_SANDBOX_TEMP_ROOT),trustedWorkspaceRoots:Je(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:Je(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:Jo(e.ORCHA_RUNTIME_EGRESS_PROXY_REQUIRED,t==="node"),egressProxySocket:a(e.ORCHA_RUNTIME_EGRESS_PROXY_SOCKET),egressProxyToken:a(e.ORCHA_RUNTIME_EGRESS_PROXY_TOKEN),egressGrantMaxTtlMs:_(e.ORCHA_RUNTIME_EGRESS_GRANT_MAX_TTL_MS,9e5),targets:Wo(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Wo(e){if(!a(e))return{};try{let t=JSON.parse(e);if(u(t))return t}catch(t){h("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function Jo(e,t){let r=a(e).toLowerCase();if(!r)return t;if(["true","1","yes","on"].includes(r))return!0;if(["false","0","no","off"].includes(r))return!1;throw new Error(`invalid boolean configuration value: ${r}`)}function Je(e,t,r=[]){let n=a(e);if(!n)return[...r];let s;try{s=JSON.parse(n)}catch{throw new Error(`${t} must be a JSON string array`)}if(!Array.isArray(s)||s.some(i=>typeof i!="string"))throw new Error(`${t} must be a JSON string array`);return s.map(i=>i.trim()).filter(Boolean)}function Xo(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(!Vo.test(s))return null;let i=Yo(r.slice(n+1).trim());return[s,i]}function Yo(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?Zo(r):r}return Qo(e).trim()}function Zo(e){return e.replaceAll("\\n",`
|
|
19
|
+
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function Qo(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 ta}from"node:http";function Xt(e,t,r){let n=JSON.stringify(r);e.writeHead(t,{"content-type":"application/json; charset=utf-8","content-length":Buffer.byteLength(n)}),e.end(n)}function X(e={}){return{ok:!0,...e}}function Xe(e,t,r){return{ok:!1,error:{code:e,message:t,...r===void 0?{}:{detail:r}}}}async function In(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 xn(e,t){if(!t)return;if((e.headers.authorization||"")!==`Bearer ${t}`)throw Object.assign(new Error("runtime bridge token is invalid"),{status:401,code:"UNAUTHORIZED"})}function Cn(e,t){let r={"GET /health":async()=>X(t.health()),"POST /agents/create":async n=>X(await t.createAgent(n)),"POST /agents/dispatch":async n=>X(await t.dispatch(n)),"POST /sessions/prompt":async n=>X(await t.prompt(n)),"POST /sessions/cancel":async n=>X(await t.cancel(n)),"POST /permissions/respond":async n=>X(await t.respondPermission(n))};return ta(async(n,s)=>{let i=new URL(n.url||"/",`http://${n.headers.host||`${e.host}:${e.port}`}`),o=`${n.method||"GET"} ${i.pathname}`,c=r[o];if(!c){Xt(s,404,Xe("NOT_FOUND",`No route for ${o}`));return}try{xn(n,e.token);let l=n.method==="GET"?{}:await In(n,e.requestLimitBytes);Xt(s,200,await c(l))}catch(l){let d=l.status||500,f=l.code||"BRIDGE_INTERNAL";Xt(s,d,Xe(f,l.message||String(l),l.detail))}})}var ca=aa(import.meta.url),ua=".orcha-runtime-bridge.pid",la=".orcha-runtime-bridge.log",da=3,fa=36e5,{command:pa,options:vn}=_a(process.argv.slice(2));Ta(vn);En();var ma=On();await ha(pa,ma,vn);async function ha(e,t,r){switch(e){case"run":case"foreground":await An(t);return;case"start":if(r.foreground){await An(t);return}Mn();return;case"reload":case"restart":await Un({quiet:!0}),Mn();return;case"stop":await Un();return;case"status":ga();return;case"help":case"--help":case"-h":Sa();return;default:throw new Error(`Unknown command: ${e}`)}}async function An(e){ya();let t=new zt(e);if(await t.start(),e.mode==="server"){let n=Cn(e,t);Nn({bridge:t,server:n}),n.listen(e.port,e.host,()=>{h("info","runtime-bridge","Orcha runtime bridge HTTP server started",{host:e.host,port:e.port,targets:Object.keys(t.targets)})});return}if(!e.orchaUrl)throw new Error("ORCHA_RUNTIME_ORCHA_URL is required in runtime node mode");let r=new Wt(e,t);Nn({bridge:t,client:r}),r.start(),h("info","runtime-bridge","Orcha runtime node started",{nodeId:e.nodeId,nodeName:e.nodeName,orchaUrl:e.orchaUrl,targets:Object.keys(t.targets)})}function Nn({bridge:e,client:t,server:r}){let n=!1,s=i=>{if(n)return;n=!0;let o=Number(e?.sessions?.size||0)>0;h("info","runtime-bridge","runtime bridge shutting down",{signal:i});try{t?.stop?.()}catch(c){h("warn","runtime-bridge","runtime client stop failed",{error:String(c)})}Promise.resolve(e?.stop?.(`process_${String(i||"shutdown").toLowerCase()}`)).catch(c=>{h("warn","runtime-bridge","runtime bridge stop failed",{error:String(c)})}).finally(()=>{try{r?.close?.()}catch(c){h("warn","runtime-bridge","runtime server close failed",{error:String(c)})}}),setTimeout(()=>process.exit(0),o?8500:200)};process.once("SIGTERM",()=>s("SIGTERM")),process.once("SIGINT",()=>s("SIGINT"))}function Mn(){let e=er(),t=Hn(),r=rr(e);if(r&&ot(r)){console.log(JSON.stringify({status:"already_running",pid:r,pidFile:e,logFile:t}));return}r&&Qe(e),kn(e),kn(t),Ze(t);let n=sa(t,"a"),s={...process.env,ORCHA_RUNTIME_PID_FILE:e,ORCHA_RUNTIME_LOG_FILE:t},i=ea(process.execPath,[ca,"run"],{cwd:process.cwd(),detached:!0,env:s,stdio:["ignore",n,n]});i.unref(),ra(n),Dn(e,`${i.pid}
|
|
20
|
+
`),console.log(JSON.stringify({status:"started",pid:i.pid,pidFile:e,logFile:t}))}async function Un({quiet:e=!1}={}){let t=er(),r=rr(t);if(!r){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!ot(r)){Qe(t),e||console.log(JSON.stringify({status:"not_running",pid:r,pidFile:t}));return}process.kill(r,"SIGTERM"),!await Pn(r,1e4)&&ot(r)&&(process.kill(r,"SIGKILL"),await Pn(r,3e3)),Qe(t),e||console.log(JSON.stringify({status:"stopped",pid:r,pidFile:t}))}function ga(){let e=er(),t=Hn(),r=rr(e),n=!!(r&&ot(r));console.log(JSON.stringify({status:n?"running":"not_running",running:n,pid:n?r:null,pidFile:e,logFile:t}))}function _a(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 Ta(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 er(){return tr(process.cwd(),process.env.ORCHA_RUNTIME_PID_FILE||ua)}function Hn(){return tr(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||la)}function ya(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=$n();if(t<=0)return;let r=tr(process.cwd(),e);Ze(r,t);let n=wa();n<=0||setInterval(()=>Ze(r,t),n).unref()}function Ze(e,t=$n()){if(t<=0||!Ln(e))return;let r=0,n="";try{if(r=bn(e).size,r<=0)return;n=Ye(e,"utf8")}catch(d){h("warn","runtime-bridge","runtime log cleanup skipped",{logFile:e,error:String(d)});return}let s=Date.now()-t*24*60*60*1e3,i=n.split(/\r?\n/),o=[],c=0;for(let d of i)d&&(Ra(d,s)?o.push(d):c+=1);if(c===0)return;let l="";try{bn(e).size>r&&(l=Ye(e,"utf8").slice(n.length));let f=[...o,...l.split(/\r?\n/).filter(Boolean)].join(`
|
|
21
|
+
`);Dn(e,f?`${f}
|
|
22
|
+
`:""),h("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:c})}catch(d){h("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function Ra(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 $n(){return Fn(process.env.ORCHA_RUNTIME_LOG_RETENTION_DAYS,da)}function wa(){return Fn(process.env.ORCHA_RUNTIME_LOG_CLEANUP_INTERVAL_MS,fa)}function Fn(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function rr(e){if(!Ln(e))return null;let t=Number.parseInt(Ye(e,"utf8").trim(),10);return Number.isInteger(t)&&t>0?t:null}function ot(e){try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function Pn(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!ot(e))return!0;await new Promise(n=>setTimeout(n,100))}return!ot(e)}function kn(e){na(oa(e),{recursive:!0})}function Qe(e){try{ia(e,{force:!0})}catch{}}function Sa(){console.log(`Usage: orcha-runtime-bridge [command] [options]
|
|
23
23
|
|
|
24
24
|
Commands:
|
|
25
25
|
run, foreground Run in the foreground. This is the default.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var f=["find_capabilities","describe_capability","execute_capability","inspect_result"],M=8*1024*1024;function _(s,a){if(!Array.isArray(s)||s.length!==1)throw new Error("one task-scoped Orcha MCP server is required");let o=s[0],e=new URL(o.url);if(o.name!=="orcha"||o.type!=="http"||!["http:","https:"].includes(e.protocol)||e.username||e.password||e.hash||a&&e.href!==new URL(a).href)throw new Error("Orcha MCP server does not match the trusted binding");let c=Object.fromEntries((o.headers||[]).map(({name:r,value:t})=>[r.toLowerCase(),t]));if(!String(c.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:e.href,headers:{...c,"content-type":"application/json",accept:"application/json"}}}async function g(s){let a=0,o=[];for await(let e of s){if(a+=e.length,a>M)throw new Error("MCP payload exceeds the size limit");o.push(Buffer.from(e))}return JSON.parse(Buffer.concat(o).toString("utf8"))}async function y(s,a,o){let e=await fetch(s.url,{method:"POST",headers:s.headers,body:JSON.stringify(a),redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(36e5),...o?[o]:[]])});if(!e.ok)throw new Error(`Orcha MCP request failed (${e.status})`);if(e.status===202||e.status===204)return null;let c=await g(e.body);if(!c||c.jsonrpc!=="2.0"||c.id!==a.id)throw new Error("Orcha MCP response identity mismatch");return c}async function E(s,a){let o=await y(s,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},a),e=o?.result?.tools;if(o?.error||!Array.isArray(e)||e.length!==f.length||f.some(c=>!e.some(r=>r.name===c&&r.inputSchema?.type==="object")))throw new Error("Orcha MCP did not expose its four authorized control tools");return e}var P={id:"orcha-runtime",name:"Orcha group member tools",register(s){let a=new Map,o=s.pluginConfig?.allowedOrchaMcpUrl;if(!o)throw new Error("Orcha plugin requires allowedOrchaMcpUrl");function e(r){let t=a.get(r);return t&&t.deadline<=Date.now()?(c(r,t),null):t}function c(r,t){a.get(r)===t&&(t.lifetime.abort(),clearTimeout(t.timer),a.delete(r))}s.registerHttpRoute({path:"/plugins/orcha-runtime/mcp-bindings",auth:"gateway",match:"exact",async handler(r,t){let i=(u,d)=>{t.writeHead(u,{"content-type":"application/json"}),t.end(JSON.stringify(d))};try{if(r.method==="GET"){i(200,{ready:!0});return}if(!["PUT","DELETE"].includes(r.method)){i(405,{error:"method_not_allowed"});return}let u=await g(r),{runId:d,sessionKey:l}=u;if(typeof d!="string"||!d||typeof l!="string"||!l){i(422,{error:"invalid_binding_identity"});return}let n=e(l);if(n&&n.runId!==d){i(409,{error:"session_already_bound"});return}if(r.method==="DELETE"){n&&c(l,n),i(200,{released:!0});return}let{agentCode:p,expiresAt:S,mcpServer:C}=u,h=Date.parse(S);if(typeof p!="string"||!p||!l.startsWith(`agent:${p}:`)||!Number.isFinite(h)||h<=Date.now()||h>Date.now()+24*36e5){i(422,{error:"invalid_binding_scope"});return}if(r.headers["if-match"]&&(!n||r.headers["if-match"]!==d)||n&&(n.agentCode!==p||n.deadline!==h)){i(409,{error:"original_binding_unavailable_or_changed"});return}let w=_([C],o),b=n?.lifetime||new AbortController,O=await E(w,b.signal);if(e(l)!==n){i(409,{error:"binding_changed"});return}if(n)n.upstream=w,n.tools=O;else{let m={runId:d,agentCode:p,deadline:h,upstream:w,tools:O,lifetime:b};m.timer=setTimeout(()=>c(l,m),h-Date.now()),m.timer.unref?.(),a.set(l,m)}i(200,{bound:!0})}catch{i(422,{error:"orcha_mcp_binding_failed"})}}}),s.registerTool(r=>{let t=e(r.sessionKey);return!t||r.agentId!==t.agentCode?null:t.tools.map(i=>({name:`orcha_${i.name}`,label:`Orcha ${i.name}`,description:i.description,parameters:i.inputSchema,async execute(u,d,l){if(e(r.sessionKey)!==t||r.agentId!==t.agentCode||!u)throw new Error("Orcha task binding expired or changed");let n=await y(t.upstream,{jsonrpc:"2.0",id:u,method:"tools/call",params:{name:i.name,arguments:d}},AbortSignal.any([t.lifetime.signal,...l?[l]:[]]));if(n?.error||!n?.result)throw new Error("Orcha rejected this task-scoped tool call");return{content:n.result.content,details:n.result.structuredContent,isError:n.result.isError===!0}}}))},{names:f.map(r=>`orcha_${r}`)})}};export{P as default};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "orcha-runtime",
|
|
3
|
+
"name": "Orcha group member tools",
|
|
4
|
+
"description": "Task-scoped Orcha tools bound to trusted OpenClaw sessions",
|
|
5
|
+
"categories": ["developer-tools"],
|
|
6
|
+
"contracts": { "tools": ["orcha_find_capabilities", "orcha_describe_capability", "orcha_execute_capability", "orcha_inspect_result"] },
|
|
7
|
+
"activation": { "onStartup": true },
|
|
8
|
+
"configSchema": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"required": ["allowedOrchaMcpUrl"],
|
|
12
|
+
"properties": { "allowedOrchaMcpUrl": { "type": "string", "minLength": 1 } }
|
|
13
|
+
}
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orcha-ai/runtime-bridge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.37",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Local Orcha runtime bridge for ACP-compatible agent runtimes.",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
13
|
"bin",
|
|
14
|
+
"openclaw-plugin",
|
|
14
15
|
"README.md",
|
|
15
16
|
".env.example"
|
|
16
17
|
],
|