Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
Your own AI agent, running 24/7 with QwikClaw logoYour own AI agent, running 24/7 with QwikClaw

QwikClaw sets up and runs an always-on OpenClaw agent for you. One click, no config files, no server setup.

Deploy now
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 47,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here
spawn-interceptor logo

spawn-interceptor

lanyasheng/openclaw-multiagent-framework

Otheropenclawby lanyasheng

Summary

OpenClaw plugin exposing 0 skills.

Install to Claude Code

openclaw plugin add lanyasheng/openclaw-multiagent-framework

Run in Claude Code. Add the marketplace first with /plugin marketplace add lanyasheng/openclaw-multiagent-framework if you haven't already.

README.md

OpenClaw Multi-Agent Collaboration Framework

> A battle-tested multi-agent collaboration protocol and architecture for OpenClaw. Solves unreliable ACP communication, agent task-registration amnesia, and ambiguous timeout semantics with a zero-config plugin system. Includes a lightweight subagent + Claude Code CLI runner as a stable ACP alternative.

中文版 (Chinese README)

Version: 2026-03-16-v10 | License: MIT | Status: Production Ready

---

Quick Summary: Communication Model at a Glance

┌─────────────────────────────────────────────────────────────────────────────┐
│                    ONE-SCREEN COMMUNICATION SUMMARY                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────┐     sessions_spawn()      ┌─────────────┐                     │
│  │  User   │──────────────────────────▶│  Worker     │                     │
│  │(Zoe/Main)│◀─────────────────────────│  Session(s) │                     │
│  └────┬────┘     task-log.jsonl        └─────────────┘                     │
│       │                                                                     │
│       │  • Sessions are ISOLATED by default                                 │
│       │  • Context sharing requires EXPLICIT mechanism                      │
│       │    (prompt / artifact / resume / external state)                    │
│       │                                                                     │
│       ▼                                                                     │
│  ┌───────────────┐                                                          │
│  │  sessions_send │  ← Continue existing session (not spawn new)           │
│  └───────────────┘                                                          │
│                                                                             │
│  KEY RULE: Agent ≠ Session ≠ Thread                                         │
│  • Agent: Configured AI entity (trading/ainews/macro)                       │
│  • Session: Isolated execution context (spawn = fresh start)                │
│  • Thread: UI container (visual, not memory)                                │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

In one sentence: This framework provides task routing, isolation, and completion tracking for OpenClaw agents — not a shared memory system or group chat simulator.

---

The Problem

When running multiple AI agents in OpenClaw, you quickly hit fundamental limitations:

1. No Completion Notification

You call sessions_spawn to start a sub-agent via ACP. It runs in the background. Then... nothing. OpenClaw never tells you when it finishes. No callback, no webhook, no event, no notification.

Root cause: OpenClaw Bug #40272 — the notifyChannel parameter in ACP is accepted but silently ignored.

2. Agent Registration Amnesia

You meticulously write documentation: "Before calling sessions_spawn, always register the task with the monitoring system." The LLM reads it. Understands it. Then calls sessions_spawn directly anyway, skipping registration. Every. Single. Time.

LLMs have muscle memory — they default to native tool calls and skip wrapper functions. Documentation-based constraints don't work for mandatory behaviors.

3. Zombie Sessions

Completed ACP sessions don't get properly cleaned up by the OpenClaw Gateway (Bug #34054). These zombie sessions accumulate silently until they hit the maxConcurrentSessions limit (default: 6), at which point all new ACP tasks fail with a cryptic "max sessions exceeded" error — even though the agent swears everything is closed.

> Update (2026-03-14): The root cause — acp-spawn.ts not calling registerSubagentRun() — has been identified and fixed in PR #46308. With this fix, subagent_ended hooks now fire for ACP sessions, enabling proper lifecycle tracking. The ACP Session Poller (Layer 3) remains useful as a fallback for older Gateway versions.

4. Timeout Ambiguity

sessions_send returns "timeout". But what does that mean?

  • The task failed? → Maybe
  • The task is still running? → Maybe
  • The message was never delivered? → Also maybe
  • The task completed but the response was too slow? → Possible

