Chapter 3

Core Concepts Overview: How Gateway, Pi, Skills, Plugin and Memory Fit Together

Chapter 3: The Complete Conceptual Map: How Gateway / Pi / Skills / Plugin / Memory Relate

3.1 Five Core Components at a Glance

Before diving into each component, let's define each one's responsibility boundary in a single sentence. These precise definitions will help you make correct architectural decisions throughout your work with OpenClaw.

Component One-Sentence Definition
Gateway The unified message entry and exit point — transforms platform-specific messages into a standard internal format and routes responses back to the originating platform
Pi The Agent's brain — understands message intent, selects tools, executes the reasoning loop, and generates responses
Skills Reusable capability packages — define what Pi can do in specific scenarios, expressed primarily as configuration files rather than code
Plugin Code modules that extend Gateway's capabilities — add new Channel Bridges, custom middleware, or extend the Plugin Registry
Memory The persistent context storage system — manages short-term conversation history, long-term user profiles, and the shared Workspace knowledge base

These five components together form the complete OpenClaw runtime. Their relationship is not a strict linear hierarchy but rather a star topology centered around Pi, with Gateway managing boundary communications.

3.2 The Full Data Flow: From WhatsApp to the User

Understanding the data flow is the most direct way to understand OpenClaw's architecture. Here is the complete chain of a WhatsApp message from arrival to response:

User (WhatsApp)
    │
    ▼ [HTTPS Webhook]
WhatsApp Business API
    │
    ▼ [HTTP POST]
Channel Bridge (whatsapp)
    │  Parse raw message format, extract text, attachments, sender info
    │  Convert to unified InternalMessage format
    ▼
Integration Gateway (Node.js process)
    │  Session resolution (8-priority Binding rules engine)
    │  Command Queue scheduling (write to appropriate Lane)
    ▼
Pi Agent Core (embedded, not a subprocess)
    │  Load System Prompt + Session Memory
    │  Call LLM Provider (Anthropic Claude API)
    │  Execute tool call loop (read/write/edit/bash)
    │  Query/update Memory
    ▼
Action Layer
    │  Execute external integration calls (if Pi calls HubSpot, Jira, etc.)
    │  Human-in-the-loop approval (high-risk actions pause and wait)
    │  Tool results returned to Pi
    ▼
Pi Agent Core (generate final response)
    │
    ▼
Integration Gateway (receives response)
    │
    ▼
Channel Bridge (whatsapp)
    │  Format response as WhatsApp message format
    ▼
WhatsApp Business API
    │
    ▼
User receives reply

This chain involves multiple format transformations, but each transformation has a clear boundary and protocol. Let's examine each node in detail.

3.3 Deep Dive: Integration Gateway

Gateway's Core Responsibilities

The Gateway is the boundary process of the entire OpenClaw system — the dividing line between the external world and the internal Agent world. It runs as a single Node.js process and communicates with the Pi process via WebSocket (localhost:18789).

The Gateway has four core subsystems:

1. Channel Bridge Collection

Each messaging platform has a corresponding Channel Bridge. A Channel Bridge is responsible for:

// The core structure of InternalMessage (simplified)
interface InternalMessage {
  id: string;              // Unique message ID
  channelId: string;       // Source Channel
  senderId: string;        // Sender's platform ID
  content: MessageContent; // Message content (text/attachments/location/etc.)
  metadata: {
    platform: string;      // 'whatsapp' | 'telegram' | 'slack' | ...
    timestamp: number;
    replyTo?: string;      // Quoted message ID (if any)
    threadId?: string;     // Thread ID (Slack threads, etc.)
  };
  sessionContext?: SessionContext; // Session resolution result (populated by Gateway)
}

2. Session Management System

A Session is Pi's persistent conversation context with a specific user on a specific Channel. Session resolution is one of the Gateway's core logic responsibilities.

3. Command Queue

The Gateway has a built-in four-Lane priority queue that manages all command scheduling destined for Pi.

4. Plugin Registry

Maintains the registry of installed Plugins and manages their lifecycle (loading, starting, stopping).

The Significance of the Single-Writer Pattern

The Gateway uses a Single-writer Pattern: at any given moment, only one process (the Gateway) writes to the SQLite database. Pi processes access Memory through the Gateway's interface rather than operating the database directly.

This design solves the following problems:

Session Resolution: 8 Levels of Priority

When a message arrives, the Gateway needs to determine which Session it belongs to, and therefore which Agent should handle it and with what configuration. Session resolution matches Binding rules in the following priority order:

