@orcha-ai/runtime-bridge 0.1.58 → 0.1.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -93,8 +93,8 @@ Build produces `bin/orcha-runtime-bridge.js` and the clean npm package in `dist/
93
93
  Version 0.1.44 routes replies, native `message` tool sends, and background notifications through the same Orcha IM sender, and streams native Channel tools and host-visible reasoning/process updates through the existing Orcha progress UI. The plugin sends response headers immediately and heartbeats every 15 seconds; task deadlines and transport timeouts remain explicit failures. Bridge and the bundled plugin must upgrade together: native delivery preflight and content negotiation reject the old JSON-only contract before starting a host turn. `orcha-runtime-node.v2` is unchanged. Deploying Orcha does not publish npm or upgrade connected devices automatically. Build and validate the release tarball before publishing:
94
94
 
95
95
  ```bash
96
- npm run release:check
97
- npm publish ./dist/orcha-ai-runtime-bridge-0.1.58.tgz --access public --registry=https://registry.npmjs.org
96
+ npm run release:check &&
97
+ npm publish ./dist/orcha-ai-runtime-bridge-0.1.60.tgz --access public --registry=https://registry.npmjs.org
98
98
  ```
99
99
 
100
100
  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.
@@ -105,7 +105,11 @@ Native delivery uses `application/x-orcha-channel-events-v2+ndjson` with `heartb
105
105
 
106
106
  Tests cover discovery errors, paths, public-field filtering, immutable commands, exact OpenClaw IDs, atomic configuration, capacity, reconnect, MCP lifecycle and cancellation. The live Codex model test is opt-in (`ORCHA_TEST_REAL_CODEX` set to the installed CLI path) and spends one short turn of the local account; fixtures do not certify a real vendor account or OpenClaw Gateway version.
107
107
 
108
- To check reply classification against the real SDK without installing or starting a Gateway, extract the official `openclaw@2026.7.1` npm tarball and run `npm run test:openclaw-sdk -- /absolute/path/to/extracted/package`. This check imports the actual SDK functions, covering final text/media, reasoning, commentary, status/progress notices and TTS supplements; it does not replace a live host/model acceptance test.
108
+ To check reply classification against the real SDK without starting another Gateway, use an existing official `openclaw@2026.10.6` installation on its host and run `npm run test:openclaw-sdk -- /absolute/path/to/openclaw/package`. This check imports the actual SDK functions, covering final text/media, reasoning, commentary, status/progress notices and TTS supplements. `node scripts/check-openclaw-native-sdk.js /absolute/path/to/openclaw/package` also checks native target resolution, message actions and receipt reconciliation; neither replaces a live host/model acceptance test. Run these checks with the Node.js version required by the selected OpenClaw release.
109
+
110
+ Version 0.1.59 adapts the plugin to OpenClaw 2026.10.6. Each enabled account owns a Gateway lifecycle task that admits HTTP deliveries until stopped; stopping the account rejects new work and cancels and drains its active host turns. Readiness describes this local HTTP runtime, not a persistent connection to Core. Config and workspace resolution use the host's current runtime config and agent resolver rather than the retired `agents.list` layout. Ordinary queued sends opt into automatic unknown-send reconciliation so the host supplies durable delivery identities, and the sender checks the host's direct-handoff fence immediately before platform I/O. Existing account credentials, saved send identities, session boundaries and the native Channel stream protocol remain unchanged. Install the updated bundle on the OpenClaw host and restart that Gateway; deploying Core alone does not update the plugin.
111
+
112
+ Acceptance for 0.1.59: Bridge checks, fixture tests and build pass, as do both SDK checks against the host's installed OpenClaw 2026.10.6. The updated plugin was installed through the official plugin installer; Gateway health passed and Bridge restarted. A user-triggered live OrchaAI reply was confirmed. This bundle was installed directly on the existing device and has not been published to npm.
109
113
 
110
114
  ## Tool error warnings (0.1.46)
111
115
 
@@ -131,7 +135,7 @@ Device Codex accepts Core's existing `session-<id>:<human-member>:<agent-member>
131
135
 
132
136
  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. Device Codex saves the thread ID returned by app-server `thread/start` under `~/.orcha/codex-sessions/` and resumes it with `thread/resume`; env-configured `codex exec` targets save `thread.started.thread_id` and use `codex exec resume <thread-id>`. 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.
133
137
 
134
- 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.
138
+ 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. The receipt retains the same `sessionId` and task scope with `runId:null`. In a group, select exactly one Agent explicitly; send the command without a quoted message, attachments, plugins or skills. Selecting an external member records an `external_session_reset` notice bound to that member through the existing message mention relation. Only that member's next native conversation changes; other members and the group's shared history, memory and checkpoints retain their boundaries. Only unfinished work belonging to the selected member blocks this reset, including delegated and background runs. Existing `context_reset` notices retain their shared-boundary meaning. Core supplies the resulting member-specific history floor through the existing native session scope or Channel delivery, so this change requires no Bridge update, schema migration or protocol version. See the authoritative [context reset rules](../docs/新文档/02-AI对话/36-默认长聊与独立话题列表交互建议.md#4-new-原地重置上下文). Other raw commands, such as `/status`, reach OpenClaw and remain subject to its own command permissions.
135
139
 
136
140
  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.
137
141
 
@@ -188,13 +192,13 @@ Acceptance on 2026-10-08: Bridge checks/tests/build and the PostgreSQL approval
188
192
 
189
193
  ### Codex file delivery (0.1.51)
190
194
 
191
- 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. Because the attachment message and the final reply appear separately, `message` is only a short caption describing the file; the tool schema tells the model not to repeat the final reply's summary there and to omit it when the reply already explains the file.
195
+ 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. All files sent by the same run share its final reply's stable message identity. The first successful upload creates that reply, later uploads append attachments, and finalization replaces the temporary `message` text while retaining every attachment. Delegated members use their own AgentRun identity, so their files remain on their own replies. Sending a file does not complete the run.
192
196
 
193
- 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.
197
+ 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). `ChatRun.run_plan.fileDeliveries` records each signed source/delivery identity, payload hash, file ID and message ID under the existing parent-run lock. Same-run retries reuse the receipt, including after credential refresh; reusing an identity with different bytes, filename or caption fails. 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.
194
198
 
195
199
  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.
196
200
 
197
- 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.
201
+ Merged replies require the updated Core endpoint; existing Bridge requests keep the same format and receive the same receipt fields. Reload an updated Bridge to receive the revised tool description. There is no database migration, protocol-version change or new project environment variable. Missing `fileDeliveries` on old run records means no recorded deliveries; historical messages are not merged or backfilled. This source change has not been published to npm or deployed.
198
202
 
199
203
  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). Resolved for device Codex in 0.1.53: app-server routes Orcha task-tool approvals to Bridge, which accepts them for the Core-authorized task.
