Skip to content

feat: add OpenClaw as ACP backend#11

Closed
canyugs wants to merge 1 commit into
mainfrom
feat/openclaw-backend
Closed

feat: add OpenClaw as ACP backend#11
canyugs wants to merge 1 commit into
mainfrom
feat/openclaw-backend

Conversation

@canyugs
Copy link
Copy Markdown
Owner

@canyugs canyugs commented May 17, 2026

0. Discord Discussion URL

Not yet — opening this PR against the fork for internal review before
upstreaming. The architectural decision (external gateway dependency vs.
bundling) is worth a Discord discussion before the upstream PR; this PR is the
concrete artifact to anchor that conversation.

1. What problem does this solve?

Adds OpenClaw as a selectable ACP
backend, so OpenAB users get the same first-class experience for OpenClaw
that they have for Kiro / Claude / Codex / Gemini / OpenCode / Copilot /
Cursor / Hermes / Grok Build.

No related issue yet — exploratory work prompted by openabdev#828 surfacing OpenClaw's
ACP capability.

2. At a Glance

Standard ACP backend (Kiro / Claude / Codex / Hermes / Grok):
  openab ──stdio──► <agent>-acp ──HTTPS──► LLM provider

OpenClaw (this PR):
  openab ──stdio──► openclaw acp ──WS──► openclaw gateway ──HTTPS──► LLM provider
                    (inside container)   (separate service, user-deployed)

3. Prior Art & Industry Research

OpenClaw itselfopenclaw acp is registered in
`src/cli/acp-cli.ts`;
declares `protocolVersion: 1`, `authMethods: []`, supports `loadSession`,
image + embeddedContext content blocks, no audio, no per-session MCP servers,
2 MB prompt cap (`src/acp/translator.ts:686-711`). The bridge requires a
running gateway daemon — `src/acp/server.ts` awaits `gatewayReady` before
serving ACP and exits otherwise.

`openclaw/acpx` — the upstream ACP
multi-agent wrapper. Its registry entry is literally
`openclaw: "openclaw acp"` (`src/agent-registry.ts`), confirming the
`openclaw acp` subcommand is the canonical stdio entry point. acpx itself
adds no useful abstraction for our use case (it expects `openclaw` already
on PATH and would just be an extra hop), so we invoke `openclaw acp`
directly — same as we do for `hermes acp`, `gemini --acp`, etc.

Hermes Agent — closest in-tree analogue for "agent with external
dependency complexity." Hermes requires out-of-band OAuth setup
(SuperGrok / xAI device flow, etc.); OpenClaw requires an out-of-band gateway
service. Both share the same Dockerfile/docs/build.yml shape — this PR
mirrors that pattern.

4. Proposed Solution

Add OpenClaw as a backend where:

  • The image installs only the openclaw npm package (Node 22.16+).
  • The container runs openclaw acp --url ws://<gateway> --session <key>
    as the stdio ACP process.
  • The OpenClaw gateway is not bundled — users deploy it separately
    (companion openclaw-gateway Zeabur template to follow).

Files:

File Change
Dockerfile.openclaw (new) node:22-bookworm-slim + npm i -g openclaw + gh CLI, matches Dockerfile.opencode shape
docs/openclaw.md (new) Gateway prerequisites, auth (env var / token file), session/model semantics, capabilities & limits, troubleshooting
config.toml.example Commented agent block with --url and --session
.github/workflows/build.yml Matrix entry across build-image / merge-manifests / promote-stable
.github/workflows/docker-smoke-test.yml Matrix entry — falls back to --help check when gateway unreachable, same path other auth-required CLIs hit
README.md Agent table row

Deliberately unchanged: src/acp/connection.rs. The auto-authenticate
flow added in openabdev#822 triggers when authMethods is non-empty; OpenClaw returns
[], so the existing code path is a no-op for this backend.

5. Why This Approach