You simply cannot tell. There's no follow-up mechanism, no status query, no retry protocol.

5. No Audit Trail

After a day of multi-agent orchestration, you ask: "What tasks were spawned today? Which completed? Which failed? How long did they take?" The answer: scroll through 50KB of chat history and try to piece it together manually.

---

The Solution: Four-Layer Completion Pipeline

Core insight: If a behavior is mandatory, it should be a system constraint — not a documentation constraint.

Instead of teaching agents to remember extra steps (which always fails), we intercept at the system level using OpenClaw's plugin hooks (which always works).

Four-Layer Completion Detection

Our completion detection uses a four-layer defensive architecture that handles different task types and edge cases:

┌─────────────────────────────────────────────────────────────────────────────┐
│                    COMPLETION DETECTION PIPELINE v3.6                        │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  LAYER 1: Native Event Stream (OpenClaw)                                   │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  sessions_spawn(runtime="acp", streamTo="parent")                  │   │
│  │  • Receives progress, stall, resumed events                        │   │
│  │  • Real-time status updates via stream                             │   │
│  │  • Covers: runtime=acp with streamTo                               │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                              ↓                                              │
│  LAYER 2: Registration Layer (spawn-interceptor)                           │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  before_tool_call hook intercepts sessions_spawn                    │   │
│  │  • Records task to task-log.jsonl (spawning)                       │   │
│  │  • Stores in pendingTasks Map                                       │   │
│  │  • NOT completion truth — only start registration                  │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                              ↓                                              │
│  LAYER 3: Basic Completion (Poller + Reaper)                               │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  L3a: ACP Session Poller (~15s)                                     │   │
│  │       Polls ~/.acpx/sessions/ for closed sessions                  │   │
│  │                                                                     │   │
│  │  L3b: Stale Reaper (30min safety net)                               │   │
│  │       Marks long-pending tasks as timeout                          │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                              ↓                                              │
│  LAYER 4: Terminal-State Correction (content-aware-completer)              │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │  Solves "Registered=False, Terminal=False" (Type 4 tasks)          │   │
│  │  • Tier 1: Requires BOTH session closed + content evidence         │   │
│  │  • Rejects historical files, empty files                           │   │
│  │  • Idempotent writes, UTC timezone safe                            │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                              ↓                                              │
│                    Unified: task-log.jsonl                                  │
└─────────────────────────────────────────────────────────────────────────────┘

Key Clarifications

| Misconception | Reality | |--------------|---------| | "Hook is completion truth" | Hook only registers task START. Completion needs Layer 3/4. | | "Intermediate states from hook" | Intermediate states come from Layer 1 native event stream, not hook. | | "Plugin auto-closes loop" | Plugin enables tracking. Content-aware completer validates completion. |

---

Communication Model & Session Boundaries

Understanding how agents communicate is critical to using this framework correctly.

Core Concepts: Agent ≠ Session ≠ Thread

| Concept | What It Is | What It Is NOT | |---------|-----------|----------------| | Agent | A configured AI entity with a system prompt and capabilities | A running process or conversation instance | | Session | A single execution context with isolated state and history | NOT automatically shared with other sessions | | Thread | A UI/conversation container (visual surface) | NOT the memory store or shared state |

Default Communication Flow

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e1f5fe', 'primaryTextColor': '#01579b', 'primaryBorderColor': '#0288d1', 'lineColor': '#0288d1', 'secondaryColor': '#fff3e0', 'tertiaryColor': '#e8f5e9'}}}%%
flowchart LR
    subgraph User["👤 User"]
        U[You/Zoe]
    end

    subgraph Orchestrator["🎯 Orchestrator"]
        Z[Zoe/Main Agent]
    end

    subgraph Workers["⚙️ Worker Sessions"]
        W1[Trading]
        W2[AINews]
        W3[Macro]
    end

    subgraph Audit["📋 Audit Trail"]
        TL[task-log.jsonl]
    end

    U -->|"1. Request"| Z
    Z -->|"2. sessions_spawn()"| W1
    Z -->|"2. sessions_spawn()"| W2
    Z -->|"2. sessions_spawn()"| W3
    W1 -->|"3. Results"| Z
    W2 -->|"3. Results"| Z
    W3 -->|"3. Results"| Z
    Z -->|"4. Response"| U
    Z -.->|"Log state"| TL

    style User fill:#e3f2fd
    style Orchestrator fill:#fff3e0
    style Workers fill:#e8f5e9
    style Audit fill:#fce4ec

