@orcha-ai/runtime-bridge 0.1.49 → 0.1.51
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 +15 -1
- package/bin/orcha-runtime-bridge.js +20 -20
- package/openclaw-plugin/index.js +6 -5
- package/openclaw-plugin/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -80,7 +80,7 @@ Version 0.1.44 routes replies, native `message` tool sends, and background notif
|
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
82
|
npm run pack:local
|
|
83
|
-
npm publish ./dist/orcha-ai-runtime-bridge-0.1.
|
|
83
|
+
npm publish ./dist/orcha-ai-runtime-bridge-0.1.51.tgz --access public --registry=https://registry.npmjs.org
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
After updating the npm package on a device, run `orcha-runtime-bridge reload --url ...` to switch the existing background process to the installed version. `reload` and `restart` also install/update the bundled plugin for OpenClaw targets saved on that device, using the target's executable and environment. Bridge stops before `openclaw plugins install <bundled-path> --force` and `openclaw gateway restart`; it starts again only after Gateway health succeeds and any configured MCP binding endpoint passes native Channel protocol preflight. Targets sharing an executable and environment update together. Installation/restart/health failures stop the command with an error and leave Bridge stopped; fix the reported problem and rerun `reload`. Package/executable preflight failures leave the existing Bridge running. The earlier manually downloaded foreground process must be stopped before connecting with npm to avoid duplicate connections.
|
|
@@ -97,6 +97,8 @@ To check reply classification against the real SDK without installing or startin
|
|
|
97
97
|
|
|
98
98
|
The OpenClaw channel sets the host's `suppressToolErrorWarnings` reply option to prevent synthesized tool-error warnings from becoming extra chat messages. Tool failures remain in the execution progress, and terminal error replies, delivery failures, timeouts, and empty-result checks keep their existing handling. Update the bundled plugin on the OpenClaw host and restart its Gateway for this change to take effect; publishing npm or deploying Core alone does not update an installed Gateway plugin.
|
|
99
99
|
|
|
100
|
+
Version 0.1.50 honors a terminal `NO_REPLY` after a confirmed message-tool delivery to the same conversation. It observes the active native session's visible assistant terminal through the host's synchronous `before_message_write` hook and official silent-reply classifier, preventing accumulated pre-tool text from becoming an extra final message. Normal follow-up replies, terminal errors, failed sends and other conversation targets retain their existing behavior. It does not read hidden reasoning or change protocol, persisted data or environment configuration. Update the installed plugin and restart Gateway after upgrading the package.
|
|
101
|
+
|
|
100
102
|
Native reply previews use the host's `onPartialReply` callback. Growing snapshots emit `agent_message_chunk`; revised or cleared snapshots emit `agent_message_snapshot` with the complete preview in `content.text`, projected by Core as the existing `message_replace` event. Assistant message boundaries separate preview paragraphs. Block streaming is disabled so previews cannot consume final IM delivery. The final Bridge result remains a delivery receipt; only the IM sender persists the actual reply and attachments. This event addition requires the updated Core, Bridge and bundled plugin together; protocol version numbers are unchanged, with no database migration or new environment variable. Existing installed plugins need an explicit update and Gateway restart.
|
|
101
103
|
|
|
102
104
|
Version 0.1.48 includes these native reply previews. Deploy Core with commit `3c165340` or later before upgrading connected devices, then reload Bridge to update its bundled Gateway plugin.
|
|
@@ -123,6 +125,18 @@ Old Orcha history and per-run native sessions are not migrated or injected. Upgr
|
|
|
123
125
|
|
|
124
126
|
Codex supports task-scoped Orcha MCP through the existing local transport adapter. OpenClaw additionally requires the bundled Gateway plugin, a trusted binding endpoint and Gateway authentication. Discovery/import does not install the plugin or configure these credentials. Claude Code's delegated dynamic MCP adapter remains unsupported and returns an explicit error.
|
|
125
127
|
|
|
128
|
+
### Codex file delivery (0.1.51)
|
|
129
|
+
|
|
130
|
+
Codex conversation and delegated turns expose `orcha.send_file({path, message?})` through that turn's local MCP proxy. The tool reads the selected file on the device, uploads it to `POST /api/mcp/orcha/files`, and returns the saved attachment's string `fileId` and `messageId`. Core binds the destination and sender to the signed active run; the model cannot choose another conversation. This uses the same attachment-message persistence as OpenClaw. It does not complete the run or replace the final reply.
|
|
131
|
+
|
|
132
|
+
Paths must resolve inside the selected workspace, configured artifact roots, or the exact current Codex thread's `generated_images` directory. Other deliverables must first be copied into the workspace. Empty files, non-regular files and files over 32 MiB are rejected locally; Core also enforces its existing `agent_runtime_artifact_max_bytes` limit (20 MiB by default). Same-run retries of the same file and caption reuse the receipt, including after credential refresh; a finished run or expired delegated lease cannot send. Uploaded file retention, group-member access, realtime notification and transaction rollback reuse the existing attachment lifecycle. Local paths and MCP credentials are not included in attachment messages.
|
|
133
|
+
|
|
134
|
+
For these tool-enabled turns, legacy image-generation events no longer publish images automatically: viewing an image, embedding a local Markdown path or inspecting an intermediate result does not deliver it. Other CLI/workflow paths retain their existing artifact collector. Use `send_file` for each intended deliverable, and treat only a successful saved receipt as delivery confirmation.
|
|
135
|
+
|
|
136
|
+
Rollout requires the updated Core endpoint, then an updated and reloaded device Bridge. There is no database migration, protocol-version change or new project environment variable. This source change has not been published to npm or deployed; historical empty attachment messages are not backfilled.
|
|
137
|
+
|
|
138
|
+
Acceptance on 2026-10-02: Bridge checks/tests/build and the PostgreSQL/Redis file/channel/MCP tests pass. The opt-in installed-Codex test now checks discovery plus an actual file upload to an isolated local fixture. With local `codex-cli 0.153.4`, discovery and `send_file` both stop before invocation with `MCP tool call requires approval, but approval policy is never`. End-to-end model delivery remains unverified, so local service restart was skipped under the repository's failed-validation rule. No host approval policy was changed. Resolve the device's approved MCP policy or implement a supported approval interaction before production acceptance; do not treat this as successful delivery. Codex supports server/tool approval settings in its [official configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference).
|
|
139
|
+
|
|
126
140
|
For OpenClaw, install the built plugin, set `plugins.entries.orcha-runtime.enabled` to `true` and its `config.allowedOrchaMcpUrl` to the Orcha MCP URL. Preserve existing plugins and allowlists, permit the `orcha_` tools for the local Agent, then follow the host version's plugin reload procedure:
|
|
127
141
|
|
|
128
142
|
```bash
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{spawn as fc}from"node:child_process";import{closeSync as pc,existsSync as Rr,mkdirSync as hc,openSync as mc,readFileSync as yr,rmSync as gc,statSync as ls,writeFileSync as ms}from"node:fs";import{dirname as gs,resolve as mt}from"node:path";import{fileURLToPath as _c}from"node:url";import{createHash as Pr}from"node:crypto";import{mkdir as Ms,readFile as Us,writeFile as Ps,rename as Ls}from"node:fs/promises";import{join as Mr}from"node:path";import{homedir as ks,hostname as vs}from"node:os";import{execFile as Is}from"node:child_process";import{access as Cs,realpath as xs}from"node:fs/promises";import{constants as As}from"node:fs";import{delimiter as Ns,join as Ar,isAbsolute as Nr}from"node:path";import{homedir as xr}from"node:os";async function he(e,t=process.env){let r=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let n of(t.PATH||"").split(Ns).filter(Nr))for(let s of r){let i=Ar(n,`${e}${s}`);try{return await Cs(i,As.X_OK),i}catch{}}return null}function bs(e,t){return new Promise(r=>Is(e,t,{timeout:8e3,maxBuffer:1024*1024,windowsHide:!0},(n,s)=>r({code:n?n.code:0,stdout:String(s||"")})))}async function me(e){let t=e==="~"?xr():e.startsWith("~/")?Ar(xr(),e.slice(2)):e;if(!Nr(t))throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u5FC5\u987B\u662F\u8BBE\u5907\u4E0A\u7684\u7EDD\u5BF9\u8DEF\u5F84\u6216 ~/ \u5F00\u5934\u7684\u8DEF\u5F84");let r=await xs(t),{stat:n}=await import("node:fs/promises");if(!(await n(r)).isDirectory())throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u662F\u6587\u4EF6\u5939");return r}async function br({find:e=he,run:t=bs,cwd:r=process.cwd()}={}){return(await Promise.all(["codex","claude","openclaw"].map(async s=>{let i=await e(s);if(!i)return[];let o={codex:"Codex",claude:"Claude Code",openclaw:"OpenClaw"}[s],a=await t(i,["--version"]),u=a.code===0&&a.stdout.match(/\d+\.\d+\.\d+[^\s]*/)?.[0]||"",d={id:s,name:o,framework:s,version:u,workspace:r,managed:!1};if(a.code!==0)return[{...d,status:"error",message:"\u7A0B\u5E8F\u65E0\u6CD5\u542F\u52A8\uFF0C\u8BF7\u5728\u672C\u673A\u68C0\u67E5\u5B89\u88C5"}];if(s==="openclaw"){let h=await t(i,["agents","list","--json"]),m;try{m=JSON.parse(h.stdout)}catch{}if(h.code!==0||!Array.isArray(m))return[{...d,status:"error",message:"\u65E0\u6CD5\u8BFB\u53D6 OpenClaw \u667A\u80FD\u4F53\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u914D\u7F6E"}];let T=await t(i,["health","--json"]);return m.filter(S=>typeof S.id=="string"&&typeof S.workspace=="string").slice(0,32).map(S=>({...d,id:`openclaw:${S.id}`,name:S.name||S.identityName||S.id,workspace:S.workspace,managed:!0,localAgentId:S.id,command:i,status:T.code===0?"ready":"needs_setup",message:T.code===0?"":"\u8BF7\u5148\u5728\u672C\u673A\u542F\u52A8\u5E76\u914D\u7F6E OpenClaw Gateway"}))}let f=await t(i,s==="codex"?["login","status"]:["auth","status"]),p=f.code===0?"ready":f.code===1?"needs_login":"error";return[{...d,command:i,status:p,message:p==="needs_login"?`\u8BF7\u5728\u672C\u673A\u8FD0\u884C ${s} ${s==="codex"?"login":"auth login"}`:p==="error"?"\u767B\u5F55\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C":""}]}))).flat()}async function Ur(e,t){let r=`${e}.${process.pid}.tmp`;await Ps(r,JSON.stringify(t),{mode:384}),await Ls(r,e)}function _e(e){let t=new URL(e);if(t.username||t.password||t.search||t.hash||t.protocol!=="https:"&&!(t.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(t.hostname)))throw new Error("\u8FDE\u63A5\u5730\u5740\u5FC5\u987B\u4F7F\u7528 HTTPS\uFF1B\u4EC5\u672C\u673A\u5F00\u53D1\u5141\u8BB8 HTTP");let r=Mr(ks(),".orcha","devices"),n=Mr(r,Pr("sha256").update(t.toString()).digest("hex").slice(0,20));return{address:t,root:r,profile:`${n}.json`,pidFile:`${n}.pid`,logFile:`${n}.log`}}async function Mt(e,{url:t,pairCode:r}){let{address:n,root:s,profile:i}=_e(t||e.orchaUrl);await Ms(s,{recursive:!0,mode:448});let o;if(r){let a=await fetch(new URL("api/agent-devices/pairings/exchange",`${n.toString().replace(/\/+$/,"")}/`),{method:"POST",redirect:"error",headers:{"content-type":"application/json"},signal:AbortSignal.timeout(15e3),body:JSON.stringify({code:r,name:vs()})}),u=await a.json();if(!a.ok||!u.success)throw new Error(u.message||u.detail||"\u8BBE\u5907\u8FDE\u63A5\u5931\u8D25");o={...u.data,targets:{}},await Ur(i,o)}else try{o=JSON.parse(await Us(i,"utf8"))}catch{throw new Error("\u6CA1\u6709\u5DF2\u8FDE\u63A5\u8BBE\u5907\uFF0C\u8BF7\u4ECE\u667A\u80FD\u4F53\u9875\u9762\u751F\u6210\u8FDE\u63A5\u7801")}e.orchaUrl=n.toString().replace(/\/+$/,""),e.mode="node",e.nodeId=o.nodeCode,e.nodeName=o.nodeName,e.nodeToken=o.token,e.targets=o.targets,e.defaultTargetCode="",e.deviceConnection=new ge(e,o,async()=>Ur(i,o))}var ge=class{constructor(t,r,n,s=br){this.config=t,this.profile=r,this.persist=n,this.discover=s}async candidates(){return{candidates:(await this.discover()).map(({command:r,localAgentId:n,...s})=>s)}}async configure(t,r){if(!Array.isArray(t.selections)||!t.selections.length||t.selections.length>32)throw new Error("\u6DFB\u52A0\u9879\u65E0\u6548");let n=new Map((await this.discover()).map(u=>[u.id,u])),s={...r.targets},i=[],o=new Set;for(let u of t.selections){let d=n.get(u.candidateId);if(!d||d.status!=="ready"||o.has(d.id))throw new Error("\u53D1\u73B0\u7ED3\u679C\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u6D4B");o.add(d.id);let f=String(u.name||"").trim();if(!f||f.length>128)throw new Error("\u667A\u80FD\u4F53\u540D\u79F0\u65E0\u6548");let p=await me(String(u.workspace||""));if(d.managed&&p!==await me(d.workspace))throw new Error("\u5DF2\u6709\u667A\u80FD\u4F53\u5FC5\u987B\u6CBF\u7528\u672C\u673A\u5DE5\u4F5C\u76EE\u5F55");let h=`${this.config.nodeId}:${Pr("sha256").update(d.id).digest("hex").slice(0,20)}`;if([...r.sessions.values()].some(m=>m.targetCode===h))throw new Error("\u6B64\u667A\u80FD\u4F53\u4ECD\u6709\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u7ED3\u675F\u4F1A\u8BDD\u518D\u4FEE\u6539\u63A5\u5165");s[h]={name:f,workspace:p,command:d.command,type:d.managed?"openclaw":"cli",...d.managed?{openclawAgentId:d.localAgentId}:d.framework==="codex"?{terminalProtocol:"codex",args:["exec","--skip-git-repo-check","--json"],promptMode:"stdin",outputMode:"json-lines",captureLastMessage:!0}:{terminalProtocol:"claude",args:["-p","--output-format","json","--no-session-persistence"],promptMode:"args",outputMode:"json-lines"}},i.push({candidateId:d.id,name:f,workspace:p,targetCode:h,framework:d.framework})}let a=this.profile.targets;this.profile.targets=s;try{await this.persist()}catch(u){throw this.profile.targets=a,u}return r.targets=s,this.config.targets=s,r.notifyCapacityChanged(),{agents:i}}};import{execFile as Xs}from"node:child_process";import{constants as Ys}from"node:fs";import{access as jr,readFile as qr,realpath as Qs}from"node:fs/promises";import{join as Te}from"node:path";import{promisify as Zs}from"node:util";var J="0.1.49";function yt(){return new Date().toISOString()}function P(e,t=2){return String(e).padStart(t,"0")}function Lr(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${P(Math.floor(r/60))}:${P(r%60)}`}function Ds(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${P(e.getMonth()+1)}-${P(e.getDate())}`,`T${P(e.getHours())}:${P(e.getMinutes())}:${P(e.getSeconds())}.${P(e.getMilliseconds(),3)}`,Lr(t)].join("")}function Hs(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 Fs(e,t){let r=Hs(e,t),n=Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second,e.getMilliseconds()),s=Math.round((n-e.getTime())/6e4);return[`${r.year}-${P(r.month)}-${P(r.day)}`,`T${P(r.hour)}:${P(r.minute)}:${P(r.second)}.${P(e.getMilliseconds(),3)}`,Lr(s)].join("")}function $s(e=new Date){let t=c(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return Fs(e,t)}catch{return Ds(e)}}function l(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function c(e){return String(e??"").trim()}function y(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)?r:t}function A(e){return Array.isArray(e)?e.map(String):[]}function et(e,t,r=process.cwd()){let n=l(e)?e:{};return c(n.cwd)||c(n.workspace)||c(t)||c(r)||process.cwd()}var Ut="[redacted]",Bs=/(authorization|api[_-]?key|credential|password|secret|token)/i;function V(e){return Bs.test(c(e))}function ut(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(Ut))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${Ut}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${Ut}`)}function tt(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]=tt(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=>tt(i,t));return t.delete(e),s}let r={},n=V(e.name||e.key);for(let[s,i]of Object.entries(e))r[s]=V(s)||n&&s.toLowerCase()==="value"?Ut:tt(i,t);return t.delete(e),r}function kr(e,t=4e3){let r=JSON.stringify(tt(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function g(e,t,r,n={}){let s={ts:$s(),level:e,module:t,msg:r,...l(n)?tt(n):{}};console.error(JSON.stringify(s))}var rt="application/x-orcha-channel-events-v2+ndjson";function M(e,t){return Object.assign(new Error(t||(["run_timeout","RUNTIME_NODE_TIMEOUT"].includes(e)?"OpenClaw \u539F\u751F IM \u6267\u884C\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002":e==="OPENCLAW_CHANNEL_PROTOCOL_MISMATCH"?"OpenClaw \u63D2\u4EF6\u4E0E Bridge \u7684\u539F\u751F IM \u534F\u8BAE\u4E0D\u517C\u5BB9\uFF0C\u8BF7\u914D\u5957\u5347\u7EA7\u3002":`OpenClaw \u539F\u751F IM \u6267\u884C\u5931\u8D25\uFF08${e}\uFF09`)),{code:e})}function vr(e,t){let r=e.cause?.code||e.code;return t?.reason?.name==="TimeoutError"||e.name==="TimeoutError"||["UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT","UND_ERR_CONNECT_TIMEOUT","ETIMEDOUT"].includes(r)?Object.assign(M("RUNTIME_NODE_TIMEOUT","OpenClaw \u8FDE\u63A5\u6216\u7B49\u5F85\u54CD\u5E94\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002"),{detail:{causeCode:r||"REQUEST_TIMEOUT"}}):e}async function Dr(e,t){if(e.headers.get("content-type")!==rt)throw await e.body?.cancel(),M("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");let r=Buffer.alloc(0);for await(let n of e.body){r=Buffer.concat([r,n]);let s;for(;(s=r.indexOf(10))>=0;){if(s>2097152)throw M("OPENCLAW_CHANNEL_FRAME_TOO_LARGE");let i=r.subarray(0,s).toString("utf8");r=r.subarray(s+1);let o;try{o=JSON.parse(i)}catch{throw M("OPENCLAW_CHANNEL_INVALID_FRAME")}if(o.type!=="heartbeat")if(o.type==="update"&&o.payload?.update&&o.payload?._meta?.channelUpdateId)await t(o.payload);else{if(o.type==="result"&&o.result?.stopReason)return o.result;throw o.type==="error"&&typeof o.code=="string"?M(o.code):M("OPENCLAW_CHANNEL_INVALID_FRAME")}}if(r.length>2097152)throw M("OPENCLAW_CHANNEL_FRAME_TOO_LARGE")}throw M("OPENCLAW_CHANNEL_STREAM_INTERRUPTED","OpenClaw \u8FC7\u7A0B\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u4EFB\u52A1\u7EC8\u6001\uFF0C\u8BF7\u68C0\u67E5\u8282\u70B9\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002")}import{createServer as qs}from"node:http";import{randomBytes as Gs}from"node:crypto";var Pt={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs","knowledge_search"]};var Ks=Object.freeze([...Pt.controlTools,...Pt.residentTools]),zs=new Set(Ks),Vs=8*1024*1024;function Lt(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 Fr(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>Vs)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function $r(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 Fr(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function Hr(e,t){let r=await $r(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},t),n=r?.result?.tools;if(r?.error){let s=Object.entries(e.headers).filter(([a])=>V(a)).flatMap(([,a])=>[a,String(a).replace(/^Bearer\s+/i,"")]),i=typeof r.error.message=="string"?ut(r.error.message,s).slice(0,512):"",o=Number.isInteger(r.error.code)?` (${r.error.code})`:"";throw new Error(`Orcha MCP tool discovery failed${o}${i?`: ${i}`:""}`)}return Js(n)}function Js(e){if(!Array.isArray(e)||e.some(t=>!t||!zs.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&Pt.controlTools.some(t=>!e.some(r=>r.name===t)))throw new Error("Orcha MCP returned an unsupported or invalid authorized tool catalog");return e}function Ws(e,t){let r=s=>Array.isArray(s)?s.map(r):s&&typeof s=="object"?Object.fromEntries(Object.keys(s).sort().map(i=>[i,r(s[i])])):s,n=s=>s.map(({name:i,inputSchema:o})=>({name:i,inputSchema:o})).sort((i,o)=>i.name.localeCompare(o.name));return JSON.stringify(r(n(e)))===JSON.stringify(r(n(t)))}async function Br(e){let t=Lt(e),r=new AbortController,n=await Hr(t,r.signal),s=Gs(32).toString("hex"),i=qs(async(o,a)=>{if(o.url!=="/mcp"||o.headers.authorization!==`Bearer ${s}`){a.writeHead(403).end();return}if(o.method!=="POST"){a.writeHead(405).end();return}try{let u=await Fr(o);if(!u||u.jsonrpc!=="2.0"||typeof u.method!="string")throw new Error("Invalid MCP request");if(u.method==="tools/call"&&!n.some(f=>f.name===u.params?.name))throw new Error("Tool is not authorized in this task binding");let d=await $r(t,u,r.signal);a.writeHead(d===null?202:200,{"content-type":"application/json"}),a.end(d===null?"":JSON.stringify(d))}catch{a.writeHead(502,{"content-type":"application/json"}).end(JSON.stringify({error:"The task-scoped Orcha MCP connection failed"}))}});return await new Promise((o,a)=>{i.once("error",a),i.listen(0,"127.0.0.1",o)}),{url:`http://127.0.0.1:${i.address().port}/mcp`,token:s,async refresh(o){let a=Lt(o,t.url);if(!Ws(n,await Hr(a,r.signal)))throw new Error("The frozen MCP tool catalog changed; start a new task");t=a},async close(){r.abort(),i.closeAllConnections(),await new Promise(o=>i.close(o))}}}var W=class{constructor(t,r){this.target=t,this.identity=r,this.bound=!1}async request(t,r,n=!1,s="mcp-bindings",i=3e4,o=null){let a=c(this.target.mcpBridgeUrl),u=c(this.target.mcpBridgeTokenEnv),d=this.target.env?.[u]||process.env[u];if(!a||!u||!d)throw Object.assign(new Error("OpenClaw requires the Orcha tool plugin, mcpBridgeUrl and mcpBridgeTokenEnv"),{code:"OPENCLAW_MCP_NOT_CONFIGURED"});let f=new URL(a);if(!["http:","https:"].includes(f.protocol)||f.username||f.password||f.pathname!=="/plugins/orcha-runtime/mcp-bindings"||f.search||f.hash)throw new Error("OpenClaw MCP binding URL must be the trusted Gateway plugin route");if(!["mcp-bindings","deliveries","background"].includes(s))throw new Error("Unsupported Orcha plugin route");f.pathname=`/plugins/orcha-runtime/${s}`;let p=AbortSignal.timeout(i);try{let h=await fetch(f,{method:t,redirect:"error",signal:p,headers:{authorization:`Bearer ${d}`,"content-type":"application/json",...o?{accept:rt}:{},...n?{"if-match":this.identity.runId}:{}},...r!==void 0?{body:JSON.stringify(r)}:{}});if(t==="GET"&&s==="deliveries"&&[404,405].includes(h.status))throw await h.body?.cancel(),M("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");if(h.ok&&o)return await Dr(h,o);let m=await h.json();if(!h.ok)throw M(m.error||"OPENCLAW_MCP_BINDING_FAILED");return m}catch(h){throw vr(h,p)}}async bind(t,r=!1){Lt(t),await this.request("PUT",{...this.identity,mcpServer:t[0]},r),this.bound=!0}async close(){this.bound&&(await this.request("DELETE",{runId:this.identity.runId,sessionKey:this.identity.sessionKey}),this.bound=!1)}};var ti=Zs(Xs),ei=12e4;async function Gr(e,t){let r=new Map,n=[];for(let s of Object.values(e)){if(s.type!=="openclaw")continue;if(s.mcpBridgeUrl&&(n.push(s),!["localhost","127.0.0.1","[::1]"].includes(new URL(s.mcpBridgeUrl).hostname))){process.stderr.write(`\u8FDC\u7A0B OpenClaw Gateway \u7684\u914D\u5957\u63D2\u4EF6\u9700\u5728\u6240\u5728\u4E3B\u673A\u66F4\u65B0\uFF1Breload \u5C06\u68C0\u67E5\u5176\u534F\u8BAE\u3002
|
|
3
|
-
`);continue}let i={...process.env,...s.env},o=c(s.command)||"openclaw",a=o.includes("/")?o:await he(o,i);if(!a)throw new Error("\u627E\u4E0D\u5230\u5DF2\u63A5\u5165\u7684 OpenClaw\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u5B89\u88C5\u540E\u91CD\u8BD5 reload");let u=await
|
|
4
|
-
`),await
|
|
5
|
-
`)}for(let s of n)if((await new
|
|
6
|
-
`):""}var vt=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=kt(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 Rc}from"node:child_process";import{closeSync as Sc,existsSync as Or,mkdirSync as Oc,openSync as Ic,readFileSync as Er,rmSync as Cc,statSync as ps,writeFileSync as ys}from"node:fs";import{dirname as ws,resolve as mt}from"node:path";import{fileURLToPath as xc}from"node:url";import{createHash as kr}from"node:crypto";import{mkdir as Ls,readFile as ks,writeFile as vs,rename as Ds}from"node:fs/promises";import{join as Pr}from"node:path";import{homedir as Hs,hostname as Fs}from"node:os";import{execFile as As}from"node:child_process";import{access as Ns,realpath as bs}from"node:fs/promises";import{constants as Ms}from"node:fs";import{delimiter as Us,join as br,isAbsolute as Mr}from"node:path";import{homedir as Nr}from"node:os";async function he(e,t=process.env){let r=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let n of(t.PATH||"").split(Us).filter(Mr))for(let s of r){let i=br(n,`${e}${s}`);try{return await Ns(i,Ms.X_OK),i}catch{}}return null}function Ps(e,t){return new Promise(r=>As(e,t,{timeout:8e3,maxBuffer:1024*1024,windowsHide:!0},(n,s)=>r({code:n?n.code:0,stdout:String(s||"")})))}async function me(e){let t=e==="~"?Nr():e.startsWith("~/")?br(Nr(),e.slice(2)):e;if(!Mr(t))throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u5FC5\u987B\u662F\u8BBE\u5907\u4E0A\u7684\u7EDD\u5BF9\u8DEF\u5F84\u6216 ~/ \u5F00\u5934\u7684\u8DEF\u5F84");let r=await bs(t),{stat:n}=await import("node:fs/promises");if(!(await n(r)).isDirectory())throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u4E0D\u662F\u6587\u4EF6\u5939");return r}async function Ur({find:e=he,run:t=Ps,cwd:r=process.cwd()}={}){return(await Promise.all(["codex","claude","openclaw"].map(async s=>{let i=await e(s);if(!i)return[];let o={codex:"Codex",claude:"Claude Code",openclaw:"OpenClaw"}[s],a=await t(i,["--version"]),u=a.code===0&&a.stdout.match(/\d+\.\d+\.\d+[^\s]*/)?.[0]||"",d={id:s,name:o,framework:s,version:u,workspace:r,managed:!1};if(a.code!==0)return[{...d,status:"error",message:"\u7A0B\u5E8F\u65E0\u6CD5\u542F\u52A8\uFF0C\u8BF7\u5728\u672C\u673A\u68C0\u67E5\u5B89\u88C5"}];if(s==="openclaw"){let h=await t(i,["agents","list","--json"]),m;try{m=JSON.parse(h.stdout)}catch{}if(h.code!==0||!Array.isArray(m))return[{...d,status:"error",message:"\u65E0\u6CD5\u8BFB\u53D6 OpenClaw \u667A\u80FD\u4F53\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u914D\u7F6E"}];let y=await t(i,["health","--json"]);return m.filter(S=>typeof S.id=="string"&&typeof S.workspace=="string").slice(0,32).map(S=>({...d,id:`openclaw:${S.id}`,name:S.name||S.identityName||S.id,workspace:S.workspace,managed:!0,localAgentId:S.id,command:i,status:y.code===0?"ready":"needs_setup",message:y.code===0?"":"\u8BF7\u5148\u5728\u672C\u673A\u542F\u52A8\u5E76\u914D\u7F6E OpenClaw Gateway"}))}let f=await t(i,s==="codex"?["login","status"]:["auth","status"]),p=f.code===0?"ready":f.code===1?"needs_login":"error";return[{...d,command:i,status:p,message:p==="needs_login"?`\u8BF7\u5728\u672C\u673A\u8FD0\u884C ${s} ${s==="codex"?"login":"auth login"}`:p==="error"?"\u767B\u5F55\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C":""}]}))).flat()}async function Lr(e,t){let r=`${e}.${process.pid}.tmp`;await vs(r,JSON.stringify(t),{mode:384}),await Ds(r,e)}function _e(e){let t=new URL(e);if(t.username||t.password||t.search||t.hash||t.protocol!=="https:"&&!(t.protocol==="http:"&&["localhost","127.0.0.1","[::1]"].includes(t.hostname)))throw new Error("\u8FDE\u63A5\u5730\u5740\u5FC5\u987B\u4F7F\u7528 HTTPS\uFF1B\u4EC5\u672C\u673A\u5F00\u53D1\u5141\u8BB8 HTTP");let r=Pr(Hs(),".orcha","devices"),n=Pr(r,kr("sha256").update(t.toString()).digest("hex").slice(0,20));return{address:t,root:r,profile:`${n}.json`,pidFile:`${n}.pid`,logFile:`${n}.log`}}async function Mt(e,{url:t,pairCode:r}){let{address:n,root:s,profile:i}=_e(t||e.orchaUrl);await Ls(s,{recursive:!0,mode:448});let o;if(r){let a=await fetch(new URL("api/agent-devices/pairings/exchange",`${n.toString().replace(/\/+$/,"")}/`),{method:"POST",redirect:"error",headers:{"content-type":"application/json"},signal:AbortSignal.timeout(15e3),body:JSON.stringify({code:r,name:Fs()})}),u=await a.json();if(!a.ok||!u.success)throw new Error(u.message||u.detail||"\u8BBE\u5907\u8FDE\u63A5\u5931\u8D25");o={...u.data,targets:{}},await Lr(i,o)}else try{o=JSON.parse(await ks(i,"utf8"))}catch{throw new Error("\u6CA1\u6709\u5DF2\u8FDE\u63A5\u8BBE\u5907\uFF0C\u8BF7\u4ECE\u667A\u80FD\u4F53\u9875\u9762\u751F\u6210\u8FDE\u63A5\u7801")}e.orchaUrl=n.toString().replace(/\/+$/,""),e.mode="node",e.nodeId=o.nodeCode,e.nodeName=o.nodeName,e.nodeToken=o.token,e.targets=o.targets,e.defaultTargetCode="",e.deviceConnection=new ge(e,o,async()=>Lr(i,o))}var ge=class{constructor(t,r,n,s=Ur){this.config=t,this.profile=r,this.persist=n,this.discover=s}async candidates(){return{candidates:(await this.discover()).map(({command:r,localAgentId:n,...s})=>s)}}async configure(t,r){if(!Array.isArray(t.selections)||!t.selections.length||t.selections.length>32)throw new Error("\u6DFB\u52A0\u9879\u65E0\u6548");let n=new Map((await this.discover()).map(u=>[u.id,u])),s={...r.targets},i=[],o=new Set;for(let u of t.selections){let d=n.get(u.candidateId);if(!d||d.status!=="ready"||o.has(d.id))throw new Error("\u53D1\u73B0\u7ED3\u679C\u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u6D4B");o.add(d.id);let f=String(u.name||"").trim();if(!f||f.length>128)throw new Error("\u667A\u80FD\u4F53\u540D\u79F0\u65E0\u6548");let p=await me(String(u.workspace||""));if(d.managed&&p!==await me(d.workspace))throw new Error("\u5DF2\u6709\u667A\u80FD\u4F53\u5FC5\u987B\u6CBF\u7528\u672C\u673A\u5DE5\u4F5C\u76EE\u5F55");let h=`${this.config.nodeId}:${kr("sha256").update(d.id).digest("hex").slice(0,20)}`;if([...r.sessions.values()].some(m=>m.targetCode===h))throw new Error("\u6B64\u667A\u80FD\u4F53\u4ECD\u6709\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u7ED3\u675F\u4F1A\u8BDD\u518D\u4FEE\u6539\u63A5\u5165");s[h]={name:f,workspace:p,command:d.command,type:d.managed?"openclaw":"cli",...d.managed?{openclawAgentId:d.localAgentId}:d.framework==="codex"?{terminalProtocol:"codex",args:["exec","--skip-git-repo-check","--json"],promptMode:"stdin",outputMode:"json-lines",captureLastMessage:!0}:{terminalProtocol:"claude",args:["-p","--output-format","json","--no-session-persistence"],promptMode:"args",outputMode:"json-lines"}},i.push({candidateId:d.id,name:f,workspace:p,targetCode:h,framework:d.framework})}let a=this.profile.targets;this.profile.targets=s;try{await this.persist()}catch(u){throw this.profile.targets=a,u}return r.targets=s,this.config.targets=s,r.notifyCapacityChanged(),{agents:i}}};import{execFile as Zs}from"node:child_process";import{constants as ti}from"node:fs";import{access as Kr,readFile as Gr,realpath as ei}from"node:fs/promises";import{join as ye}from"node:path";import{promisify as ri}from"node:util";var W="0.1.51";function wt(){return new Date().toISOString()}function L(e,t=2){return String(e).padStart(t,"0")}function vr(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${L(Math.floor(r/60))}:${L(r%60)}`}function $s(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${L(e.getMonth()+1)}-${L(e.getDate())}`,`T${L(e.getHours())}:${L(e.getMinutes())}:${L(e.getSeconds())}.${L(e.getMilliseconds(),3)}`,vr(t)].join("")}function Bs(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 js(e,t){let r=Bs(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}-${L(r.month)}-${L(r.day)}`,`T${L(r.hour)}:${L(r.minute)}:${L(r.second)}.${L(e.getMilliseconds(),3)}`,vr(s)].join("")}function qs(e=new Date){let t=c(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return js(e,t)}catch{return $s(e)}}function l(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function c(e){return String(e??"").trim()}function E(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)?r:t}function b(e){return Array.isArray(e)?e.map(String):[]}function et(e,t,r=process.cwd()){let n=l(e)?e:{};return c(n.cwd)||c(n.workspace)||c(t)||c(r)||process.cwd()}var Ut="[redacted]",Ks=/(authorization|api[_-]?key|credential|password|secret|token)/i;function J(e){return Ks.test(c(e))}function rt(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(Ut))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${Ut}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${Ut}`)}function tt(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]=tt(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=>tt(i,t));return t.delete(e),s}let r={},n=J(e.name||e.key);for(let[s,i]of Object.entries(e))r[s]=J(s)||n&&s.toLowerCase()==="value"?Ut:tt(i,t);return t.delete(e),r}function Dr(e,t=4e3){let r=JSON.stringify(tt(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function g(e,t,r,n={}){let s={ts:qs(),level:e,module:t,msg:r,...l(n)?tt(n):{}};console.error(JSON.stringify(s))}var nt="application/x-orcha-channel-events-v2+ndjson";function P(e,t){return Object.assign(new Error(t||(["run_timeout","RUNTIME_NODE_TIMEOUT"].includes(e)?"OpenClaw \u539F\u751F IM \u6267\u884C\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002":e==="OPENCLAW_CHANNEL_PROTOCOL_MISMATCH"?"OpenClaw \u63D2\u4EF6\u4E0E Bridge \u7684\u539F\u751F IM \u534F\u8BAE\u4E0D\u517C\u5BB9\uFF0C\u8BF7\u914D\u5957\u5347\u7EA7\u3002":`OpenClaw \u539F\u751F IM \u6267\u884C\u5931\u8D25\uFF08${e}\uFF09`)),{code:e})}function Hr(e,t){let r=e.cause?.code||e.code;return t?.reason?.name==="TimeoutError"||e.name==="TimeoutError"||["UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT","UND_ERR_CONNECT_TIMEOUT","ETIMEDOUT"].includes(r)?Object.assign(P("RUNTIME_NODE_TIMEOUT","OpenClaw \u8FDE\u63A5\u6216\u7B49\u5F85\u54CD\u5E94\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002"),{detail:{causeCode:r||"REQUEST_TIMEOUT"}}):e}async function Fr(e,t){if(e.headers.get("content-type")!==nt)throw await e.body?.cancel(),P("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");let r=Buffer.alloc(0);for await(let n of e.body){r=Buffer.concat([r,n]);let s;for(;(s=r.indexOf(10))>=0;){if(s>2097152)throw P("OPENCLAW_CHANNEL_FRAME_TOO_LARGE");let i=r.subarray(0,s).toString("utf8");r=r.subarray(s+1);let o;try{o=JSON.parse(i)}catch{throw P("OPENCLAW_CHANNEL_INVALID_FRAME")}if(o.type!=="heartbeat")if(o.type==="update"&&o.payload?.update&&o.payload?._meta?.channelUpdateId)await t(o.payload);else{if(o.type==="result"&&o.result?.stopReason)return o.result;throw o.type==="error"&&typeof o.code=="string"?P(o.code):P("OPENCLAW_CHANNEL_INVALID_FRAME")}}if(r.length>2097152)throw P("OPENCLAW_CHANNEL_FRAME_TOO_LARGE")}throw P("OPENCLAW_CHANNEL_STREAM_INTERRUPTED","OpenClaw \u8FC7\u7A0B\u8FDE\u63A5\u4E2D\u65AD\uFF0C\u672A\u6536\u5230\u4EFB\u52A1\u7EC8\u6001\uFF0C\u8BF7\u68C0\u67E5\u8282\u70B9\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002")}import{createServer as zs}from"node:http";import{randomBytes as Js}from"node:crypto";var Pt={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs","knowledge_search"]};var Ws=Object.freeze([...Pt.controlTools,...Pt.residentTools]),Vs=new Set(Ws),Xs=8*1024*1024;function Lt(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 Br(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>Xs)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function jr(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 Br(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function $r(e,t){let r=await jr(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},t),n=r?.result?.tools;if(r?.error){let s=Object.entries(e.headers).filter(([a])=>J(a)).flatMap(([,a])=>[a,String(a).replace(/^Bearer\s+/i,"")]),i=typeof r.error.message=="string"?rt(r.error.message,s).slice(0,512):"",o=Number.isInteger(r.error.code)?` (${r.error.code})`:"";throw new Error(`Orcha MCP tool discovery failed${o}${i?`: ${i}`:""}`)}return Ys(n)}function Ys(e){if(!Array.isArray(e)||e.some(t=>!t||!Vs.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&Pt.controlTools.some(t=>!e.some(r=>r.name===t)))throw new Error("Orcha MCP returned an unsupported or invalid authorized tool catalog");return e}function Qs(e,t){let r=s=>Array.isArray(s)?s.map(r):s&&typeof s=="object"?Object.fromEntries(Object.keys(s).sort().map(i=>[i,r(s[i])])):s,n=s=>s.map(({name:i,inputSchema:o})=>({name:i,inputSchema:o})).sort((i,o)=>i.name.localeCompare(o.name));return JSON.stringify(r(n(e)))===JSON.stringify(r(n(t)))}async function qr(e,t=[]){let r=Lt(e),n=new AbortController,s=await $r(r,n.signal);if(t.some(a=>s.some(u=>u.name===a.name)))throw new Error("Local and remote MCP tools conflict");let i=Js(32).toString("hex"),o=zs(async(a,u)=>{if(a.url!=="/mcp"||a.headers.authorization!==`Bearer ${i}`){u.writeHead(403).end();return}if(a.method!=="POST"){u.writeHead(405).end();return}try{let d=await Br(a);if(!d||d.jsonrpc!=="2.0"||typeof d.method!="string")throw new Error("Invalid MCP request");let f=d.method==="tools/call"&&t.find(h=>h.name===d.params?.name);if(d.method==="tools/call"&&!f&&!s.some(h=>h.name===d.params?.name))throw new Error("Tool is not authorized in this task binding");let p;if(f)try{p={jsonrpc:"2.0",id:d.id,result:await f.call(d.params.arguments,{upstream:r,signal:n.signal})}}catch(h){p={jsonrpc:"2.0",id:d.id,result:{isError:!0,content:[{type:"text",text:rt(String(h.message),[r.headers.authorization,i])}]}}}else p=await jr(r,d,n.signal),d.method==="tools/list"&&p?.result?.tools&&p.result.tools.push(...t.map(({call:h,...m})=>m));u.writeHead(p===null?202:200,{"content-type":"application/json"}),u.end(p===null?"":JSON.stringify(p))}catch{u.writeHead(502,{"content-type":"application/json"}).end(JSON.stringify({error:"The task-scoped Orcha MCP connection failed"}))}});return await new Promise((a,u)=>{o.once("error",u),o.listen(0,"127.0.0.1",a)}),{url:`http://127.0.0.1:${o.address().port}/mcp`,token:i,async refresh(a){let u=Lt(a,r.url);if(!Qs(s,await $r(u,n.signal)))throw new Error("The frozen MCP tool catalog changed; start a new task");r=u},async close(){n.abort(),o.closeAllConnections(),await new Promise(a=>o.close(a))}}}var V=class{constructor(t,r){this.target=t,this.identity=r,this.bound=!1}async request(t,r,n=!1,s="mcp-bindings",i=3e4,o=null){let a=c(this.target.mcpBridgeUrl),u=c(this.target.mcpBridgeTokenEnv),d=this.target.env?.[u]||process.env[u];if(!a||!u||!d)throw Object.assign(new Error("OpenClaw requires the Orcha tool plugin, mcpBridgeUrl and mcpBridgeTokenEnv"),{code:"OPENCLAW_MCP_NOT_CONFIGURED"});let f=new URL(a);if(!["http:","https:"].includes(f.protocol)||f.username||f.password||f.pathname!=="/plugins/orcha-runtime/mcp-bindings"||f.search||f.hash)throw new Error("OpenClaw MCP binding URL must be the trusted Gateway plugin route");if(!["mcp-bindings","deliveries","background"].includes(s))throw new Error("Unsupported Orcha plugin route");f.pathname=`/plugins/orcha-runtime/${s}`;let p=AbortSignal.timeout(i);try{let h=await fetch(f,{method:t,redirect:"error",signal:p,headers:{authorization:`Bearer ${d}`,"content-type":"application/json",...o?{accept:nt}:{},...n?{"if-match":this.identity.runId}:{}},...r!==void 0?{body:JSON.stringify(r)}:{}});if(t==="GET"&&s==="deliveries"&&[404,405].includes(h.status))throw await h.body?.cancel(),P("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");if(h.ok&&o)return await Fr(h,o);let m=await h.json();if(!h.ok)throw P(m.error||"OPENCLAW_MCP_BINDING_FAILED");return m}catch(h){throw Hr(h,p)}}async bind(t,r=!1){Lt(t),await this.request("PUT",{...this.identity,mcpServer:t[0]},r),this.bound=!0}async close(){this.bound&&(await this.request("DELETE",{runId:this.identity.runId,sessionKey:this.identity.sessionKey}),this.bound=!1)}};var ni=ri(Zs),si=12e4;async function zr(e,t){let r=new Map,n=[];for(let s of Object.values(e)){if(s.type!=="openclaw")continue;if(s.mcpBridgeUrl&&(n.push(s),!["localhost","127.0.0.1","[::1]"].includes(new URL(s.mcpBridgeUrl).hostname))){process.stderr.write(`\u8FDC\u7A0B OpenClaw Gateway \u7684\u914D\u5957\u63D2\u4EF6\u9700\u5728\u6240\u5728\u4E3B\u673A\u66F4\u65B0\uFF1Breload \u5C06\u68C0\u67E5\u5176\u534F\u8BAE\u3002
|
|
3
|
+
`);continue}let i={...process.env,...s.env},o=c(s.command)||"openclaw",a=o.includes("/")?o:await he(o,i);if(!a)throw new Error("\u627E\u4E0D\u5230\u5DF2\u63A5\u5165\u7684 OpenClaw\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u5B89\u88C5\u540E\u91CD\u8BD5 reload");let u=await ei(a);await Kr(u,ti.X_OK);let d=JSON.stringify([u,Object.entries(i).sort(([f],[p])=>f.localeCompare(p))]);r.has(d)||r.set(d,{command:u,env:i})}if(r.size)try{let s=JSON.parse(await Gr(ye(t,"openclaw.plugin.json"),"utf8")),i=JSON.parse(await Gr(ye(t,"package.json"),"utf8"));if(await Kr(ye(t,"index.js")),s.id!=="orcha-runtime"||i.version!==W)throw new Error("\u63D2\u4EF6\u6807\u8BC6\u6216\u7248\u672C\u4E0D\u5339\u914D")}catch(s){throw new Error("\u914D\u5957 OpenClaw \u63D2\u4EF6\u7F3A\u5931\u3001\u635F\u574F\u6216\u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u65B0\u5B89\u88C5 Bridge\uFF1B\u6E90\u7801\u8FD0\u884C\u8BF7\u5148 npm run build",{cause:s})}return async()=>{for(let s of r.values()){process.stderr.write(`\u6B63\u5728\u5B89\u88C5\u914D\u5957 OpenClaw \u63D2\u4EF6\u5E76\u91CD\u542F Gateway\u2026
|
|
4
|
+
`),await we(s,["plugins","install",t,"--force"]),await we(s,["gateway","restart"]);let i=await we(s,["health","--json"]);if(JSON.parse(i).ok!==!0)throw new Error("OpenClaw Gateway \u5065\u5EB7\u68C0\u67E5\u5931\u8D25\uFF0CBridge \u672A\u542F\u52A8\uFF0C\u8BF7\u4FEE\u590D\u540E\u91CD\u8BD5 reload");process.stderr.write(`OpenClaw \u914D\u5957\u63D2\u4EF6\u5DF2\u66F4\u65B0\uFF0CGateway \u5065\u5EB7\u68C0\u67E5\u901A\u8FC7\u3002
|
|
5
|
+
`)}for(let s of n)if((await new V(s,{}).request("GET",void 0,!1,"deliveries")).streamType!==nt)throw P("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH")}}async function we(e,t){try{let{stdout:r}=await ni(e.command,t,{env:e.env,timeout:si,killSignal:"SIGKILL",maxBuffer:1048576,windowsHide:!0});return r}catch(r){let n=Object.entries(e.env).filter(([i])=>J(i)).map(([,i])=>i),s=rt(r.stderr||r.message,n).trim();throw new Error(`OpenClaw ${t.slice(0,2).join(" ")} \u5931\u8D25\uFF0CBridge \u672A\u542F\u52A8\uFF0C\u8BF7\u4FEE\u590D\u540E\u91CD\u8BD5 reload\uFF1A${s}`)}}import{createHash as Na,randomUUID as re}from"node:crypto";function kt(e){return Array.isArray(e)?e.map(t=>l(t)?t.type==="text"?c(t.text):t.type==="file"?c(t.uri):t.type==="image"?c(t.uri):"":"").filter(Boolean).join(`
|
|
6
|
+
`):""}var vt=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=kt(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 ii}from"node:child_process";var Tt="2.0",Te=3e4,oi=4e3;function Dt(e,t){let r=Object.entries(l(t)?t:{}).filter(([n])=>J(n)).map(([,n])=>n);return rt(e,r)}function ai(e){return{code:Number.isInteger(e?.code)?e.code:-32e3,message:c(e?.message)||String(e),data:l(e?.data)?e.data:void 0}}function ci(e){if(!l(e))return new Error(String(e||"runtime error"));let t=c(e.message)||"runtime error",r="data"in e?Dr(e.data,4e3):"",n=new Error(r?`${t}; data=${r}`:t);return n.rpcCode=e.code,n.data=e.data,n}function ui(e){return l(e)&&"id"in e&&!("method"in e)}function li(e){return l(e)&&typeof e.method=="string"&&"id"in e}function di(e){return l(e)&&typeof e.method=="string"&&!("id"in e)}var Ht=class{constructor({command:t,args:r=[],cwd:n,env:s,label:i,framing:o="line",detached:a=!0}){this.command=t,this.args=Array.isArray(r)?r.map(String):[],this.cwd=n||process.cwd(),this.env=l(s)?{...s}:{...process.env},this.label=i||t,this.framing=o==="content-length"?"content-length":"line",this.detached=a!==!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=ii(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(-oi);let i=Dt(s.trimEnd(),this.env);i&&g("debug","runtime.stderr","runtime stderr",{target:this.label,text:i})}),this.child.on("exit",(s,i)=>this.handleExit(s,i)),this.child.on("error",s=>{this.spawnError=s,this.rejectAll(s)}),t)){let s=Math.max(1,E(n,Te));try{await this.call("initialize",{protocolVersion:1,clientCapabilities:{},...r},s)}catch(i){let o=this.startupFailureDetail(),a=Dt(i?.message||i,this.env);g("warn","runtime.initialize","runtime initialize failed",{target:this.label,timeoutMs:s,cause:a,...o}),await this.stop("initialize failed",{termTimeoutMs:1e3,killTimeoutMs:1e3});let u=o.stderr?`; stderr: ${o.stderr}`:`; command=${o.command}; cwd=${o.cwd}`;throw Object.assign(new Error(`runtime initialize failed: ${a}${u}`,{cause:i}),{code:"RUNTIME_INITIALIZE_FAILED",detail:o})}}}startupFailureDetail(){return{command:this.command,cwd:this.cwd,exited:this.exited,exitCode:this.exitCode,exitSignal:this.exitSignal,...this.spawnError?{spawnError:Dt(this.spawnError.message,this.env)}:{},...this.stderrTail.trim()?{stderr:Dt(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
|
|
7
7
|
\r
|
|
8
|
-
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){g("warn","runtime.protocol","missing Content-Length header",{target:this.label}),this.headerBuffer=Buffer.alloc(0);return}let i=Number.parseInt(s[1],10),o=r+4,a=o+i;if(this.headerBuffer.length<a)return;let u=this.headerBuffer.subarray(o,a).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(a),this.dispatchRaw(u)}}dispatchRaw(t){let r;try{r=JSON.parse(t)}catch(n){g("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(n)});return}this.dispatch(r)}dispatch(t){if(
|
|
8
|
+
`);if(r<0)return;let s=this.headerBuffer.subarray(0,r).toString("utf8").match(/content-length:\s*(\d+)/i);if(!s){g("warn","runtime.protocol","missing Content-Length header",{target:this.label}),this.headerBuffer=Buffer.alloc(0);return}let i=Number.parseInt(s[1],10),o=r+4,a=o+i;if(this.headerBuffer.length<a)return;let u=this.headerBuffer.subarray(o,a).toString("utf8");this.headerBuffer=this.headerBuffer.subarray(a),this.dispatchRaw(u)}}dispatchRaw(t){let r;try{r=JSON.parse(t)}catch(n){g("warn","runtime.protocol","invalid JSON frame",{target:this.label,error:String(n)});return}this.dispatch(r)}dispatch(t){if(ui(t)){this.resolveResponse(t);return}if(li(t)){this.handleRequest(t);return}di(t)&&this.handleNotification(t)}resolveResponse(t){let r=String(t.id),n=this.pending.get(r);n&&(clearTimeout(n.timer),this.pending.delete(r),t.error?(g("warn","runtime.protocol","runtime rpc error",{target:this.label,method:n.method,requestId:r,error:t.error}),n.reject(ci(t.error))):n.resolve(t.result))}async handleRequest(t){let r=this.requestHandlers.get(t.method);if(!r){this.writeFrame({jsonrpc:Tt,id:t.id,error:{code:-32601,message:`method not found: ${t.method}`}});return}try{let n=await r(l(t.params)?t.params:{},t);this.writeFrame({jsonrpc:Tt,id:t.id,result:n??{}})}catch(n){this.writeFrame({jsonrpc:Tt,id:t.id,error:ai(n)})}}handleNotification(t){let r=this.notificationHandlers.get(t.method);if(r)for(let n of r)n(l(t.params)?t.params:{},t)}call(t,r={},n=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:Tt,id:s,method:t,params:r};return new Promise((o,a)=>{let u=setTimeout(()=>{this.pending.delete(s),a(new Error(`${t} timed out after ${n}ms`))},n);this.pending.set(s,{resolve:o,reject:a,timer:u,method:t}),this.writeFrame(i,d=>{d&&(clearTimeout(u),this.pending.delete(s),a(d))})})}notify(t,r={}){this.writeFrame({jsonrpc:Tt,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
|
|
9
9
|
\r
|
|
10
10
|
${n}`:`${n}
|
|
11
|
-
`;this.child.stdin.write(s,r)}onNotification(t,r){let n=this.notificationHandlers.get(t)||new Set;return n.add(r),this.notificationHandlers.set(t,n),()=>{n.delete(r),n.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,r){return this.requestHandlers.set(t,r),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let r of this.pending.values())clearTimeout(r.timer),r.reject(t);this.pending.clear()}handleExit(t,r){this.exited=!0,this.exitCode=t,this.exitSignal=r,this.rejectAll(new Error(`runtime exited before response (${t}/${r})`));for(let n of this.exitHandlers)n(t,r)}async waitForExit(t=5e3){return!this.child||this.exited?!0:await new Promise(r=>{let n=setTimeout(()=>{s(),r(!1)},t);n.unref?.();let s=()=>{clearTimeout(n),this.exitHandlers.delete(i)},i=()=>{s(),r(!0)};this.exitHandlers.add(i),this.exited&&i()})}signal(t){if(!this.child||this.exited)return!1;let r=this.child.pid;if(!r)return!1;try{return this.detached&&process.platform!=="win32"?process.kill(-r,t):this.child.kill(t),!0}catch(n){if(n?.code==="ESRCH")return this.exited=!0,!1;try{return this.child.kill(t),!0}catch(s){return s?.code!=="ESRCH"&&g("warn","runtime","runtime signal failed",{target:this.label,pid:r,signal:t,error:String(s)}),!1}}}async stop(t="stop",{termTimeoutMs:r=5e3,killTimeoutMs:n=2e3}={}){if(!(!this.child||this.exited)){if(this.stopPromise)return await this.stopPromise;this.stopPromise=(async()=>{if(!this.child||this.exited)return;let s=this.child.pid;g("info","runtime","stopping runtime",{target:this.label,reason:t,pid:s}),this.rejectAll(new Error(`runtime stopped: ${t}`)),this.signal("SIGTERM"),!await this.waitForExit(r)&&this.child&&!this.exited&&(g("warn","runtime","runtime did not exit after SIGTERM; force killing",{target:this.label,reason:t,pid:s}),this.signal("SIGKILL"),await this.waitForExit(n))})();try{await this.stopPromise}finally{this.stopPromise=null}}}};import{randomUUID as Jr}from"node:crypto";import{existsSync as ui,readFileSync as li,realpathSync as Kr,statSync as di}from"node:fs";import{basename as Wr,extname as Xr,isAbsolute as Et,join as fi,relative as Yr,resolve as zr}from"node:path";var pi=25*1024*1024;function Qr(e,t=""){let r=c(t);if(r)return r;let n=Xr(c(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function Zr(e,t){let r=typeof e=="string"?e.trim():"";return!r||r==="<omitted>"?"":r.startsWith("data:")?r:`data:${t};base64,${r.replace(/\s+/g,"")}`}function Ft(e){if(Array.isArray(e))return e.map(c).filter(Boolean);let t=c(e);return t?[t]:[]}function hi(e,t){let r=Yr(t,e);return r===""||!!r&&!r.startsWith("..")&&!Et(r)}function mi(e,t){let r=c(e);if(!r||!ui(r))return"";try{let n=Kr(r);for(let s of t)try{let i=Kr(s);if(hi(n,i))return n}catch{}}catch{return""}return""}function gi(e,t){let r=c(e);if(!r||!Et(r))return r;for(let n of Array.isArray(t)?t:[]){if(!l(n))continue;let s=c(n.runtimeRoot),i=c(n.hostRoot);if(!s||!i||!Et(s)||!Et(i))continue;let o=Yr(zr(s),zr(r));if(o===""||!o.startsWith("..")&&!Et(o))return o?fi(i,o):i}return r}function Ee(e,t,r={}){let n=c(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:_i(n,t,r)}function _i(e,t,r={}){let n=[...Ft(r.trustedFileRoots),...Ft(r.trustedFileRoot),...Ft(r.artifactRoots),...Ft(r.artifactRoot)],s=mi(gi(e,r.pathMappings),n);if(!s)return"";try{let i=di(s);return!i.isFile()||i.size<=0||i.size>pi?"":`data:${t};base64,${li(s).toString("base64")}`}catch{return""}}function x(...e){for(let t of e){let r=c(t);if(r)return r}return""}function Ti(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=Xr(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function Se(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!l(e))return null;let n=l(e.payload)?e.payload:{},s=c(e.type),i=c(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),a=x(n.saved_path,n.savedPath),u=x(n.revised_prompt,n.revisedPrompt),d=Qr(a,n.mimeType||n.mime_type),f=Zr(n.result,d)||Ee(a,d,t);if(!f)return null;let p=f.startsWith("data:")?f:"",h=a?Wr(a):`${o||Jr()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:h||"Generated image",summary:u||"Generated image",content:{prompt:u||void 0,dataUrl:p||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:p||void 0,previewUrl:f,fileUrl:f,metadata:{source:r,eventType:i,callId:o||void 0,savedPath:a||void 0,filename:h,mimeType:d,revisedPrompt:u||void 0}}}function yi(e){let t=l(e)?e:{},r=[];for(let n of["_artifacts","artifacts"]){let s=t[n];Array.isArray(s)&&r.push(...s)}for(let n of["_artifact","artifact"]){let s=t[n];l(s)&&r.push(s)}return r}function wi(e,t={}){let{source:r="runtime_artifact"}=t,n=l(e)?e:{};if(!Object.keys(n).length)return null;let s=l(n.content)?{...n.content}:{},i=l(n.metadata)?{...n.metadata}:{},o=x(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),a=x(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),u=x(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),d=Ti(n,s,u,o),f=d?Qr(o,a):a;if(d){let N=x(n.dataUrl,s.dataUrl),_=N.startsWith("data:")?N:"",w=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),E=Zr(n.result??s.result,f)||_||Ee(o,f,t)||Ee(w,f,t);E&&(E.startsWith("data:")&&(s.dataUrl||=E),s.imageUrl||=E,s.previewUrl||=E,s.fileUrl||=E,f&&(s.mimeType||=f))}for(let[N,_]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let w=n[N];w!=null&&w!==""&&!(_ in s)&&(s[_]=w)}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),h=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),m=x(n.dataUrl,s.dataUrl,p.startsWith("data:")?p:"",h.startsWith("data:")?h:""),T=x(n.filename,i.filename,o?Wr(o):""),S=x(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:u,type:n.type||u,fieldKey:S,title:x(n.title,T,"Runtime artifact"),summary:x(n.summary,s.prompt,n.title,T,"Runtime artifact"),content:s,dataUrl:m||void 0,fileUrl:p||void 0,previewUrl:h||void 0,metadata:{...i,source:x(i.source,r),savedPath:o||i.savedPath,filename:T||i.filename,mimeType:f||i.mimeType}}}function $t(e,t){if(!t||!e)return;let r=l(t.metadata)?t.metadata:{},n=x(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||Jr(),s=e.get(n);if(!s){e.set(n,t);return}s.content={...l(s.content)?s.content:{},...l(t.content)?t.content:{}},s.metadata={...l(s.metadata)?s.metadata:{},...r},s.previewUrl=t.previewUrl||s.previewUrl,s.fileUrl=t.fileUrl||s.fileUrl,s.summary=t.summary||s.summary,s.title=t.title||s.title}function Re(e,t,r={}){for(let n of yi(e))$t(t,wi(n,r))}function Oe(e){if(!l(e)||!l(e.payload))return l(e)?e:{value:e};let t=c(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 Vr(e,t,r){if(!l(e))return e;let n=l(e.event)?e.event:null;return n?($t(t,Se(n,r)),{...e,event:Oe(n)}):e}function tn(e,t,r={}){if(!l(e))return e;Re(e,t,r);let n=Vr(e,t,r),s=l(n.update)?Vr(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function en(e,t,r={}){let n=l(e)?{...e}:{};Re(n,t,r),Re(l(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function rn(e,t){let r=y(e,t);return r>0?r:t}var lt=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=c(this.target.command);if(!t)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let r={command:t,args:A(this.target.args),cwd:et(this.target,this.agent.workspace),environment:l(this.target.env)?this.target.env:{}},n=this.options.prepareLaunch?await this.options.prepareLaunch(r):{...r,environment:{...process.env,...r.environment},cleanup:async()=>{}};this.launch=n,this.launchCleanup=n.cleanup,this.proc=new Ht({command:n.command,args:n.args,cwd:n.cwd,env:n.environment,label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:c(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:rn(this.target.initializeTimeoutMs,rn(this.options.initializeTimeoutMs,3e4)),initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:J},...l(this.target.initializeParams)?this.target.initializeParams:{}}})}catch(s){throw await this.proc?.stop("runtime startup failed"),this.proc=null,await this.cleanupLaunch(),s}}async sessionNew(t={}){return await this.ensureStarted(),this.proc.call("session/new",this.sessionNewParams(t))}sessionNewParams(t={}){let r=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return{...t,mcpServers:r}}async sessionPrompt(t,r){await this.ensureStarted();let n=c(t.sessionId),s=new Map,i=this.artifactOptions(),o=this.proc.onNotification("session/update",u=>{let d=c(u.sessionId);(!d||d===n)&&r(tn(u,s,i))}),a=async u=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:u,emitUpdate:r})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,a),this.permissionHandlers.set("*",a);try{let u=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return en(u,s,i)}finally{o(),n&&this.permissionHandlers.delete(n),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let r=c(t.sessionId),n=this.permissionHandlers.get(r)||this.permissionHandlers.get("*");return n?n(t):{outcome:"denied",reason:"no active Orcha permission handler"}}artifactSource(){return c(this.target.type||"acp")==="openclaw"?"openclaw_image_generation":"acp_runtime_image_generation"}artifactOptions(){let t=l(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[c(this.launch?.artifactDirectory),c(this.launch?.homeDirectory),c(this.target.artifactRoot),c(this.target.artifactDir),c(this.target.runtimeArtifactRoot),c(t.ORCHA_RUNTIME_ARTIFACT_DIR),...A(this.target.trustedArtifactRoots),...A(this.target.trustedFileRoots),...A(this.target.artifactRoots),...A(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{existsSync as nn,readFileSync as Ei}from"node:fs";import{dirname as Ri,resolve as Bt}from"node:path";import{fileURLToPath as Si}from"node:url";var Oi=/^[A-Za-z_][A-Za-z0-9_]*$/,X=24*60*60*1e3;function sn(e=process.env,t=process.cwd()){let r=c(e.ORCHA_RUNTIME_ENV_FILE),n=r?Bt(t,r):Bt(t,".env");if(!nn(n))return r&&g("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Ei(n,"utf8");for(let o of i.split(/\r?\n/)){let a=xi(o);if(!a)continue;let[u,d]=a;Object.prototype.hasOwnProperty.call(e,u)||(e[u]=d,s.push(u))}return g("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function on(e=process.env){let t=c(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),r=c(e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1"),n=!1,s=Ri(Si(import.meta.url)),i=Bt(s,"sandbox","broker.js"),o=Bt(s,"orcha-runtime-sandbox-broker.js"),a=nn(i)?i:o,u=c(e.ORCHA_RUNTIME_SANDBOX_BROKER_COMMAND);return{mode:t,host:r,port:y(e.ORCHA_RUNTIME_BRIDGE_PORT,5588),token:e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",orchaUrl:c(e.ORCHA_RUNTIME_ORCHA_URL),nodeToken:e.ORCHA_RUNTIME_NODE_TOKEN||e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",nodeId:c(e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"local-runtime-node"),nodeName:c(e.ORCHA_RUNTIME_NODE_NAME||e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"Local Runtime Node"),reconnectMs:y(e.ORCHA_RUNTIME_RECONNECT_MS,3e3),connectTimeoutMs:y(e.ORCHA_RUNTIME_CONNECT_TIMEOUT_MS||e.ORCHA_RUNTIME_WS_CONNECT_TIMEOUT_MS,1e4),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:y(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),initializeTimeoutMs:y(e.ORCHA_RUNTIME_INITIALIZE_TIMEOUT_MS,3e4),sessionPromptTimeoutMs:y(e.ORCHA_RUNTIME_SESSION_PROMPT_TIMEOUT_MS,X),permissionRequestTimeoutMs:y(e.ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS,3e5),sessionIdleTtlMs:y(e.ORCHA_RUNTIME_SESSION_IDLE_TTL_MS,6e5),sessionCleanupIntervalMs:y(e.ORCHA_RUNTIME_SESSION_CLEANUP_INTERVAL_MS,6e4),maxSessionsPerTarget:y(e.ORCHA_RUNTIME_MAX_SESSIONS_PER_TARGET,8),openClawSessionIdleTtlMs:y(e.ORCHA_RUNTIME_OPENCLAW_SESSION_IDLE_TTL_MS,6e4),openClawMaxSessions:y(e.ORCHA_RUNTIME_OPENCLAW_MAX_SESSIONS,1),heartbeatIntervalMs:y(e.ORCHA_RUNTIME_HEARTBEAT_INTERVAL_MS,15e3),sandboxRequired:n,sandboxBrokerCommand:u||process.execPath,sandboxBrokerArguments:Ie(e.ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS,"ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS",u?[]:[a]),sandboxProbeTimeoutMs:y(e.ORCHA_RUNTIME_SANDBOX_PROBE_TIMEOUT_MS,1e4),sandboxTempRoot:c(e.ORCHA_RUNTIME_SANDBOX_TEMP_ROOT),trustedWorkspaceRoots:Ie(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:Ie(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:Ci(e.ORCHA_RUNTIME_EGRESS_PROXY_REQUIRED,t==="node"),egressProxySocket:c(e.ORCHA_RUNTIME_EGRESS_PROXY_SOCKET),egressProxyToken:c(e.ORCHA_RUNTIME_EGRESS_PROXY_TOKEN),egressGrantMaxTtlMs:y(e.ORCHA_RUNTIME_EGRESS_GRANT_MAX_TTL_MS,9e5),targets:Ii(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Ii(e){if(!c(e))return{};try{let t=JSON.parse(e);if(l(t))return t}catch(t){g("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function Ci(e,t){let r=c(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 Ie(e,t,r=[]){let n=c(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 xi(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(!Oi.test(s))return null;let i=Ai(r.slice(n+1).trim());return[s,i]}function Ai(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?Ni(r):r}return bi(e).trim()}function Ni(e){return e.replaceAll("\\n",`
|
|
12
|
-
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function bi(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}var jt=class{constructor(t,r,n,s,i={}){this.agent=t,this.target=r,this.options=i,this.sessionKey=n,this.mcp=null,this.metadata=null,this.finished=!1,this.transport=new W(r,{runId:i.runId}),this.expiresAt=new Date(Date.now()+Number(i.sandboxPolicy?.maxRuntimeSeconds||i.sessionPromptTimeoutMs/1e3||X/1e3)*1e3).toISOString()}async sessionNew({mcpServers:t,metadata:r}){if(r?.source!=="channel_message"||r.delivery?.dispatchMode!=="bridge")throw new Error("Invalid native Channel dispatch");return this.mcp=t[0],this.metadata=r,{sessionId:this.sessionKey}}async refreshMcpServers(t){this.mcp=t[0],this.promptBody&&await this.transport.request("PATCH",{...this.promptBody,mcpServer:this.mcp,attachOnly:!0},!1,"deliveries")}async sessionPrompt({prompt:t},r){if((await this.transport.request("GET",void 0,!1,"deliveries")).streamType!==rt)throw M("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");this.promptBody={runId:this.options.runId,agentCode:this.target.openclawAgentId||this.metadata.agentCode,delivery:this.metadata.delivery,expiresAt:this.expiresAt,mcpServer:this.mcp,attachOnly:this.options.attachOnly===!0,prompt:t};let s=await this.transport.request("POST",this.promptBody,!1,"deliveries",Number(this.options.sessionPromptTimeoutMs||X),i=>r?.(i));return this.finished=!0,s}async stop(){!this.finished&&this.promptBody&&await this.transport.request("DELETE",{runId:this.options.runId},!1,"deliveries")}};function Ce(e){let t=l(e.metadata)?e.metadata:{};return c(t.agentCode)}function an(e,t,r){let n=c(r?.openclawAgentId)||Ce(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var qt=class extends lt{constructor(t,r,n,s={},i={}){if(i.source==="channel_message")return new jt(t,r,n,s,i);let o=c(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",a=c(r.command)||"openclaw",u=Array.isArray(r.args)?r.args.map(String):[],d=u.length>0?u:["acp","--session",an(t,o,r)];super(t,{...r,command:a,args:d},s,i),this.boundSessionKey=an(t,o,r),this.binding=null}async sessionNew(t={}){if(t.mcpServers?.length){let r=[...this.target.args],n=r.indexOf("--session"),s=r.find(u=>u.startsWith("--session=")),i=s?s.slice(10):n<0?null:r[n+1];if(i&&i!==this.boundSessionKey)throw Object.assign(new Error("OpenClaw --session must match this Orcha task's private session"),{code:"OPENCLAW_SESSION_BINDING_CONFLICT"});i===null&&r.push("--session",this.boundSessionKey),this.target.args=r;let o=c(this.options.runId),a=Number(this.options.sandboxPolicy?.maxRuntimeSeconds||this.options.sessionPromptTimeoutMs/1e3||X/1e3);if(!o||!Ce(this.agent))throw new Error("OpenClaw MCP requires a trusted task and Agent identity");this.binding=new W(this.target,{runId:o,sessionKey:this.boundSessionKey,agentCode:c(this.target.openclawAgentId)||Ce(this.agent),expiresAt:new Date(Date.now()+a*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 yn}from"node:child_process";import{randomUUID as dt}from"node:crypto";import{existsSync as wn,mkdirSync as Di,readdirSync as En,readFileSync as Rn,realpathSync as Ot,rmSync as Hi,rmdirSync as Fi,statSync as $i,unlinkSync as Bi}from"node:fs";import{homedir as Sn,tmpdir as On}from"node:os";import{basename as Ue,dirname as ji,join as F,resolve as hn}from"node:path";async function cn(e){let t=await Br(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()}}import{createHash as Mi,randomUUID as Ui}from"node:crypto";import{mkdirSync as un,readFileSync as Pi,renameSync as Li,rmSync as ki,writeFileSync as ln}from"node:fs";import{homedir as vi}from"node:os";import{join as Rt}from"node:path";var dn=e=>Mi("sha256").update(JSON.stringify(e)).digest("hex"),nt=(e,t)=>Object.assign(new Error(t),{code:e}),fn=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Gt=class{constructor(t,r=Rt(vi(),".orcha","codex-sessions")){this.directory=Rt(r,dn(t))}async turn(t,r,n,s,i){if(!t)throw nt("BAD_REQUEST","Codex native turn requires a run ID");un(this.directory,{recursive:!0,mode:448});let o=Rt(this.directory,"active");try{un(o,{mode:448})}catch(f){throw f.code==="EEXIST"?nt("RUNTIME_SESSION_BUSY","Codex \u4EFB\u52A1\u4ECD\u5728\u8FD0\u884C\u6216\u4E0A\u8F6E\u5F02\u5E38\u4E2D\u65AD\uFF1B\u8BF7\u7B49\u5F85\u5B8C\u6210\uFF0C\u6216\u53D1\u9001 /new \u5F00\u59CB\u65B0\u4EFB\u52A1"):f}let a=Rt(this.directory,"session.json"),u,d=()=>{let f=`${a}.${Ui()}.pending`;ln(f,JSON.stringify(u),{mode:384}),Li(f,a)};try{try{u=JSON.parse(Pi(a,"utf8"))}catch(m){if(m.code!=="ENOENT")throw m}if(u&&!fn.test(u.threadId||""))throw nt("RUNTIME_OPERATION_NOT_FOUND","Codex \u4E0A\u8F6E\u672A\u80FD\u4FDD\u5B58\u539F\u751F\u4F1A\u8BDD\u6807\u8BC6\uFF0C\u8BF7\u53D1\u9001 /new");try{ln(Rt(this.directory,`${dn(t)}.run`),"",{flag:"wx",mode:384})}catch(m){throw m.code==="EEXIST"?nt("RUNTIME_OPERATION_NOT_FOUND","\u6B64\u8F6E Codex \u5DF2\u6267\u884C\u6216\u6267\u884C\u7ED3\u679C\u4E0D\u786E\u5B9A\uFF0C\u4E0D\u80FD\u91CD\u590D\u53D1\u9001"):m}u||={threadId:null},d();let f,p=m=>{if(f)return;let T=m.update?.sessionUpdate==="runtime_event"&&m.update.event;if(T?.type==="thread.started")try{if(!fn.test(T.thread_id||"")||u.threadId&&u.threadId!==T.thread_id)throw nt("CODEX_SESSION_MISMATCH","Codex \u8FD4\u56DE\u4E86\u4E0D\u540C\u7684\u539F\u751F\u4F1A\u8BDD\uFF0C\u8BF7\u53D1\u9001 /new");u.threadId=T.thread_id,d()}catch(S){f=S,i();return}n(m)},h=await r(u.threadId,p,m=>{!f&&u.threadId&&s?.(m)});if(f)throw f;if(!u.threadId)throw nt("CODEX_SESSION_MISSING","Codex \u6CA1\u6709\u8FD4\u56DE\u539F\u751F\u4F1A\u8BDD\u6807\u8BC6\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C\u5E76\u53D1\u9001 /new");return h}finally{ki(o,{recursive:!0})}}};function pn(e,t){let r=e.indexOf("exec");if(r<0||e.includes("resume")||e.includes("--ephemeral"))throw nt("BAD_REQUEST","Codex \u539F\u751F\u4F1A\u8BDD\u9700\u8981\u6807\u51C6 codex exec \u914D\u7F6E");return t?[...e.slice(0,r+1),"resume",t,...e.slice(r+1)]:e}var In=5e3,qi=2*60*1e3,Gi=2*60*1e3,Ki=12,zi=1e3,Vi=1500,Ji=1e3,Wi=/^(?:task|session)-[1-9]\d*(?::[1-9]\d*){4}(?![\s\S])/,Kt=24*60*60*1e3,St=new Set(["final_answer","final","complete","completed","done"]),Xi=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"]),Yi=new Set(["context_compacted","context_compaction","context_compressed"]);function Vt(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{yn("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 xe(e){Vt(e,"SIGTERM");let t=setTimeout(()=>Vt(e,"SIGKILL"),In);return t.unref?.(),t}function H(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>H(t)).join("");if(!l(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let r=H(e[t]);if(r)return r}return""}function Cn(e){if(!l(e))return"";let t=l(e.payload)?e.payload:{};if(c(e.type)==="event_msg"){if(c(t.type)==="agent_message")return c(t.message);if(c(t.type)==="task_complete")return c(t.last_agent_message)}if(c(e.type)==="response_item"&&c(t.type)==="message"&&c(t.role)==="assistant")return H(t.content)||H(t.message);if(c(e.type)==="result")return H(e.result);let r=H(e.delta)||H(e.text)||H(e.content);if(r)return r;let n=l(e.item)?e.item:{};return["message","agent_message"].includes(c(n.type))||c(n.role)==="assistant"?H(n.content)||H(n.text)||H(n.message):""}function xn(e,t={}){return Se(e,{source:"codex_cli_image_generation",...t})}function An(e,t){$t(e.artifacts,t)}function Nn(e){return tt(Oe(e))}function Pe(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{},r=c(e.type),n=c(t.type);if(r==="event_msg"&&n==="task_complete")return!0;let s=c(t.phase||t.status||t.stage).toLowerCase();if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&c(t.role)==="assistant")return St.has(s);let i=l(e.item)?e.item:{};return r==="item.completed"&&c(i.type)==="agent_message"?!0:r==="result"&&e.is_error!==!0?c(e.result).length>0:!1}function Ae(e){let t=c(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=Ue(c(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function mn(e,t,r){let n=l(t.error)?t.error:{},s=c(n.message)||H(t.error)||c(t.result)||c(t.message)||r;return Object.assign(new Error(s),{code:e})}function Qi(e,t){if(!l(e))return null;let r=c(e.type).toLowerCase();if(t==="codex")return r==="turn.completed"?{status:"completed",result:{stopReason:"end_turn"}}:r==="turn.failed"?{status:"failed",error:mn("RUNTIME_CODEX_TURN_FAILED",e,"Codex turn failed")}:null;if(t==="claude"&&r==="result"){let n=c(e.subtype).toLowerCase();return e.is_error===!0||n.startsWith("error")||["failed","failure"].includes(n)?{status:"failed",error:mn("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...c(e.result)?{output:c(e.result)}:{}}}}return null}function gn(e){return l(e)?c(e.phase||e.status||e.stage).toLowerCase():""}function Zi(e){if(!l(e)||Pe(e))return!1;let t=l(e.payload)?e.payload:{},r=c(e.type),n=c(t.type),s=gn(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&c(t.role)==="assistant")return!!(s&&!St.has(s));let i=l(e.item)?e.item:{},o=gn(i);return c(i.role)==="assistant"||c(i.type)==="message"?!!(o&&!St.has(o)):!1}function to(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:Ue(e)==="codex"}function eo(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:Ue(e)==="codex"}function bn(e){return Math.max(20,y(e.codexTranscriptPollMs||e.transcriptPollMs,zi))}function ro(e){return Math.max(0,y(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,Vi))}function Jt(e){if(typeof e=="boolean")return e;let t=c(e).toLowerCase();return["true","1","yes","y","on"].includes(t)?!0:["false","0","no","n","off"].includes(t)?!1:null}function Le(e){let t=l(e?.metadata)?e.metadata:{};return l(t._runtimeBridge)?t._runtimeBridge:{}}function Ne(e){return c(Le(e).promptKind).toLowerCase()}function no(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=Jt(r);if(n!=null)return n}return Ne(t)==="chat"}function so(e,t){let r=Le(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=Jt(s);if(i!=null)return i}let n=Ne(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=Jt(s);if(i!=null)return i}return Ne(e)==="chat"}function io(e){let t=Le(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=Jt(r);if(n!=null)return n}return null}function oo(e,t){let r=io(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function ao(e,t){return!e.finalTextOnly||t}function Mn(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 Un(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 co(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function uo(e,t){let r=l(e.env)?e.env:{},n=c(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||F(On(),"orcha-runtime-artifacts"),s=c(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||dt(),i=F(n,s),o=F(i,dt());return Di(o,{recursive:!0}),{root:o,realRoot:Ot(o),sessionRoot:i,realSessionRoot:Ot(i)}}function lo(e){let t=c(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:Ot(t),sessionRoot:"",realSessionRoot:""}}function Pn(e){return c(l(e)?e.root:e)}function _n(e){let t=Pn(e),r=c(l(e)?e.sessionRoot:ji(t)),n=c(l(e)?e.realSessionRoot:"");if(r)try{if(n&&Ot(r)!==n)return;Fi(r)}catch{}}function fo(e,t={}){let r=Pn(e),n=c(l(e)?e.realRoot:"");if(r){try{if(n&&Ot(r)!==n){g("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{_n(e);return}try{Hi(r,{recursive:!0,force:!0})}catch(s){g("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:r,error:String(s?.message||s)});return}_n(e)}}function po(e,t,r=null){return{trustedFileRoots:[t,c(r?.artifactDirectory),c(r?.homeDirectory),...A(e.trustedArtifactRoots),...A(e.trustedFileRoots),...A(e.artifactRoots),...A(e.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(r?.pathMappings)?r.pathMappings:[]}}function Ln(e){let t=c(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let r=l(e.env)?e.env:{},n=c(e.codexHome||r.CODEX_HOME||process.env.CODEX_HOME)||F(Sn(),".codex");return F(n,"sessions")}function ho(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 F(e,n,s,i)}function kn(e,t,r){let n=new Set;for(let s of[t-Kt,t,t+Kt,r-Kt,r,r+Kt])n.add(ho(e,s));return[...n].filter(s=>wn(s))}function mo(e,t,r){let n=Ln(e),s=t-qi,i=r+Gi,o=[];for(let a of kn(n,t,r)){let u=[];try{u=En(a)}catch{continue}for(let d of u){if(!d.endsWith(".jsonl"))continue;let f=F(a,d);try{let p=$i(f);if(!p.isFile()||p.mtimeMs<s||p.mtimeMs>i)continue;o.push({path:f,mtimeMs:p.mtimeMs})}catch{}}}return o.sort((a,u)=>u.mtimeMs-a.mtimeMs).slice(0,Ki)}function go(e,t,r=t){let n=Ln(e),s=new Set;for(let i of kn(n,t,r)){let o=[];try{o=En(i)}catch{continue}for(let a of o)a.endsWith(".jsonl")&&s.add(F(i,a))}return s}function be(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)be(n,t,r+1);return}if(l(e))for(let n of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])n in e&&be(e[n],t,r+1)}}function vn(e){return c(e).replace(/\s+/g," ")}function _o(e){let t=vn(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 a=t.slice(Math.max(0,o),Math.max(0,o)+r).trim();a.length>=40&&!s.has(a)&&(s.add(a),i.push(a))}return i}function To(e,t){let r=_o(t);if(!r.length)return!1;let n=[];for(let i of e)be(i,n);let s=vn(n.join(" "));return r.every(i=>s.includes(i))}function yo(e){return e.find(t=>l(t)&&c(t.type)==="session_meta"&&l(t.payload))||null}function wo(e){let t=l(e?.payload)?e.payload:{},r=c(e?.timestamp||t.timestamp),n=Date.parse(r);return Number.isFinite(n)?n:Number.NaN}function Eo(e){let t=c(e.originator),r=c(e.source);if(t!=="codex_exec"&&r!=="exec"||c(e.parent_thread_id))return!1;let n=c(e.thread_source);if(n&&n!=="user")return!1;let s=c(e.session_id),i=c(e.id);return!(s&&i&&s!==i)}function Ro(e,t,r){if(!To(e,t.promptText))return!1;let n=yo(e);if(!n)return!1;let s=n.payload;if(!Eo(s))return!1;let i=wo(n);if(!Number.isFinite(i)||i<t.startedAtMs-5e3||i>r+5e3)return!1;let o=c(t.target.cwd),a=c(s.cwd);return!(o&&a&&hn(o)!==hn(a))}function Tn(e){try{return Oo(Rn(e,"utf8"))}catch{return null}}function So(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=Tn(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of mo(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=Tn(s.path);!i||!Ro(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,g("warn","runtime.cli","codex transcript fallback disabled; multiple matching transcripts",{target:e.target.targetCode,sessionId:t,transcriptCount:n.length})),null):(e.matchedPath=n[0].path,g("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function Oo(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 Io(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{},r=c(e.type),n=c(t.type);return r==="event_msg"&&n==="image_generation_end"||r==="response_item"&&n==="image_generation_call"}function Co(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return c(e.type)==="response_item"&&Xi.has(c(t.type))}function xo(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return Yi.has(c(t.type))}function Ao(e,t,r,n){let s=Cn(e),i=Pe(e),o=0,a=0,u=0;if(s&&!i&&t.emitThoughtChunks&&Un(t,r,n,s)&&(u=1),s&&i){let d=t.emittedTexts.size?`
|
|
11
|
+
`;this.child.stdin.write(s,r)}onNotification(t,r){let n=this.notificationHandlers.get(t)||new Set;return n.add(r),this.notificationHandlers.set(t,n),()=>{n.delete(r),n.size===0&&this.notificationHandlers.delete(t)}}onRequest(t,r){return this.requestHandlers.set(t,r),()=>this.requestHandlers.delete(t)}onExit(t){return this.exitHandlers.add(t),()=>this.exitHandlers.delete(t)}rejectAll(t){for(let r of this.pending.values())clearTimeout(r.timer),r.reject(t);this.pending.clear()}handleExit(t,r){this.exited=!0,this.exitCode=t,this.exitSignal=r,this.rejectAll(new Error(`runtime exited before response (${t}/${r})`));for(let n of this.exitHandlers)n(t,r)}async waitForExit(t=5e3){return!this.child||this.exited?!0:await new Promise(r=>{let n=setTimeout(()=>{s(),r(!1)},t);n.unref?.();let s=()=>{clearTimeout(n),this.exitHandlers.delete(i)},i=()=>{s(),r(!0)};this.exitHandlers.add(i),this.exited&&i()})}signal(t){if(!this.child||this.exited)return!1;let r=this.child.pid;if(!r)return!1;try{return this.detached&&process.platform!=="win32"?process.kill(-r,t):this.child.kill(t),!0}catch(n){if(n?.code==="ESRCH")return this.exited=!0,!1;try{return this.child.kill(t),!0}catch(s){return s?.code!=="ESRCH"&&g("warn","runtime","runtime signal failed",{target:this.label,pid:r,signal:t,error:String(s)}),!1}}}async stop(t="stop",{termTimeoutMs:r=5e3,killTimeoutMs:n=2e3}={}){if(!(!this.child||this.exited)){if(this.stopPromise)return await this.stopPromise;this.stopPromise=(async()=>{if(!this.child||this.exited)return;let s=this.child.pid;g("info","runtime","stopping runtime",{target:this.label,reason:t,pid:s}),this.rejectAll(new Error(`runtime stopped: ${t}`)),this.signal("SIGTERM"),!await this.waitForExit(r)&&this.child&&!this.exited&&(g("warn","runtime","runtime did not exit after SIGTERM; force killing",{target:this.label,reason:t,pid:s}),this.signal("SIGKILL"),await this.waitForExit(n))})();try{await this.stopPromise}finally{this.stopPromise=null}}}};import{randomUUID as Xr}from"node:crypto";import{existsSync as fi,readFileSync as pi,realpathSync as Jr,statSync as hi}from"node:fs";import{basename as Yr,extname as Qr,isAbsolute as Et,join as mi,relative as Zr,resolve as Wr}from"node:path";var gi=25*1024*1024;function tn(e,t=""){let r=c(t);if(r)return r;let n=Qr(c(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function en(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 Ft(e){if(Array.isArray(e))return e.map(c).filter(Boolean);let t=c(e);return t?[t]:[]}function _i(e,t){let r=Zr(t,e);return r===""||!!r&&!r.startsWith("..")&&!Et(r)}function yi(e,t){let r=c(e);if(!r||!fi(r))return"";try{let n=Jr(r);for(let s of t)try{let i=Jr(s);if(_i(n,i))return n}catch{}}catch{return""}return""}function wi(e,t){let r=c(e);if(!r||!Et(r))return r;for(let n of Array.isArray(t)?t:[]){if(!l(n))continue;let s=c(n.runtimeRoot),i=c(n.hostRoot);if(!s||!i||!Et(s)||!Et(i))continue;let o=Zr(Wr(s),Wr(r));if(o===""||!o.startsWith("..")&&!Et(o))return o?mi(i,o):i}return r}function Ee(e,t,r={}){let n=c(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:Ti(n,t,r)}function Ti(e,t,r={}){let n=[...Ft(r.trustedFileRoots),...Ft(r.trustedFileRoot),...Ft(r.artifactRoots),...Ft(r.artifactRoot)],s=yi(wi(e,r.pathMappings),n);if(!s)return"";try{let i=hi(s);return!i.isFile()||i.size<=0||i.size>gi?"":`data:${t};base64,${pi(s).toString("base64")}`}catch{return""}}function A(...e){for(let t of e){let r=c(t);if(r)return r}return""}function Ei(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=A(n,e.previewUrl,e.fileUrl,e.imageUrl,e.dataUrl,e.url,e.uri,t.previewUrl,t.fileUrl,t.imageUrl,t.dataUrl,t.url,t.uri),o=Qr(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function Se(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!l(e))return null;let n=l(e.payload)?e.payload:{},s=c(e.type),i=c(n.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let o=A(n.call_id,n.id),a=A(n.saved_path,n.savedPath),u=A(n.revised_prompt,n.revisedPrompt),d=tn(a,n.mimeType||n.mime_type),f=en(n.result,d)||Ee(a,d,t);if(!f)return null;let p=f.startsWith("data:")?f:"",h=a?Yr(a):`${o||Xr()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:h||"Generated image",summary:u||"Generated image",content:{prompt:u||void 0,dataUrl:p||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:p||void 0,previewUrl:f,fileUrl:f,metadata:{source:r,eventType:i,callId:o||void 0,savedPath:a||void 0,filename:h,mimeType:d,revisedPrompt:u||void 0}}}function Ri(e){let t=l(e)?e:{},r=[];for(let n of["_artifacts","artifacts"]){let s=t[n];Array.isArray(s)&&r.push(...s)}for(let n of["_artifact","artifact"]){let s=t[n];l(s)&&r.push(s)}return r}function Si(e,t={}){let{source:r="runtime_artifact"}=t,n=l(e)?e:{};if(!Object.keys(n).length)return null;let s=l(n.content)?{...n.content}:{},i=l(n.metadata)?{...n.metadata}:{},o=A(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),a=A(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),u=A(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),d=Ei(n,s,u,o),f=d?tn(o,a):a;if(d){let x=A(n.dataUrl,s.dataUrl),_=x.startsWith("data:")?x:"",w=A(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),T=en(n.result??s.result,f)||_||Ee(o,f,t)||Ee(w,f,t);T&&(T.startsWith("data:")&&(s.dataUrl||=T),s.imageUrl||=T,s.previewUrl||=T,s.fileUrl||=T,f&&(s.mimeType||=f))}for(let[x,_]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let w=n[x];w!=null&&w!==""&&!(_ in s)&&(s[_]=w)}let p=A(n.fileUrl,n.downloadUrl,n.imageUrl,n.dataUrl,n.url,n.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),h=A(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),m=A(n.dataUrl,s.dataUrl,p.startsWith("data:")?p:"",h.startsWith("data:")?h:""),y=A(n.filename,i.filename,o?Yr(o):""),S=A(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:u,type:n.type||u,fieldKey:S,title:A(n.title,y,"Runtime artifact"),summary:A(n.summary,s.prompt,n.title,y,"Runtime artifact"),content:s,dataUrl:m||void 0,fileUrl:p||void 0,previewUrl:h||void 0,metadata:{...i,source:A(i.source,r),savedPath:o||i.savedPath,filename:y||i.filename,mimeType:f||i.mimeType}}}function $t(e,t){if(!t||!e)return;let r=l(t.metadata)?t.metadata:{},n=A(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||Xr(),s=e.get(n);if(!s){e.set(n,t);return}s.content={...l(s.content)?s.content:{},...l(t.content)?t.content:{}},s.metadata={...l(s.metadata)?s.metadata:{},...r},s.previewUrl=t.previewUrl||s.previewUrl,s.fileUrl=t.fileUrl||s.fileUrl,s.summary=t.summary||s.summary,s.title=t.title||s.title}function Re(e,t,r={}){for(let n of Ri(e))$t(t,Si(n,r))}function Oe(e){if(!l(e)||!l(e.payload))return l(e)?e:{value:e};let t=c(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 Vr(e,t,r){if(!l(e))return e;let n=l(e.event)?e.event:null;return n?($t(t,Se(n,r)),{...e,event:Oe(n)}):e}function rn(e,t,r={}){if(!l(e))return e;Re(e,t,r);let n=Vr(e,t,r),s=l(n.update)?Vr(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function nn(e,t,r={}){let n=l(e)?{...e}:{};Re(n,t,r),Re(l(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function sn(e,t){let r=E(e,t);return r>0?r:t}var lt=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=c(this.target.command);if(!t)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let r={command:t,args:b(this.target.args),cwd:et(this.target,this.agent.workspace),environment:l(this.target.env)?this.target.env:{}},n=this.options.prepareLaunch?await this.options.prepareLaunch(r):{...r,environment:{...process.env,...r.environment},cleanup:async()=>{}};this.launch=n,this.launchCleanup=n.cleanup,this.proc=new Ht({command:n.command,args:n.args,cwd:n.cwd,env:n.environment,label:`${this.agent.agentId}:${this.agent.targetCode}`,framing:c(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:sn(this.target.initializeTimeoutMs,sn(this.options.initializeTimeoutMs,3e4)),initializeParams:{clientInfo:{name:"orcha-runtime-bridge",version:W},...l(this.target.initializeParams)?this.target.initializeParams:{}}})}catch(s){throw await this.proc?.stop("runtime startup failed"),this.proc=null,await this.cleanupLaunch(),s}}async sessionNew(t={}){return await this.ensureStarted(),this.proc.call("session/new",this.sessionNewParams(t))}sessionNewParams(t={}){let r=Array.isArray(t.mcpServers)?t.mcpServers:Array.isArray(this.target.mcpServers)?this.target.mcpServers:[];return{...t,mcpServers:r}}async sessionPrompt(t,r){await this.ensureStarted();let n=c(t.sessionId),s=new Map,i=this.artifactOptions(),o=this.proc.onNotification("session/update",u=>{let d=c(u.sessionId);(!d||d===n)&&r(rn(u,s,i))}),a=async u=>this.callbacks.onPermissionRequest?.({agent:this.agent,runtimeSessionId:n,request:u,emitUpdate:r})||{outcome:"denied",reason:"permission handler is not configured"};n&&this.permissionHandlers.set(n,a),this.permissionHandlers.set("*",a);try{let u=await this.proc.call("session/prompt",t,this.options.sessionPromptTimeoutMs);return nn(u,s,i)}finally{o(),n&&this.permissionHandlers.delete(n),this.permissionHandlers.delete("*")}}async sessionCancel(t){return await this.ensureStarted(),this.proc.call("session/cancel",t,5e3).catch(()=>({ok:!0}))}async handlePermissionRequest(t){let r=c(t.sessionId),n=this.permissionHandlers.get(r)||this.permissionHandlers.get("*");return n?n(t):{outcome:"denied",reason:"no active Orcha permission handler"}}artifactSource(){return c(this.target.type||"acp")==="openclaw"?"openclaw_image_generation":"acp_runtime_image_generation"}artifactOptions(){let t=l(this.target.env)?this.target.env:{};return{source:this.artifactSource(),trustedFileRoots:[c(this.launch?.artifactDirectory),c(this.launch?.homeDirectory),c(this.target.artifactRoot),c(this.target.artifactDir),c(this.target.runtimeArtifactRoot),c(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{existsSync as on,readFileSync as Oi}from"node:fs";import{dirname as Ii,resolve as Bt}from"node:path";import{fileURLToPath as Ci}from"node:url";var xi=/^[A-Za-z_][A-Za-z0-9_]*$/,X=24*60*60*1e3;function an(e=process.env,t=process.cwd()){let r=c(e.ORCHA_RUNTIME_ENV_FILE),n=r?Bt(t,r):Bt(t,".env");if(!on(n))return r&&g("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Oi(n,"utf8");for(let o of i.split(/\r?\n/)){let a=bi(o);if(!a)continue;let[u,d]=a;Object.prototype.hasOwnProperty.call(e,u)||(e[u]=d,s.push(u))}return g("info","config","runtime env file loaded",{path:n,keyCount:s.length}),{loaded:!0,path:n,keys:s}}function cn(e=process.env){let t=c(e.ORCHA_RUNTIME_MODE||(e.ORCHA_RUNTIME_ORCHA_URL?"node":"server")),r=c(e.ORCHA_RUNTIME_BRIDGE_HOST||"127.0.0.1"),n=!1,s=Ii(Ci(import.meta.url)),i=Bt(s,"sandbox","broker.js"),o=Bt(s,"orcha-runtime-sandbox-broker.js"),a=on(i)?i:o,u=c(e.ORCHA_RUNTIME_SANDBOX_BROKER_COMMAND);return{mode:t,host:r,port:E(e.ORCHA_RUNTIME_BRIDGE_PORT,5588),token:e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",orchaUrl:c(e.ORCHA_RUNTIME_ORCHA_URL),nodeToken:e.ORCHA_RUNTIME_NODE_TOKEN||e.ORCHA_RUNTIME_BRIDGE_TOKEN||"",nodeId:c(e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"local-runtime-node"),nodeName:c(e.ORCHA_RUNTIME_NODE_NAME||e.ORCHA_RUNTIME_NODE_ID||e.HOSTNAME||"Local Runtime Node"),reconnectMs:E(e.ORCHA_RUNTIME_RECONNECT_MS,3e3),connectTimeoutMs:E(e.ORCHA_RUNTIME_CONNECT_TIMEOUT_MS||e.ORCHA_RUNTIME_WS_CONNECT_TIMEOUT_MS,1e4),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:E(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),initializeTimeoutMs:E(e.ORCHA_RUNTIME_INITIALIZE_TIMEOUT_MS,3e4),sessionPromptTimeoutMs:E(e.ORCHA_RUNTIME_SESSION_PROMPT_TIMEOUT_MS,X),permissionRequestTimeoutMs:E(e.ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS,3e5),sessionIdleTtlMs:E(e.ORCHA_RUNTIME_SESSION_IDLE_TTL_MS,6e5),sessionCleanupIntervalMs:E(e.ORCHA_RUNTIME_SESSION_CLEANUP_INTERVAL_MS,6e4),maxSessionsPerTarget:E(e.ORCHA_RUNTIME_MAX_SESSIONS_PER_TARGET,8),openClawSessionIdleTtlMs:E(e.ORCHA_RUNTIME_OPENCLAW_SESSION_IDLE_TTL_MS,6e4),openClawMaxSessions:E(e.ORCHA_RUNTIME_OPENCLAW_MAX_SESSIONS,1),heartbeatIntervalMs:E(e.ORCHA_RUNTIME_HEARTBEAT_INTERVAL_MS,15e3),sandboxRequired:n,sandboxBrokerCommand:u||process.execPath,sandboxBrokerArguments:Ie(e.ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS,"ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS",u?[]:[a]),sandboxProbeTimeoutMs:E(e.ORCHA_RUNTIME_SANDBOX_PROBE_TIMEOUT_MS,1e4),sandboxTempRoot:c(e.ORCHA_RUNTIME_SANDBOX_TEMP_ROOT),trustedWorkspaceRoots:Ie(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:Ie(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:Ni(e.ORCHA_RUNTIME_EGRESS_PROXY_REQUIRED,t==="node"),egressProxySocket:c(e.ORCHA_RUNTIME_EGRESS_PROXY_SOCKET),egressProxyToken:c(e.ORCHA_RUNTIME_EGRESS_PROXY_TOKEN),egressGrantMaxTtlMs:E(e.ORCHA_RUNTIME_EGRESS_GRANT_MAX_TTL_MS,9e5),targets:Ai(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Ai(e){if(!c(e))return{};try{let t=JSON.parse(e);if(l(t))return t}catch(t){g("warn","config","invalid ORCHA_RUNTIME_TARGETS_JSON",{error:String(t)})}return{}}function Ni(e,t){let r=c(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 Ie(e,t,r=[]){let n=c(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 bi(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(!xi.test(s))return null;let i=Mi(r.slice(n+1).trim());return[s,i]}function Mi(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?Ui(r):r}return Pi(e).trim()}function Ui(e){return e.replaceAll("\\n",`
|
|
12
|
+
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function Pi(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}var jt=class{constructor(t,r,n,s,i={}){this.agent=t,this.target=r,this.options=i,this.sessionKey=n,this.mcp=null,this.metadata=null,this.finished=!1,this.transport=new V(r,{runId:i.runId}),this.expiresAt=new Date(Date.now()+Number(i.sandboxPolicy?.maxRuntimeSeconds||i.sessionPromptTimeoutMs/1e3||X/1e3)*1e3).toISOString()}async sessionNew({mcpServers:t,metadata:r}){if(r?.source!=="channel_message"||r.delivery?.dispatchMode!=="bridge")throw new Error("Invalid native Channel dispatch");return this.mcp=t[0],this.metadata=r,{sessionId:this.sessionKey}}async refreshMcpServers(t){this.mcp=t[0],this.promptBody&&await this.transport.request("PATCH",{...this.promptBody,mcpServer:this.mcp,attachOnly:!0},!1,"deliveries")}async sessionPrompt({prompt:t},r){if((await this.transport.request("GET",void 0,!1,"deliveries")).streamType!==nt)throw P("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");this.promptBody={runId:this.options.runId,agentCode:this.target.openclawAgentId||this.metadata.agentCode,delivery:this.metadata.delivery,expiresAt:this.expiresAt,mcpServer:this.mcp,attachOnly:this.options.attachOnly===!0,prompt:t};let s=await this.transport.request("POST",this.promptBody,!1,"deliveries",Number(this.options.sessionPromptTimeoutMs||X),i=>r?.(i));return this.finished=!0,s}async stop(){!this.finished&&this.promptBody&&await this.transport.request("DELETE",{runId:this.options.runId},!1,"deliveries")}};function Ce(e){let t=l(e.metadata)?e.metadata:{};return c(t.agentCode)}function un(e,t,r){let n=c(r?.openclawAgentId)||Ce(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var qt=class extends lt{constructor(t,r,n,s={},i={}){if(i.source==="channel_message")return new jt(t,r,n,s,i);let o=c(n).replace(/[^A-Za-z0-9._-]+/g,"-")||"default",a=c(r.command)||"openclaw",u=Array.isArray(r.args)?r.args.map(String):[],d=u.length>0?u:["acp","--session",un(t,o,r)];super(t,{...r,command:a,args:d},s,i),this.boundSessionKey=un(t,o,r),this.binding=null}async sessionNew(t={}){if(t.mcpServers?.length){let r=[...this.target.args],n=r.indexOf("--session"),s=r.find(u=>u.startsWith("--session=")),i=s?s.slice(10):n<0?null:r[n+1];if(i&&i!==this.boundSessionKey)throw Object.assign(new Error("OpenClaw --session must match this Orcha task's private session"),{code:"OPENCLAW_SESSION_BINDING_CONFLICT"});i===null&&r.push("--session",this.boundSessionKey),this.target.args=r;let o=c(this.options.runId),a=Number(this.options.sandboxPolicy?.maxRuntimeSeconds||this.options.sessionPromptTimeoutMs/1e3||X/1e3);if(!o||!Ce(this.agent))throw new Error("OpenClaw MCP requires a trusted task and Agent identity");this.binding=new V(this.target,{runId:o,sessionKey:this.boundSessionKey,agentCode:c(this.target.openclawAgentId)||Ce(this.agent),expiresAt:new Date(Date.now()+a*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 On}from"node:child_process";import{randomUUID as dt}from"node:crypto";import{existsSync as In,mkdirSync as Ji,readdirSync as Cn,readFileSync as xn,realpathSync as Ot,rmSync as Wi,rmdirSync as Vi,statSync as Xi,unlinkSync as Yi}from"node:fs";import{homedir as An,tmpdir as Nn}from"node:os";import{basename as Pe,dirname as Qi,join as k,resolve as wn}from"node:path";import{createHash as ln}from"node:crypto";import{constants as xe}from"node:fs";import{open as Li,realpath as dn}from"node:fs/promises";import{basename as ki,isAbsolute as vi,relative as Di,resolve as Hi}from"node:path";var Fi=32*1024*1024,$i={name:"send_file",description:"Send one explicitly selected local file to the current OrchaAI conversation. Use this to deliver images, PDFs, documents, spreadsheets or other files to the user; viewing an image or writing a local Markdown link does not send it. path must be in the current workspace, this Codex thread's generated_images directory, or a configured artifact root. Copy other intended deliverables into the workspace first. Success means the attachment message is saved; do not send it again or embed the local path. Internal previews and intermediate files need not be sent.",inputSchema:{type:"object",additionalProperties:!1,required:["path"],properties:{path:{type:"string",minLength:1,description:"Absolute file path, or a path relative to the current workspace."},message:{type:"string",maxLength:1e4,description:"Optional caption for the attachment message."}}}};function fn(e){return{...$i,async call(t,{upstream:r,signal:n}){if(!t||typeof t.path!="string"||!t.path.trim()||Object.keys(t).some(T=>!["path","message"].includes(T))||t.message!==void 0&&(typeof t.message!="string"||t.message.length>1e4))throw new Error("send_file requires a file path and an optional caption of at most 10000 characters");let{cwd:s,roots:i}=e();if(!s)throw new Error("The current file delivery workspace is unavailable");let o=await dn(Hi(s,t.path)),a=!1;for(let T of i)try{let R=Di(await dn(T),o);(!R||R!==".."&&!R.startsWith("../")&&!R.startsWith("..\\")&&!vi(R))&&(a=!0)}catch{}if(!a)throw new Error("File is outside the current workspace and authorized artifact roots");let u=await Li(o,xe.O_RDONLY|xe.O_NOFOLLOW|xe.O_NONBLOCK),d;try{let T=await u.stat();if(!T.isFile()||T.size<=0||T.size>Fi)throw new Error("Select a non-empty regular file of at most 32 MiB");d=Buffer.alloc(T.size);let R=0;for(;R<d.length;){let{bytesRead:M}=await u.read(d,R,d.length-R,R);if(!M)throw new Error("File changed while preparing delivery; retry after it is saved");R+=M}let N=await u.stat();if(N.size!==T.size||N.mtimeMs!==T.mtimeMs)throw new Error("File changed while preparing delivery; retry after it is saved")}finally{await u.close()}let f=t.message||"",p=ki(o),h=ln("sha256").update(d).digest("hex"),m=ln("sha256").update(JSON.stringify([o,h,f])).digest("hex"),y=new FormData;y.set("deliveryId",m),y.set("message",f),y.set("file",new Blob([d]),p);let S=new URL(r.url);S.pathname=`${S.pathname.replace(/\/$/,"")}/files`;let x=await fetch(S,{method:"POST",headers:{authorization:r.headers.authorization},body:y,redirect:"error",signal:AbortSignal.any([n,AbortSignal.timeout(12e4)])});if(!x.ok)throw new Error(`File delivery failed (HTTP ${x.status}); no successful receipt was received`);let _=await x.json();if(!_.success)throw new Error(`File delivery failed: ${String(_.message||_.code||"request rejected").slice(0,512)}`);let w=_.data;if(!w?.accepted||typeof w.messageId!="string"||!w.messageId||typeof w.fileId!="string"||!w.fileId)throw new Error("File delivery did not return a saved message and file receipt");return{content:[{type:"text",text:JSON.stringify(w)}],structuredContent:w,isError:!1}}}}async function pn(e,t){let r=await qr(e,t?[fn(t)]:[]),n="ORCHA_TASK_MCP_TOKEN";return{args:["-c",`mcp_servers.orcha={url=${JSON.stringify(r.url)},bearer_token_env_var=${JSON.stringify(n)},required=true}`],environment:{[n]:r.token},refresh:s=>r.refresh(s),close:()=>r.close()}}import{createHash as Bi,randomUUID as ji}from"node:crypto";import{mkdirSync as hn,readFileSync as qi,renameSync as Ki,rmSync as Gi,writeFileSync as mn}from"node:fs";import{homedir as zi}from"node:os";import{join as Rt}from"node:path";var gn=e=>Bi("sha256").update(JSON.stringify(e)).digest("hex"),st=(e,t)=>Object.assign(new Error(t),{code:e}),_n=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Kt=class{constructor(t,r=Rt(zi(),".orcha","codex-sessions")){this.directory=Rt(r,gn(t))}async turn(t,r,n,s,i){if(!t)throw st("BAD_REQUEST","Codex native turn requires a run ID");hn(this.directory,{recursive:!0,mode:448});let o=Rt(this.directory,"active");try{hn(o,{mode:448})}catch(f){throw f.code==="EEXIST"?st("RUNTIME_SESSION_BUSY","Codex \u4EFB\u52A1\u4ECD\u5728\u8FD0\u884C\u6216\u4E0A\u8F6E\u5F02\u5E38\u4E2D\u65AD\uFF1B\u8BF7\u7B49\u5F85\u5B8C\u6210\uFF0C\u6216\u53D1\u9001 /new \u5F00\u59CB\u65B0\u4EFB\u52A1"):f}let a=Rt(this.directory,"session.json"),u,d=()=>{let f=`${a}.${ji()}.pending`;mn(f,JSON.stringify(u),{mode:384}),Ki(f,a)};try{try{u=JSON.parse(qi(a,"utf8"))}catch(m){if(m.code!=="ENOENT")throw m}if(u&&!_n.test(u.threadId||""))throw st("RUNTIME_OPERATION_NOT_FOUND","Codex \u4E0A\u8F6E\u672A\u80FD\u4FDD\u5B58\u539F\u751F\u4F1A\u8BDD\u6807\u8BC6\uFF0C\u8BF7\u53D1\u9001 /new");try{mn(Rt(this.directory,`${gn(t)}.run`),"",{flag:"wx",mode:384})}catch(m){throw m.code==="EEXIST"?st("RUNTIME_OPERATION_NOT_FOUND","\u6B64\u8F6E Codex \u5DF2\u6267\u884C\u6216\u6267\u884C\u7ED3\u679C\u4E0D\u786E\u5B9A\uFF0C\u4E0D\u80FD\u91CD\u590D\u53D1\u9001"):m}u||={threadId:null},d();let f,p=m=>{if(f)return;let y=m.update?.sessionUpdate==="runtime_event"&&m.update.event;if(y?.type==="thread.started")try{if(!_n.test(y.thread_id||"")||u.threadId&&u.threadId!==y.thread_id)throw st("CODEX_SESSION_MISMATCH","Codex \u8FD4\u56DE\u4E86\u4E0D\u540C\u7684\u539F\u751F\u4F1A\u8BDD\uFF0C\u8BF7\u53D1\u9001 /new");u.threadId=y.thread_id,d()}catch(S){f=S,i();return}n(m)},h=await r(u.threadId,p,m=>{!f&&u.threadId&&s?.(m)});if(f)throw f;if(!u.threadId)throw st("CODEX_SESSION_MISSING","Codex \u6CA1\u6709\u8FD4\u56DE\u539F\u751F\u4F1A\u8BDD\u6807\u8BC6\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C\u5E76\u53D1\u9001 /new");return h}finally{Gi(o,{recursive:!0})}}};function yn(e,t){let r=e.indexOf("exec");if(r<0||e.includes("resume")||e.includes("--ephemeral"))throw st("BAD_REQUEST","Codex \u539F\u751F\u4F1A\u8BDD\u9700\u8981\u6807\u51C6 codex exec \u914D\u7F6E");return t?[...e.slice(0,r+1),"resume",t,...e.slice(r+1)]:e}var bn=5e3,Zi=2*60*1e3,to=2*60*1e3,eo=12,ro=1e3,no=1500,so=1e3,io=/^(?:task|session)-[1-9]\d*(?::[1-9]\d*){4}(?![\s\S])/,Gt=24*60*60*1e3,St=new Set(["final_answer","final","complete","completed","done"]),oo=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"]),ao=new Set(["context_compacted","context_compaction","context_compressed"]);function Jt(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{On("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 Ae(e){Jt(e,"SIGTERM");let t=setTimeout(()=>Jt(e,"SIGKILL"),bn);return t.unref?.(),t}function F(e){if(typeof e=="string")return e;if(Array.isArray(e))return e.map(t=>F(t)).join("");if(!l(e))return"";for(let t of["text","delta","output_text","content","message","output"]){let r=F(e[t]);if(r)return r}return""}function Mn(e){if(!l(e))return"";let t=l(e.payload)?e.payload:{};if(c(e.type)==="event_msg"){if(c(t.type)==="agent_message")return c(t.message);if(c(t.type)==="task_complete")return c(t.last_agent_message)}if(c(e.type)==="response_item"&&c(t.type)==="message"&&c(t.role)==="assistant")return F(t.content)||F(t.message);if(c(e.type)==="result")return F(e.result);let r=F(e.delta)||F(e.text)||F(e.content);if(r)return r;let n=l(e.item)?e.item:{};return["message","agent_message"].includes(c(n.type))||c(n.role)==="assistant"?F(n.content)||F(n.text)||F(n.message):""}function Un(e,t){e.explicitFileDelivery||$t(e.artifacts,Se(t,{source:"codex_cli_image_generation",...e.artifactOptions}))}function Pn(e){return tt(Oe(e))}function Le(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{},r=c(e.type),n=c(t.type);if(r==="event_msg"&&n==="task_complete")return!0;let s=c(t.phase||t.status||t.stage).toLowerCase();if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&c(t.role)==="assistant")return St.has(s);let i=l(e.item)?e.item:{};return r==="item.completed"&&c(i.type)==="agent_message"?!0:r==="result"&&e.is_error!==!0?c(e.result).length>0:!1}function Ne(e){let t=c(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=Pe(c(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function Tn(e,t,r){let n=l(t.error)?t.error:{},s=c(n.message)||F(t.error)||c(t.result)||c(t.message)||r;return Object.assign(new Error(s),{code:e})}function co(e,t){if(!l(e))return null;let r=c(e.type).toLowerCase();if(t==="codex")return r==="turn.completed"?{status:"completed",result:{stopReason:"end_turn"}}:r==="turn.failed"?{status:"failed",error:Tn("RUNTIME_CODEX_TURN_FAILED",e,"Codex turn failed")}:null;if(t==="claude"&&r==="result"){let n=c(e.subtype).toLowerCase();return e.is_error===!0||n.startsWith("error")||["failed","failure"].includes(n)?{status:"failed",error:Tn("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...c(e.result)?{output:c(e.result)}:{}}}}return null}function En(e){return l(e)?c(e.phase||e.status||e.stage).toLowerCase():""}function uo(e){if(!l(e)||Le(e))return!1;let t=l(e.payload)?e.payload:{},r=c(e.type),n=c(t.type),s=En(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&c(t.role)==="assistant")return!!(s&&!St.has(s));let i=l(e.item)?e.item:{},o=En(i);return c(i.role)==="assistant"||c(i.type)==="message"?!!(o&&!St.has(o)):!1}function lo(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:Pe(e)==="codex"}function fo(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:Pe(e)==="codex"}function Ln(e){return Math.max(20,E(e.codexTranscriptPollMs||e.transcriptPollMs,ro))}function po(e){return Math.max(0,E(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,no))}function Wt(e){if(typeof e=="boolean")return e;let t=c(e).toLowerCase();return["true","1","yes","y","on"].includes(t)?!0:["false","0","no","n","off"].includes(t)?!1:null}function ke(e){let t=l(e?.metadata)?e.metadata:{};return l(t._runtimeBridge)?t._runtimeBridge:{}}function be(e){return c(ke(e).promptKind).toLowerCase()}function ho(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=Wt(r);if(n!=null)return n}return be(t)==="chat"}function mo(e,t){let r=ke(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=Wt(s);if(i!=null)return i}let n=be(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=Wt(s);if(i!=null)return i}return be(e)==="chat"}function go(e){let t=ke(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=Wt(r);if(n!=null)return n}return null}function _o(e,t){let r=go(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function yo(e,t){return!e.finalTextOnly||t}function kn(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 vn(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 wo(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function To(e,t){let r=l(e.env)?e.env:{},n=c(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||k(Nn(),"orcha-runtime-artifacts"),s=c(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||dt(),i=k(n,s),o=k(i,dt());return Ji(o,{recursive:!0}),{root:o,realRoot:Ot(o),sessionRoot:i,realSessionRoot:Ot(i)}}function Eo(e){let t=c(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:Ot(t),sessionRoot:"",realSessionRoot:""}}function Dn(e){return c(l(e)?e.root:e)}function Rn(e){let t=Dn(e),r=c(l(e)?e.sessionRoot:Qi(t)),n=c(l(e)?e.realSessionRoot:"");if(r)try{if(n&&Ot(r)!==n)return;Vi(r)}catch{}}function Ro(e,t={}){let r=Dn(e),n=c(l(e)?e.realRoot:"");if(r){try{if(n&&Ot(r)!==n){g("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{Rn(e);return}try{Wi(r,{recursive:!0,force:!0})}catch(s){g("warn","runtime.cli","runtime artifact directory cleanup failed",{...t,artifactRoot:r,error:String(s?.message||s)});return}Rn(e)}}function So(e,t,r=null){return{trustedFileRoots:[t,c(r?.artifactDirectory),c(r?.homeDirectory),...b(e.trustedArtifactRoots),...b(e.trustedFileRoots),...b(e.artifactRoots),...b(e.artifactFileRoots)].filter(Boolean),pathMappings:Array.isArray(r?.pathMappings)?r.pathMappings:[]}}function ve(e){let t=c(e.codexSessionsRoot||e.codexSessionRoot);if(t)return t;let r=l(e.env)?e.env:{},n=c(e.codexHome||r.CODEX_HOME||process.env.CODEX_HOME)||k(An(),".codex");return k(n,"sessions")}function Oo(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 k(e,n,s,i)}function Hn(e,t,r){let n=new Set;for(let s of[t-Gt,t,t+Gt,r-Gt,r,r+Gt])n.add(Oo(e,s));return[...n].filter(s=>In(s))}function Io(e,t,r){let n=ve(e),s=t-Zi,i=r+to,o=[];for(let a of Hn(n,t,r)){let u=[];try{u=Cn(a)}catch{continue}for(let d of u){if(!d.endsWith(".jsonl"))continue;let f=k(a,d);try{let p=Xi(f);if(!p.isFile()||p.mtimeMs<s||p.mtimeMs>i)continue;o.push({path:f,mtimeMs:p.mtimeMs})}catch{}}}return o.sort((a,u)=>u.mtimeMs-a.mtimeMs).slice(0,eo)}function Co(e,t,r=t){let n=ve(e),s=new Set;for(let i of Hn(n,t,r)){let o=[];try{o=Cn(i)}catch{continue}for(let a of o)a.endsWith(".jsonl")&&s.add(k(i,a))}return s}function Me(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)Me(n,t,r+1);return}if(l(e))for(let n of["payload","item","text","delta","output_text","content","message","output","input","prompt","last_agent_message","revised_prompt"])n in e&&Me(e[n],t,r+1)}}function Fn(e){return c(e).replace(/\s+/g," ")}function xo(e){let t=Fn(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 a=t.slice(Math.max(0,o),Math.max(0,o)+r).trim();a.length>=40&&!s.has(a)&&(s.add(a),i.push(a))}return i}function Ao(e,t){let r=xo(t);if(!r.length)return!1;let n=[];for(let i of e)Me(i,n);let s=Fn(n.join(" "));return r.every(i=>s.includes(i))}function No(e){return e.find(t=>l(t)&&c(t.type)==="session_meta"&&l(t.payload))||null}function bo(e){let t=l(e?.payload)?e.payload:{},r=c(e?.timestamp||t.timestamp),n=Date.parse(r);return Number.isFinite(n)?n:Number.NaN}function Mo(e){let t=c(e.originator),r=c(e.source);if(t!=="codex_exec"&&r!=="exec"||c(e.parent_thread_id))return!1;let n=c(e.thread_source);if(n&&n!=="user")return!1;let s=c(e.session_id),i=c(e.id);return!(s&&i&&s!==i)}function Uo(e,t,r){if(!Ao(e,t.promptText))return!1;let n=No(e);if(!n)return!1;let s=n.payload;if(!Mo(s))return!1;let i=bo(n);if(!Number.isFinite(i)||i<t.startedAtMs-5e3||i>r+5e3)return!1;let o=c(t.target.cwd),a=c(s.cwd);return!(o&&a&&wn(o)!==wn(a))}function Sn(e){try{return Lo(xn(e,"utf8"))}catch{return null}}function Po(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=Sn(e.matchedPath);return s?{path:e.matchedPath,events:s}:null}let n=[];for(let s of Io(e.target,e.startedAtMs,r)){if(e.baselinePaths.has(s.path))continue;let i=Sn(s.path);!i||!Uo(i,e,r)||n.push({path:s.path,events:i})}return n.length!==1?(n.length>1&&(e.disabled=!0,g("warn","runtime.cli","codex transcript fallback disabled; multiple matching transcripts",{target:e.target.targetCode,sessionId:t,transcriptCount:n.length})),null):(e.matchedPath=n[0].path,g("info","runtime.cli","codex transcript stream attached",{target:e.target.targetCode,sessionId:t}),n[0])}function Lo(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 ko(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{},r=c(e.type),n=c(t.type);return r==="event_msg"&&n==="image_generation_end"||r==="response_item"&&n==="image_generation_call"}function vo(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return c(e.type)==="response_item"&&oo.has(c(t.type))}function Do(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return ao.has(c(t.type))}function Ho(e,t,r,n){let s=Mn(e),i=Le(e),o=0,a=0,u=0;if(s&&!i&&t.emitThoughtChunks&&vn(t,r,n,s)&&(u=1),s&&i){let d=t.emittedTexts.size?`
|
|
13
13
|
|
|
14
|
-
${s}`:s;
|
|
15
|
-
`,le,
|
|
16
|
-
`}}})}}}async sessionCancel(t){let r=c(t.sessionId),n=this.active.get(r);return n?(g("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),
|
|
17
|
-
`)}function Bn(e,t,r=""){if(!jn(e))return e==null?null:{required:!0,status:"failed",outcome:c(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=Je(e),s=e.verificationPlan.required===!0;if(c(r)&&c(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=qo(t),o=e.verificationPlan.checks.map(u=>Xo(u,i));return{required:!0,status:o.some(u=>u.status==="failed")?"failed":o.some(u=>u.status==="missing")?"missing":"passed",outcome:e.outcome,goalContractHash:n,checks:o}}function jn(e){if(!l(e)||e.schemaVersion!==Fo||!c(e.outcome))return!1;let t=e.verificationPlan;if(!l(t)||typeof t.required!="boolean"||!Array.isArray(t.checks)||t.required&&t.checks.length===0)return!1;let r=new Set;for(let n of t.checks)if(!l(n)||!c(n.id)||r.has(c(n.id))||(r.add(c(n.id)),!Array.isArray(n.toolNames)||n.toolNames.length===0||n.toolNames.some(s=>!c(s)))||!Number.isSafeInteger(n.requiredMatches)||n.requiredMatches<1||n.arguments!==void 0&&!l(n.arguments))return!1;return!0}function qo(e){let t=new Map,r=[];for(let n of Array.isArray(e)?e:[]){let s=l(n?.update)?n.update:{},i=c(s.sessionUpdate);if(i==="runtime_event"){Go(s.event,t,r);continue}if(i==="tool_call"){let o=Yt(s)||`tool-${r.length+1}`,a=Xt(t,r,o),u=ze(s,s.name||s.toolName||s.kind);a.toolName=u.toolName,a.arguments=u.arguments,a.status=It(s.status),a.evidence=Zt(s);continue}if(i==="tool_call_update"){let o=Yt(s);if(!o)continue;let a=Xt(t,r,o),u=ze(s,s.name||s.toolName||s.kind);a.toolName||=u.toolName,Object.keys(a.arguments).length===0&&(a.arguments=u.arguments),a.status=It(s.status),a.evidence.push(...Zt(s))}}return r}function Go(e,t,r){let n=l(e)&&l(e.payload)?e.payload:l(e)?e:{},s=c(n.type);if(["function_call","custom_tool_call","local_shell_call","mcp_tool_call"].includes(s)){let a=Yt(n)||`runtime-${r.length+1}`,u=Xt(t,r,a),d=ze(n,n.name||n.tool||s,s);u.toolName=d.toolName,u.arguments=d.arguments,u.status=It(n.status),u.evidence.push(...Zt(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=Yt(n);if(!i)return;let o=Xt(t,r,i);o.status=Jo(n,o.toolName),o.evidence.push(...Zt(n))}function Xt(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 Ko(e){let t=c(e).toLowerCase();return jo.get(t)||t}function ze(e,t,r=""){let n=zo(e),s=c(r)==="mcp_tool_call"||c(e?.kind).toLowerCase()==="mcp",i=l(e?._meta)?e._meta:{},o=c(e?.server||e?.serverName||e?.server_name||e?.mcpServer||i.server||i.serverName).toLowerCase();if(s&&o==="orcha"){let a=c(e?.tool||e?.toolName||e?.name||t);return{toolName:"plugin_operation",arguments:{...n,...a?{operationCode:a}:{}}}}return{toolName:Ko(t),arguments:n}}function Yt(e){return l(e)?c(e.call_id||e.callId||e.toolCallId||e.id):""}function zo(e){if(!l(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=Vo(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 Vo(e){if(l(e))return structuredClone(e);if(typeof e!="string")return null;try{let t=JSON.parse(e);return l(t)?t:null}catch{return null}}function Jo(e,t){if(!l(e))return"unknown";let r=Qt(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function Qt(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return Wo(e,t,r);if(Array.isArray(e))return e.flatMap(o=>Qt(o,t+1,r));if(!l(e))return[];let n=[];typeof e.isError=="boolean"&&n.push(e.isError?"failed":"success"),typeof e.ok=="boolean"&&n.push(e.ok?"success":"failed"),typeof e.success=="boolean"&&n.push(e.success?"success":"failed");let s=It(e.status);s!=="unknown"&&n.push(s);let i=e.exitCode??e.exit_code;typeof i=="number"&&Number.isFinite(i)&&n.push(i===0?"success":"failed");for(let o of["output","result","structuredContent","content"])e[o]!==void 0&&n.push(...Qt(e[o],t+1,r));return n}function Wo(e,t,r){let n=e.trim();if(!n)return[];try{return Qt(JSON.parse(n),t+1,r)}catch{}if(r.parseCliExitCode!==!0)return[];let s=[];for(let i of n.matchAll(/(?:process\s+exited\s+with\s+code|exit\s+code\s*:?)\s*(-?\d+)/gi))s.push(Number(i[1])===0?"success":"failed");return s}function It(e){let t=c(e).toLowerCase();return $o.has(t)?"success":Bo.has(t)?"failed":"unknown"}function Zt(e){if(!l(e))return[];let t=l(e.output)?e.output:{},r=[e.verificationEvidence,l(e.verification)?e.verification.evidence:null,t.verificationEvidence,l(t.verification)?t.verification.evidence:null],n=[];for(let s of r)for(let i of Array.isArray(s)?s:s?[s]:[])!l(i)||!c(i.id)||n.push({id:c(i.id),status:It(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...c(i.message)?{message:c(i.message)}:{}});return n}function Xo(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&Ve(e.arguments||{},o.arguments)),n=c(e.evidenceId),s=r.filter(o=>o.status==="success"&&(!n||o.evidence.some(a=>a.id===n&&a.status==="success")));if(s.length>=e.requiredMatches)return Ke(e,"passed",s,`Runtime tool evidence passed ${s.length} times.`);let i=r.filter(o=>o.status==="failed"||n&&o.evidence.some(a=>a.id===n&&a.status==="failed"));return s.length===0&&i.length?Ke(e,"failed",i,"Runtime tool evidence failed."):Ke(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function Ke(e,t,r,n){let s=r.map(i=>i.toolCallId).filter(Boolean);return{id:e.id,status:t,message:n,...c(e.description)?{description:c(e.description)}:{},toolNames:e.toolNames,requiredMatches:e.requiredMatches,observedMatches:s.length,toolCallIds:s,...l(e.arguments)?{arguments:e.arguments}:{},...c(e.evidenceId)?{evidenceId:c(e.evidenceId)}:{}}}function Ve(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>Ve(r,t[n])):l(e)?l(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&Ve(n,t[r])):!1:Object.is(e,t)}function q(e){if(e===null||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="string")return Fn(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new Error("invalid_jcs_number");return JSON.stringify(Object.is(e,-0)?0:e)}if(Array.isArray(e))return`[${Array.from({length:e.length},(t,r)=>{if(!Object.hasOwn(e,r))throw new Error("invalid_jcs_json_value");return q(e[r])}).join(",")}]`;if(l(e))return`{${Object.keys(e).sort().map(t=>`${Fn(t)}:${q(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function Fn(e){return Yo(e),JSON.stringify(e)}function Yo(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 Qo}from"node:child_process";import{createHash as Zo,randomUUID as ta}from"node:crypto";import{constants as ea}from"node:fs";import{access as ra,mkdir as We,readdir as na,realpath as Ct,rm as sa,stat as ia}from"node:fs/promises";import oa from"node:http";import{tmpdir as aa}from"node:os";import{isAbsolute as xt,join as ft,relative as qn,resolve as Ye}from"node:path";var Qe=1,ca="orcha.process-isolation/v1",Ze="orcha.egress-proxy/v1",ua="--disable-wasm-trap-handler",te={read_only:0,workspace_write:1,workspace_network:2},Xe={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},la=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function st(e){if(!l(e))throw R("RUNTIME_SANDBOX_POLICY_REQUIRED","sandboxPolicy is required");let t=structuredClone(e),r=c(t.accessMode),n=c(t.accessModeCeiling);if(!(r in Xe)||!(n in Xe))throw R("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if(te[r]>te[n])throw R("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=Xe[r];if(t.filesystemMode!==s||t.networkMode!==i)throw R("RUNTIME_SANDBOX_POLICY_INVALID","runtime access profile does not match its mode");if(Number(t.policySchemaVersion)!==Qe||!Number.isInteger(Number(t.policyRevision))||Number(t.policyRevision)<1)throw R("RUNTIME_SANDBOX_POLICY_INVALID","unsupported sandbox policy schema or revision");for(let[a,u]of Object.entries({outsideWorkspaceAccess:"denied",hostAccess:"denied",hostEnvironmentAccess:"denied",dockerSocketAccess:"denied",environmentMode:"allowlist"}))if(t[a]!==u)throw R("RUNTIME_SANDBOX_POLICY_INVALID",`${a} cannot be relaxed`);let o=l(t.processIsolation)?t.processIsolation:{};if(o.mode!=="required"||o.backend==="direct")throw R("RUNTIME_SANDBOX_POLICY_INVALID","strong process isolation is required");if(Array.isArray(t.alwaysApprovedApprovalKeys)&&t.alwaysApprovedApprovalKeys.length)throw R("RUNTIME_SANDBOX_POLICY_INVALID","persistent runtime approvals are forbidden");return t}function Gn(e,t){let r=st(e),n=st(t);return te[n.accessMode]<te[r.accessMode]}async function Kn(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[Qe],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await Vn(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw R("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await ma(t,A(e.sandboxBrokerArguments),e.sandboxProbeTimeoutMs);if(r.enforced!==!0||c(r.protocolVersion)!=="orcha.runtime-sandbox-broker/v1"||!["bubblewrap","broker"].includes(c(r.backend)))throw R("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker did not report enforced isolation");let n=l(r.probes)?r.probes:{};for(let s of["emptyRoot","outsideWorkspaceDenied","hostFilesystemDenied","sensitiveFilesDenied","environmentAllowlist","dockerSocketDenied","networkNamespace","workspaceReadOnly","workspaceWrite","resourceLimits"])if(n[s]!==!0)throw R("RUNTIME_SANDBOX_UNAVAILABLE",`sandbox broker probe failed: ${s}`);return e.egressProxyRequired&&await Ta(e),{dispatchable:!0,enforced:!0,backend:c(r.backend),daemonStatus:"ok",daemonProtocolVersion:c(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[Qe],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function tr(e,t,r){let n=c(t.workspace||t.cwd),s=c(r),i=n||(t.allowRequestWorkspace===!0?s:"");if(!i||!xt(i))throw R("RUNTIME_WORKSPACE_NOT_CONFIGURED","runtime target must configure an absolute trusted workspace");let o=await Ct(i);if(!(await ia(o)).isDirectory())throw R("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>Ct(d))):[o]).some(d=>rr(d,o)))throw R("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function zn({config:e,target:t,command:r,args:n,cwd:s,environment:i,runId:o,agentId:a,sessionId:u,sandboxPolicy:d}){if(!e.sandboxRequired)return{command:r,args:[...n],cwd:s,environment:{...process.env,...i},tempDirectory:"",isolation:{enforced:!1,backend:"development_direct"},cleanup:async()=>{}};let f=st(d),p=await tr(e,t,s),h=await Ct(s);if(!rr(p,h))throw R("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let m=await Vn(e.sandboxBrokerCommand,process.env.PATH||"");if(!m)throw R("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let T=`runtime-${Zo("sha256").update(String(o)).digest("hex").slice(0,32)}`,S=Ye(e.sandboxTempRoot||ft(aa(),"orcha-runtime-sandboxes"));await We(S,{recursive:!0,mode:448});let N=ft(S,`${T}-${ta()}`),_=ft(N,"home"),w=ft(N,"artifacts");await We(_,{recursive:!0,mode:448}),await We(w,{recursive:!0,mode:448});let E=f.networkMode==="restricted"?await ga(e,{runId:String(o),instanceId:T,policyRevision:Number(f.policyRevision),ttlMs:Math.min(y(f.maxRuntimeSeconds,900)*1e3,e.egressGrantMaxTtlMs),maxTransferBytes:y(f.maxNetworkBytes,64*1024*1024)}):null,O={PATH:c(i.PATH||process.env.PATH),LANG:c(i.LANG||process.env.LANG||"C.UTF-8"),HOME:"/tmp/home",TMPDIR:"/tmp",USER:"orcha",LOGNAME:"orcha",SHELL:"/bin/sh",ORCHA_AGENT_ID:String(a),ORCHA_SESSION_ID:String(u),ORCHA_RUN_ID:String(o),ORCHA_RUNTIME_ARTIFACT_DIR:"/tmp/artifacts",...fa(t,i)};O.HOME="/tmp/home",O.TMPDIR="/tmp",O.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",O.NODE_OPTIONS=ua;let U={schemaVersion:ca,runId:String(o),instanceId:T,workspace:p,cwd:h,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await pa(p),temporaryDirectory:N,egressProxy:E,environment:O,resourceLimits:ha(f),readOnlyToolchainRoots:await da(e,t)},v=!1,D=async()=>{if(!v){v=!0;try{E&&await _a(e,E,{runId:String(o),instanceId:T})}finally{await sa(N,{recursive:!0,force:!0})}}};return{command:m,args:[...A(e.sandboxBrokerArguments),"--",r,...n],cwd:h,environment:{PATH:process.env.PATH||"",LANG:process.env.LANG||"C.UTF-8",ORCHA_PROCESS_ISOLATION_REQUEST:JSON.stringify(U)},tempDirectory:N,homeDirectory:_,artifactDirectory:w,pathMappings:[{runtimeRoot:"/tmp/artifacts",hostRoot:w},{runtimeRoot:"/tmp/home",hostRoot:_}],isolation:{enforced:!0,backend:"broker",instanceId:T,policyRevision:f.policyRevision},cleanup:D}}async function da(e,t){let r=A(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(A(e.trustedToolchainRoots).map(i=>Ct(i)));if(!n.length)throw R("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","target toolchain roots require ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS");let s=[];for(let i of r){if(!xt(i))throw R("RUNTIME_TOOLCHAIN_ROOT_INVALID","toolchain roots must be absolute");let o=await Ct(i);if(!n.some(a=>rr(a,o)))throw R("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function fa(e,t){let r=l(e.env)?e.env:{},n={};for(let[s,i]of Object.entries(r))/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&i!=null&&(n[s]=String(i));for(let s of["ORCHA_RUNTIME_PROMPT","ORCHA_RUNTIME_ARTIFACT_DIR"])t[s]!=null&&(n[s]=String(t[s]));return n}async function pa(e){let t=[],r=0,n=async s=>{let i;try{i=await na(s,{withFileTypes:!0})}catch(o){if(s===e)throw o;return}for(let o of i){if(r+=1,r>1e4)throw R("RUNTIME_WORKSPACE_SCAN_LIMIT_EXCEEDED","workspace contains more than 10000 entries");let a=ft(s,o.name),u=qn(e,a),d=o.name.toLowerCase();(la.has(d)||d.startsWith(".env."))&&t.push(u),o.isDirectory()&&!o.isSymbolicLink()&&await n(a)}};return await n(e),t.sort()}function ha(e){return{maxCpuSeconds:Math.max(1,y(e.maxRuntimeSeconds,900)),maxMemoryBytes:y(e.maxMemoryBytes,2*1024*1024*1024),maxProcesses:y(e.maxProcesses,128),maxOpenFiles:y(e.maxOpenFiles,1024),maxFileBytes:y(e.maxFileBytes,64*1024*1024)}}async function ma(e,t,r){return await new Promise((n,s)=>{let i=Qo(e,[...t,"--probe"],{env:{PATH:process.env.PATH||"",LANG:"C.UTF-8"},stdio:["ignore","pipe","pipe"],windowsHide:!0}),o=[],a=[];i.stdout.on("data",d=>o.push(Buffer.from(d))),i.stderr.on("data",d=>a.push(Buffer.from(d)));let u=setTimeout(()=>i.kill("SIGKILL"),Math.max(1e3,r));i.once("error",s),i.once("close",d=>{if(clearTimeout(u),d!==0){s(R("RUNTIME_SANDBOX_UNAVAILABLE",Buffer.concat(a).toString("utf8").trim()||`sandbox probe exited with ${d}`));return}try{n(JSON.parse(Buffer.concat(o).toString("utf8")))}catch{s(R("RUNTIME_SANDBOX_UNAVAILABLE","sandbox probe returned invalid JSON"))}})})}async function Vn(e,t){let r=c(e);if(!r)return"";let n=xt(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>ft(s,r));for(let s of n)try{return await ra(s,ea.X_OK),s}catch{}return""}async function ga(e,t){if(!e.egressProxyRequired)throw R("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await er(e,"POST","/v1/grants",{protocolVersion:Ze,...t}),n={socketPath:e.egressProxySocket,grantId:c(r.grantId),credential:c(r.credential)};if(!n.grantId||!n.credential)throw R("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy returned an invalid grant");return n}async function _a(e,t,r){await er(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:Ze,...r}).catch(()=>{})}async function Ta(e){let t=await er(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==Ze)throw R("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function er(e,t,r,n){if(!xt(e.egressProxySocket)||!e.egressProxyToken)throw R("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy socket and token are required");return await new Promise((s,i)=>{let o=oa.request({socketPath:e.egressProxySocket,path:r,method:t,headers:{Authorization:`Bearer ${e.egressProxyToken}`,Accept:"application/json",...n?{"Content-Type":"application/json"}:{}}},a=>{let u=[],d=0;a.on("data",f=>{d+=f.length,d>1048576?o.destroy(new Error("egress response is too large")):u.push(Buffer.from(f))}),a.once("end",()=>{try{let f=JSON.parse(Buffer.concat(u).toString("utf8")||"{}");(a.statusCode||500)>=400?i(R("RUNTIME_EGRESS_UNAVAILABLE",c(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 rr(e,t){let r=qn(Ye(e),Ye(t));return r===""||!r.startsWith("..")&&!xt(r)}function R(e,t){return Object.assign(new Error(t),{code:e})}var nr=24e3,sr=8,ir=50,or=6e3,wa=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),Ea=10*60*1e3,Ra=60*1e3,Sa=8,Oa=30*60*1e3,Ia=60*1e3,Ca=1,Yn=2400,xa=new Set(["max_tokens","max_output_tokens","length"]),Aa=new Set(["agent_message_chunk","tool_call","tool_call_update"]),Na=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),ba=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function Ma(e){if(!l(e))return{};let t={};for(let r of["name","code","serverName","serverCode","type","transport","url","command","protocolVersion"]){let n=c(e[r]);n&&(t[r]=n)}return t}function Ua(e){return(Array.isArray(e)?e:[]).map(Ma).sort((t,r)=>{let n=q(t),s=q(r);return n<s?-1:n>s?1:0})}function Pa(e){return!l(e)||e.verificationPlan?.required!==!0?!1:(Array.isArray(e.verificationPlan.checks)?e.verificationPlan.checks:[]).some(r=>l(r)&&Array.isArray(r.toolNames)&&r.toolNames.some(n=>c(n)==="plugin_operation"))}function La(e,t,r){let n=l(e?._meta)?e._meta:{};return{...l(e)?e:{},sessionId:t,update:l(e?.update)?e.update:{},_meta:{...n,orchaAgentId:r.agentId,runtimeSessionId:r.runtimeSessionId,bridgeUpdateId:re()}}}function k(e){return e==null||e===""?!1:typeof e=="string"?c(e)!=="":Array.isArray(e)?e.length>0:l(e)?Object.keys(e).length>0:!0}function Qn(e){let t=c(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return wa.has(t)}function Y(e,t){let r=y(e,t);return Number.isFinite(r)&&r>0?r:t}function At(e,t=!1){if(typeof e=="boolean")return e;let r=c(e).toLowerCase();return["true","1","yes","y","on"].includes(r)?!0:["false","0","no","n","off"].includes(r)?!1:t}function K(e){return c(e?.type||"echo")}function Zn(e){let t=K(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function ur(e){if(l(e)){if(Object.prototype.hasOwnProperty.call(e,"releaseAfterPrompt"))return e.releaseAfterPrompt;if(Object.prototype.hasOwnProperty.call(e,"disposeAfterPrompt"))return e.disposeAfterPrompt}}function ka(e){let t=String(e||"");if(ba.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 lr(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=or)return e;let r=e.length-or;return`${e.slice(0,or)}... [truncated ${r} characters]`}if(t>=sr)return Array.isArray(e)?`[array truncated at depth ${sr}, items=${e.length}]`:l(e)?`[object truncated at depth ${sr}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,ir).map(n=>lr(n,t+1));return e.length>ir&&r.push(`[truncated ${e.length-ir} items]`),r}if(l(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=ka(n)?"[REDACTED]":lr(s,t+1);return r}return String(e)}var va=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 Da(e){if(!l(e))return e;let t={};for(let r of va)k(e[r])&&(t[r]=e[r]);return t}function Ha(e){if(!l(e))return e;let t={...e};return l(t.renderedPayload)&&(t.renderedPayload=Da(t.renderedPayload)),t}function Fa(e){let t=l(e)?e:{},r={};k(t.metadata)&&(r.metadata=Ha(t.metadata));for(let[n,s]of Object.entries(t))Na.has(n)||n==="metadata"||k(s)&&(r[n]=s);return r}function $a(e){let t=l(e)?e:{},r=l(t.metadata)?t.metadata:{},n=l(r.renderedPayload)?r.renderedPayload:{};return l(t.resultContract)?t.resultContract:l(n.resultContract)?n.resultContract:{}}function ts(e){return c($a(e).kind).toLowerCase()==="decision"}function Ba(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:K(e)==="cli"}function Jn(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return At(t,Zn(e))}function ja(e,t){let r=l(e?.metadata)?{...e.metadata}:{},n=l(r._runtimeBridge)?{...r._runtimeBridge}:{},s=ur(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:Ba(t),releaseAfterPrompt:s===void 0?Jn(t):At(s,Jn(t)),requiresRuntimeResult:ts(e)},r}function qa(e){let t=Fa(e);if(!k(t))return"";let r=JSON.stringify(lr(t),null,2);if(r.length<=nr)return r;let n=r.length-nr;return`${r.slice(0,nr)}
|
|
18
|
-
... [truncated ${n} characters]`}function
|
|
19
|
-
`:"";t+=`${s}${n}`}}return t.trim()}function
|
|
20
|
-
`?1:0)).trim()}function
|
|
21
|
-
`)}function ec(e,t){let r=l(t)?{...t}:{},n=ns(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function rc(e,t){return{...e,_meta:{...l(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:hr(t)||"max_tokens"}}}}function nc(e,t){let r=typeof e?.output=="string"?e.output:pr(t),n=new L("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:hr(e)||"max_tokens",retryAttempted:!0},n}var se=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=yt(),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 Kn(this.config)}catch(t){this.sandboxCapabilities={...this.sandboxCapabilities,dispatchable:!1,enforced:!1,backend:"unavailable",daemonStatus:"unavailable",reason:c(t?.code||t?.message||t)||"sandbox_probe_failed"},g("error","runtime-bridge","runtime node sandbox probe failed; node will not accept work",{reason:this.sandboxCapabilities.reason})}return this.sandboxCapabilities}assertDispatchable(){if(this.config.sandboxRequired&&!(this.sandboxCapabilities.dispatchable===!0&&this.sandboxCapabilities.enforced===!0))throw Object.assign(new Error("runtime node strong sandbox is unavailable"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"})}operationIdentity(t,r,n){let s=l(t.goalContract)?Je(t.goalContract):c(t.goalContractHash),i=ya("sha256").update(q({prompt:Array.isArray(t.prompt)?t.prompt:[],mcpServers:Ua(t.mcpServers),metadata:l(t.metadata)?t.metadata:{}})).digest("hex");return{agentId:r,runId:c(t.runId),sessionId:n,targetCode:c(t.targetCode||t.framework),workspace:c(t.workspace),goalContractHash:s,requestHash:i}}assertOperationIdentity(t,r,n,s){let i=this.operationIdentity(r,n,s),o=Object.keys(t.identity).find(a=>t.identity[a]!==i[a]);if(o)throw Object.assign(new Error(`runtime operation correlation conflict: ${t.correlationId}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT",field:o})}createOperation(t,r,n,s){let i={correlationId:t,agentId:n,sessionId:s,identity:this.operationIdentity(r,n,s),sandboxPolicy:l(r.sandboxPolicy)?structuredClone(r.sandboxPolicy):null,status:"running",updates:[],listeners:new Set,waiters:[],response:null,error:null,mcpServers:r.mcpServers,createdAtMs:Date.now(),completedAtMs:null};return this.operations.set(t,i),i}async attachOperation(t,r={}){let n=()=>{if(r.onUpdate)for(let s of t.updates)r.onUpdate(s)};if(t.status==="completed")return n(),t.response;if(t.status==="failed")throw n(),t.error;r.onUpdate&&t.listeners.add(r.onUpdate);try{return n(),await new Promise((s,i)=>t.waiters.push({resolve:s,reject:i}))}finally{r.onUpdate&&t.listeners.delete(r.onUpdate)}}completeOperation(t,r){if(t.status==="running"){t.status="completed",t.response=r,t.mcpServers=null,t.completedAtMs=Date.now();for(let n of t.waiters.splice(0))n.resolve(r);t.listeners.clear()}}promptResponse(t,r,n,s,i,o=s){let a=l(t.metadata)?t.metadata:{},u=l(a._runtimeBridge)?a._runtimeBridge:{},d=a.source==="channel_message"?i:ss(i,o,u),f=Bn(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=Y(this.config.operationTtlMs,Oa);for(let[n,s]of this.operations)s.status!=="running"&&t-(s.completedAtMs||s.createdAtMs)>r&&this.operations.delete(n)}targetFor(t){let r=c(t)||this.config.defaultTargetCode,n=this.targets[r];if(!r||!l(n)){let s=new Error(`runtime target is not configured: ${r||"<empty>"}`);throw s.code="RUNTIME_TARGET_NOT_FOUND",s}return{code:r,target:n}}targetIdleTtlMs(t){let n=K(t)==="openclaw"?Y(this.config.openClawSessionIdleTtlMs,Ia):Y(this.config.sessionIdleTtlMs,Ea);return Y(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=K(t)==="openclaw"?Y(this.config.openClawMaxSessions,Ca):Y(this.config.maxSessionsPerTarget,Sa);return Y(t?.maxSessions,n)}targetReservationCount(t){return Number(this.targetReservations.get(t)||0)}notifyCapacityChanged(){try{this.onCapacityChanged?.()}catch(t){g("warn","runtime-bridge","capacity heartbeat callback failed",{error:String(t)})}}targetCapacitySnapshot(t=!0){return Object.entries(this.targets).map(([r,n])=>{let s=[...this.sessions.values()].filter(f=>f.targetCode===r),i=s.filter(f=>f.busy).length,o=s.length-i,a=this.targetReservationCount(r),u=this.targetMaxSessions(n),d=t?Math.max(0,u-i-a):0;return{targetCode:r,targetName:c(n?.name||n?.targetName||r),targetType:c(n?.type||"echo"),status:t?d>0?"available":"busy":"unavailable",maxSessions:u,busySessions:i,idleSessions:o,reservedSessions:a,availableSessions:d}})}targetReleaseAfterPrompt(t,r={}){let n=K(t),s=l(r?._runtimeBridge)?r._runtimeBridge:{},i=ur(s);return i!==void 0?At(i,!1):At(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=l(r?._runtimeBridge)?r._runtimeBridge:{},s=ur(n);return s!==void 0?At(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=Y(this.config.sessionCleanupIntervalMs,Ra);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(r=>{g("warn","runtime-bridge","runtime session cleanup failed",{error:String(r)})})},t),this.cleanupTimer.unref?.())}sessionCountForTarget(t){let r=0;for(let n of this.sessions.values())n.targetCode===t&&(r+=1);return r}idleTargetSessions(t){return[...this.sessions.entries()].filter(([,r])=>r.targetCode===t&&!r.busy).sort((r,n)=>(r[1].lastUsedAtMs||0)-(n[1].lastUsedAtMs||0))}async closeSession(t,r="session_closed"){let n=this.sessions.get(t);if(!n)return!1;try{await n.runtime?.stop?.(r)}catch(s){g("warn","runtime-bridge","runtime session stop failed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,error:String(s)})}return this.sessions.delete(t),this.runtimeSessionIndex.delete(`${n.agentId}:${n.runtimeSessionId}`),this.notifyCapacityChanged(),g("info","runtime-bridge","runtime session closed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,reason:r}),!0}async closeAllSessions(t="bridge_shutdown"){for(let r of[...this.sessions.keys()])await this.closeSession(r,t)}async stop(t="bridge_stop"){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=null,await this.closeAllSessions(t)}async cleanupExpiredSessions(t=Date.now()){for(let[r,n]of[...this.sessions.entries()])n.busy||t-(n.lastUsedAtMs||n.createdAtMs||t)>n.idleTtlMs&&await this.closeSession(r,"idle_timeout")}async reserveTargetSlot(t,r){let n=this.targetMaxSessions(r);for(;this.sessionCountForTarget(t)+this.targetReservationCount(t)>=n;){let s=this.idleTargetSessions(t);if(!s.length){let i=new Error(`runtime target session limit reached: ${t}`);throw i.code="RUNTIME_TARGET_SESSION_LIMIT",i}await this.closeSession(s[0][0],"target_session_limit")}this.targetReservations.set(t,this.targetReservationCount(t)+1),this.notifyCapacityChanged()}releaseTargetSlot(t){let r=Math.max(0,this.targetReservationCount(t)-1);r>0?this.targetReservations.set(t,r):this.targetReservations.delete(t),this.notifyCapacityChanged()}async createAgent(t){let r=c(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 tr(this.config,s,t.workspace):c(t.workspace),a={agentId:r,targetCode:n,framework:c(t.framework||n),workspace:o,metadata:l(t.metadata)?t.metadata:{},createdAt:yt(),runtimeKind:K(s)};return this.agents.set(r,a),{agent:a}}runtimeFor(t,r,n={}){let{target:s}=this.targetFor(t.targetCode),i=K(s),o={onPermissionRequest:u=>n.source==="conversation_delegation"?{outcome:"denied",reason:"External group member permission continuation is not supported"}:this.requestPermission(u)},a={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs,initializeTimeoutMs:this.config.initializeTimeoutMs,sandboxRequired:this.config.sandboxRequired,runId:n.runId,source:n.source,cloudSessionId:r,orchaUrl:this.config.orchaUrl,attachOnly:n.attachOnly,sandboxPolicy:n.sandboxPolicy,...this.config.sandboxRequired?{prepareLaunch:u=>zn({config:this.config,target:s,...u,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new lt(t,s,o,a):i==="openclaw"?new qt(t,s,r,o,a):i==="cli"?new Wt(t,s,a):new vt(t)}async prompt(t,r={}){if(this.assertDispatchable(),this.config.sandboxRequired){let a=c(t.runId);if(!a)throw Object.assign(new Error("runId is required"),{code:"BAD_REQUEST"});t={...t,runId:a,sandboxPolicy:st(t.sandboxPolicy)}}let n=c(t.agentId),s=c(t.sessionId)||re(),i=c(t.correlationId);if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});if(this.cleanupOperations(),i){let a=this.operations.get(i);if(a){if(this.assertOperationIdentity(a,t,n,s),a.status==="running"&&(["conversation_delegation","channel_message"].includes(t.metadata?.source)||t.metadata?.source==="ai_chat_runtime_node"&&t.framework==="codex")){a.mcpServers=t.mcpServers;let u=this.sessions.get(`${n}:${s}`);if(u){if(!u.runtime.refreshMcpServers)throw Object.assign(new Error("This runtime cannot refresh task MCP credentials"),{code:"unsupported_dynamic_mcp"});await u.runtime.refreshMcpServers(t.mcpServers)}}return this.attachOperation(a,r)}if(t.attachOnly===!0&&!(t.metadata?.source==="channel_message"&&this.targetFor(t.targetCode||t.framework).target.type==="openclaw"))throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"})}else if(t.attachOnly===!0)throw Object.assign(new Error("correlationId is required for attachOnly"),{code:"BAD_REQUEST"});let o=i?this.createOperation(i,t,n,s):null;if(o){let a=this.attachOperation(o,r);return(async()=>{try{await this._promptOwned(t,{},o,n,s)}catch(u){let d=o.status==="completed";this.failOperation(o,u),d&&g("warn","runtime-bridge","runtime cleanup failed after operation completion",{correlationId:o.correlationId,error:String(u)})}})(),await a}return await this._promptOwned(t,r,o,n,s)}async _promptOwned(t,r,n,s,i){let o=c(t.runId),a=this.config.sandboxRequired?st(n?.sandboxPolicy||t.sandboxPolicy):null,u=this.agents.get(s),d=this.targetFor(t.targetCode||t.framework||u?.targetCode);if(u&&u.targetCode!==d.code)throw Object.assign(new Error(`runtime agent target conflict: ${s}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});if(K(d.target)==="cli"&&Pa(t.goalContract))throw Object.assign(new Error("CLI runtimes do not support per-run dynamic MCP required by plugin_operation"),{code:"unsupported_dynamic_mcp"});let f=u||(await this.createAgent({agentId:s,targetCode:d.code,framework:t.framework,workspace:t.workspace,metadata:t.metadata})).agent;if(!this.config.sandboxRequired){let _=c(t.workspace);_&&_!==f.workspace&&(f.workspace=_)}let p=`${s}:${i}`;await this.cleanupExpiredSessions();let h=this.sessions.get(p),m=null;if(h&&h.targetCode!==d.code)throw Object.assign(new Error(`runtime session target conflict: ${i}`),{code:"RUNTIME_SESSION_TARGET_CONFLICT"});if(h&&this.config.sandboxRequired&&h.runId!==o)throw Object.assign(new Error(`runtime session cannot be shared across runs: ${i}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});if(!h){if(this.startingSessions.has(p))throw Object.assign(new Error(`runtime session is already starting: ${i}`),{code:"RUNTIME_SESSION_BUSY"});this.startingSessions.add(p);let{code:_,target:w}=d,E;try{await this.reserveTargetSlot(_,w),m=_;let O=this.runtimeFor(f,i,{runId:o,sandboxPolicy:a,source:t.metadata?.source,attachOnly:t.attachOnly});E=O;let U=n?.mcpServers||t.mcpServers||[],v=await O.sessionNew({cwd:et(w,f.workspace),mcpServers:U,metadata:l(t.metadata)?t.metadata:{}});if(n&&n.status!=="running")throw Object.assign(new Error("Runtime operation was cancelled before prompt dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"});let D=Date.now();h={agentId:s,sessionId:i,runtime:O,targetCode:_,runtimeKind:K(w),runId:o,sandboxPolicy:a?structuredClone(a):null,runtimeSessionId:c(l(v)?v.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(w),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(w,t.metadata),createdAtMs:D,lastUsedAtMs:D,busy:!1,createdAt:yt()},this.sessions.set(p,h),this.runtimeSessionIndex.set(`${s}:${h.runtimeSessionId}`,h),n?.mcpServers!==U&&n?.mcpServers&&O.refreshMcpServers&&await O.refreshMcpServers(n.mcpServers)}catch(O){throw this.sessions.get(p)?.runtime===E?await this.closeSession(p,"session_start_failed"):await E?.stop("session_start_failed"),m&&(this.releaseTargetSlot(m),m=null),O}finally{this.startingSessions.delete(p)}}if(h.busy){let _=new Error(`runtime session is already running: ${i}`);throw _.code="RUNTIME_SESSION_BUSY",_}h.busy=!0,m&&this.releaseTargetSlot(m),this.notifyCapacityChanged(),h.operationCorrelationId=n?.correlationId||null,h.lastUsedAtMs=Date.now();let T=n?.updates||[],S=_=>{let w=La(_,i,h);if(T.push(w),n)for(let E of n.listeners)try{E?.(w)}catch(O){g("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(O)})}else r.onUpdate?.(w)},N=_=>{if(!(!n||n.status!=="running"||!l(_))){if(_.status==="failed"){let w=_.error;if(w instanceof Error){this.failOperation(n,w);return}let E=l(w)?w:{},O=Object.assign(new Error(c(E.message||_.message)||"runtime terminal failure"),{code:c(E.code||_.code)||"RUNTIME_TERMINAL_FAILED"});this.failOperation(n,O);return}this.completeOperation(n,this.promptResponse(t,h,i,T,l(_.result)?_.result:{stopReason:"end_turn"}))}};try{let _=$n(t.goalContract),w=Array.isArray(t.prompt)?[...t.prompt]:[];_&&w.unshift({type:"text",text:_,metadata:{source:"orcha_goal_contract"}});let E=l(t.metadata)?t.metadata:{},O=l(E._runtimeBridge)?E._runtimeBridge:{},U=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:w,metadata:E},S,N),v=T,D=null;if(Zn({type:h.runtimeKind})&&Za(U,T,O)){D=U;let z=T.length,I=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:[{type:"text",text:tc()}],metadata:E,_meta:{thinking:"off"}},S,N);U=ec(D,I),v=T.slice(z)}let Q;try{Q=this.promptResponse(t,h,i,T,U,v)}catch(z){throw D&&is(U)?nc(U,v):z}return D&&(Q.result=rc(Q.result,D)),n&&this.completeOperation(n,Q),Q}finally{h.busy=!1,this.notifyCapacityChanged(),h.operationCorrelationId===n?.correlationId&&(h.operationCorrelationId=null),h.lastUsedAtMs=Date.now(),this.promptReleaseAfterPrompt(h,l(t.metadata)?t.metadata:{})&&await this.closeSession(p,"release_after_prompt"),n&&(n.mcpServers=null)}}async updatePolicy(t){if(this.assertDispatchable(),!this.config.sandboxRequired)throw Object.assign(new Error("runtime sandbox policy updates require an enforced sandbox"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"});let r=c(t.agentId),n=c(t.runId),s=c(t.sessionId),i=c(t.correlationId);if(!r||!n||!s||!i)throw Object.assign(new Error("agentId, runId, sessionId and correlationId are required"),{code:"BAD_REQUEST"});let o=st(t.sandboxPolicy),a=this.operations.get(i);if(a&&(a.agentId!==r||a.sessionId!==s||a.identity.runId!==n))throw Object.assign(new Error(`runtime operation policy identity conflict: ${i}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let u=`${r}:${s}`,d=this.sessions.get(u);if(d&&d.runId!==n)throw Object.assign(new Error(`runtime session policy identity conflict: ${s}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});let f=d?.sandboxPolicy||a?.sandboxPolicy;if(!f)throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"});let p=Number(f.policyRevision),h=Number(o.policyRevision);if(h<p)throw Object.assign(new Error("runtime sandbox policy revision is stale"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});if(h===p){if(q(f)!==q(o))throw Object.assign(new Error("runtime sandbox policy revision payload conflicts"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});return{updated:!1,idempotent:!0,policyRevision:p,accessMode:f.accessMode}}let m=Gn(f,o);a&&(a.sandboxPolicy=structuredClone(o)),d&&(d.sandboxPolicy=structuredClone(o));let T=!1;return m&&d?.busy===!0&&(await d.runtime.sessionCancel({sessionId:d.runtimeSessionId}),T=await this.closeSession(u,"sandbox_policy_downgrade")),{updated:!0,policyRevision:h,accessMode:o.accessMode,activeCommandCancelled:T,deferredToNextLaunch:!m&&d?.busy===!0}}async cancel(t){let r=c(t.agentId),n=c(t.sessionId),s=c(t.correlationId);if(s){let a=this.operations.get(s);if(!a||a.status!=="running")return{cancelled:!1,correlationId:s,reason:"operation_not_running"};if(a.agentId!==r||a.sessionId!==n)throw Object.assign(new Error(`runtime operation cancellation identity conflict: ${s}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let u=this.sessions.get(`${r}:${n}`);return!u||u.busy!==!0||u.operationCorrelationId!==s?(this.failOperation(a,Object.assign(new Error("Runtime operation cancelled before dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"})),{cancelled:!0,correlationId:s,reason:"cancelled_before_dispatch"}):(await u.runtime.sessionCancel({sessionId:u.runtimeSessionId}),await this.closeSession(`${r}:${n}`,"cancelled"),{cancelled:!0,correlationId:s})}let i=`${r}:${n}`,o=this.sessions.get(i);return o?(await o.runtime.sessionCancel({sessionId:o.runtimeSessionId}),await this.closeSession(i,"cancelled"),{cancelled:!0}):{cancelled:!1}}async dispatch(t,r={}){let n=c(t.agentId),s=c(t.taskId),i=c(t.executionId);if(!n||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let o=c(t.sessionId)||`dispatch-${i||s}`,a=c(t.instructions),u=qa(t),d=ts(t),{target:f}=this.targetFor(t.targetCode||t.framework),p=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",a?`instructions: ${a}`:"",u?"orchaContext:":"",u,u?"Use orchaContext as the source of truth for upstream outputs, review reports, artifacts, and workflow metadata.":"","Follow the execution protocol in instructions exactly.","When embedding a generated artifact in final Markdown, use the Orcha artifact placeholder as the link target: orcha-artifact://<fieldKey>/<index>.","Example: use  for the first generated image artifact.","Do not use local filesystem paths, file:// URLs, or data: URLs in final Markdown; Orcha replaces artifact placeholders after ingestion.",d?`For decision results, put the raw report between ${Fe} and ${$e}.`:"",d?`Then put a JSON object containing _decision between ${Be} and ${je}.`:"",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 ${Yn} 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(`
|
|
22
|
-
`)}];return this.prompt({...t,agentId:n,sessionId:o,prompt:p,metadata:ja(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=re(),a=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||re(),u={permissionId:i,agentId:t.agentId,sessionId:a,runtimeSessionId:r,request:l(n)?n:{},status:"pending",createdAt:yt()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:u}}),await new Promise(d=>{let f=y(n?.timeoutMs,this.config.permissionRequestTimeoutMs),p=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:p,resolve:d,permission:u})})}async respondPermission(t){let r=c(t.permissionId),n=this.pendingPermissions.get(r),s=c(t.outcome||"approved")||"approved";return n?(clearTimeout(n.timer),this.pendingPermissions.delete(r),n.resolve({permissionId:r,outcome:s,response:l(t.response)?t.response:{},userId:c(t.userId),metadata:l(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:r,outcome:s}):{accepted:!1,permissionId:r,outcome:s}}health(){return{status:this.config.sandboxRequired&&!this.sandboxCapabilities.dispatchable?"unavailable":"ok",bridgeVersion:J,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 sc from"node:http";import ic from"node:https";import{randomBytes as os}from"node:crypto";var ht=1,it=3,oc=1e4,ie=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=ac(r.connectTimeoutMs,oc),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:"?ic:sc,n=os(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,a)=>{if(this.clearConnectTimer(),this.readyState===it){o.destroy();return}this.socket=o,this.readyState=ht,o.on("data",u=>this.onData(u)),o.on("close",()=>this.onClose()),o.on("error",u=>{this.readyState!==it&&this.emit("error",{error:u,message:u.message,type:"error"}),this.onClose()}),a?.length&&this.onData(a),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!==it&&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===ht||this.readyState===it)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!==ht||this.socket.write(mr(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==it){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===ht&&this.socket.write(mr(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==it&&(this.clearConnectTimer(),this.readyState=it,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,a=2;if(o===126){if(this.buffer.length<a+2)return;o=this.buffer.readUInt16BE(a),a+=2}else if(o===127){if(this.buffer.length<a+8)return;let f=this.buffer.readUInt32BE(a),p=this.buffer.readUInt32BE(a+4);o=f*2**32+p,a+=8}let u=a;if(i&&(a+=4),this.buffer.length<a+o)return;let d=this.buffer.subarray(a,a+o);if(i){let f=this.buffer.subarray(u,u+4);d=Buffer.from(d.map((p,h)=>p^f[h%4]))}this.buffer=this.buffer.subarray(a+o),s===1?this.emit("message",{data:d.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(mr(10,d))}}};function ac(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function mr(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=os(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 a=0;a<r;a+=1)i[o+a]=t[a]^s[a%4];return i}function cc(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 uc(e,t=!0){return Object.entries(e||{}).map(([r,n])=>({targetCode:r,targetName:c(n?.name||n?.targetName||r),targetType:c(n?.type||"echo"),status:t?"available":"unavailable"}))}var lc=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),oe=class{constructor(t,r){this.config=t,this.bridge=r,this.ws=null,this.stopped=!1,this.connected=!1,this.reconnectTimer=null,this.heartbeatTimer=null,this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=()=>this.scheduleCapacityHeartbeat()}sandboxCapabilities(){return this.bridge.sandboxCapabilities||{dispatchable:this.config.sandboxRequired!==!0,enforced:!1,backend:"development_direct",daemonStatus:"development_only",policySchemaVersions:[1],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:!1}}supportedMethods(){return[...lc,...this.config.deviceConnection?["devices/discover","devices/configure"]:[]]}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):uc(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=cc(this.config.orchaUrl),r=new ie(t,{connectTimeoutMs:this.config.connectTimeoutMs});this.ws=r,r.addEventListener("open",()=>{if(this.ws!==r||this.stopped){r.close();return}this.authenticate(r)}),r.addEventListener("message",n=>this.handleMessage(n.data,r)),r.addEventListener("close",()=>this.scheduleReconnect("close",r)),r.addEventListener("error",n=>{g("warn","orcha-client","runtime node websocket error",{error:String(n?.message||n?.type||n)})})}authenticate(t=this.ws){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:J,protocolVersion:"orcha-runtime-node.v2",defaultTargetCode:this.config.defaultTargetCode,supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t)}scheduleReconnect(t,r=this.ws){r&&this.ws!==r||(this.connected=!1,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,r&&this.ws===r&&(this.ws=null),!this.stopped&&(this.reconnectTimer||(g("info","orcha-client","runtime node disconnected; reconnect scheduled",{reason:t,reconnectMs:this.config.reconnectMs}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.config.reconnectMs))))}async handleMessage(t,r=this.ws){if(r&&this.ws!==r)return;let n;try{n=JSON.parse(String(t))}catch(s){g("warn","orcha-client","invalid Orcha websocket frame",{error:String(s)});return}if(l(n)){if(n.type==="runtime_node.authenticated"){if(r&&this.ws!==r)return;this.connected=!0,this.startHeartbeat(r),g("info","orcha-client","runtime node authenticated",{nodeId:this.config.nodeId,connectionId:n.connectionId});return}if(n.type==="orcha.runtime.request"){await this.handleRequest(n);return}n.type==="runtime_node.ping"&&this.send({type:"runtime_node.pong",ts:new Date().toISOString(),supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()})}}startHeartbeat(t){this.heartbeatTimer&&clearInterval(this.heartbeatTimer);let r=Math.max(1e3,Number(this.config.heartbeatIntervalMs||15e3)),n=()=>this.sendCapacityHeartbeat(t);n(),this.heartbeatTimer=setInterval(n,r),this.heartbeatTimer.unref?.()}scheduleCapacityHeartbeat(){if(!this.connected||this.capacityHeartbeatTimer)return;let t=Math.max(25,Math.min(1e3,Number(this.config.capacityHeartbeatDebounceMs||100)));this.capacityHeartbeatTimer=setTimeout(()=>{this.capacityHeartbeatTimer=null,this.sendCapacityHeartbeat()},t),this.capacityHeartbeatTimer.unref?.()}sendCapacityHeartbeat(t=this.ws){return this.connected?this.send({type:"runtime_node.heartbeat",ts:new Date().toISOString(),supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t):!1}async handleRequest(t){let r=c(t.id),n=c(t.method),s=l(t.params)?t.params:{};try{let i=await this.invoke(n,s,r);this.send({type:"orcha.runtime.response",id:r,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:r,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i),...i.detail===void 0?{}:{detail:i.detail}}})}}async invoke(t,r,n){if(t==="devices/discover"&&this.config.deviceConnection)return this.config.deviceConnection.candidates();if(t==="devices/configure"&&this.config.deviceConnection)return this.config.deviceConnection.configure(r,this.bridge);if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(r);if(t==="agents/dispatch")return this.bridge.dispatch(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/prompt")return this.bridge.prompt(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/policy")return this.bridge.updatePolicy(r);if(t==="sessions/cancel")return this.bridge.cancel(r);if(t==="permissions/respond")return this.bridge.respondPermission(r);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,r){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:r})}send(t,r=this.ws){return!r||r!==this.ws||r.readyState!==ht?!1:(r.send(JSON.stringify(t)),!0)}};import{createServer as dc}from"node:http";function ae(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 ot(e={}){return{ok:!0,...e}}function gr(e,t,r){return{ok:!1,error:{code:e,message:t,...r===void 0?{}:{detail:r}}}}async function as(e,t){let r=[],n=0;for await(let i of e){if(n+=i.length,n>t)throw Object.assign(new Error("request body too large"),{status:413,code:"REQUEST_TOO_LARGE"});r.push(i)}if(r.length===0)return{};let s=Buffer.concat(r).toString("utf8");if(!s.trim())return{};try{let i=JSON.parse(s);if(!l(i))throw Object.assign(new Error("JSON body must be an object"),{status:400,code:"BAD_JSON"});return i}catch(i){throw i.status?i:Object.assign(new Error(`invalid JSON body: ${i.message}`),{status:400,code:"BAD_JSON"})}}function cs(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 us(e,t){let r={"GET /health":async()=>ot(t.health()),"POST /agents/create":async n=>ot(await t.createAgent(n)),"POST /agents/dispatch":async n=>ot(await t.dispatch(n)),"POST /sessions/prompt":async n=>ot(await t.prompt(n)),"POST /sessions/cancel":async n=>ot(await t.cancel(n)),"POST /permissions/respond":async n=>ot(await t.respondPermission(n))};return dc(async(n,s)=>{let i=new URL(n.url||"/",`http://${n.headers.host||`${e.host}:${e.port}`}`),o=`${n.method||"GET"} ${i.pathname}`,a=r[o];if(!a){ae(s,404,gr("NOT_FOUND",`No route for ${o}`));return}try{cs(n,e.token);let u=n.method==="GET"?{}:await as(n,e.requestLimitBytes);ae(s,200,await a(u))}catch(u){let d=u.status||500,f=u.code||"BRIDGE_INTERNAL";ae(s,d,gr(f,u.message||String(u),u.detail))}})}var _s=_c(import.meta.url),Tc=".orcha-runtime-bridge.pid",yc=".orcha-runtime-bridge.log",wc=3,Ec=36e5,{command:Rc,options:Ts}=Ic(process.argv.slice(2));Cc(Ts);sn();var Sc=on();await ys(Rc,Sc,Ts);async function ys(e,t,r){if(r.url){let s=_e(r.url);r.pidFile||(process.env.ORCHA_RUNTIME_PID_FILE=s.pidFile),r.logFile||(process.env.ORCHA_RUNTIME_LOG_FILE=s.logFile)}let n=()=>["connect","--url",t.orchaUrl,"--foreground"];switch(e){case"connect":if(r.pairCode&&at(ue(ce())))throw new Error("\u8BBE\u5907\u8FDE\u63A5\u4ECD\u5728\u540E\u53F0\u8FD0\u884C\uFF0C\u8BF7\u5148\u6267\u884C stop --url \u540E\u91CD\u65B0\u914D\u5BF9");await Mt(t,r),r.foreground?await _r(t):Tr(n());return;case"run":case"foreground":r.url&&await Mt(t,r),await _r(t);return;case"start":if(r.url)return ys("connect",t,r);if(r.foreground){await _r(t);return}Tr();return;case"reload":case"restart":{r.url&&await Mt(t,{url:r.url});let s=mt(gs(_s),".."),i=mt(s,...Rr(mt(s,"src","index.js"))?["dist","package"]:[],"openclaw-plugin"),o=await Gr(t.targets,i);await fs({quiet:!0}),await o(),Tr(r.url?n():void 0);return}case"stop":await fs();return;case"status":Oc();return;case"help":case"--help":case"-h":bc();return;default:throw new Error(`Unknown command: ${e}`)}}async function _r(e){xc();let t=new se(e);if(await t.start(),e.mode==="server"){let n=us(e,t);ds({bridge:t,server:n}),n.listen(e.port,e.host,()=>{g("info","runtime-bridge","Orcha runtime bridge HTTP server started",{host:e.host,port:e.port,targets:Object.keys(t.targets)})});return}if(!e.orchaUrl)throw new Error("ORCHA_RUNTIME_ORCHA_URL is required in runtime node mode");let r=new oe(e,t);ds({bridge:t,client:r}),r.start(),g("info","runtime-bridge","Orcha runtime node started",{nodeId:e.nodeId,nodeName:e.nodeName,orchaUrl:e.orchaUrl,targets:Object.keys(t.targets)})}function ds({bridge:e,client:t,server:r}){let n=!1,s=i=>{if(n)return;n=!0;let o=Number(e?.sessions?.size||0)>0;g("info","runtime-bridge","runtime bridge shutting down",{signal:i});try{t?.stop?.()}catch(a){g("warn","runtime-bridge","runtime client stop failed",{error:String(a)})}Promise.resolve(e?.stop?.(`process_${String(i||"shutdown").toLowerCase()}`)).catch(a=>{g("warn","runtime-bridge","runtime bridge stop failed",{error:String(a)})}).finally(()=>{try{r?.close?.()}catch(a){g("warn","runtime-bridge","runtime server close failed",{error:String(a)})}}),setTimeout(()=>process.exit(0),o?8500:200)};process.once("SIGTERM",()=>s("SIGTERM")),process.once("SIGINT",()=>s("SIGINT"))}function Tr(e=["run"]){let t=ce(),r=ws(),n=ue(t);if(n&&at(n)){console.log(JSON.stringify({status:"already_running",pid:n,pidFile:t,logFile:r}));return}n&&Er(t),hs(t),hs(r),wr(r);let s=mc(r,"a"),i={...process.env,ORCHA_RUNTIME_PID_FILE:t,ORCHA_RUNTIME_LOG_FILE:r},o=fc(process.execPath,[_s,...e,"--pid-file",t,"--log-file",r],{cwd:process.cwd(),detached:!0,env:i,stdio:["ignore",s,s]});o.unref(),pc(s),ms(t,`${o.pid}
|
|
23
|
-
`),console.log(JSON.stringify({status:"started",pid:o.pid,pidFile:t,logFile:r}))}async function
|
|
24
|
-
`);
|
|
25
|
-
`:""),g("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:a})}catch(d){g("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function
|
|
14
|
+
${s}`:s;kn(t,r,n,d,s)&&(o=1,a=1)}return s&&i&&(t.finalTextSeen=!0),Un(t,e),(ko(e)||vo(e)||Do(e)||i)&&n({sessionId:r,update:{sessionUpdate:"runtime_event",event:Pn(e)}}),{textCount:o,finalTextCount:a,thoughtCount:u}}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,a=0,u=0,d=0,f=Po(t,r,s);if(f){let p=Math.min(t.processedLines.get(f.path)||0,f.events.length),h=e.artifacts.size;for(let m of f.events.slice(p)){let y=Ho(m,e,r,n);a+=y.textCount,u+=y.finalTextCount,d+=y.thoughtCount}t.processedLines.set(f.path,f.events.length),(f.events.length>p||e.artifacts.size>h)&&(o=1)}return{artifactCount:e.artifacts.size-i,transcriptCount:o,textCount:a,finalTextCount:u,thoughtCount:d}}function Fo(e,{remove:t=!0}={}){if(!e||!In(e))return"";try{return xn(e,"utf8").trim()}catch{return""}finally{t&&zt(e)}}function zt(e){if(e)try{Yi(e)}catch{}}function $o(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 Bo(e){return new Promise(t=>setTimeout(t,e))}function jo(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 qo(e,t,r,n,s,i){let o=Ue(e,t,r,n,Date.now()),a=()=>jo(e,r,n,Fo(s,{remove:!1}));if(a()||e.finalTextSeen)return zt(s),o;let u=po(i);if(u<=0||!t&&!s)return zt(s),o;let d=Date.now()+u,f=Math.min(Ln(i),100);for(;!e.finalTextSeen&&Date.now()<d&&(await Bo(Math.min(f,Math.max(0,d-Date.now()))),o=$o(o,Ue(e,t,r,n,Date.now())),!a()););return zt(s),o}var Vt=class{constructor(t,r,n={}){if(this.agent=t,this.target=r,this.options=n,this.active=new Map,n.source==="ai_chat_runtime_node"&&Ne(r)==="codex"){if(typeof n.cloudSessionId!="string"||!io.test(n.cloudSessionId))throw Object.assign(new Error("Codex \u539F\u751F\u4F1A\u8BDD\u6807\u8BC6\u65E0\u6548\uFF1A\u9700\u8981\u5B8C\u6574\u7684\u4EFB\u52A1\u6216\u4F1A\u8BDD\u9694\u79BB\u6807\u8BC6"),{code:"BAD_REQUEST"});if(!n.orchaUrl)throw Object.assign(new Error("Codex \u539F\u751F\u4F1A\u8BDD\u7F3A\u5C11 OrchaAI \u670D\u52A1\u5730\u5740\uFF0C\u8BF7\u91CD\u65B0\u8FDE\u63A5\u8BBE\u5907"),{code:"BAD_REQUEST"});if(n.prepareLaunch)throw Object.assign(new Error("Codex \u539F\u751F\u4F1A\u8BDD\u4E0D\u652F\u6301\u6C99\u7BB1\u542F\u52A8\uFF0C\u8BF7\u4F7F\u7528\u5DF2\u63A5\u5165\u7684\u672C\u673A\u8BBE\u5907"),{code:"BAD_REQUEST"});this.nativeSession=new Kt([n.orchaUrl,t.agentId,t.targetCode,n.cloudSessionId,et(r,t.workspace),r.command,r.env?.CODEX_HOME||process.env.CODEX_HOME||k(An(),".codex")])}}async sessionNew(t={}){let r=t.mcpServers||[];if(r.length&&(t.metadata?.source==="conversation_delegation"||this.nativeSession)&&Ne(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.explicitFileDelivery=!0,this.taskMcp=await pn(r,()=>({cwd:this.deliveryCwd,roots:[...this.deliveryRoots||[],...this.deliveryThreadId?[k(ve(this.target),"..","generated_images",this.deliveryThreadId)]:[]]}))}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}-${dt()}`}}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){return this.nativeSession?this.nativeSession.turn(this.options.runId,(s,i,o)=>this.runPrompt(t,i,o,s),s=>{let i=s.update?.event;i?.type==="thread.started"&&(this.deliveryThreadId=i.thread_id),r(s)},n,()=>this.sessionCancel(t)):this.runPrompt(t,r,n)}async runPrompt(t,r,n,s){let i=Date.now(),o=c(this.target.command);if(!o)throw new Error(`runtime target ${this.agent.targetCode} is missing command`);let a=c(t.sessionId)||dt(),u=kt(t.prompt),d=c(this.target.promptMode||"stdin"),f=this.buildArgs(d,u),p=[...this.taskMcp?.args||[],...this.nativeSession?yn(f,s):f],h=et(this.target,this.agent.workspace),m=typeof this.options.prepareLaunch=="function",S=lo(o,p,this.target)?m?`/tmp/orcha-runtime-last-message-${dt()}.txt`:k(Nn(),`orcha-runtime-last-message-${dt()}.txt`):"";S&&p.push("--output-last-message",S);let x={...l(this.target.env)?this.target.env:{},...this.taskMcp?.environment||{},...d==="env"?{ORCHA_RUNTIME_PROMPT:u}:{},ORCHA_AGENT_ID:this.agent.agentId,ORCHA_SESSION_ID:a},_=m?await this.options.prepareLaunch({command:o,args:p,cwd:h,environment:x}):{command:o,args:p,cwd:h,environment:{...process.env,...x},cleanup:async()=>{}},w=m?Eo(_):To(this.target,a),T=w.root,R=So(this.target,T,_);this.deliveryCwd=h,this.deliveryRoots=[h,...R.trustedFileRoots].filter(Boolean),this.deliveryThreadId=s||null;let N=fo(o,this.target),M={...this.target,targetCode:this.agent.targetCode,cwd:h,...m?{codexHome:k(_.homeDirectory,".codex")}:{}},H=N?Co(M,i):new Set,Q=m&&S?k(_.tempDirectory,S.slice(5)):S,z=E(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,E(this.options.sessionPromptTimeoutMs,X));m||(_.environment.ORCHA_RUNTIME_ARTIFACT_DIR=T);let I=On(_.command,_.args,{cwd:_.cwd,env:_.environment,stdio:["pipe","pipe","pipe"],detached:process.platform!=="win32",windowsHide:!0});this.active.set(a,I),g("info","runtime.cli","runtime prompt started",{target:this.agent.targetCode,sessionId:a,pid:I.pid,timeoutMs:z,isolation:_.isolation});let Ir="",le=c(this.target.outputMode||"text"),U={explicitFileDelivery:this.explicitFileDelivery,artifacts:new Map,emittedTexts:new Set,emittedThoughtTexts:new Set,value:"",artifactOptions:R,finalTextSeen:!1,finalTextOnly:_o(t,this.target),emitThoughtChunks:mo(t,this.target),terminalOutcome:null,terminalProtocol:Ne(this.target),emitTerminal:null},de=N?wo(M,u,i,H):null;return I.stdout.setEncoding("utf8"),I.stdout.on("data",ut=>this.handleStdout(ut,le,U,a,r)),I.stderr.setEncoding("utf8"),I.stderr.on("data",ut=>{Ir+=ut,this.target.emitStderr===!0&&r({sessionId:a,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:ut}}})}),d==="stdin"?I.stdin.end(u):I.stdin.end(),await new Promise((ut,fe)=>{let gt=!1,Cr=!1,bt=null,_t=null,pe=de&&ho(this.target,t)?setInterval(()=>{try{Ue(U,de,a,r)}catch(C){g("warn","runtime.cli","codex transcript stream poll failed",{target:this.agent.targetCode,sessionId:a,error:String(C?.message||C)})}},Ln(this.target)):null;pe?.unref?.();let xr=setTimeout(()=>{Cr=!0,g("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:a,pid:I.pid,timeoutMs:z}),Jt(I,"SIGTERM"),bt=setTimeout(()=>{g("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:a,pid:I.pid}),Jt(I,"SIGKILL")},bn),bt.unref?.(),yt(Object.assign(new Error(`runtime CLI timed out after ${z}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},z);xr.unref?.();let Ar=async()=>{clearTimeout(xr),_t&&clearTimeout(_t),pe&&clearInterval(pe),bt&&!Cr&&clearTimeout(bt),Ro(w,{target:this.agent.targetCode,sessionId:a}),this.active.delete(a),U.emitTerminal=null,await _.cleanup?.()},Cs=C=>{gt||(gt=!0,Ar().then(()=>ut(C),fe))},yt=C=>{gt||(gt=!0,Ar().then(()=>fe(C),B=>{g("warn","runtime.cli","sandbox launch cleanup failed",{target:this.agent.targetCode,sessionId:a,error:String(B?.message||B)}),fe(C)}))};U.emitTerminal=C=>{let B={...l(C.result)?C.result:{},_artifacts:[...U.artifacts.values()]};try{n?.({...C,result:B})}catch(Z){g("warn","runtime.cli","runtime terminal listener failed",{target:this.agent.targetCode,sessionId:a,error:String(Z?.message||Z)})}let $=Math.max(0,E(this.target.terminalExitGraceMs,so));_t=setTimeout(()=>{_t=null,!(gt||this.active.get(a)!==I)&&(g("warn","runtime.cli","runtime stayed alive after terminal event; terminating child",{target:this.agent.targetCode,sessionId:a,pid:I.pid,terminalProtocol:U.terminalProtocol,graceMs:$}),Ae(I))},$),_t.unref?.()},I.on("error",C=>{g("warn","runtime.cli","runtime child error",{target:this.agent.targetCode,sessionId:a,pid:I.pid,error:String(C?.message||C)}),yt(C)}),I.on("exit",(C,B)=>{(async()=>{le==="json-lines"&&U.value.trim()&&this.handleStdout(`
|
|
15
|
+
`,le,U,a,r);let $=await qo(U,de,a,r,Q,this.target);($.artifactCount>0||$.textCount>0||$.thoughtCount>0)&&g("info","runtime.cli","codex transcript updates collected",{target:this.agent.targetCode,sessionId:a,artifactCount:$.artifactCount,textCount:$.textCount,finalTextCount:$.finalTextCount,thoughtCount:$.thoughtCount,transcriptCount:$.transcriptCount});let Z=Ir.trim();if(Z&&g("debug","runtime.cli","runtime stderr",{target:this.agent.targetCode,sessionId:a,stderr:Z}),g("info","runtime.cli","runtime prompt finished",{target:this.agent.targetCode,sessionId:a,pid:I.pid,exitCode:C,signal:B,artifactCount:U.artifacts.size,finalTextSeen:U.finalTextSeen}),U.terminalOutcome?.status==="failed"){yt(U.terminalOutcome.error);return}if(C!==0&&U.terminalOutcome?.status!=="completed"){let xs=Object.assign(new Error(`runtime CLI exited with code ${C??"unknown"}${B?` (${B})`:""}`),{code:"RUNTIME_CLI_EXIT_NONZERO",exitCode:C,signal:B});yt(xs);return}Cs({stopReason:"end_turn",exitCode:C,signal:B,_artifacts:[...U.artifacts.values()],...Z?{stderr:Z}:{}})})().catch(yt)})})}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 a of o){let u=a.trim();if(u)try{let d=JSON.parse(u);!this.nativeSession&&d.type==="thread.started"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(d.thread_id||"")&&(this.deliveryThreadId=d.thread_id),Un(n,d),i({sessionId:s,update:{sessionUpdate:"runtime_event",event:Pn(d)}});let f=Mn(d),p=Le(d);f&&n.emitThoughtChunks&&!p&&uo(d)?vn(n,s,i,f):f&&yo(n,p)&&kn(n,s,i,f),f&&p&&(n.finalTextSeen=!0);let h=co(d,n.terminalProtocol);h&&!n.terminalOutcome&&(h.status==="failed"||n.finalTextSeen||n.artifacts.size>0)&&(n.terminalOutcome=h,n.emitTerminal?.(h))}catch{i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`${a}
|
|
16
|
+
`}}})}}}async sessionCancel(t){let r=c(t.sessionId),n=this.active.get(r);return n?(g("info","runtime.cli","cancelling runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid}),Ae(n),{ok:!0,cancelled:!0}):{ok:!0,cancelled:!1}}async stop(t="stop"){for(let[r,n]of this.active.entries())g("info","runtime.cli","stopping runtime child",{target:this.agent.targetCode,sessionId:r,pid:n.pid,reason:t}),Ae(n);this.active.clear(),await this.taskMcp?.close(),this.taskMcp=null}};var De="ORCHA_RUNTIME_OUTPUT_START",He="ORCHA_RUNTIME_OUTPUT_END",Fe="ORCHA_RUNTIME_CONTROL_START",$e="ORCHA_RUNTIME_CONTROL_END",Be=De,je=He,qe=Fe,Ke=$e,Ge=[De,He,Fe,$e],Ko=new Set(["_artifacts","_decision","_meta"]),Go=new RegExp(`(?:^|(?<=[\\r\\n]))[ \\t]*(?<marker>${Ge.join("|")})[ \\t]*(?=\\r\\n?|\\n|$)`,"g"),v=class extends Error{constructor(t,r,n){super(r),this.name="RuntimeResultProtocolError",this.code=t,this.detail={rawOutput:n}}};function Bn(e){let t=typeof e=="string"?e.trimStart():"";return Ge.some(r=>t.startsWith(r))}function ze(e){if(typeof e!="string")return null;let t=e,r=zo(t);if(![...r.values()].some(m=>m.length>0))return null;let n=[],s=[];for(let[m,y]of r)y.length===0?n.push(m):y.length>1&&s.push(m);if(n.length>0||s.length>0){let m=[];throw n.length>0&&m.push(`\u7F3A\u5C11 ${n.join(", ")}`),s.length>0&&m.push(`\u91CD\u590D ${s.join(", ")}`),new v("invalid_markers",`Runtime Result \u534F\u8BAE\u6807\u8BB0\u4E0D\u5B8C\u6574\uFF1A${m.join("\uFF1B")}`,t)}let i=r.get(De)[0],o=r.get(He)[0],a=r.get(Fe)[0],u=r.get($e)[0];if(!(i.end<=o.start&&o.end<=a.start&&a.end<=u.start))throw new v("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=Jo(t.slice(i.end,o.start));if(!d.trim())throw new v("empty_output","Runtime Result OUTPUT \u5757\u4E0D\u80FD\u4E3A\u7A7A",t);let f=t.slice(a.end,u.start).trim();if(!f)throw new v("empty_control","Runtime Result CONTROL \u5757\u4E0D\u80FD\u4E3A\u7A7A",t);let p;try{p=JSON.parse(f)}catch(m){throw new v("invalid_control_json",`Runtime Result CONTROL \u5757\u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${String(m?.message||m)}`,t)}if(!$n(p))throw new v("invalid_control_type","Runtime Result CONTROL \u5757\u5FC5\u987B\u662F JSON \u5BF9\u8C61",t);let h=Object.keys(p).filter(m=>!Ko.has(m)).sort();if(h.length>0)throw new v("invalid_control_keys",`Runtime Result CONTROL \u5757\u5305\u542B\u975E\u6807\u51C6\u5B57\u6BB5\uFF1A${h.join(", ")}`,t);if("_artifacts"in p&&!Array.isArray(p._artifacts))throw new v("invalid_control_field_type","Runtime Result CONTROL \u5757\u7684 _artifacts \u5FC5\u987B\u662F JSON \u6570\u7EC4",t);for(let m of["_decision","_meta"])if(m in p&&!$n(p[m]))throw new v("invalid_control_field_type",`Runtime Result CONTROL \u5757\u7684 ${m} \u5FC5\u987B\u662F JSON \u5BF9\u8C61`,t);return{output:d,...p}}function zo(e){let t=new Map(Ge.map(r=>[r,[]]));for(let r of e.matchAll(Go))t.get(r.groups.marker).push({start:r.index,end:r.index+r[0].length});return t}function Jo(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 $n(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}import{createHash as Wo}from"node:crypto";var Vo="orcha.goal-contract/v1",Xo=new Set(["complete","completed","done","ok","passed","success","succeeded"]),Yo=new Set(["aborted","blocked","cancelled","canceled","denied","error","failed","failure","timeout","timed_out"]),Qo=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 Wo("sha256").update(q(e)).digest("hex")}function qn(e){if(!Gn(e))return"";let t=["The following Orcha goal contract is immutable for this turn. Do not narrow its outcome or constraints.",`<goal_contract>${JSON.stringify(e)}</goal_contract>`];return e.verificationPlan?.required===!0&&t.push("Every verification check must be satisfied by a real successful tool call from one of its toolNames.","Each check requires requiredMatches distinct successful tool call IDs; repeated updates for one call count once.","A final text claim is not verification; missing or failed tool evidence prevents completion."),t.join(`
|
|
17
|
+
`)}function Kn(e,t,r=""){if(!Gn(e))return e==null?null:{required:!0,status:"failed",outcome:c(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=Xe(e),s=e.verificationPlan.required===!0;if(c(r)&&c(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=Zo(t),o=e.verificationPlan.checks.map(u=>oa(u,i));return{required:!0,status:o.some(u=>u.status==="failed")?"failed":o.some(u=>u.status==="missing")?"missing":"passed",outcome:e.outcome,goalContractHash:n,checks:o}}function Gn(e){if(!l(e)||e.schemaVersion!==Vo||!c(e.outcome))return!1;let t=e.verificationPlan;if(!l(t)||typeof t.required!="boolean"||!Array.isArray(t.checks)||t.required&&t.checks.length===0)return!1;let r=new Set;for(let n of t.checks)if(!l(n)||!c(n.id)||r.has(c(n.id))||(r.add(c(n.id)),!Array.isArray(n.toolNames)||n.toolNames.length===0||n.toolNames.some(s=>!c(s)))||!Number.isSafeInteger(n.requiredMatches)||n.requiredMatches<1||n.arguments!==void 0&&!l(n.arguments))return!1;return!0}function Zo(e){let t=new Map,r=[];for(let n of Array.isArray(e)?e:[]){let s=l(n?.update)?n.update:{},i=c(s.sessionUpdate);if(i==="runtime_event"){ta(s.event,t,r);continue}if(i==="tool_call"){let o=Yt(s)||`tool-${r.length+1}`,a=Xt(t,r,o),u=We(s,s.name||s.toolName||s.kind);a.toolName=u.toolName,a.arguments=u.arguments,a.status=It(s.status),a.evidence=Zt(s);continue}if(i==="tool_call_update"){let o=Yt(s);if(!o)continue;let a=Xt(t,r,o),u=We(s,s.name||s.toolName||s.kind);a.toolName||=u.toolName,Object.keys(a.arguments).length===0&&(a.arguments=u.arguments),a.status=It(s.status),a.evidence.push(...Zt(s))}}return r}function ta(e,t,r){let n=l(e)&&l(e.payload)?e.payload:l(e)?e:{},s=c(n.type);if(["function_call","custom_tool_call","local_shell_call","mcp_tool_call"].includes(s)){let a=Yt(n)||`runtime-${r.length+1}`,u=Xt(t,r,a),d=We(n,n.name||n.tool||s,s);u.toolName=d.toolName,u.arguments=d.arguments,u.status=It(n.status),u.evidence.push(...Zt(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=Yt(n);if(!i)return;let o=Xt(t,r,i);o.status=sa(n,o.toolName),o.evidence.push(...Zt(n))}function Xt(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 ea(e){let t=c(e).toLowerCase();return Qo.get(t)||t}function We(e,t,r=""){let n=ra(e),s=c(r)==="mcp_tool_call"||c(e?.kind).toLowerCase()==="mcp",i=l(e?._meta)?e._meta:{},o=c(e?.server||e?.serverName||e?.server_name||e?.mcpServer||i.server||i.serverName).toLowerCase();if(s&&o==="orcha"){let a=c(e?.tool||e?.toolName||e?.name||t);return{toolName:"plugin_operation",arguments:{...n,...a?{operationCode:a}:{}}}}return{toolName:ea(t),arguments:n}}function Yt(e){return l(e)?c(e.call_id||e.callId||e.toolCallId||e.id):""}function ra(e){if(!l(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=na(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 na(e){if(l(e))return structuredClone(e);if(typeof e!="string")return null;try{let t=JSON.parse(e);return l(t)?t:null}catch{return null}}function sa(e,t){if(!l(e))return"unknown";let r=Qt(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function Qt(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return ia(e,t,r);if(Array.isArray(e))return e.flatMap(o=>Qt(o,t+1,r));if(!l(e))return[];let n=[];typeof e.isError=="boolean"&&n.push(e.isError?"failed":"success"),typeof e.ok=="boolean"&&n.push(e.ok?"success":"failed"),typeof e.success=="boolean"&&n.push(e.success?"success":"failed");let s=It(e.status);s!=="unknown"&&n.push(s);let i=e.exitCode??e.exit_code;typeof i=="number"&&Number.isFinite(i)&&n.push(i===0?"success":"failed");for(let o of["output","result","structuredContent","content"])e[o]!==void 0&&n.push(...Qt(e[o],t+1,r));return n}function ia(e,t,r){let n=e.trim();if(!n)return[];try{return Qt(JSON.parse(n),t+1,r)}catch{}if(r.parseCliExitCode!==!0)return[];let s=[];for(let i of n.matchAll(/(?:process\s+exited\s+with\s+code|exit\s+code\s*:?)\s*(-?\d+)/gi))s.push(Number(i[1])===0?"success":"failed");return s}function It(e){let t=c(e).toLowerCase();return Xo.has(t)?"success":Yo.has(t)?"failed":"unknown"}function Zt(e){if(!l(e))return[];let t=l(e.output)?e.output:{},r=[e.verificationEvidence,l(e.verification)?e.verification.evidence:null,t.verificationEvidence,l(t.verification)?t.verification.evidence:null],n=[];for(let s of r)for(let i of Array.isArray(s)?s:s?[s]:[])!l(i)||!c(i.id)||n.push({id:c(i.id),status:It(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...c(i.message)?{message:c(i.message)}:{}});return n}function oa(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&Ve(e.arguments||{},o.arguments)),n=c(e.evidenceId),s=r.filter(o=>o.status==="success"&&(!n||o.evidence.some(a=>a.id===n&&a.status==="success")));if(s.length>=e.requiredMatches)return Je(e,"passed",s,`Runtime tool evidence passed ${s.length} times.`);let i=r.filter(o=>o.status==="failed"||n&&o.evidence.some(a=>a.id===n&&a.status==="failed"));return s.length===0&&i.length?Je(e,"failed",i,"Runtime tool evidence failed."):Je(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function Je(e,t,r,n){let s=r.map(i=>i.toolCallId).filter(Boolean);return{id:e.id,status:t,message:n,...c(e.description)?{description:c(e.description)}:{},toolNames:e.toolNames,requiredMatches:e.requiredMatches,observedMatches:s.length,toolCallIds:s,...l(e.arguments)?{arguments:e.arguments}:{},...c(e.evidenceId)?{evidenceId:c(e.evidenceId)}:{}}}function Ve(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>Ve(r,t[n])):l(e)?l(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&Ve(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 jn(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new Error("invalid_jcs_number");return JSON.stringify(Object.is(e,-0)?0:e)}if(Array.isArray(e))return`[${Array.from({length:e.length},(t,r)=>{if(!Object.hasOwn(e,r))throw new Error("invalid_jcs_json_value");return q(e[r])}).join(",")}]`;if(l(e))return`{${Object.keys(e).sort().map(t=>`${jn(t)}:${q(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function jn(e){return aa(e),JSON.stringify(e)}function aa(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 ca}from"node:child_process";import{createHash as ua,randomUUID as la}from"node:crypto";import{constants as da}from"node:fs";import{access as fa,mkdir as Ye,readdir as pa,realpath as Ct,rm as ha,stat as ma}from"node:fs/promises";import ga from"node:http";import{tmpdir as _a}from"node:os";import{isAbsolute as xt,join as ft,relative as zn,resolve as Ze}from"node:path";var tr=1,ya="orcha.process-isolation/v1",er="orcha.egress-proxy/v1",wa="--disable-wasm-trap-handler",te={read_only:0,workspace_write:1,workspace_network:2},Qe={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},Ta=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function it(e){if(!l(e))throw O("RUNTIME_SANDBOX_POLICY_REQUIRED","sandboxPolicy is required");let t=structuredClone(e),r=c(t.accessMode),n=c(t.accessModeCeiling);if(!(r in Qe)||!(n in Qe))throw O("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if(te[r]>te[n])throw O("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=Qe[r];if(t.filesystemMode!==s||t.networkMode!==i)throw O("RUNTIME_SANDBOX_POLICY_INVALID","runtime access profile does not match its mode");if(Number(t.policySchemaVersion)!==tr||!Number.isInteger(Number(t.policyRevision))||Number(t.policyRevision)<1)throw O("RUNTIME_SANDBOX_POLICY_INVALID","unsupported sandbox policy schema or revision");for(let[a,u]of Object.entries({outsideWorkspaceAccess:"denied",hostAccess:"denied",hostEnvironmentAccess:"denied",dockerSocketAccess:"denied",environmentMode:"allowlist"}))if(t[a]!==u)throw O("RUNTIME_SANDBOX_POLICY_INVALID",`${a} cannot be relaxed`);let o=l(t.processIsolation)?t.processIsolation:{};if(o.mode!=="required"||o.backend==="direct")throw O("RUNTIME_SANDBOX_POLICY_INVALID","strong process isolation is required");if(Array.isArray(t.alwaysApprovedApprovalKeys)&&t.alwaysApprovedApprovalKeys.length)throw O("RUNTIME_SANDBOX_POLICY_INVALID","persistent runtime approvals are forbidden");return t}function Jn(e,t){let r=it(e),n=it(t);return te[n.accessMode]<te[r.accessMode]}async function Wn(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[tr],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await Xn(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw O("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await Ia(t,b(e.sandboxBrokerArguments),e.sandboxProbeTimeoutMs);if(r.enforced!==!0||c(r.protocolVersion)!=="orcha.runtime-sandbox-broker/v1"||!["bubblewrap","broker"].includes(c(r.backend)))throw O("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker did not report enforced isolation");let n=l(r.probes)?r.probes:{};for(let s of["emptyRoot","outsideWorkspaceDenied","hostFilesystemDenied","sensitiveFilesDenied","environmentAllowlist","dockerSocketDenied","networkNamespace","workspaceReadOnly","workspaceWrite","resourceLimits"])if(n[s]!==!0)throw O("RUNTIME_SANDBOX_UNAVAILABLE",`sandbox broker probe failed: ${s}`);return e.egressProxyRequired&&await Aa(e),{dispatchable:!0,enforced:!0,backend:c(r.backend),daemonStatus:"ok",daemonProtocolVersion:c(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[tr],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function rr(e,t,r){let n=c(t.workspace||t.cwd),s=c(r),i=n||(t.allowRequestWorkspace===!0?s:"");if(!i||!xt(i))throw O("RUNTIME_WORKSPACE_NOT_CONFIGURED","runtime target must configure an absolute trusted workspace");let o=await Ct(i);if(!(await ma(o)).isDirectory())throw O("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>Ct(d))):[o]).some(d=>sr(d,o)))throw O("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function Vn({config:e,target:t,command:r,args:n,cwd:s,environment:i,runId:o,agentId:a,sessionId:u,sandboxPolicy:d}){if(!e.sandboxRequired)return{command:r,args:[...n],cwd:s,environment:{...process.env,...i},tempDirectory:"",isolation:{enforced:!1,backend:"development_direct"},cleanup:async()=>{}};let f=it(d),p=await rr(e,t,s),h=await Ct(s);if(!sr(p,h))throw O("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let m=await Xn(e.sandboxBrokerCommand,process.env.PATH||"");if(!m)throw O("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let y=`runtime-${ua("sha256").update(String(o)).digest("hex").slice(0,32)}`,S=Ze(e.sandboxTempRoot||ft(_a(),"orcha-runtime-sandboxes"));await Ye(S,{recursive:!0,mode:448});let x=ft(S,`${y}-${la()}`),_=ft(x,"home"),w=ft(x,"artifacts");await Ye(_,{recursive:!0,mode:448}),await Ye(w,{recursive:!0,mode:448});let T=f.networkMode==="restricted"?await Ca(e,{runId:String(o),instanceId:y,policyRevision:Number(f.policyRevision),ttlMs:Math.min(E(f.maxRuntimeSeconds,900)*1e3,e.egressGrantMaxTtlMs),maxTransferBytes:E(f.maxNetworkBytes,64*1024*1024)}):null,R={PATH:c(i.PATH||process.env.PATH),LANG:c(i.LANG||process.env.LANG||"C.UTF-8"),HOME:"/tmp/home",TMPDIR:"/tmp",USER:"orcha",LOGNAME:"orcha",SHELL:"/bin/sh",ORCHA_AGENT_ID:String(a),ORCHA_SESSION_ID:String(u),ORCHA_RUN_ID:String(o),ORCHA_RUNTIME_ARTIFACT_DIR:"/tmp/artifacts",...Ra(t,i)};R.HOME="/tmp/home",R.TMPDIR="/tmp",R.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",R.NODE_OPTIONS=wa;let N={schemaVersion:ya,runId:String(o),instanceId:y,workspace:p,cwd:h,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await Sa(p),temporaryDirectory:x,egressProxy:T,environment:R,resourceLimits:Oa(f),readOnlyToolchainRoots:await Ea(e,t)},M=!1,H=async()=>{if(!M){M=!0;try{T&&await xa(e,T,{runId:String(o),instanceId:y})}finally{await ha(x,{recursive:!0,force:!0})}}};return{command:m,args:[...b(e.sandboxBrokerArguments),"--",r,...n],cwd:h,environment:{PATH:process.env.PATH||"",LANG:process.env.LANG||"C.UTF-8",ORCHA_PROCESS_ISOLATION_REQUEST:JSON.stringify(N)},tempDirectory:x,homeDirectory:_,artifactDirectory:w,pathMappings:[{runtimeRoot:"/tmp/artifacts",hostRoot:w},{runtimeRoot:"/tmp/home",hostRoot:_}],isolation:{enforced:!0,backend:"broker",instanceId:y,policyRevision:f.policyRevision},cleanup:H}}async function Ea(e,t){let r=b(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(b(e.trustedToolchainRoots).map(i=>Ct(i)));if(!n.length)throw O("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","target toolchain roots require ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS");let s=[];for(let i of r){if(!xt(i))throw O("RUNTIME_TOOLCHAIN_ROOT_INVALID","toolchain roots must be absolute");let o=await Ct(i);if(!n.some(a=>sr(a,o)))throw O("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function Ra(e,t){let r=l(e.env)?e.env:{},n={};for(let[s,i]of Object.entries(r))/^[A-Za-z_][A-Za-z0-9_]*$/.test(s)&&i!=null&&(n[s]=String(i));for(let s of["ORCHA_RUNTIME_PROMPT","ORCHA_RUNTIME_ARTIFACT_DIR"])t[s]!=null&&(n[s]=String(t[s]));return n}async function Sa(e){let t=[],r=0,n=async s=>{let i;try{i=await pa(s,{withFileTypes:!0})}catch(o){if(s===e)throw o;return}for(let o of i){if(r+=1,r>1e4)throw O("RUNTIME_WORKSPACE_SCAN_LIMIT_EXCEEDED","workspace contains more than 10000 entries");let a=ft(s,o.name),u=zn(e,a),d=o.name.toLowerCase();(Ta.has(d)||d.startsWith(".env."))&&t.push(u),o.isDirectory()&&!o.isSymbolicLink()&&await n(a)}};return await n(e),t.sort()}function Oa(e){return{maxCpuSeconds:Math.max(1,E(e.maxRuntimeSeconds,900)),maxMemoryBytes:E(e.maxMemoryBytes,2*1024*1024*1024),maxProcesses:E(e.maxProcesses,128),maxOpenFiles:E(e.maxOpenFiles,1024),maxFileBytes:E(e.maxFileBytes,64*1024*1024)}}async function Ia(e,t,r){return await new Promise((n,s)=>{let i=ca(e,[...t,"--probe"],{env:{PATH:process.env.PATH||"",LANG:"C.UTF-8"},stdio:["ignore","pipe","pipe"],windowsHide:!0}),o=[],a=[];i.stdout.on("data",d=>o.push(Buffer.from(d))),i.stderr.on("data",d=>a.push(Buffer.from(d)));let u=setTimeout(()=>i.kill("SIGKILL"),Math.max(1e3,r));i.once("error",s),i.once("close",d=>{if(clearTimeout(u),d!==0){s(O("RUNTIME_SANDBOX_UNAVAILABLE",Buffer.concat(a).toString("utf8").trim()||`sandbox probe exited with ${d}`));return}try{n(JSON.parse(Buffer.concat(o).toString("utf8")))}catch{s(O("RUNTIME_SANDBOX_UNAVAILABLE","sandbox probe returned invalid JSON"))}})})}async function Xn(e,t){let r=c(e);if(!r)return"";let n=xt(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>ft(s,r));for(let s of n)try{return await fa(s,da.X_OK),s}catch{}return""}async function Ca(e,t){if(!e.egressProxyRequired)throw O("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await nr(e,"POST","/v1/grants",{protocolVersion:er,...t}),n={socketPath:e.egressProxySocket,grantId:c(r.grantId),credential:c(r.credential)};if(!n.grantId||!n.credential)throw O("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy returned an invalid grant");return n}async function xa(e,t,r){await nr(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:er,...r}).catch(()=>{})}async function Aa(e){let t=await nr(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==er)throw O("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function nr(e,t,r,n){if(!xt(e.egressProxySocket)||!e.egressProxyToken)throw O("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy socket and token are required");return await new Promise((s,i)=>{let o=ga.request({socketPath:e.egressProxySocket,path:r,method:t,headers:{Authorization:`Bearer ${e.egressProxyToken}`,Accept:"application/json",...n?{"Content-Type":"application/json"}:{}}},a=>{let u=[],d=0;a.on("data",f=>{d+=f.length,d>1048576?o.destroy(new Error("egress response is too large")):u.push(Buffer.from(f))}),a.once("end",()=>{try{let f=JSON.parse(Buffer.concat(u).toString("utf8")||"{}");(a.statusCode||500)>=400?i(O("RUNTIME_EGRESS_UNAVAILABLE",c(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 sr(e,t){let r=zn(Ze(e),Ze(t));return r===""||!r.startsWith("..")&&!xt(r)}function O(e,t){return Object.assign(new Error(t),{code:e})}var ir=24e3,or=8,ar=50,cr=6e3,ba=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),Ma=10*60*1e3,Ua=60*1e3,Pa=8,La=30*60*1e3,ka=60*1e3,va=1,ts=2400,Da=new Set(["max_tokens","max_output_tokens","length"]),Ha=new Set(["agent_message_chunk","tool_call","tool_call_update"]),Fa=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),$a=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function Ba(e){if(!l(e))return{};let t={};for(let r of["name","code","serverName","serverCode","type","transport","url","command","protocolVersion"]){let n=c(e[r]);n&&(t[r]=n)}return t}function ja(e){return(Array.isArray(e)?e:[]).map(Ba).sort((t,r)=>{let n=q(t),s=q(r);return n<s?-1:n>s?1:0})}function qa(e){return!l(e)||e.verificationPlan?.required!==!0?!1:(Array.isArray(e.verificationPlan.checks)?e.verificationPlan.checks:[]).some(r=>l(r)&&Array.isArray(r.toolNames)&&r.toolNames.some(n=>c(n)==="plugin_operation"))}function Ka(e,t,r){let n=l(e?._meta)?e._meta:{};return{...l(e)?e:{},sessionId:t,update:l(e?.update)?e.update:{},_meta:{...n,orchaAgentId:r.agentId,runtimeSessionId:r.runtimeSessionId,bridgeUpdateId:re()}}}function D(e){return e==null||e===""?!1:typeof e=="string"?c(e)!=="":Array.isArray(e)?e.length>0:l(e)?Object.keys(e).length>0:!0}function es(e){let t=c(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return ba.has(t)}function Y(e,t){let r=E(e,t);return Number.isFinite(r)&&r>0?r:t}function At(e,t=!1){if(typeof e=="boolean")return e;let r=c(e).toLowerCase();return["true","1","yes","y","on"].includes(r)?!0:["false","0","no","n","off"].includes(r)?!1:t}function G(e){return c(e?.type||"echo")}function rs(e){let t=G(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function dr(e){if(l(e)){if(Object.prototype.hasOwnProperty.call(e,"releaseAfterPrompt"))return e.releaseAfterPrompt;if(Object.prototype.hasOwnProperty.call(e,"disposeAfterPrompt"))return e.disposeAfterPrompt}}function Ga(e){let t=String(e||"");if($a.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 fr(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=cr)return e;let r=e.length-cr;return`${e.slice(0,cr)}... [truncated ${r} characters]`}if(t>=or)return Array.isArray(e)?`[array truncated at depth ${or}, items=${e.length}]`:l(e)?`[object truncated at depth ${or}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,ar).map(n=>fr(n,t+1));return e.length>ar&&r.push(`[truncated ${e.length-ar} items]`),r}if(l(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=Ga(n)?"[REDACTED]":fr(s,t+1);return r}return String(e)}var za=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 Ja(e){if(!l(e))return e;let t={};for(let r of za)D(e[r])&&(t[r]=e[r]);return t}function Wa(e){if(!l(e))return e;let t={...e};return l(t.renderedPayload)&&(t.renderedPayload=Ja(t.renderedPayload)),t}function Va(e){let t=l(e)?e:{},r={};D(t.metadata)&&(r.metadata=Wa(t.metadata));for(let[n,s]of Object.entries(t))Fa.has(n)||n==="metadata"||D(s)&&(r[n]=s);return r}function Xa(e){let t=l(e)?e:{},r=l(t.metadata)?t.metadata:{},n=l(r.renderedPayload)?r.renderedPayload:{};return l(t.resultContract)?t.resultContract:l(n.resultContract)?n.resultContract:{}}function ns(e){return c(Xa(e).kind).toLowerCase()==="decision"}function Ya(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:G(e)==="cli"}function Yn(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return At(t,rs(e))}function Qa(e,t){let r=l(e?.metadata)?{...e.metadata}:{},n=l(r._runtimeBridge)?{...r._runtimeBridge}:{},s=dr(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:Ya(t),releaseAfterPrompt:s===void 0?Yn(t):At(s,Yn(t)),requiresRuntimeResult:ns(e)},r}function Za(e){let t=Va(e);if(!D(t))return"";let r=JSON.stringify(fr(t),null,2);if(r.length<=ir)return r;let n=r.length-ir;return`${r.slice(0,ir)}
|
|
18
|
+
... [truncated ${n} characters]`}function hr(e){if(!l(e))return"";let t=l(e.update)?e.update:e,n=(l(t.content)?t.content:{}).text??t.text;return n==null?"":String(n)}function pr(e){if(!l(e))return"";let t=l(e.update)?e.update:e;return c(t.sessionUpdate)}function mr(e){if(!Array.isArray(e))return"";let t=!1,r=[],n=[],s=[],i=()=>{r.length>0&&(n.push(r),r=[])};for(let a of e){let u=pr(a),d=hr(a);if(!u){d&&s.push(d);continue}if(t=!0,u==="agent_message_chunk"){d&&r.push(d);continue}(u==="agent_thought_chunk"||u==="user_message_chunk"||u==="tool_call"||u==="tool_call_update"||u==="plan")&&i()}if(i(),!t)return pt(s);let o=n[n.length-1]||[];return pt(o)}function tc(e){return Array.isArray(e)?e.map(hr).filter(t=>t!==""):[]}function ne(e){return Array.isArray(e)?e.some(r=>pr(r))?e.filter(r=>Ha.has(pr(r))).map(hr).filter(r=>r!==""):tc(e):[]}function ec(e){if(!l(e))return null;let t=l(e.update)?e.update:e;return c(t.sessionUpdate)!=="runtime_event"?null:l(t.event)?t.event:null}function rc(e){if(!l(e))return"";let t=l(e.payload)?e.payload:{},r=c(e.type),n=c(t.type);if(r==="event_msg"){if(n==="task_complete")return c(t.last_agent_message||t.message||t.output);if(n==="agent_message"){let s=c(t.phase||t.status||t.stage).toLowerCase();if(["final_answer","final","complete","completed","done"].includes(s))return c(t.message||t.text||t.content)}}return""}function nc(e){if(!Array.isArray(e))return"";for(let t=e.length-1;t>=0;t-=1){let r=rc(ec(e[t]));if(r)return r}return""}function pt(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=Bn(n)&&!/[\r\n]$/.test(t)?`
|
|
19
|
+
`:"";t+=`${s}${n}`}}return t.trim()}function sc(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]===`
|
|
20
|
+
`?1:0)).trim()}function Qn(e){let t=String(e||"").trim();if(!t)return null;try{let r=JSON.parse(t);if(l(r)&&(ss(r)||D(r._artifacts)||D(r.artifacts)||D(r._decision)||D(r._meta)))return r}catch{}return null}function Nt(e){try{return ze(e)}catch{return null}}function ee(...e){let t=null;for(let r of e)try{if(ze(r))return}catch(n){t||=n}if(t)throw t}function ur(e){let t=String(e||"").trim();if(!t)return null;let r=Nt(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=Qn(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=Qn(t.slice(s));if(i)return i}return null}function ic(e){let t=Nt(mr(e));if(t)return t;let r=ne(e);for(let n=r.length-1;n>=0;n-=1){let s=Nt(r[n]);if(s)return s}return Nt(pt(r))}function ss(e){if(!l(e))return!1;if(D(e.output))return!0;for(let t of["content","text","message","summary"])if(c(e[t]))return!0;return!!(es(e.status)||c(e.error)||c(e.errorMessage))}function j(e){let t=l(e)?{...e}:{};return(!Array.isArray(t._artifacts)||t._artifacts.length===0)&&Array.isArray(t.artifacts)&&t.artifacts.length>0&&(t._artifacts=t.artifacts),delete t.artifacts,t}function oc(e){return l(e)?typeof(l(e._decision)?e._decision:l(e.decision)?e.decision:e).passed=="boolean":!1}function is(e){return l(e)?l(e._decision)&&typeof e._decision.passed=="boolean"?!0:oc(e.output):!1}function lr(e,t,r){let n=l(e)?{...e}:{};if(!D(n.output)){for(let s of["summary","message","content","text"])if(c(n[s])){n.output=c(n[s]);break}}return!D(n.output)&&c(r)&&(n.output=c(r)),{...n,_meta:{...l(n._meta)?n._meta:{},runtimeOutputSource:t,requiredRuntimeResult:!0,finalMessagePreview:c(r).slice(0,1e3)}}}var ac=["dataUrl","dataURL","contentDataUrl","contentDataURL","contentBase64","base64","data"];function Zn(e){if(!l(e))return"";let t=l(e.content)?e.content:{},r=l(e.metadata)?e.metadata:{};return c(e.fieldKey||e.field_key||t.fieldKey||r.fieldKey)}function cc(e,t){let r=l(e.content)?e.content:{},n=l(t.content)?t.content:{},s={...e,...t,content:{...r,...n},metadata:{...l(e.metadata)?e.metadata:{},...l(t.metadata)?t.metadata:{}}};for(let i of ac)D(e[i])&&(s[i]=e[i]),D(r[i])&&(s.content[i]=r[i]);return s}function os(e,t){let r=Array.isArray(e)?e.filter(l):[],n=Array.isArray(t)?t.filter(l):[];if(!r.length)return n;if(!n.length)return r;let s=[...r],i=new Map;for(let a=0;a<r.length;a+=1){let u=Zn(r[a]),d=i.get(u)||[];d.push(a),i.set(u,d)}let o=new Map;for(let a of n){let u=Zn(a),d=o.get(u)||0;o.set(u,d+1);let f=i.get(u)?.[d];f===void 0?s.push(a):s[f]=cc(s[f],a)}return s}function K(e,t,r){let n={...e,...t,_meta:{...l(e._meta)?e._meta:{},...l(t._meta)?t._meta:{},runtimeOutputSource:r}};return(Array.isArray(e._artifacts)||Array.isArray(t._artifacts))&&(n._artifacts=os(e._artifacts,t._artifacts)),n}function as(e,t,r={}){let n=c(r.promptKind),s=r.requiresRuntimeResult===!0,i=s||n==="dispatch",o=j(e),a=typeof o.output=="string"?Nt(o.output):null;if(a)return K(o,j(a),"result_block");let u=nc(t),d=u?ur(u):null,f=i?ic(t):null;if(ss(o))return es(o.status)||c(o.error)||c(o.errorMessage)?o:n==="dispatch"&&d?K(o,j(d),"final_event"):n==="dispatch"&&f?K(o,j(f),"updates"):!s||is(o)?o:d?K(o,j(d),"final_event"):f?K(o,j(f),"updates"):(ee(o.output,u,pt(ne(t))),lr(o,"result",o.output));if(d)return K(o,j(d),"final_event");if(f)return K(o,j(f),"updates");if(u)return s?(ee(u,pt(ne(t))),lr(o,"final_event",u)):{...o,output:u,_meta:{...l(o._meta)?o._meta:{},runtimeOutputSource:"final_event"}};let p=mr(t),h=ur(p);if(h)return K(o,j(h),"updates");let m=sc(p);if(!m)return s&&ee(pt(ne(t))),o;let y=ur(m);return y?K(o,j(y),"updates"):s?(ee(p,m),lr(o,"updates",m)):{...o,output:m,_meta:{...l(o._meta)?o._meta:{},runtimeOutputSource:"updates"}}}function gr(e){return l(e)?c(e.stopReason||e.stop_reason).toLowerCase():""}function cs(e){return Da.has(gr(e))}function uc(e,t,r){if(r.promptKind!=="dispatch"||r.requiresRuntimeResult!==!0||!cs(e))return!1;try{return!is(as(e,t,r))}catch{return!0}}function lc(){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 ${ts} Unicode characters.`,`Output ${Be}, ${je}, ${qe}, and ${Ke} on their own lines.`,"The CONTROL block must be valid JSON containing _decision and must be fully closed.","Return only the two protocol blocks."].join(`
|
|
21
|
+
`)}function dc(e,t){let r=l(t)?{...t}:{},n=os(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function fc(e,t){return{...e,_meta:{...l(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:gr(t)||"max_tokens"}}}}function pc(e,t){let r=typeof e?.output=="string"?e.output:mr(t),n=new v("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:gr(e)||"max_tokens",retryAttempted:!0},n}var se=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=wt(),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 Wn(this.config)}catch(t){this.sandboxCapabilities={...this.sandboxCapabilities,dispatchable:!1,enforced:!1,backend:"unavailable",daemonStatus:"unavailable",reason:c(t?.code||t?.message||t)||"sandbox_probe_failed"},g("error","runtime-bridge","runtime node sandbox probe failed; node will not accept work",{reason:this.sandboxCapabilities.reason})}return this.sandboxCapabilities}assertDispatchable(){if(this.config.sandboxRequired&&!(this.sandboxCapabilities.dispatchable===!0&&this.sandboxCapabilities.enforced===!0))throw Object.assign(new Error("runtime node strong sandbox is unavailable"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"})}operationIdentity(t,r,n){let s=l(t.goalContract)?Xe(t.goalContract):c(t.goalContractHash),i=Na("sha256").update(q({prompt:Array.isArray(t.prompt)?t.prompt:[],mcpServers:ja(t.mcpServers),metadata:l(t.metadata)?t.metadata:{}})).digest("hex");return{agentId:r,runId:c(t.runId),sessionId:n,targetCode:c(t.targetCode||t.framework),workspace:c(t.workspace),goalContractHash:s,requestHash:i}}assertOperationIdentity(t,r,n,s){let i=this.operationIdentity(r,n,s),o=Object.keys(t.identity).find(a=>t.identity[a]!==i[a]);if(o)throw Object.assign(new Error(`runtime operation correlation conflict: ${t.correlationId}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT",field:o})}createOperation(t,r,n,s){let i={correlationId:t,agentId:n,sessionId:s,identity:this.operationIdentity(r,n,s),sandboxPolicy:l(r.sandboxPolicy)?structuredClone(r.sandboxPolicy):null,status:"running",updates:[],listeners:new Set,waiters:[],response:null,error:null,mcpServers:r.mcpServers,createdAtMs:Date.now(),completedAtMs:null};return this.operations.set(t,i),i}async attachOperation(t,r={}){let n=()=>{if(r.onUpdate)for(let s of t.updates)r.onUpdate(s)};if(t.status==="completed")return n(),t.response;if(t.status==="failed")throw n(),t.error;r.onUpdate&&t.listeners.add(r.onUpdate);try{return n(),await new Promise((s,i)=>t.waiters.push({resolve:s,reject:i}))}finally{r.onUpdate&&t.listeners.delete(r.onUpdate)}}completeOperation(t,r){if(t.status==="running"){t.status="completed",t.response=r,t.mcpServers=null,t.completedAtMs=Date.now();for(let n of t.waiters.splice(0))n.resolve(r);t.listeners.clear()}}promptResponse(t,r,n,s,i,o=s){let a=l(t.metadata)?t.metadata:{},u=l(a._runtimeBridge)?a._runtimeBridge:{},d=a.source==="channel_message"?i:as(i,o,u),f=Kn(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=Y(this.config.operationTtlMs,La);for(let[n,s]of this.operations)s.status!=="running"&&t-(s.completedAtMs||s.createdAtMs)>r&&this.operations.delete(n)}targetFor(t){let r=c(t)||this.config.defaultTargetCode,n=this.targets[r];if(!r||!l(n)){let s=new Error(`runtime target is not configured: ${r||"<empty>"}`);throw s.code="RUNTIME_TARGET_NOT_FOUND",s}return{code:r,target:n}}targetIdleTtlMs(t){let n=G(t)==="openclaw"?Y(this.config.openClawSessionIdleTtlMs,ka):Y(this.config.sessionIdleTtlMs,Ma);return Y(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=G(t)==="openclaw"?Y(this.config.openClawMaxSessions,va):Y(this.config.maxSessionsPerTarget,Pa);return Y(t?.maxSessions,n)}targetReservationCount(t){return Number(this.targetReservations.get(t)||0)}notifyCapacityChanged(){try{this.onCapacityChanged?.()}catch(t){g("warn","runtime-bridge","capacity heartbeat callback failed",{error:String(t)})}}targetCapacitySnapshot(t=!0){return Object.entries(this.targets).map(([r,n])=>{let s=[...this.sessions.values()].filter(f=>f.targetCode===r),i=s.filter(f=>f.busy).length,o=s.length-i,a=this.targetReservationCount(r),u=this.targetMaxSessions(n),d=t?Math.max(0,u-i-a):0;return{targetCode:r,targetName:c(n?.name||n?.targetName||r),targetType:c(n?.type||"echo"),status:t?d>0?"available":"busy":"unavailable",maxSessions:u,busySessions:i,idleSessions:o,reservedSessions:a,availableSessions:d}})}targetReleaseAfterPrompt(t,r={}){let n=G(t),s=l(r?._runtimeBridge)?r._runtimeBridge:{},i=dr(s);return i!==void 0?At(i,!1):At(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=l(r?._runtimeBridge)?r._runtimeBridge:{},s=dr(n);return s!==void 0?At(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=Y(this.config.sessionCleanupIntervalMs,Ua);t<=0||(this.cleanupTimer=setInterval(()=>{this.cleanupExpiredSessions().catch(r=>{g("warn","runtime-bridge","runtime session cleanup failed",{error:String(r)})})},t),this.cleanupTimer.unref?.())}sessionCountForTarget(t){let r=0;for(let n of this.sessions.values())n.targetCode===t&&(r+=1);return r}idleTargetSessions(t){return[...this.sessions.entries()].filter(([,r])=>r.targetCode===t&&!r.busy).sort((r,n)=>(r[1].lastUsedAtMs||0)-(n[1].lastUsedAtMs||0))}async closeSession(t,r="session_closed"){let n=this.sessions.get(t);if(!n)return!1;try{await n.runtime?.stop?.(r)}catch(s){g("warn","runtime-bridge","runtime session stop failed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,error:String(s)})}return this.sessions.delete(t),this.runtimeSessionIndex.delete(`${n.agentId}:${n.runtimeSessionId}`),this.notifyCapacityChanged(),g("info","runtime-bridge","runtime session closed",{sessionId:n.sessionId,runtimeSessionId:n.runtimeSessionId,targetCode:n.targetCode,runtimeKind:n.runtimeKind,reason:r}),!0}async closeAllSessions(t="bridge_shutdown"){for(let r of[...this.sessions.keys()])await this.closeSession(r,t)}async stop(t="bridge_stop"){this.cleanupTimer&&clearInterval(this.cleanupTimer),this.cleanupTimer=null,await this.closeAllSessions(t)}async cleanupExpiredSessions(t=Date.now()){for(let[r,n]of[...this.sessions.entries()])n.busy||t-(n.lastUsedAtMs||n.createdAtMs||t)>n.idleTtlMs&&await this.closeSession(r,"idle_timeout")}async reserveTargetSlot(t,r){let n=this.targetMaxSessions(r);for(;this.sessionCountForTarget(t)+this.targetReservationCount(t)>=n;){let s=this.idleTargetSessions(t);if(!s.length){let i=new Error(`runtime target session limit reached: ${t}`);throw i.code="RUNTIME_TARGET_SESSION_LIMIT",i}await this.closeSession(s[0][0],"target_session_limit")}this.targetReservations.set(t,this.targetReservationCount(t)+1),this.notifyCapacityChanged()}releaseTargetSlot(t){let r=Math.max(0,this.targetReservationCount(t)-1);r>0?this.targetReservations.set(t,r):this.targetReservations.delete(t),this.notifyCapacityChanged()}async createAgent(t){let r=c(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 rr(this.config,s,t.workspace):c(t.workspace),a={agentId:r,targetCode:n,framework:c(t.framework||n),workspace:o,metadata:l(t.metadata)?t.metadata:{},createdAt:wt(),runtimeKind:G(s)};return this.agents.set(r,a),{agent:a}}runtimeFor(t,r,n={}){let{target:s}=this.targetFor(t.targetCode),i=G(s),o={onPermissionRequest:u=>n.source==="conversation_delegation"?{outcome:"denied",reason:"External group member permission continuation is not supported"}:this.requestPermission(u)},a={sessionPromptTimeoutMs:this.config.sessionPromptTimeoutMs,initializeTimeoutMs:this.config.initializeTimeoutMs,sandboxRequired:this.config.sandboxRequired,runId:n.runId,source:n.source,cloudSessionId:r,orchaUrl:this.config.orchaUrl,attachOnly:n.attachOnly,sandboxPolicy:n.sandboxPolicy,...this.config.sandboxRequired?{prepareLaunch:u=>Vn({config:this.config,target:s,...u,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new lt(t,s,o,a):i==="openclaw"?new qt(t,s,r,o,a):i==="cli"?new Vt(t,s,a):new vt(t)}async prompt(t,r={}){if(this.assertDispatchable(),this.config.sandboxRequired){let a=c(t.runId);if(!a)throw Object.assign(new Error("runId is required"),{code:"BAD_REQUEST"});t={...t,runId:a,sandboxPolicy:it(t.sandboxPolicy)}}let n=c(t.agentId),s=c(t.sessionId)||re(),i=c(t.correlationId);if(!n)throw Object.assign(new Error("agentId is required"),{status:400,code:"BAD_REQUEST"});if(this.cleanupOperations(),i){let a=this.operations.get(i);if(a){if(this.assertOperationIdentity(a,t,n,s),a.status==="running"&&(["conversation_delegation","channel_message"].includes(t.metadata?.source)||t.metadata?.source==="ai_chat_runtime_node"&&t.framework==="codex")){a.mcpServers=t.mcpServers;let u=this.sessions.get(`${n}:${s}`);if(u){if(!u.runtime.refreshMcpServers)throw Object.assign(new Error("This runtime cannot refresh task MCP credentials"),{code:"unsupported_dynamic_mcp"});await u.runtime.refreshMcpServers(t.mcpServers)}}return this.attachOperation(a,r)}if(t.attachOnly===!0&&!(t.metadata?.source==="channel_message"&&this.targetFor(t.targetCode||t.framework).target.type==="openclaw"))throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"})}else if(t.attachOnly===!0)throw Object.assign(new Error("correlationId is required for attachOnly"),{code:"BAD_REQUEST"});let o=i?this.createOperation(i,t,n,s):null;if(o){let a=this.attachOperation(o,r);return(async()=>{try{await this._promptOwned(t,{},o,n,s)}catch(u){let d=o.status==="completed";this.failOperation(o,u),d&&g("warn","runtime-bridge","runtime cleanup failed after operation completion",{correlationId:o.correlationId,error:String(u)})}})(),await a}return await this._promptOwned(t,r,o,n,s)}async _promptOwned(t,r,n,s,i){let o=c(t.runId),a=this.config.sandboxRequired?it(n?.sandboxPolicy||t.sandboxPolicy):null,u=this.agents.get(s),d=this.targetFor(t.targetCode||t.framework||u?.targetCode);if(u&&u.targetCode!==d.code)throw Object.assign(new Error(`runtime agent target conflict: ${s}`),{code:"RUNTIME_AGENT_TARGET_CONFLICT"});if(G(d.target)==="cli"&&qa(t.goalContract))throw Object.assign(new Error("CLI runtimes do not support per-run dynamic MCP required by plugin_operation"),{code:"unsupported_dynamic_mcp"});let f=u||(await this.createAgent({agentId:s,targetCode:d.code,framework:t.framework,workspace:t.workspace,metadata:t.metadata})).agent;if(!this.config.sandboxRequired){let _=c(t.workspace);_&&_!==f.workspace&&(f.workspace=_)}let p=`${s}:${i}`;await this.cleanupExpiredSessions();let h=this.sessions.get(p),m=null;if(h&&h.targetCode!==d.code)throw Object.assign(new Error(`runtime session target conflict: ${i}`),{code:"RUNTIME_SESSION_TARGET_CONFLICT"});if(h&&this.config.sandboxRequired&&h.runId!==o)throw Object.assign(new Error(`runtime session cannot be shared across runs: ${i}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});if(!h){if(this.startingSessions.has(p))throw Object.assign(new Error(`runtime session is already starting: ${i}`),{code:"RUNTIME_SESSION_BUSY"});this.startingSessions.add(p);let{code:_,target:w}=d,T;try{await this.reserveTargetSlot(_,w),m=_;let R=this.runtimeFor(f,i,{runId:o,sandboxPolicy:a,source:t.metadata?.source,attachOnly:t.attachOnly});T=R;let N=n?.mcpServers||t.mcpServers||[],M=await R.sessionNew({cwd:et(w,f.workspace),mcpServers:N,metadata:l(t.metadata)?t.metadata:{}});if(n&&n.status!=="running")throw Object.assign(new Error("Runtime operation was cancelled before prompt dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"});let H=Date.now();h={agentId:s,sessionId:i,runtime:R,targetCode:_,runtimeKind:G(w),runId:o,sandboxPolicy:a?structuredClone(a):null,runtimeSessionId:c(l(M)?M.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(w),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(w,t.metadata),createdAtMs:H,lastUsedAtMs:H,busy:!1,createdAt:wt()},this.sessions.set(p,h),this.runtimeSessionIndex.set(`${s}:${h.runtimeSessionId}`,h),n?.mcpServers!==N&&n?.mcpServers&&R.refreshMcpServers&&await R.refreshMcpServers(n.mcpServers)}catch(R){throw this.sessions.get(p)?.runtime===T?await this.closeSession(p,"session_start_failed"):await T?.stop("session_start_failed"),m&&(this.releaseTargetSlot(m),m=null),R}finally{this.startingSessions.delete(p)}}if(h.busy){let _=new Error(`runtime session is already running: ${i}`);throw _.code="RUNTIME_SESSION_BUSY",_}h.busy=!0,m&&this.releaseTargetSlot(m),this.notifyCapacityChanged(),h.operationCorrelationId=n?.correlationId||null,h.lastUsedAtMs=Date.now();let y=n?.updates||[],S=_=>{let w=Ka(_,i,h);if(y.push(w),n)for(let T of n.listeners)try{T?.(w)}catch(R){g("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(R)})}else r.onUpdate?.(w)},x=_=>{if(!(!n||n.status!=="running"||!l(_))){if(_.status==="failed"){let w=_.error;if(w instanceof Error){this.failOperation(n,w);return}let T=l(w)?w:{},R=Object.assign(new Error(c(T.message||_.message)||"runtime terminal failure"),{code:c(T.code||_.code)||"RUNTIME_TERMINAL_FAILED"});this.failOperation(n,R);return}this.completeOperation(n,this.promptResponse(t,h,i,y,l(_.result)?_.result:{stopReason:"end_turn"}))}};try{let _=qn(t.goalContract),w=Array.isArray(t.prompt)?[...t.prompt]:[];_&&w.unshift({type:"text",text:_,metadata:{source:"orcha_goal_contract"}});let T=l(t.metadata)?t.metadata:{},R=l(T._runtimeBridge)?T._runtimeBridge:{},N=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:w,metadata:T},S,x),M=y,H=null;if(rs({type:h.runtimeKind})&&uc(N,y,R)){H=N;let z=y.length,I=await h.runtime.sessionPrompt({sessionId:h.runtimeSessionId,prompt:[{type:"text",text:lc()}],metadata:T,_meta:{thinking:"off"}},S,x);N=dc(H,I),M=y.slice(z)}let Q;try{Q=this.promptResponse(t,h,i,y,N,M)}catch(z){throw H&&cs(N)?pc(N,M):z}return H&&(Q.result=fc(Q.result,H)),n&&this.completeOperation(n,Q),Q}finally{h.busy=!1,this.notifyCapacityChanged(),h.operationCorrelationId===n?.correlationId&&(h.operationCorrelationId=null),h.lastUsedAtMs=Date.now(),this.promptReleaseAfterPrompt(h,l(t.metadata)?t.metadata:{})&&await this.closeSession(p,"release_after_prompt"),n&&(n.mcpServers=null)}}async updatePolicy(t){if(this.assertDispatchable(),!this.config.sandboxRequired)throw Object.assign(new Error("runtime sandbox policy updates require an enforced sandbox"),{code:"RUNTIME_NODE_SANDBOX_UNAVAILABLE"});let r=c(t.agentId),n=c(t.runId),s=c(t.sessionId),i=c(t.correlationId);if(!r||!n||!s||!i)throw Object.assign(new Error("agentId, runId, sessionId and correlationId are required"),{code:"BAD_REQUEST"});let o=it(t.sandboxPolicy),a=this.operations.get(i);if(a&&(a.agentId!==r||a.sessionId!==s||a.identity.runId!==n))throw Object.assign(new Error(`runtime operation policy identity conflict: ${i}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let u=`${r}:${s}`,d=this.sessions.get(u);if(d&&d.runId!==n)throw Object.assign(new Error(`runtime session policy identity conflict: ${s}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});let f=d?.sandboxPolicy||a?.sandboxPolicy;if(!f)throw Object.assign(new Error(`runtime operation is no longer available: ${i}`),{code:"RUNTIME_OPERATION_NOT_FOUND"});let p=Number(f.policyRevision),h=Number(o.policyRevision);if(h<p)throw Object.assign(new Error("runtime sandbox policy revision is stale"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});if(h===p){if(q(f)!==q(o))throw Object.assign(new Error("runtime sandbox policy revision payload conflicts"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:p});return{updated:!1,idempotent:!0,policyRevision:p,accessMode:f.accessMode}}let m=Jn(f,o);a&&(a.sandboxPolicy=structuredClone(o)),d&&(d.sandboxPolicy=structuredClone(o));let y=!1;return m&&d?.busy===!0&&(await d.runtime.sessionCancel({sessionId:d.runtimeSessionId}),y=await this.closeSession(u,"sandbox_policy_downgrade")),{updated:!0,policyRevision:h,accessMode:o.accessMode,activeCommandCancelled:y,deferredToNextLaunch:!m&&d?.busy===!0}}async cancel(t){let r=c(t.agentId),n=c(t.sessionId),s=c(t.correlationId);if(s){let a=this.operations.get(s);if(!a||a.status!=="running")return{cancelled:!1,correlationId:s,reason:"operation_not_running"};if(a.agentId!==r||a.sessionId!==n)throw Object.assign(new Error(`runtime operation cancellation identity conflict: ${s}`),{code:"RUNTIME_OPERATION_CORRELATION_CONFLICT"});let u=this.sessions.get(`${r}:${n}`);return!u||u.busy!==!0||u.operationCorrelationId!==s?(this.failOperation(a,Object.assign(new Error("Runtime operation cancelled before dispatch"),{code:"RUNTIME_OPERATION_CANCELLED"})),{cancelled:!0,correlationId:s,reason:"cancelled_before_dispatch"}):(await u.runtime.sessionCancel({sessionId:u.runtimeSessionId}),await this.closeSession(`${r}:${n}`,"cancelled"),{cancelled:!0,correlationId:s})}let i=`${r}:${n}`,o=this.sessions.get(i);return o?(await o.runtime.sessionCancel({sessionId:o.runtimeSessionId}),await this.closeSession(i,"cancelled"),{cancelled:!0}):{cancelled:!1}}async dispatch(t,r={}){let n=c(t.agentId),s=c(t.taskId),i=c(t.executionId);if(!n||!s)throw Object.assign(new Error("agentId and taskId are required"),{status:400,code:"BAD_REQUEST"});let o=c(t.sessionId)||`dispatch-${i||s}`,a=c(t.instructions),u=Za(t),d=ns(t),{target:f}=this.targetFor(t.targetCode||t.framework),p=[{type:"text",text:["Task dispatch received.",`taskId: ${s}`,i?`executionId: ${i}`:"",a?`instructions: ${a}`:"",u?"orchaContext:":"",u,u?"Use orchaContext as the source of truth for upstream outputs, review reports, artifacts, and workflow metadata.":"","Follow the execution protocol in instructions exactly.","When embedding a generated artifact in final Markdown, use the Orcha artifact placeholder as the link target: orcha-artifact://<fieldKey>/<index>.","Example: use  for the first generated image artifact.","Do not use local filesystem paths, file:// URLs, or data: URLs in final Markdown; Orcha replaces artifact placeholders after ingestion.",d?`For decision results, put the raw report between ${Be} and ${je}.`:"",d?`Then put a JSON object containing _decision between ${qe} and ${Ke}.`:"",d?"Do not JSON-escape the report. Keep output out of the CONTROL JSON, and put every protocol marker on its own line.":"",d?`Keep the report within ${ts} 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(`
|
|
22
|
+
`)}];return this.prompt({...t,agentId:n,sessionId:o,prompt:p,metadata:Qa(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=re(),a=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||re(),u={permissionId:i,agentId:t.agentId,sessionId:a,runtimeSessionId:r,request:l(n)?n:{},status:"pending",createdAt:wt()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:u}}),await new Promise(d=>{let f=E(n?.timeoutMs,this.config.permissionRequestTimeoutMs),p=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:p,resolve:d,permission:u})})}async respondPermission(t){let r=c(t.permissionId),n=this.pendingPermissions.get(r),s=c(t.outcome||"approved")||"approved";return n?(clearTimeout(n.timer),this.pendingPermissions.delete(r),n.resolve({permissionId:r,outcome:s,response:l(t.response)?t.response:{},userId:c(t.userId),metadata:l(t.metadata)?t.metadata:{}}),{accepted:!0,permissionId:r,outcome:s}):{accepted:!1,permissionId:r,outcome:s}}health(){return{status:this.config.sandboxRequired&&!this.sandboxCapabilities.dispatchable?"unavailable":"ok",bridgeVersion:W,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 hc from"node:http";import mc from"node:https";import{randomBytes as us}from"node:crypto";var ht=1,ot=3,gc=1e4,ie=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=_c(r.connectTimeoutMs,gc),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:"?mc:hc,n=us(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,a)=>{if(this.clearConnectTimer(),this.readyState===ot){o.destroy();return}this.socket=o,this.readyState=ht,o.on("data",u=>this.onData(u)),o.on("close",()=>this.onClose()),o.on("error",u=>{this.readyState!==ot&&this.emit("error",{error:u,message:u.message,type:"error"}),this.onClose()}),a?.length&&this.onData(a),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!==ot&&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===ht||this.readyState===ot)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!==ht||this.socket.write(_r(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==ot){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===ht&&this.socket.write(_r(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==ot&&(this.clearConnectTimer(),this.readyState=ot,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,a=2;if(o===126){if(this.buffer.length<a+2)return;o=this.buffer.readUInt16BE(a),a+=2}else if(o===127){if(this.buffer.length<a+8)return;let f=this.buffer.readUInt32BE(a),p=this.buffer.readUInt32BE(a+4);o=f*2**32+p,a+=8}let u=a;if(i&&(a+=4),this.buffer.length<a+o)return;let d=this.buffer.subarray(a,a+o);if(i){let f=this.buffer.subarray(u,u+4);d=Buffer.from(d.map((p,h)=>p^f[h%4]))}this.buffer=this.buffer.subarray(a+o),s===1?this.emit("message",{data:d.toString("utf8")}):s===8?this.close():s===9&&this.socket?.write(_r(10,d))}}};function _c(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function _r(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=us(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 a=0;a<r;a+=1)i[o+a]=t[a]^s[a%4];return i}function yc(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 wc(e,t=!0){return Object.entries(e||{}).map(([r,n])=>({targetCode:r,targetName:c(n?.name||n?.targetName||r),targetType:c(n?.type||"echo"),status:t?"available":"unavailable"}))}var Tc=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),oe=class{constructor(t,r){this.config=t,this.bridge=r,this.ws=null,this.stopped=!1,this.connected=!1,this.reconnectTimer=null,this.heartbeatTimer=null,this.capacityHeartbeatTimer=null,this.bridge.onCapacityChanged=()=>this.scheduleCapacityHeartbeat()}sandboxCapabilities(){return this.bridge.sandboxCapabilities||{dispatchable:this.config.sandboxRequired!==!0,enforced:!1,backend:"development_direct",daemonStatus:"development_only",policySchemaVersions:[1],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:!1}}supportedMethods(){return[...Tc,...this.config.deviceConnection?["devices/discover","devices/configure"]:[]]}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):wc(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=yc(this.config.orchaUrl),r=new ie(t,{connectTimeoutMs:this.config.connectTimeoutMs});this.ws=r,r.addEventListener("open",()=>{if(this.ws!==r||this.stopped){r.close();return}this.authenticate(r)}),r.addEventListener("message",n=>this.handleMessage(n.data,r)),r.addEventListener("close",()=>this.scheduleReconnect("close",r)),r.addEventListener("error",n=>{g("warn","orcha-client","runtime node websocket error",{error:String(n?.message||n?.type||n)})})}authenticate(t=this.ws){this.send({type:"runtime_node.authenticate",token:this.config.nodeToken,nodeId:this.config.nodeId,nodeName:this.config.nodeName,version:W,protocolVersion:"orcha-runtime-node.v2",defaultTargetCode:this.config.defaultTargetCode,supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t)}scheduleReconnect(t,r=this.ws){r&&this.ws!==r||(this.connected=!1,this.heartbeatTimer&&clearInterval(this.heartbeatTimer),this.heartbeatTimer=null,this.capacityHeartbeatTimer&&clearTimeout(this.capacityHeartbeatTimer),this.capacityHeartbeatTimer=null,r&&this.ws===r&&(this.ws=null),!this.stopped&&(this.reconnectTimer||(g("info","orcha-client","runtime node disconnected; reconnect scheduled",{reason:t,reconnectMs:this.config.reconnectMs}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.config.reconnectMs))))}async handleMessage(t,r=this.ws){if(r&&this.ws!==r)return;let n;try{n=JSON.parse(String(t))}catch(s){g("warn","orcha-client","invalid Orcha websocket frame",{error:String(s)});return}if(l(n)){if(n.type==="runtime_node.authenticated"){if(r&&this.ws!==r)return;this.connected=!0,this.startHeartbeat(r),g("info","orcha-client","runtime node authenticated",{nodeId:this.config.nodeId,connectionId:n.connectionId});return}if(n.type==="orcha.runtime.request"){await this.handleRequest(n);return}n.type==="runtime_node.ping"&&this.send({type:"runtime_node.pong",ts:new Date().toISOString(),supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()})}}startHeartbeat(t){this.heartbeatTimer&&clearInterval(this.heartbeatTimer);let r=Math.max(1e3,Number(this.config.heartbeatIntervalMs||15e3)),n=()=>this.sendCapacityHeartbeat(t);n(),this.heartbeatTimer=setInterval(n,r),this.heartbeatTimer.unref?.()}scheduleCapacityHeartbeat(){if(!this.connected||this.capacityHeartbeatTimer)return;let t=Math.max(25,Math.min(1e3,Number(this.config.capacityHeartbeatDebounceMs||100)));this.capacityHeartbeatTimer=setTimeout(()=>{this.capacityHeartbeatTimer=null,this.sendCapacityHeartbeat()},t),this.capacityHeartbeatTimer.unref?.()}sendCapacityHeartbeat(t=this.ws){return this.connected?this.send({type:"runtime_node.heartbeat",ts:new Date().toISOString(),supportedMethods:this.supportedMethods(),sandboxCapabilities:this.sandboxCapabilities(),targets:this.runtimeTargets()},t):!1}async handleRequest(t){let r=c(t.id),n=c(t.method),s=l(t.params)?t.params:{};try{let i=await this.invoke(n,s,r);this.send({type:"orcha.runtime.response",id:r,ok:!0,result:i})}catch(i){this.send({type:"orcha.runtime.response",id:r,ok:!1,error:{code:i.code||"RUNTIME_NODE_ERROR",message:i.message||String(i),...i.detail===void 0?{}:{detail:i.detail}}})}}async invoke(t,r,n){if(t==="devices/discover"&&this.config.deviceConnection)return this.config.deviceConnection.candidates();if(t==="devices/configure"&&this.config.deviceConnection)return this.config.deviceConnection.configure(r,this.bridge);if(t==="health")return this.bridge.health();if(t==="agents/create")return this.bridge.createAgent(r);if(t==="agents/dispatch")return this.bridge.dispatch(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/prompt")return this.bridge.prompt(r,{onUpdate:s=>this.sendUpdate(n,s)});if(t==="sessions/policy")return this.bridge.updatePolicy(r);if(t==="sessions/cancel")return this.bridge.cancel(r);if(t==="permissions/respond")return this.bridge.respondPermission(r);throw Object.assign(new Error(`unsupported Orcha runtime method: ${t}`),{code:"METHOD_NOT_FOUND"})}sendUpdate(t,r){this.send({type:"orcha.runtime.event",requestId:t,eventType:"runtime.update",payload:r})}send(t,r=this.ws){return!r||r!==this.ws||r.readyState!==ht?!1:(r.send(JSON.stringify(t)),!0)}};import{createServer as Ec}from"node:http";function ae(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 at(e={}){return{ok:!0,...e}}function yr(e,t,r){return{ok:!1,error:{code:e,message:t,...r===void 0?{}:{detail:r}}}}async function ls(e,t){let r=[],n=0;for await(let i of e){if(n+=i.length,n>t)throw Object.assign(new Error("request body too large"),{status:413,code:"REQUEST_TOO_LARGE"});r.push(i)}if(r.length===0)return{};let s=Buffer.concat(r).toString("utf8");if(!s.trim())return{};try{let i=JSON.parse(s);if(!l(i))throw Object.assign(new Error("JSON body must be an object"),{status:400,code:"BAD_JSON"});return i}catch(i){throw i.status?i:Object.assign(new Error(`invalid JSON body: ${i.message}`),{status:400,code:"BAD_JSON"})}}function ds(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 fs(e,t){let r={"GET /health":async()=>at(t.health()),"POST /agents/create":async n=>at(await t.createAgent(n)),"POST /agents/dispatch":async n=>at(await t.dispatch(n)),"POST /sessions/prompt":async n=>at(await t.prompt(n)),"POST /sessions/cancel":async n=>at(await t.cancel(n)),"POST /permissions/respond":async n=>at(await t.respondPermission(n))};return Ec(async(n,s)=>{let i=new URL(n.url||"/",`http://${n.headers.host||`${e.host}:${e.port}`}`),o=`${n.method||"GET"} ${i.pathname}`,a=r[o];if(!a){ae(s,404,yr("NOT_FOUND",`No route for ${o}`));return}try{ds(n,e.token);let u=n.method==="GET"?{}:await ls(n,e.requestLimitBytes);ae(s,200,await a(u))}catch(u){let d=u.status||500,f=u.code||"BRIDGE_INTERNAL";ae(s,d,yr(f,u.message||String(u),u.detail))}})}var Ts=xc(import.meta.url),Ac=".orcha-runtime-bridge.pid",Nc=".orcha-runtime-bridge.log",bc=3,Mc=36e5,{command:Uc,options:Es}=kc(process.argv.slice(2));vc(Es);an();var Pc=cn();await Rs(Uc,Pc,Es);async function Rs(e,t,r){if(r.url){let s=_e(r.url);r.pidFile||(process.env.ORCHA_RUNTIME_PID_FILE=s.pidFile),r.logFile||(process.env.ORCHA_RUNTIME_LOG_FILE=s.logFile)}let n=()=>["connect","--url",t.orchaUrl,"--foreground"];switch(e){case"connect":if(r.pairCode&&ct(ue(ce())))throw new Error("\u8BBE\u5907\u8FDE\u63A5\u4ECD\u5728\u540E\u53F0\u8FD0\u884C\uFF0C\u8BF7\u5148\u6267\u884C stop --url \u540E\u91CD\u65B0\u914D\u5BF9");await Mt(t,r),r.foreground?await wr(t):Tr(n());return;case"run":case"foreground":r.url&&await Mt(t,r),await wr(t);return;case"start":if(r.url)return Rs("connect",t,r);if(r.foreground){await wr(t);return}Tr();return;case"reload":case"restart":{r.url&&await Mt(t,{url:r.url});let s=mt(ws(Ts),".."),i=mt(s,...Or(mt(s,"src","index.js"))?["dist","package"]:[],"openclaw-plugin"),o=await zr(t.targets,i);await ms({quiet:!0}),await o(),Tr(r.url?n():void 0);return}case"stop":await ms();return;case"status":Lc();return;case"help":case"--help":case"-h":$c();return;default:throw new Error(`Unknown command: ${e}`)}}async function wr(e){Dc();let t=new se(e);if(await t.start(),e.mode==="server"){let n=fs(e,t);hs({bridge:t,server:n}),n.listen(e.port,e.host,()=>{g("info","runtime-bridge","Orcha runtime bridge HTTP server started",{host:e.host,port:e.port,targets:Object.keys(t.targets)})});return}if(!e.orchaUrl)throw new Error("ORCHA_RUNTIME_ORCHA_URL is required in runtime node mode");let r=new oe(e,t);hs({bridge:t,client:r}),r.start(),g("info","runtime-bridge","Orcha runtime node started",{nodeId:e.nodeId,nodeName:e.nodeName,orchaUrl:e.orchaUrl,targets:Object.keys(t.targets)})}function hs({bridge:e,client:t,server:r}){let n=!1,s=i=>{if(n)return;n=!0;let o=Number(e?.sessions?.size||0)>0;g("info","runtime-bridge","runtime bridge shutting down",{signal:i});try{t?.stop?.()}catch(a){g("warn","runtime-bridge","runtime client stop failed",{error:String(a)})}Promise.resolve(e?.stop?.(`process_${String(i||"shutdown").toLowerCase()}`)).catch(a=>{g("warn","runtime-bridge","runtime bridge stop failed",{error:String(a)})}).finally(()=>{try{r?.close?.()}catch(a){g("warn","runtime-bridge","runtime server close failed",{error:String(a)})}}),setTimeout(()=>process.exit(0),o?8500:200)};process.once("SIGTERM",()=>s("SIGTERM")),process.once("SIGINT",()=>s("SIGINT"))}function Tr(e=["run"]){let t=ce(),r=Ss(),n=ue(t);if(n&&ct(n)){console.log(JSON.stringify({status:"already_running",pid:n,pidFile:t,logFile:r}));return}n&&Sr(t),_s(t),_s(r),Rr(r);let s=Ic(r,"a"),i={...process.env,ORCHA_RUNTIME_PID_FILE:t,ORCHA_RUNTIME_LOG_FILE:r},o=Rc(process.execPath,[Ts,...e,"--pid-file",t,"--log-file",r],{cwd:process.cwd(),detached:!0,env:i,stdio:["ignore",s,s]});o.unref(),Sc(s),ys(t,`${o.pid}
|
|
23
|
+
`),console.log(JSON.stringify({status:"started",pid:o.pid,pidFile:t,logFile:r}))}async function ms({quiet:e=!1}={}){let t=ce(),r=ue(t);if(!r){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!ct(r)){Sr(t),e||console.log(JSON.stringify({status:"not_running",pid:r,pidFile:t}));return}process.kill(r,"SIGTERM"),!await gs(r,1e4)&&ct(r)&&(process.kill(r,"SIGKILL"),await gs(r,3e3)),Sr(t),e||console.log(JSON.stringify({status:"stopped",pid:r,pidFile:t}))}function Lc(){let e=ce(),t=Ss(),r=ue(e),n=!!(r&&ct(r));console.log(JSON.stringify({status:n?"running":"not_running",running:n,pid:n?r:null,pidFile:e,logFile:t}))}function kc(e){let t=[],r={};for(let s=0;s<e.length;s+=1){let i=e[s];i==="--url"?r.url=e[++s]:i==="--pair-code"?r.pairCode=e[++s]:i==="--daemon"?r.daemon=!0:i==="--foreground"?r.foreground=!0:i==="--env-file"?r.envFile=e[++s]:i==="--pid-file"?r.pidFile=e[++s]:i==="--log-file"?r.logFile=e[++s]:t.push(i)}return{command:t[0]||"run",options:r}}function vc(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 ce(){return mt(process.cwd(),process.env.ORCHA_RUNTIME_PID_FILE||Ac)}function Ss(){return mt(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||Nc)}function Dc(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=Os();if(t<=0)return;let r=mt(process.cwd(),e);Rr(r,t);let n=Fc();n<=0||setInterval(()=>Rr(r,t),n).unref()}function Rr(e,t=Os()){if(t<=0||!Or(e))return;let r=0,n="";try{if(r=ps(e).size,r<=0)return;n=Er(e,"utf8")}catch(d){g("warn","runtime-bridge","runtime log cleanup skipped",{logFile:e,error:String(d)});return}let s=Date.now()-t*24*60*60*1e3,i=n.split(/\r?\n/),o=[],a=0;for(let d of i)d&&(Hc(d,s)?o.push(d):a+=1);if(a===0)return;let u="";try{ps(e).size>r&&(u=Er(e,"utf8").slice(n.length));let f=[...o,...u.split(/\r?\n/).filter(Boolean)].join(`
|
|
24
|
+
`);ys(e,f?`${f}
|
|
25
|
+
`:""),g("info","runtime-bridge","runtime log cleanup completed",{logFile:e,retentionDays:t,removed:a})}catch(d){g("warn","runtime-bridge","runtime log cleanup failed",{logFile:e,error:String(d)})}}function Hc(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 Os(){return Is(process.env.ORCHA_RUNTIME_LOG_RETENTION_DAYS,bc)}function Fc(){return Is(process.env.ORCHA_RUNTIME_LOG_CLEANUP_INTERVAL_MS,Mc)}function Is(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function ue(e){if(!Or(e))return null;let t=Number.parseInt(Er(e,"utf8").trim(),10);return Number.isInteger(t)&&t>0?t:null}function ct(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function gs(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!ct(e))return!0;await new Promise(n=>setTimeout(n,100))}return!ct(e)}function _s(e){Oc(ws(e),{recursive:!0})}function Sr(e){try{Cc(e,{force:!0})}catch{}}function $c(){console.log(`Usage: orcha-runtime-bridge [command] [options]
|
|
26
26
|
|
|
27
27
|
Commands:
|
|
28
28
|
connect Pair or reconnect this device, then run in the background.
|
package/openclaw-plugin/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import{getPluginRuntimeGatewayRequestScope as Je}from"openclaw/plugin-sdk/plugin-runtime";import{loadOutboundMediaFromUrl as We}from"openclaw/plugin-sdk/outbound-media";function Se(e){return String(e??"").trim()}var G="[redacted]",Ne=/(authorization|api[_-]?key|credential|password|secret|token)/i;function ie(e){return Ne.test(Se(e))}function ce(e,n=[]){let o=String(e??"");for(let f of n){let c=String(f??"");c.length>=4&&(o=o.split(c).join(G))}return o.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${G}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${G}`)}var W={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs","knowledge_search"]};var Q=Object.freeze([...W.controlTools,...W.residentTools]),Ce=new Set(Q),Re=8*1024*1024;function de(e,n){if(!Array.isArray(e)||e.length!==1)throw new Error("one task-scoped Orcha MCP server is required");let o=e[0],f=new URL(o.url);if(o.name!=="orcha"||o.type!=="http"||!["http:","https:"].includes(f.protocol)||f.username||f.password||f.hash||n&&f.href!==new URL(n).href)throw new Error("Orcha MCP server does not match the trusted binding");let c=Object.fromEntries((o.headers||[]).map(({name:l,value:m})=>[l.toLowerCase(),m]));if(!String(c.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:f.href,headers:{...c,"content-type":"application/json",accept:"application/json"}}}async function v(e){let n=0,o=[];for await(let f of e){if(n+=f.length,n>Re)throw new Error("MCP payload exceeds the size limit");o.push(Buffer.from(f))}return JSON.parse(Buffer.concat(o).toString("utf8"))}async function Z(e,n,o){let f=await fetch(e.url,{method:"POST",headers:e.headers,body:JSON.stringify(n),redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(36e5),...o?[o]:[]])});if(!f.ok)throw new Error(`Orcha MCP request failed (${f.status})`);if(f.status===202||f.status===204)return null;let c=await v(f.body);if(!c||c.jsonrpc!=="2.0"||c.id!==n.id)throw new Error("Orcha MCP response identity mismatch");return c}async function le(e,n){let o=await Z(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},n),f=o?.result?.tools;if(o?.error){let c=Object.entries(e.headers).filter(([i])=>ie(i)).flatMap(([,i])=>[i,String(i).replace(/^Bearer\s+/i,"")]),l=typeof o.error.message=="string"?ce(o.error.message,c).slice(0,512):"",m=Number.isInteger(o.error.code)?` (${o.error.code})`:"";throw new Error(`Orcha MCP tool discovery failed${m}${l?`: ${l}`:""}`)}return Me(f)}function Me(e){if(!Array.isArray(e)||e.some(n=>!n||!Ce.has(n.name)||n.inputSchema?.type!=="object"||typeof n.description!="string")||new Set(e.map(n=>n.name)).size!==e.length||e.length&&W.controlTools.some(n=>!e.some(o=>o.name===n)))throw new Error("Orcha MCP returned an unsupported or invalid authorized tool catalog");return e}function ue(e,n){let o=c=>Array.isArray(c)?c.map(o):c&&typeof c=="object"?Object.fromEntries(Object.keys(c).sort().map(l=>[l,o(c[l])])):c,f=c=>c.map(({name:l,inputSchema:m})=>({name:l,inputSchema:m})).sort((l,m)=>l.name.localeCompare(m.name));return JSON.stringify(o(f(e)))===JSON.stringify(o(f(n)))}var q=e=>Object.assign(new Error(e),{status:409});function pe(e){let n=new Map,o=e.pluginConfig?.allowedOrchaMcpUrl;if(!o)throw new Error("Orcha plugin requires allowedOrchaMcpUrl");function f(m,i=n.get(m)){!i||n.get(m)!==i||(i.lifetime.abort(),clearTimeout(i.timer),n.delete(m))}function c(m){let i=n.get(m);return i&&i.deadline<=Date.now()?(f(m,i),null):i}async function l(m,{refresh:i=!1}={}){let{runId:u,sessionKey:O,agentCode:L,expiresAt:x,mcpServer:t}=m,h=Date.parse(x);if(typeof u!="string"||!u||typeof O!="string"||!O||typeof L!="string"||!L||!O.startsWith(`agent:${L}:`)||!Number.isFinite(h)||h<=Date.now()||h>Date.now()+24*36e5)throw new Error("invalid_binding_scope");let I=c(O);if(i&&!I||I&&(I.runId!==u||I.agentCode!==L||I.deadline!==h))throw q("original_binding_unavailable_or_changed");let r=de([t],o),d=I?.lifetime||new AbortController,a=await le(r,d.signal);if(c(O)!==I)throw q("binding_changed");if(I){if(!ue(I.tools,a))throw q("frozen_tool_catalog_changed");I.upstream=r}else{let s={runId:u,agentCode:L,deadline:h,upstream:r,tools:a,lifetime:d};s.timer=setTimeout(()=>f(O,s),h-Date.now()),s.timer.unref?.(),n.set(O,s)}}return e.registerTool(m=>{let i=c(m.sessionKey);return!i||m.agentId!==i.agentCode?null:i.tools.map(u=>({name:`orcha_${u.name}`,label:`Orcha ${u.name}`,description:u.description,parameters:u.inputSchema,async execute(O,L,x){if(c(m.sessionKey)!==i||m.agentId!==i.agentCode||!O||!i.tools.some(h=>h.name===u.name))throw new Error("Orcha task binding expired or changed");let t=await Z(i.upstream,{jsonrpc:"2.0",id:O,method:"tools/call",params:{name:u.name,arguments:L}},AbortSignal.any([i.lifetime.signal,...x?[x]:[]]));if(t?.error||!t?.result)throw new Error("Orcha rejected this task-scoped tool call");return{content:t.result.content,details:t.result.structuredContent,isError:t.result.isError===!0}}}))},{names:Q.map(m=>`orcha_${m}`)}),{bind:l,active:c,release:f,allowedUrl:o}}import{createHash as xe}from"node:crypto";import{mkdirSync as ke,readFileSync as Ue,renameSync as $e,writeFileSync as He}from"node:fs";import{join as ge}from"node:path";import{createHash as Pe}from"node:crypto";var fe=e=>Pe("sha256").update(JSON.stringify(e)).digest("hex"),B=e=>Object.assign(new Error(e),{code:e}),X=e=>{let n=String(e||"").replace(/^orcha:/,"");return/^[1-9]\d{0,18}$/.test(n)?n:void 0},me={normalizeTarget:X,targetResolver:{looksLikeId:e=>!!X(e),hint:"Orcha session ID"}};function he({core:e,load:n,save:o,loadMedia:f,activeRun:c}){let l=new Map,m=(t,h)=>fe([t,h]),i=t=>({channel:"orcha",messageId:t.messageId,chatId:t.sessionId,receipt:{primaryPlatformMessageId:t.messageId,platformMessageIds:[t.messageId],parts:[{platformMessageId:t.messageId,kind:"unknown",index:0}],sentAt:Date.now()}});async function u(t,h,I={}){return await I.onPlatformSendDispatch?.(),I.signal?.throwIfAborted(),i(await e(t,"/messages",h.payload,{cfg:I.cfg,signal:I.signal}))}async function O(t){t.signal?.throwIfAborted();let h=X(t.to);if(!h)throw B("invalid_conversation");if(!t.deliveryQueueId)throw B("OPENCLAW_DURABLE_DELIVERY_ID_REQUIRED");let I=t.run&&t.run.delivery.bindingId===t.accountId&&t.run.delivery.sessionId===h?t.run:null,r=t.replyToId||I?.delivery.messageId||null,d=t.payload||{text:t.text||"",mediaUrl:t.mediaUrl},a=d.mediaUrls||(d.mediaUrl?[d.mediaUrl]:[]),s=m(t.accountId,t.deliveryQueueId),p=fe([h,d.text||"",a,r,I?.runId||null]),_=n(s,"sends");if(_&&_.requestHash!==p)throw B("channel_send_conflict");let E=l.get(s);if(E){if(E.requestHash!==p)throw B("channel_send_conflict");return E.promise}let T=(async()=>{let y=_;if(!y){let w=[];for(let P of a){let b=await f(P,{maxBytes:33554432,mediaAccess:t.mediaAccess,mediaReadFile:t.mediaReadFile,mediaLocalRoots:t.mediaLocalRoots}),N=new FormData;N.set("sessionId",h),N.set("file",new Blob([b.buffer],{type:b.contentType||"application/octet-stream"}),b.fileName||"attachment"),w.push((await e(t.accountId,"/files",N,{cfg:t.cfg,signal:t.signal})).inputPart)}y={requestHash:p,payload:{sourceMessageId:`openclaw:${s}`,sessionId:h,content:d.text||"",inputParts:w,...r?{replyToMessageId:r}:{},...I?{agentRunId:I.runId}:{}}},o(s,y,"sends")}let S=await u(t.accountId,y,t);return I&&!I.messageIds.includes(S.messageId)&&I.messageIds.push(S.messageId),S})().finally(()=>l.delete(s));return l.set(s,{requestHash:p,promise:T}),T}return{send:O,message:{send:{text:O,media:O,payload:O},durableFinal:{capabilities:{text:!0,media:!0,payload:!0,replyTo:!0,reconcileUnknownSend:!0},reconcileUnknownSendKinds:{text:!0,media:!0,payload:!0},async reconcileUnknownSend(t){let h=n(m(t.accountId,t.queueId),"sends");if(!h)return{status:"not_sent"};if(h.payload.sessionId!==String(t.to).replace(/^orcha:/,""))throw B("channel_send_conflict");let I=await u(t.accountId,h,t);return{status:"sent",receipt:I.receipt,messageId:I.messageId}}}},actions:{describeMessageTool:()=>({actions:["send"],mediaSourceParams:{send:["media"]}}),supportsAction:({action:t})=>t==="send",isToolDeliveryAction:({args:t})=>t.action==="send",extractToolSend:({args:t})=>typeof(t.to||t.target)=="string"?{to:t.to||t.target,accountId:t.accountId}:null,async handleAction(t){if(t.action!=="send")throw B("unsupported_channel_action");let h=t.params;if(t.dryRun)return{content:[{type:"text",text:"Orcha send dry run"}],details:{dryRun:!0}};let I=c(t.sessionKey),r=await O({cfg:t.cfg,accountId:t.accountId,to:h.to||h.target,text:h.message,mediaUrl:h.media,replyToId:h.replyTo,deliveryQueueId:h.idempotencyKey,mediaAccess:t.mediaAccess,mediaLocalRoots:t.mediaLocalRoots,mediaReadFile:t.mediaReadFile,run:I,signal:I?.controller.signal});return{content:[{type:"text",text:JSON.stringify(r)}],details:r}}}}}var z="application/x-orcha-channel-events-v2+ndjson";function K(e,n){return Object.assign(new Error(n||(["run_timeout","RUNTIME_NODE_TIMEOUT"].includes(e)?"OpenClaw \u539F\u751F IM \u6267\u884C\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002":e==="OPENCLAW_CHANNEL_PROTOCOL_MISMATCH"?"OpenClaw \u63D2\u4EF6\u4E0E Bridge \u7684\u539F\u751F IM \u534F\u8BAE\u4E0D\u517C\u5BB9\uFF0C\u8BF7\u914D\u5957\u5347\u7EA7\u3002":`OpenClaw \u539F\u751F IM \u6267\u884C\u5931\u8D25\uFF08${e}\uFF09`)),{code:e})}function ee(e,n){let o=e.cause?.code||e.code;return n?.reason?.name==="TimeoutError"||e.name==="TimeoutError"||["UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT","UND_ERR_CONNECT_TIMEOUT","ETIMEDOUT"].includes(o)?Object.assign(K("RUNTIME_NODE_TIMEOUT","OpenClaw \u8FDE\u63A5\u6216\u7B49\u5F85\u54CD\u5E94\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002"),{detail:{causeCode:o||"REQUEST_TIMEOUT"}}):e}var we=e=>xe("sha256").update(JSON.stringify(e)).digest("hex"),R=(e,n=409)=>Object.assign(new Error(e),{status:n,code:e}),Y=e=>typeof e=="string"&&/^[1-9]\d{0,18}$/.test(e),De=e=>new Promise(n=>setTimeout(n,e));function ye(e,n,o){return`agent:${e}:orcha:task:${we([o,n.bindingId,n.bindingRevision,n.sessionId,n.taskContextId,n.memberId,n.historyFromSeq,n.runtimePolicyRevision])}`}function Ie(e,n,o,f,c){let l=new Map,m=()=>e.config;function i(r,d=m()){let a=d?.channels?.orcha?.accounts?.[r];if(!Y(r)||!a||a.enabled===!1||!a.serviceToken||!a.agentId)throw R("orcha_channel_account_unavailable",403);return{...a,accountId:r}}async function u(r,d,a,{cfg:s,signal:p,method:_="POST"}={}){let E=i(r,s),T=new URL(`/api/agent-channels${d}`,n.allowedUrl),y=a instanceof FormData,S=AbortSignal.any([AbortSignal.timeout(3e4),...p?[p]:[]]);try{let w=await fetch(T,{method:_,redirect:"error",signal:S,headers:{authorization:`Bearer ${E.serviceToken}`,...y?{}:{"content-type":"application/json"}},...a!==void 0?{body:y?a:JSON.stringify(a)}:{}}),P=await v(w.body);if(!w.ok||P.success!==!0)throw R(`orcha_channel_request_${w.status}`,w.status);return P.data}catch(w){throw ee(w,S)}}function O(r,d="runs"){if(!/^[a-zA-Z0-9_-]{1,128}$/.test(r))throw R("invalid_record_identity",422);let a=ge(e.runtime.state.resolveStateDir(),"plugins","orcha-runtime",d);return ke(a,{recursive:!0,mode:448}),ge(a,`${r}.json`)}function L(r,d){try{return JSON.parse(Ue(O(r,d),"utf8"))}catch(a){if(a.code==="ENOENT")return null;throw a}}function x(r,d,a){let s=O(r,a),p=`${s}.pending`;He(p,JSON.stringify(d),{mode:384}),$e(p,s)}async function t(r,d=!1,a){let s=i(r.delivery?.bindingId),{runId:p,delivery:_}=r;if(!Y(p)||!Y(_.sessionId)||_.taskContextId!==null&&!Y(_.taskContextId)||_.mode!=="channel"||r.agentCode!==s.agentId)throw R("invalid_channel_delivery",422);if(!Array.isArray(r.prompt)||r.prompt.some(C=>!["text","image","file"].includes(C.type)||(C.type==="text"?typeof C.text!="string":typeof C.uri!="string")))throw R("invalid_channel_prompt",422);let E=we({agentCode:r.agentCode,delivery:_,prompt:r.prompt}),T=L(p);if(T&&T.requestHash!==E)throw R("channel_delivery_conflict");if(T?.status==="completed")return T.result;if(T?.status==="failed")throw R(T.error);let y=l.get(p),S=T?.expiresAt||r.expiresAt,w=ye(s.agentId,_,n.allowedUrl),P=()=>{let C=n.active(w);C?.runId===p&&n.release(w,C)},b=T?.hostRunId||`orcha-${p}`;if(T&&!y||r.attachOnly&&!y&&!T)throw R("RUNTIME_OPERATION_NOT_FOUND");if(y){try{await n.bind({runId:p,sessionKey:w,agentCode:s.agentId,expiresAt:S,mcpServer:r.mcpServer},{refresh:!0})}catch(C){if(l.get(p)!==y)return await y.promise;throw C}if(d)return{refreshed:!0};y.listeners.add(a);try{for(let C of y.updates)a?.(C);return await y.promise}finally{y.listeners.delete(a)}}if(d)throw R("RUNTIME_OPERATION_NOT_FOUND");let N=new AbortController,M={runId:p,delivery:_,messageIds:[],controller:N,promise:null,listeners:new Set(a?[a]:[]),updates:[],bytes:0},$=C=>{let k={type:"update",payload:{sessionId:w,update:C,_meta:{channelUpdateId:`${b}:${M.updates.length+1}`}}},H=Buffer.byteLength(JSON.stringify(k));if(H>2097152||M.bytes+H>16777216){N.abort(K("OPENCLAW_CHANNEL_PROGRESS_LIMIT"));return}M.bytes+=H,M.updates.push(k);for(let V of M.listeners)V?.(k)};return l.set(p,M),M.promise=(async()=>{await n.bind({runId:p,sessionKey:w,agentCode:s.agentId,expiresAt:S,mcpServer:r.mcpServer}),x(p,{requestHash:E,status:"running",sessionKey:w,hostRunId:b,expiresAt:S});let C=0,k,H,V=setTimeout(()=>N.abort(R("run_timeout")),Date.parse(S)-Date.now());try{let F=e.runtime.channel.reply;if(typeof F?.dispatchReplyWithBufferedBlockDispatcher!="function"||typeof e.runtime.events?.onAgentEvent!="function")throw R("OPENCLAW_CHANNEL_RUNTIME_UNAVAILABLE");H=e.runtime.events.onAgentEvent(g=>{let A=g.data;g.runId!==b||g.stream!=="tool"||!A?.toolCallId||A.hideFromChannelProgress||!["start","update","result"].includes(A.phase)||$({sessionUpdate:A.phase==="start"?"tool_call":"tool_call_update",toolCallId:A.toolCallId,title:A.name,status:A.phase==="result"?A.isError?"failed":"completed":"in_progress",...A.args?{rawInput:A.args}:{},...A.result!==void 0?{rawOutput:A.result}:{}})});let U="",ne="",j="",Te=g=>{if(typeof g.text!="string")return;let A=[ne,g.text].filter(Boolean).join(`
|
|
1
|
+
import{getPluginRuntimeGatewayRequestScope as Ke}from"openclaw/plugin-sdk/plugin-runtime";import{loadOutboundMediaFromUrl as Ye}from"openclaw/plugin-sdk/outbound-media";function Ce(e){return String(e??"").trim()}var Q="[redacted]",Re=/(authorization|api[_-]?key|credential|password|secret|token)/i;function ce(e){return Re.test(Ce(e))}function le(e,t=[]){let i=String(e??"");for(let g of t){let l=String(g??"");l.length>=4&&(i=i.split(l).join(Q))}return i.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${Q}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${Q}`)}var z={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs","knowledge_search"]};var Z=Object.freeze([...z.controlTools,...z.residentTools]),xe=new Set(Z),Pe=8*1024*1024;function de(e,t){if(!Array.isArray(e)||e.length!==1)throw new Error("one task-scoped Orcha MCP server is required");let i=e[0],g=new URL(i.url);if(i.name!=="orcha"||i.type!=="http"||!["http:","https:"].includes(g.protocol)||g.username||g.password||g.hash||t&&g.href!==new URL(t).href)throw new Error("Orcha MCP server does not match the trusted binding");let l=Object.fromEntries((i.headers||[]).map(({name:T,value:s})=>[T.toLowerCase(),s]));if(!String(l.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:g.href,headers:{...l,"content-type":"application/json",accept:"application/json"}}}async function B(e){let t=0,i=[];for await(let g of e){if(t+=g.length,t>Pe)throw new Error("MCP payload exceeds the size limit");i.push(Buffer.from(g))}return JSON.parse(Buffer.concat(i).toString("utf8"))}async function q(e,t,i){let g=await fetch(e.url,{method:"POST",headers:e.headers,body:JSON.stringify(t),redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(36e5),...i?[i]:[]])});if(!g.ok)throw new Error(`Orcha MCP request failed (${g.status})`);if(g.status===202||g.status===204)return null;let l=await B(g.body);if(!l||l.jsonrpc!=="2.0"||l.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return l}async function ue(e,t){let i=await q(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},t),g=i?.result?.tools;if(i?.error){let l=Object.entries(e.headers).filter(([u])=>ce(u)).flatMap(([,u])=>[u,String(u).replace(/^Bearer\s+/i,"")]),T=typeof i.error.message=="string"?le(i.error.message,l).slice(0,512):"",s=Number.isInteger(i.error.code)?` (${i.error.code})`:"";throw new Error(`Orcha MCP tool discovery failed${s}${T?`: ${T}`:""}`)}return Le(g)}function Le(e){if(!Array.isArray(e)||e.some(t=>!t||!xe.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&z.controlTools.some(t=>!e.some(i=>i.name===t)))throw new Error("Orcha MCP returned an unsupported or invalid authorized tool catalog");return e}function pe(e,t){let i=l=>Array.isArray(l)?l.map(i):l&&typeof l=="object"?Object.fromEntries(Object.keys(l).sort().map(T=>[T,i(l[T])])):l,g=l=>l.map(({name:T,inputSchema:s})=>({name:T,inputSchema:s})).sort((T,s)=>T.name.localeCompare(s.name));return JSON.stringify(i(g(e)))===JSON.stringify(i(g(t)))}var X=e=>Object.assign(new Error(e),{status:409});function fe(e){let t=new Map,i=e.pluginConfig?.allowedOrchaMcpUrl;if(!i)throw new Error("Orcha plugin requires allowedOrchaMcpUrl");function g(s,u=t.get(s)){!u||t.get(s)!==u||(u.lifetime.abort(),clearTimeout(u.timer),t.delete(s))}function l(s){let u=t.get(s);return u&&u.deadline<=Date.now()?(g(s,u),null):u}async function T(s,{refresh:u=!1}={}){let{runId:_,sessionKey:c,agentCode:M,expiresAt:k,mcpServer:n}=s,m=Date.parse(k);if(typeof _!="string"||!_||typeof c!="string"||!c||typeof M!="string"||!M||!c.startsWith(`agent:${M}:`)||!Number.isFinite(m)||m<=Date.now()||m>Date.now()+24*36e5)throw new Error("invalid_binding_scope");let h=l(c);if(u&&!h||h&&(h.runId!==_||h.agentCode!==M||h.deadline!==m))throw X("original_binding_unavailable_or_changed");let L=de([n],i),r=h?.lifetime||new AbortController,d=await ue(L,r.signal);if(l(c)!==h)throw X("binding_changed");if(h){if(!pe(h.tools,d))throw X("frozen_tool_catalog_changed");h.upstream=L}else{let o={runId:_,agentCode:M,deadline:m,upstream:L,tools:d,lifetime:r};o.timer=setTimeout(()=>g(c,o),m-Date.now()),o.timer.unref?.(),t.set(c,o)}}return e.registerTool(s=>{let u=l(s.sessionKey);return!u||s.agentId!==u.agentCode?null:u.tools.map(_=>({name:`orcha_${_.name}`,label:`Orcha ${_.name}`,description:_.description,parameters:_.inputSchema,async execute(c,M,k){if(l(s.sessionKey)!==u||s.agentId!==u.agentCode||!c||!u.tools.some(m=>m.name===_.name))throw new Error("Orcha task binding expired or changed");let n=await q(u.upstream,{jsonrpc:"2.0",id:c,method:"tools/call",params:{name:_.name,arguments:M}},AbortSignal.any([u.lifetime.signal,...k?[k]:[]]));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:Z.map(s=>`orcha_${s}`)}),{bind:T,active:l,release:g,allowedUrl:i}}import{createHash as $e}from"node:crypto";import{mkdirSync as He,readFileSync as De,renameSync as ve,writeFileSync as Be}from"node:fs";import{join as ye}from"node:path";import{createHash as ke}from"node:crypto";var me=e=>ke("sha256").update(JSON.stringify(e)).digest("hex"),j=e=>Object.assign(new Error(e),{code:e}),ee=e=>{let t=String(e||"").replace(/^orcha:/,"");return/^[1-9]\d{0,18}$/.test(t)?t:void 0},he={normalizeTarget:ee,targetResolver:{looksLikeId:e=>!!ee(e),hint:"Orcha session ID"}};function ge({core:e,load:t,save:i,loadMedia:g,activeRun:l}){let T=new Map,s=(n,m)=>me([n,m]),u=n=>({channel:"orcha",messageId:n.messageId,chatId:n.sessionId,receipt:{primaryPlatformMessageId:n.messageId,platformMessageIds:[n.messageId],parts:[{platformMessageId:n.messageId,kind:"unknown",index:0}],sentAt:Date.now()}});async function _(n,m,h={}){return await h.onPlatformSendDispatch?.(),h.signal?.throwIfAborted(),u(await e(n,"/messages",m.payload,{cfg:h.cfg,signal:h.signal}))}async function c(n){n.signal?.throwIfAborted();let m=ee(n.to);if(!m)throw j("invalid_conversation");if(!n.deliveryQueueId)throw j("OPENCLAW_DURABLE_DELIVERY_ID_REQUIRED");let h=n.run&&n.run.delivery.bindingId===n.accountId&&n.run.delivery.sessionId===m?n.run:null,L=n.replyToId||h?.delivery.messageId||null,r=n.payload||{text:n.text||"",mediaUrl:n.mediaUrl},d=r.mediaUrls||(r.mediaUrl?[r.mediaUrl]:[]),o=s(n.accountId,n.deliveryQueueId),a=me([m,r.text||"",d,L,h?.runId||null]),p=t(o,"sends");if(p&&p.requestHash!==a)throw j("channel_send_conflict");let y=T.get(o);if(y){if(y.requestHash!==a)throw j("channel_send_conflict");return y.promise}let E=(async()=>{let O=p;if(!O){let S=[];for(let I of d){let P=await g(I,{maxBytes:33554432,mediaAccess:n.mediaAccess,mediaReadFile:n.mediaReadFile,mediaLocalRoots:n.mediaLocalRoots}),N=new FormData;N.set("sessionId",m),N.set("file",new Blob([P.buffer],{type:P.contentType||"application/octet-stream"}),P.fileName||"attachment"),S.push((await e(n.accountId,"/files",N,{cfg:n.cfg,signal:n.signal})).inputPart)}O={requestHash:a,payload:{sourceMessageId:`openclaw:${o}`,sessionId:m,content:r.text||"",inputParts:S,...L?{replyToMessageId:L}:{},...h?{agentRunId:h.runId}:{}}},i(o,O,"sends")}let w=await _(n.accountId,O,n);return h&&!h.messageIds.includes(w.messageId)&&h.messageIds.push(w.messageId),w})().finally(()=>T.delete(o));return T.set(o,{requestHash:a,promise:E}),E}return{send:c,message:{send:{text:c,media:c,payload:c},durableFinal:{capabilities:{text:!0,media:!0,payload:!0,replyTo:!0,reconcileUnknownSend:!0},reconcileUnknownSendKinds:{text:!0,media:!0,payload:!0},async reconcileUnknownSend(n){let m=t(s(n.accountId,n.queueId),"sends");if(!m)return{status:"not_sent"};if(m.payload.sessionId!==String(n.to).replace(/^orcha:/,""))throw j("channel_send_conflict");let h=await _(n.accountId,m,n);return{status:"sent",receipt:h.receipt,messageId:h.messageId}}}},actions:{describeMessageTool:()=>({actions:["send"],mediaSourceParams:{send:["media"]}}),supportsAction:({action:n})=>n==="send",isToolDeliveryAction:({args:n})=>n.action==="send",extractToolSend:({args:n})=>typeof(n.to||n.target)=="string"?{to:n.to||n.target,accountId:n.accountId}:null,async handleAction(n){if(n.action!=="send")throw j("unsupported_channel_action");let m=n.params;if(n.dryRun)return{content:[{type:"text",text:"Orcha send dry run"}],details:{dryRun:!0}};let h=l(n.sessionKey),L=await c({cfg:n.cfg,accountId:n.accountId,to:m.to||m.target,text:m.message,mediaUrl:m.media,replyToId:m.replyTo,deliveryQueueId:m.idempotencyKey,mediaAccess:n.mediaAccess,mediaLocalRoots:n.mediaLocalRoots,mediaReadFile:n.mediaReadFile,run:h,signal:h?.controller.signal});return{content:[{type:"text",text:JSON.stringify(L)}],details:L}}}}}var K="application/x-orcha-channel-events-v2+ndjson";function Y(e,t){return Object.assign(new Error(t||(["run_timeout","RUNTIME_NODE_TIMEOUT"].includes(e)?"OpenClaw \u539F\u751F IM \u6267\u884C\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002":e==="OPENCLAW_CHANNEL_PROTOCOL_MISMATCH"?"OpenClaw \u63D2\u4EF6\u4E0E Bridge \u7684\u539F\u751F IM \u534F\u8BAE\u4E0D\u517C\u5BB9\uFF0C\u8BF7\u914D\u5957\u5347\u7EA7\u3002":`OpenClaw \u539F\u751F IM \u6267\u884C\u5931\u8D25\uFF08${e}\uFF09`)),{code:e})}function te(e,t){let i=e.cause?.code||e.code;return t?.reason?.name==="TimeoutError"||e.name==="TimeoutError"||["UND_ERR_HEADERS_TIMEOUT","UND_ERR_BODY_TIMEOUT","UND_ERR_CONNECT_TIMEOUT","ETIMEDOUT"].includes(i)?Object.assign(Y("RUNTIME_NODE_TIMEOUT","OpenClaw \u8FDE\u63A5\u6216\u7B49\u5F85\u54CD\u5E94\u8D85\u65F6\uFF0C\u4EFB\u52A1\u5DF2\u7ED3\u675F\uFF0C\u8BF7\u91CD\u8BD5\u3002"),{detail:{causeCode:i||"REQUEST_TIMEOUT"}}):e}var Ie=e=>$e("sha256").update(JSON.stringify(e)).digest("hex"),R=(e,t=409)=>Object.assign(new Error(e),{status:t,code:e}),V=e=>typeof e=="string"&&/^[1-9]\d{0,18}$/.test(e),je=e=>new Promise(t=>setTimeout(t,e));function we(e,t,i){return`agent:${e}:orcha:task:${Ie([i,t.bindingId,t.bindingRevision,t.sessionId,t.taskContextId,t.memberId,t.historyFromSeq,t.runtimePolicyRevision])}`}function _e(e,t,i,g,l,T){let s=new Map;e.on("before_message_write",({message:r},d)=>{if(r?.role!=="assistant")return;let o=t.active(d.sessionKey),a=s.get(o?.runId);a&&d.agentId===o.agentCode&&(a.silentFinal=T(r))});let u=()=>e.config;function _(r,d=u()){let o=d?.channels?.orcha?.accounts?.[r];if(!V(r)||!o||o.enabled===!1||!o.serviceToken||!o.agentId)throw R("orcha_channel_account_unavailable",403);return{...o,accountId:r}}async function c(r,d,o,{cfg:a,signal:p,method:y="POST"}={}){let E=_(r,a),O=new URL(`/api/agent-channels${d}`,t.allowedUrl),w=o instanceof FormData,S=AbortSignal.any([AbortSignal.timeout(3e4),...p?[p]:[]]);try{let I=await fetch(O,{method:y,redirect:"error",signal:S,headers:{authorization:`Bearer ${E.serviceToken}`,...w?{}:{"content-type":"application/json"}},...o!==void 0?{body:w?o:JSON.stringify(o)}:{}}),P=await B(I.body);if(!I.ok||P.success!==!0)throw R(`orcha_channel_request_${I.status}`,I.status);return P.data}catch(I){throw te(I,S)}}function M(r,d="runs"){if(!/^[a-zA-Z0-9_-]{1,128}$/.test(r))throw R("invalid_record_identity",422);let o=ye(e.runtime.state.resolveStateDir(),"plugins","orcha-runtime",d);return He(o,{recursive:!0,mode:448}),ye(o,`${r}.json`)}function k(r,d){try{return JSON.parse(De(M(r,d),"utf8"))}catch(o){if(o.code==="ENOENT")return null;throw o}}function n(r,d,o){let a=M(r,o),p=`${a}.pending`;Be(p,JSON.stringify(d),{mode:384}),ve(p,a)}async function m(r,d=!1,o){let a=_(r.delivery?.bindingId),{runId:p,delivery:y}=r;if(!V(p)||!V(y.sessionId)||y.taskContextId!==null&&!V(y.taskContextId)||y.mode!=="channel"||r.agentCode!==a.agentId)throw R("invalid_channel_delivery",422);if(!Array.isArray(r.prompt)||r.prompt.some(C=>!["text","image","file"].includes(C.type)||(C.type==="text"?typeof C.text!="string":typeof C.uri!="string")))throw R("invalid_channel_prompt",422);let E=Ie({agentCode:r.agentCode,delivery:y,prompt:r.prompt}),O=k(p);if(O&&O.requestHash!==E)throw R("channel_delivery_conflict");if(O?.status==="completed")return O.result;if(O?.status==="failed")throw R(O.error);let w=s.get(p),S=O?.expiresAt||r.expiresAt,I=we(a.agentId,y,t.allowedUrl),P=()=>{let C=t.active(I);C?.runId===p&&t.release(I,C)},N=O?.hostRunId||`orcha-${p}`;if(O&&!w||r.attachOnly&&!w&&!O)throw R("RUNTIME_OPERATION_NOT_FOUND");if(w){try{await t.bind({runId:p,sessionKey:I,agentCode:a.agentId,expiresAt:S,mcpServer:r.mcpServer},{refresh:!0})}catch(C){if(s.get(p)!==w)return await w.promise;throw C}if(d)return{refreshed:!0};w.listeners.add(o);try{for(let C of w.updates)o?.(C);return await w.promise}finally{w.listeners.delete(o)}}if(d)throw R("RUNTIME_OPERATION_NOT_FOUND");let b=new AbortController,x={runId:p,delivery:y,messageIds:[],controller:b,promise:null,listeners:new Set(o?[o]:[]),updates:[],bytes:0},H=C=>{let U={type:"update",payload:{sessionId:I,update:C,_meta:{channelUpdateId:`${N}:${x.updates.length+1}`}}},D=Buffer.byteLength(JSON.stringify(U));if(D>2097152||x.bytes+D>16777216){b.abort(Y("OPENCLAW_CHANNEL_PROGRESS_LIMIT"));return}x.bytes+=D,x.updates.push(U);for(let G of x.listeners)G?.(U)};return s.set(p,x),x.promise=(async()=>{await t.bind({runId:p,sessionKey:I,agentCode:a.agentId,expiresAt:S,mcpServer:r.mcpServer}),n(p,{requestHash:E,status:"running",sessionKey:I,hostRunId:N,expiresAt:S});let C=0,U,D,G=setTimeout(()=>b.abort(R("run_timeout")),Date.parse(S)-Date.now());try{let J=e.runtime.channel.reply;if(typeof J?.dispatchReplyWithBufferedBlockDispatcher!="function"||typeof e.runtime.events?.onAgentEvent!="function")throw R("OPENCLAW_CHANNEL_RUNTIME_UNAVAILABLE");D=e.runtime.events.onAgentEvent(f=>{let A=f.data;f.runId!==N||f.stream!=="tool"||!A?.toolCallId||A.hideFromChannelProgress||!["start","update","result"].includes(A.phase)||H({sessionUpdate:A.phase==="start"?"tool_call":"tool_call_update",toolCallId:A.toolCallId,title:A.name,status:A.phase==="result"?A.isError?"failed":"completed":"in_progress",...A.args?{rawInput:A.args}:{},...A.result!==void 0?{rawOutput:A.result}:{}})});let $="",re="",F="",Se=f=>{if(typeof f.text!="string")return;let A=[re,f.text].filter(Boolean).join(`
|
|
2
2
|
|
|
3
|
-
`);if(A===
|
|
3
|
+
`);if(A===F)return;let v=A.startsWith(F);H({sessionUpdate:v?"agent_message_chunk":"agent_message_snapshot",content:{type:"text",text:v?A.slice(F.length):A}}),F=A},oe=f=>{if(f.requiresReasoningProgressOptIn||typeof f.text!="string")return;let A=f.text.startsWith($)?f.text.slice($.length):f.text;$=f.text,A&&H({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:A}})},W=r.prompt.filter(f=>f.type==="text").map(f=>f.text).join(`
|
|
4
4
|
|
|
5
|
-
`),
|
|
6
|
-
`,
|
|
7
|
-
`)}).finally(()=>{E-=
|
|
5
|
+
`),ie=r.prompt.filter(f=>f.type!=="text"),be={Body:W,BodyForAgent:W,BodyForCommands:W,RawBody:W,From:`orcha:${y.memberId}`,To:`orcha:${y.sessionId}`,SessionKey:I,AccountId:y.bindingId,Provider:"orcha",Surface:"orcha",ChatType:"direct",OriginatingChannel:"orcha",OriginatingTo:y.sessionId,MessageSid:y.messageId||p,MediaUrls:ie.map(f=>f.uri),MediaTypes:ie.map(f=>f.mimeType||"application/octet-stream"),CommandAuthorized:!1,WasMentioned:!0};if(await J.dispatchReplyWithBufferedBlockDispatcher({ctx:be,cfg:u(),replyOptions:{runId:N,abortSignal:b.signal,suppressTyping:!0,suppressDefaultToolProgressMessages:!0,suppressToolErrorWarnings:!0,disableBlockStreaming:!0,reasoningPayloadsEnabled:!0,commentaryPayloadsEnabled:!0,onAssistantMessageStart:()=>{$="",re=F},onPartialReply:Se,onReasoningStream:oe},dispatcherOptions:{deliver:async(f,A)=>{if(b.signal.throwIfAborted(),f.isReasoning&&oe(f),f.isCommentary&&f.text&&H({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:f.text}}),A.kind==="final"&&g(f)){if(x.silentFinal&&x.messageIds.length&&!f.isError)return;let v=u(),ae=v?.agents?.list?.find(Ne=>Ne.id===a.agentId)?.workspace||v?.agents?.defaults?.workspace;await h.send({cfg:v,accountId:y.bindingId,to:y.sessionId,payload:f,run:x,deliveryQueueId:`${N}:final:${++C}`,signal:b.signal,mediaLocalRoots:ae?[ae]:void 0})}},onError:f=>{U??=f}}}),U)throw U;if(b.signal.throwIfAborted(),!x.messageIds.length)throw R("runtime_node_empty_result");let se={stopReason:"end_turn",messageIds:x.messageIds,sessionId:I};return n(p,{requestHash:E,status:"completed",sessionKey:I,hostRunId:N,expiresAt:S,result:se}),se}catch(J){let $=b.signal.aborted?b.signal.reason:te(J,b.signal);throw n(p,{requestHash:E,status:"failed",sessionKey:I,hostRunId:N,expiresAt:S,error:$.code||"channel_host_failed"}),$}finally{D?.(),clearTimeout(G),P(),s.delete(p)}})().catch(C=>{throw P(),s.delete(p),C}),x.promise}let h=ge({core:c,load:k,save:n,loadMedia:l,activeRun:r=>s.get(t.active(r)?.runId)});e.registerChannel({plugin:{id:"orcha",meta:{id:"orcha",label:"Orcha",selectionLabel:"Orcha",docsPath:"/channels/orcha",blurb:"Enterprise people and Agent conversations"},capabilities:{chatTypes:["direct","group"],media:!0},config:{listAccountIds:r=>Object.keys(r?.channels?.orcha?.accounts||{}),inspectAccount:(r,d)=>{let o=r?.channels?.orcha?.accounts?.[d];return{enabled:!!(o&&o.enabled!==!1),configured:!!(o?.serviceToken&&o?.agentId),tokenStatus:o?.serviceToken?"available":"missing"}},resolveAccount:(r,d)=>_(d,r),isEnabled:r=>r.enabled!==!1,isConfigured:r=>!!(r.serviceToken&&r.agentId)},outbound:{deliveryMode:"direct",textChunkLimit:1e5},message:h.message,actions:h.actions,messaging:he}});async function L(r){let{accountId:d,grantId:o,externalInvocationId:a}=r;_(d);let p=await c(d,"/runs",{grantId:o,externalInvocationId:a,input:r.input||{}}),y=p.agentRunId;if(["completed","failed","cancelled","expired"].includes(p.status))return p;let E;do E=await c(d,`/runs/${y}/claim`,{}),E.attemptId||await je(Math.max(1,E.retryAfterSeconds||2)*1e3);while(!E.attemptId);let O=we(_(d).agentId,E.delivery,t.allowedUrl),w,S=!1,I=setInterval(async()=>{if(!S){S=!0;try{let b=await c(d,`/runs/${y}/heartbeat`,{attemptId:E.attemptId});t.active(O)&&await t.bind({runId:y,sessionKey:O,agentCode:_(d).agentId,expiresAt:E.expiresAt,mcpServer:b.mcpServer},{refresh:!0})}catch(b){w=b,s.get(y)?.controller.abort(b),t.release(O)}finally{S=!1}}},Math.max(1,E.heartbeatIntervalSeconds)*1e3),P,N;try{let b;try{b=await m({runId:y,agentCode:_(d).agentId,delivery:E.delivery,prompt:[{type:"text",text:JSON.stringify({task:E.prompt,eventInput:E.input})}],mcpServer:E.mcpServer,expiresAt:E.expiresAt,attachOnly:E.recovery})}catch(H){N=H}if(w)throw w;P=N?{attemptId:E.attemptId,errorMessage:Y(N.code||"channel_host_failed").message,status:"failed"}:{attemptId:E.attemptId,messageIds:b.messageIds,status:"completed"};let x=await c(d,`/runs/${y}/complete`,P);if(N)throw N;return x}finally{clearInterval(I),t.release(O)}}for(let[r,d]of[["deliveries",m],["background",L]])e.registerHttpRoute({path:`/plugins/orcha-runtime/${r}`,auth:"gateway",match:"exact",async handler(o,a){let p,y=Promise.resolve(),E=0,O=w=>{if(a.destroyed||a.writableEnded)return;let S=JSON.stringify(w)+`
|
|
6
|
+
`,I=Buffer.byteLength(S);if(I>2097152||E+a.writableLength+I>2097152){a.destroy();return}return E+=I,y=y.then(async()=>{a.destroyed||a.writableEnded||(await i(),a.write(S))}).catch(P=>{!a.destroyed&&!a.writableEnded&&a.end(JSON.stringify({type:"error",code:P.code||"OPENCLAW_CHANNEL_AUTH_FAILED"})+`
|
|
7
|
+
`)}).finally(()=>{E-=I}),y};try{if(r==="deliveries"&&o.method==="GET"){await i(),a.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify({streamType:K}));return}if(!["POST","PATCH","DELETE"].includes(o.method))throw R("method_not_allowed",405);let w=await B(o);if(await i(),r==="deliveries"&&o.method==="POST"){if(o.headers.accept!==K)throw R("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH",409);a.writeHead(200,{"content-type":K,"cache-control":"no-store","x-accel-buffering":"no"}),O({type:"heartbeat"}),p=setInterval(()=>O({type:"heartbeat"}),15e3),a.once("close",()=>clearInterval(p));let I=await m(w,!1,O);await i(),await O({type:"result",result:I}),a.end();return}if(o.method==="DELETE"){let I=s.get(w.runId);I?.controller.abort(R("RUNTIME_OPERATION_CANCELLED")),a.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify({cancelled:!!I}));return}if(o.method==="PATCH"&&r!=="deliveries")throw R("method_not_allowed",405);let S=await d(w,o.method==="PATCH");await i(),a.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify(S))}catch(w){a.headersSent?(await O({type:"error",code:w.code||"channel_host_failed"}),a.end()):a.writableEnded||a.writeHead(w.status||500,{"content-type":"application/json"}).end(JSON.stringify({error:w.code||w.message}))}finally{clearInterval(p)}}})}function Ee(e,t,i,g){return{id:"orcha-runtime",name:"Orcha Channel and authorized tools",register(l){let T=fe(l);l.registerHttpRoute({path:"/plugins/orcha-runtime/mcp-bindings",auth:"gateway",match:"exact",async handler(s,u){let _=(c,M)=>{u.writeHead(c,{"content-type":"application/json"}),u.end(JSON.stringify(M))};try{if(s.method==="GET"){_(200,{ready:!0});return}if(!["PUT","DELETE"].includes(s.method)){_(405,{error:"method_not_allowed"});return}let c=await B(s);if(await e(),typeof c.runId!="string"||!c.runId||typeof c.sessionKey!="string"||!c.sessionKey){_(422,{error:"invalid_binding_identity"});return}let M=T.active(c.sessionKey);if(s.headers["if-match"]&&s.headers["if-match"]!==c.runId){_(409,{error:"binding_run_conflict"});return}if(M&&M.runId!==c.runId){_(409,{error:"session_already_bound"});return}s.method==="DELETE"?T.release(c.sessionKey):await T.bind(c,{refresh:!!s.headers["if-match"]}),_(200,{[s.method==="DELETE"?"released":"bound"]:!0})}catch(c){u.writableEnded||_(c.status||422,{error:c.message})}}}),_e(l,T,e,t,i,g)}}}import{isFastModeAutoProgressPayload as Fe,isReasoningReplyPayload as Je,isReplyPayloadNonTerminalToolErrorWarning as We,isReplyPayloadTtsSupplement as ze}from"openclaw/plugin-sdk/reply-payload";import{isSilentReplyText as Oe}from"openclaw/plugin-sdk/reply-chunking";function Te(e){return e?.role!=="assistant"||e.stopReason!=="stop"?!1:typeof e.content=="string"?Oe(e.content):!Array.isArray(e.content)||e.content.some(t=>!["text","thinking"].includes(t.type))?!1:Oe(e.content.filter(t=>t.type==="text").map(t=>t.text).join(`
|
|
8
|
+
`))}function Ae(e){return!Je(e)&&!e.isCommentary&&!e.isCompactionNotice&&!e.isFallbackNotice&&!e.isStatusNotice&&!Fe(e)&&!We(e)&&!ze(e)}var Tt=Ee(async()=>{await Ke()?.revalidate?.()},Ae,Ye,Te);export{Tt as default};
|