openclaw
Research notes on OpenClaw's architecture, API, and automation patterns for integration with sandbox-agent.
How it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Research notes on OpenClaw's architecture, API, and automation patterns for integration with sandbox-agent.
Agent definition
openclaw.mdOpenClaw (formerly Clawdbot) Research
Research notes on OpenClaw's architecture, API, and automation patterns for integration with sandbox-agent.
Overview
- **Provider**: Multi-provider (Anthropic, OpenAI, etc. via Pi agent)
- **Execution Method**: WebSocket Gateway + HTTP APIs
- **Session Persistence**: Session Key (string) + Session ID (UUID)
- **SDK**: No official SDK - uses WebSocket/HTTP protocol directly
- **Binary**: `clawdbot` (npm global install or local)
- **Default Port**: 18789 (WebSocket + HTTP multiplex)
Architecture
OpenClaw is architected differently from other coding agents (Claude Code, Codex, OpenCode, Amp):
┌─────────────────────────────────────┐
│ Gateway Service │ ws://127.0.0.1:18789
│ (long-running daemon) │ http://127.0.0.1:18789
│ │
│ ┌─────────────────────────────┐ │
│ │ Pi Agent (embedded RPC) │ │
│ │ - Tool execution │ │
│ │ - Model routing │ │
│ │ - Session management │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
│
├── WebSocket (full control plane)
├── HTTP /v1/chat/completions (OpenAI-compatible)
├── HTTP /v1/responses (OpenResponses-compatible)
├── HTTP /tools/invoke (single tool invocation)
└── HTTP /hooks/agent (webhook triggers)**Key Difference**: OpenClaw runs as a **daemon** that owns the agent runtime. Other agents (Claude, Codex, Amp) spawn a subprocess per turn. OpenClaw is more similar to OpenCode's server model but with a persistent gateway.
Automation Methods (Priority Order)
1. WebSocket Gateway Protocol (Recommended)
Full-featured bidirectional control with streaming events.
Connection Handshake
// Connect to Gateway
const ws = new WebSocket("ws://127.0.0.1:18789");
// First frame MUST be connect request
ws.send(JSON.stringify({
type: "req",
id: "1",
method: "connect",
params: {
minProtocol: 3,
maxProtocol: 3,
client: {
id: "gateway-client", // or custom client id
version: "1.0.0",
platform: "linux",
mode: "backend"
},
role: "operator",
scopes: ["operator.admin"],
caps: [],
auth: { token: "YOUR_GATEWAY_TOKEN" }
}
}));
// Expect hello-ok response
// { type: "res", id: "1", ok: true, payload: { type: "hello-ok", ... } }Agent Request
// Send agent turn request
const runId = crypto.randomUUID();
ws.send(JSON.stringify({
type: "req",
id: runId,
method: "agent",
params: {
message: "Your prompt here",
idempotencyKey: runId,
sessionKey: "agent:main:main", // or custom session key
thinking: "low", // optional: low|medium|high
deliver: false, // don't send to messaging channel
timeout: 300000 // 5 minute timeout
}
}));Response Flow (Two-Stage)
// Stage 1: Immediate ack
// { type: "res", id: "...", ok: true, payload: { runId, status: "accepted", acceptedAt: 1234567890 } }
// Stage 2: Streaming events
// { type: "event", event: "agent", payload: { runId, seq: 1, stream: "output", data: {...} } }
// { type: "event", event: "agent", payload: { runId, seq: 2, stream: "tool", data: {...} } }
// ...
// Stage 3: Final response (same id as request)
// { type: "res", id: "...", ok: true, payload: { runId, status: "ok", summary: "completed", result: {...} } }2. OpenAI-Compatible HTTP API
For simple integration with tools expecting OpenAI Chat Completions.
**Enable in config:**
{
gateway: {
http: {
endpoints: {
chatCompletions: { enabled: true }
}
}
}
}**Request:**
curl -X POST http://127.0.0.1:18789/v1/chat/completions \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "clawdbot:main",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}'**Model Format:**
- `model: "clawdbot:<agentId>"` (e.g., `"clawdbot:main"`)
- `model: "agent:<agentId>"` (alias)
3. OpenResponses HTTP API
For clients that speak OpenResponses (item-based input, function tools).
**Enable in config:**
{
gateway: {
http: {
endpoints: {
responses: { enabled: true }
}
}
}
}**Request:**
curl -X POST http://127.0.0.1:18789/v1/responses \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "clawdbot:main",
"input": "Hello",
"stream": true
}'4. Webhooks (Fire-and-Forget)
For event-driven automation without maintaining a connection.
**Enable in config:**
{
hooks: {
enabled: true,
token: "webhook-secret",
path: "/hooks"
}
}**Request:**
curl -X POST http://127.0.0.1:18789/hooks/agent \
-H "Authorization: Bearer webhook-secret" \
-H "Content-Type: application/json" \
-d '{
"message": "Run this task",
"name": "Automation",
"sessionKey": "hook:automation:task-123",
"deliver": false,
"timeoutSeconds": 120
}'**Response:** `202 Accepted` (async run started)
5. CLI Subprocess
For simple one-off automation (similar to Claude Code pattern).
clawdbot agent --message "Your prompt" --session-key "automation:task"
Session Management
Session Key Format
agent:<agentId>:<sessionType>
agent:main:main # Main agent, main session
agent:main:subagent:abc # Subagent session
agent:beta:main # Beta agent, main session
hook:email:msg-123 # Webhook-spawned session
global # Legacy global session
Session Operations (WebSocket)
// List sessions
{ type: "req", id: "...", method: "sessions.list", params: { limit: 50, activeMinutes: 120 } }
// Resolve session info
{ type: "req", id: "...", method: "sessions.resolve", params: { key: "agent:main:main" } }
//Read more
OpenClaw (formerly Clawdbot) Research
Research notes on OpenClaw's architecture, API, and automation patterns for integration with sandbox-agent.
Overview
- **Provider**: Multi-provider (Anthropic, OpenAI, etc. via Pi agent)
- **Execution Method**: WebSocket Gateway + HTTP APIs
- **Session Persistence**: Session Key (string) + Session ID (UUID)
- **SDK**: No official SDK - uses WebSocket/HTTP protocol directly
- **Binary**: `clawdbot` (npm global install or local)
- **Default Port**: 18789 (WebSocket + HTTP multiplex)
Architecture
OpenClaw is architected differently from other coding agents (Claude Code, Codex, OpenCode, Amp):
┌─────────────────────────────────────┐
│ Gateway Service │ ws://127.0.0.1:18789
│ (long-running daemon) │ http://127.0.0.1:18789
│ │
│ ┌─────────────────────────────┐ │
│ │ Pi Agent (embedded RPC) │ │
│ │ - Tool execution │ │
│ │ - Model routing │ │
│ │ - Session management │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
│
├── WebSocket (full control plane)
├── HTTP /v1/chat/completions (OpenAI-compatible)
├── HTTP /v1/responses (OpenResponses-compatible)
├── HTTP /tools/invoke (single tool invocation)
└── HTTP /hooks/agent (webhook triggers)**Key Difference**: OpenClaw runs as a **daemon** that owns the agent runtime. Other agents (Claude, Codex, Amp) spawn a subprocess per turn. OpenClaw is more similar to OpenCode's server model but with a persistent gateway.
Automation Methods (Priority Order)
1. WebSocket Gateway Protocol (Recommended)
Full-featured bidirectional control with streaming events.
Connection Handshake
// Connect to Gateway
const ws = new WebSocket("ws://127.0.0.1:18789");
// First frame MUST be connect request
ws.send(JSON.stringify({
type: "req",
id: "1",
method: "connect",
params: {
minProtocol: 3,
maxProtocol: 3,
client: {
id: "gateway-client", // or custom client id
version: "1.0.0",
platform: "linux",
mode: "backend"
},
role: "operator",
scopes: ["operator.admin"],
caps: [],
auth: { token: "YOUR_GATEWAY_TOKEN" }
}
}));
// Expect hello-ok response
// { type: "res", id: "1", ok: true, payload: { type: "hello-ok", ... } }Agent Request
// Send agent turn request
const runId = crypto.randomUUID();
ws.send(JSON.stringify({
type: "req",
id: runId,
method: "agent",
params: {
message: "Your prompt here",
idempotencyKey: runId,
sessionKey: "agent:main:main", // or custom session key
thinking: "low", // optional: low|medium|high
deliver: false, // don't send to messaging channel
timeout: 300000 // 5 minute timeout
}
}));Response Flow (Two-Stage)
// Stage 1: Immediate ack
// { type: "res", id: "...", ok: true, payload: { runId, status: "accepted", acceptedAt: 1234567890 } }
// Stage 2: Streaming events
// { type: "event", event: "agent", payload: { runId, seq: 1, stream: "output", data: {...} } }
// { type: "event", event: "agent", payload: { runId, seq: 2, stream: "tool", data: {...} } }
// ...
// Stage 3: Final response (same id as request)
// { type: "res", id: "...", ok: true, payload: { runId, status: "ok", summary: "completed", result: {...} } }2. OpenAI-Compatible HTTP API
For simple integration with tools expecting OpenAI Chat Completions.
**Enable in config:**
{
gateway: {
http: {
endpoints: {
chatCompletions: { enabled: true }
}
}
}
}**Request:**
curl -X POST http://127.0.0.1:18789/v1/chat/completions \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "clawdbot:main",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}'**Model Format:**
- `model: "clawdbot:<agentId>"` (e.g., `"clawdbot:main"`)
- `model: "agent:<agentId>"` (alias)
3. OpenResponses HTTP API
For clients that speak OpenResponses (item-based input, function tools).
**Enable in config:**
{
gateway: {
http: {
endpoints: {
responses: { enabled: true }
}
}
}
}**Request:**
curl -X POST http://127.0.0.1:18789/v1/responses \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "clawdbot:main",
"input": "Hello",
"stream": true
}'4. Webhooks (Fire-and-Forget)
For event-driven automation without maintaining a connection.
**Enable in config:**
{
hooks: {
enabled: true,
token: "webhook-secret",
path: "/hooks"
}
}**Request:**
curl -X POST http://127.0.0.1:18789/hooks/agent \
-H "Authorization: Bearer webhook-secret" \
-H "Content-Type: application/json" \
-d '{
"message": "Run this task",
"name": "Automation",
"sessionKey": "hook:automation:task-123",
"deliver": false,
"timeoutSeconds": 120
}'**Response:** `202 Accepted` (async run started)
5. CLI Subprocess
For simple one-off automation (similar to Claude Code pattern).
clawdbot agent --message "Your prompt" --session-key "automation:task"
Session Management
Session Key Format
agent:<agentId>:<sessionType> agent:main:main # Main agent, main session agent:main:subagent:abc # Subagent session agent:beta:main # Beta agent, main session hook:email:msg-123 # Webhook-spawned session global # Legacy global session
Session Operations (WebSocket)
// List sessions
{ type: "req", id: "...", method: "sessions.list", params: { limit: 50, activeMinutes: 120 } }
// Resolve session info
{ type: "req", id: "...", method: "sessions.resolve", params: { key: "agent:main:main" } }
//Run Coding Agents in Sandboxes. Control Them Over HTTP. Supports Claude Code, Codex, OpenCode, and Amp.
Repo: rivet-dev/sandbox-agent
Other agents on sandbox-agent.
- amp
Research notes on Sourcegraph Amp's configuration, credential discovery, and runtime behavior.
Open agent - codex
Research notes on OpenAI Codex's configuration, credential discovery, and runtime behavior based on agent-jj implementation.
Open agent - opencode
Research notes on OpenCode's configuration, credential discovery, and runtime behavior based on agent-jj implementation.
Open agent