ASCII Version (for non-Mermaid renderers):

┌─────────┐     ┌──────────────┐     ┌─────────────────────┐     ┌──────────────┐     ┌─────────┐
│  User   │────▶│ Orchestrator │────▶│   Worker Session(s) │────▶│ Orchestrator │────▶│  User   │
│ (You)   │◀────│   (Zoe/Main) │◀────│  (trading/ainews/   │◀────│   (Zoe/Main) │◀────│ (You)   │
└─────────┘     └──────────────┘     │    macro/...)        │     └──────────────┘     └─────────┘
                                      └─────────────────────┘
                                              │
                                              ▼
                                      ┌───────────────┐
                                      │  task-log     │
                                      │  (persistent  │
                                      │   audit trail)│
                                      └───────────────┘

Key Points:

  • The Orchestrator (typically Zoe/main agent) is the sole moderator
  • Worker sessions are spawned to handle specific tasks
  • Results flow back through the Orchestrator, not directly to the user
  • Each session has isolated memory by default

sessions_send vs sessions_spawn

| Function | Purpose | Use When | |----------|---------|----------| | sessions_spawn | Create a NEW session with a fresh context | Starting a new task or workflow | | sessions_send | Send a message to an EXISTING session | Continuing a multi-turn conversation |

Important:

  • sessions_spawn creates a new isolated session with no prior history
  • sessions_send requires the session to already exist (created by prior sessions_spawn)
  • Both functions use sessionKey to identify the target

Control Plane vs Messaging Plane

Two distinct planes that must not be confused:

| Plane | Tool | Purpose | Addressing | |-------|------|---------|------------| | Control Plane | sessions_send | Agent-to-agent control messages | sessionKey (exact) | | Messaging Plane | message.send / provider | User-visible notifications only | channel/label |

Critical distinction: message delivered ≠ control request received

  • Message delivered (messaging plane): Message reached the channel
  • Control request received (control plane): Target agent processed the request and sent ACK

For internal agent-to-agent control, always use sessions_send with sessionKey. Never use message.send or provider channels for control messages.

Context Sharing Model

Default: Sessions are Isolated

Session A                    Session B
┌─────────┐                 ┌─────────┐
│ History │◀───── NO ─────▶│ History │
│ State   │   sharing      │ State   │
└─────────┘                └─────────┘

Sharing Requires Explicit Mechanisms:

| Mechanism | How It Works | Use Case | |-----------|--------------|----------| | Prompt Injection | Pass context in the prompt parameter | One-time context transfer | | Artifacts | Write to/read from shared files | Persistent data exchange | | Resume | Use resume parameter to continue | Long-running workflows | | External State | Database, JSON files, etc. | Cross-session persistence |