External gateway over in-container gateway. The alternative (Option A:
supervisord + openclaw gateway + openclaw acp in the same container)
breaks OpenAB's single-process-per-container model, adds a persistent volume
contract (~/.openclaw/ for config + sessions + transcripts), and couples
OpenAB releases to OpenClaw gateway versions. Keeping the gateway external
preserves single-process consistency with all eight existing backends and
keeps OpenClaw version bumps independent.

Known tradeoff — /model semantics differ. OpenClaw routes by
session key (agent:<name>:<thread>), not by ACP model field. The
/model gpt-4o slash command is a no-op for this backend; users switch
models by editing the gateway-side agent definition or by changing
--session. Documented explicitly in docs/openclaw.md. Not introducing a
fake mapping layer in OpenAB — would be surprising magic and tightly couple
us to gateway-side naming conventions.

Known limitation — deployment is two pieces. Users must run an OpenClaw
gateway somewhere. Companion Zeabur template (separate PR) reduces this to a
one-click deploy.

6. Alternatives Considered

Alternative Why rejected
Option A: bundle gateway in same container Breaks single-process model; needs supervisord, persistent volume for ~/.openclaw/, version coupling. Higher long-term maintenance cost on OpenAB maintainers.
Env-var-only LLM proxy (OPENAI_BASE_URL=openclaw-gateway) OpenClaw exposes OpenAI-compat HTTP (/v1/chat/completions) but not Anthropic-compat (/v1/messages) — so Claude Code can't use it. Also, this isn't an OpenAB-side integration at all; it's just env-var config users can do today without our involvement. Doesn't deliver "OpenClaw as a named backend" UX.
Fork upstream to strip gateway requirement Massive divergence cost; not viable.
Wait for upstream @openclaw/acp-bridge thin package No upstream plans; would block this work indefinitely. Revisit if it ships.
Route through acpx Adds a hop that resolves to openclaw acp anyway; no value.

7. Validation

  • cargo check — no Rust changes; existing src/acp/connection.rs
    no-op verified by inspection (OpenClaw authMethods: []).
  • cargo test — no behavior change in OpenAB core.
  • cargo clippy — no new code paths.
  • Docker smoke test — matrix entry added. When run without a gateway,
    the bridge exits with gateway closed before ready; the workflow
    falls back to openclaw --help check (same path Hermes/others take
    when they need auth).
  • Manual end-to-end (TODO before upstream): deploy
    openclaw-gateway to a test cluster, run OpenAB with this image
    pointing at it, send a message in the test Discord channel
    (1493817398997029006), verify ACP round-trip + tool calls + image
    attachments.
  • Helm chart values for agents.openclaw.* — not added in this PR
    to keep diff focused; will follow once manual e2e confirms the
    argument shape.

Notes

  • This PR is targeted at the fork's main for internal review.
    Upstream PR (against openabdev/openab) will follow after Discord
    discussion + manual e2e validation.
  • Companion openclaw-gateway Zeabur template tracked separately.

