feat(backends): add hermes, openclaw (ACP) + nanoclaw (socket) backends#56
Open
drewstone wants to merge 2 commits into
Open
feat(backends): add hermes, openclaw (ACP) + nanoclaw (socket) backends#56drewstone wants to merge 2 commits into
drewstone wants to merge 2 commits into
Conversation
… Protocol)
cli-bridge had no ACP client; the existing backends spawn a CLI and parse stdout, but
hermes and openclaw expose `<bin> acp` — a JSON-RPC 2.0 ndjson stdio server with a
stateful session. AcpBackend drives any such agent:
spawn `<bin> acp` (cwd=req.cwd so it discovers workspace skills/context)
→ initialize → session/new {cwd,mcpServers} → session/prompt {prompt:[text]}
← stream session/update {content:{text}} → ChatDelta.content (message chunks only;
thought/plan/tool chunks skipped so reasoning never pollutes the OpenAI stream)
← session/request_permission → auto-allow (first option; trusted scope)
← result {stopReason} → finish_reason
Registered as hermes + openclaw backends (config bins HERMES_BIN/OPENCLAW_BIN, opt-in
via BRIDGE_BACKENDS; health reports `unavailable` if the binary is absent).
VERIFIED: live end-to-end against `hermes acp` — health ready (v0.10.0), the handshake +
session/prompt streamed real deltas with a clean stop. Wire protocol confirmed by a raw
ndjson probe first. 4/4 unit tests against a mock ACP agent (handshake, message-vs-thought
filtering, permission auto-allow, spawn-error), typechecks clean.
nanoclaw is NOT included here: it is a multi-channel messaging DAEMON (boots a DB +
channels, no `acp`/one-shot stdio mode), so it does not fit the stdio-backend model —
it needs a different integration (its own HTTP/queue interface), tracked separately.
…daemon
NanoClaw isn't a one-shot CLI: it's a long-lived multi-channel agent daemon (Claude Code
under the @onecli-sh Chat SDK) that exposes a CLI channel over a Unix socket
(<nanoclaw>/data/cli.sock). So the proper integration is a socket CLIENT, mirroring
NanoClaw's own scripts/chat.ts:
connect(socket) → write {"text": prompt}\n
← stream {"text": reply}\n lines → ChatDelta.content
completion is SILENCE-based (NanoClaw sends no done event) — ends after silenceMs of
quiet following the first reply, or socket close, or the hard cap.
Registered as the `nanoclaw` backend (NANOCLAW_SOCKET → the daemon's data/cli.sock;
opt-in via BRIDGE_BACKENDS; health=unavailable when the daemon isn't running).
LIMITATION (documented): the daemon owns its own workspace, so NanoClaw does NOT honor a
per-request cwd — workspace skill/profile materialization doesn't reach it (configure
skills on the NanoClaw side). This is inherent to its daemon model, not a shortcut.
Verified: 5/5 tests against a REAL Unix-socket server speaking NanoClaw's exact protocol
(stream-then-silence, socket-close finish, health ready/unavailable). Typechecks clean.
Owner
Author
Added: NanoClaw backend (3rd harness)NanoClaw doesn't fit the ACP/stdio model — it's a long-lived multi-channel daemon (Claude Code under the @onecli-sh Chat SDK) exposing a CLI channel over a Unix socket (
This PR now adds all three harnesses you asked for: hermes + openclaw (ACP) and nanoclaw (socket). 9/9 tests, typecheck clean. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a generic ACP (Agent Client Protocol) backend to cli-bridge, registering hermes and openclaw. These two don't fit the existing "spawn a CLI, parse stdout" pattern — they expose
<bin> acp, a JSON-RPC 2.0 ndjson stdio server with a stateful session. cli-bridge had no ACP client; this is it.Wire flow (verified live against
hermes acp, protocol v1)Only message chunks become content —
agent_thought_chunk/ plan / tool chunks are skipped so reasoning never pollutes the OpenAI stream.Registration
hermes+openclawbackends (binsHERMES_BIN/OPENCLAW_BIN), opt-in viaBRIDGE_BACKENDS. Health reportsunavailableif the binary is absent (openclaw isn't installed on every host yet), so registering is safe.Verification
hermes acp:health→ ready (Hermes v0.10.0);chat()→ spawned the ACP server, ran the full handshake +session/prompt, streamed real deltas, clean stop. The wire protocol was confirmed by a raw ndjson probe before writing the backend.nanoclaw (intentionally not here)
nanoclaw is a multi-channel messaging daemon (it boots a DB + channels;
acpjust starts the daemon — no one-shot stdio mode), so it doesn't fit the stdio-backend model. It needs a different integration (its own HTTP/queue interface) — tracked separately so this PR stays a clean, verified ACP addition.🤖 Generated with Claude Code