# OpenClaw 系统架构设计文档 > 项目:https://github.com/openclaw/openclaw > 文档版本:1.0 > 创建日期:2026-02-06 --- ## 目录 - [1. 概述](#1-概述) - [2. 项目整体结构](#2-项目整体结构) - [3. 核心架构设计](#3-核心架构设计) - [3.1 CLI 命令系统](#31-cli-命令系统) - [3.2 网关架构](#32-网关架构) - [3.3 消息通道系统](#33-消息通道系统) - [3.4 媒体管道](#34-媒体管道) - [3.5 基础设施层](#35-基础设施层) - [4. 关键设计模式](#4-关键设计模式) - [4.1 依赖注入](#41-依赖注入) - [4.2 状态管理](#42-状态管理) - [4.3 消息路由机制](#43-消息路由机制) - [4.4 配置系统](#44-配置系统) - [4.5 钩子系统](#45-钩子系统) - [5. 插件扩展机制](#5-插件扩展机制) - [5.1 插件类型](#51-插件类型) - [5.2 插件 API](#52-插件-api) - [5.3 通道插件](#53-通道插件) - [5.4 插件运行时](#54-插件运行时) - [6. 路与会话管理](#6-路由与会话管理) - [6.1 路由解析](#61-路由解析) - [6.2 会话管理](#62-会话管理) - [6.3 会话持久化](#63-会话持久化) - [7. 模块间关系](#7-模块间关系) - [8. 通信协议](#8-通信协议) - [8.1 Gateway Protocol](#81-gateway-protocol) - [8.2 ACP (Agent Client Protocol)](#82-acp-agent-client-protocol) - [9. 认证与安全](#9-认证与安全) - [9.1 设备配对](#91-设备配对) - [9.2 Gateway 认证](#92-gateway-认证) - [9.3 SSRF 防护](#93-ssrf-防护) - [10. 测试策略](#10-测试策略) - [11. 构建与部署](#11-构建与部署) - [12. 编码规范](#12-编码规范) - [13. 附录:代码示例](#13-附录代码示例) --- ## 1. 概述 OpenClaw 是一个多平台消息聚合与 AI Agent 平台,支持 WhatsApp、Telegram、Discord、Slack、Signal、iMessage 等多个消息通道,以及多种 AI 模型提供者。 ### 1.1 核心特性 - **多通道支持**:通过插件化架构支持十多种消息平台 - **Gateway 架构**:集中式的 WebSocket 网关服务所有客户端 - **插件系统**:可扩展的插件机制(通道、模型提供者、内存等) - **灵活路由**:基于绑定的智能消息路由 - **会话管理**:持久化的会话存储和历史记录 - **媒体处理**:完整的媒体上传、存储和处理管道 ### 1.2 技术栈 - **语言**:TypeScript (ESM) - **运行时**:Node 22+,支持 Bun - **包管理**:pnpm(保持 npm 兼容性) - **测试**:Vitest + V8 覆盖率 - **Lint/Format**:Oxlint + Oxfmt - **协议**:WebSocket (JSON),HTTP (REST + OpenAI 兼容) --- ## 2. 项目整体结构 ### 2.1 主要目录 ``` openclaw/ ├── src/ │ ├── cli/ # CLI 入口和命令系统 │ ├── commands/ # 命令实现 │ ├── gateway/ # Gateway 服务器 │ ├── channels/ # 通道系统 │ ├── providers/ # AI 模型提供者 │ ├── agents/ # Agent 运行时 │ ├── media/ # 媒体管道 │ ├── infra/ # 基础设施 │ ├── config/ # 配置系统 │ ├── plugins/ # 插件系统 │ ├── plugin-sdk/ # 插件开发 SDK │ ├── routing/ # 路由系统 │ ├── acp/ # Agent Client Protocol │ ├── pairing/ # 设备配对 │ ├── hooks/ # 生命周期钩子 │ ├── terminal/ # 终端输出工具 │ ├── logging/ # 日志系统 │ └── ... ├── extensions/ # 扩展插件(工作区包) ├── apps/ # 移动应用和 macOS 应用 ├── ui/ # Web UI (dien) ├── docs/ # 文档 ├── skills/ # 内置技能 └── openclaw.mjs # CLI 入口点 ``` ### 2.2 程序入口 ``` openclaw.mjs (编译缓存入口) └─> src/index.ts └─> buildProgram() ├─> createProgramContext() └─> registerProgramCommands() ``` ### 2.3 包导出 ```json { "exports": { ".": "./dist/index.js", "./plugin-sdk": "./dist/plugin-sdk/index.js", "./cli-entry": "./openclaw.mjs" } } ``` --- ## 3. 核心架构设计 ### 3.1 CLI 命令系统 #### 3.1.1 命令注册表模式 CLI 基于 `commander`,采用注册表模式进行命令注册: ```typescript // src/cli/program/command-registry.ts export const commandRegistry: CommandRegistration[] = [ { id: "setup", register: ({ program }) => registerSetupCommand(program) }, { id: "onboard", register: ({ program }) => registerOnboardCommand(program) }, { id: "config", register: ({ program }) => registerConfigCli(program) }, { id: "memory", register: ({ program }) => registerMemoryCli(program) }, { id: "agent", register: ({ program, ctx }) => registerAgentCommands(program, ctx) }, // ... 更多命令 ]; ``` #### 3.1.2 命令分类 | 类别 | 模块 | 示例命令 | | -------- | --------------- | ------------------------------ | | 核心命令 | `src/commands/` | `agent`, `send`, `message` | | 配置命令 | `src/config/` | `config set/get/apply` | | 通道命令 | Sub CLI | `channels status/login/logout` | | Gateway | Sub CLI | `gateway run/stop` | | Daemon | Sub CLI | `daemon start/stop` | | 节点 | Sub CLI | `nodes list/status` | #### 3.1.3 路由机制 ```typescript // src/cli/program/routing.ts export type RouteSpec = { match: (path: string[]) => boolean; loadPlugins?: boolean; // 是否加载插件以解析命令 run: (argv: string[]) => Promise; }; ``` 路由机制允许快速解析某些命令路径,例如网关模式下直接启动而无需加载所有插件。 --- ### 3.2 网关架构 #### 3.2.1 网关启动入口 ``` src/gateway/server.impl.ts └─> startGatewayServer(port, opts): Promise ``` #### 3.2.2 核心子系统 | 子系统 | 实现路径 | 职责 | | ---------- | ------------------------------------- | --------------------- | | 协议验证 | `src/gateway/protocol/` | Ajv 验证所有 JSON 帧 | | 方法处理器 | `src/gateway/server-methods/` | 各个 gateway 方法实现 | | 运行时状态 | `src/gateway/server-runtime-state.ts` | 服务器状态、缓冲区 | | 通道管理 | `src/gateway/server-channels.ts` | 通道启停 | | 事件处理 | `src/gateway/server-chat.ts` | Agent 事件和广播 | | WebSocket | `src/gateway/server-ws-runtime.ts` | WS 连接和帧分发 | | 配置重载 | `src/gateway/config-reload.ts` | 监听配置变更 | | 启动/停止 | `src/gateway/server-close.ts` | 优雅关闭 | | 协议定义 | `src/gateway/protocol/` | 请求/事件帧模式 | #### 3.2.3 网关启动流程 ``` startGatewayServer() ├─> 加载配置 (loadConfig) ├─> 加载插件 (loadGatewayPlugins) │ ├─> 注册插件钩子 │ ├─> 注册通道插件 │ └─> 注册自定义 Gateway 方法 ├─> 创建运行时状态 (createGatewayRuntimeState) │ ├─> HTTP 服务器 │ ├─> WebSocket 服务器 │ ├─> Canvas Host (a2ui, 端口 18793) │ └─> 协议验证 (AJV) ├─> 注册状态恢复 ├─> 注册方法处理器 (coreGatewayHandlers + plugin 处理器) ├─> 启动通道 (startChannels) ├─> 启动 Cron 服务 (buildGatewayCronService) ├─> 配置重载监听 (startGatewayConfigReloader) └─> 返回 GatewayServer 实例 ``` #### 3.2.4 HTTP 端点 默认端口:`18789` | 端点 | 方法 | 用途 | | ---------------------- | --------- | ------------------ | | `/ws` | WebSocket | 控制和事件流 | | `/v1/gateway/*` | POST | 增量 API 方法 | | `/v1/chat/completions` | POST | OpenAI 兼容 | | `/v1/responses` | POST | OpenResponses 兼容 | | `/media/*` | GET/PUT | 媒体服务 | --- ### 3.3 消息通道系统 #### 3.3.1 通道插件化 所有通道必须实现 `ChannelPlugin` 接口: ```typescript export type ChannelPlugin = { id: ChannelId; meta: ChannelMeta; capabilities: ChannelCapabilities; config: ChannelConfigAdapter; configSchema?: ChannelConfigSchema; setup?: ChannelSetupAdapter; pairing?: ChannelPairingAdapter; security?: ChannelSecurityAdapter; groups?: ChannelGroupAdapter; mentions?: ChannelMentionAdapter; outbound?: ChannelOutboundAdapter; status?: ChannelStatusAdapter; gatewayMethods?: string[]; gateway?: ChannelGatewayAdapter; auth?: ChannelAuthAdapter; elevated?: ChannelElevatedAdapter; commands?: ChannelCommandAdapter; streaming?: ChannelStreamingAdapter; threading?: ChannelThreadingAdapter; messaging?: ChannelMessagingAdapter; agentPrompt?: ChannelAgentPromptAdapter; directory?: ChannelDirectoryAdapter; resolver?: ChannelResolverAdapter; actions?: ChannelMessageActionAdapter; heartbeat?: ChannelHeartbeatAdapter; agentTools?: ChannelAgentToolFactory | ChannelAgentTool[]; }; ``` #### 3.3.2 核心适配器 | 适配器 | 接口 | 职责 | | ------------------------- | ---------------------------------- | ---------- | | `ChannelConfigAdapter` | `listAccountIds`, `resolveAccount` | 配置解析 | | `ChannelOutboundAdapter` | `sendText`, `sendMedia` | 消息发送 | | `ChannelGatewayAdapter` | `startAccount`, `stopAccount` | 网关启停 | | `ChannelStatusAdapter` | `snapshots`, `probe`, `audit` | 状态探查 | | `ChannelGroupAdapter` | `resolveGroup` | 群组上下文 | | `ChannelSecurityAdapter` | `resolveDMPolicy` | 安全策略 | | `ChannelDirectoryAdapter` | `listGroups`, `listPeers` | 用户目录 | | `ChannelAuthAdapter` | `login` | 登录流程 | #### 3.3.3 内置通道 | 通道 | 实现目录 | | ------------ | --------------------------- | | WhatsApp Web | `src/web/`, `src/whatsapp/` | | Telegram | `src/telegram/` | | Discord | `src/discord/` | | Slack | `src/slack/` | | Signal | `src/signal/` | | iMessage | `src/imessage/` | | LINE | `src/line/` | | Google Chat | `src/googlechat/` | | MS Teams | `src/msteams/` | #### 3.3.4 扩展通道 位于 `extensions/*/`: - `bluebubbles` / `matrix` / `msteams` (extension) - `tton` / `zalo` / `zalouser` - `nostr` / `mattermost` - `nextcloud-talk` / `feishu` --- ### 3.4 媒体管道 #### 3.4.1 核心组件 | 文件 | 职责 | | -------------- | -------------------------------------------- | | `mime.ts` | MIME 类型检测(magic number + content type) | | `parse.ts` | 消息媒介提取(文本、图片、音频等) | | `store.ts` | 磁盘存储,文件命名 `{original}---{uuid}.ext` | | `fetch.ts` | HTTP/HTTPS 远程获取 | | `host.ts` | HTTP 服务,鉴权和 Headers | | `image-ops.ts` | 图片调整大小 (JPEG) | | `audio.ts` | 音频转换、兼容性检查 | | `server.ts` | HTTP 服务配置 | #### 3.4.2 存储结构 ``` ~/.openclaw/media/ ├── inbound/ # 接收的媒体 └── outbound/ # 发送的媒体 ``` #### 3.4.3 媒体处理流程 ``` 入站: 消息媒介提取 ↓ MIME 检测 (magic number) ↓ 保存到磁盘 (store.ts) ↓ 生成内部 URL 出站: 媒体上传/处理 ↓ MIME 检测 ↓ 压缩/转换 (可选) ↓ 保存到磁盘 ↓ 通过 HTTP 端点服务 ``` --- ### 3.5 基础设施层 #### 3.5.1 端口管理 `src/infra/ports.ts` | 功能 | 说明 | | -------------------------- | ------------------ | | `checkPortAvailability` | 检查端口是否可用 | | `killPortOccupyingProcess` | 杀死占用端口的进程 | | `autoDetectAvailablePort` | 自动检测可用端口 | | `DEFAULT_PORT` | 默认端口 18789 | #### 3.5.2 SSRF 防护 `src/infra/net/ssrf.ts` 解析主机名并验证是否为安全的内部地址。 #### 3.5.3 事件系统 | 表件 | 事件类型 | | ---------------------- | ------------ | | `diagnostic-events.ts` | 诊断事件 | | `heartbeat-events.ts` | 心跳事件 | | `system-events.ts` | 系统事件队列 | | `channel-activity.ts` | 通道活动跟踪 | #### 3.5.4 出站传送 `src/infra/outbound/deliver.ts` 支持三种传送模式: - `single` - 单通道 - `gateway` - 通过网关 - `mixed` - 混合模式 --- ## 4. 关键设计模式 ### 4.1 依赖注入 #### 4.1.1 CLI 依赖 ```typescript // src/cli/deps.ts export type CliDeps = { sendMessageWhatsApp: typeof sendMessageWhatsApp; sendMessageTelegram: typeof sendMessageTelegram; sendMessageDiscord: typeof sendMessageDiscord; sendMessageSlack: typeof sendMessageSlack; sendMessageSignal: typeof sendMessageSignal; sendMessageIMessage: typeof sendMessageIMessage; }; export function createDefaultDeps(): CliDeps { return { sendMessageWhatsApp, sendMessageTelegram, sendMessageDiscord, sendMessageSlack, sendMessageSignal, sendMessageIMessage, }; } ``` #### 4.1.2 插件运行时依赖 ```typescript // src/plugins/runtime/types.ts export type PluginRuntime = { version: string; config: { loadConfig, writeConfigFile }; system: { enqueueSystemEvent, runCommandWithTimeout }; media: { loadWebMedia, detectMime, mediaKindFromMime, ... }; tts: { textToSpeechTelephony }; tools: { createMemoryGetTool, createMemorySearchTool, ... }; channel: { text: { chunkByNewline, chunkMarkdownText, ... }; reply: { dispatchReplyWithBufferedBlockDispatcher, ... }; routing: { resolveAgentRoute }; pairing: { buildPairingReply, ... }; network: { fetchRemoteMedia, saveMediaBuffer }; activity: { record, get }; session: { resolveStorePath, ... }; // 各通道特定函数... }; logging: { shouldLogVerbose, getChildLogger }; state: { resolveStateDir }; }; ``` --- ### 4.2 状态管理 #### 4.2.1 配置状态 ```typescript // 配置加载流程 loadConfig() → parseConfigJson5() → validateConfigObject() → migrateLegacyConfig() ``` 配置文件位置:`~/.openclaw/config.json5` #### 4.2.2 配置监听和重载 `src/gateway/config-reload.ts` 监听配置文件变更,触发网关状态更新。 #### 4.2.3 通道状态 ```typescript // src/gateway/server-channels.ts type ChannelRuntime = { id: string; accountId: string; status: Snapshot; stop?: () => Promise; // ... }; ``` #### 4.2.4 会话状态 会话存储位置:`~/.openclaw/sessions/{channel}/{accountId}/{session}.jsonl` 会话键格式:`session/{agentId}/{channel}/{accountId}/{peer}` --- ### 4.3 消息路由机制 #### 4.3.1 路由解析 ```typescript // src/routing/resolve-route.ts export type ResolveAgentRouteInput = { cfg: OpenClawConfig; channel: string; accountId?: string | null; peer?: RoutePeer | null; parentPeer?: RoutePeer | null; guildId?: string | null; teamId?: string | null; }; export type ResolvedAgentRoute = { agentId: string; channel: string; accountId: string; sessionKey: string; mainSessionKey: string; matchedBy: | "binding.peer" | "binding.peer.parent" | "binding.guild" | "binding.team" | "binding.account" | "binding.channel" | "default"; }; ``` #### 4.3.2 路由匹配优先级 ``` 1. peer (具体用户/组) 2. thread parent peer (继承) 3. guildId (Discord 服务器) 4. teamId (Slack/Teams) 5. account (非通配符) 6. account (通配符) 7. default (默认代理) ``` #### 4.3.3 会话键构建 ```typescript // src/routing/session-key.ts export function buildAgentSessionKey(params: { agentId: string; channel: string; accountId?: string | null; peer?: RoutePeer | null; dmScope?: "main" | "per-peer" | "per-channel-peer" | "per-account-channel-peer"; identityLinks?: Record; }): string; ``` --- ### 4.4 配置系统 #### 4.4.1 配置模块 ``` src/config/ ├── types.agent-defaults.ts ├── types.agents.ts ├── types.auth.ts ├── types.base.ts ├── types.browser.ts ├── types.channels.ts ├── types.openclaw.ts ├── types.cron.ts ├── types.sandbox.ts ├── types.memory.ts ├── types.models.ts ├── types.node-host.ts ├── types.tts.ts ├── types.tools.ts ├── types.whatsapp.ts ├── types.imessage.ts ├── types.slack.ts ├── ... (更多通道配置) ├── config.ts (主导出) └── ... ``` #### 4.4.2 验证机制 使用 Zod 进行模式验证: ```typescript validateConfigObject(config): ValidationResult validateConfigObjectWithPlugins(config, plugins): ValidationResult ``` #### 4.4.3 配置迁移 `migrateLegacyConfig()` - 处理旧配置版本的自动迁移。 --- ### 4.5 钩子系统 #### 4.5.1 钩子类型 ```typescript // src/hooks/types.ts export type HookEntry = { name: string; handler: HookHandler; priority?: number; }; export type HookEvent = | "before_agent_start" | "after_agent_start" | "before_message_send" | "after_message_send" | "message_received" | "tool_called" | "config_changed" // ... 更多钩子 }; ``` #### 4.5.2 钩子注册方式 - 插件通过 `api.registerHook()` 注册 - 优先级按 `priority` 数值排序 --- ## 5. 插件扩展机制 ### 5.1 插件类型 | 类型 | 说明 | 示例 | | ---------- | ----------------- | ---------------------- | | `memory` | 内存/向量存储插件 | LanceDB | | `channel` | 通道插件 | Matrix, Zalo | | `provider` | 模型提供者插件 | 自定义 OpenAI 兼容 API | ### 5.2 插件 API ```typescript // src/plugins/types.ts export type OpenClawPluginDefinition = { id?: string; name?: string; description?: string; version?: string; kind?: PluginKind; // "channel" | "memory" | "provider" | ... configSchema?: OpenClawPluginConfigSchema; register?: (api: OpenClawPluginApi) => void | Promise; activate?: (api: OpenClawPluginApi) => void | Promise; }; ``` ### 5.3 通道插件 参见 [3.3.1 节](#331-通道插件化)。 ### 5.4 插件运行时 插件通过 `OpenClawPluginApi.runtime` 访问运行时 API,参见 [4.1.2 节](#412-插件运行时依赖)。 --- ## 6. 路由与会话管理 ### 6.1 路由解析 详见 [4.3.1 节](#431-路由解析)。 ### 6.2 会话结构 ``` ~/.openclaw/sessions/ └── {channel}/ └── {accountId}/ └── {session}.jsonl (JSONL 格式) ``` 每行包含: - `role`: "user" | "assistant" - `content`: 消息内容 - `timestamp`: 时间戳 - `meta`: 元数据 ### 6.3 会话 API ```typescript loadSessionStore(sessionPath): Promise saveSessionStore(sessionPath, session): Promise updateLastRoute(channel, accountId, route): Promise ``` --- ## 7. 模块间关系 ### 7.1 CLI 层 ``` openclaw.mjs └─> src/index.ts ├─> createDefaultDeps() ├─> buildProgram() │ ├─> createProgramContext() │ └─> registerProgramCommands() │ ├─> registerSetupCommand() │ ├─> registerOnboardCommand() │ ├─> registerConfigCli() │ ├─> registerAgentCommands() │ ├─> registerSubCliCommands() │ └─> ... └─> 程序解析 → 各命令处理器 ``` ### 7.2 Gateway 层 ``` startGatewayServer() ├─> 配置加载 (loadConfig) ├─> 插件加载 (loadGatewayPlugins) │ ├─> 插件注册表 │ └─> 通道插件 (listChannelPlugins) ├─> 运行时状态 (createGatewayRuntimeState) │ ├─> HTTP 服务器 │ ├─> WebSocket 服务器 │ ├─> Canvas Host (a2ui) │ └─> 协议验证 (AJV) ├─> 方法处理器 ├─> 事件广播 ├─> 通道管理器 ├─> Cron 服务 ├─> 节点注册 └─> 配置重载 ``` ### 7.3 消息流转 ``` 入站: 平台消息 → 通道适配器 → Gateway 事件 → 路由解析 → Agent 执行 → 出站 出站: CLI/Web/App → Gateway 方法 → 根据路由分发 → 通道适配器 → 平台 ``` --- ## 8. 通信协议 ### 8.1 Gateway Protocol 详见 `docs/concepts/architecture.md` 和 `docs/gateway/protocol.md`。 核心帧类型: ```typescript export type GatewayFrame = | RequestFrame // {type:"req", id, method, params} | ResponseFrame // {type:"res", id, ok, payload|error} | EventFrame; // {type:"event", event, payload, seq?, stateVersion?} ``` #### 事件类型 - `agent` - Agent 执行事件 - `chat` - 聊天更新 - `presence` - 在线状态 - `health` - 健康状态 - `heartbeat` - 心跳 - `cron` - Cron 任务 - `tick` - 定时脉冲 #### 常用 Gateway 方法 | 方法 | 功能 | | ----------------- | ------------ | | `health` | 健康检查 | | `status` | 状态查询 | | `send` | 发送消息 | | `agent` | 启动 Agent | | `channels.list` | 列出通道账户 | | `channels.status` | 通道状态 | | `channels.login` | 通道登录 | ### 8.2 ACP (Agent Client Protocol) 位于 `src/acp/`,用于 Agent 与客户端的通信。 --- ## 9. 认证与安全 ### 9.1 设备配对 新建设备 ID 需要配对批准: - 本地连接:自动批准 - 远程连接:需要显式批准 - 挑战签名:防止劫持 设备令牌存储在 `~/.openclaw/device-tokens.json`。 ### 9.2 Gateway 认证 ```typescript // src/config/auth.ts export type GatewayAuth = { token?: string; // Bearer Token 检查 allowed?: string[]; // 允许的设备 ID }; ``` ### 9.3 SSRF 防护 `src/infra/net/ssrf.ts` - 防止服务器端请求伪造。 --- ## 10. 测试策略 ### 10.1 测试框架 - **框架**:Vitest - **覆盖率**:V8 - **阈值**:70% (线/分/函数/语句) ### 10.2 测试类型 | 类型 | 后缀 | 说明 | | -------- | --------------- | ------------ | | 单元测试 | `*.test.ts` | 功能单元测试 | | E2E 测试 | `*.e2e.test.ts` | 端到端测试 | ### 10.3 测试命令 ```bash pnpm test # 运行所有测试 pnpm test:coverage # 运行测试并生成覆盖率报告 pnpm test:live # 运行 Live 测试 (需要真实凭证) ``` --- ## 11. 构建与部署 ### 11.1 构建命令 ```bash pnpm build # 完整构建 pnpm tsgo # TypeScript 类型检查 pnpm check # Lint + Format ``` ### 11.2 macOS 应用打包 ```bash scripts/package-mac-app.sh ``` ### 11.3 发布流程 详解见 `docs/platforms/mac/release.md` 和 `docs/reference/RELEASING.md`。 发布通道: - **stable**: 版本标签 (v2026.2.4) + npm tag `latest` - **beta**: 预发布标签 (v2026.2.4-beta.N) + npm tag `beta` - **dev**: main 分支头部 (无标签) --- ## 12. 编码规范 ### 12.1 语言与风格 - **语言**:TypeScript (ESM) - **严格类型**:避免 `any` - **格式化**:Oxlint + Oxfmt - **文件大小**:目标 < ~700 LOC ### 12.2 命名规范 - **产品/文档标题**:OpenClaw (大写) - **CLI 命令**:openclaw (小写) - **包/二进制名**:openclaw (小写) - **配置键**:openclaw (小写) ### 12.3 代码注释 为复杂或非显而易见的逻辑添加简短注释。 ### 12.4 终端输出 - **进度条**:`src/cli/progress.ts` (osc-progress + @clack/prompts) - **表格**:`src/terminal/table.ts` (ANSI 安全换行) ### 12.5 多 Agent 安全 - 不创建/应用/删除 git stash 除非明确要求 - 不删除/修改 git worktree 除非明确要求 - 尊重其他 Agent 的工作 --- ## 13. 附录:代码示例 ### 13.1 注册插件钩子 ```typescript export default function register(api: OpenClawPluginApi) { api.on("before_agent_start", async (event, ctx) => { console.log("Agent starting:", ctx.agentId); return { systemPrompt: "Custom system prompt...", prependContext: "Extended context...\n", }; }); api.on("message_received", async (event, ctx) => { console.log("Received:", event.content); }); } ``` ### 13.2 注册自定义命令 ```typescript api.registerCommand({ name: "tts", description: "Text to speech", acceptsArgs: true, requireAuth: true, handler: async (ctx) => { const text = ctx.args || ""; // ... 处理 tts 并回复 return { text: `Speaking: ${text}` }; }, }); ``` ### 13.3 注册通道 ```typescript api.registerChannel({ id: "mychannel" as ChannelId, meta: { id: "mychannel" as ChannelId, label: "My Channel", selectionLabel: "My Channel", docsPath: "/channels/mychannel", blurb: "My custom channel implementation", }, capabilities: { chatTypes: ["dm", "group"], media: true, reactions: true, reply: true, }, config: { listAccountIds: (cfg) => Object.keys(cfg.mychannel?.accounts ?? {}), resolveAccount: (cfg, accountId) => cfg.mychannel?.accounts?.[accountId] ?? {}, defaultAccountId: (cfg) => "default", }, outbound: { deliveryMode: "gateway", sendText: async (ctx) => { // 发送文本到平台 return { ok: true }; }, }, gatewayMethods: ["mychannel.send"], gateway: { startAccount: async (ctx) => { // 启动通道监听器 }, stopAccount: async (ctx) => { // 停止通道监听器 }, }, }); ``` ### 13.4 使用插件 SDK ```typescript import { registerTool, resolveAgentRoute, loadConfig, dispatchReplyWithBufferedBlockDispatcher, } from 'openclaw/plugin-sdk'; export default function register(api: OpenClawPluginApi) { const tool = { type: 'function', name: 'mytool', description: 'My custom tool', parameters: { type: 'object', properties: {}, additionalProperties: false, }, handler: async ({ accountId, messageChannel, agentId, ... }) => { // 处理工具 return { success: true, content: [], data: undefined, }; }, }; api.registerTool(tool); } ``` --- ## 参考资料 - [Gateway Architecture](/docs/concepts/architecture.md) - [Gateway Protocol](/docs/gateway/protocol.md) - [提交 PR 指南](/docs/help/submitting-a-pr.md) - [提交 Issue 指南](/docs/help/submitting-an-issue.md) - [测试文档](/docs/testing.md) - [发布文档](/docs/reference/RELEASING.md) - [macOS 发布](/docs/platforms/mac/release.md) --- **文档结束**