Skip to main content
This is the first adapter behind the RuntimeAdapter seam, and the template the other four runtimes follow. It changes nothing about how OpenClaw runs; it only re-expresses a live Gateway session as the normalized lifecycle stream. The adapter depends on the structural OpenClawGatewayClient shape (not the concrete GatewayClient class), so a test double or the server’s operator-client slice can be passed in.

Public API

All exports come from src/index.ts. The package declares a single . export in package.json (no subpath barrels).

Classes

OpenClawAdapter members:
  • capabilities(): Capabilities: returns { streaming: true, mcp: false, worktrees: false, resume: true, toolApproval: true, models: [], runtimeClass: 'connected-substrate', nativeSkills: 'preserve', nativeMemory: 'preserve', nativeChannels: 'gateway', nativeScheduler: true }. nativeHome is deliberately omitted; the Gateway owns its own state dir. The connected-substrate class is what makes the one-shot executor runner refuse OpenClaw by construction: its runs ride the LIVE Gateway session over this adapter’s long-lived client.
  • health(): Promise<HealthResult>: races client.agents.list() against a 2 s timeout; any throw → { ok: false, message }, else { ok: true }.
  • start(_task: TaskHandle, opts: StartOpts): Promise<RunHandle>: concatenates opts.context (if any) above opts.message, then calls the raw RPC chat.send with { sessionKey, message, deliver: false, idempotencyKey: crypto.randomUUID() }. The runId is not returned here; it late-binds on the first streaming frame inside events(), so the handle is { adapterId: 'openclaw', sessionKey, runId: null }. A {ok:true} ack that carries accepted: false or a no-run status (no-active-run / no_active_run / dropped / rejected / no_session) throws “acknowledged but did not start a run” so the caller can release/retry instead of blocking on frames that never come.
  • events(run: RunHandle): AsyncIterable<RuntimeEvent>: subscribes eagerly (on call, not on first pull) to client.onEvent, filters frames to run.sessionKey, late/re-binds run.runId from each frame, accumulates non-reasoning text-delta text, and yields the mapped stream via a bounded createAsyncQueue (max: 1000). It is a continuous session observer; it yields across multiple runs on the same long-lived session. Consumer termination (return()) unsubscribes.
  • abort(run: RunHandle): Promise<void>: two-tier teardown via Promise.allSettled: the surgical per-run chat.abort(sessionKey, runId) only when a runId is bound, PLUS the heavier sessions.abort(sessionKey, runId?) backstop ALWAYS (covers the runId-not-yet-bound race and queued/pending work).
  • setModel(run: RunHandle, model: string): Promise<void>: sessions.patch(sessionKey, { model }).
  • writeContext(run: RunHandle, key: string, value: string): Promise<void>: agents.files.set(agentId, key, value), recovering agentId from the agent:<agentId>:<session> sessionKey shape.

Functions

Types & interfaces

The Capabilities, HealthResult, RunHandle, RuntimeAdapter, RuntimeEvent, RuntimeEventBase, StartOpts, and TaskHandle types referenced above are owned by @clawboo/executor; EventFrame, AgentsListResult, and SessionPatchResult come from @clawboo/gateway-client. None are re-exported here.

Used by

  • apps/web/server/lib/runtimes/serverAdapter.ts, whose buildOpenClawServerAdapter instantiates new OpenClawAdapter(client) over the operator connection; the server-side team orchestrator (serverDeliver) uses it to run an OpenClaw team member’s turn.
  • apps/web/server/lib/teamChat/runTeamExchange.ts, wraps the operator client in OpenClawAdapter to drive a peer-chat turn.
  • apps/web/server/lib/routines/openclawDispatch.ts, imports OpenClawAdapter + OpenClawGatewayClient for the connected-substrate routine dispatcher (uses the adapter’s start/events/abort slice; makeAdapter is a test seam).
  • apps/web/server/lib/routines/wakeBridge.ts, probes a scheduled OpenClaw fire via new OpenClawAdapter(operatorClient).
  • apps/web/server/lib/agentSource/openClawAgentSource.ts, exposes its operator client typed as OpenClawGatewayClient.

Source

packages/adapters/openclaw/src/index.ts (barrel; re-exports ./adapter, ./types, ./mapFrame).

See also

Last modified on August 4, 2026