chore: bump submodules + update wire protocol + STATUS

Submodules now have real implementations of the HTTP+WS bridge and the
channel-side MCP server. STATUS reflects locked architecture decisions
and the laptop smoke-test plan. wire-protocol.md updated to drop the
auth token and permission_request descriptions (no longer in scope).
This commit is contained in:
zhi
2026-05-14 13:28:22 +00:00
parent 7a632697a9
commit 57fc8610ed
4 changed files with 95 additions and 147 deletions

View File

@@ -1,68 +1,39 @@
# SynthesisAgent — Status (paused 2026-05-14)
# SynthesisAgent — Status (in development, 2026-05-14)
## Where we left off
## Architecture decisions (locked)
Scaffolding complete. Two submodules wired up with their core skeletons:
- **HTTP provider pattern**: OpenclawPlugin registers as model provider `synthesis-claude-bridge`. OpenClaw routes agent turns via `POST /v1/chat/completions`. (Mirrors contractor-agent.)
- **WebSocket bridge**: ClaudePlugin (in spawned claude) dials back into OpenclawPlugin's WS. Single long-lived connection per Claude process.
- **Session granularity**: `agent_id::chat_id` (matches contractor-agent's `buildSessionKey`).
- **Reply channel**: ClaudePlugin exposes a `reply(text, final?)` MCP tool. Model calls it. ClaudePlugin → WS → OpenclawPlugin → SSE → OpenClaw.
- **Channel dev mode**: `--dangerously-load-development-channels server:synthesis`. Process-manager pipes "1\n" to stdin to auto-confirm the dev dialog.
- **No auth, no permission_request reverse**: same-machine deployment, full perms.
- **Tool catalog v1**: ClaudePlugin only exposes `reply`. Claude Code's built-in tools (Read/Edit/Bash) do everything else. OpenClaw tool proxy deferred to v2.
- `SynthesisAgent.ClaudePlugin/server.ts` — stdio MCP server + bridge WebSocket client. Reads 4 env vars, forwards `tool_call` / `permission_request` to OpenClaw side, translates `inbound_message` frames to `notifications/claude/channel`.
- `SynthesisAgent.OpenclawPlugin` — process manager (spawn/resume/idle-GC), session mapping (JSON persist), bridge WS server, OpenClaw plugin entry. Tool-dispatch and inbound-event-subscription are stubbed.
## Implementation status
Wire protocol fully specified in `docs/wire-protocol.md`.
- ✅ Scaffold for both submodules + parent repo
- ✅ Submodules are separate gitea repos, referenced by SHA from parent
- ✅ Capability declaration uses `experimental.claude/channel` (validated bug fix)
- ✅ OpenclawPlugin: HTTP + WS server, process manager, session mapping, FIFO queue, SSE heartbeat, `--channels` spawn with dev-confirm auto-pipe
- ✅ ClaudePlugin: WS client, MCP server, `reply` tool, `notifications/claude/channel` emission, reconnect
- ✅ Wire protocol doc reflects current behavior
- ⏳ Not yet tested end-to-end on laptop — next step
## Open blockers (in priority order)
## Laptop smoke test plan
### Done / validated 2026-05-14 on laptop (SSH via T2)
See `SynthesisAgent.OpenclawPlugin/README.md` for the exact commands. Summary:
1. `claude mcp add --scope user synthesis -- bun run <path>/server.ts`
2. `bun index.ts` in OpenclawPlugin (standalone mode)
3. `curl POST /v1/chat/completions` with a "say READY" prompt
4. Watch for "READY" in the SSE stream
-`--channels` flag exists in Claude Code 2.1.140/141 (hidden from `--help`)
- ✅ Syntax: `plugin:<name>@<marketplace>` or `server:<name>`
-`--plugin-dir <path>` IS documented and works for local plugin loading
- ✅ Capability declaration must be `experimental.claude/channel` not top-level — **scaffolding patched**
-`-p` mode does NOT trigger turns from channel notifications — interactive only
- ✅ Full gating chain decoded from binary (see `memory/claude_channels_protocol.md`)
- ❌ Did NOT capture an end-to-end "claude responds to channel notification" trace — got stuck at `--dangerously-load-development-channels` allowlist gate in script-PTY runs (interactive confirm may not have flowed through). Indirect evidence is overwhelming via the Discord plugin's working production pattern; remaining doubt is small.
## Deferred to v2
### Remaining
1. **`.mcp.json` not written** — sandbox flagged it as sensitive on Write. Five-line file, need to drop in by hand or approve the write.
2. **Confirm channel notification → new turn empirically** — Have user run interactively (no PTY tricks):
```
claude --mcp-config /tmp/synthesis-mcp.json \
--channels server:synthesis-stub \
--dangerously-load-development-channels server:synthesis-stub
```
(in a trusted dir), confirm dev mode at the prompt, watch for the stub's 1.5s-delayed channel-test ping triggering a turn.
3. **Decide deployment path**:
- `server:` channels are flagged "dangerous dev only" — fine for our own use, awkward for shipping
- `plugin:` channels need to be in marketplace allowlist (org `allowedChannelPlugins`) — requires distribution mechanism
- Easiest dev path: local marketplace pointing at our repo
4. **OpenClaw plugin-sdk inbound subscription API** — `index.ts` has a TODO where `api.channels.onInbound(...)` should live. Need to read `contractor-agent/index.ts` carefully and copy the actual pattern.
5. **Tool catalog source** — `web/bridge-server.ts` sends an empty `tools: []` in `hello_ack`. Must enumerate OpenClaw's real tool surface and forward.
6. **`tool_call` dispatch** — currently returns `not implemented`. Need to wire to OpenClaw's tool execution path.
7. **Permission routing back to source channel** — bridge auto-denies any `permission_request` today.
## Quick-start tests to run when resuming
```bash
# 0. write .mcp.json (blocked last time)
# 1. verify --channels accepts local path or local marketplace
claude --channels plugin:synthesis-claude@/root/.openclaw/workspace/workspace-developer/SynthesisAgent/SynthesisAgent.ClaudePlugin 2>&1 | head -20
# 2. once #1 works: smoke-test notifications/claude/channel from a stub server
# (build a 30-line MCP server that fakes inbound_message after 5s)
```
## Files to start from when picking up
- `README.md` — context refresher
- `docs/wire-protocol.md` — protocol contract
- `SynthesisAgent.OpenclawPlugin/README.md` — TODO list for that side
- `SynthesisAgent.ClaudePlugin/README.md` — TODO list for that side
Reference implementations to crib from:
- `~/.claude/plugins/marketplaces/claude-plugins-official/external_plugins/discord/server.ts` — channel protocol model
- `/root/.openclaw/plugins/contractor-agent/index.ts` — OpenClaw plugin lifecycle model
## Why paused
User pivoted to investigate a recurrence of the Discord duplicate-messages bug ([[discord_duplicate_messages]]). SynthesisAgent is the longer-term fix for that whole class of problem; the duplicate-messages bug is the short-term hotfix path.
- OpenClaw tool proxy via MCP (read/edit/etc. forwarded as MCP tools instead of using Claude Code's built-ins) — only matters if we want OpenClaw-specific tools (memory_*, wiki_*, canvas) to be accessible from the bridged session
- Full session-key extraction from OpenClaw "Conversation info" block (currently using HTTP headers)
- `plugin:` channel form for marketplace distribution (currently `server:` + dev flag)
- Permission_request reverse channel (skipped per design)
- Install / uninstall script (mirrors contractor-agent's `scripts/install.mjs`)
- Better stop-hook integration for graceful shutdown
- Multi-machine deployment (currently same-host only)