1. peer match      → The message originates from a specific peer identifier (exact user ID match)
2. parent          → Inherits parent Session configuration (for sub-tasks in multi-turn conversations)
3. guild + role    → Combination of specific server + specific role in Discord/Slack
4. guild           → All users in a specific Discord/Slack server
5. team            → Organization-level configuration
6. account         → User account-level configuration
7. channel         → Channel-level default configuration
8. default         → Global default configuration

Higher priority (lower number) means more specific matching. This mechanism lets you configure different Agent behavior for different users while maintaining a sensible default.

Configuration example:

{
  "bindings": [
    {
      "priority": 1,
      "match": { "type": "peer", "peerId": "user:[email protected]" },
      "agent": "vip-agent",
      "config": { "model": "claude-opus-4-5-20251201" }
    },
    {
      "priority": 7,
      "match": { "type": "channel", "channelId": "whatsapp-business" },
      "agent": "support-agent",
      "config": { "model": "claude-haiku-3-5-20251201" }
    }
  ]
}

3.4 Deep Dive: The Pi Framework

Pi's Four Core Packages

The Pi framework consists of four npm packages, each with a clear responsibility:

pi-ai/
  ├── Purpose: LLM Provider abstraction layer
  ├── Responsibility: Unify the API call interface across different Providers
  └── Key interfaces: LLMProvider, CompletionRequest, CompletionResponse

pi-agent-core/
  ├── Purpose: Pi's core reasoning engine
  ├── Responsibility: Manage reasoning loop (ReAct pattern), dispatch tool calls,
  │               manage Session state
  └── Key interfaces: AgentSession, ToolRegistry, ReasoningLoop

pi-coding-agent/
  ├── Purpose: Extended Agent for coding scenarios
  ├── Responsibility: Extends pi-agent-core with code understanding,
  │               test generation, and other specialized tools
  └── Key interfaces: CodeContext, FileSystem, TestRunner

pi-tui/
  ├── Purpose: Terminal UI (TUI mode Control UI)
  ├── Responsibility: Provide a visual management interface in environments
  │               without a browser
  └── Key interfaces: Dashboard, SessionViewer, LogStream

Pi's Four Foundational Tools

Pi exposes only 4 foundational tools — a deliberate design decision, not a feature gap:

Tool Description Parameters
read Read file or URL content path: string
write Write content to a file path: string, content: string
edit Make precise modifications to a file (diff mode) path: string, old: string, new: string
bash Execute a shell command command: string, timeout?: number

Business integrations (calling the HubSpot API, querying Jira, etc.) are not implemented by extending these 4 tools — they are implemented through Skills and the Action Layer. Keeping Pi's tool set minimal allows the System Prompt to stay under 1,000 tokens, which has a significant impact on performance and cost.

Embedded Execution vs. Subprocess

Pi runs as an embedded module within the Gateway process, not as an independent child process. This design has important performance and architectural implications:

Subprocess mode (traditional approach):