200
204
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import{spawn as hu}from"node:child_process";import{closeSync as gu,existsSync as Kr,mkdirSync as _u,openSync as yu,readFileSync as jr,rmSync as wu,statSync as Hs,writeFileSync as Gs}from"node:fs";import{dirname as Ks,resolve as Ct}from"node:path";import{fileURLToPath as Tu}from"node:url";import{createHash as es}from"node:crypto";import{mkdir as ia,readFile as oa,writeFile as aa,rename as ca}from"node:fs/promises";import{join as ts}from"node:path";import{homedir as ua,hostname as la}from"node:os";import{execFile as ti}from"node:child_process";import{access as ei,realpath as ri}from"node:fs/promises";import{constants as ni}from"node:fs";import{delimiter as si,join as Xr,isAbsolute as Yr}from"node:path";import{homedir as Wr}from"node:os";async function xe(e,t=process.env){let r=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let n of(t.PATH||"").split(si).filter(Yr))for(let s of r){let i=Xr(n,`${e}${s}`);try{return await ei(i,ni.X_OK),i}catch{}}return null}function ii(e,t){return new Promise(r=>ti(e,t,{timeout:8e3,maxBuffer:1024*1024,windowsHide:!0},(n,s)=>r({code:n?n.code:0,stdout:String(s||"")})))}async function Ae(e){let t=e==="~"?Wr():e.startsWith("~/")?Xr(Wr(),e.slice(2)):e;if(!Yr(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 ri(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 Qr({find:e=xe,run:t=ii,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"]),c=a.code===0&&a.stdout.match(/\d+\.\d+\.\d+[^\s]*/)?.[0]||"",l={id:s,name:o,framework:s,version:c,workspace:r,managed:!1};if(a.code!==0)return[{...l,status:"error",message:"\u7A0B\u5E8F\u65E0\u6CD5\u542F\u52A8\uFF0C\u8BF7\u5728\u672C\u673A\u68C0\u67E5\u5B89\u88C5"}];if(s==="openclaw"){let f=await t(i,["agents","list","--json"]),h;try{h=JSON.parse(f.stdout)}catch{}if(f.code!==0||!Array.isArray(h))return[{...l,status:"error",message:"\u65E0\u6CD5\u8BFB\u53D6 OpenClaw \u667A\u80FD\u4F53\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u914D\u7F6E"}];let _=await t(i,["health","--json"]);return h.filter(w=>typeof w.id=="string"&&typeof w.workspace=="string").slice(0,32).map(w=>({...l,id:`openclaw:${w.id}`,name:w.name||w.identityName||w.id,workspace:w.workspace,managed:!0,localAgentId:w.id,command:i,status:_.code===0?"ready":"needs_setup",message:_.code===0?"":"\u8BF7\u5148\u5728\u672C\u673A\u542F\u52A8\u5E76\u914D\u7F6E OpenClaw Gateway"}))}let p=await t(i,s==="codex"?["login","status"]:["auth","status"]),m=p.code===0?"ready":p.code===1?"needs_login":"error";return[{...l,command:i,status:m,message:m==="needs_login"?`\u8BF7\u5728\u672C\u673A\u8FD0\u884C ${s} ${s==="codex"?"login":"auth login"}`:m==="error"?"\u767B\u5F55\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C":""}]}))).flat()}import{spawn as ra}from"node:child_process";import{createInterface as na}from"node:readline";import{randomUUID as sa}from"node:crypto";import{createInterface as di}from"node:readline";var B="0.1.58";function Mt(){return new Date().toISOString()}function $(e,t=2){return String(e).padStart(t,"0")}function Zr(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${$(Math.floor(r/60))}:${$(r%60)}`}function oi(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${$(e.getMonth()+1)}-${$(e.getDate())}`,`T${$(e.getHours())}:${$(e.getMinutes())}:${$(e.getSeconds())}.${$(e.getMilliseconds(),3)}`,Zr(t)].join("")}function ai(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 ci(e,t){let r=ai(e,t),n=Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second,e.getMilliseconds()),s=Math.round((n-e.getTime())/6e4);return[`${r.year}-${$(r.month)}-${$(r.day)}`,`T${$(r.hour)}:${$(r.minute)}:${$(r.second)}.${$(e.getMilliseconds(),3)}`,Zr(s)].join("")}function ui(e=new Date){let t=u(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return ci(e,t)}catch{return oi(e)}}function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function u(e){return String(e??"").trim()}function R(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)?r:t}function k(e){return Array.isArray(e)?e.map(String):[]}function K(e,t,r=process.cwd()){let n=d(e)?e:{};return u(n.cwd)||u(n.workspace)||u(t)||u(r)||process.cwd()}var qt="[redacted]",li=/(authorization|api[_-]?key|credential|password|secret|token)/i;function rt(e){return li.test(u(e))}function ct(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(qt))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${qt}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${qt}`)}function at(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]=at(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=>at(i,t));return t.delete(e),s}let r={},n=rt(e.name||e.key);for(let[s,i]of Object.entries(e))r[s]=rt(s)||n&&s.toLowerCase()==="value"?qt:at(i,t);return t.delete(e),r}function tn(e,t=4e3){let r=JSON.stringify(at(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function g(e,t,r,n={}){let s={ts:ui(),level:e,module:t,msg:r,...d(n)?at(n):{}};console.error(JSON.stringify(s))}function Gt(e,{onNotification:t=()=>{},onRequest:r=()=>{throw new Error("Unsupported request")}}={}){let n=1,s=new Map,i=o=>e.stdin.write(`${JSON.stringify(o)}
2
+ import{spawn as hu}from"node:child_process";import{closeSync as gu,existsSync as Kr,mkdirSync as _u,openSync as yu,readFileSync as jr,rmSync as wu,statSync as Hs,writeFileSync as Gs}from"node:fs";import{dirname as Ks,resolve as Ct}from"node:path";import{fileURLToPath as Tu}from"node:url";import{createHash as es}from"node:crypto";import{mkdir as ia,readFile as oa,writeFile as aa,rename as ca}from"node:fs/promises";import{join as ts}from"node:path";import{homedir as ua,hostname as la}from"node:os";import{execFile as ti}from"node:child_process";import{access as ei,realpath as ri}from"node:fs/promises";import{constants as ni}from"node:fs";import{delimiter as si,join as Xr,isAbsolute as Yr}from"node:path";import{homedir as Wr}from"node:os";async function xe(e,t=process.env){let r=process.platform==="win32"?[".exe",".cmd",".bat",""]:[""];for(let n of(t.PATH||"").split(si).filter(Yr))for(let s of r){let i=Xr(n,`${e}${s}`);try{return await ei(i,ni.X_OK),i}catch{}}return null}function ii(e,t){return new Promise(r=>ti(e,t,{timeout:8e3,maxBuffer:1024*1024,windowsHide:!0},(n,s)=>r({code:n?n.code:0,stdout:String(s||"")})))}async function Ae(e){let t=e==="~"?Wr():e.startsWith("~/")?Xr(Wr(),e.slice(2)):e;if(!Yr(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 ri(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 Qr({find:e=xe,run:t=ii,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"]),c=a.code===0&&a.stdout.match(/\d+\.\d+\.\d+[^\s]*/)?.[0]||"",l={id:s,name:o,framework:s,version:c,workspace:r,managed:!1};if(a.code!==0)return[{...l,status:"error",message:"\u7A0B\u5E8F\u65E0\u6CD5\u542F\u52A8\uFF0C\u8BF7\u5728\u672C\u673A\u68C0\u67E5\u5B89\u88C5"}];if(s==="openclaw"){let f=await t(i,["agents","list","--json"]),h;try{h=JSON.parse(f.stdout)}catch{}if(f.code!==0||!Array.isArray(h))return[{...l,status:"error",message:"\u65E0\u6CD5\u8BFB\u53D6 OpenClaw \u667A\u80FD\u4F53\uFF0C\u8BF7\u68C0\u67E5\u672C\u673A\u914D\u7F6E"}];let _=await t(i,["health","--json"]);return h.filter(w=>typeof w.id=="string"&&typeof w.workspace=="string").slice(0,32).map(w=>({...l,id:`openclaw:${w.id}`,name:w.name||w.identityName||w.id,workspace:w.workspace,managed:!0,localAgentId:w.id,command:i,status:_.code===0?"ready":"needs_setup",message:_.code===0?"":"\u8BF7\u5148\u5728\u672C\u673A\u542F\u52A8\u5E76\u914D\u7F6E OpenClaw Gateway"}))}let p=await t(i,s==="codex"?["login","status"]:["auth","status"]),m=p.code===0?"ready":p.code===1?"needs_login":"error";return[{...l,command:i,status:m,message:m==="needs_login"?`\u8BF7\u5728\u672C\u673A\u8FD0\u884C ${s} ${s==="codex"?"login":"auth login"}`:m==="error"?"\u767B\u5F55\u72B6\u6001\u68C0\u6D4B\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5 CLI \u7248\u672C":""}]}))).flat()}import{spawn as ra}from"node:child_process";import{createInterface as na}from"node:readline";import{randomUUID as sa}from"node:crypto";import{createInterface as di}from"node:readline";var B="0.1.60";function Mt(){return new Date().toISOString()}function $(e,t=2){return String(e).padStart(t,"0")}function Zr(e){let t=e>=0?"+":"-",r=Math.abs(e);return`${t}${$(Math.floor(r/60))}:${$(r%60)}`}function oi(e){let t=-e.getTimezoneOffset();return[`${e.getFullYear()}-${$(e.getMonth()+1)}-${$(e.getDate())}`,`T${$(e.getHours())}:${$(e.getMinutes())}:${$(e.getSeconds())}.${$(e.getMilliseconds(),3)}`,Zr(t)].join("")}function ai(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 ci(e,t){let r=ai(e,t),n=Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second,e.getMilliseconds()),s=Math.round((n-e.getTime())/6e4);return[`${r.year}-${$(r.month)}-${$(r.day)}`,`T${$(r.hour)}:${$(r.minute)}:${$(r.second)}.${$(e.getMilliseconds(),3)}`,Zr(s)].join("")}function ui(e=new Date){let t=u(process.env.ORCHA_RUNTIME_LOG_TIMEZONE||process.env.TZ||"Asia/Shanghai");try{return ci(e,t)}catch{return oi(e)}}function d(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function u(e){return String(e??"").trim()}function R(e,t){let r=Number.parseInt(String(e??""),10);return Number.isFinite(r)?r:t}function k(e){return Array.isArray(e)?e.map(String):[]}function K(e,t,r=process.cwd()){let n=d(e)?e:{};return u(n.cwd)||u(n.workspace)||u(t)||u(r)||process.cwd()}var qt="[redacted]",li=/(authorization|api[_-]?key|credential|password|secret|token)/i;function rt(e){return li.test(u(e))}function ct(e,t=[]){let r=String(e??"");for(let n of t){let s=String(n??"");s.length>=4&&(r=r.split(s).join(qt))}return r.replace(/((?:authorization|api[_-]?key|credential|password|secret|token)\s*[:=]\s*)(?:"[^"]*"|'[^']*'|[^\s,;]+)/gi,`$1${qt}`).replace(/([?&](?:api[_-]?key|credential|password|secret|token)=)[^&\s]+/gi,`$1${qt}`)}function at(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]=at(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=>at(i,t));return t.delete(e),s}let r={},n=rt(e.name||e.key);for(let[s,i]of Object.entries(e))r[s]=rt(s)||n&&s.toLowerCase()==="value"?qt:at(i,t);return t.delete(e),r}function tn(e,t=4e3){let r=JSON.stringify(at(e))??String(e);return!Number.isFinite(t)||r.length<=t?r:`${r.slice(0,t)}...`}function g(e,t,r,n={}){let s={ts:ui(),level:e,module:t,msg:r,...d(n)?at(n):{}};console.error(JSON.stringify(s))}function Gt(e,{onNotification:t=()=>{},onRequest:r=()=>{throw new Error("Unsupported request")}}={}){let n=1,s=new Map,i=o=>e.stdin.write(`${JSON.stringify(o)}
3
3
  `);return di({input:e.stdout}).on("line",o=>{if(!o.trim())return;let a;try{a=JSON.parse(o)}catch{g("warn","runtime.codex","ignored non-JSON app-server output");return}if(typeof a.method=="string"&&a.id!==void 0){Promise.resolve().then(()=>r(a.method,d(a.params)?a.params:{})).then(l=>i({id:a.id,result:l}),l=>i({id:a.id,error:{code:-32603,message:String(l?.message||l)}}));return}if(typeof a.method=="string"){t(a.method,d(a.params)?a.params:{});return}let c=s.get(a.id);c&&(s.delete(a.id),a.error?c.reject(Object.assign(new Error(u(a.error.message)||"Codex app-server request failed"),{code:"RUNTIME_CODEX_APP_SERVER_ERROR"})):c.resolve(a.result))}),e.once("exit",()=>{for(let o of s.values())o.reject(new Error("Codex app-server closed"));s.clear()}),{request:(o,a)=>new Promise((c,l)=>{let p=n++;s.set(p,{resolve:c,reject:l}),i({id:p,method:o,params:a})}),notify:o=>i({method:o})}}import{spawn as $n}from"node:child_process";import{randomUUID as wt}from"node:crypto";import{existsSync as Hn,mkdirSync as co,readdirSync as Fn,readFileSync as Bn,realpathSync as kt,rmSync as uo,rmdirSync as lo,statSync as po,unlinkSync as fo}from"node:fs";import{homedir as mo,tmpdir as jn}from"node:os";import{basename as Fe,dirname as ho,join as q,resolve as Pn}from"node:path";import{randomUUID as sn}from"node:crypto";import{existsSync as pi,readFileSync as fi,realpathSync as en,statSync as mi}from"node:fs";import{basename as on,extname as an,isAbsolute as Ut,join as hi,relative as cn,resolve as rn}from"node:path";var gi=25*1024*1024;function un(e,t=""){let r=u(t);if(r)return r;let n=an(u(e)).toLowerCase();return n===".jpg"||n===".jpeg"?"image/jpeg":n===".webp"?"image/webp":n===".gif"?"image/gif":"image/png"}function ln(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 Kt(e){if(Array.isArray(e))return e.map(u).filter(Boolean);let t=u(e);return t?[t]:[]}function _i(e,t){let r=cn(t,e);return r===""||!!r&&!r.startsWith("..")&&!Ut(r)}function yi(e,t){let r=u(e);if(!r||!pi(r))return"";try{let n=en(r);for(let s of t)try{let i=en(s);if(_i(n,i))return n}catch{}}catch{return""}return""}function wi(e,t){let r=u(e);if(!r||!Ut(r))return r;for(let n of Array.isArray(t)?t:[]){if(!d(n))continue;let s=u(n.runtimeRoot),i=u(n.hostRoot);if(!s||!i||!Ut(s)||!Ut(i))continue;let o=cn(rn(s),rn(r));if(o===""||!o.startsWith("..")&&!Ut(o))return o?hi(i,o):i}return r}function be(e,t,r={}){let n=u(e);return!n||n.startsWith("data:")||/^https?:\/\//i.test(n)?n:Ti(n,t,r)}function Ti(e,t,r={}){let n=[...Kt(r.trustedFileRoots),...Kt(r.trustedFileRoot),...Kt(r.artifactRoots),...Kt(r.artifactRoot)],s=yi(wi(e,r.pathMappings),n);if(!s)return"";try{let i=mi(s);return!i.isFile()||i.size<=0||i.size>gi?"":`data:${t};base64,${fi(s).toString("base64")}`}catch{return""}}function v(...e){for(let t of e){let r=u(t);if(r)return r}return""}function Ei(e,t,r,n){let s=r.toLowerCase();if(s==="image"||s==="picture")return!0;let i=v(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=an(i.split("?",1)[0].split("#",1)[0]).toLowerCase();return[".png",".jpg",".jpeg",".webp",".gif"].includes(o)}function Me(e,t={}){let{source:r="runtime_image_generation_event"}=t;if(!d(e))return null;let n=d(e.payload)?e.payload:{},s=u(e.type),i=u(n.type);if(!(s==="event_msg"&&i==="image_generation_end"||s==="response_item"&&i==="image_generation_call"))return null;let o=v(n.call_id,n.id),a=v(n.saved_path,n.savedPath),c=v(n.revised_prompt,n.revisedPrompt),l=un(a,n.mimeType||n.mime_type),p=ln(n.result,l)||be(a,l,t);if(!p)return null;let m=p.startsWith("data:")?p:"",f=a?on(a):`${o||sn()}.png`;return{artifactType:"image",type:"image",fieldKey:"image",title:f||"Generated image",summary:c||"Generated image",content:{prompt:c||void 0,dataUrl:m||void 0,imageUrl:p,previewUrl:p,fileUrl:p,mimeType:l},dataUrl:m||void 0,previewUrl:p,fileUrl:p,metadata:{source:r,eventType:i,callId:o||void 0,savedPath:a||void 0,filename:f,mimeType:l,revisedPrompt:c||void 0}}}function Oi(e){let t=d(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];d(s)&&r.push(s)}return r}function Si(e,t={}){let{source:r="runtime_artifact"}=t,n=d(e)?e:{};if(!Object.keys(n).length)return null;let s=d(n.content)?{...n.content}:{},i=d(n.metadata)?{...n.metadata}:{},o=v(n.saved_path,n.savedPath,s.saved_path,s.savedPath,i.savedPath),a=v(n.mimeType,n.mime_type,s.mimeType,s.mime_type,i.mimeType),c=v(n.artifactType,n.artifact_type,n.type,n.kind,s.type,o?"image":"file"),l=Ei(n,s,c,o),p=l?un(o,a):a;if(l){let I=v(n.dataUrl,s.dataUrl),E=I.startsWith("data:")?I:"",C=v(n.imageUrl,n.previewUrl,n.fileUrl,n.downloadUrl,n.url,n.uri,s.imageUrl,s.previewUrl,s.fileUrl,s.downloadUrl,s.url,s.uri),y=ln(n.result??s.result,p)||E||be(o,p,t)||be(C,p,t);y&&(y.startsWith("data:")&&(s.dataUrl||=y),s.imageUrl||=y,s.previewUrl||=y,s.fileUrl||=y,p&&(s.mimeType||=p))}for(let[I,E]of[["prompt","prompt"],["previewUrl","previewUrl"],["fileUrl","fileUrl"],["downloadUrl","downloadUrl"],["imageUrl","imageUrl"],["dataUrl","dataUrl"],["url","url"],["uri","uri"],["mimeType","mimeType"],["mime_type","mimeType"]]){let C=n[I];C!=null&&C!==""&&!(E in s)&&(s[E]=C)}let m=v(n.fileUrl,n.downloadUrl,n.imageUrl,n.dataUrl,n.url,n.uri,s.fileUrl,s.downloadUrl,s.imageUrl,s.dataUrl,s.url,s.uri),f=v(n.previewUrl,n.imageUrl,n.dataUrl,n.url,n.fileUrl,n.uri,s.previewUrl,s.imageUrl,s.dataUrl,s.url,s.fileUrl,s.uri),h=v(n.dataUrl,s.dataUrl,m.startsWith("data:")?m:"",f.startsWith("data:")?f:""),_=v(n.filename,i.filename,o?on(o):""),w=v(n.fieldKey,n.field_key,s.fieldKey,i.fieldKey,l?"image":"artifact");return{...n,artifactType:c,type:n.type||c,fieldKey:w,title:v(n.title,_,"Runtime artifact"),summary:v(n.summary,s.prompt,n.title,_,"Runtime artifact"),content:s,dataUrl:h||void 0,fileUrl:m||void 0,previewUrl:f||void 0,metadata:{...i,source:v(i.source,r),savedPath:o||i.savedPath,filename:_||i.filename,mimeType:p||i.mimeType}}}function zt(e,t){if(!t||!e)return;let r=d(t.metadata)?t.metadata:{},n=v(r.savedPath,r.callId,t.previewUrl,t.fileUrl)||sn(),s=e.get(n);if(!s){e.set(n,t);return}s.content={...d(s.content)?s.content:{},...d(t.content)?t.content:{}},s.metadata={...d(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 Ne(e,t,r={}){for(let n of Oi(e))zt(t,Si(n,r))}function Ue(e){if(!d(e)||!d(e.payload))return d(e)?e:{value:e};let t=u(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 nn(e,t,r){if(!d(e))return e;let n=d(e.event)?e.event:null;return n?(zt(t,Me(n,r)),{...e,event:Ue(n)}):e}function dn(e,t,r={}){if(!d(e))return e;Ne(e,t,r);let n=nn(e,t,r),s=d(n.update)?nn(n.update,t,r):null;return s&&s!==n.update&&(n={...n,update:s}),n}function pn(e,t,r={}){let n=d(e)?{...e}:{};Ne(n,t,r),Ne(d(n.output)?n.output:{},t,r);let s=[...t?.values?.()||[]];return s.length&&(n._artifacts=s),delete n.artifacts,n}function yt(e){return Array.isArray(e)?e.map(t=>d(t)?t.type==="text"?u(t.text):t.type==="file"?u(t.uri):t.type==="image"?u(t.uri):"":"").filter(Boolean).join(`
4
- `):""}import{createHash as Gi,randomUUID as Ki}from"node:crypto";import{mkdirSync as In,readFileSync as zi,renameSync as Vi,rmSync as Ji,writeFileSync as Cn}from"node:fs";import{homedir as Le}from"node:os";import{join as lt}from"node:path";import{createServer as Ii}from"node:http";import{randomBytes as Ci}from"node:crypto";var Vt={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs","knowledge_search"]};var xi=Object.freeze([...Vt.controlTools,...Vt.residentTools]),Ai=new Set(xi),bi=8*1024*1024;function Jt(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 mn(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>bi)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function hn(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 mn(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function fn(e,t){let r=await hn(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])=>rt(a)).flatMap(([,a])=>[a,String(a).replace(/^Bearer\s+/i,"")]),i=typeof r.error.message=="string"?ct(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 Ni(n)}function Ni(e){if(!Array.isArray(e)||e.some(t=>!t||!Ai.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&Vt.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 Mi(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 gn(e,t=[]){let r=Jt(e),n=new AbortController,s=await fn(r,n.signal);if(t.some(a=>s.some(c=>c.name===a.name)))throw new Error("Local and remote MCP tools conflict");let i=Ci(32).toString("hex"),o=Ii(async(a,c)=>{if(a.url!=="/mcp"||a.headers.authorization!==`Bearer ${i}`){c.writeHead(403).end();return}if(a.method!=="POST"){c.writeHead(405).end();return}try{let l=await mn(a);if(!l||l.jsonrpc!=="2.0"||typeof l.method!="string")throw new Error("Invalid MCP request");let p=l.method==="tools/call"&&t.find(f=>f.name===l.params?.name);if(l.method==="tools/call"&&!p&&!s.some(f=>f.name===l.params?.name))throw new Error("Tool is not authorized in this task binding");let m;if(p)try{m={jsonrpc:"2.0",id:l.id,result:await p.call(l.params.arguments,{upstream:r,signal:n.signal})}}catch(f){m={jsonrpc:"2.0",id:l.id,result:{isError:!0,content:[{type:"text",text:ct(String(f.message),[r.headers.authorization,i])}]}}}else m=await hn(r,l,n.signal),l.method==="tools/list"&&m?.result?.tools&&m.result.tools.push(...t.map(({call:f,...h})=>h));c.writeHead(m===null?202:200,{"content-type":"application/json"}),c.end(m===null?"":JSON.stringify(m))}catch{c.writeHead(502,{"content-type":"application/json"}).end(JSON.stringify({error:"The task-scoped Orcha MCP connection failed"}))}});return await new Promise((a,c)=>{o.once("error",c),o.listen(0,"127.0.0.1",a)}),{url:`http://127.0.0.1:${o.address().port}/mcp`,token:i,async refresh(a){let c=Jt(a,r.url);if(!Mi(s,await fn(c,n.signal)))throw new Error("The frozen MCP tool catalog changed; start a new task");r=c},async close(){n.abort(),o.closeAllConnections(),await new Promise(a=>o.close(a))}}}import{createHash as _n}from"node:crypto";import{constants as Pe}from"node:fs";import{open as Ui,realpath as yn}from"node:fs/promises";import{basename as Pi,isAbsolute as Li,relative as ki,resolve as vi}from"node:path";var Di=32*1024*1024,$i={name:"send_file",description:"Send one explicitly selected local file to the current OrchaAI conversation. Use this to deliver images, PDFs, documents, spreadsheets or other files to the user; viewing an image or writing a local Markdown link does not send it. path must be in the current workspace, 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 short caption for the attachment message, such as what the file is. The attachment is saved as its own message and your final reply is still posted separately, so do not repeat the final reply's summary, findings or conclusions here; omit it when the final reply already explains the file."}}}};function wn(e){return{...$i,async call(t,{upstream:r,signal:n}){if(!t||typeof t.path!="string"||!t.path.trim()||Object.keys(t).some(y=>!["path","message"].includes(y))||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 yn(vi(s,t.path)),a=!1;for(let y of i)try{let O=ki(await yn(y),o);(!O||O!==".."&&!O.startsWith("../")&&!O.startsWith("..\\")&&!Li(O))&&(a=!0)}catch{}if(!a)throw new Error("File is outside the current workspace and authorized artifact roots");let c=await Ui(o,Pe.O_RDONLY|Pe.O_NOFOLLOW|Pe.O_NONBLOCK),l;try{let y=await c.stat();if(!y.isFile()||y.size<=0||y.size>Di)throw new Error("Select a non-empty regular file of at most 32 MiB");l=Buffer.alloc(y.size);let O=0;for(;O<l.length;){let{bytesRead:A}=await c.read(l,O,l.length-O,O);if(!A)throw new Error("File changed while preparing delivery; retry after it is saved");O+=A}let M=await c.stat();if(M.size!==y.size||M.mtimeMs!==y.mtimeMs)throw new Error("File changed while preparing delivery; retry after it is saved")}finally{await c.close()}let p=t.message||"",m=Pi(o),f=_n("sha256").update(l).digest("hex"),h=_n("sha256").update(JSON.stringify([o,f,p])).digest("hex"),_=new FormData;_.set("deliveryId",h),_.set("message",p),_.set("file",new Blob([l]),m);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:_,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 E=await I.json();if(!E.success)throw new Error(`File delivery failed: ${String(E.message||E.code||"request rejected").slice(0,512)}`);let C=E.data;if(!C?.accepted||typeof C.messageId!="string"||!C.messageId||typeof C.fileId!="string"||!C.fileId)throw new Error("File delivery did not return a saved message and file receipt");return{content:[{type:"text",text:JSON.stringify(C)}],structuredContent:C,isError:!1}}}}var Hi=new Set(["Bash","PowerShell"]),Fi=new Set(["Edit","Write","MultiEdit","NotebookEdit"]),Bi="SandboxNetworkAccess",Tn=2e3,En=50;function ut(e,t=0){return typeof e=="string"?e.length>Tn?`${e.slice(0,Tn)}\u2026`:e:t>=4&&(Array.isArray(e)||d(e))?"\u2026":Array.isArray(e)?e.slice(0,En).map(r=>ut(r,t+1)):d(e)?Object.fromEntries(Object.entries(e).slice(0,En).map(([r,n])=>[r,ut(n,t+1)])):e}function ji(e){let t=e.tool_name,r=e.input,n=Hi.has(t)?"command":Fi.has(t)?"file_change":t===Bi?"permission":"other",s=r.file_path||r.notebook_path;return{runtime:"claude",kind:n,toolName:t,title:typeof e.description=="string"?e.description:"",...n==="command"&&typeof r.command=="string"?{command:r.command}:{},...n==="file_change"&&typeof s=="string"?{paths:[s]}:{},input:ut(r)}}async function On(e,t,r){if(e?.subtype!=="can_use_tool"||typeof e.tool_name!="string"||!d(e.input))return{subtype:"error",error:`OrchaAI does not handle Claude control request ${e?.subtype}`};let n=await t(ji(e),{signal:r}),s=n?.response?.reason||n?.reason||n?.outcome||"not approved";return{subtype:"success",response:n?.outcome==="approved"?{behavior:"allow",updatedInput:e.input}:{behavior:"deny",message:`OrchaAI did not approve this action (${s}). Do not retry the same action unless the user asks.`}}}var qi=new Set(["threadId","turnId","itemId","approvalId","startedAtMs","environmentId","command","cwd","reason"]);function Sn(e,t,r){let n=Object.fromEntries(Object.entries(t).filter(([i,o])=>!qi.has(i)&&o!=null)),s={runtime:"codex",title:typeof t.reason=="string"?t.reason:"",input:ut(n)};if(e==="item/commandExecution/requestApproval")return{...s,kind:"command",toolName:"shell",...typeof t.command=="string"?{command:t.command}:{},...typeof t.cwd=="string"?{cwd:t.cwd}:{}};if(e==="item/fileChange/requestApproval"){let i=Array.isArray(r?.changes)?r.changes.map(o=>o?.path).filter(o=>typeof o=="string"):[];return{...s,kind:"file_change",toolName:"apply_patch",...i.length?{paths:i}:{}}}return{...s,kind:"permission",...typeof t.cwd=="string"?{cwd:t.cwd}:{}}}function Rn(e,t,r){return e==="item/permissions/requestApproval"?{permissions:Object.fromEntries(Object.entries(d(t.permissions)?t.permissions:{}).filter(([,s])=>r&&s!=null)),scope:"turn"}:{decision:r?"accept":"decline"}}var xn=e=>Gi("sha256").update(JSON.stringify(e)).digest("hex"),Q=(e,t)=>Object.assign(new Error(t),{code:e}),An=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,ke="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(`
4
+ `):""}import{createHash as Gi,randomUUID as Ki}from"node:crypto";import{mkdirSync as In,readFileSync as zi,renameSync as Vi,rmSync as Ji,writeFileSync as Cn}from"node:fs";import{homedir as Le}from"node:os";import{join as lt}from"node:path";import{createServer as Ii}from"node:http";import{randomBytes as Ci}from"node:crypto";var Vt={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs","knowledge_search"]};var xi=Object.freeze([...Vt.controlTools,...Vt.residentTools]),Ai=new Set(xi),bi=8*1024*1024;function Jt(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 mn(e){let t=0,r=[];for await(let n of e){if(t+=n.length,t>bi)throw new Error("MCP payload exceeds the size limit");r.push(Buffer.from(n))}return JSON.parse(Buffer.concat(r).toString("utf8"))}async function hn(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 mn(n.body);if(!s||s.jsonrpc!=="2.0"||s.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return s}async function fn(e,t){let r=await hn(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])=>rt(a)).flatMap(([,a])=>[a,String(a).replace(/^Bearer\s+/i,"")]),i=typeof r.error.message=="string"?ct(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 Ni(n)}function Ni(e){if(!Array.isArray(e)||e.some(t=>!t||!Ai.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&Vt.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 Mi(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 gn(e,t=[]){let r=Jt(e),n=new AbortController,s=await fn(r,n.signal);if(t.some(a=>s.some(c=>c.name===a.name)))throw new Error("Local and remote MCP tools conflict");let i=Ci(32).toString("hex"),o=Ii(async(a,c)=>{if(a.url!=="/mcp"||a.headers.authorization!==`Bearer ${i}`){c.writeHead(403).end();return}if(a.method!=="POST"){c.writeHead(405).end();return}try{let l=await mn(a);if(!l||l.jsonrpc!=="2.0"||typeof l.method!="string")throw new Error("Invalid MCP request");let p=l.method==="tools/call"&&t.find(f=>f.name===l.params?.name);if(l.method==="tools/call"&&!p&&!s.some(f=>f.name===l.params?.name))throw new Error("Tool is not authorized in this task binding");let m;if(p)try{m={jsonrpc:"2.0",id:l.id,result:await p.call(l.params.arguments,{upstream:r,signal:n.signal})}}catch(f){m={jsonrpc:"2.0",id:l.id,result:{isError:!0,content:[{type:"text",text:ct(String(f.message),[r.headers.authorization,i])}]}}}else m=await hn(r,l,n.signal),l.method==="tools/list"&&m?.result?.tools&&m.result.tools.push(...t.map(({call:f,...h})=>h));c.writeHead(m===null?202:200,{"content-type":"application/json"}),c.end(m===null?"":JSON.stringify(m))}catch{c.writeHead(502,{"content-type":"application/json"}).end(JSON.stringify({error:"The task-scoped Orcha MCP connection failed"}))}});return await new Promise((a,c)=>{o.once("error",c),o.listen(0,"127.0.0.1",a)}),{url:`http://127.0.0.1:${o.address().port}/mcp`,token:i,async refresh(a){let c=Jt(a,r.url);if(!Mi(s,await fn(c,n.signal)))throw new Error("The frozen MCP tool catalog changed; start a new task");r=c},async close(){n.abort(),o.closeAllConnections(),await new Promise(a=>o.close(a))}}}import{createHash as _n}from"node:crypto";import{constants as Pe}from"node:fs";import{open as Ui,realpath as yn}from"node:fs/promises";import{basename as Pi,isAbsolute as Li,relative as ki,resolve as vi}from"node:path";var Di=32*1024*1024,$i={name:"send_file",description:"Send one explicitly selected local file to the current OrchaAI conversation. Use this to deliver images, PDFs, documents, spreadsheets or other files to the user; viewing an image or writing a local Markdown link does not send it. path must be in the current workspace, 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 short description shown while the file is being delivered. Files sent in this turn share one message with your final reply, which replaces this temporary text and keeps the attachments. Explain the deliverables in your final reply; omit this description when unnecessary."}}}};function wn(e){return{...$i,async call(t,{upstream:r,signal:n}){if(!t||typeof t.path!="string"||!t.path.trim()||Object.keys(t).some(y=>!["path","message"].includes(y))||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 yn(vi(s,t.path)),a=!1;for(let y of i)try{let O=ki(await yn(y),o);(!O||O!==".."&&!O.startsWith("../")&&!O.startsWith("..\\")&&!Li(O))&&(a=!0)}catch{}if(!a)throw new Error("File is outside the current workspace and authorized artifact roots");let c=await Ui(o,Pe.O_RDONLY|Pe.O_NOFOLLOW|Pe.O_NONBLOCK),l;try{let y=await c.stat();if(!y.isFile()||y.size<=0||y.size>Di)throw new Error("Select a non-empty regular file of at most 32 MiB");l=Buffer.alloc(y.size);let O=0;for(;O<l.length;){let{bytesRead:A}=await c.read(l,O,l.length-O,O);if(!A)throw new Error("File changed while preparing delivery; retry after it is saved");O+=A}let M=await c.stat();if(M.size!==y.size||M.mtimeMs!==y.mtimeMs)throw new Error("File changed while preparing delivery; retry after it is saved")}finally{await c.close()}let p=t.message||"",m=Pi(o),f=_n("sha256").update(l).digest("hex"),h=_n("sha256").update(JSON.stringify([o,f,p])).digest("hex"),_=new FormData;_.set("deliveryId",h),_.set("message",p),_.set("file",new Blob([l]),m);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:_,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 E=await I.json();if(!E.success)throw new Error(`File delivery failed: ${String(E.message||E.code||"request rejected").slice(0,512)}`);let C=E.data;if(!C?.accepted||typeof C.messageId!="string"||!C.messageId||typeof C.fileId!="string"||!C.fileId)throw new Error("File delivery did not return a saved message and file receipt");return{content:[{type:"text",text:JSON.stringify(C)}],structuredContent:C,isError:!1}}}}var Hi=new Set(["Bash","PowerShell"]),Fi=new Set(["Edit","Write","MultiEdit","NotebookEdit"]),Bi="SandboxNetworkAccess",Tn=2e3,En=50;function ut(e,t=0){return typeof e=="string"?e.length>Tn?`${e.slice(0,Tn)}\u2026`:e:t>=4&&(Array.isArray(e)||d(e))?"\u2026":Array.isArray(e)?e.slice(0,En).map(r=>ut(r,t+1)):d(e)?Object.fromEntries(Object.entries(e).slice(0,En).map(([r,n])=>[r,ut(n,t+1)])):e}function ji(e){let t=e.tool_name,r=e.input,n=Hi.has(t)?"command":Fi.has(t)?"file_change":t===Bi?"permission":"other",s=r.file_path||r.notebook_path;return{runtime:"claude",kind:n,toolName:t,title:typeof e.description=="string"?e.description:"",...n==="command"&&typeof r.command=="string"?{command:r.command}:{},...n==="file_change"&&typeof s=="string"?{paths:[s]}:{},input:ut(r)}}async function On(e,t,r){if(e?.subtype!=="can_use_tool"||typeof e.tool_name!="string"||!d(e.input))return{subtype:"error",error:`OrchaAI does not handle Claude control request ${e?.subtype}`};let n=await t(ji(e),{signal:r}),s=n?.response?.reason||n?.reason||n?.outcome||"not approved";return{subtype:"success",response:n?.outcome==="approved"?{behavior:"allow",updatedInput:e.input}:{behavior:"deny",message:`OrchaAI did not approve this action (${s}). Do not retry the same action unless the user asks.`}}}var qi=new Set(["threadId","turnId","itemId","approvalId","startedAtMs","environmentId","command","cwd","reason"]);function Sn(e,t,r){let n=Object.fromEntries(Object.entries(t).filter(([i,o])=>!qi.has(i)&&o!=null)),s={runtime:"codex",title:typeof t.reason=="string"?t.reason:"",input:ut(n)};if(e==="item/commandExecution/requestApproval")return{...s,kind:"command",toolName:"shell",...typeof t.command=="string"?{command:t.command}:{},...typeof t.cwd=="string"?{cwd:t.cwd}:{}};if(e==="item/fileChange/requestApproval"){let i=Array.isArray(r?.changes)?r.changes.map(o=>o?.path).filter(o=>typeof o=="string"):[];return{...s,kind:"file_change",toolName:"apply_patch",...i.length?{paths:i}:{}}}return{...s,kind:"permission",...typeof t.cwd=="string"?{cwd:t.cwd}:{}}}function Rn(e,t,r){return e==="item/permissions/requestApproval"?{permissions:Object.fromEntries(Object.entries(d(t.permissions)?t.permissions:{}).filter(([,s])=>r&&s!=null)),scope:"turn"}:{decision:r?"accept":"decline"}}var xn=e=>Gi("sha256").update(JSON.stringify(e)).digest("hex"),Q=(e,t)=>Object.assign(new Error(t),{code:e}),An=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,ke="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(`
5
5
  `):""}var Pt=(e,t)=>({sessionUpdate:e,content:{type:"text",text:t}});function Yi(e,t,{emitThoughts:r,streamText:n}){let s=e?.type;if(s==="result"&&e.is_error!==!0){let c=typeof e.result=="string"?e.result:"",l=t.streamed;return t.text=t.streamed="",c?l?l.trim()===c.trim()?[]:[Pt("agent_message_snapshot",c)]:[Pt("agent_message_chunk",c)]:[]}if(!["assistant","user","stream_event"].includes(s))return null;let i=[];if(e.parent_tool_use_id)return i;let o=()=>{let c=t.streamed||t.text;t.streamed&&i.push(Pt("agent_message_snapshot","")),c&&r&&i.push(Pt("agent_thought_chunk",c)),t.text=t.streamed=""},a=c=>{t.streamed=(t.streamed||"")+c,i.push(Pt("agent_message_chunk",c))};if(s==="stream_event"){if(!n)return i;t.streaming=!0;let c=e.event,l=c?.content_block?.type;return c?.type==="content_block_start"&&l==="tool_use"?o():c?.type==="content_block_start"&&l==="text"&&t.streamed?a(`
6
6
 
7
7
  `):c?.type==="content_block_delta"&&c.delta?.type==="text_delta"&&c.delta.text&&a(c.delta.text),i}for(let c of Array.isArray(e.message?.content)?e.message.content:[])s==="user"?c?.type==="tool_result"&&c.tool_use_id&&i.push({sessionUpdate:"tool_call_update",toolCallId:c.tool_use_id,status:c.is_error?"failed":"completed",rawOutput:Xi(c.content)}):c?.type==="text"&&c.text?t.streaming||(t.text=t.text?`${t.text}
@@ -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 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(`
1
+ import{getPluginRuntimeGatewayRequestScope as Ve}from"openclaw/plugin-sdk/plugin-runtime";import{loadOutboundMediaFromUrl as Ge}from"openclaw/plugin-sdk/outbound-media";function Re(e){return String(e??"").trim()}var q="[redacted]",Me=/(authorization|api[_-]?key|credential|password|secret|token)/i;function de(e){return Me.test(Re(e))}function ue(e,t=[]){let a=String(e??"");for(let w of t){let d=String(w??"");d.length>=4&&(a=a.split(d).join(q))}return a.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 Y={controlTools:["find_capabilities_and_skills","describe_capability","inspect_result","execute_capability"],residentTools:["search_orcha_docs","knowledge_search"]};var X=Object.freeze([...Y.controlTools,...Y.residentTools]),Pe=new Set(X),xe=8*1024*1024;function pe(e,t){if(!Array.isArray(e)||e.length!==1)throw new Error("one task-scoped Orcha MCP server is required");let a=e[0],w=new URL(a.url);if(a.name!=="orcha"||a.type!=="http"||!["http:","https:"].includes(w.protocol)||w.username||w.password||w.hash||t&&w.href!==new URL(t).href)throw new Error("Orcha MCP server does not match the trusted binding");let d=Object.fromEntries((a.headers||[]).map(({name:T,value:s})=>[T.toLowerCase(),s]));if(!String(d.authorization||"").startsWith("Bearer "))throw new Error("Orcha MCP task credentials are missing");return{url:w.href,headers:{...d,"content-type":"application/json",accept:"application/json"}}}async function j(e){let t=0,a=[];for await(let w of e){if(t+=w.length,t>xe)throw new Error("MCP payload exceeds the size limit");a.push(Buffer.from(w))}return JSON.parse(Buffer.concat(a).toString("utf8"))}async function ee(e,t,a){let w=await fetch(e.url,{method:"POST",headers:e.headers,body:JSON.stringify(t),redirect:"error",signal:AbortSignal.any([AbortSignal.timeout(36e5),...a?[a]:[]])});if(!w.ok)throw new Error(`Orcha MCP request failed (${w.status})`);if(w.status===202||w.status===204)return null;let d=await j(w.body);if(!d||d.jsonrpc!=="2.0"||d.id!==t.id)throw new Error("Orcha MCP response identity mismatch");return d}async function fe(e,t){let a=await ee(e,{jsonrpc:"2.0",id:"orcha-bind-tools",method:"tools/list"},t),w=a?.result?.tools;if(a?.error){let d=Object.entries(e.headers).filter(([u])=>de(u)).flatMap(([,u])=>[u,String(u).replace(/^Bearer\s+/i,"")]),T=typeof a.error.message=="string"?ue(a.error.message,d).slice(0,512):"",s=Number.isInteger(a.error.code)?` (${a.error.code})`:"";throw new Error(`Orcha MCP tool discovery failed${s}${T?`: ${T}`:""}`)}return Ue(w)}function Ue(e){if(!Array.isArray(e)||e.some(t=>!t||!Pe.has(t.name)||t.inputSchema?.type!=="object"||typeof t.description!="string")||new Set(e.map(t=>t.name)).size!==e.length||e.length&&Y.controlTools.some(t=>!e.some(a=>a.name===t)))throw new Error("Orcha MCP returned an unsupported or invalid authorized tool catalog");return e}function me(e,t){let a=d=>Array.isArray(d)?d.map(a):d&&typeof d=="object"?Object.fromEntries(Object.keys(d).sort().map(T=>[T,a(d[T])])):d,w=d=>d.map(({name:T,inputSchema:s})=>({name:T,inputSchema:s})).sort((T,s)=>T.name.localeCompare(s.name));return JSON.stringify(a(w(e)))===JSON.stringify(a(w(t)))}var te=e=>Object.assign(new Error(e),{status:409});function he(e){let t=new Map,a=e.pluginConfig?.allowedOrchaMcpUrl;if(!a)throw new Error("Orcha plugin requires allowedOrchaMcpUrl");function w(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()?(w(s,u),null):u}async function T(s,{refresh:u=!1}={}){let{runId:I,sessionKey:p,agentCode:N,expiresAt:U,mcpServer:n}=s,_=Date.parse(U);if(typeof I!="string"||!I||typeof p!="string"||!p||typeof N!="string"||!N||!p.startsWith(`agent:${N}:`)||!Number.isFinite(_)||_<=Date.now()||_>Date.now()+24*36e5)throw new Error("invalid_binding_scope");let f=d(p);if(u&&!f||f&&(f.runId!==I||f.agentCode!==N||f.deadline!==_))throw te("original_binding_unavailable_or_changed");let L=pe([n],a),x=f?.lifetime||new AbortController,v=await fe(L,x.signal);if(d(p)!==f)throw te("binding_changed");if(f){if(!me(f.tools,v))throw te("frozen_tool_catalog_changed");f.upstream=L}else{let r={runId:I,agentCode:N,deadline:_,upstream:L,tools:v,lifetime:x};r.timer=setTimeout(()=>w(p,r),_-Date.now()),r.timer.unref?.(),t.set(p,r)}}return e.registerTool(s=>{let u=d(s.sessionKey);return!u||s.agentId!==u.agentCode?null:u.tools.map(I=>({name:`orcha_${I.name}`,label:`Orcha ${I.name}`,description:I.description,parameters:I.inputSchema,async execute(p,N,U){if(d(s.sessionKey)!==u||s.agentId!==u.agentCode||!p||!u.tools.some(_=>_.name===I.name))throw new Error("Orcha task binding expired or changed");let n=await ee(u.upstream,{jsonrpc:"2.0",id:p,method:"tools/call",params:{name:I.name,arguments:N}},AbortSignal.any([u.lifetime.signal,...U?[U]:[]]));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:X.map(s=>`orcha_${s}`)}),{bind:T,active:d,release:w,allowedUrl:a}}import{createHash as De}from"node:crypto";import{once as He}from"node:events";import{mkdirSync as $e,readFileSync as Be,renameSync as je,writeFileSync as Fe}from"node:fs";import{join as _e}from"node:path";import{createHash as ke}from"node:crypto";var ge=e=>ke("sha256").update(JSON.stringify(e)).digest("hex"),F=e=>Object.assign(new Error(e),{code:e}),ne=e=>{let t=String(e||"").replace(/^orcha:/,"");return/^[1-9]\d{0,18}$/.test(t)?t:void 0},ye={normalizeTarget:ne,targetResolver:{looksLikeId:e=>!!ne(e),hint:"Orcha session ID"}};function we({core:e,load:t,save:a,loadMedia:w,activeRun:d}){let T=new Map,s=(n,_)=>ge([n,_]),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 I(n,_,f={}){return await f.onPlatformSendDispatch?.(),f.signal?.throwIfAborted(),f.assertDirectAdapterHandoff?.(),u(await e(n,"/messages",_.payload,{cfg:f.cfg,signal:f.signal}))}async function p(n){n.signal?.throwIfAborted();let _=ne(n.to);if(!_)throw F("invalid_conversation");if(!n.deliveryQueueId)throw F("OPENCLAW_DURABLE_DELIVERY_ID_REQUIRED");let f=n.run&&n.run.delivery.bindingId===n.accountId&&n.run.delivery.sessionId===_?n.run:null,L=n.replyToId||f?.delivery.messageId||null,x=n.payload||{text:n.text||"",mediaUrl:n.mediaUrl},v=x.mediaUrls||(x.mediaUrl?[x.mediaUrl]:[]),r=s(n.accountId,n.deliveryQueueId),i=ge([_,x.text||"",v,L,f?.runId||null]),o=t(r,"sends");if(o&&o.requestHash!==i)throw F("channel_send_conflict");let c=T.get(r);if(c){if(c.requestHash!==i)throw F("channel_send_conflict");return c.promise}let m=(async()=>{let h=o;if(!h){let O=[];for(let E of v){let A=await w(E,{maxBytes:33554432,mediaAccess:n.mediaAccess,mediaReadFile:n.mediaReadFile,mediaLocalRoots:n.mediaLocalRoots}),y=new FormData;y.set("sessionId",_),y.set("file",new Blob([A.buffer],{type:A.contentType||"application/octet-stream"}),A.fileName||"attachment"),O.push((await e(n.accountId,"/files",y,{cfg:n.cfg,signal:n.signal})).inputPart)}h={requestHash:i,payload:{sourceMessageId:`openclaw:${r}`,sessionId:_,content:x.text||"",inputParts:O,...L?{replyToMessageId:L}:{},...f?{agentRunId:f.runId}:{}}},a(r,h,"sends")}let l=await I(n.accountId,h,n);return f&&!f.messageIds.includes(l.messageId)&&f.messageIds.push(l.messageId),l})().finally(()=>T.delete(r));return T.set(r,{requestHash:i,promise:m}),m}return{send:p,message:{send:{text:p,media:p,payload:p},durableFinal:{capabilities:{text:!0,media:!0,payload:!0,replyTo:!0,reconcileUnknownSend:!0},automaticUnknownSendReconciliation:!0,reconcileUnknownSendKinds:{text:!0,media:!0,payload:!0},async reconcileUnknownSend(n){let _=t(s(n.accountId,n.queueId),"sends");if(!_)return{status:"not_sent"};if(_.payload.sessionId!==String(n.to).replace(/^orcha:/,""))throw F("channel_send_conflict");let f=await I(n.accountId,_,n);return{status:"sent",receipt:f.receipt,messageId:f.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 F("unsupported_channel_action");let _=n.params;if(n.dryRun)return{content:[{type:"text",text:"Orcha send dry run"}],details:{dryRun:!0}};let f=d(n.sessionKey),L=await p({cfg:n.cfg,accountId:n.accountId,to:_.to||_.target,text:_.message,mediaUrl:_.media,replyToId:_.replyTo,deliveryQueueId:_.idempotencyKey,mediaAccess:n.mediaAccess,mediaLocalRoots:n.mediaLocalRoots,mediaReadFile:n.mediaReadFile,run:f,signal:f?.controller.signal});return{content:[{type:"text",text:JSON.stringify(L)}],details:L}}}}}var V="application/x-orcha-channel-events-v2+ndjson";function G(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 re(e,t){let a=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(a)?Object.assign(G("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:a||"REQUEST_TIMEOUT"}}):e}var Ie=e=>De("sha256").update(JSON.stringify(e)).digest("hex"),b=(e,t=409)=>Object.assign(new Error(e),{status:t,code:e}),Q=e=>typeof e=="string"&&/^[1-9]\d{0,18}$/.test(e),Je=e=>new Promise(t=>setTimeout(t,e));function Ee(e,t,a){return`agent:${e}:orcha:task:${Ie([a,t.bindingId,t.bindingRevision,t.sessionId,t.taskContextId,t.memberId,t.historyFromSeq,t.runtimePolicyRevision])}`}function Oe(e,t,a,w,d,T){let s=new Map,u=new Map;e.on("before_message_write",({message:r},i)=>{if(r?.role!=="assistant")return;let o=t.active(i.sessionKey),c=s.get(o?.runId);c&&i.agentId===o.agentCode&&(c.silentFinal=T(r))});let I=()=>e.runtime.config.current();function p(r){let i=u.get(r);if(!i||i.aborted)throw b("OPENCLAW_CHANNEL_RUNTIME_UNAVAILABLE",503);return i}function N(r,i=I()){let o=i?.channels?.orcha?.accounts?.[r];if(!Q(r)||!o||o.enabled===!1||!o.serviceToken||!o.agentId)throw b("orcha_channel_account_unavailable",403);return{...o,accountId:r}}async function U(r,i,o,{cfg:c,signal:m,method:h="POST"}={}){let l=N(r,c),O=new URL(`/api/agent-channels${i}`,t.allowedUrl),E=o instanceof FormData,A=AbortSignal.any([AbortSignal.timeout(3e4),p(r),...m?[m]:[]]);try{A.throwIfAborted();let y=await fetch(O,{method:h,redirect:"error",signal:A,headers:{authorization:`Bearer ${l.serviceToken}`,...E?{}:{"content-type":"application/json"}},...o!==void 0?{body:E?o:JSON.stringify(o)}:{}}),k=await j(y.body);if(!y.ok||k.success!==!0)throw b(`orcha_channel_request_${y.status}`,y.status);return k.data}catch(y){throw re(y,A)}}function n(r,i="runs"){if(!/^[a-zA-Z0-9_-]{1,128}$/.test(r))throw b("invalid_record_identity",422);let o=_e(e.runtime.state.resolveStateDir(),"plugins","orcha-runtime",i);return $e(o,{recursive:!0,mode:448}),_e(o,`${r}.json`)}function _(r,i){try{return JSON.parse(Be(n(r,i),"utf8"))}catch(o){if(o.code==="ENOENT")return null;throw o}}function f(r,i,o){let c=n(r,o),m=`${c}.pending`;Fe(m,JSON.stringify(i),{mode:384}),je(m,c)}async function L(r,i=!1,o){let c=N(r.delivery?.bindingId);p(c.accountId);let{runId:m,delivery:h}=r;if(!Q(m)||!Q(h.sessionId)||h.taskContextId!==null&&!Q(h.taskContextId)||h.mode!=="channel"||r.agentCode!==c.agentId)throw b("invalid_channel_delivery",422);if(!Array.isArray(r.prompt)||r.prompt.some(R=>!["text","image","file"].includes(R.type)||(R.type==="text"?typeof R.text!="string":typeof R.uri!="string")))throw b("invalid_channel_prompt",422);let l=Ie({agentCode:r.agentCode,delivery:h,prompt:r.prompt}),O=_(m);if(O&&O.requestHash!==l)throw b("channel_delivery_conflict");if(O?.status==="completed")return O.result;if(O?.status==="failed")throw b(O.error);let E=s.get(m),A=O?.expiresAt||r.expiresAt,y=Ee(c.agentId,h,t.allowedUrl),k=()=>{let R=t.active(y);R?.runId===m&&t.release(y,R)},P=O?.hostRunId||`orcha-${m}`;if(O&&!E||r.attachOnly&&!E&&!O)throw b("RUNTIME_OPERATION_NOT_FOUND");if(E){try{await t.bind({runId:m,sessionKey:y,agentCode:c.agentId,expiresAt:A,mcpServer:r.mcpServer},{refresh:!0})}catch(R){if(s.get(m)!==E)return await E.promise;throw R}if(i)return{refreshed:!0};E.listeners.add(o);try{for(let R of E.updates)o?.(R);return await E.promise}finally{E.listeners.delete(o)}}if(i)throw b("RUNTIME_OPERATION_NOT_FOUND");let C=new AbortController,M={runId:m,delivery:h,messageIds:[],controller:C,promise:null,listeners:new Set(o?[o]:[]),updates:[],bytes:0},$=R=>{let D={type:"update",payload:{sessionId:y,update:R,_meta:{channelUpdateId:`${P}:${M.updates.length+1}`}}},B=Buffer.byteLength(JSON.stringify(D));if(B>2097152||M.bytes+B>16777216){C.abort(G("OPENCLAW_CHANNEL_PROGRESS_LIMIT"));return}M.bytes+=B,M.updates.push(D);for(let Z of M.listeners)Z?.(D)};return s.set(m,M),M.promise=(async()=>{await t.bind({runId:m,sessionKey:y,agentCode:c.agentId,expiresAt:A,mcpServer:r.mcpServer}),f(m,{requestHash:l,status:"running",sessionKey:y,hostRunId:P,expiresAt:A});let R=0,D,B,Z=setTimeout(()=>C.abort(b("run_timeout")),Date.parse(A)-Date.now());try{let z=e.runtime.channel.reply;if(typeof z?.dispatchReplyWithBufferedBlockDispatcher!="function"||typeof e.runtime.events?.onAgentEvent!="function")throw b("OPENCLAW_CHANNEL_RUNTIME_UNAVAILABLE");B=e.runtime.events.onAgentEvent(g=>{let S=g.data;g.runId!==P||g.stream!=="tool"||!S?.toolCallId||S.hideFromChannelProgress||!["start","update","result"].includes(S.phase)||$({sessionUpdate:S.phase==="start"?"tool_call":"tool_call_update",toolCallId:S.toolCallId,title:S.name,status:S.phase==="result"?S.isError?"failed":"completed":"in_progress",...S.args?{rawInput:S.args}:{},...S.result!==void 0?{rawOutput:S.result}:{}})});let H="",ie="",J="",be=g=>{if(typeof g.text!="string")return;let S=[ie,g.text].filter(Boolean).join(`
2
2
 
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(`
3
+ `);if(S===J)return;let W=S.startsWith(J);$({sessionUpdate:W?"agent_message_chunk":"agent_message_snapshot",content:{type:"text",text:W?S.slice(J.length):S}}),J=S},ae=g=>{if(g.requiresReasoningProgressOptIn||typeof g.text!="string")return;let S=g.text.startsWith(H)?g.text.slice(H.length):g.text;H=g.text,S&&$({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:S}})},K=r.prompt.filter(g=>g.type==="text").map(g=>g.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:l,activeRun:r=>s.get(t.active(r)?.runId)});e.registerChannel({plugin:{id:"orcha",meta:{id:"orcha",label:"Orcha",selectionLabel:"Orcha",docsPath:"/channels/orcha",blurb:"Enterprise people and Agent conversations"},capabilities:{chatTypes:["direct","group"],media:!0},config:{listAccountIds:r=>Object.keys(r?.channels?.orcha?.accounts||{}),inspectAccount:(r,d)=>{let o=r?.channels?.orcha?.accounts?.[d];return{enabled:!!(o&&o.enabled!==!1),configured:!!(o?.serviceToken&&o?.agentId),tokenStatus:o?.serviceToken?"available":"missing"}},resolveAccount:(r,d)=>_(d,r),isEnabled:r=>r.enabled!==!1,isConfigured:r=>!!(r.serviceToken&&r.agentId)},outbound:{deliveryMode:"direct",textChunkLimit:1e5},message:h.message,actions:h.actions,messaging:he}});async function L(r){let{accountId:d,grantId:o,externalInvocationId:a}=r;_(d);let p=await c(d,"/runs",{grantId:o,externalInvocationId:a,input:r.input||{}}),y=p.agentRunId;if(["completed","failed","cancelled","expired"].includes(p.status))return p;let E;do E=await c(d,`/runs/${y}/claim`,{}),E.attemptId||await je(Math.max(1,E.retryAfterSeconds||2)*1e3);while(!E.attemptId);let O=we(_(d).agentId,E.delivery,t.allowedUrl),w,S=!1,I=setInterval(async()=>{if(!S){S=!0;try{let b=await c(d,`/runs/${y}/heartbeat`,{attemptId:E.attemptId});t.active(O)&&await t.bind({runId:y,sessionKey:O,agentCode:_(d).agentId,expiresAt:E.expiresAt,mcpServer:b.mcpServer},{refresh:!0})}catch(b){w=b,s.get(y)?.controller.abort(b),t.release(O)}finally{S=!1}}},Math.max(1,E.heartbeatIntervalSeconds)*1e3),P,N;try{let b;try{b=await m({runId:y,agentCode:_(d).agentId,delivery:E.delivery,prompt:[{type:"text",text:JSON.stringify({task:E.prompt,eventInput:E.input})}],mcpServer:E.mcpServer,expiresAt:E.expiresAt,attachOnly:E.recovery})}catch(H){N=H}if(w)throw w;P=N?{attemptId:E.attemptId,errorMessage:Y(N.code||"channel_host_failed").message,status:"failed"}:{attemptId:E.attemptId,messageIds:b.messageIds,status:"completed"};let x=await c(d,`/runs/${y}/complete`,P);if(N)throw N;return x}finally{clearInterval(I),t.release(O)}}for(let[r,d]of[["deliveries",m],["background",L]])e.registerHttpRoute({path:`/plugins/orcha-runtime/${r}`,auth:"gateway",match:"exact",async handler(o,a){let p,y=Promise.resolve(),E=0,O=w=>{if(a.destroyed||a.writableEnded)return;let S=JSON.stringify(w)+`
6
- `,I=Buffer.byteLength(S);if(I>2097152||E+a.writableLength+I>2097152){a.destroy();return}return E+=I,y=y.then(async()=>{a.destroyed||a.writableEnded||(await i(),a.write(S))}).catch(P=>{!a.destroyed&&!a.writableEnded&&a.end(JSON.stringify({type:"error",code:P.code||"OPENCLAW_CHANNEL_AUTH_FAILED"})+`
7
- `)}).finally(()=>{E-=I}),y};try{if(r==="deliveries"&&o.method==="GET"){await i(),a.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify({streamType:K}));return}if(!["POST","PATCH","DELETE"].includes(o.method))throw R("method_not_allowed",405);let w=await B(o);if(await i(),r==="deliveries"&&o.method==="POST"){if(o.headers.accept!==K)throw R("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH",409);a.writeHead(200,{"content-type":K,"cache-control":"no-store","x-accel-buffering":"no"}),O({type:"heartbeat"}),p=setInterval(()=>O({type:"heartbeat"}),15e3),a.once("close",()=>clearInterval(p));let I=await m(w,!1,O);await i(),await O({type:"result",result:I}),a.end();return}if(o.method==="DELETE"){let I=s.get(w.runId);I?.controller.abort(R("RUNTIME_OPERATION_CANCELLED")),a.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify({cancelled:!!I}));return}if(o.method==="PATCH"&&r!=="deliveries")throw R("method_not_allowed",405);let S=await d(w,o.method==="PATCH");await i(),a.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify(S))}catch(w){a.headersSent?(await O({type:"error",code:w.code||"channel_host_failed"}),a.end()):a.writableEnded||a.writeHead(w.status||500,{"content-type":"application/json"}).end(JSON.stringify({error:w.code||w.message}))}finally{clearInterval(p)}}})}function Ee(e,t,i,g){return{id:"orcha-runtime",name:"Orcha Channel and authorized tools",register(l){let T=fe(l);l.registerHttpRoute({path:"/plugins/orcha-runtime/mcp-bindings",auth:"gateway",match:"exact",async handler(s,u){let _=(c,M)=>{u.writeHead(c,{"content-type":"application/json"}),u.end(JSON.stringify(M))};try{if(s.method==="GET"){_(200,{ready:!0});return}if(!["PUT","DELETE"].includes(s.method)){_(405,{error:"method_not_allowed"});return}let c=await B(s);if(await e(),typeof c.runId!="string"||!c.runId||typeof c.sessionKey!="string"||!c.sessionKey){_(422,{error:"invalid_binding_identity"});return}let M=T.active(c.sessionKey);if(s.headers["if-match"]&&s.headers["if-match"]!==c.runId){_(409,{error:"binding_run_conflict"});return}if(M&&M.runId!==c.runId){_(409,{error:"session_already_bound"});return}s.method==="DELETE"?T.release(c.sessionKey):await T.bind(c,{refresh:!!s.headers["if-match"]}),_(200,{[s.method==="DELETE"?"released":"bound"]:!0})}catch(c){u.writableEnded||_(c.status||422,{error:c.message})}}}),_e(l,T,e,t,i,g)}}}import{isFastModeAutoProgressPayload as Fe,isReasoningReplyPayload as Je,isReplyPayloadNonTerminalToolErrorWarning as We,isReplyPayloadTtsSupplement as ze}from"openclaw/plugin-sdk/reply-payload";import{isSilentReplyText as Oe}from"openclaw/plugin-sdk/reply-chunking";function Te(e){return e?.role!=="assistant"||e.stopReason!=="stop"?!1:typeof e.content=="string"?Oe(e.content):!Array.isArray(e.content)||e.content.some(t=>!["text","thinking"].includes(t.type))?!1:Oe(e.content.filter(t=>t.type==="text").map(t=>t.text).join(`
8
- `))}function Ae(e){return!Je(e)&&!e.isCommentary&&!e.isCompactionNotice&&!e.isFallbackNotice&&!e.isStatusNotice&&!Fe(e)&&!We(e)&&!ze(e)}var Tt=Ee(async()=>{await Ke()?.revalidate?.()},Ae,Ye,Te);export{Tt as default};
5
+ `),se=r.prompt.filter(g=>g.type!=="text"),Ce={Body:K,BodyForAgent:K,BodyForCommands:K,RawBody:K,From:`orcha:${h.memberId}`,To:`orcha:${h.sessionId}`,SessionKey:y,AccountId:h.bindingId,Provider:"orcha",Surface:"orcha",ChatType:"direct",OriginatingChannel:"orcha",OriginatingTo:h.sessionId,MessageSid:h.messageId||m,MediaUrls:se.map(g=>g.uri),MediaTypes:se.map(g=>g.mimeType||"application/octet-stream"),CommandAuthorized:!1,WasMentioned:!0};if(await z.dispatchReplyWithBufferedBlockDispatcher({ctx:Ce,cfg:I(),replyOptions:{runId:P,abortSignal:C.signal,suppressTyping:!0,suppressDefaultToolProgressMessages:!0,suppressToolErrorWarnings:!0,disableBlockStreaming:!0,reasoningPayloadsEnabled:!0,commentaryPayloadsEnabled:!0,onAssistantMessageStart:()=>{H="",ie=J},onPartialReply:be,onReasoningStream:ae},dispatcherOptions:{deliver:async(g,S)=>{if(C.signal.throwIfAborted(),g.isReasoning&&ae(g),g.isCommentary&&g.text&&$({sessionUpdate:"agent_thought_chunk",content:{type:"text",text:g.text}}),S.kind==="final"&&w(g)){if(M.silentFinal&&M.messageIds.length&&!g.isError)return;let W=I(),le=e.runtime.agent.resolveAgentWorkspaceDir(W,c.agentId);await x.send({cfg:W,accountId:h.bindingId,to:h.sessionId,payload:g,run:M,deliveryQueueId:`${P}:final:${++R}`,signal:C.signal,mediaLocalRoots:le?[le]:void 0})}},onError:g=>{D??=g}}}),D)throw D;if(C.signal.throwIfAborted(),!M.messageIds.length)throw b("runtime_node_empty_result");let ce={stopReason:"end_turn",messageIds:M.messageIds,sessionId:y};return f(m,{requestHash:l,status:"completed",sessionKey:y,hostRunId:P,expiresAt:A,result:ce}),ce}catch(z){let H=C.signal.aborted?C.signal.reason:re(z,C.signal);throw f(m,{requestHash:l,status:"failed",sessionKey:y,hostRunId:P,expiresAt:A,error:H.code||"channel_host_failed"}),H}finally{B?.(),clearTimeout(Z),k(),s.delete(m)}})().catch(R=>{throw k(),s.delete(m),R}),M.promise}let x=we({core:U,load:_,save:f,loadMedia:d,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,i)=>{let o=r?.channels?.orcha?.accounts?.[i];return{enabled:!!(o&&o.enabled!==!1),configured:!!(o?.serviceToken&&o?.agentId),tokenStatus:o?.serviceToken?"available":"missing"}},resolveAccount:(r,i)=>N(i,r),isEnabled:r=>r.enabled!==!1,isConfigured:r=>!!(r.serviceToken&&r.agentId)},gateway:{async startAccount({cfg:r,accountId:i,abortSignal:o,setStatus:c}){if(N(i,r),o.aborted)return;if(u.has(i))throw b("channel_delivery_conflict");u.set(i,o);let m=He(o,"abort");try{c({accountId:i,running:!0,lifecycle:"ready",lastError:null}),await m}finally{u.delete(i);let h=[...s.values()].filter(l=>l.delivery.bindingId===i);for(let l of h)l.controller.abort(b("RUNTIME_OPERATION_CANCELLED"));await Promise.allSettled(h.map(l=>l.promise)),c({accountId:i,running:!1,lifecycle:"stopped"})}}},outbound:{deliveryMode:"direct",textChunkLimit:1e5},message:x.message,actions:x.actions,messaging:ye}});async function v(r){let{accountId:i,grantId:o,externalInvocationId:c}=r;N(i),p(i);let m=await U(i,"/runs",{grantId:o,externalInvocationId:c,input:r.input||{}}),h=m.agentRunId;if(["completed","failed","cancelled","expired"].includes(m.status))return m;let l;do l=await U(i,`/runs/${h}/claim`,{}),l.attemptId||await Je(Math.max(1,l.retryAfterSeconds||2)*1e3);while(!l.attemptId);let O=Ee(N(i).agentId,l.delivery,t.allowedUrl),E,A=!1,y=setInterval(async()=>{if(!A){A=!0;try{let C=await U(i,`/runs/${h}/heartbeat`,{attemptId:l.attemptId});t.active(O)&&await t.bind({runId:h,sessionKey:O,agentCode:N(i).agentId,expiresAt:l.expiresAt,mcpServer:C.mcpServer},{refresh:!0})}catch(C){E=C,s.get(h)?.controller.abort(C),t.release(O)}finally{A=!1}}},Math.max(1,l.heartbeatIntervalSeconds)*1e3),k,P;try{let C;try{C=await L({runId:h,agentCode:N(i).agentId,delivery:l.delivery,prompt:[{type:"text",text:JSON.stringify({task:l.prompt,eventInput:l.input})}],mcpServer:l.mcpServer,expiresAt:l.expiresAt,attachOnly:l.recovery})}catch($){P=$}if(E)throw E;k=P?{attemptId:l.attemptId,errorMessage:G(P.code||"channel_host_failed").message,status:"failed"}:{attemptId:l.attemptId,messageIds:C.messageIds,status:"completed"};let M=await U(i,`/runs/${h}/complete`,k);if(P)throw P;return M}finally{clearInterval(y),t.release(O)}}for(let[r,i]of[["deliveries",L],["background",v]])e.registerHttpRoute({path:`/plugins/orcha-runtime/${r}`,auth:"gateway",match:"exact",async handler(o,c){let m,h=Promise.resolve(),l=0,O=E=>{if(c.destroyed||c.writableEnded)return;let A=JSON.stringify(E)+`
6
+ `,y=Buffer.byteLength(A);if(y>2097152||l+c.writableLength+y>2097152){c.destroy();return}return l+=y,h=h.then(async()=>{c.destroyed||c.writableEnded||(await a(),c.write(A))}).catch(k=>{!c.destroyed&&!c.writableEnded&&c.end(JSON.stringify({type:"error",code:k.code||"OPENCLAW_CHANNEL_AUTH_FAILED"})+`
7
+ `)}).finally(()=>{l-=y}),h};try{if(r==="deliveries"&&o.method==="GET"){await a(),c.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify({streamType:V}));return}if(!["POST","PATCH","DELETE"].includes(o.method))throw b("method_not_allowed",405);let E=await j(o);if(await a(),r==="deliveries"&&o.method==="POST"){if(o.headers.accept!==V)throw b("OPENCLAW_CHANNEL_PROTOCOL_MISMATCH",409);c.writeHead(200,{"content-type":V,"cache-control":"no-store","x-accel-buffering":"no"}),O({type:"heartbeat"}),m=setInterval(()=>O({type:"heartbeat"}),15e3),c.once("close",()=>clearInterval(m));let y=await L(E,!1,O);await a(),await O({type:"result",result:y}),c.end();return}if(o.method==="DELETE"){let y=s.get(E.runId);y?.controller.abort(b("RUNTIME_OPERATION_CANCELLED")),c.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify({cancelled:!!y}));return}if(o.method==="PATCH"&&r!=="deliveries")throw b("method_not_allowed",405);let A=await i(E,o.method==="PATCH");await a(),c.writeHead(200,{"content-type":"application/json"}).end(JSON.stringify(A))}catch(E){c.headersSent?(await O({type:"error",code:E.code||"channel_host_failed"}),c.end()):c.writableEnded||c.writeHead(E.status||500,{"content-type":"application/json"}).end(JSON.stringify({error:E.code||E.message}))}finally{clearInterval(m)}}})}function Te(e,t,a,w){return{id:"orcha-runtime",name:"Orcha Channel and authorized tools",register(d){let T=he(d);d.registerHttpRoute({path:"/plugins/orcha-runtime/mcp-bindings",auth:"gateway",match:"exact",async handler(s,u){let I=(p,N)=>{u.writeHead(p,{"content-type":"application/json"}),u.end(JSON.stringify(N))};try{if(s.method==="GET"){I(200,{ready:!0});return}if(!["PUT","DELETE"].includes(s.method)){I(405,{error:"method_not_allowed"});return}let p=await j(s);if(await e(),typeof p.runId!="string"||!p.runId||typeof p.sessionKey!="string"||!p.sessionKey){I(422,{error:"invalid_binding_identity"});return}let N=T.active(p.sessionKey);if(s.headers["if-match"]&&s.headers["if-match"]!==p.runId){I(409,{error:"binding_run_conflict"});return}if(N&&N.runId!==p.runId){I(409,{error:"session_already_bound"});return}s.method==="DELETE"?T.release(p.sessionKey):await T.bind(p,{refresh:!!s.headers["if-match"]}),I(200,{[s.method==="DELETE"?"released":"bound"]:!0})}catch(p){u.writableEnded||I(p.status||422,{error:p.message})}}}),Oe(d,T,e,t,a,w)}}}import{isFastModeAutoProgressPayload as We,isReasoningReplyPayload as ze,isReplyPayloadNonTerminalToolErrorWarning as Ke,isReplyPayloadTtsSupplement as Ye}from"openclaw/plugin-sdk/reply-payload";import{isSilentReplyText as Ae}from"openclaw/plugin-sdk/reply-chunking";function Se(e){return e?.role!=="assistant"||e.stopReason!=="stop"?!1:typeof e.content=="string"?Ae(e.content):!Array.isArray(e.content)||e.content.some(t=>!["text","thinking"].includes(t.type))?!1:Ae(e.content.filter(t=>t.type==="text").map(t=>t.text).join(`
8
+ `))}function Ne(e){return!ze(e)&&!e.isCommentary&&!e.isCompactionNotice&&!e.isFallbackNotice&&!e.isStatusNotice&&!We(e)&&!Ke(e)&&!Ye(e)}var St=Te(async()=>{await Ve()?.revalidate?.()},Ne,Ge,Se);export{St as default};
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orcha-ai/openclaw-tools",
3
- "version": "0.1.58",
3
+ "version": "0.1.60",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "openclaw": { "extensions": ["./index.js"] }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orcha-ai/runtime-bridge",
3
- "version": "0.1.58",
3
+ "version": "0.1.60",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Local Orcha runtime bridge for ACP-compatible agent runtimes.",