How OpenClaw Actually Works: Gateway Routing, Session Keys, and the Pi Runtime
I run OpenClaw daily across Discord, Telegram, and scheduled background routines.
If you treat an AI assistant as just a prompt wrapper around an LLM API, it breaks as soon as real users and background tasks touch it:
- A second message arrives while a slow shell script is running, causing parallel turns to collide.
- You ping the bot in a group chat, and background cron reminders start firing into that group instead of your private DM.
- You switch between debugging infrastructure and drafting an article in one window, quickly filling your context window with noise.
OpenClaw avoids this by separating communication from execution:
- The Gateway manages network connections, routing rules, session keys, turn queueing, and transcript files on disk.
- The Agent Runtime runs isolated execution loops powered by Mario Zechner’s Pi engine.
Here is how a message flows through the system:
Normalizing Inbound Transports
OpenClaw keeps transport details away from the core routing logic. Each chat platform (Discord, Telegram, WhatsApp, Slack, Matrix, iMessage) runs as an isolated channel plugin.
When an event arrives, its adapter converts vendor-specific payloads into a standard internal structure:
- Message text along with media attachments
- Sender identification
- Account ID
- Scope type (direct message, group, channel, thread, topic)
Because the gateway only works with this normalized structure, routing logic stays identical regardless of where the message originated.
Routing to the Right Agent
In OpenClaw, an agent is not just a custom system prompt. Every agent gets an isolated directory tree on disk containing dedicated memory files, daily scratchpads, tool policies, and transcripts.
The Gateway determines which agent handles an incoming message by checking bindings in top-down priority:
- Exact peer match: explicit peer ID bindings.
- Parent peer inheritance: threads and forum topics inherit bindings from their parent channel.
- Peer wildcard: wildcard peer rules.
- Guild or Team match: Discord server roles or Slack workspace teams.
- Account match: specific channel account IDs.
- Channel fallback: fallback rules across an entire channel.
- Default agent: configured default fallback.
Session Keys and Context Isolation
Once an agent is selected, the Gateway derives a Session Key.
The session key defines execution boundaries and context isolation. OpenClaw structures keys hierarchically:
agent:<agentId>:<scope>
A few examples from my setup:
- Personal direct messages:
agent:main:main - Shared room:
agent:main:discord:channel:1479375441797320 - Task thread:
agent:main:discord:channel:1479375441797320:thread:15435047259395 - Topic lane:
agent:main:telegram:group:-1001928374:topic:42
This structure solves context pollution cleanly. When I investigate a bug inside a dedicated thread, that transcript remains completely isolated from my daily personal session.
Separating Metadata from Transcripts
OpenClaw splits session state into two pieces on disk:
- Session Store: A fast key-value store mapping each key to its active session ID, last update timestamp, and last known route.
- Transcripts: Append-only JSONL files containing turn logs, tool invocations, and responses for a given session ID.
When a message arrives, the Gateway checks the last update timestamp. If the session has expired past an idle threshold or hit a daily reset boundary, the Gateway mints a fresh session ID. The old transcript remains on disk for auditing, while the session key immediately points to a clean slate.
Protecting the Default Outbound Route
By default, personal direct messages collapse into agent:main:main, and the last active channel becomes the target for outbound alerts.
If another user messages the bot in a shared group, allowing their message to update the outbound route would hijack scheduled notifications and push them to the wrong channel.
OpenClaw prevents this by deriving a pinned owner from configuration rules. Other users can receive scoped replies when allowed, but only the pinned owner can update the outbound notification target.
Serializing Turns
If you send multiple messages while an agent is executing a command, OpenClaw queues them per session key. The active turn runs to completion, writes its changes to disk, and the next queued turn starts with the updated history.
Assembling the Prompt on Every Turn
OpenClaw builds a fresh prompt for every turn from markdown files on disk and live runtime state:
Skills load lazily: only their names and matching descriptions sit in the prompt. The agent reads the full skill markdown from disk only when it decides to run that workflow.
The Pi Execution Loop
Once the prompt is ready, the Gateway hands control to the Pi runtime.
Inside Pi, the model decides whether to respond with text or invoke tools such as reading files, patching code, running terminal commands, or searching. Each tool result appends back into context, and the loop repeats until the model finishes its task.
Throughout this process, Pi streams structured events back so terminal interfaces and chat channels can display live progress.
When the turn ends, the Gateway saves the new transcript entries, updates the session timestamp, and hands the output to the channel adapter to deliver back to your chat.
Trigger Types
Beyond direct chat messages, OpenClaw supports five different event sources:
- Interactive user messages from chat apps
- Periodic heartbeat ticks for background hygiene and checks
- Scheduled cron jobs for morning digests and sync tasks
- Inbound HTTP webhooks from external services
- Internal events from child sub-agents finishing background work
Why This Architecture Works
OpenClaw stays reliable in daily operation because of straightforward design choices:
- Channel adapters keep chat protocol quirks isolated from core logic.
- Hierarchical session namespaces set concurrency boundaries without external lock managers.
- Transcripts stay append-only, making audits and rollbacks simple.
- Rules, identity, and memory live in plain Markdown files under Git version control.