What This Framework Solves (and Doesn't)

| Problem Solved | How | What It Is NOT | |----------------|-----|----------------| | Task Routing | Orchestrator dispatches to appropriate worker | NOT automatic load balancing | | Isolation | Each session runs independently | NOT a shared memory system | | State Tracking | task-log.jsonl records all state transitions | NOT a group chat simulator | | Result Recovery | Four-layer completion pipeline ensures no lost results | NOT automatic retries |

Common Misconceptions

| Misconception | Reality | |--------------|---------| | "All agents share memory automatically" | False. Sessions are isolated by default. Sharing requires explicit prompt/artifact/resume. | | "UI thread = shared memory" | False. UI thread/channel is a visual container, not memory. State is per-session. | | "sessions_send talks to the same 'person'" | False. It sends to the same session, which has no memory of previous sessions unless resumed. | | "This is a group chat framework" | False. It's task routing and isolation, not social simulation. | | "spawn means create a new agent" | False. It creates a new session with an existing agent configuration. |

Practical Example

# Zoe (Orchestrator) spawns a trading analysis task
sessions_spawn(
    sessionKey="agent:trading:daily-analysis",  # Unique session ID
    agentId="trading",                           # Which agent config to use
    prompt="Analyze BTC price action for today", # Context passed explicitly
    mode="run",
    streamTo="parent",                           # Enables Layer 1 event stream
)

# Later, Zoe checks results via task-log, not by assuming shared memory
# The trading session does NOT automatically know what the macro session did
# unless Zoe explicitly passes that context in the prompt or via artifact

---

Positioning: Why This Approach Now

What This Framework Is

This is a lightweight coordination layer built on top of OpenClaw's native sessions/threads, augmented with shared files/artifacts for cross-session communication. It solves specific, concrete problems:

1. Completion detection when OpenClaw doesn't notify you (Bug #40272) 2. Task registration that agents can't forget (via plugin hooks) 3. State tracking across isolated sessions (via task-log.jsonl) 4. Zombie session cleanup (workaround for Bug #34054)

Design Philosophy: Fit for Current Scale

For a small team running a few agents (e.g., trading + AI news + macro analysis), this approach prioritizes:

| Principle | How We Apply It | |-----------|-----------------| | Trust + Context | Human oversight via Zoe as orchestrator; context passed explicitly | | Point-to-point routing | Orchestrator dispatches to specific workers by ID | | Explicit handoff | Each spawn is intentional; no automatic broadcast or subscription | | Shared artifacts | Files in shared-context/ serve as the "shared memory" | | Human oversight | Zoe (main agent) reviews and decides; not fully autonomous |

This is an intentional choice, not a lack of awareness of mainstream frameworks.

---

What We Borrowed from Mainstream Frameworks

We studied existing solutions and incorporated their insights, while staying lightweight:

Microsoft AutoGen Core

Reference patterns: Topic/subscription, direct messaging + broadcast, handoffs, concurrent agents

What we adopted:

  • The concept of an orchestrator coordinating multiple specialized agents
  • Explicit handoff patterns (Zoe decides which agent handles what)

Why we differ:

  • AutoGen Core provides a runtime-level message bus with broadcast capabilities
  • We use point-to-point routing via sessions_spawn — simpler for our scale, no broadcast needed

LangGraph

Reference patterns: Low-level orchestration, durable execution, human-in-the-loop, comprehensive memory

What we adopted:

  • Persistence layer (task-log.jsonl as durable state)
  • Explicit state management rather than implicit memory
  • Recognition that workflows need structure, not just prompts

Why we differ:

  • LangGraph provides graph-based workflow definition with cycles, conditions, and checkpoints
  • We use linear orchestrator patterns — sufficient for current task routing needs

CrewAI

Reference patterns: Crews + Flows, role-based collaboration, event-driven workflows, state management between tasks

What we adopted:

  • Role-based agent definitions (trading agent, news agent, macro agent)
  • Task delegation from a coordinator to workers
  • Shared state via artifacts/files between tasks

Why we differ:

  • CrewAI provides higher-level abstractions (Flows, Crews) with built-in collaboration patterns
  • We use lower-level OpenClaw primitives (sessions_spawn, sessions_send) — more control, less magic

Our Honest Assessment

| Framework | Strengths | Why Not Used (for now) | |-----------|-----------|------------------------| | AutoGen Core | Mature message routing, broadcast | Adds complexity we don't need at 3-4 agent scale | | LangGraph | Durable workflows, graph structure | Overkill for linear task dispatch; we'd need OpenClaw integration layer | | CrewAI | High-level collaboration patterns | Abstractions hide OpenClaw behavior we need to work around |

We respect these frameworks and may evolve toward their patterns as needs grow.

---

When to Evolve Beyond This Design

This lightweight approach works well for small teams, few agents, and explicit orchestration. Consider migrating to heavier frameworks when:

Trigger Conditions for Evolution

| Current Limit | Future Need | Candidate Pattern | |---------------|-------------|-------------------| | 3-4 agents, point-to-point | 10+ agents, dynamic discovery | Topic/subscription (AutoGen-style) | | Single orchestrator | Multiple coordinators needing sync | Broadcast bus or event broker | | Explicit spawn/send | Automatic workflow resumption | Durable workflow engine (LangGraph-style) | | File-based artifacts | Rich shared state with transactions | Comprehensive memory layer | | Linear task chains | Complex branching/joining | Graph-based orchestration | | Zoe reviews everything | Full autonomy required | Reduced human-in-the-loop |

Migration Path

If you hit these limits:

1. Evaluate AutoGen Core for message routing and broadcast needs 2. Evaluate LangGraph for durable, complex workflows 3. Consider a hybrid: Keep this framework for OpenClaw-specific workarounds, add framework for orchestration

Our Commitment

This framework will remain honest about its scope:

  • Not a replacement for full agent runtimes
  • Not a broadcast bus or message broker
  • Not a workflow engine with cycles and conditions

It is: A pragmatic layer that makes OpenClaw's multi-agent capabilities reliable at small scale.

---

spawn-interceptor Plugin (v3.6.0)

An OpenClaw plugin (~300 lines of JavaScript) that:

1. Automatically intercepts every sessions_spawn call via the before_tool_call hook 2. Logs the task to task-log.jsonl with status spawning 3. Provides foundation for completion detection (Layer 2)

Zero configuration. Zero agent-side changes. Agents don't even know it exists.

Architecture

Agent calls sessions_spawn()
         │
         ▼
┌─────────────────────────────────────────────────┐
│             spawn-interceptor v3.6.0              │
│          (OpenClaw Plugin, ~250 lines)          │
├─────────────────────────────────────────────────┤
│                                                 │
│  ┌─ before_tool_call hook ──────────────────┐   │
│  │  • Detect sessions_spawn calls           │   │
│  │  • Extract task metadata (agent, runtime) │   │
│  │  • Log to task-log.jsonl (spawning)      │   │
│  │  • Store in pendingTasks Map             │   │
│  └──────────────────────────────────────────┘   │
│                                                 │
│  ┌─ Completion Detection (4 layers) ────────┐   │
│  │                                          │   │
│  │  L1: Native Event Stream                 │   │
│  │      streamTo="parent" progress events   │   │
│  │                                          │   │
│  │  L2: Registration Layer         (hook)   │   │
│  │      Records spawning state              │   │
│  │                                          │   │
│  │  L3: Basic Completion                    │   │
│  │      • ACP Session Poller (~15s)         │   │
│  │      • Stale Reaper (30min)              │   │
│  │                                          │   │
│  │  L4: Terminal-State Correction           │   │
│  │      content-aware-completer.py          │   │
│  │      Requires content evidence           │   │
│  │                                          │   │
│  └──────────────────────────────────────────┘   │
│                                                 │
│  → Update task-log.jsonl (completed/failed)     │
│  → Persist pendingTasks to .pending-tasks.json  │
└─────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────────────┐
│              task-log.jsonl                     │
│    (Single source of truth for ALL events)      │
├─────────────────────────────────────────────────┤
│ Writers:                                        │
│   • spawn-interceptor (Layer 2)                 │
│   • content-aware-completer (Layer 4)           │
│   • completion-listener (notifications)         │
│                                                 │
│ Consumers:                                      │
│   • Any JSONL reader                            │
└─────────────────────────────────────────────────┘

content-aware-completer (Layer 4)

Solves the Type 4 task problem (tasks that appear non-terminal but should be completed):

| Tier | Evidence Required | Action | Confidence | |------|------------------|--------|------------| | Tier 1 | Session closed + Content evidence | Mark complete | High | | Tier 2 | Session closed, No content | Keep pending | Medium | | Tier 3 | Content present, Session open | Keep pending | Low | | Tier 4 | No evidence | Keep pending | Low |

Core Rules:

  • Strong Evidence Required: Both session closed AND content evidence
  • Historical File Rejection: Prevents marking tasks complete based on old files
  • Empty File Rejection: Ignores zero-byte outputs
  • Idempotent Writes: Safe to run multiple times
  • UTC Timezone Safe: All timestamps in UTC

---

Quick Start

Prerequisites

  • OpenClaw >= 2026.3.x (requires before_tool_call plugin hook support)
  • Python 3.10+ (for completion-listener and content-aware-completer)
  • At least 1 agent configured

1. Install the Plugin

cp -r plugins/spawn-interceptor ~/.openclaw/extensions/

2. Restart the Gateway

# macOS
launchctl kickstart -k gui/$(id -u)/ai.openclaw.gateway

# Linux
systemctl --user restart openclaw-gateway

3. Verify

# Trigger an ACP task, then check the log:
tail -f ~/.openclaw/shared-context/monitor-tasks/task-log.jsonl

You should see entries like:

{
  "taskId": "tsk_20260313_abc123",
  "agentId": "main",
  "runtime": "acp",
  "status": "spawning",
  "spawnedAt": "2026-03-13T01:30:00.000Z"
}

4. (Optional) Set up content-aware-completer

# Run continuously for Tier 4 completion correction
python3 examples/content-aware-completer/content_aware_completer.py --loop --interval 30

# Or run once
python3 examples/content-aware-completer/content_aware_completer.py --once

Recommended mode: mode="run" for coding/documentation tasks. Use mode="session" or mode="thread" only for complex multi-turn tasks.

See QUICKSTART.md for the full deployment guide.

---

Alternative: Subagent + Claude Code CLI

If ACP's zombie sessions, concurrency deadlocks, and cross-process event loss are blocking you, there's a simpler path: bypass ACP entirely.

Instead of sessions_spawn(runtime="acp") -> acpx -> Claude Code Agent -> Claude Code CLI (four layers, each with its own session management), use sessions_spawn(runtime="subagent") + exec claude --print (two layers, Gateway-managed).

Key Differences

| Issue | ACP | Subagent + CLI | |-------|-----|----------------| | Zombie sessions | Common (session stays open after process exits) | Impossible (CLI exits = done) | | Concurrent deadlocks | maxConcurrentSessions exhaustion | No session pool | | Cross-process events | onAgentEvent only works in-process | No cross-process dependency | | Completion detection | 5-layer polling pipeline (~960 lines) | Native subagent_ended (0 extra lines) | | Process cleanup | Manual acpx GC | Dual timeout watchdog + SIGTERM->SIGKILL |

Quick Start

# From your agent, use exec to run the v1 wrapper:
bash scripts/run_v1.sh "Your coding task here" "task-label"

See examples/subagent-claude-runner/README.md for full setup and usage.

Trade-offs

  • CLI fallback latency: Completion notification has ~20s delay (spawn-interceptor falls back to CLI when subagent.run() is unavailable outside request context)
  • No intermediate progress: Claude Code transcript writes at LLM turn boundaries only. Milestones require explicit MILESTONE: markers
  • Single-shot only: claude --print is one-shot. For multi-turn interactive sessions, ACP is still needed

---

Known OpenClaw Bugs

This framework exists partly because of these unresolved bugs in OpenClaw:

| Issue | Description | Impact | Our Workaround | |-------|------------|--------|---------------| | #34054 | Gateway doesn't call runtime.close() for completed oneshot sessions | Zombie sessions hit maxConcurrentSessions limit | Daily GC in Guardian script | | #35886 | ACP child processes not cleaned after TTL | Zombie process accumulation | Guardian health-check auto-restart | | #40272 | notifyChannel doesn't work in ACP | No native completion notification | Four-layer completion pipeline | | (undocumented) | subagent_ended hook didn't fire for ACP runtime | ACP task status stuck at spawning | ACP Session Poller (Layer 3); fixed upstream in PR #46308 |

---

Default Agent Template

When spawning ACP agents, use this minimal template:

# Default version (coding/docs tasks)
sessions_spawn(
    sessionKey=f"agent:{agent_id}:task",
    agentId=agent_id,
    prompt="Your task here",
    mode="run",  # Recommended for most tasks
    streamTo="parent",  # Enables Layer 1 event stream
)

For complex multi-turn tasks:

# Extended version (complex multi-turn tasks only)
sessions_spawn(
    sessionKey=f"agent:{agent_id}:task",
    agentId=agent_id,
    prompt="Your complex task here",
    mode="session",  # Only for complex multi-turn
    streamTo="parent",
)

---

Documentation

| Document | Purpose | |----------|---------| | DOCS_MAP.md | Start here — recommended reading order for new readers | | COMMUNICATION_ISSUES.md | Problem analysis & design rationale (start here after README) | | ARCHITECTURE.md | Architecture deep-dive with data flow diagrams | | AGENT_PROTOCOL.md | Full collaboration protocol specification | | ROUNDTABLE_PROTOCOL.md | Shared-channel discussion rules for multi-agent roundtables | | COMPLETION_TRUTH_MATRIX.md | Runtime completion sources and fallback chains | | CAPABILITY_LAYERS.md | L1 (OpenClaw native) / L2 (framework) / L3 (needs core changes) | | CONTENT_AWARE_COMPLETER.md | Layer 4 completion validation documentation | | QUICKSTART.md | Detailed deployment guide | | GETTING_STARTED.md | Onboarding for new users | | ANTIPATTERNS.md | Pitfalls and lessons learned | | INTERNAL_VS_OSS.md | Open source vs internal version differences | | RELEASE_NOTES.md | Version history |

---

Repository Structure

├── plugins/
│   └── spawn-interceptor/        # OpenClaw plugin (~250 lines)
│       ├── index.js              # v3.6.0: hooks + completion pipeline
│       ├── package.json          # Plugin metadata
│       └── openclaw.plugin.json  # OpenClaw plugin manifest
├── examples/
│   ├── completion-relay/         # Basic completion listener
│   │   ├── completion_listener.py
│   │   └── tests/
│   ├── content-aware-completer/  # Layer 4 completion validation
│   │   ├── content_aware_completer.py
│   │   └── tests/
│   ├── subagent-claude-runner/    # ACP alternative: subagent + Claude Code CLI
│   │   ├── runner.js             # CLI process manager with dual timeout watchdog
│   │   ├── run_v1.sh             # Blocking orchestration wrapper
│   │   ├── watcher.js            # Optional progress monitor
│   │   ├── cleanup.sh            # Run directory garbage collection
│   │   └── README.md             # Setup and usage guide
│   ├── l2_capabilities.py        # L2 capability implementations
│   └── protocol_messages.py      # Protocol message format demo
├── COMMUNICATION_ISSUES.md       # Core design document
├── ARCHITECTURE.md               # Architecture deep-dive
├── AGENT_PROTOCOL.md             # Collaboration protocol
├── CONTENT_AWARE_COMPLETER.md    # Layer 4 documentation
├── INTERNAL_VS_OSS.md            # Open source scope
├── RELEASE_NOTES.md              # Version history
└── README_CN.md                  # Chinese README

---

Design Principles

| Principle | Old Way | Our Way | |-----------|---------|---------| | Task registration | Agent must remember wrapper function | Plugin hook auto-intercepts (Layer 2) | | Completion detection | Single point of failure | Four-layer defensive pipeline | | Intermediate states | Not tracked | Native event stream (Layer 1) | | Terminal validation | Session closed = complete | Content evidence required (Layer 4) | | State management | In-memory only (lost on restart) | Persistent to JSONL + pending file | | Monitoring | Separate files per component | Unified task-log.jsonl | | Error handling | Silent failures | DLQ + Stale Reaper + Content validation |

---

Contributing

PRs and Issues welcome. See CONTRIBUTING.md for guidelines.

License

MIT License

Related plugins

Browse all →