Commits merged: - docs(FN-3717): update openclaw runtime and settings docs - test(FN-3717): fix openclaw engine test typing - test(FN-3717): strengthen openclaw bridge coverage - feat(FN-3717): complete Step 2 — wire engine and bundle delivery - fix(FN-3717): address openclaw bridge review feedback - feat(FN-3717): complete Step 1 — add OpenClaw MCP bridge Files changed: .changeset/fn-3717-openclaw-tool-bridge.md | 5 ++ docs/settings-reference.md | 28 +++++--- packages/cli/src/__tests__/bundle-output.test.ts | 9 +++ packages/cli/tsup.config.ts | 7 ++ .../src/__tests__/openclaw-runtime-e2e.test.ts | 28 ++++++++ .../__tests__/openclaw-runtime-integration.test.ts | 10 +++ plugins/fusion-plugin-openclaw-runtime/README.md | 13 ++++ .../src/__tests__/cli-spawn.test.ts | 82 +++++++++++++++++++--- .../src/__tests__/mcp-config.test.ts | 45 ++++++++++++ .../src/__tests__/runtime-adapter.test.ts | 46 ++++++++++++ .../fusion-plugin-openclaw-runtime/src/index.ts | 5 ++ .../src/mcp-config.ts | 60 ++++++++++++++++ .../src/mcp-schema-server.cjs | 59 ++++++++++++++++ .../src/pi-module.ts | 52 ++++++++++++-- .../src/runtime-adapter.ts | 26 +++++++ .../fusion-plugin-openclaw-runtime/src/types.ts | 4 ++ 16 files changed, 457 insertions(+), 22 deletions(-) Fusion-Task-Id: FN-3717
5.0 KiB
OpenClaw Runtime Plugin
Drives the local openclaw CLI (openclaw/openclaw) as a subprocess. By default it runs openclaw agent --local (embedded mode, no daemon required); you can opt into the WebSocket gateway with useGateway: true.
What it does
For each promptWithFallback(session, prompt):
- Spawns
openclaw --no-color agent --local --json --session-id <uuid> --message <prompt>(plus--agent,--model,--thinking,--timeoutif configured). - Reads the single JSON document on stdout (matching
OpenClawAgentJson):- Concatenates
payloads[]where!isError && !isReasoning→session.callbacks.onText(...). - Joins
payloads[].isReasoning === true→session.callbacks.onThinking(...). - Surfaces tool-level errors (
payloads[].isError === true) as a logger warning. - Stores
meta.agentMeta.usageon the session for token accounting.
- Concatenates
- Reuses the same UUID across every prompt for the session so OpenClaw resumes the same agent conversation server-side.
The previous HTTP /v1/chat/completions integration has been removed — that endpoint required a separate gateway daemon and was an OpenAI-compat shim. The CLI surface is the canonical OpenClaw API.
Fusion tool-control (MCP bridge)
When a Fusion OpenClaw session includes custom tools, the runtime plugin now enables tool-control through OpenClaw's supported MCP configuration flow:
- Collect session tools and filter out built-ins:
read,write,edit,bash,grep,find. - Convert remaining tools into MCP-compatible schemas.
- Write a temporary schema file and MCP server config (
node mcp-schema-server.cjs <schema.json>). - Configure a profile-scoped MCP server using
openclaw --profile <id> mcp set fusion-custom-tools <json>. - Spawn the agent turn with
openclaw --profile <id> agent ...so OpenClaw can see the configured MCP server.
No private protocol is used — this is the verified OpenClaw CLI contract (mcp set + --profile).
Prerequisites
npm install -g openclaw
Verify with openclaw --version (expect OpenClaw 2026.x.y).
If you want gateway mode (useGateway: true), also start openclaw gateway run separately.
First-run note: the very first
openclaw agentinvocation lazy-installs runtime deps and can take 30–60s. Subsequent calls are fast.
Settings
| Key | Env var | Default | Notes |
|---|---|---|---|
binaryPath |
OPENCLAW_BIN |
openclaw |
Path to the openclaw binary. |
agentId |
OPENCLAW_AGENT_ID |
main |
Maps to --agent <id>. List with openclaw agents list. |
model |
OPENCLAW_MODEL |
(OpenClaw default) | Maps to --model <provider/model>, e.g. anthropic/claude-haiku-4-5. |
thinking |
OPENCLAW_THINKING |
off |
One of `off |
cliTimeoutSec |
OPENCLAW_TIMEOUT_SEC |
0 |
OpenClaw-side timeout (0 = no limit). |
cliTimeoutMs |
OPENCLAW_CLI_TIMEOUT_MS |
300000 |
Hard kill on the Fusion side. |
useGateway |
OPENCLAW_USE_GATEWAY |
false |
When true, omit --local; the CLI tries the WS gateway and falls back to embedded after ~2 s. |
Settings precedence: plugin settings → env var → default.
Limitations
- No per-token streaming.
--jsonemits a single JSON document at process exit.onTextis called exactly once. - Default ignores the gateway. With
useGateway: false(default) we always pass--local, skipping the WebSocket connect attempt entirely. Most users want this. - Built-in tools are intentionally excluded from MCP bridge.
read,write,edit,bash,grep, andfindstay native to Fusion and are not duplicated through OpenClaw MCP. - AbortSignal sends SIGTERM. If the CLI ignores it (e.g. during a long model download), the hard-kill timer (
cliTimeoutMs) eventually fires.
Public API
import {
OpenClawRuntimeAdapter,
resolveCliConfig,
buildOpenClawArgs,
createCliSession,
promptCli,
describeCliModel,
extractStderrError,
probeOpenClawBinary,
type CliConfig,
type GatewaySession,
type OpenClawAgentJson,
type OpenClawBinaryStatus,
} from "@fusion-plugin-examples/openclaw-runtime";
probeOpenClawBinary({ binaryPath?, timeoutMs? }) runs openclaw --version and returns { available, version, binaryPath, reason, probeDurationMs } — used by the dashboard's "Runtimes → OpenClaw" settings card.
Agent configuration
To create a Fusion agent backed by OpenClaw, set runtimeConfig.runtimeHint:
{
"name": "OpenClaw Executor",
"role": "executor",
"runtimeConfig": {
"runtimeHint": "openclaw"
}
}
Runtime selection happens in the dashboard's New Agent → Plugin Runtime → OpenClaw.
Metadata
- Plugin ID:
fusion-plugin-openclaw-runtime - Runtime ID:
openclaw - Package:
@fusion-plugin-examples/openclaw-runtime
Development
pnpm --filter @fusion-plugin-examples/openclaw-runtime test # 44 tests
pnpm --filter @fusion-plugin-examples/openclaw-runtime build