Add OpenClaw (https://github.com/openclaw/openclaw) as a new ACP backend
via the `openclaw acp` subcommand, which bridges ACP stdio to a running
OpenClaw gateway over WebSocket.

Unlike other backends (Kiro / Claude / Codex / Hermes / etc.) where the
ACP CLI is the entire agent, OpenClaw requires a separately-running
gateway service for provider routing, model selection, and agent
runtime. The OpenAB container only embeds the bridge CLI.

Files:
- Dockerfile.openclaw — node:22-bookworm-slim + `npm i -g openclaw`
- docs/openclaw.md — gateway prerequisites, auth, session/model semantics
- config.toml.example — commented example agent block
- .github/workflows/build.yml — matrix entries (build / merge / promote)
- .github/workflows/docker-smoke-test.yml — matrix entry (falls back to
  --help check when gateway unreachable, same as other auth-required CLIs)
- README.md — agent table row

Notes:
- src/acp/connection.rs intentionally unchanged — `openclaw acp` returns
  `authMethods: []`, so the auto-authenticate flow from openabdev#822 is a no-op
- `/model` slash command does not switch LLM models for OpenClaw; routing
  is by `--session` key on the gateway side (documented in docs/openclaw.md)
- Companion zeabur-template for `openclaw-gateway` to follow in a separate
  PR so users can one-click the required gateway service
Copilot AI review requested due to automatic review settings May 17, 2026 03:01
@github-actions
Copy link
Copy Markdown

⚠️ This PR is missing a Discord Discussion URL in the body.

All PRs must reference a prior Discord discussion to ensure community alignment before implementation.

Please edit the PR description to include a link like:

Discord Discussion URL: https://discord.com/channels/...

This PR will be automatically closed in 3 days if the link is not added.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds OpenClaw as a new selectable ACP backend, mirroring the existing per-agent pattern (Dockerfile + docs + config example + CI matrix entries). The bridge process (openclaw acp) connects over WebSocket to a separately-deployed OpenClaw gateway — the gateway is intentionally not bundled, preserving the project's single-process-per-container model.

Changes:

  • New Dockerfile.openclaw (node:22-bookworm-slim + globally installed openclaw npm package + gh CLI), modeled on Dockerfile.opencode.
  • New docs/openclaw.md covering architecture, gateway prerequisites, authentication, session/model semantics, capability matrix, and troubleshooting; plus README and config.toml.example entries.
  • Adds the -openclaw variant to the build.yml (build-image, merge-manifests, promote-stable) and docker-smoke-test.yml matrices.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Adds OpenClaw row to the supported-agents table.
docs/openclaw.md New user-facing doc with architecture, helm/config examples, capability/limits matrix, and troubleshooting.
Dockerfile.openclaw New runtime image installing the openclaw npm package and gh CLI on node:22-bookworm-slim.
config.toml.example Adds a commented [agent] block illustrating the openclaw bridge invocation.
.github/workflows/build.yml Adds -openclaw to the build/merge/promote matrices.
.github/workflows/docker-smoke-test.yml Adds -openclaw smoke-test matrix entry (falls back to --help when the gateway is unreachable).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Dockerfile.openclaw
# Install openclaw
# Note: openclaw does not publish SHA256 checksums for its npm releases,
# so checksum verification is not performed.
ARG OPENCLAW_VERSION=latest
Comment thread docs/openclaw.md
Comment on lines +37 to +48
```bash
helm install openab openab/openab \
--set agents.kiro.enabled=false \
--set agents.openclaw.discord.enabled=true \
--set agents.openclaw.discord.botToken="$DISCORD_BOT_TOKEN" \
--set-string 'agents.openclaw.discord.allowedChannels[0]=YOUR_CHANNEL_ID' \
--set agents.openclaw.image=ghcr.io/openabdev/openab-openclaw:latest \
--set agents.openclaw.command=openclaw \
--set-json 'agents.openclaw.args=["acp","--url","ws://openclaw-gateway:18789","--session","agent:main:main"]' \
--set agents.openclaw.workingDir=/home/node \
--set agents.openclaw.env.OPENCLAW_GATEWAY_TOKEN="$OPENCLAW_GATEWAY_TOKEN"
```
Comment thread config.toml.example
# command = "openclaw"
# args = ["acp", "--url", "ws://openclaw-gateway:18789", "--session", "agent:main:main"]
# working_dir = "/home/node"
# env = { OPENCLAW_GATEWAY_TOKEN = "${OPENCLAW_GATEWAY_TOKEN}" }
@github-actions
Copy link
Copy Markdown

🔒 Auto-closing: this PR has had the closing-soon label for more than 3 days without a Discord Discussion URL being added.

Feel free to reopen after adding the discussion link to the PR body.

@github-actions github-actions Bot closed this May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

closing-soon pending-screening PR awaiting automated screening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants