Project Walkthrough: CLI → One Reply
This page ties a single end-to-end path together: how one request / one inbound message becomes a delivered reply.
10-minute observable baseline
Before diving into internals, make the system observable:
- Start the gateway:
openclaw gateway- Tail logs (file logger):
openclaw logs --follow- Open the Control UI and complete one chat run:
openclaw dashboardWhat you should be able to observe:
- Control plane: after a successful
connect, you receive server events liketick/presence(see TypeBox). - Chat:
chat.sendACKs quickly with arunId, then the reply streams back viachatevents (see Control UI).
0) Start with the control plane (WS: connect / subscribe / call)
- First frame must be
connect - After the handshake, you continuously receive event streams (e.g.
tick/presence) - Then you call methods (e.g.
chat.send/agent/logs.tail) - Most methods ACK quickly; results arrive via streamed events
See:
End-to-end map (from connect to reply)
flowchart TD
A[Control UI / CLI] -->|WS connect| B[Gateway WS control plane]
B --> C{authorize + dispatch}
C -->|chat.send| D[chat handler]
D --> E[resolve route / sessionKey]
E --> F[enqueue lane: session:<key>]
F --> G[runEmbeddedPiAgent]
G --> H[model + tools]
H --> I[stream chat events]
I --> A
Code entry points (use rg):
- control plane:
src/gateway/server.ts,src/gateway/server/ws-connection/message-handler.ts,src/gateway/server-methods.ts chat.send:src/gateway/server-methods/chat.ts- session keys:
src/config/sessions/session-key.ts,src/gateway/server-session-key.ts - lanes/queue:
src/process/command-queue.ts,src/agents/pi-embedded-runner/lanes.ts,src/gateway/server-lanes.ts
1) CLI → Gateway: startup and observability
Common entry points:
openclaw gatewayopenclaw gateway statusopenclaw logs --follow
See:
2) Channels → inbound normalization
Channels vary a lot (WhatsApp/Telegram/Discord/…). OpenClaw normalizes them into a shared inbound model before routing and execution.
See:
3) Routing + session keys (ordering and isolation)
Key ideas:
- resolve
agentId - choose a
sessionKey(DM collapse vs group/channel isolation) - enqueue by
sessionKey(lane) to preserve ordering
See:
4) The agent loop (run → attempt → streaming → persist)
See:
5) Deterministic delivery (back to the same channel)
See:
Debug checklist
- WS connection issues: start with the
connect.challenge/connectflow in Gateway protocol, then check Health checks. chat.send“hangs”: inspectchatevents in Control UI, or useopenclaw gateway callfor a minimal repro (see CLI: gateway).- Ordering/isolation issues: verify session key choice and lane semantics (see Session tool and Queue + lanes).