OpenClaw Core Flow Part 3: Tools, Memory & the Hook Pipeline

Part 1 traced the gateway. Part 2 covered routing and the agent loop. Now we complete the picture: how tools execute in Docker sandboxes, how memory retrieval works, and the exact order of all 13 plugin hooks in the message path.


Tool Policy: Who Gets What

File: src/agents/tool-policy.ts

OpenClaw 核心流程第三部分:工具、记忆与 Hook 管道

第一部分 追踪了 gateway。第二部分 涵盖了路由与 agent 循环。现在我们完成最后一块拼图:工具如何在 Docker 沙箱中执行、记忆检索的工作原理,以及消息路径中所有 13 个插件 hook 的精确执行顺序。


工具策略:谁能使用什么

文件: src/agents/tool-policy.ts

工具通过带有分组展开的分层策略进行管控:

const TOOL_GROUPS = {
  "group:memory": ["memory_search", "memory_get"],
  "group:web":    ["web_search", "web_fetch"],
  "group:fs":     ["read", "write", "edit", "apply_patch"],
  "group:runtime": ["exec", "process"],
};

四种预设配置控制访问权限:

配置 访问范围
minimal session_status
coding 文件系统、运行时、会话、记忆、图像
messaging 消息 + 会话工具
full 无限制

策略编译为 glob 匹配器,采用拒绝优先语义。解析层级:agent 专属 → 全局 → agent 级别 → 全局工具策略。子 agent 受到额外限制 — gatewaycronmemory_searchsessions_send 始终被拒绝。

OpenClaw Core Flow Part 2: The Double Loop — Routing, Prompts & the Agent State Machine

Part 1 covered the gateway path from WebSocket to dispatchInboundMessage(). Now we trace what happens inside — from routing a message to the right agent, through system prompt construction, to the core LLM loop.


Channel → MsgContext Normalization

When a message arrives from any channel (WhatsApp, Telegram, Discord…), it’s normalized into MsgContext — a comprehensive type with 80+ fields defined in src/auto-reply/templating.ts:

OpenClaw 核心流程第二部分:双重循环 — 路由、提示词与 Agent 状态机

第一部分 介绍了从 WebSocket 到 dispatchInboundMessage() 的 gateway 路径。本篇继续深入内部——从将消息路由到正确的 agent,到系统提示词构建,再到核心 LLM 循环。


Channel → MsgContext 规范化

当消息从任意 channel(WhatsApp、Telegram、Discord……)到达时,会被规范化为 MsgContext——这是一个定义在 src/auto-reply/templating.ts 中、包含 80 多个字段的综合类型:

type MsgContext = {
  Body?: string;           // 标准消息内容
  BodyForAgent?: string;   // 可能包含信封/历史/上下文
  Channel?: string;        // "whatsapp"、"telegram" 等
  From?: string;           // 发送者 ID
  ChatType?: string;       // "direct" | "group" | "channel"
  GroupId?: string;
  ReplyToId?: string;
  MediaPath?: string;
  CommandAuthorized?: boolean;  // 默认为 false(默认拒绝)
  // ... 70+ 个其他字段
};

src/auto-reply/reply/inbound-context.ts 中的 finalizeInboundContext() 负责执行规范化:

OpenClaw Core Flow Part 1: From WebSocket to Agent — The Gateway Path

In our previous series we mapped the architecture. Now we go deeper — tracing the actual code path a message takes from arrival to response. This is the function-by-function walkthrough.

/images/openclaw-core-flow.svg


Server Bootstrap

File: src/gateway/server.impl.ts

OpenClaw 核心流程 Part 1:从 WebSocket 到 Agent — Gateway 路径全解析

上一个系列中,我们梳理了整体架构。现在我们深入一层——追踪一条消息从到达到响应的完整代码路径。本文是逐函数的详细 walkthrough。

/images/openclaw-core-flow.svg


服务器启动

文件: src/gateway/server.impl.ts

一切从 startGatewayServer(port = 18789) 开始。服务器以 noServer 模式创建 WebSocketServer,最大 payload 限制为 25MB,挂载 HTTP upgrade 处理器,并连接 agent 事件系统。

const httpServer = opts.tlsOptions
  ? createHttpsServer(opts.tlsOptions, handleRequest)
  : createHttpServer(handleRequest);

upgrade 处理器负责路由 WebSocket 连接,Canvas 路径有特殊处理(单独认证):