@orcha-ai/runtime-bridge
v0.1.59
Published
Local Orcha runtime bridge for ACP-compatible agent runtimes.
Maintainers
Readme
Orcha Runtime Bridge
Bridge connects a user's device and discovers Codex, Claude Code and configured OpenClaw agents. Cloud Node Runtime infrastructure is managed separately in cloud-agent-runtime/ and the Runtime Nodes page.
Connect a device
- Open 智能体 → 添加智能体 → 从我的设备添加 in the current tenant.
- Install or update the npm package on the computer with your agents installed. Node.js 22.19 or newer is required.
- Copy and run the one-time connection command. Bridge starts in the background; the terminal can be closed.
- Select discovered agents, confirm names and local directories, then add.
npm install -g @orcha-ai/runtime-bridge@latest
orcha-runtime-bridge connect --url https://orcha.example.com --pair-code ONE_TIME_CODEThe code expires after 10 minutes and is consumed once. The device belongs to the signed-in user and tenant. Imported agents are private by default and use existing sharing settings. Shared users still execute on the owner's device.
For subsequent connections, omit the consumed code:
orcha-runtime-bridge connect --url https://orcha.example.comconnect exchanges the one-time code in the foreground, then starts the existing daemon manager with the saved profile. The code and device credential are not passed to the background command. Reconnecting an already running device returns its existing process; stop it first before replacing its pairing.
Since 0.1.58, network failures reconnect with exponential backoff and jitter, capped at 60 seconds; successful authentication resets the delay. An HTTP or runtime_node.error 401/403 stops reconnecting. Update the device credentials and restart Bridge to connect again; rejected credentials are never retried indefinitely.
Manage the device from any terminal directory with the same server address:
orcha-runtime-bridge status --url https://orcha.example.com
orcha-runtime-bridge reload --url https://orcha.example.com
orcha-runtime-bridge stop --url https://orcha.example.com
orcha-runtime-bridge start --url https://orcha.example.comThe server-specific PID and log files live beside the device profile under ~/.orcha/devices/; --pid-file and --log-file override them. status reports the local process state; the Orcha page reports whether the device is online. Use connect --foreground --url ... for diagnosis after stopping its background process. Closing the terminal does not stop the daemon; shutting down the computer does. This command does not install an OS login/startup service. Legacy env-configured start/status/reload/stop --env-file ... keep their existing behavior.
The credential and local launch configuration live under ~/.orcha/devices/<server-hash>.json, written atomically with mode 0600. A new pairing for the same server replaces that local profile. Disconnect the previous device in Orcha to revoke its credential. Discovery does not upload vendor credentials, command paths, environment maps or transcripts.
Remote deployments require HTTPS; HTTP is allowed only on loopback. Bridge opens an outbound WebSocket to /api/agent-runtime-bridge/ws. The device needs no inbound port. The reverse proxy must forward WebSocket upgrades to the Runtime Gateway.
Models and reasoning (0.1.57)
Device Bridge advertises agents/models through supportedMethods on the existing v2 protocol. Import queries the native model catalog in the selected workspace. The model picker's Sync action re-queries that target; it never changes a conversation selection. Codex uses app-server model/list and config/read; Claude Code uses its stdio initialize response. Only model identifiers, names, native effort levels and defaults leave the device. Authentication, account metadata and launch configuration stay local. Catalog failures are real errors; the platform keeps the last successful catalog.
Per-conversation selections reach Codex turn/start as model / effort, or Claude Code as --model / --effort. Clearing a Codex selection resolves the workspace's native defaults before resuming; Claude uses its native default alias. Native session identity, approvals and task MCP bindings remain in place. A running operation's identity includes these controls, so reconnect cannot substitute another selection. The actual model is recorded only when reported by the native runtime.
The platform stores selections on the agent's conversation member and freezes them when a message is accepted, including settings used by later group delegations. Only the current group owner can edit member model and reasoning settings, and they must have permission to use that agent. Agent ownership and administrator roles alone do not grant permission to change group settings. Group settings do not change the agent's global configuration or sharing rules. Authorized shared users can choose settings for their own direct conversations.
Rollout requires the approved member-column migration on Core, then Bridge 0.1.57 or later installed and reloaded on the device. Existing Bridges retain device-default execution and reject explicit selections until upgraded. OpenClaw currently reports model controls as unsupported and keeps its native defaults; it never receives fabricated catalog choices. Version 0.1.57 was published to npm on 2026-10-16. Native catalog discovery has been checked locally; model execution through an upgraded real device remains an acceptance step.
Discovery and execution
Discovery checks executables in absolute PATH entries and runs fixed probes:
- Codex:
--version,login status. - Claude Code:
--version,auth status(JSON is the default). - OpenClaw:
--version,agents list --json,health --json.
Missing installations are absent; failed probes are explicit errors. Login and Gateway setup happen locally. Discovery does not install applications, sign in, run a model prompt or scan the entire disk. Detection does not guarantee vendor quota or future model calls.
Codex/Claude Code use a user-selected existing local directory. OpenClaw keeps its existing agent ID and directory; its private session key uses that ID, not Orcha's generated Agent code. Core cannot supply arbitrary launch commands. Every selection and directory is validated before one atomic profile update. Core serializes imports by locking the device credential to prevent duplicate Agents.
Codex device targets run codex app-server, the Codex surface that asks its client to approve actions; ordinary directories work as well as Git repositories. Profiles saved by Bridge 0.1.52 or earlier with exactly exec --skip-git-repo-check --json are rewritten to this launch the next time Bridge loads the device profile, and their saved threads resume unchanged. Customized Codex arguments are left untouched and keep running codex exec without approvals until updated locally. Remove this upgrade once connected devices no longer run those profiles.
Claude Code device targets use -p --output-format stream-json --verbose --include-partial-messages and receive the prompt on stdin. Profiles saved by Bridge 0.1.51 or earlier with exactly -p --output-format json --no-session-persistence, and by 0.1.53 or earlier with exactly -p --output-format stream-json --verbose, are rewritten to this launch the next time Bridge loads the device profile; customized Claude arguments are left untouched and must be updated locally if they block native sessions. Remove this upgrade once connected devices no longer run those profiles.
Targets are namespaced by device code and candidate digest. Chat, group delegation, workflow dispatch and recovery are pinned to that device; an offline or revoked device never falls back to a different computer. External execution uses the local CLI's own permissions, not Orcha's cloud Docker Sandbox.
The automated discovery path is exercised on macOS/Linux. On Windows, use WSL with the CLIs installed there; native .cmd/.bat launchers are not supported by the shell-free process adapter.
Official probe references: Codex CLI, Claude Code CLI, OpenClaw agents.
Protocol and cutover
The existing orcha-runtime-node.v2 transport negotiates devices/discover and devices/configure alongside execution/session methods. Existing Node and ServiceToken records are reused. Core checks ownership, exact node/candidate identity, target namespace and the returned selections before creating Agents.
Legacy manual external-node registration is rejected. Platform service tokens create only cloud Node Runtime nodes. Arbitrary runtimeTargetCode is no longer an Agent creation path. The explicit cleanup procedure is in 智能体管理与构建.
Build and validate
npm ci
npm run check
npm test
npm run buildBuild produces bin/orcha-runtime-bridge.js and the clean npm package in dist/package, including the OpenClaw plugin. Bridge is distributed through npm; backend images do not bundle a separate browser download.
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:
npm run release:check &&
npm publish ./dist/orcha-ai-runtime-bridge-0.1.59.tgz --access public --registry=https://registry.npmjs.orgAfter 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.
Installing/updating the npm package alone does not change OpenClaw; run Bridge reload afterwards. Automatic plugin installation uses OpenClaw's official installer and preserves existing plugin/channel configuration. It does not create account credentials or configure MCP authorization. Create a binding in the Orcha Agent's 消息通道 tab, merge its generated channels.orcha.accounts configuration into OpenClaw, and retain the existing Gateway/MCP binding configuration below. A remote mcpBridgeUrl cannot be upgraded by the local reload command: update its plugin on the Gateway host. Source-checkout reload requires npm run build first to provide the self-contained plugin in dist/package. Existing ACP/CLI targets without a native binding continue using their configured execution path. Real OpenClaw host/model acceptance remains required before production use.
Native delivery uses application/x-orcha-channel-events-v2+ndjson with heartbeat, update, result, and error frames. Tool events are restricted to the exact host run and honor hidden-progress flags; reasoning uses only the host's public reply callback without enabling hidden reasoning. Final text and attachments are sent through POST /api/agent-channels/messages; terminal frames carry only messageIds and status. Core validates the existing receipts and projects execution metadata onto the original reply. Core, Bridge and plugin must upgrade together; old JSON/v1 streams and body-based background completion are incompatible. Skill authors use the native message tool with action: "send", channel: "orcha", accountId (binding ID), target (session ID), and message/media. Credentials stay in the configured account. Durable queue IDs and native tool idempotency keys are persisted before sending; unknown acknowledgements reconcile through the same idempotent Core endpoint. Core persists updates under the Attempt fence and deduplicates their stable channel IDs before acknowledging them. An active plugin operation keeps at most 16 MiB of replay history; exceeding it fails explicitly. Plugin restarts cannot reconstruct an in-flight host turn and continue to fail with RUNTIME_OPERATION_NOT_FOUND. This release requires no database migration or new environment variables.
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.
To check reply classification against the real SDK without starting another Gateway, use an existing official [email protected] 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.
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.
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.
Tool error warnings (0.1.46)
The OpenClaw channel sets the host's suppressToolErrorWarnings reply option to prevent synthesized tool-error warnings from becoming extra chat messages. Tool failures remain in the execution progress, and terminal error replies, delivery failures, timeouts, and empty-result checks keep their existing handling. Update the bundled plugin on the OpenClaw host and restart its Gateway for this change to take effect; publishing npm or deploying Core alone does not update an installed Gateway plugin.
Version 0.1.50 honors a terminal NO_REPLY after a confirmed message-tool delivery to the same conversation. It observes the active native session's visible assistant terminal through the host's synchronous before_message_write hook and official silent-reply classifier, preventing accumulated pre-tool text from becoming an extra final message. Normal follow-up replies, terminal errors, failed sends and other conversation targets retain their existing behavior. It does not read hidden reasoning or change protocol, persisted data or environment configuration. Update the installed plugin and restart Gateway after upgrading the package.
Native reply previews use the host's onPartialReply callback. Growing snapshots emit agent_message_chunk; revised or cleared snapshots emit agent_message_snapshot with the complete preview in content.text, projected by Core as the existing message_replace event. Assistant message boundaries separate preview paragraphs. Block streaming is disabled so previews cannot consume final IM delivery. The final Bridge result remains a delivery receipt; only the IM sender persists the actual reply and attachments. This event addition requires the updated Core, Bridge and bundled plugin together; protocol version numbers are unchanged, with no database migration or new environment variable. Existing installed plugins need an explicit update and Gateway restart.
Version 0.1.48 includes these native reply previews. Deploy Core with commit 3c165340 or later before upgrading connected devices, then reload Bridge to update its bundled Gateway plugin.
Long chats and independent topics (0.1.45)
Bridge and the bundled OpenClaw plugin are versioned together. Version 0.1.45 accepts an explicit taskContextId: null for long chats and independent topic conversations. Missing or invalid task identifiers still fail validation. Native session keys include the conversation ID, so separate conversations remain isolated even when both have no embedded task ID. External proactive messages and background results use the existing long chat unless bound to an existing run.
Only the UI new-topic action creates an independent conversation. /new resets the context inside the current conversation. The corresponding Core/frontend update requires the memory and checkpoint migration described in 长聊与独立话题. Publishing this package does not deploy Core or migrate its database. Upgrade the device package and run Bridge reload to install the bundled plugin; update remote Gateway plugins on their own host. No wire protocol version or environment variable is added.
Native conversation context
Version 0.1.49 fixes Codex ordinary conversation admission in Bridge and distinguishes invalid scope, missing Core address and sandbox launch errors. It retains the existing Core session format and native history isolation.
Device Codex accepts Core's existing session-<id>:<human-member>:<agent-member>:<history-floor>:<policy-revision> scope for ordinary conversations and task-<id>:... for task contexts. All five numeric fields remain strings and must be positive decimal integers. The complete scope is preserved in the native identity, including membership, context reset and policy boundaries. Invalid scope, missing Core address and unsupported sandbox launch produce separate errors. This fixes the previous task-only Bridge check without changing Core's payload, protocol version or stored session mappings. Reload the device Bridge after installing the fix; restarting Core alone does not reload the device process.
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.
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. Other raw commands, such as /status, reach OpenClaw and remain subject to its own command permissions.
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.
Delegated group member tools
Codex and Claude Code support task-scoped Orcha MCP through the same local transport adapter. OpenClaw additionally requires the bundled Gateway plugin, a trusted binding endpoint and Gateway authentication. Discovery/import does not install the plugin or configure these credentials.
Claude Code native IM turns (0.1.52)
Device Claude Code now follows the same IM model as device Codex: Core sends only the current message, Bridge resumes the scoped native session, and conversation and delegated turns receive the task's Orcha MCP tools, including send_file. The MCP proxy is passed with --mcp-config; argv contains only the loopback URL and an ${ORCHA_TASK_MCP_TOKEN} header placeholder that Claude Code expands from the child environment. --allowedTools mcp__orcha lets the Core-authorized task tools run without a local prompt; other Claude tools keep the device's own permission settings, and since 0.1.53 anything those settings would prompt for goes to the Orcha user (see Device approvals). Claude Code continues without an unreachable MCP server, so Bridge stops the turn with RUNTIME_CLAUDE_MCP_UNAVAILABLE when system/init does not report orcha as connected; the native session is not advanced.
stream-json events become the existing Orcha progress updates: top-level tool_use/tool_result blocks map to tool_call/tool_call_update, text before a tool call becomes process commentary, and the result event remains the authoritative final reply. Since 0.1.54 the reply streams while Claude writes it (see Claude Code streaming replies). Subagent internals stay inside their parent tool call, tool result images are reduced to their text, and thinking blocks are not forwarded. The generated_images delivery root remains Codex-only; Claude deliverables must be in the workspace or a configured artifact root.
Rollout requires Core with this change, then the updated and reloaded device Bridge. There is no database migration, protocol-version change or new project environment variable. Old Orcha history is not injected into Claude Code. The fixture tests use a fake Claude CLI over a real HTTP MCP endpoint; a real Claude turn was accepted with 0.1.53 (see Device approvals).
Claude Code approvals over stdio (0.1.56)
Claude Code's sandbox asks before it connects to a host that no local rule allows. In print mode it sends that ask only to a stdio host, never to an MCP --permission-prompt-tool. Bridge used to close stdin right after writing the prompt, so the ask failed at once and Claude reported deny network-outbound <host> (user denied) although nobody had been asked. Group-chat turns that needed GitLab or the Alibaba Cloud API failed this way.
Native IM turns now launch Claude Code with --input-format stream-json --permission-prompt-tool stdio. The prompt is the first user input message, and stdin stays open until the turn's result event. Bridge answers each control_request itself:
can_use_toolcarries both tool prompts and theSandboxNetworkAccessnetwork ask. Both go to the Orcha user through the existing approval contract. A network ask is reported askind: "permission"withtoolName: "SandboxNetworkAccess", Claude's ownAllow network connection to <host>?astitleandinput: {host}. Approval answers{"behavior":"allow","updatedInput":...}with the original input and never returns Claude'spermission_suggestions, so the host is allowed only for that Claude process and no local rule is written. Denial, timeout or cancellation answers{"behavior":"deny","message":...}.control_cancel_requestwithdraws the matching pending approval (permission_resolvedwithcancelled); the request is then left unanswered.- Any other control request subtype is answered with an error.
This replaces the mcp__orcha__permission_prompt tool on the task MCP proxy, so Claude has one approval channel, and its wait follows ORCHA_RUNTIME_PERMISSION_TIMEOUT_MS (300 seconds by default) instead of the old 270-second HTTP MCP cap. Delegated group-member turns do not host the channel; Claude denies their prompts locally, so they still never wait. Approval does not relax local configuration: a host that should always be reachable belongs in the device's sandbox.network.allowedDomains.
Rollout: install and reload Bridge 0.1.56 on devices; Core is unchanged. There is no database migration, protocol-version change or new project environment variable. Acceptance on 2026-10-13: Bridge checks, tests and build pass with a fake Claude CLI covering approve, deny, withdraw and unsupported control requests. In one real run with local Claude Code 2.1.287 (haiku, sandbox enabled), an approved network ask let curl reach the host, and a denied ask on the resumed session was blocked; both turns exited cleanly. The live web confirmation and a connected device running 0.1.56 have not been accepted yet.
Streamed text batching (0.1.55)
Bridge 0.1.54 sent one WebSocket frame per Claude text_delta. A reply that arrived in a burst filled the gateway's 128-frame room queue. Frames dropped there are never replayed by Bridge, so the reply could stay "in progress" until the 24-hour request timeout. Bridge now merges consecutive agent_message_chunk or agent_thought_chunk updates for up to 100 ms before they receive a bridgeUpdateId. The live events and the final response therefore carry the same merged updates. Any other update, the end of the runtime turn and terminal events release the pending text first, so ordering is unchanged. Chunks that extend the buffered text (cumulative streams), chunks that start a runtime result marker and updates carrying extra fields are never merged. This applies to every runtime, not only Claude Code.
Core no longer drops Bridge frames by count. Requests without a run room get their own ordered queue, bounded only by bytes, and a request that exceeds the byte budget fails with RUNTIME_ROOM_OVERLOADED instead of waiting silently. Rollout order is free: the Core change alone stops stuck replies, and this Bridge change cuts the number of frames per reply. There is no protocol-version change, database migration or new project environment variable. Acceptance so far covers the dispatch fixture checks; a real streamed Claude turn on a connected device with 0.1.55 has not been accepted yet.
Claude Code streaming replies (0.1.54)
Without partial messages Claude Code prints each assistant message only after it is complete, so a long answer left the Orcha reply empty until the turn ended. Bridge now launches Claude Code with --include-partial-messages. Top-level text_delta events stream as agent_message_chunk. When a tool_use block starts after streamed text, that text was commentary: Bridge clears the reply with an empty agent_message_snapshot and re-emits the text as agent_thought_chunk. The result event adds nothing when it matches the streamed text and otherwise replaces it with an agent_message_snapshot. Thinking, tool input deltas and subagent stream events are not forwarded; thinking time still shows no text. Prompts that ask for final text only, and customized launches without the flag, keep whole-message progress.
Core folds agent_message_snapshot into the stored reply with the same replace semantics as its live message_replace projection; earlier Core versions ignored snapshots there and would store withdrawn commentary in the reply. Rollout: deploy Core first, then install and reload Bridge 0.1.54 on devices. There is no database migration, protocol-version change or new project environment variable. Acceptance so far covers the fixture tests with a fake Claude CLI; a real streamed Claude turn on a connected device has not been accepted yet.
Device approvals (0.1.53)
Device Codex and Claude Code keep deciding locally which actions need confirmation; Bridge only changes who answers. Instead of an automatic denial, a request the device's own settings would prompt for reaches the user who started the Orcha turn, as a confirmation above the chat input. The native process waits in place and continues the same turn as soon as the user approves or denies. Nothing relaxes or rewrites local permission configuration.
- Claude Code answers its stdio control requests through Bridge since 0.1.56, which also covers sandbox network asks (see Claude Code approvals over stdio). The 0.1.53
mcp__orcha__permission_prompttool and its 270-second cap are gone. - Codex runs
codex app-serverover stdio JSON-RPC (one process per turn, likeexec).item/commandExecution/requestApproval,item/fileChange/requestApprovalanditem/permissions/requestApprovalgo to the user and are answeredaccept(or the requested permissions for this turn) ordecline. MCP approval elicitations from theorchaserver are accepted because Core already authorized the task tools; elicitations from other servers are declined, anditem/tool/requestUserInputis not supported yet. The task MCP-coverride is passed after the subcommand because app-server drops top-level overrides once it receives its own. A failedorchaMCP startup ends the turn withRUNTIME_CODEX_MCP_UNAVAILABLE. - Bridge contract: a
permission_requestupdate carriespermission.request = {runtime, kind, title, command?, cwd?, paths?, toolName?, input}withkindone ofcommand,file_change,permission,other, plusexpiresAt. Every ending emitspermission_resolvedwithoutcomeapproved,denied,expired(wait timeout) orcancelled(the native turn ended first).permissions/responddelivers the user's decision. The wait usesORCHA_RUNTIME_PERMISSION_TIMEOUT_MS(300 seconds by default). Delegated group-member turns never wait and are denied, as before. ACP permission requests keep their existing handling. - Core shows only requests whose
runtimeisclaudeorcodex. It persists each one as aChatToolCallwithtool_code = external_agent_permissionandexternal_call_id = permissionId, and reuses the confirmation Interaction. Only the turn's initiator can answer. A decision never converges or resumes the ChatRun, because the process is still running. Approvals left open when the turn ends are withdrawn, and an answer that arrives after Bridge stopped waiting is recorded as expired.
Rollout: deploy Core first, then install and reload Bridge 0.1.53 on devices. An older Core ignores the requests, and the device action is denied when the wait expires. There is no database migration, protocol-version change or new project environment variable.
Acceptance on 2026-10-08: Bridge checks/tests/build and the PostgreSQL approval lifecycle test pass. One real turn each ran with local Claude Code 2.1.287 and, through the opt-in test, codex-cli 0.160.1. Claude ran the approved command and never ran the denied one. Codex called the Orcha task tool, uploaded a file through send_file, and ran a read-only-sandbox escalation only after approval. Multi-turn resumed conversations, group delegation and the live web confirmation have not been accepted on a real device yet.
Codex file delivery (0.1.51)
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.
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.
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.
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.
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. 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.
For OpenClaw, install the built plugin, set plugins.entries.orcha-runtime.enabled to true and its config.allowedOrchaMcpUrl to the Orcha MCP URL. Preserve existing plugins and allowlists, permit the orcha_ tools for the local Agent, then follow the host version's plugin reload procedure:
openclaw plugins install /absolute/path/to/runtime-bridge/dist/package/openclaw-pluginAdvanced local target configuration retains mcpBridgeUrl (the Gateway /plugins/orcha-runtime/mcp-bindings route) and mcpBridgeTokenEnv (the existing local environment variable holding Gateway authentication). Configure these in the connected device profile while Bridge is stopped, then reconnect. Tokens stay on the device. Orcha's per-run MCP credential is separate and short-lived. The binding uses the discovered local Agent ID; grants are task-scoped and released on termination. Missing configuration, rejected credentials or a lost binding fails explicitly.
The env-configured run/start commands and HTTP adapter remain for adapter development. They do not authorize legacy manual external nodes to register with current Core; user devices use connect or start --url with a saved pairing.