Gateway ──IPC/HTTP──► Pi subprocess
  Latency: 5-20ms (inter-process communication)
  Memory: Gateway and Pi each have independent memory spaces
  Isolation: Strong (process crash doesn't affect the other)

Embedded mode (OpenClaw approach):

Gateway [Pi module runs in the same process]
  Latency: < 0.1ms (function calls)
  Memory: Shared memory space; Pi can directly access Gateway's internal data structures
  Isolation: Weaker (but maintained through TypeScript type system and module boundaries)

Embedded mode allows Pi to directly read the Gateway's Session state and Memory cache without serialization/deserialization — a significant advantage for latency and throughput in high-concurrency scenarios (where the Command Queue processes multiple Sub-agent tasks simultaneously).

3.5 Command Queue in Depth

The Command Queue is the Gateway's task scheduling center, managing the execution order of all commands destined for Pi. Its design goal is: guarantee that messages within a Session are processed in order, while maximizing overall concurrent throughput.

Four Lanes

┌─────────────────────────────────────────────────────────────┐
│                      Command Queue                          │
│                                                             │
│  Global Lane    [====] [====] [====] [====]  max: 4        │
│  Session Lane   [================================]  max: 1  │
│  SubAgent Lane  [=][=][=][=][=][=][=][=]     max: 8        │
│  Cron Lane      [=][=][=][=]...              max: ∞        │
└─────────────────────────────────────────────────────────────┘

Global Lane (concurrency limit: 4): Handles global tasks that require exclusive resources, such as configuration reloads, Plugin installations, and database backups. The concurrency limit of 4 prevents resource contention.

Session Lane (concurrency limit: 1): Each active Session has its own independent Session Lane with a concurrency limit of 1. This guarantees that a given user's messages are processed in order, with no out-of-sequence responses. The Session Lane is Pi's primary channel for processing user messages.

SubAgent Lane (concurrency limit: 8): When Pi decides to launch sub-Agents while handling a task (for example, scraping multiple web pages in parallel), sub-tasks are scheduled through the SubAgent Lane, with at most 8 concurrent. This is how OpenClaw implements concurrent Agent decomposition.

Cron Lane (no concurrency limit): Handles scheduled tasks (periodic report delivery, periodic data sync, etc.). No concurrency limit; triggered by cron expressions.

Four Processing Modes

collect       → Accumulate all pending commands and batch-process; for bulk import scenarios
steer         → Real-time processing; each command immediately enters Pi's reasoning loop
followup      → Handle post-reasoning actions (send response, update Memory, etc.)
steer-backlog → When Session Lane has backlog, merge multiple queued messages before processing

3.6 Skills in Depth

Skills Are Not Code

This is one of the most common misconceptions among newcomers. Skills are not features you need to write code to implement. They are configuration packages that combine existing capabilities (Pi's tools, Gateway's integrations, external APIs) into reusable scenarios.

The structure of a Skill:

# skills/email-summarizer.skill.yaml
id: email-summarizer
name: "Email Summarizer"
version: "1.0.0"
description: "Fetches and summarizes unread emails from Gmail"

triggers:
  - type: command
    pattern: "/summarize-emails"
  - type: schedule
    cron: "0 9 * * MON-FRI"  # Every weekday morning at 9am

inputs:
  - name: maxEmails
    type: integer
    default: 10
    description: "Maximum number of emails to summarize"

steps:
  - id: fetch-emails
    action: integration.gmail.listUnread
    params:
      maxResults: "{{ inputs.maxEmails }}"
  
  - id: summarize
    action: pi.prompt
    params:
      prompt: |
        Please summarize the following emails concisely:
        {{ steps.fetch-emails.result | json }}
      model: claude-haiku-3-5-20251201

outputs:
  - name: summary
    value: "{{ steps.summarize.result }}"

Not a single line of TypeScript. The Skill describes in YAML: trigger conditions, input parameters, execution steps (call the Gmail integration + call Pi for summarization), and output.

Skills Marketplace

The official Skills Marketplace (skills.openclaw.ai) provides community-contributed Skill packages. Installation:

# Browse available Skills
openclaw skills search "email"

# Install a Skill
openclaw skills install [email protected]

# List installed Skills
openclaw skills list

# Enable a Skill in an Agent
# Edit openclaw.json:
{
  "agents": [
    {
      "id": "my-agent",
      "skills": ["email-summarizer"]
    }
  ]
}

3.7 Plugins in Depth

Plugins Are Not Skills

This is another common misconception. The difference between Plugins and Skills:

Dimension Skills Plugins
Implementation YAML/JSON configuration TypeScript code
What they extend Pi's capabilities (what to do) Gateway's capabilities (how to communicate)
Typical use Define business workflows Add new Channel Bridges
Developer requirement No programming needed Requires TypeScript development
Where they run Inside Pi's reasoning loop Inside the Gateway process

Plugins are primarily used for:

Plugin development uses the plugin-sdk:

// plugins/custom-platform/index.ts
import { definePlugin, ChannelBridge, InternalMessage } from '@openclaw/plugin-sdk';

export default definePlugin({
  id: 'custom-platform',
  name: 'Custom Platform Bridge',
  version: '1.0.0',
  
  async setup(registry) {
    registry.registerChannelBridge({
      id: 'custom-platform',
      
      async connect(config) {
        // Establish connection to the custom platform
      },
      
      async receive(): AsyncIterator<InternalMessage> {
        // Receive messages from the platform, convert to InternalMessage
      },
      
      async send(response) {
        // Send response back to the platform
      }
    });
  }
});

3.8 Memory System in Depth

Three-Tier Memory Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Memory System                           │
│                                                             │
│  Short-term Memory                                          │
│  └─ Current Session conversation history (last N messages)  │
│  └─ Storage: RAM, optionally persisted on Session end       │
│  └─ Lifecycle: tied to Session                              │
│                                                             │
│  Long-term Memory                                           │
│  └─ User profiles (preferences, past decisions, key facts)  │
│  └─ Storage: SQLite (vectorized, optional pgvector)         │
│  └─ Lifecycle: persistent, cross-Session                    │
│                                                             │
│  Workspace Memory                                           │
│  └─ Shared team knowledge base (Markdown + semantic index)  │
│  └─ Storage: local filesystem + SQLite vector index         │
│  └─ Lifecycle: persistent, shared across all Agents         │
└─────────────────────────────────────────────────────────────┘

Memory Configuration Example

{
  "memory": {
    "shortTerm": {
      "maxMessages": 50,
      "persistOnSessionEnd": true
    },
    "longTerm": {
      "enabled": true,
      "storage": "sqlite",
      "embeddingModel": "text-embedding-3-small",
      "embeddingProvider": "openai",
      "maxEntries": 10000
    },
    "workspace": {
      "enabled": true,
      "paths": [
        "~/.openclaw/workspace/",
        "/path/to/company-docs/"
      ],
      "indexOnStartup": true,
      "watchForChanges": true
    }
  }
}

How Memory Influences Pi's Reasoning

Before Pi processes each message, the Gateway automatically:

  1. Loads the Short-term Memory for the current Session (conversation history)
  2. Semantically retrieves relevant user information from Long-term Memory based on the current message
  3. Injects the retrieved context into the appropriate section of the System Prompt

This process is transparent to both Pi and the user, but has a significant impact on conversation quality. Pi can "remember" that a user mentioned last time they disliked a certain style, prefer English responses, or referenced a project background weeks ago.

3.9 Precise Definitions of Key Terms

The following terms have precise meanings in OpenClaw documentation and the community. Confusing them leads to configuration errors:

Channel vs. Session

Channel: A persistent messaging platform connection configuration. For example, a configuration that connects to a Slack workspace is one Channel. Channels are static — defined in the configuration file and don't change over time.

Session: A specific conversation context between a user and an Agent on a Channel. Different users' conversations on the same Channel correspond to different Sessions. Sessions are dynamic — automatically created and managed as users send messages.

WhatsApp Channel (1 channel)
  ├── Session: User A's conversation with the Agent
  ├── Session: User B's conversation with the Agent
  └── Session: User C's conversation with the Agent

Binding vs. Tool

Binding: A rule that routes an incoming message to a specific Agent and configuration. Bindings operate at the Gateway layer, before messages reach Pi.

Tool: An operation that Pi can call during reasoning. Tools operate at the Agent Core layer, inside Pi's reasoning loop.

Workspace vs. Project

Workspace: A Memory-layer concept in OpenClaw — the storage location of the shared knowledge base (a collection of folder paths).

Project: (Not an OpenClaw-specific term) — typically refers to a business application built using OpenClaw. A project may include multiple Agents, multiple Channels, and multiple Skills.

3.10 Configuration-Driven vs. Code-Driven: The Paradigm Difference

OpenClaw commits to a configuration-driven paradigm, in sharp contrast to the code-driven paradigms of frameworks like LangChain and AutoGen.

The Core Idea of Configuration-Driven

Configuration-driven means that system behavior is described by data (JSON/YAML files), not by code (TypeScript/Python functions).

Code-driven (LangChain style):

# Every behavior change requires modifying code
chain = LLMChain(
    llm=ChatAnthropic(model="claude-opus-4-5"),
    prompt=ChatPromptTemplate.from_messages([
        ("system", "You are a customer support agent."),
        ("human", "{input}")
    ])
)
result = chain.invoke({"input": user_message})

Configuration-driven (OpenClaw style):

{
  "agents": [{
    "id": "support-agent",
    "systemPrompt": "You are a customer support agent.",
    "llmProvider": "anthropic-primary"
  }]
}

Changing the Agent's behavior only requires editing the JSON file — no rewriting or redeploying code. This enables non-developers to independently maintain Agent configuration.

Real-World Impact of the Paradigm Difference

Operation Code-Driven (LangChain) Configuration-Driven (OpenClaw)
Modify System Prompt Edit code, redeploy Edit JSON, hot reload
Add new messaging platform Write adapter code Install Plugin (or use built-in)
Adjust routing rules Modify routing logic code Edit Binding rules
Non-developer maintenance Nearly impossible Entirely feasible
Version control readability git diff is hard to interpret git diff is clearly readable

Summary

This chapter mapped out the responsibility boundaries and interrelationships of OpenClaw's five core components:

Understanding the boundaries of these components is the key to avoiding common misconceptions (Skills are not code; Plugins are not Skills). In the next chapter, we will further clarify OpenClaw's positioning and applicable scenarios through a systematic comparison with LangChain, AutoGen, and CrewAI.

Rate this chapter
4.8  / 5  (95 ratings)

💬 Comments