@orcha-ai/runtime-bridge 0.1.50 → 0.1.52
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 +27 -5
- package/bin/orcha-runtime-bridge.js +23 -20
- package/openclaw-plugin/index.js +4 -4
- package/openclaw-plugin/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,8 @@ Codex/Claude Code use a user-selected existing local directory. OpenClaw keeps i
|
|
|
53
53
|
|
|
54
54
|
Codex device targets use `exec --skip-git-repo-check --json` so ordinary directories work as well as Git repositories. Existing device profiles created without this flag need their Codex target arguments updated locally and Bridge reloaded; updating the npm package alone does not rewrite saved profiles.
|
|
55
55
|
|
|
56
|
+
Claude Code device targets use `-p --output-format stream-json --verbose` and receive the prompt on stdin. Profiles saved by Bridge 0.1.51 or earlier with exactly `-p --output-format json --no-session-persistence` are rewritten to this launch the next time Bridge loads the device profile; customized Claude arguments are left untouched and must be updated locally if they block native sessions. Remove this upgrade once connected devices no longer run those profiles.
|
|
57
|
+
|
|
56
58
|
Targets are namespaced by device code and candidate digest. Chat, group delegation, workflow dispatch and recovery are pinned to that device; an offline or revoked device never falls back to a different computer. External execution uses the local CLI's own permissions, not Orcha's cloud Docker Sandbox.
|
|
57
59
|
|
|
58
60
|
The automated discovery path is exercised on macOS/Linux. On Windows, use WSL with the CLIs installed there; native `.cmd`/`.bat` launchers are not supported by the shell-free process adapter.
|
|
@@ -80,7 +82,7 @@ Version 0.1.44 routes replies, native `message` tool sends, and background notif
|
|
|
80
82
|
|
|
81
83
|
```bash
|
|
82
84
|
npm run pack:local
|
|
83
|
-
npm publish ./dist/orcha-ai-runtime-bridge-0.1.
|
|
85
|
+
npm publish ./dist/orcha-ai-runtime-bridge-0.1.52.tgz --access public --registry=https://registry.npmjs.org
|
|
84
86
|
```
|
|
85
87
|
|
|
86
88
|
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.
|
|
@@ -115,15 +117,35 @@ Version 0.1.49 fixes Codex ordinary conversation admission in Bridge and disting
|
|
|
115
117
|
|
|
116
118
|
Device Codex accepts Core's existing `session-<id>:<human-member>:<agent-member>:<history-floor>:<policy-revision>` scope for ordinary conversations and `task-<id>:...` for task contexts. All five numeric fields remain strings and must be positive decimal integers. The complete scope is preserved in the native identity, including membership, context reset and policy boundaries. Invalid scope, missing Core address and unsupported sandbox launch produce separate errors. This fixes the previous task-only Bridge check without changing Core's payload, protocol version or stored session mappings. Reload the device Bridge after installing the fix; restarting Core alone does not reload the device process.
|
|
117
119
|
|
|
118
|
-
OpenClaw native Channel and device
|
|
120
|
+
OpenClaw native Channel, device Codex and device Claude Code conversations send only the current message and attachments. Orcha conversation IDs and optional historical task IDs define conversation boundaries; native runtimes own history and compaction. OpenClaw session keys include the Core endpoint, binding revision, chat/task/member and history/policy scope. Codex saves the actual `thread.started.thread_id` under `~/.orcha/codex-sessions/` and uses `codex exec resume <thread-id>` for later turns. The identity also includes the endpoint, Agent, target, workspace and Codex home. It never uses `--last`. Claude Code saves the `session_id` from its `system/init` event under `~/.orcha/claude-sessions/` and uses `claude -p --resume <session-id>`; the identity includes the endpoint, Agent, target, workspace and Claude config directory, and never uses `--continue`. Each turn still has a separate run ID, tool credential and retry fence. Device Codex and Claude Code close their temporary MCP proxy after each turn and open a fresh one for the next.
|
|
119
121
|
|
|
120
|
-
Send exactly `/new` to an Agent to reset context while staying in the current conversation. It creates no model run and is not forwarded to OpenClaw or
|
|
122
|
+
Send exactly `/new` to an Agent to reset context while staying in the current conversation. It creates no model run and is not forwarded to OpenClaw, Codex or Claude Code. Core records a centered “已开始新对话” system notice; existing messages remain visible, while subsequent model context starts after this boundary. The receipt retains the same `sessionId` and task scope with `runId:null`. In a group, select an Agent explicitly; send the command without a quoted message, attachments, plugins or skills. Complete or stop unfinished work in that context before resetting. The existing history boundary in native session keys makes the next OpenClaw/Codex/Claude Code turn start a fresh native conversation. Other raw commands, such as `/status`, reach OpenClaw and remain subject to its own command permissions.
|
|
121
123
|
|
|
122
|
-
Old Orcha history and per-run native sessions are not migrated or injected. Upgrade Core, Bridge and the bundled plugin together. A normal Bridge restart preserves completed Codex conversations. If a process crashes during a
|
|
124
|
+
Old Orcha history and per-run native sessions are not migrated or injected. Upgrade Core, Bridge and the bundled plugin together. A normal Bridge restart preserves completed Codex and Claude Code conversations. If a process crashes during a native turn, its durable lock remains and the affected conversation requires `/new`: automatically replaying a detached process could repeat side effects. Missing/mismatched native IDs and repeated run IDs fail explicitly. Keep the local Codex home or Claude config directory and the Orcha session mapping together; clearing either does not authorize silently starting over in the same conversation.
|
|
123
125
|
|
|
124
126
|
## Delegated group member tools
|
|
125
127
|
|
|
126
|
-
Codex
|
|
128
|
+
Codex and Claude Code support task-scoped Orcha MCP through the same 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.
|
|
129
|
+
|
|
130
|
+
### Claude Code native IM turns (0.1.52)
|
|
131
|
+
|
|
132
|
+
Device Claude Code now follows the same IM model as device Codex: Core sends only the current message, Bridge resumes the scoped native session, and conversation and delegated turns receive the task's Orcha MCP tools, including `send_file`. The MCP proxy is passed with `--mcp-config`; argv contains only the loopback URL and an `${ORCHA_TASK_MCP_TOKEN}` header placeholder that Claude Code expands from the child environment. `--allowedTools mcp__orcha` lets the Core-authorized task tools run without a local prompt; other Claude tools keep the device's own permission settings, and print mode denies anything that would prompt. Claude Code continues without an unreachable MCP server, so Bridge stops the turn with `RUNTIME_CLAUDE_MCP_UNAVAILABLE` when `system/init` does not report `orcha` as connected; the native session is not advanced.
|
|
133
|
+
|
|
134
|
+
`stream-json` events become the existing Orcha progress updates: top-level `tool_use`/`tool_result` blocks map to `tool_call`/`tool_call_update`, text before a tool call becomes process commentary, and the `result` event remains the only final reply. Subagent internals stay inside their parent tool call, tool result images are reduced to their text, and thinking blocks are not forwarded. The `generated_images` delivery root remains Codex-only; Claude deliverables must be in the workspace or a configured artifact root.
|
|
135
|
+
|
|
136
|
+
Rollout requires Core with this change, then the updated and reloaded device Bridge. There is no database migration, protocol-version change or new project environment variable. Old Orcha history is not injected into Claude Code. The fixture tests use a fake Claude CLI over a real HTTP MCP endpoint; a real Claude account/model turn has not been accepted yet.
|
|
137
|
+
|
|
138
|
+
### Codex file delivery (0.1.51)
|
|
139
|
+
|
|
140
|
+
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.
|
|
141
|
+
|
|
142
|
+
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.
|
|
143
|
+
|
|
144
|
+
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.
|
|
145
|
+
|
|
146
|
+
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.
|
|
147
|
+
|
|
148
|
+
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).
|
|
127
149
|
|
|
128
150
|
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:
|
|
129
151
|
|
|
@@ -1,28 +1,31 @@
|
|
|
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.50";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
|
|
4
|
-
`),await
|
|
5
|
-
`)}for(let s of n)if((await new
|
|
6
|
-
`):""}var
|
|
2
|
+
import{spawn as xc}from"node:child_process";import{closeSync as Nc,existsSync as Ar,mkdirSync as bc,openSync as Mc,readFileSync as Or,rmSync as Uc,statSync as ms,writeFileSync as Ts}from"node:fs";import{dirname as Es,resolve as _t}from"node:path";import{fileURLToPath as Pc}from"node:url";import{createHash as Dr}from"node:crypto";import{mkdir as vs,readFile as Ds,writeFile as Hs,rename as $s}from"node:fs/promises";import{join as vr}from"node:path";import{homedir as Fs,hostname as Bs}from"node:os";import{execFile as bs}from"node:child_process";import{access as Ms,realpath as Us}from"node:fs/promises";import{constants as Ps}from"node:fs";import{delimiter as Ls,join as Pr,isAbsolute as Lr}from"node:path";import{homedir as Ur}from"node:os";async function ge(e,t=process.env){let r=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let n of(t.PATH||"").split(Ls).filter(Lr))for(let s of r){let i=Pr(n,`${e}${s}`);try{return await Ms(i,Ps.X_OK),i}catch{}}return null}function ks(e,t){return new Promise(r=>bs(e,t,{timeout:8e3,maxBuffer:1024*1024,windowsHide:!0},(n,s)=>r({code:n?n.code:0,stdout:String(s||"")})))}async function _e(e){let t=e==="~"?Ur():e.startsWith("~/")?Pr(Ur(),e.slice(2)):e;if(!Lr(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 Us(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 kr({find:e=ge,run:t=ks,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 p=await t(i,["agents","list","--json"]),m;try{m=JSON.parse(p.stdout)}catch{}if(p.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(w=>typeof w.id=="string"&&typeof w.workspace=="string").slice(0,32).map(w=>({...d,id:`openclaw:${w.id}`,name:w.name||w.identityName||w.id,workspace:w.workspace,managed:!0,localAgentId:w.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"]),h=f.code===0?"ready":f.code===1?"needs_login":"error";return[{...d,command:i,status:h,message:h==="needs_login"?`\u8BF7\u5728\u672C\u673A\u8FD0\u884C ${s} ${s==="codex"?"login":"auth login"}`:h==="error"?"\u767B\u5F55\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C":""}]}))).flat()}var Hr={terminalProtocol:"claude",args:["-p","--output-format","stream-json","--verbose"],promptMode:"stdin",outputMode:"json-lines"},js=JSON.stringify(["-p","--output-format","json","--no-session-persistence"]);async function ye(e,t){let r=`${e}.${process.pid}.tmp`;await Hs(r,JSON.stringify(t),{mode:384}),await $s(r,e)}function Te(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=vr(Fs(),".orcha","devices"),n=vr(r,Dr("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 Ut(e,{url:t,pairCode:r}){let{address:n,root:s,profile:i}=Te(t||e.orchaUrl);await vs(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:Bs()})}),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 ye(i,o)}else{try{o=JSON.parse(await Ds(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")}let a=Object.values(o.targets||{}).filter(u=>u.terminalProtocol==="claude"&&u.promptMode==="args"&&JSON.stringify(u.args)===js);for(let u of a)Object.assign(u,structuredClone(Hr));a.length&&await ye(i,o)}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 we(e,o,async()=>ye(i,o))}var we=class{constructor(t,r,n,s=kr){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 h=await _e(String(u.workspace||""));if(d.managed&&h!==await _e(d.workspace))throw new Error("\u5DF2\u6709\u667A\u80FD\u4F53\u5FC5\u987B\u6CBF\u7528\u672C\u673A\u5DE5\u4F5C\u76EE\u5F55");let p=`${this.config.nodeId}:${Dr("sha256").update(d.id).digest("hex").slice(0,20)}`;if([...r.sessions.values()].some(m=>m.targetCode===p))throw new Error("\u6B64\u667A\u80FD\u4F53\u4ECD\u6709\u4F1A\u8BDD\uFF0C\u8BF7\u5148\u7ED3\u675F\u4F1A\u8BDD\u518D\u4FEE\u6539\u63A5\u5165");s[p]={name:f,workspace:h,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}:structuredClone(Hr)},i.push({candidateId:d.id,name:f,workspace:h,targetCode:p,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 ri}from"node:child_process";import{constants as ni}from"node:fs";import{access as Vr,readFile as Jr,realpath as si}from"node:fs/promises";import{join as Ee}from"node:path";import{promisify as ii}from"node:util";var W="0.1.52";function Et(){return new Date().toISOString()}function L(e,t=2){return String(e).padStart(t,"0")}function $r(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${L(Math.floor(r/60))}:${L(r%60)}`}function qs(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)}`,$r(t)].join("")}function Gs(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 Ks(e,t){let r=Gs(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)}`,$r(s)].join("")}function zs(e=new Date){let t=c(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return Ks(e,t)}catch{return qs(e)}}function l(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function c(e){return String(e??"").trim()}function S(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 rt(e,t,r=process.cwd()){let n=l(e)?e:{};return c(n.cwd)||c(n.workspace)||c(t)||c(r)||process.cwd()}var Pt="[redacted]",Vs=/(authorization|api[_-]?key|credential|password|secret|token)/i;function J(e){return Vs.test(c(e))}function nt(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(Pt))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${Pt}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${Pt}`)}function et(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]=et(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=>et(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"?Pt:et(i,t);return t.delete(e),r}function Fr(e,t=4e3){let r=JSON.stringify(et(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function g(e,t,r,n={}){let s={ts:zs(),level:e,module:t,msg:r,...l(n)?et(n):{}};console.error(JSON.stringify(s))}var st="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 Br(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 jr(e,t){if(e.headers.get("content-type")!==st)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 Ws}from"node:http";import{randomBytes as Xs}from"node:crypto";var Lt={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs","knowledge_search"]};var Ys=Object.freeze([...Lt.controlTools,...Lt.residentTools]),Qs=new Set(Ys),Zs=8*1024*1024;function kt(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 Gr(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>Zs)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function Kr(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 Gr(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function qr(e,t){let r=await Kr(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"?nt(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 ti(n)}function ti(e){if(!Array.isArray(e)||e.some(t=>!t||!Qs.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&Lt.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 ei(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 zr(e,t=[]){let r=kt(e),n=new AbortController,s=await qr(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=Xs(32).toString("hex"),o=Ws(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 Gr(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(p=>p.name===d.params?.name);if(d.method==="tools/call"&&!f&&!s.some(p=>p.name===d.params?.name))throw new Error("Tool is not authorized in this task binding");let h;if(f)try{h={jsonrpc:"2.0",id:d.id,result:await f.call(d.params.arguments,{upstream:r,signal:n.signal})}}catch(p){h={jsonrpc:"2.0",id:d.id,result:{isError:!0,content:[{type:"text",text:nt(String(p.message),[r.headers.authorization,i])}]}}}else h=await Kr(r,d,n.signal),d.method==="tools/list"&&h?.result?.tools&&h.result.tools.push(...t.map(({call:p,...m})=>m));u.writeHead(h===null?202:200,{"content-type":"application/json"}),u.end(h===null?"":JSON.stringify(h))}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=kt(a,r.url);if(!ei(s,await qr(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 X=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 h=AbortSignal.timeout(i);try{let p=await fetch(f,{method:t,redirect:"error",signal:h,headers:{authorization:`Bearer ${d}`,"content-type":"application/json",...o?{accept:st}:{},...n?{"if-match":this.identity.runId}:{}},...r!==void 0?{body:JSON.stringify(r)}:{}});if(t==="GET"&&s==="deliveries"&&[404,405].includes(p.status))throw await p.body?.cancel(),P("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH");if(p.ok&&o)return await jr(p,o);let m=await p.json();if(!p.ok)throw P(m.error||"OPENCLAW_MCP_BINDING_FAILED");return m}catch(p){throw Br(p,h)}}async bind(t,r=!1){kt(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 oi=ii(ri),ai=12e4;async function Wr(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 ge(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 si(a);await Vr(u,ni.X_OK);let d=JSON.stringify([u,Object.entries(i).sort(([f],[h])=>f.localeCompare(h))]);r.has(d)||r.set(d,{command:u,env:i})}if(r.size)try{let s=JSON.parse(await Jr(Ee(t,"openclaw.plugin.json"),"utf8")),i=JSON.parse(await Jr(Ee(t,"package.json"),"utf8"));if(await Vr(Ee(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 Se(s,["plugins","install",t,"--force"]),await Se(s,["gateway","restart"]);let i=await Se(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 X(s,{}).request("GET",void 0,!1,"deliveries")).streamType!==st)throw P("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH")}}async function Se(e,t){try{let{stdout:r}=await oi(e.command,t,{env:e.env,timeout:ai,killSignal:"SIGKILL",maxBuffer:1048576,windowsHide:!0});return r}catch(r){let n=Object.entries(e.env).filter(([i])=>J(i)).map(([,i])=>i),s=nt(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 ka,randomUUID as se}from"node:crypto";function vt(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 Dt=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=vt(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 ci}from"node:child_process";var St="2.0",Re=3e4,ui=4e3;function Ht(e,t){let r=Object.entries(l(t)?t:{}).filter(([n])=>J(n)).map(([,n])=>n);return nt(e,r)}function li(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 di(e){if(!l(e))return new Error(String(e||"runtime error"));let t=c(e.message)||"runtime error",r="data"in e?Fr(e.data,4e3):"",n=new Error(r?`${t}; data=${r}`:t);return n.rpcCode=e.code,n.data=e.data,n}function fi(e){return l(e)&&"id"in e&&!("method"in e)}function pi(e){return l(e)&&typeof e.method=="string"&&"id"in e}function hi(e){return l(e)&&typeof e.method=="string"&&!("id"in e)}var $t=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=Re}={}){if(!(this.child&&!this.exited)&&(this.exited=!1,this.exitCode=null,this.exitSignal=null,this.stderrTail="",this.spawnError=null,this.child=ci(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(-ui);let i=Ht(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,S(n,Re));try{await this.call("initialize",{protocolVersion:1,clientCapabilities:{},...r},s)}catch(i){let o=this.startupFailureDetail(),a=Ht(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:Ht(this.spawnError.message,this.env)}:{},...this.stderrTail.trim()?{stderr:Ht(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(fi(t)){this.resolveResponse(t);return}if(pi(t)){this.handleRequest(t);return}hi(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(di(t.error))):n.resolve(t.result))}async handleRequest(t){let r=this.requestHandlers.get(t.method);if(!r){this.writeFrame({jsonrpc:St,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:St,id:t.id,result:n??{}})}catch(n){this.writeFrame({jsonrpc:St,id:t.id,error:li(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=Re){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:St,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:St,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 Zr}from"node:crypto";import{existsSync as mi,readFileSync as gi,realpathSync as Xr,statSync as _i}from"node:fs";import{basename as tn,extname as en,isAbsolute as Rt,join as yi,relative as rn,resolve as Yr}from"node:path";var wi=25*1024*1024;function nn(e,t=""){let r=c(t);if(r)return r;let n=en(c(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function sn(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 Ti(e,t){let r=rn(t,e);return r===""||!!r&&!r.startsWith("..")&&!Rt(r)}function Ei(e,t){let r=c(e);if(!r||!mi(r))return"";try{let n=Xr(r);for(let s of t)try{let i=Xr(s);if(Ti(n,i))return n}catch{}}catch{return""}return""}function Si(e,t){let r=c(e);if(!r||!Rt(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||!Rt(s)||!Rt(i))continue;let o=rn(Yr(s),Yr(r));if(o===""||!o.startsWith("..")&&!Rt(o))return o?yi(i,o):i}return r}function Oe(e,t,r={}){let n=c(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:Ri(n,t,r)}function Ri(e,t,r={}){let n=[...Ft(r.trustedFileRoots),...Ft(r.trustedFileRoot),...Ft(r.artifactRoots),...Ft(r.artifactRoot)],s=Ei(Si(e,r.pathMappings),n);if(!s)return"";try{let i=_i(s);return!i.isFile()||i.size<=0||i.size>wi?"":`data:${t};base64,${gi(s).toString("base64")}`}catch{return""}}function x(...e){for(let t of e){let r=c(t);if(r)return r}return""}function Oi(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=en(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function Ce(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=nn(a,n.mimeType||n.mime_type),f=sn(n.result,d)||Oe(a,d,t);if(!f)return null;let h=f.startsWith("data:")?f:"",p=a?tn(a):`${o||Zr()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:p||"Generated image",summary:u||"Generated image",content:{prompt:u||void 0,dataUrl:h||void 0,imageUrl:f,previewUrl:f,fileUrl:f,mimeType:d},dataUrl:h||void 0,previewUrl:f,fileUrl:f,metadata:{source:r,eventType:i,callId:o||void 0,savedPath:a||void 0,filename:p,mimeType:d,revisedPrompt:u||void 0}}}function Ii(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 Ci(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=Oi(n,s,u,o),f=d?nn(o,a):a;if(d){let I=x(n.dataUrl,s.dataUrl),_=I.startsWith("data:")?I:"",T=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=sn(n.result??s.result,f)||_||Oe(o,f,t)||Oe(T,f,t);E&&(E.startsWith("data:")&&(s.dataUrl||=E),s.imageUrl||=E,s.previewUrl||=E,s.fileUrl||=E,f&&(s.mimeType||=f))}for(let[I,_]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let T=n[I];T!=null&&T!==""&&!(_ in s)&&(s[_]=T)}let h=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),p=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,h.startsWith("data:")?h:"",p.startsWith("data:")?p:""),y=x(n.filename,i.filename,o?tn(o):""),w=x(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,d?"image":"artifact");return{...n,artifactType:u,type:n.type||u,fieldKey:w,title:x(n.title,y,"Runtime artifact"),summary:x(n.summary,s.prompt,n.title,y,"Runtime artifact"),content:s,dataUrl:m||void 0,fileUrl:h||void 0,previewUrl:p||void 0,metadata:{...i,source:x(i.source,r),savedPath:o||i.savedPath,filename:y||i.filename,mimeType:f||i.mimeType}}}function Bt(e,t){if(!t||!e)return;let r=l(t.metadata)?t.metadata:{},n=x(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||Zr(),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 Ie(e,t,r={}){for(let n of Ii(e))Bt(t,Ci(n,r))}function Ae(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 Qr(e,t,r){if(!l(e))return e;let n=l(e.event)?e.event:null;return n?(Bt(t,Ce(n,r)),{...e,event:Ae(n)}):e}function on(e,t,r={}){if(!l(e))return e;Ie(e,t,r);let n=Qr(e,t,r),s=l(n.update)?Qr(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function an(e,t,r={}){let n=l(e)?{...e}:{};Ie(n,t,r),Ie(l(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function cn(e,t){let r=S(e,t);return r>0?r:t}var ft=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:rt(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 $t({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:cn(this.target.initializeTimeoutMs,cn(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(on(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 an(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 un,readFileSync as Ai}from"node:fs";import{dirname as xi,resolve as jt}from"node:path";import{fileURLToPath as Ni}from"node:url";var bi=/^[A-Za-z_][A-Za-z0-9_]*$/,Y=24*60*60*1e3;function ln(e=process.env,t=process.cwd()){let r=c(e.ORCHA_RUNTIME_ENV_FILE),n=r?jt(t,r):jt(t,".env");if(!un(n))return r&&g("warn","config","runtime env file not found",{path:n}),{loaded:!1,path:n,keys:[]};let s=[],i=Ai(n,"utf8");for(let o of i.split(/\r?\n/)){let a=Pi(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 dn(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=xi(Ni(import.meta.url)),i=jt(s,"sandbox","broker.js"),o=jt(s,"orcha-runtime-sandbox-broker.js"),a=un(i)?i:o,u=c(e.ORCHA_RUNTIME_SANDBOX_BROKER_COMMAND);return{mode:t,host:r,port:S(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:S(e.ORCHA_RUNTIME_RECONNECT_MS,3e3),connectTimeoutMs:S(e.ORCHA_RUNTIME_CONNECT_TIMEOUT_MS||e.ORCHA_RUNTIME_WS_CONNECT_TIMEOUT_MS,1e4),defaultTargetCode:e.ORCHA_RUNTIME_DEFAULT_TARGET||"echo",requestLimitBytes:S(e.ORCHA_RUNTIME_REQUEST_LIMIT_BYTES,1048576),initializeTimeoutMs:S(e.ORCHA_RUNTIME_INITIALIZE_TIMEOUT_MS,3e4),sessionPromptTimeoutMs:S(e.ORCHA_RUNTIME_SESSION_PROMPT_TIMEOUT_MS,Y),permissionRequestTimeoutMs:S(e.ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS,3e5),sessionIdleTtlMs:S(e.ORCHA_RUNTIME_SESSION_IDLE_TTL_MS,6e5),sessionCleanupIntervalMs:S(e.ORCHA_RUNTIME_SESSION_CLEANUP_INTERVAL_MS,6e4),maxSessionsPerTarget:S(e.ORCHA_RUNTIME_MAX_SESSIONS_PER_TARGET,8),openClawSessionIdleTtlMs:S(e.ORCHA_RUNTIME_OPENCLAW_SESSION_IDLE_TTL_MS,6e4),openClawMaxSessions:S(e.ORCHA_RUNTIME_OPENCLAW_MAX_SESSIONS,1),heartbeatIntervalMs:S(e.ORCHA_RUNTIME_HEARTBEAT_INTERVAL_MS,15e3),sandboxRequired:n,sandboxBrokerCommand:u||process.execPath,sandboxBrokerArguments:xe(e.ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS,"ORCHA_RUNTIME_SANDBOX_BROKER_ARGUMENTS",u?[]:[a]),sandboxProbeTimeoutMs:S(e.ORCHA_RUNTIME_SANDBOX_PROBE_TIMEOUT_MS,1e4),sandboxTempRoot:c(e.ORCHA_RUNTIME_SANDBOX_TEMP_ROOT),trustedWorkspaceRoots:xe(e.ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS,"ORCHA_RUNTIME_TRUSTED_WORKSPACE_ROOTS"),trustedToolchainRoots:xe(e.ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS,"ORCHA_RUNTIME_TRUSTED_TOOLCHAIN_ROOTS"),egressProxyRequired:Ui(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:S(e.ORCHA_RUNTIME_EGRESS_GRANT_MAX_TTL_MS,9e5),targets:Mi(e.ORCHA_RUNTIME_TARGETS_JSON||"")}}function Mi(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 Ui(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 xe(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 Pi(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(!bi.test(s))return null;let i=Li(r.slice(n+1).trim());return[s,i]}function Li(e){if(!e)return"";let t=e[0];if((t==='"'||t==="'")&&e.endsWith(t)){let r=e.slice(1,-1);return t==='"'?ki(r):r}return vi(e).trim()}function ki(e){return e.replaceAll("\\n",`
|
|
12
|
+
`).replaceAll("\\r","\r").replaceAll("\\t"," ").replaceAll('\\"','"').replaceAll("\\\\","\\")}function vi(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 qt=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 X(r,{runId:i.runId}),this.expiresAt=new Date(Date.now()+Number(i.sandboxPolicy?.maxRuntimeSeconds||i.sessionPromptTimeoutMs/1e3||Y/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!==st)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||Y),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 Ne(e){let t=l(e.metadata)?e.metadata:{};return c(t.agentCode)}function fn(e,t,r){let n=c(r?.openclawAgentId)||Ne(e);return n?`agent:${n}:${t}`:`orcha-${t}`}var Gt=class extends ft{constructor(t,r,n,s={},i={}){if(i.source==="channel_message")return new qt(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",fn(t,o,r)];super(t,{...r,command:a,args:d},s,i),this.boundSessionKey=fn(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||Y/1e3);if(!o||!Ne(this.agent))throw new Error("OpenClaw MCP requires a trusted task and Agent identity");this.binding=new X(this.target,{runId:o,sessionKey:this.boundSessionKey,agentCode:c(this.target.openclawAgentId)||Ne(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 An}from"node:child_process";import{randomUUID as pt}from"node:crypto";import{existsSync as xn,mkdirSync as Qi,readdirSync as Nn,readFileSync as bn,realpathSync as It,rmSync as Zi,rmdirSync as to,statSync as eo,unlinkSync as ro}from"node:fs";import{homedir as no,tmpdir as Mn}from"node:os";import{basename as ve,dirname as so,join as $,resolve as En}from"node:path";import{createHash as Gi,randomUUID as Ki}from"node:crypto";import{mkdirSync as gn,readFileSync as zi,renameSync as Vi,rmSync as Ji,writeFileSync as _n}from"node:fs";import{homedir as Me}from"node:os";import{join as it}from"node:path";import{createHash as pn}from"node:crypto";import{constants as be}from"node:fs";import{open as Di,realpath as hn}from"node:fs/promises";import{basename as Hi,isAbsolute as $i,relative as Fi,resolve as Bi}from"node:path";var ji=32*1024*1024,qi={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, a configured artifact root, or (Codex only) the current thread's generated_images directory. 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 mn(e){return{...qi,async call(t,{upstream:r,signal:n}){if(!t||typeof t.path!="string"||!t.path.trim()||Object.keys(t).some(E=>!["path","message"].includes(E))||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 hn(Bi(s,t.path)),a=!1;for(let E of i)try{let R=Fi(await hn(E),o);(!R||R!==".."&&!R.startsWith("../")&&!R.startsWith("..\\")&&!$i(R))&&(a=!0)}catch{}if(!a)throw new Error("File is outside the current workspace and authorized artifact roots");let u=await Di(o,be.O_RDONLY|be.O_NOFOLLOW|be.O_NONBLOCK),d;try{let E=await u.stat();if(!E.isFile()||E.size<=0||E.size>ji)throw new Error("Select a non-empty regular file of at most 32 MiB");d=Buffer.alloc(E.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!==E.size||N.mtimeMs!==E.mtimeMs)throw new Error("File changed while preparing delivery; retry after it is saved")}finally{await u.close()}let f=t.message||"",h=Hi(o),p=pn("sha256").update(d).digest("hex"),m=pn("sha256").update(JSON.stringify([o,p,f])).digest("hex"),y=new FormData;y.set("deliveryId",m),y.set("message",f),y.set("file",new Blob([d]),h);let w=new URL(r.url);w.pathname=`${w.pathname.replace(/\/$/,"")}/files`;let I=await fetch(w,{method:"POST",headers:{authorization:r.headers.authorization},body:y,redirect:"error",signal:AbortSignal.any([n,AbortSignal.timeout(12e4)])});if(!I.ok)throw new Error(`File delivery failed (HTTP ${I.status}); no successful receipt was received`);let _=await I.json();if(!_.success)throw new Error(`File delivery failed: ${String(_.message||_.code||"request rejected").slice(0,512)}`);let T=_.data;if(!T?.accepted||typeof T.messageId!="string"||!T.messageId||typeof T.fileId!="string"||!T.fileId)throw new Error("File delivery did not return a saved message and file receipt");return{content:[{type:"text",text:JSON.stringify(T)}],structuredContent:T,isError:!1}}}}var yn=e=>Gi("sha256").update(JSON.stringify(e)).digest("hex"),q=(e,t)=>Object.assign(new Error(t),{code:e}),wn=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Ue="ORCHA_TASK_MCP_TOKEN",Wi=new Set(["--no-session-persistence","--resume","-r","--continue","-c","--session-id","--fork-session"]);function Xi(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>t?.type==="text").map(t=>t.text).join(`
|
|
13
|
+
`):""}function Yi(e,t,r){if(!["assistant","user"].includes(e?.type))return null;let n=e.parent_tool_use_id?[]:Array.isArray(e.message?.content)?e.message.content:[],s=[];for(let i of n)e.type==="user"?i?.type==="tool_result"&&i.tool_use_id&&s.push({sessionUpdate:"tool_call_update",toolCallId:i.tool_use_id,status:i.is_error?"failed":"completed",rawOutput:Xi(i.content)}):i?.type==="text"&&i.text?t.text=t.text?`${t.text}
|
|
13
14
|
|
|
14
|
-
${s}`:s;Mn(t,r,n,d,s)&&(o=1,a=1)}return s&&i&&(t.finalTextSeen=!0),An(t,xn(e,t.artifactOptions)),(Io(e)||Co(e)||xo(e)||i)&&n({sessionId:r,update:{sessionUpdate:"runtime_event",event:Nn(e)}}),{textCount:o,finalTextCount:a,thoughtCount:u}}function Me(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=So(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 T=Ao(m,e,r,n);a+=T.textCount,u+=T.finalTextCount,d+=T.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 No(e,{remove:t=!0}={}){if(!e||!wn(e))return"";try{return Rn(e,"utf8").trim()}catch{return""}finally{t&&zt(e)}}function zt(e){if(e)try{Bi(e)}catch{}}function bo(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 Mo(e){return new Promise(t=>setTimeout(t,e))}function Uo(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 Po(e,t,r,n,s,i){let o=Me(e,t,r,n,Date.now()),a=()=>Uo(e,r,n,No(s,{remove:!1}));if(a()||e.finalTextSeen)return zt(s),o;let u=ro(i);if(u<=0||!t&&!s)return zt(s),o;let d=Date.now()+u,f=Math.min(bn(i),100);for(;!e.finalTextSeen&&Date.now()<d&&(await Mo(Math.min(f,Math.max(0,d-Date.now()))),o=bo(o,Me(e,t,r,n,Date.now())),!a()););return zt(s),o}var Wt=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"&&Ae(r)==="codex"){if(typeof n.cloudSessionId!="string"||!Wi.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 Gt([n.orchaUrl,t.agentId,t.targetCode,n.cloudSessionId,et(r,t.workspace),r.command,r.env?.CODEX_HOME||process.env.CODEX_HOME||F(Sn(),".codex")])}}async sessionNew(t={}){let r=t.mcpServers||[];if(r.length&&(t.metadata?.source==="conversation_delegation"||this.nativeSession)&&Ae(this.target)==="codex"){if(this.options.prepareLaunch)throw Object.assign(new Error("Codex task MCP requires a reachable node-local transport; this sandbox launcher does not provide one"),{code:"unsupported_dynamic_mcp"});this.taskMcp=await cn(r)}else if(r.length&&t.metadata?.source==="conversation_delegation")throw Object.assign(new Error("This CLI adapter does not support task-scoped MCP"),{code:"unsupported_dynamic_mcp"});return{sessionId:`cli-${this.agent.agentId}-${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),r,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?pn(f,s):f],h=et(this.target,this.agent.workspace),m=typeof this.options.prepareLaunch=="function",S=to(o,p,this.target)?m?`/tmp/orcha-runtime-last-message-${dt()}.txt`:F(On(),`orcha-runtime-last-message-${dt()}.txt`):"";S&&p.push("--output-last-message",S);let N={...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:N}):{command:o,args:p,cwd:h,environment:{...process.env,...N},cleanup:async()=>{}},w=m?lo(_):uo(this.target,a),E=w.root,O=po(this.target,E,_),U=eo(o,this.target),v={...this.target,targetCode:this.agent.targetCode,cwd:h,...m?{codexHome:F(_.homeDirectory,".codex")}:{}},D=U?go(v,i):new Set,Q=m&&S?F(_.tempDirectory,S.slice(5)):S,z=y(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,y(this.options.sessionPromptTimeoutMs,X));m||(_.environment.ORCHA_RUNTIME_ARTIFACT_DIR=E);let I=yn(_.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 Sr="",le=c(this.target.outputMode||"text"),b={artifacts:new Map,emittedTexts:new Set,emittedThoughtTexts:new Set,value:"",artifactOptions:O,finalTextSeen:!1,finalTextOnly:oo(t,this.target),emitThoughtChunks:so(t,this.target),terminalOutcome:null,terminalProtocol:Ae(this.target),emitTerminal:null},de=U?co(v,u,i,D):null;return I.stdout.setEncoding("utf8"),I.stdout.on("data",ct=>this.handleStdout(ct,le,b,a,r)),I.stderr.setEncoding("utf8"),I.stderr.on("data",ct=>{Sr+=ct,this.target.emitStderr===!0&&r({sessionId:a,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:ct}}})}),d==="stdin"?I.stdin.end(u):I.stdin.end(),await new Promise((ct,fe)=>{let gt=!1,Or=!1,bt=null,_t=null,pe=de&&no(this.target,t)?setInterval(()=>{try{Me(b,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)})}},bn(this.target)):null;pe?.unref?.();let Ir=setTimeout(()=>{Or=!0,g("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:a,pid:I.pid,timeoutMs:z}),Vt(I,"SIGTERM"),bt=setTimeout(()=>{g("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:a,pid:I.pid}),Vt(I,"SIGKILL")},In),bt.unref?.(),Tt(Object.assign(new Error(`runtime CLI timed out after ${z}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},z);Ir.unref?.();let Cr=async()=>{clearTimeout(Ir),_t&&clearTimeout(_t),pe&&clearInterval(pe),bt&&!Or&&clearTimeout(bt),fo(w,{target:this.agent.targetCode,sessionId:a}),this.active.delete(a),b.emitTerminal=null,await _.cleanup?.()},Ss=C=>{gt||(gt=!0,Cr().then(()=>ct(C),fe))},Tt=C=>{gt||(gt=!0,Cr().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)}))};b.emitTerminal=C=>{let B={...l(C.result)?C.result:{},_artifacts:[...b.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,y(this.target.terminalExitGraceMs,Ji));_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:b.terminalProtocol,graceMs:$}),xe(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)}),Tt(C)}),I.on("exit",(C,B)=>{(async()=>{le==="json-lines"&&b.value.trim()&&this.handleStdout(`
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
`:"";t+=`${s}${n}`}}return t.trim()}function Ja(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
|
-
|
|
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 fs({quiet:e=!1}={}){let t=ce(),r=ue(t);if(!r){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!at(r)){Er(t),e||console.log(JSON.stringify({status:"not_running",pid:r,pidFile:t}));return}process.kill(r,"SIGTERM"),!await ps(r,1e4)&&at(r)&&(process.kill(r,"SIGKILL"),await ps(r,3e3)),Er(t),e||console.log(JSON.stringify({status:"stopped",pid:r,pidFile:t}))}function Oc(){let e=ce(),t=ws(),r=ue(e),n=!!(r&&at(r));console.log(JSON.stringify({status:n?"running":"not_running",running:n,pid:n?r:null,pidFile:e,logFile:t}))}function Ic(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 Cc(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||Tc)}function ws(){return mt(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||yc)}function xc(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=Es();if(t<=0)return;let r=mt(process.cwd(),e);wr(r,t);let n=Nc();n<=0||setInterval(()=>wr(r,t),n).unref()}function wr(e,t=Es()){if(t<=0||!Rr(e))return;let r=0,n="";try{if(r=ls(e).size,r<=0)return;n=yr(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&&(Ac(d,s)?o.push(d):a+=1);if(a===0)return;let u="";try{ls(e).size>r&&(u=yr(e,"utf8").slice(n.length));let f=[...o,...u.split(/\r?\n/).filter(Boolean)].join(`
|
|
24
|
-
`);ms(e,f?`${f}
|
|
25
|
-
|
|
15
|
+
${i.text}`:i.text:i?.type==="tool_use"&&i.id&&(t.text&&r&&s.push({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:t.text}}),t.text="",s.push({sessionUpdate:"tool_call",toolCallId:i.id,title:i.name,status:"in_progress",rawInput:i.input}));return s}var ot=Object.freeze({codex:{label:"Codex",code:"CODEX",sessionDirectory:"codex-sessions",home:e=>e.env?.CODEX_HOME||process.env.CODEX_HOME||it(Me(),".codex"),threadId:e=>e?.type==="thread.started"?e.thread_id:void 0,resumeArgs(e,t){let r=e.indexOf("exec");if(r<0||e.includes("resume")||e.includes("--ephemeral"))throw q("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},mcpArgs:e=>["-c",`mcp_servers.orcha={url=${JSON.stringify(e)},bearer_token_env_var=${JSON.stringify(Ue)},required=true}`]},claude:{label:"Claude Code",code:"CLAUDE",sessionDirectory:"claude-sessions",home:e=>e.env?.CLAUDE_CONFIG_DIR||process.env.CLAUDE_CONFIG_DIR||it(Me(),".claude"),threadId:e=>e?.type==="system"&&e.subtype==="init"?e.session_id:void 0,resumeArgs(e,t){let r=e.indexOf("--output-format");if(!e.includes("-p")&&!e.includes("--print")||r<0||e[r+1]!=="stream-json"||!e.includes("--verbose")||e.some(n=>Wi.has(n)))throw q("BAD_REQUEST","Claude Code \u539F\u751F\u4F1A\u8BDD\u9700\u8981\u6807\u51C6 claude -p --output-format stream-json --verbose \u914D\u7F6E");return t?[...e,"--resume",t]:e},mcpArgs:e=>["--mcp-config",JSON.stringify({mcpServers:{orcha:{type:"http",url:e,headers:{Authorization:`Bearer \${${Ue}}`}}}}),"--allowedTools","mcp__orcha"],taskMcpError(e){if(e?.type!=="system"||e.subtype!=="init")return null;let t=e.mcp_servers?.find(r=>r?.name==="orcha")?.status||"missing";return t==="connected"?null:q("RUNTIME_CLAUDE_MCP_UNAVAILABLE",`Claude Code \u672A\u80FD\u8FDE\u63A5 OrchaAI \u4EFB\u52A1\u5DE5\u5177\uFF08${t}\uFF09\uFF0C\u672C\u8F6E\u672A\u6267\u884C`)},progress:Yi}});async function Tn(e,t,r){let n=await zr(t,r?[mn(r)]:[]);return{args:e.mcpArgs(n.url),environment:{[Ue]:n.token},refresh:s=>n.refresh(s),close:()=>n.close()}}var Kt=class{constructor(t,r,n=it(Me(),".orcha",ot[t].sessionDirectory)){this.adapter=ot[t],this.directory=it(n,yn(r))}async turn(t,r,n,s,i){let{label:o,code:a}=this.adapter;if(!t)throw q("BAD_REQUEST",`${o} native turn requires a run ID`);gn(this.directory,{recursive:!0,mode:448});let u=it(this.directory,"active");try{gn(u,{mode:448})}catch(p){throw p.code==="EEXIST"?q("RUNTIME_SESSION_BUSY",`${o} \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`):p}let d=it(this.directory,"session.json"),f,h=()=>{let p=`${d}.${Ki()}.pending`;_n(p,JSON.stringify(f),{mode:384}),Vi(p,d)};try{try{f=JSON.parse(zi(d,"utf8"))}catch(w){if(w.code!=="ENOENT")throw w}if(f&&!wn.test(f.threadId||""))throw q("RUNTIME_OPERATION_NOT_FOUND",`${o} \u4E0A\u8F6E\u672A\u80FD\u4FDD\u5B58\u539F\u751F\u4F1A\u8BDD\u6807\u8BC6\uFF0C\u8BF7\u53D1\u9001 /new`);try{_n(it(this.directory,`${yn(t)}.run`),"",{flag:"wx",mode:384})}catch(w){throw w.code==="EEXIST"?q("RUNTIME_OPERATION_NOT_FOUND",`\u6B64\u8F6E ${o} \u5DF2\u6267\u884C\u6216\u6267\u884C\u7ED3\u679C\u4E0D\u786E\u5B9A\uFF0C\u4E0D\u80FD\u91CD\u590D\u53D1\u9001`):w}f||={threadId:null},h();let p,m=w=>{if(p)return;let I=w.update?.sessionUpdate==="runtime_event"?this.adapter.threadId(w.update.event):void 0;if(I!==void 0)try{if(!wn.test(I||"")||f.threadId&&f.threadId!==I)throw q(`${a}_SESSION_MISMATCH`,`${o} \u8FD4\u56DE\u4E86\u4E0D\u540C\u7684\u539F\u751F\u4F1A\u8BDD\uFF0C\u8BF7\u53D1\u9001 /new`);f.threadId=I,h()}catch(_){p=_,i();return}n(w)},y=await r(f.threadId,m,w=>{!p&&f.threadId&&s?.(w)});if(p)throw p;if(!f.threadId)throw q(`${a}_SESSION_MISSING`,`${o} \u6CA1\u6709\u8FD4\u56DE\u539F\u751F\u4F1A\u8BDD\u6807\u8BC6\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C\u5E76\u53D1\u9001 /new`);return y}finally{Ji(u,{recursive:!0})}}};var Un=5e3,io=2*60*1e3,oo=2*60*1e3,ao=12,co=1e3,uo=1500,lo=1e3,fo=/^(?:task|session)-[1-9]\d*(?::[1-9]\d*){4}(?![\s\S])/,zt=24*60*60*1e3,Ot=new Set(["final_answer","final","complete","completed","done"]),po=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"]),ho=new Set(["context_compacted","context_compaction","context_compressed"]);function Wt(e,t){if(e?.pid){if(process.platform==="win32"){let r=["/PID",String(e.pid),"/T"];t==="SIGKILL"&&r.push("/F");try{An("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 Vt(e){Wt(e,"SIGTERM");let t=setTimeout(()=>Wt(e,"SIGKILL"),Un);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 Pn(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 Ln(e,t){e.explicitFileDelivery||Bt(e.artifacts,Ce(t,{source:"codex_cli_image_generation",...e.artifactOptions}))}function kn(e){return et(Ae(e))}function De(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 Ot.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 Sn(e){let t=c(e.terminalProtocol||e.eventProtocol).toLowerCase();if(t)return t;let r=ve(c(e.command)).replace(/\.exe$/i,"").toLowerCase();return r==="codex"||r==="claude"?r:""}function Rn(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 mo(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:Rn("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:Rn("RUNTIME_CLAUDE_RESULT_FAILED",e,"Claude result failed")}:{status:"completed",result:{stopReason:"end_turn",...c(e.result)?{output:c(e.result)}:{}}}}return null}function On(e){return l(e)?c(e.phase||e.status||e.stage).toLowerCase():""}function go(e){if(!l(e)||De(e))return!1;let t=l(e.payload)?e.payload:{},r=c(e.type),n=c(t.type),s=On(t);if(r==="event_msg"&&n==="agent_message"||r==="response_item"&&n==="message"&&c(t.role)==="assistant")return!!(s&&!Ot.has(s));let i=l(e.item)?e.item:{},o=On(i);return c(i.role)==="assistant"||c(i.type)==="message"?!!(o&&!Ot.has(o)):!1}function _o(e,t,r){return r.captureLastMessage===!1||t.includes("--output-last-message")||t.includes("-o")?!1:r.captureLastMessage===!0?!0:ve(e)==="codex"}function yo(e,t){return t.collectCodexTranscriptArtifacts===!1?!1:t.collectCodexTranscriptArtifacts===!0?!0:ve(e)==="codex"}function vn(e){return Math.max(20,S(e.codexTranscriptPollMs||e.transcriptPollMs,co))}function wo(e){return Math.max(0,S(e.codexFinalOutputWaitMs||e.finalOutputWaitMs,uo))}function Xt(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 He(e){let t=l(e?.metadata)?e.metadata:{};return l(t._runtimeBridge)?t._runtimeBridge:{}}function Pe(e){return c(He(e).promptKind).toLowerCase()}function To(e,t){for(let r of[e.codexTranscriptStreaming,e.streamCodexTranscript]){let n=Xt(r);if(n!=null)return n}return Pe(t)==="chat"}function Eo(e,t){let r=He(e);for(let s of[r.emitThoughtChunks,r.streamThoughts]){let i=Xt(s);if(i!=null)return i}let n=Pe(e);if(n&&n!=="chat")return!1;for(let s of[t.emitThoughtChunks,t.streamThoughts]){let i=Xt(s);if(i!=null)return i}return Pe(e)==="chat"}function So(e){let t=He(e);for(let r of[t.finalTextOnly,t.finalOutputOnly]){let n=Xt(r);if(n!=null)return n}return null}function Ro(e,t){let r=So(e);return r??(t.finalTextOnly===!0||t.finalOutputOnly===!0?!0:(t.finalTextOnly===!1||t.finalOutputOnly===!1,!1))}function Oo(e,t){return!e.finalTextOnly||t}function Dn(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 Hn(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 Io(e,t,r,n=new Set){return{target:e,promptText:t,startedAtMs:r,baselinePaths:n,matchedPath:"",disabled:!1,processedLines:new Map}}function Co(e,t){let r=l(e.env)?e.env:{},n=c(e.artifactRoot||e.artifactDir||e.runtimeArtifactRoot||r.ORCHA_RUNTIME_ARTIFACT_DIR)||$(Mn(),"orcha-runtime-artifacts"),s=c(t).replace(/[^A-Za-z0-9._-]+/g,"-").slice(0,80)||pt(),i=$(n,s),o=$(i,pt());return Qi(o,{recursive:!0}),{root:o,realRoot:It(o),sessionRoot:i,realSessionRoot:It(i)}}function Ao(e){let t=c(e?.artifactDirectory);if(!t)throw new Error("sandbox launch did not provide an artifact directory");return{root:t,realRoot:It(t),sessionRoot:"",realSessionRoot:""}}function $n(e){return c(l(e)?e.root:e)}function In(e){let t=$n(e),r=c(l(e)?e.sessionRoot:so(t)),n=c(l(e)?e.realSessionRoot:"");if(r)try{if(n&&It(r)!==n)return;to(r)}catch{}}function xo(e,t={}){let r=$n(e),n=c(l(e)?e.realRoot:"");if(r){try{if(n&&It(r)!==n){g("warn","runtime.cli","runtime artifact directory cleanup skipped; path changed",{...t,artifactRoot:r});return}}catch{In(e);return}try{Zi(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}In(e)}}function No(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 $e(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)||$(no(),".codex");return $(n,"sessions")}function bo(e,t){let r=new Date(t),n=String(r.getFullYear()),s=String(r.getMonth()+1).padStart(2,"0"),i=String(r.getDate()).padStart(2,"0");return $(e,n,s,i)}function Fn(e,t,r){let n=new Set;for(let s of[t-zt,t,t+zt,r-zt,r,r+zt])n.add(bo(e,s));return[...n].filter(s=>xn(s))}function Mo(e,t,r){let n=$e(e),s=t-io,i=r+oo,o=[];for(let a of Fn(n,t,r)){let u=[];try{u=Nn(a)}catch{continue}for(let d of u){if(!d.endsWith(".jsonl"))continue;let f=$(a,d);try{let h=eo(f);if(!h.isFile()||h.mtimeMs<s||h.mtimeMs>i)continue;o.push({path:f,mtimeMs:h.mtimeMs})}catch{}}}return o.sort((a,u)=>u.mtimeMs-a.mtimeMs).slice(0,ao)}function Uo(e,t,r=t){let n=$e(e),s=new Set;for(let i of Fn(n,t,r)){let o=[];try{o=Nn(i)}catch{continue}for(let a of o)a.endsWith(".jsonl")&&s.add($(i,a))}return s}function Le(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)Le(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&&Le(e[n],t,r+1)}}function Bn(e){return c(e).replace(/\s+/g," ")}function Po(e){let t=Bn(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 Lo(e,t){let r=Po(t);if(!r.length)return!1;let n=[];for(let i of e)Le(i,n);let s=Bn(n.join(" "));return r.every(i=>s.includes(i))}function ko(e){return e.find(t=>l(t)&&c(t.type)==="session_meta"&&l(t.payload))||null}function vo(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 Do(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 Ho(e,t,r){if(!Lo(e,t.promptText))return!1;let n=ko(e);if(!n)return!1;let s=n.payload;if(!Do(s))return!1;let i=vo(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&&En(o)!==En(a))}function Cn(e){try{return Fo(bn(e,"utf8"))}catch{return null}}function $o(e,t,r){if(!e||e.disabled)return null;if(e.matchedPath){let s=Cn(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=Cn(s.path);!i||!Ho(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 Fo(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 Bo(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 jo(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return c(e.type)==="response_item"&&po.has(c(t.type))}function qo(e){if(!l(e))return!1;let t=l(e.payload)?e.payload:{};return ho.has(c(t.type))}function Go(e,t,r,n){let s=Pn(e),i=De(e),o=0,a=0,u=0;if(s&&!i&&t.emitThoughtChunks&&Hn(t,r,n,s)&&(u=1),s&&i){let d=t.emittedTexts.size?`
|
|
16
|
+
|
|
17
|
+
${s}`:s;Dn(t,r,n,d,s)&&(o=1,a=1)}return s&&i&&(t.finalTextSeen=!0),Ln(t,e),(Bo(e)||jo(e)||qo(e)||i)&&n({sessionId:r,update:{sessionUpdate:"runtime_event",event:kn(e)}}),{textCount:o,finalTextCount:a,thoughtCount:u}}function ke(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=$o(t,r,s);if(f){let h=Math.min(t.processedLines.get(f.path)||0,f.events.length),p=e.artifacts.size;for(let m of f.events.slice(h)){let y=Go(m,e,r,n);a+=y.textCount,u+=y.finalTextCount,d+=y.thoughtCount}t.processedLines.set(f.path,f.events.length),(f.events.length>h||e.artifacts.size>p)&&(o=1)}return{artifactCount:e.artifacts.size-i,transcriptCount:o,textCount:a,finalTextCount:u,thoughtCount:d}}function Ko(e,{remove:t=!0}={}){if(!e||!xn(e))return"";try{return bn(e,"utf8").trim()}catch{return""}finally{t&&Jt(e)}}function Jt(e){if(e)try{ro(e)}catch{}}function zo(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 Vo(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 Wo(e,t,r,n,s,i){let o=ke(e,t,r,n,Date.now()),a=()=>Jo(e,r,n,Ko(s,{remove:!1}));if(a()||e.finalTextSeen)return Jt(s),o;let u=wo(i);if(u<=0||!t&&!s)return Jt(s),o;let d=Date.now()+u,f=Math.min(vn(i),100);for(;!e.finalTextSeen&&Date.now()<d&&(await Vo(Math.min(f,Math.max(0,d-Date.now()))),o=zo(o,ke(e,t,r,n,Date.now())),!a()););return Jt(s),o}var Yt=class{constructor(t,r,n={}){this.agent=t,this.target=r,this.options=n,this.active=new Map;let s=Sn(r);if(this.adapter=Object.hasOwn(ot,s)?ot[s]:null,n.source==="ai_chat_runtime_node"&&this.adapter){let{label:i}=this.adapter;if(typeof n.cloudSessionId!="string"||!fo.test(n.cloudSessionId))throw Object.assign(new Error(`${i} \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(`${i} \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(`${i} \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(s,[n.orchaUrl,t.agentId,t.targetCode,n.cloudSessionId,rt(r,t.workspace),r.command,this.adapter.home(r)])}}async sessionNew(t={}){let r=t.mcpServers||[];if(r.length&&(t.metadata?.source==="conversation_delegation"||this.nativeSession)&&this.adapter){if(this.options.prepareLaunch)throw Object.assign(new Error(`${this.adapter.label} 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 Tn(this.adapter,r,()=>({cwd:this.deliveryCwd,roots:[...this.deliveryRoots||[],...this.deliveryThreadId?[$($e(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}-${pt()}`}}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)||pt(),u=vt(t.prompt),d=c(this.target.promptMode||"stdin"),f=this.buildArgs(d,u),h=[...this.taskMcp?.args||[],...this.nativeSession?this.adapter.resumeArgs(f,s):f],p=rt(this.target,this.agent.workspace),m=typeof this.options.prepareLaunch=="function",w=_o(o,h,this.target)?m?`/tmp/orcha-runtime-last-message-${pt()}.txt`:$(Mn(),`orcha-runtime-last-message-${pt()}.txt`):"";w&&h.push("--output-last-message",w);let I={...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:h,cwd:p,environment:I}):{command:o,args:h,cwd:p,environment:{...process.env,...I},cleanup:async()=>{}},T=m?Ao(_):Co(this.target,a),E=T.root,R=No(this.target,E,_);this.deliveryCwd=p,this.deliveryRoots=[p,...R.trustedFileRoots].filter(Boolean),this.deliveryThreadId=s||null;let N=yo(o,this.target),M={...this.target,targetCode:this.agent.targetCode,cwd:p,...m?{codexHome:$(_.homeDirectory,".codex")}:{}},D=N?Uo(M,i):new Set,Z=m&&w?$(_.tempDirectory,w.slice(5)):w,V=S(this.target.timeoutMs||this.target.sessionPromptTimeoutMs,S(this.options.sessionPromptTimeoutMs,Y));m||(_.environment.ORCHA_RUNTIME_ARTIFACT_DIR=E);let C=An(_.command,_.args,{cwd:_.cwd,env:_.environment,stdio:["pipe","pipe","pipe"],detached:process.platform!=="win32",windowsHide:!0});this.active.set(a,C),g("info","runtime.cli","runtime prompt started",{target:this.agent.targetCode,sessionId:a,pid:C.pid,timeoutMs:V,isolation:_.isolation});let xr="",fe=c(this.target.outputMode||"text"),U={explicitFileDelivery:this.explicitFileDelivery,artifacts:new Map,emittedTexts:new Set,emittedThoughtTexts:new Set,value:"",artifactOptions:R,finalTextSeen:!1,finalTextOnly:Ro(t,this.target),emitThoughtChunks:Eo(t,this.target),terminalOutcome:null,terminalProtocol:Sn(this.target),emitTerminal:null,progress:{}},pe=N?Io(M,u,i,D):null;return C.stdout.setEncoding("utf8"),C.stdout.on("data",dt=>this.handleStdout(dt,fe,U,a,r)),C.stderr.setEncoding("utf8"),C.stderr.on("data",dt=>{xr+=dt,this.target.emitStderr===!0&&r({sessionId:a,update:{sessionUpdate:"runtime_stderr_chunk",content:{type:"text",text:dt}}})}),d==="stdin"?C.stdin.end(u):C.stdin.end(),await new Promise((dt,he)=>{let yt=!1,Nr=!1,Mt=null,wt=null,me=pe&&To(this.target,t)?setInterval(()=>{try{ke(U,pe,a,r)}catch(A){g("warn","runtime.cli","codex transcript stream poll failed",{target:this.agent.targetCode,sessionId:a,error:String(A?.message||A)})}},vn(this.target)):null;me?.unref?.();let br=setTimeout(()=>{Nr=!0,g("warn","runtime.cli","runtime prompt timed out; terminating child",{target:this.agent.targetCode,sessionId:a,pid:C.pid,timeoutMs:V}),Wt(C,"SIGTERM"),Mt=setTimeout(()=>{g("warn","runtime.cli","runtime prompt force killing child",{target:this.agent.targetCode,sessionId:a,pid:C.pid}),Wt(C,"SIGKILL")},Un),Mt.unref?.(),Tt(Object.assign(new Error(`runtime CLI timed out after ${V}ms`),{code:"RUNTIME_CLI_TIMEOUT"}))},V);br.unref?.();let Mr=async()=>{clearTimeout(br),wt&&clearTimeout(wt),me&&clearInterval(me),Mt&&!Nr&&clearTimeout(Mt),xo(T,{target:this.agent.targetCode,sessionId:a}),this.active.delete(a),U.emitTerminal=null,await _.cleanup?.()},xs=A=>{yt||(yt=!0,Mr().then(()=>dt(A),he))},Tt=A=>{yt||(yt=!0,Mr().then(()=>he(A),B=>{g("warn","runtime.cli","sandbox launch cleanup failed",{target:this.agent.targetCode,sessionId:a,error:String(B?.message||B)}),he(A)}))};U.emitTerminal=A=>{let B={...l(A.result)?A.result:{},_artifacts:[...U.artifacts.values()]};try{n?.({...A,result:B})}catch(tt){g("warn","runtime.cli","runtime terminal listener failed",{target:this.agent.targetCode,sessionId:a,error:String(tt?.message||tt)})}let F=Math.max(0,S(this.target.terminalExitGraceMs,lo));wt=setTimeout(()=>{wt=null,!(yt||this.active.get(a)!==C)&&(g("warn","runtime.cli","runtime stayed alive after terminal event; terminating child",{target:this.agent.targetCode,sessionId:a,pid:C.pid,terminalProtocol:U.terminalProtocol,graceMs:F}),Vt(C))},F),wt.unref?.()},C.on("error",A=>{g("warn","runtime.cli","runtime child error",{target:this.agent.targetCode,sessionId:a,pid:C.pid,error:String(A?.message||A)}),Tt(A)}),C.on("exit",(A,B)=>{(async()=>{fe==="json-lines"&&U.value.trim()&&this.handleStdout(`
|
|
18
|
+
`,fe,U,a,r);let F=await Wo(U,pe,a,r,Z,this.target);(F.artifactCount>0||F.textCount>0||F.thoughtCount>0)&&g("info","runtime.cli","codex transcript updates collected",{target:this.agent.targetCode,sessionId:a,artifactCount:F.artifactCount,textCount:F.textCount,finalTextCount:F.finalTextCount,thoughtCount:F.thoughtCount,transcriptCount:F.transcriptCount});let tt=xr.trim();if(tt&&g("debug","runtime.cli","runtime stderr",{target:this.agent.targetCode,sessionId:a,stderr:tt}),g("info","runtime.cli","runtime prompt finished",{target:this.agent.targetCode,sessionId:a,pid:C.pid,exitCode:A,signal:B,artifactCount:U.artifacts.size,finalTextSeen:U.finalTextSeen}),U.terminalOutcome?.status==="failed"){Tt(U.terminalOutcome.error);return}if(A!==0&&U.terminalOutcome?.status!=="completed"){let Ns=Object.assign(new Error(`runtime CLI exited with code ${A??"unknown"}${B?` (${B})`:""}`),{code:"RUNTIME_CLI_EXIT_NONZERO",exitCode:A,signal:B});Tt(Ns);return}xs({stopReason:"end_turn",exitCode:A,signal:B,_artifacts:[...U.artifacts.values()],...tt?{stderr:tt}:{}})})().catch(Tt)})})}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);let f=this.taskMcp&&this.adapter?.taskMcpError?.(d);if(f){n.terminalOutcome||(n.terminalOutcome={status:"failed",error:f},n.emitTerminal?.(n.terminalOutcome)),Vt(this.active.get(s));continue}Ln(n,d);let h=this.adapter?.progress?.(d,n.progress,n.emitThoughtChunks);for(let w of h||[{sessionUpdate:"runtime_event",event:kn(d)}])i({sessionId:s,update:w});let p=Pn(d),m=De(d);p&&n.emitThoughtChunks&&!m&&go(d)?Hn(n,s,i,p):p&&Oo(n,m)&&Dn(n,s,i,p),p&&m&&(n.finalTextSeen=!0);let y=mo(d,n.terminalProtocol);y&&!n.terminalOutcome&&(y.status==="failed"||n.finalTextSeen||n.artifacts.size>0)&&(n.terminalOutcome=y,n.emitTerminal?.(y))}catch{i({sessionId:s,update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:`${a}
|
|
19
|
+
`}}})}}}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}),Vt(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}),Vt(n);this.active.clear(),await this.taskMcp?.close(),this.taskMcp=null}};var Fe="ORCHA_RUNTIME_OUTPUT_START",Be="ORCHA_RUNTIME_OUTPUT_END",je="ORCHA_RUNTIME_CONTROL_START",qe="ORCHA_RUNTIME_CONTROL_END",Ge=Fe,Ke=Be,ze=je,Ve=qe,Je=[Fe,Be,je,qe],Xo=new Set(["_artifacts","_decision","_meta"]),Yo=new RegExp(`(?:^|(?<=[\\r\\n]))[ \\t]*(?<marker>${Je.join("|")})[ \\t]*(?=\\r\\n?|\\n|$)`,"g"),k=class extends Error{constructor(t,r,n){super(r),this.name="RuntimeResultProtocolError",this.code=t,this.detail={rawOutput:n}}};function qn(e){let t=typeof e=="string"?e.trimStart():"";return Je.some(r=>t.startsWith(r))}function We(e){if(typeof e!="string")return null;let t=e,r=Qo(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 k("invalid_markers",`Runtime Result \u534F\u8BAE\u6807\u8BB0\u4E0D\u5B8C\u6574\uFF1A${m.join("\uFF1B")}`,t)}let i=r.get(Fe)[0],o=r.get(Be)[0],a=r.get(je)[0],u=r.get(qe)[0];if(!(i.end<=o.start&&o.end<=a.start&&a.end<=u.start))throw new k("invalid_marker_order","Runtime Result \u534F\u8BAE\u6807\u8BB0\u987A\u5E8F\u9519\u8BEF\uFF1A\u5FC5\u987B\u5148\u8F93\u51FA OUTPUT \u5757\uFF0C\u518D\u8F93\u51FA CONTROL \u5757",t);let d=Zo(t.slice(i.end,o.start));if(!d.trim())throw new k("empty_output","Runtime Result OUTPUT \u5757\u4E0D\u80FD\u4E3A\u7A7A",t);let f=t.slice(a.end,u.start).trim();if(!f)throw new k("empty_control","Runtime Result CONTROL \u5757\u4E0D\u80FD\u4E3A\u7A7A",t);let h;try{h=JSON.parse(f)}catch(m){throw new k("invalid_control_json",`Runtime Result CONTROL \u5757\u4E0D\u662F\u5408\u6CD5 JSON\uFF1A${String(m?.message||m)}`,t)}if(!jn(h))throw new k("invalid_control_type","Runtime Result CONTROL \u5757\u5FC5\u987B\u662F JSON \u5BF9\u8C61",t);let p=Object.keys(h).filter(m=>!Xo.has(m)).sort();if(p.length>0)throw new k("invalid_control_keys",`Runtime Result CONTROL \u5757\u5305\u542B\u975E\u6807\u51C6\u5B57\u6BB5\uFF1A${p.join(", ")}`,t);if("_artifacts"in h&&!Array.isArray(h._artifacts))throw new k("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 h&&!jn(h[m]))throw new k("invalid_control_field_type",`Runtime Result CONTROL \u5757\u7684 ${m} \u5FC5\u987B\u662F JSON \u5BF9\u8C61`,t);return{output:d,...h}}function Qo(e){let t=new Map(Je.map(r=>[r,[]]));for(let r of e.matchAll(Yo))t.get(r.groups.marker).push({start:r.index,end:r.index+r[0].length});return t}function Zo(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 jn(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}import{createHash as ta}from"node:crypto";var ea="orcha.goal-contract/v1",ra=new Set(["complete","completed","done","ok","passed","success","succeeded"]),na=new Set(["aborted","blocked","cancelled","canceled","denied","error","failed","failure","timeout","timed_out"]),sa=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 Ze(e){return ta("sha256").update(G(e)).digest("hex")}function Kn(e){if(!Vn(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(`
|
|
20
|
+
`)}function zn(e,t,r=""){if(!Vn(e))return e==null?null:{required:!0,status:"failed",outcome:c(e?.outcome),goalContractHash:"",checks:[],errorCode:"invalid_goal_contract"};let n=Ze(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=ia(t),o=e.verificationPlan.checks.map(u=>fa(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 Vn(e){if(!l(e)||e.schemaVersion!==ea||!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 ia(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"){oa(s.event,t,r);continue}if(i==="tool_call"){let o=Zt(s)||`tool-${r.length+1}`,a=Qt(t,r,o),u=Ye(s,s.name||s.toolName||s.kind);a.toolName=u.toolName,a.arguments=u.arguments,a.status=Ct(s.status),a.evidence=ee(s);continue}if(i==="tool_call_update"){let o=Zt(s);if(!o)continue;let a=Qt(t,r,o),u=Ye(s,s.name||s.toolName||s.kind);a.toolName||=u.toolName,Object.keys(a.arguments).length===0&&(a.arguments=u.arguments),a.status=Ct(s.status),a.evidence.push(...ee(s))}}return r}function oa(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=Zt(n)||`runtime-${r.length+1}`,u=Qt(t,r,a),d=Ye(n,n.name||n.tool||s,s);u.toolName=d.toolName,u.arguments=d.arguments,u.status=Ct(n.status),u.evidence.push(...ee(n));return}if(!["function_call_output","custom_tool_call_output","local_shell_call_output","mcp_tool_call_output"].includes(s))return;let i=Zt(n);if(!i)return;let o=Qt(t,r,i);o.status=la(n,o.toolName),o.evidence.push(...ee(n))}function Qt(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 aa(e){let t=c(e).toLowerCase();return sa.get(t)||t}function Ye(e,t,r=""){let n=ca(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:aa(t),arguments:n}}function Zt(e){return l(e)?c(e.call_id||e.callId||e.toolCallId||e.id):""}function ca(e){if(!l(e))return{};for(let r of["arguments","args","rawInput","input","params","parameters"]){let n=ua(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 ua(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 la(e,t){if(!l(e))return"unknown";let r=te(e,0,{parseCliExitCode:t==="run_command"||t==="apply_patch"});return r.includes("failed")?"failed":r.includes("success")?"success":"unknown"}function te(e,t=0,r={}){if(t>8||e===null||e===void 0)return[];if(typeof e=="string")return da(e,t,r);if(Array.isArray(e))return e.flatMap(o=>te(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=Ct(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(...te(e[o],t+1,r));return n}function da(e,t,r){let n=e.trim();if(!n)return[];try{return te(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 Ct(e){let t=c(e).toLowerCase();return ra.has(t)?"success":na.has(t)?"failed":"unknown"}function ee(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:Ct(i.status??(i.passed===!0?"passed":i.passed===!1?"failed":"")),...c(i.message)?{message:c(i.message)}:{}});return n}function fa(e,t){let r=t.filter(o=>e.toolNames.includes(o.toolName)&&Qe(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 Xe(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?Xe(e,"failed",i,"Runtime tool evidence failed."):Xe(e,"missing",s,`Only ${s.length}/${e.requiredMatches} required tool executions passed.`)}function Xe(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 Qe(e,t){return Array.isArray(e)?Array.isArray(t)&&e.length===t.length&&e.every((r,n)=>Qe(r,t[n])):l(e)?l(t)?Object.entries(e).every(([r,n])=>Object.hasOwn(t,r)&&Qe(n,t[r])):!1:Object.is(e,t)}function G(e){if(e===null||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="string")return Gn(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 G(e[r])}).join(",")}]`;if(l(e))return`{${Object.keys(e).sort().map(t=>`${Gn(t)}:${G(e[t])}`).join(",")}}`;throw new Error("invalid_jcs_json_value")}function Gn(e){return pa(e),JSON.stringify(e)}function pa(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 ha}from"node:child_process";import{createHash as ma,randomUUID as ga}from"node:crypto";import{constants as _a}from"node:fs";import{access as ya,mkdir as tr,readdir as wa,realpath as At,rm as Ta,stat as Ea}from"node:fs/promises";import Sa from"node:http";import{tmpdir as Ra}from"node:os";import{isAbsolute as xt,join as ht,relative as Jn,resolve as rr}from"node:path";var nr=1,Oa="orcha.process-isolation/v1",sr="orcha.egress-proxy/v1",Ia="--disable-wasm-trap-handler",re={read_only:0,workspace_write:1,workspace_network:2},er={read_only:["read_only","denied"],workspace_write:["workspace_write","denied"],workspace_network:["workspace_write","restricted"]},Ca=new Set([".env",".git-credentials",".netrc",".npmrc",".pypirc","credentials.json","secrets.json","id_rsa","id_ed25519"]);function at(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 er)||!(n in er))throw O("RUNTIME_SANDBOX_POLICY_INVALID","unsupported runtime access mode");if(re[r]>re[n])throw O("RUNTIME_SANDBOX_POLICY_INVALID","access mode exceeds its ceiling");let[s,i]=er[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)!==nr||!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 Wn(e,t){let r=at(e),n=at(t);return re[n.accessMode]<re[r.accessMode]}async function Xn(e){if(!e.sandboxRequired)return{dispatchable:!0,enforced:!1,backend:"direct",daemonStatus:"not_required",daemonProtocolVersion:"",policySchemaVersions:[nr],runtimePolicyUpdates:!1,workspaceSync:!1,egressProxy:!1,reason:"external_runtime_sandbox_not_required"};let t=await Qn(e.sandboxBrokerCommand,process.env.PATH||"");if(!t)throw O("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let r=await Ma(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 La(e),{dispatchable:!0,enforced:!0,backend:c(r.backend),daemonStatus:"ok",daemonProtocolVersion:c(r.protocolVersion||"orcha.runtime-sandbox-broker/v1"),policySchemaVersions:[nr],runtimePolicyUpdates:!0,workspaceSync:!1,egressProxy:e.egressProxyRequired}}async function ir(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 At(i);if(!(await Ea(o)).isDirectory())throw O("RUNTIME_WORKSPACE_INVALID","runtime workspace is not a directory");if(!(e.trustedWorkspaceRoots.length?await Promise.all(e.trustedWorkspaceRoots.map(d=>At(d))):[o]).some(d=>ar(d,o)))throw O("RUNTIME_WORKSPACE_OUTSIDE_TRUSTED_ROOT","runtime workspace is outside trusted roots");return o}async function Yn({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=at(d),h=await ir(e,t,s),p=await At(s);if(!ar(h,p))throw O("RUNTIME_WORKSPACE_CWD_INVALID","runtime cwd is outside its workspace");let m=await Qn(e.sandboxBrokerCommand,process.env.PATH||"");if(!m)throw O("RUNTIME_SANDBOX_UNAVAILABLE","sandbox broker is not executable");let y=`runtime-${ma("sha256").update(String(o)).digest("hex").slice(0,32)}`,w=rr(e.sandboxTempRoot||ht(Ra(),"orcha-runtime-sandboxes"));await tr(w,{recursive:!0,mode:448});let I=ht(w,`${y}-${ga()}`),_=ht(I,"home"),T=ht(I,"artifacts");await tr(_,{recursive:!0,mode:448}),await tr(T,{recursive:!0,mode:448});let E=f.networkMode==="restricted"?await Ua(e,{runId:String(o),instanceId:y,policyRevision:Number(f.policyRevision),ttlMs:Math.min(S(f.maxRuntimeSeconds,900)*1e3,e.egressGrantMaxTtlMs),maxTransferBytes:S(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",...xa(t,i)};R.HOME="/tmp/home",R.TMPDIR="/tmp",R.ORCHA_RUNTIME_ARTIFACT_DIR="/tmp/artifacts",R.NODE_OPTIONS=Ia;let N={schemaVersion:Oa,runId:String(o),instanceId:y,workspace:h,cwd:p,filesystemMode:f.filesystemMode,networkMode:f.networkMode,environmentMode:"allowlist",deniedRelativePaths:await Na(h),temporaryDirectory:I,egressProxy:E,environment:R,resourceLimits:ba(f),readOnlyToolchainRoots:await Aa(e,t)},M=!1,D=async()=>{if(!M){M=!0;try{E&&await Pa(e,E,{runId:String(o),instanceId:y})}finally{await Ta(I,{recursive:!0,force:!0})}}};return{command:m,args:[...b(e.sandboxBrokerArguments),"--",r,...n],cwd:p,environment:{PATH:process.env.PATH||"",LANG:process.env.LANG||"C.UTF-8",ORCHA_PROCESS_ISOLATION_REQUEST:JSON.stringify(N)},tempDirectory:I,homeDirectory:_,artifactDirectory:T,pathMappings:[{runtimeRoot:"/tmp/artifacts",hostRoot:T},{runtimeRoot:"/tmp/home",hostRoot:_}],isolation:{enforced:!0,backend:"broker",instanceId:y,policyRevision:f.policyRevision},cleanup:D}}async function Aa(e,t){let r=b(t.toolchainRoots||t.sandboxToolchainRoots);if(!r.length)return[];let n=await Promise.all(b(e.trustedToolchainRoots).map(i=>At(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 At(i);if(!n.some(a=>ar(a,o)))throw O("RUNTIME_TOOLCHAIN_ROOT_NOT_TRUSTED","toolchain root is outside trusted roots");s.push(o)}return[...new Set(s)]}function xa(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 Na(e){let t=[],r=0,n=async s=>{let i;try{i=await wa(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=ht(s,o.name),u=Jn(e,a),d=o.name.toLowerCase();(Ca.has(d)||d.startsWith(".env."))&&t.push(u),o.isDirectory()&&!o.isSymbolicLink()&&await n(a)}};return await n(e),t.sort()}function ba(e){return{maxCpuSeconds:Math.max(1,S(e.maxRuntimeSeconds,900)),maxMemoryBytes:S(e.maxMemoryBytes,2*1024*1024*1024),maxProcesses:S(e.maxProcesses,128),maxOpenFiles:S(e.maxOpenFiles,1024),maxFileBytes:S(e.maxFileBytes,64*1024*1024)}}async function Ma(e,t,r){return await new Promise((n,s)=>{let i=ha(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 Qn(e,t){let r=c(e);if(!r)return"";let n=xt(r)?[r]:String(t||"").split(":").filter(Boolean).map(s=>ht(s,r));for(let s of n)try{return await ya(s,_a.X_OK),s}catch{}return""}async function Ua(e,t){if(!e.egressProxyRequired)throw O("RUNTIME_EGRESS_UNAVAILABLE","restricted network requires the Egress Proxy");let r=await or(e,"POST","/v1/grants",{protocolVersion:sr,...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 Pa(e,t,r){await or(e,"POST",`/v1/grants/${encodeURIComponent(t.grantId)}/revoke`,{protocolVersion:sr,...r}).catch(()=>{})}async function La(e){let t=await or(e,"GET","/health");if(t.status!=="ok"||t.proxy!=="orcha-egress-proxy"||t.protocolVersion!==sr)throw O("RUNTIME_EGRESS_UNAVAILABLE","Egress Proxy is unavailable or incompatible")}async function or(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=Sa.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 ar(e,t){let r=Jn(rr(e),rr(t));return r===""||!r.startsWith("..")&&!xt(r)}function O(e,t){return Object.assign(new Error(t),{code:e})}var cr=24e3,ur=8,lr=50,dr=6e3,va=new Set(["fail","failed","failure","error","errored","timeout","timed_out","cancelled","canceled","aborted"]),Da=10*60*1e3,Ha=60*1e3,$a=8,Fa=30*60*1e3,Ba=60*1e3,ja=1,rs=2400,qa=new Set(["max_tokens","max_output_tokens","length"]),Ga=new Set(["agent_message_chunk","tool_call","tool_call_update"]),Ka=new Set(["agentId","taskId","executionId","sessionId","nodeId","targetCode","framework","workspace","instructions"]),za=/(^|[_-])(token|secret|password|authorization|api[-_]?key|private[-_]?key|credential|cookie|jwt|access[-_]?token|refresh[-_]?token|service[-_]?token|execution[-_]?token)([_-]|$)/i;function Va(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(Va).sort((t,r)=>{let n=G(t),s=G(r);return n<s?-1:n>s?1:0})}function Wa(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 Xa(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:se()}}}function v(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 ns(e){let t=c(e).toLowerCase().replace(/[.。!!]+$/g,"").replace(/[\s-]+/g,"_");return va.has(t)}function Q(e,t){let r=S(e,t);return Number.isFinite(r)&&r>0?r:t}function Nt(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 z(e){return c(e?.type||"echo")}function ss(e){let t=z(e);return t==="acp"||t==="stdio-acp"||t==="openclaw"}function hr(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 Ya(e){let t=String(e||"");if(za.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 mr(e,t=0){if(e==null||typeof e=="number"||typeof e=="boolean")return e;if(typeof e=="string"){if(e.length<=dr)return e;let r=e.length-dr;return`${e.slice(0,dr)}... [truncated ${r} characters]`}if(t>=ur)return Array.isArray(e)?`[array truncated at depth ${ur}, items=${e.length}]`:l(e)?`[object truncated at depth ${ur}, keys=${Object.keys(e).length}]`:String(e);if(Array.isArray(e)){let r=e.slice(0,lr).map(n=>mr(n,t+1));return e.length>lr&&r.push(`[truncated ${e.length-lr} items]`),r}if(l(e)){let r={};for(let[n,s]of Object.entries(e))r[n]=Ya(n)?"[REDACTED]":mr(s,t+1);return r}return String(e)}var Qa=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 Za(e){if(!l(e))return e;let t={};for(let r of Qa)v(e[r])&&(t[r]=e[r]);return t}function tc(e){if(!l(e))return e;let t={...e};return l(t.renderedPayload)&&(t.renderedPayload=Za(t.renderedPayload)),t}function ec(e){let t=l(e)?e:{},r={};v(t.metadata)&&(r.metadata=tc(t.metadata));for(let[n,s]of Object.entries(t))Ka.has(n)||n==="metadata"||v(s)&&(r[n]=s);return r}function rc(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 is(e){return c(rc(e).kind).toLowerCase()==="decision"}function nc(e){return e?.dispatchFinalTextOnly===!0||e?.dispatchFinalOutputOnly===!0?!0:e?.dispatchFinalTextOnly===!1||e?.dispatchFinalOutputOnly===!1?!1:z(e)==="cli"}function Zn(e){let t=e?.dispatchReleaseAfterPrompt??e?.dispatchDisposeAfterPrompt;return Nt(t,ss(e))}function sc(e,t){let r=l(e?.metadata)?{...e.metadata}:{},n=l(r._runtimeBridge)?{...r._runtimeBridge}:{},s=hr(n);return r._runtimeBridge={...n,promptKind:"dispatch",finalTextOnly:nc(t),releaseAfterPrompt:s===void 0?Zn(t):Nt(s,Zn(t)),requiresRuntimeResult:is(e)},r}function ic(e){let t=ec(e);if(!v(t))return"";let r=JSON.stringify(mr(t),null,2);if(r.length<=cr)return r;let n=r.length-cr;return`${r.slice(0,cr)}
|
|
21
|
+
... [truncated ${n} characters]`}function _r(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 gr(e){if(!l(e))return"";let t=l(e.update)?e.update:e;return c(t.sessionUpdate)}function yr(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=gr(a),d=_r(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 mt(s);let o=n[n.length-1]||[];return mt(o)}function oc(e){return Array.isArray(e)?e.map(_r).filter(t=>t!==""):[]}function ie(e){return Array.isArray(e)?e.some(r=>gr(r))?e.filter(r=>Ga.has(gr(r))).map(_r).filter(r=>r!==""):oc(e):[]}function ac(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 cc(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 uc(e){if(!Array.isArray(e))return"";for(let t=e.length-1;t>=0;t-=1){let r=cc(ac(e[t]));if(r)return r}return""}function mt(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=qn(n)&&!/[\r\n]$/.test(t)?`
|
|
22
|
+
`:"";t+=`${s}${n}`}}return t.trim()}function lc(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]===`
|
|
23
|
+
`?1:0)).trim()}function ts(e){let t=String(e||"").trim();if(!t)return null;try{let r=JSON.parse(t);if(l(r)&&(os(r)||v(r._artifacts)||v(r.artifacts)||v(r._decision)||v(r._meta)))return r}catch{}return null}function bt(e){try{return We(e)}catch{return null}}function ne(...e){let t=null;for(let r of e)try{if(We(r))return}catch(n){t||=n}if(t)throw t}function fr(e){let t=String(e||"").trim();if(!t)return null;let r=bt(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=ts(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=ts(t.slice(s));if(i)return i}return null}function dc(e){let t=bt(yr(e));if(t)return t;let r=ie(e);for(let n=r.length-1;n>=0;n-=1){let s=bt(r[n]);if(s)return s}return bt(mt(r))}function os(e){if(!l(e))return!1;if(v(e.output))return!0;for(let t of["content","text","message","summary"])if(c(e[t]))return!0;return!!(ns(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 fc(e){return l(e)?typeof(l(e._decision)?e._decision:l(e.decision)?e.decision:e).passed=="boolean":!1}function as(e){return l(e)?l(e._decision)&&typeof e._decision.passed=="boolean"?!0:fc(e.output):!1}function pr(e,t,r){let n=l(e)?{...e}:{};if(!v(n.output)){for(let s of["summary","message","content","text"])if(c(n[s])){n.output=c(n[s]);break}}return!v(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 pc=["dataUrl","dataURL","contentDataUrl","contentDataURL","contentBase64","base64","data"];function es(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 hc(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 pc)v(e[i])&&(s[i]=e[i]),v(r[i])&&(s.content[i]=r[i]);return s}function cs(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=es(r[a]),d=i.get(u)||[];d.push(a),i.set(u,d)}let o=new Map;for(let a of n){let u=es(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]=hc(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=cs(e._artifacts,t._artifacts)),n}function us(e,t,r={}){let n=c(r.promptKind),s=r.requiresRuntimeResult===!0,i=s||n==="dispatch",o=j(e),a=typeof o.output=="string"?bt(o.output):null;if(a)return K(o,j(a),"result_block");let u=uc(t),d=u?fr(u):null,f=i?dc(t):null;if(os(o))return ns(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||as(o)?o:d?K(o,j(d),"final_event"):f?K(o,j(f),"updates"):(ne(o.output,u,mt(ie(t))),pr(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?(ne(u,mt(ie(t))),pr(o,"final_event",u)):{...o,output:u,_meta:{...l(o._meta)?o._meta:{},runtimeOutputSource:"final_event"}};let h=yr(t),p=fr(h);if(p)return K(o,j(p),"updates");let m=lc(h);if(!m)return s&&ne(mt(ie(t))),o;let y=fr(m);return y?K(o,j(y),"updates"):s?(ne(h,m),pr(o,"updates",m)):{...o,output:m,_meta:{...l(o._meta)?o._meta:{},runtimeOutputSource:"updates"}}}function wr(e){return l(e)?c(e.stopReason||e.stop_reason).toLowerCase():""}function ls(e){return qa.has(wr(e))}function mc(e,t,r){if(r.promptKind!=="dispatch"||r.requiresRuntimeResult!==!0||!ls(e))return!1;try{return!as(us(e,t,r))}catch{return!0}}function gc(){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 ${rs} Unicode characters.`,`Output ${Ge}, ${Ke}, ${ze}, and ${Ve} 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(`
|
|
24
|
+
`)}function _c(e,t){let r=l(t)?{...t}:{},n=cs(e?._artifacts,t?._artifacts);return n.length>0&&(r._artifacts=n),r}function yc(e,t){return{...e,_meta:{...l(e?._meta)?e._meta:{},runtimeProtocolRetry:{attempted:!0,recovered:!0,reason:wr(t)||"max_tokens"}}}}function wc(e,t){let r=typeof e?.output=="string"?e.output:yr(t),n=new k("runtime_output_truncated","Runtime Result \u8FBE\u5230\u6700\u5927\u8F93\u51FA\u957F\u5EA6\uFF0C\u7D27\u51D1\u91CD\u8BD5\u540E\u4ECD\u672A\u5B8C\u6574\u8FD4\u56DE",r);return n.detail={...n.detail,stopReason:wr(e)||"max_tokens",retryAttempted:!0},n}var oe=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=Et(),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 Xn(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)?Ze(t.goalContract):c(t.goalContractHash),i=ka("sha256").update(G({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:us(i,o,u),f=zn(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=Q(this.config.operationTtlMs,Fa);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=z(t)==="openclaw"?Q(this.config.openClawSessionIdleTtlMs,Ba):Q(this.config.sessionIdleTtlMs,Da);return Q(t?.sessionIdleTtlMs??t?.idleTtlMs,n)}targetMaxSessions(t){let n=z(t)==="openclaw"?Q(this.config.openClawMaxSessions,ja):Q(this.config.maxSessionsPerTarget,$a);return Q(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=z(t),s=l(r?._runtimeBridge)?r._runtimeBridge:{},i=hr(s);return i!==void 0?Nt(i,!1):Nt(t?.releaseAfterPrompt??t?.disposeAfterPrompt,n==="openclaw")}promptReleaseAfterPrompt(t,r={}){if(this.config.sandboxRequired)return!0;let n=l(r?._runtimeBridge)?r._runtimeBridge:{},s=hr(n);return s!==void 0?Nt(s,t.releaseAfterPrompt):t.releaseAfterPrompt}startSessionCleanup(){let t=Q(this.config.sessionCleanupIntervalMs,Ha);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 ir(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:Et(),runtimeKind:z(s)};return this.agents.set(r,a),{agent:a}}runtimeFor(t,r,n={}){let{target:s}=this.targetFor(t.targetCode),i=z(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=>Yn({config:this.config,target:s,...u,runId:n.runId,agentId:t.agentId,sessionId:r,sandboxPolicy:n.sandboxPolicy})}:{}};return i==="stdio-acp"||i==="acp"?new ft(t,s,o,a):i==="openclaw"?new Gt(t,s,r,o,a):i==="cli"?new Yt(t,s,a):new Dt(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:at(t.sandboxPolicy)}}let n=c(t.agentId),s=c(t.sessionId)||se(),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"&&Object.hasOwn(ot,t.framework||""))){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?at(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(z(d.target)==="cli"&&Wa(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 h=`${s}:${i}`;await this.cleanupExpiredSessions();let p=this.sessions.get(h),m=null;if(p&&p.targetCode!==d.code)throw Object.assign(new Error(`runtime session target conflict: ${i}`),{code:"RUNTIME_SESSION_TARGET_CONFLICT"});if(p&&this.config.sandboxRequired&&p.runId!==o)throw Object.assign(new Error(`runtime session cannot be shared across runs: ${i}`),{code:"RUNTIME_SESSION_RUN_CONFLICT"});if(!p){if(this.startingSessions.has(h))throw Object.assign(new Error(`runtime session is already starting: ${i}`),{code:"RUNTIME_SESSION_BUSY"});this.startingSessions.add(h);let{code:_,target:T}=d,E;try{await this.reserveTargetSlot(_,T),m=_;let R=this.runtimeFor(f,i,{runId:o,sandboxPolicy:a,source:t.metadata?.source,attachOnly:t.attachOnly});E=R;let N=n?.mcpServers||t.mcpServers||[],M=await R.sessionNew({cwd:rt(T,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 D=Date.now();p={agentId:s,sessionId:i,runtime:R,targetCode:_,runtimeKind:z(T),runId:o,sandboxPolicy:a?structuredClone(a):null,runtimeSessionId:c(l(M)?M.sessionId:"")||i,idleTtlMs:this.targetIdleTtlMs(T),releaseAfterPrompt:this.config.sandboxRequired?!0:this.targetReleaseAfterPrompt(T,t.metadata),createdAtMs:D,lastUsedAtMs:D,busy:!1,createdAt:Et()},this.sessions.set(h,p),this.runtimeSessionIndex.set(`${s}:${p.runtimeSessionId}`,p),n?.mcpServers!==N&&n?.mcpServers&&R.refreshMcpServers&&await R.refreshMcpServers(n.mcpServers)}catch(R){throw this.sessions.get(h)?.runtime===E?await this.closeSession(h,"session_start_failed"):await E?.stop("session_start_failed"),m&&(this.releaseTargetSlot(m),m=null),R}finally{this.startingSessions.delete(h)}}if(p.busy){let _=new Error(`runtime session is already running: ${i}`);throw _.code="RUNTIME_SESSION_BUSY",_}p.busy=!0,m&&this.releaseTargetSlot(m),this.notifyCapacityChanged(),p.operationCorrelationId=n?.correlationId||null,p.lastUsedAtMs=Date.now();let y=n?.updates||[],w=_=>{let T=Xa(_,i,p);if(y.push(T),n)for(let E of n.listeners)try{E?.(T)}catch(R){g("warn","runtime-bridge","runtime operation update listener failed",{correlationId:n.correlationId,error:String(R)})}else r.onUpdate?.(T)},I=_=>{if(!(!n||n.status!=="running"||!l(_))){if(_.status==="failed"){let T=_.error;if(T instanceof Error){this.failOperation(n,T);return}let E=l(T)?T:{},R=Object.assign(new Error(c(E.message||_.message)||"runtime terminal failure"),{code:c(E.code||_.code)||"RUNTIME_TERMINAL_FAILED"});this.failOperation(n,R);return}this.completeOperation(n,this.promptResponse(t,p,i,y,l(_.result)?_.result:{stopReason:"end_turn"}))}};try{let _=Kn(t.goalContract),T=Array.isArray(t.prompt)?[...t.prompt]:[];_&&T.unshift({type:"text",text:_,metadata:{source:"orcha_goal_contract"}});let E=l(t.metadata)?t.metadata:{},R=l(E._runtimeBridge)?E._runtimeBridge:{},N=await p.runtime.sessionPrompt({sessionId:p.runtimeSessionId,prompt:T,metadata:E},w,I),M=y,D=null;if(ss({type:p.runtimeKind})&&mc(N,y,R)){D=N;let V=y.length,C=await p.runtime.sessionPrompt({sessionId:p.runtimeSessionId,prompt:[{type:"text",text:gc()}],metadata:E,_meta:{thinking:"off"}},w,I);N=_c(D,C),M=y.slice(V)}let Z;try{Z=this.promptResponse(t,p,i,y,N,M)}catch(V){throw D&&ls(N)?wc(N,M):V}return D&&(Z.result=yc(Z.result,D)),n&&this.completeOperation(n,Z),Z}finally{p.busy=!1,this.notifyCapacityChanged(),p.operationCorrelationId===n?.correlationId&&(p.operationCorrelationId=null),p.lastUsedAtMs=Date.now(),this.promptReleaseAfterPrompt(p,l(t.metadata)?t.metadata:{})&&await this.closeSession(h,"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=at(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 h=Number(f.policyRevision),p=Number(o.policyRevision);if(p<h)throw Object.assign(new Error("runtime sandbox policy revision is stale"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:h});if(p===h){if(G(f)!==G(o))throw Object.assign(new Error("runtime sandbox policy revision payload conflicts"),{code:"RUNTIME_POLICY_REVISION_CONFLICT",currentPolicyRevision:h});return{updated:!1,idempotent:!0,policyRevision:h,accessMode:f.accessMode}}let m=Wn(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:p,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=ic(t),d=is(t),{target:f}=this.targetFor(t.targetCode||t.framework),h=[{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 ${Ge} and ${Ke}.`:"",d?`Then put a JSON object containing _decision between ${ze} and ${Ve}.`:"",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 ${rs} 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(`
|
|
25
|
+
`)}];return this.prompt({...t,agentId:n,sessionId:o,prompt:h,metadata:sc(t,f)},r)}async requestPermission({agent:t,runtimeSessionId:r,request:n,emitUpdate:s}){let i=se(),a=this.runtimeSessionIndex.get(`${t.agentId}:${r}`)?.sessionId||r||se(),u={permissionId:i,agentId:t.agentId,sessionId:a,runtimeSessionId:r,request:l(n)?n:{},status:"pending",createdAt:Et()};return s?.({sessionId:r,update:{sessionUpdate:"permission_request",permission:u}}),await new Promise(d=>{let f=S(n?.timeoutMs,this.config.permissionRequestTimeoutMs),h=setTimeout(()=>{this.pendingPermissions.delete(i),d({permissionId:i,outcome:"denied",response:{reason:"permission request timed out"}})},f);this.pendingPermissions.set(i,{timer:h,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 Tc from"node:http";import Ec from"node:https";import{randomBytes as ds}from"node:crypto";var gt=1,ct=3,Sc=1e4,ae=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=Rc(r.connectTimeoutMs,Sc),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:"?Ec:Tc,n=ds(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===ct){o.destroy();return}this.socket=o,this.readyState=gt,o.on("data",u=>this.onData(u)),o.on("close",()=>this.onClose()),o.on("error",u=>{this.readyState!==ct&&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!==ct&&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===gt||this.readyState===ct)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!==gt||this.socket.write(Tr(1,Buffer.from(String(t),"utf8")))}close(){if(this.readyState!==ct){if(this.clearConnectTimer(),!this.socket){this.request?.destroy(),this.onClose();return}try{this.readyState===gt&&this.socket.write(Tr(8,Buffer.alloc(0))),this.socket.end()}catch{this.socket.destroy()}this.onClose()}}onClose(){this.readyState!==ct&&(this.clearConnectTimer(),this.readyState=ct,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),h=this.buffer.readUInt32BE(a+4);o=f*2**32+h,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((h,p)=>h^f[p%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(Tr(10,d))}}};function Rc(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function Tr(e,t){let r=t.length,n=2;r>=126&&r<=65535?n+=2:r>65535&&(n+=8);let s=ds(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 Oc(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 Ic(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 Cc=Object.freeze(["health","agents/create","agents/dispatch","sessions/prompt","sessions/policy","sessions/cancel","permissions/respond"]),ce=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[...Cc,...this.config.deviceConnection?["devices/discover","devices/configure"]:[]]}runtimeTargets(){let t=this.sandboxCapabilities().dispatchable===!0;return typeof this.bridge.targetCapacitySnapshot=="function"?this.bridge.targetCapacitySnapshot(t):Ic(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=Oc(this.config.orchaUrl),r=new ae(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!==gt?!1:(r.send(JSON.stringify(t)),!0)}};import{createServer as Ac}from"node:http";function ue(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 ut(e={}){return{ok:!0,...e}}function Er(e,t,r){return{ok:!1,error:{code:e,message:t,...r===void 0?{}:{detail:r}}}}async function fs(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 ps(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 hs(e,t){let r={"GET /health":async()=>ut(t.health()),"POST /agents/create":async n=>ut(await t.createAgent(n)),"POST /agents/dispatch":async n=>ut(await t.dispatch(n)),"POST /sessions/prompt":async n=>ut(await t.prompt(n)),"POST /sessions/cancel":async n=>ut(await t.cancel(n)),"POST /permissions/respond":async n=>ut(await t.respondPermission(n))};return Ac(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){ue(s,404,Er("NOT_FOUND",`No route for ${o}`));return}try{ps(n,e.token);let u=n.method==="GET"?{}:await fs(n,e.requestLimitBytes);ue(s,200,await a(u))}catch(u){let d=u.status||500,f=u.code||"BRIDGE_INTERNAL";ue(s,d,Er(f,u.message||String(u),u.detail))}})}var Ss=Pc(import.meta.url),Lc=".orcha-runtime-bridge.pid",kc=".orcha-runtime-bridge.log",vc=3,Dc=36e5,{command:Hc,options:Rs}=Bc(process.argv.slice(2));jc(Rs);ln();var $c=dn();await Os(Hc,$c,Rs);async function Os(e,t,r){if(r.url){let s=Te(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&<(de(le())))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 Ut(t,r),r.foreground?await Sr(t):Rr(n());return;case"run":case"foreground":r.url&&await Ut(t,r),await Sr(t);return;case"start":if(r.url)return Os("connect",t,r);if(r.foreground){await Sr(t);return}Rr();return;case"reload":case"restart":{r.url&&await Ut(t,{url:r.url});let s=_t(Es(Ss),".."),i=_t(s,...Ar(_t(s,"src","index.js"))?["dist","package"]:[],"openclaw-plugin"),o=await Wr(t.targets,i);await _s({quiet:!0}),await o(),Rr(r.url?n():void 0);return}case"stop":await _s();return;case"status":Fc();return;case"help":case"--help":case"-h":zc();return;default:throw new Error(`Unknown command: ${e}`)}}async function Sr(e){qc();let t=new oe(e);if(await t.start(),e.mode==="server"){let n=hs(e,t);gs({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 ce(e,t);gs({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 gs({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 Rr(e=["run"]){let t=le(),r=Is(),n=de(t);if(n&<(n)){console.log(JSON.stringify({status:"already_running",pid:n,pidFile:t,logFile:r}));return}n&&Cr(t),ws(t),ws(r),Ir(r);let s=Mc(r,"a"),i={...process.env,ORCHA_RUNTIME_PID_FILE:t,ORCHA_RUNTIME_LOG_FILE:r},o=xc(process.execPath,[Ss,...e,"--pid-file",t,"--log-file",r],{cwd:process.cwd(),detached:!0,env:i,stdio:["ignore",s,s]});o.unref(),Nc(s),Ts(t,`${o.pid}
|
|
26
|
+
`),console.log(JSON.stringify({status:"started",pid:o.pid,pidFile:t,logFile:r}))}async function _s({quiet:e=!1}={}){let t=le(),r=de(t);if(!r){e||console.log(JSON.stringify({status:"not_running",pidFile:t}));return}if(!lt(r)){Cr(t),e||console.log(JSON.stringify({status:"not_running",pid:r,pidFile:t}));return}process.kill(r,"SIGTERM"),!await ys(r,1e4)&<(r)&&(process.kill(r,"SIGKILL"),await ys(r,3e3)),Cr(t),e||console.log(JSON.stringify({status:"stopped",pid:r,pidFile:t}))}function Fc(){let e=le(),t=Is(),r=de(e),n=!!(r&<(r));console.log(JSON.stringify({status:n?"running":"not_running",running:n,pid:n?r:null,pidFile:e,logFile:t}))}function Bc(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 jc(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 le(){return _t(process.cwd(),process.env.ORCHA_RUNTIME_PID_FILE||Lc)}function Is(){return _t(process.cwd(),process.env.ORCHA_RUNTIME_LOG_FILE||kc)}function qc(){let e=process.env.ORCHA_RUNTIME_LOG_FILE;if(!e)return;let t=Cs();if(t<=0)return;let r=_t(process.cwd(),e);Ir(r,t);let n=Kc();n<=0||setInterval(()=>Ir(r,t),n).unref()}function Ir(e,t=Cs()){if(t<=0||!Ar(e))return;let r=0,n="";try{if(r=ms(e).size,r<=0)return;n=Or(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&&(Gc(d,s)?o.push(d):a+=1);if(a===0)return;let u="";try{ms(e).size>r&&(u=Or(e,"utf8").slice(n.length));let f=[...o,...u.split(/\r?\n/).filter(Boolean)].join(`
|
|
27
|
+
`);Ts(e,f?`${f}
|
|
28
|
+
`:""),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 Gc(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 Cs(){return As(process.env.ORCHA_RUNTIME_LOG_RETENTION_DAYS,vc)}function Kc(){return As(process.env.ORCHA_RUNTIME_LOG_CLEANUP_INTERVAL_MS,Dc)}function As(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)&&r>=0?r:t}function de(e){if(!Ar(e))return null;let t=Number.parseInt(Or(e,"utf8").trim(),10);return Number.isInteger(t)&&t>0?t:null}function lt(e){if(!Number.isInteger(e)||e<=0)return!1;try{return process.kill(e,0),!0}catch(t){return t?.code==="EPERM"}}async function ys(e,t){let r=Date.now();for(;Date.now()-r<t;){if(!lt(e))return!0;await new Promise(n=>setTimeout(n,100))}return!lt(e)}function ws(e){bc(Es(e),{recursive:!0})}function Cr(e){try{Uc(e,{force:!0})}catch{}}function zc(){console.log(`Usage: orcha-runtime-bridge [command] [options]
|
|
26
29
|
|
|
27
30
|
Commands:
|
|
28
31
|
connect Pair or reconnect this device, then run in the background.
|
package/openclaw-plugin/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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 de(e,t=[]){let i=String(e??"");for(let g of t){let d=String(g??"");d.length>=4&&(i=i.split(d).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 le(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 d=Object.fromEntries((i.headers||[]).map(({name:O,value:s})=>[O.toLowerCase(),s]));if(!String(d.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:g.href,headers:{...d,"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 d=await B(g.body);if(!d||d.jsonrpc!=="2.0"||d.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return d}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 d=Object.entries(e.headers).filter(([u])=>ce(u)).flatMap(([,u])=>[u,String(u).replace(/^Bearer\s+/i,"")]),O=typeof i.error.message=="string"?de(i.error.message,d).slice(0,512):"",s=Number.isInteger(i.error.code)?` (${i.error.code})`:"";throw new Error(`Orcha MCP tool discovery failed${s}${O?`: ${O}`:""}`)}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=d=>Array.isArray(d)?d.map(i):d&&typeof d=="object"?Object.fromEntries(Object.keys(d).sort().map(O=>[O,i(d[O])])):d,g=d=>d.map(({name:O,inputSchema:s})=>({name:O,inputSchema:s})).sort((O,s)=>O.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 d(s){let u=t.get(s);return u&&u.deadline<=Date.now()?(g(s,u),null):u}async function O(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=d(c);if(u&&!h||h&&(h.runId!==_||h.agentCode!==M||h.deadline!==m))throw X("original_binding_unavailable_or_changed");let L=le([n],i),r=h?.lifetime||new AbortController,l=await ue(L,r.signal);if(d(c)!==h)throw X("binding_changed");if(h){if(!pe(h.tools,l))throw X("frozen_tool_catalog_changed");h.upstream=L}else{let o={runId:_,agentCode:M,deadline:m,upstream:L,tools:l,lifetime:r};o.timer=setTimeout(()=>g(c,o),m-Date.now()),o.timer.unref?.(),t.set(c,o)}}return e.registerTool(s=>{let u=d(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(d(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:O,active:d,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:d}){let O=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},l=r.mediaUrls||(r.mediaUrl?[r.mediaUrl]:[]),o=s(n.accountId,n.deliveryQueueId),a=me([m,r.text||"",l,L,h?.runId||null]),p=t(o,"sends");if(p&&p.requestHash!==a)throw j("channel_send_conflict");let y=O.get(o);if(y){if(y.requestHash!==a)throw j("channel_send_conflict");return y.promise}let E=(async()=>{let T=p;if(!T){let S=[];for(let I of l){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)}T={requestHash:a,payload:{sourceMessageId:`openclaw:${o}`,sessionId:m,content:r.text||"",inputParts:S,...L?{replyToMessageId:L}:{},...h?{agentRunId:h.runId}:{}}},i(o,T,"sends")}let w=await _(n.accountId,T,n);return h&&!h.messageIds.includes(w.messageId)&&h.messageIds.push(w.messageId),w})().finally(()=>O.delete(o));return O.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=d(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,d,O){let s=new Map;e.on("before_message_write",({message:r},l)=>{if(r?.role!=="assistant")return;let o=t.active(l.sessionKey),a=s.get(o?.runId);a&&l.agentId===o.agentCode&&(a.silentFinal=O(r))});let u=()=>e.config;function _(r,l=u()){let o=l?.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,l,o,{cfg:a,signal:p,method:y="POST"}={}){let E=_(r,a),T=new URL(`/api/agent-channels${l}`,t.allowedUrl),w=o instanceof FormData,S=AbortSignal.any([AbortSignal.timeout(3e4),...p?[p]:[]]);try{let I=await fetch(T,{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,l="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",l);return He(o,{recursive:!0,mode:448}),ye(o,`${r}.json`)}function k(r,l){try{return JSON.parse(De(M(r,l),"utf8"))}catch(o){if(o.code==="ENOENT")return null;throw o}}function n(r,l,o){let a=M(r,o),p=`${a}.pending`;Be(p,JSON.stringify(l),{mode:384}),ve(p,a)}async function m(r,l=!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}),T=k(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 w=s.get(p),S=T?.expiresAt||r.expiresAt,I=we(a.agentId,y,t.allowedUrl),P=()=>{let C=t.active(I);C?.runId===p&&t.release(I,C)},N=T?.hostRunId||`orcha-${p}`;if(T&&!w||r.attachOnly&&!w&&!T)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(l)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(l)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(`
|
|
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
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
|
-
`),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:
|
|
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
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"}),
|
|
8
|
-
`))}function Ae(e){return!Je(e)&&!e.isCommentary&&!e.isCompactionNotice&&!e.isFallbackNotice&&!e.isStatusNotice&&!Fe(e)&&!We(e)&&!ze(e)}var
|
|
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};
|