chore: initial scaffolding for SynthesisAgent

Bridge between OpenClaw (multi-channel hub) and interactive Claude Code,
keeping autonomous agent usage on the subscription quota after the
2026-06-15 Agent SDK credit split.

Initial scaffolding only — two submodules with skeletons:

- SynthesisAgent.ClaudePlugin: stdio MCP server registered as a --channels
  source. Declares experimental.claude/channel capability (verified 2026-05-14
  against the official Anthropic discord plugin) and emits
  notifications/claude/channel to push OpenClaw inbound messages into the
  Claude turn loop.

- SynthesisAgent.OpenclawPlugin: process manager + session mapping +
  bridge WebSocket. Currently shaped around a custom ws protocol; will be
  rewritten as a model-provider HTTP server (contractor-agent pattern) so
  OpenClaw routes inbound channel messages through it via /v1/chat/completions.

See STATUS.md for the open punch list and docs/wire-protocol.md for the
(soon-to-change) inter-plugin frame schema.
This commit is contained in:
zhi
2026-05-14 09:39:02 +00:00
commit 0fb46e318e
20 changed files with 1285 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
# SynthesisAgent.OpenclawPlugin
The **OpenClaw side** of SynthesisAgent. Lives inside the OpenClaw process; spawns and manages one long-lived interactive `claude` per OpenClaw session.
## Components
```
index.ts entry: definePluginEntry, wires up the others
core/config.ts plugin config schema + defaults
core/session-mapping.ts persistent openclaw_session ↔ claude_session_uuid
core/process-manager.ts spawn/resume/kill claude processes
core/cli.ts admin commands (`openclaw synthesis ...`)
web/bridge-server.ts WebSocket server that ClaudePlugins connect into
```
## Lifecycle
```
plugin loaded
SessionMapping reads ~/.openclaw/synthesis/sessions.json
ProcessManager idle, no spawns yet
BridgeServer binds 127.0.0.1:18801
inbound Discord msg for session=alice
processManager.ensure('alice')
- mapping.ensure → claude_session_uuid (new or existing)
- spawn `claude --channels plugin:synthesis-claude@local --resume <uuid> ...`
- inject env: SYNTHESIS_BRIDGE_URL / TOKEN / OPENCLAW_SESSION / CLAUDE_SESSION
ClaudePlugin (in spawned claude) dials ws://127.0.0.1:18801/bridge
- sends hello frame
- server validates token, marks process ready, sends hello_ack with tool catalog
processManager.ensure resolves
inbound message pushed → notifications/claude/channel → Claude starts new turn
Claude calls tools/call → forwarded to OpenClaw tool surface
Claude finishes → process stays alive, idle timer reset
1 hour idle → idleSweeper SIGTERMs the process
mapping is preserved → next message resumes via --resume
```
## Config
See `openclaw.plugin.json` `configSchema`. Override in `~/.openclaw/openclaw.json`:
```json
{
"plugins": {
"entries": {
"synthesis-agent": {
"bridgePort": 18801,
"bridgeToken": "<random secret>",
"idleKillMs": 1800000,
"maxProcesses": 8
}
}
}
}
```
## TODO
- [ ] Discover exact OpenClaw plugin-sdk API for: inbound event subscription, CLI command registration, tool catalog enumeration. See `contractor-agent/index.ts` for current best example.
- [ ] Wire `api.channels.onInbound(...)` to `pm.ensure()` + `bridgeServer.pushInbound()`.
- [ ] Implement tool dispatch in `web/bridge-server.ts` (current `tool_call` handler returns not-implemented).
- [ ] Implement permission routing back to source channel.
- [ ] CLI: `openclaw synthesis list`, `push`, `kill`, `forget`.
- [ ] Settle path conflict: this plugin needs to live at `/root/.openclaw/plugins/synthesis-agent/` to be auto-loaded. Either symlink from this repo or document copy-install.
- [ ] Decide policy on `--no-session-persistence` flag (currently we rely on default persistence so `--resume` works).