Files
zclaw_openfang/docs/archive/openclaw-legacy/openclaw-knowledge-base.md
iven 07079293f4 feat(hands): restructure Hands UI with Chinese localization
Major changes:
- Add HandList.tsx component for left sidebar
- Add HandTaskPanel.tsx for middle content area
- Restructure Sidebar tabs: 分身/HANDS/Workflow
- Remove Hands tab from RightPanel
- Localize all UI text to Chinese
- Archive legacy OpenClaw documentation
- Add Hands integration lessons document
- Update feature checklist with new components

UI improvements:
- Left sidebar now shows Hands list with status icons
- Middle area shows selected Hand's tasks and results
- Consistent styling with Tailwind CSS
- Chinese status labels and buttons

Documentation:
- Create docs/archive/openclaw-legacy/ for old docs
- Add docs/knowledge-base/hands-integration-lessons.md
- Update docs/knowledge-base/feature-checklist.md
- Update docs/knowledge-base/README.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 23:16:32 +08:00

959 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OpenClaw 线上知识库
**版本**: 1.0.0
**最后更新**: 2026-03-12
**目的**: 为 ZClaw 项目提供全面、结构化的 OpenClaw 抷术参考
---
## 目录
1. [核心概念](#核心概念)
2. [系统架构](#系统架构)
3. [Gateway 协议](#gateway-协议)
4. [配置系统](#配置系统)
5. [Skills 与 Tools](#skills-与-tools)
6. [插件开发](#插件开发)
7. [多 Agent 路由](#多-agent-路由)
8. [安全与沙箱](#安全与沙箱)
9. [Heartbeat 机制](#heartbeat-机制)
10. [Channels 通道系统](#channels-通道系统)
11. [最佳实践](#最佳实践)
12. [ZClaw 映射指南](#zclaw-映射指南)
---
## 核心概念
### OpenClaw 是什么?
OpenClaw 是一个 **自托管的 AI Agent 硴关**,不是简单的"聊天 UI + 模型接入器"。
**核心定位**
- **自托管**: 运行在你自己的硬件上,你的规则
- **多通道**: 一个 Gateway 同时服务 WhatsApp、Telegram、Discord、飞书等多个渠道
- **Agent 原生**: 为编码 Agent 构建,支持工具调用、会话、记忆、多 Agent 路由
- **开源**: MIT 许可,社区驱动
**关键洞察** OpenClaw 的核心价值是 **执行 + 持续性 + 可控性**
- **执行**: 能真正读写文件、跑命令、控浏览器、发消息
- **持续性**: 不只是一次性问答,而是可长期运转的 Agent
- **可控性**: 用户能看到配置、文本指令、工作区与约束,而不是黑盒
### Agent 的真正含义
在 OpenClaw 中,一个 Agent 包含:
- 一个 `agentId`
- 一个独立 workspace / agentDir
- 一组 bootstrap 文件 (`AGENTS.md``SOUL.md``USER.md``IDENTITY.md`)
- 一套工具与 sandbox 规则
- 一套 session 历史
- 一组可能的 channel bindings
- 一种人格 / 工作方式 / 角色定位
### Bootstrap 文件职责
| 文件 | 职责 | 内容示例 |
|------|------|----------|
| `AGENTS.md` | 操作规范与行为准则 | 会话启动 checklist、安全规范、工具使用规则 |
| `SOUL.md` | 身份、气质、边界 | Core Truths、Boundaries、Vibe、Continuity |
| `USER.md` | 关于用户的信息 | 用户习惯、上下文、沟通偏好、时区 |
| `IDENTITY.md` | Agent 外显身份 | Name、Emoji、Avatar、Vibe |
| `HEARTBEAT.md` | 心跳任务指令 | 定时检查任务、触发条件、投递目标 |
---
## 系统架构
### 四层架构
```
┌─────────────────────────────────────────────────────────────┐
│ 应用层 (Application) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │WhatsApp │ │Telegram │ │ Discord │ │ 飞书 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │
│ └────────────┴────────────┴────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Gateway (中枢) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ WebSocket │ │ HTTP API │ │ Config │ │ │
│ │ │ Server │ │ Server │ │ Manager │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Agent Runtime │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Skills │ │ Tools │ │ Memory │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ LLM Providers │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │ Claude │ │ GPT-4 │ │ GLM │ │ Qwen │ │ │
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### Gateway 职责
Gateway 是 OpenClaw 的真正控制面板:
- WebSocket 协议握手与会话维持
- Agent 运行时管理
- Session/stream 事件分发
- Channels 消息收发
- 配置热加载与配置 RPC
- Skills / Tools / Plugins / Heartbeat 协调
- Device auth / pairing / scopes
### Workspace 结构
```
~/.openclaw/
├── openclaw.json # 主配置文件
├── .env # 环境变量
├── workspace/ # 默认工作区
│ ├── AGENTS.md
│ ├── SOUL.md
│ ├── USER.md
│ ├── IDENTITY.md
│ ├── memory.md
│ └── memory/
│ └── YYYY-MM-DD.md
├── agents/ # 多 Agent 状态目录
│ └── <agentId>/
│ ├── agent/
│ │ └── auth-profiles.json
│ └── sessions/
│ └── <sessionKey>.jsonl
└── skills/ # 托管技能目录
```
---
## Gateway 协议
### WebSocket 帧类型
```typescript
// 请求帧
interface GatewayRequest {
type: 'req';
id: string;
method: string;
params?: Record<string, any>;
}
// 响应帧
interface GatewayResponse {
type: 'res';
id: string;
ok: boolean;
payload?: any;
error?: any;
}
// 事件帧
interface GatewayEvent {
type: 'event';
event: string;
payload?: any;
seq?: number;
}
```
### 握手流程
```
客户端 Gateway
│ │
│────── WebSocket Connect ────▶│
│ │
│◀───── connect.challenge ─────│ (包含 nonce)
│ │
│────── connect request ──────▶│ (包含 device 签名)
│ │
│◀───── connect response ──────│ (成功/失败)
│ │
│◀═══════ 事件流 ═══════════════│ (agent, chat, etc.)
│ │
```
### Device 认证
```typescript
// 签名载荷格式 (v2)
const payload = [
'v2',
deviceId,
clientId,
clientMode,
role,
scopes.join(','),
String(signedAt),
token || '',
nonce,
].join('|');
// 使用 Ed25519 签名
const signature = nacl.sign.detached(messageBytes, secretKey);
```
### 连接参数
```typescript
interface ConnectParams {
minProtocol: 3;
maxProtocol: 3;
client: {
id: string; // 客户端标识
version: string; // 客户端版本
platform: string; // Win32/Darwin/Linux
mode: 'operator' | 'node';
};
role: 'operator' | 'node';
scopes: string[]; // ['operator.read', 'operator.write']
auth?: { token?: string };
device: {
id: string; // 设备 ID (公钥指纹)
publicKey: string; // Base64 编码的公钥
signature: string; // 签名
signedAt: number; // 签名时间戳
nonce: string; // 服务器提供的 nonce
};
}
```
### 核心 RPC 方法
| 方法 | 描述 | 参数 |
|------|------|------|
| `agent` | 发送消息给 Agent | `message`, `sessionKey?`, `model?` |
| `health` | 获取健康状态 | - |
| `status` | 获取 Gateway 状态 | - |
| `config.get` | 获取配置 | `path` |
| `config.patch` | 更新配置 | `path`, `value` |
| `send` | 通过渠道发送消息 | `channel`, `chatId`, `text` |
### Agent 流事件
```typescript
interface AgentStreamEvent {
stream: 'assistant' | 'tool' | 'lifecycle';
delta?: string; // 增量文本
content?: string; // 完整内容
tool?: string; // 工具名称
phase?: 'start' | 'end' | 'error';
runId?: string; // 运行 ID
error?: string; // 错误信息
}
```
---
## 配置系统
### 配置文件位置
```
~/.openclaw/openclaw.json # 主配置
~/.openclaw/.env # 环境变量
```
### 配置层级与优先级
```
agents.defaults.* # 全局默认
↓ 覆盖
agents.list[].* # 每个 Agent 的覆盖
↓ 覆盖
channels.defaults.* # 全渠道默认
↓ 覆盖
channels.<channel>.* # 单渠道覆盖
↓ 覆盖
channels.<channel>.accounts.<id>.* # 账号级覆盖
```
### 热加载模式
| 模式 | 行为 |
|------|------|
| `hybrid` (默认) | 安全更改即时生效,关键更改自动重启 |
| `hot` | 只热应用安全更改,需重启时记录警告 |
| `restart` | 任何更改都重启 Gateway |
| `off` | 禁用文件监控,手动重启生效 |
### CLI 配置命令
```bash
# 查看配置
openclaw config get agents.defaults.workspace
# 设置配置
openclaw config set agents.defaults.heartbeat.every "2h"
# 删除配置
openclaw config unset tools.web.search.apiKey
# 配置向导
openclaw configure
# 完整设置向导
openclaw onboard
```
### 环境变量引用
```json
{
"gateway": {
"auth": {
"token": "${OPENCLAW_GATEWAY_TOKEN}"
}
},
"models": {
"providers": {
"openai": {
"apiKey": "${OPENAI_API_KEY}"
}
}
}
}
```
---
## Skills 与 Tools
### Skills 加载位置与优先级
1. **Bundled skills**: 安装包自带
2. **Managed/local skills**: `~/.openclaw/skills`
3. **Workspace skills**: `<workspace>/skills`
4. **Extra dirs**: `skills.load.extraDirs` 配置
**优先级**: workspace > managed > bundled > extraDirs
### SKILL.md 格式
```markdown
---
name: my-skill
description: 技能描述
homepage: https://example.com
user-invocable: true
disable-model-invocation: false
---
# 技能标题
技能说明内容...
Use {baseDir} to reference skill folder path.
```
### Skills vs Tools 区别
| 概念 | 描述 | 示例 |
|------|------|------|
| **Skills** | 任务说明 + 规则 + 可选脚本的组合 | 代码审查、文档生成 |
| **Tools** | 类型化的可执行能力 | `exec`, `read`, `write`, `browser` |
### 内置 Tools
```json
{
"tools": {
"exec": { "shell": true },
"web": {
"search": { "enabled": true }
},
"browser": { "enabled": true },
"read": {},
"write": {},
"edit": {}
}
}
```
### MCP 支持
OpenClaw 原生支持 MCP (Model Context Protocol):
- 给 Agent 扩展新的上下文来源与工具面
- 让技能可以调用标准化外部能力
- 让模型在不写死工具的情况下复用第三方协议能力
---
## 插件开发
### 插件结构
```
my-plugin/
├── openclaw.plugin.json # 必需: 插件清单
├── index.ts # 入口文件
├── package.json
└── dist/
```
### openclaw.plugin.json
```json
{
"id": "my-plugin",
"name": "My Plugin",
"version": "1.0.0",
"description": "Plugin description",
"main": "dist/index.js",
"skills": ["./skills"],
"config": {
"enabled": {
"type": "boolean",
"default": true
}
}
}
```
### 插件 API
```typescript
interface PluginAPI {
config: Record<string, any>;
// 注册 Gateway RPC 方法
registerGatewayMethod(
method: string,
handler: (ctx: RpcContext) => void
): void;
// 注册钩子
registerHook(
event: string,
handler: (...args: any[]) => any,
meta?: Record<string, any>
): void;
}
interface RpcContext {
params: Record<string, any>;
respond(ok: boolean, payload: any): void;
}
```
### ZClaw 插件示例
```typescript
// plugins/zclaw-ui/index.ts
export default function register(api: PluginAPI) {
// 注册自定义 RPC 方法
api.registerGatewayMethod('zclaw.clones.list', ({ respond }) => {
const data = readZclawData();
respond(true, { clones: data.clones });
});
// 注册启动钩子
api.registerHook('gateway:startup', async () => {
console.log('[ZCLAW] Plugin loaded');
});
}
```
---
## 多 Agent 路由
### 路由规则 (按优先级)
1. `peer` 精确匹配 (DM/group/channel id)
2. `parentPeer` 继承匹配 (thread 继承)
3. `guildId + roles` (Discord 角色路由)
4. `guildId` (Discord)
5. `teamId` (Slack)
6. `accountId` 规则
7. channel-level 匹配 (`accountId: "*"`)
8. fallback 到默认 Agent
### Binding 配置
```json
{
"bindings": [
{
"agentId": "work",
"match": {
"channel": "whatsapp",
"accountId": "personal",
"peer": { "kind": "direct", "id": "+15551234567" }
}
},
{
"agentId": "main",
"match": { "channel": "whatsapp" }
}
]
}
```
### 多 Agent 配置示例
```json
{
"agents": {
"list": [
{
"id": "home",
"default": true,
"workspace": "~/.openclaw/workspace-home"
},
{
"id": "work",
"workspace": "~/.openclaw/workspace-work",
"model": "anthropic/claude-opus-4-6"
}
]
},
"bindings": [
{ "agentId": "home", "match": { "channel": "whatsapp", "accountId": "personal" } },
{ "agentId": "work", "match": { "channel": "whatsapp", "accountId": "biz" } }
]
}
```
---
## 安全与沙箱
### 沙箱模式
| 模式 | 描述 |
|------|------|
| `off` | 无沙箱,直接执行 |
| `write` | 只沙箱写操作 |
| `all` | 所有操作都在沙箱中执行 |
### 工具策略
```json
{
"agents": {
"list": [
{
"id": "family",
"sandbox": { "mode": "all" },
"tools": {
"allow": ["read", "exec"],
"deny": ["write", "browser"]
}
}
]
}
}
```
### 安全检查清单
- [ ] 无硬编码密钥 (使用 env 引用)
- [ ] DM 访问控制已配置
- [ ] 群聊 mention 规则已设置
- [ ] 工具权限最小化
- [ ] 沙箱模式适当
- [ ] Gateway 端口不对外暴露
---
## Heartbeat 机制
### 概念
Heartbeat 不是简单的 cron而是 **定期触发一个完整 Agent turn**
- 默认读取 `HEARTBEAT.md`
- 如果没事做,返回 `HEARTBEAT_OK`
- 可以配置投递目标 (`none``last` 或具体渠道)
- 可以设置 active hours
- 支持 per-agent 覆盖
### 配置
```json
{
"agents": {
"defaults": {
"heartbeat": {
"every": "1h",
"activeHours": { "start": "09:00", "end": "18:00" },
"deliverTo": "last"
}
}
}
}
```
### HEARTBEAT.md 示例
```markdown
# 心跳任务
每小时检查:
1. 是否有待处理的提醒
2. 是否需要发送日报
3. 日历事件提醒
如果无事可做,回复 HEARTBEAT_OK
```
---
## Channels 通道系统
### 支持的通道
| 通道 | 多账号 | 描述 |
|------|--------|------|
| WhatsApp | ✅ | 通过 Web WhatsApp |
| Telegram | ✅ | Bot API |
| Discord | ✅ | Bot + Guild |
| 飞书 | ✅ | 企业自建应用 |
| Slack | ✅ | Bot + Workspace |
| iMessage | ❌ | macOS only |
| Signal | ✅ | 通过 signald |
### 通道配置结构
```json
{
"channels": {
"whatsapp": {
"enabled": true,
"dmPolicy": "pairing",
"allowFrom": ["+15555550123"],
"accounts": {
"personal": {
"authDir": "~/.openclaw/credentials/whatsapp/personal"
},
"biz": {
"authDir": "~/.openclaw/credentials/whatsapp/biz"
}
}
}
}
}
```
### 访问控制
```json
{
"channels": {
"whatsapp": {
"dmPolicy": "allowlist",
"allowFrom": ["+15555550123"],
"groups": {
"*": { "requireMention": true }
}
}
},
"messages": {
"groupChat": {
"mentionPatterns": ["@openclaw", "小龙虾"]
}
}
}
```
---
## 最佳实践
### 1. 配置管理
```bash
# 使用 CLI 而非直接编辑 JSON
openclaw config set agents.defaults.model "anthropic/claude-sonnet-4-6"
# 验证配置
openclaw doctor
# 查看日志
openclaw logs --follow
```
### 2. Agent 隔离
- 每个 Agent 使用独立 workspace
- 不共享 `agentDir` (会导致 auth/session 冲突)
- 敏感 Agent 启用沙箱
### 3. 密钥管理
```json
// 使用环境变量引用
{
"models": {
"providers": {
"openai": {
"apiKey": "${OPENAI_API_KEY}"
}
}
}
}
```
### 4. 错误处理
- Gateway 连接是协议适配工程,不是简单的 ws 连接
- 实现指数退避重连
- 正确处理 `connect.challenge`
---
## ZClaw 映射指南
### 设置页面对应关系
| ZClaw 页面 | OpenClaw 子系统 | 真实目标 |
|-----------|-----------------|----------|
| 通用 | 系统级设置 | 控制连接状态、系统级行为开关 |
| 模型与 API | providers / model defaults | 管理 provider 配置、主模型与 fallback |
| MCP 服务 | Tools / MCP | 定义 Agent 可接入的外部能力 |
| 技能 | Skills | 管理 Agent 可调用的工作流知识库 |
| IM 频道 | Channels | 管理消息来源和路由规则 |
| 工作区 | Workspace / Sandbox | 确定 Agent 执行边界 |
| 数据与隐私 | Data / Telemetry | 明确数据存储位置和隐私设置 |
| 分身/快速配置 | Agents / Bindings | 创建/配置新的 Agent 实例 |
### ZClaw 自定义 RPC 方法
```typescript
// plugins/zclaw-ui 注册的方法
client.listClones() // zclaw.clones.list
client.createClone(opts) // zclaw.clones.create
client.updateClone(id, opts) // zclaw.clones.update
client.deleteClone(id) // zclaw.clones.delete
client.getUsageStats() // zclaw.stats.usage
client.getSessionStats() // zclaw.stats.sessions
client.getWorkspaceInfo() // zclaw.workspace.info
client.getPluginStatus() // zclaw.plugins.status
client.getQuickConfig() // zclaw.config.quick
client.listSkills() // zclaw.skills.list
```
### 分身 (Clone) = Agent 实例
```typescript
interface CloneConfig {
id: string;
name: string;
role?: string;
nickname?: string;
scenarios?: string[];
model?: string;
workspaceDir?: string;
workspaceResolvedPath?: string;
restrictFiles?: boolean;
privacyOptIn?: boolean;
userName?: string;
userRole?: string;
bootstrapReady?: boolean;
bootstrapFiles?: Array<{ name: string; path: string; exists: boolean }>;
}
```
### 判断标准
> 如果一个页面改动之后,没有改变 OpenClaw Runtime 的真实行为、真实配置、真实路由、真实工作区或真实 Agent 上下文,那它大概率还只是"演示 UI",不是系统能力。
---
## ZCLAW 桌面 Gateway 握手排障案例2026-03
### 症状演进
1. 初始表现为桌面端长时间停留在“握手中...”
2. 修正握手客户端身份后,错误表象变成 `WebSocket connection failed`
3. 修复候选地址 fallback 的错误覆盖后,暴露出真实错误 `origin not allowed`
4. 自动补齐 `gateway.controlUi.allowedOrigins` 后,错误继续推进为 `pairing required`
### 已确认的排查结论
- `gateway.auth.token` 已正确从 `openclaw.json` 读取并注入桌面端连接
- Tauri 调试版实际运行的是 `target/debug/resources/openclaw-runtime`
- Gateway WebSocket 握手客户端身份需满足当前 schema
- `client.id=cli`
- `client.mode=cli`
- `role=operator`
- 浏览器 / WebView 环境与 Node 探针的关键差异是会附带 `Origin`
- Tauri WebView 需要被加入:
- `gateway.controlUi.allowedOrigins`
- `http://tauri.localhost`
- `tauri://localhost`
-`origin not allowed` 被解决后Gateway 会继续要求对当前设备完成 pairing
### 有效的排障方法
#### 1. 先分离“网络失败”和“协议失败”
如果 UI 只显示 `WebSocket connection failed`,先检查连接代码是否在多个候选地址之间 fallback并把更早的握手错误覆盖掉。
ZCLAW 的处理方式是:
- 仅对以下错误继续尝试下一个候选地址:
- `WebSocket connection failed`
- `Gateway handshake timed out`
- `WebSocket closed before handshake completed`
- 对握手 / 鉴权 / schema 错误立即停止 fallback原样暴露给 UI
#### 2. 用独立协议探针验证 Gateway 真正接受的握手参数
在本案例中Node 探针证明了:
- `cli/cli/operator` 是可接受的客户端身份
- 设备 `deviceId` 必须和 `publicKey` 的派生规则一致
- 仅靠终端探针成功并不能证明 Tauri WebView 一定能连通,因为 WebView 会额外带 `Origin`
#### 3. 优先检查本地 Gateway 的 pending / paired devices
可用命令:
```powershell
openclaw devices list --json
```
本案例中,`pairing required` 发生时,`devices list` 已能看到当前桌面端的 pending 请求,说明:
- 连接已到达 Gateway
- 当前缺的是“批准这台设备”,不是 token 或网络
### ZCLAW 当前修复策略
#### A. 连接前自动准备本地 Gateway
桌面端在 Tauri 运行时连接前,先调用本地准备逻辑:
- 确保 `gateway.controlUi.allowedOrigins` 包含:
- `http://tauri.localhost`
- `tauri://localhost`
- 如果配置被修改且 Gateway 正在运行,自动重启 Gateway 使配置生效
#### B. 握手遇到 `pairing required` 时自动批准本机桌面设备
当前策略只在**本地 loopback Gateway** 下启用:
- 仅匹配 `ws://127.0.0.1:*``ws://localhost:*`
- 前端读取当前桌面端持久化的 `deviceId/publicKey`
- Tauri 侧调用:
```powershell
openclaw devices list --json
openclaw devices approve <requestId> --json --token <token> --url <url>
```
- 只批准同时匹配以下条件的 pending request
- `deviceId`
- `publicKey`
- 批准成功后立即重试连接
### 后续遇到同类问题时的最短排障顺序
1. 确认当前运行的是目标 `desktop.exe`
2. 确认 `openclaw.json` 中有 `gateway.auth.token`
3. 确认 WebView localStorage 已持久化 `zclaw_gateway_url` / `zclaw_gateway_token`
4. 把握手错误原样暴露,不要让 fallback 覆盖
5. 若报 `origin not allowed`
- 检查 `gateway.controlUi.allowedOrigins`
6. 若报 `pairing required`
- 检查 `openclaw devices list --json`
- 看当前桌面设备是否进入 `pending`
7. 如果 pending 存在,优先做“只批准本机当前设备”的自动化,而不是直接放宽所有设备
---
## ZCLAW 桌面聊天 / 模型配置协议错配案例2026-03
### 症状
- 桌面端显示 Gateway 已连接,但发送消息立即失败
- 常见错误文案为:
- `invalid agent params: must have required property 'idempotencyKey'`
- `invalid agent params: must NOT have additional properties: model`
- 模型与 API 页面可以切换本地显示值,但不会改变 Gateway 的真实默认模型
### 根因
- ZCLAW 桌面端此前仍按旧协议调用 `agent`
- 发送了顶层 `model`
- 没有发送必填 `idempotencyKey`
- 当前 OpenClaw runtime 的 `agent` schema 已变更为:
- `message` 必填
- `idempotencyKey` 必填
- `model` 不是允许的顶层字段
- 桌面端“模型切换”之前只是本地 Zustand 状态,没有写回 Gateway 配置,因此不会影响真实运行时行为
### 有效排查方法
1. 不要只看仓库里的旧 client 封装,要直接核对当前实际 runtime 的 schema
2. 如果仓库源码里搜不到新字段(如 `idempotencyKey`),优先检查打包后的 `openclaw-runtime`
3. 在本案例中,真实约束来自 runtime 中的 `AgentParamsSchema`
- `message: NonEmptyString`
- `idempotencyKey: NonEmptyString`
- `agentId/sessionKey/...` 可选
- `additionalProperties: false`
4. 对模型配置,不要只改前端本地状态;应优先确认 runtime 是否已暴露:
- `models.list`
- `config.get`
- `config.apply`
### ZCLAW 当前修复策略
- `desktop/src/lib/gateway-client.ts`
- `chat()` 改为发送 `idempotencyKey`
- 停止发送非法顶层 `model`
- 新增 `models.list` / `config.get` / `config.apply` 客户端接口
- `desktop/src/store/chatStore.ts`
- 发送消息时不再把本地 `clone_*` 直接当作 runtime `agentId`
- 继续保留前端会话与分身关联信息,避免 UI 上下文丢失
- `desktop/src/components/Settings/ModelsAPI.tsx`
- 改为基于真实 Gateway 配置读写默认模型与中文模型插件 Provider 配置
- `desktop/src/components/ChatArea.tsx`
- 聊天输入区模型下拉改为通过 `config.apply` 更新 Gateway 默认模型,而不是只切本地显示
### 当前结论
- 如果错误同时出现 `missing idempotencyKey``unexpected property model`,优先判断为“桌面端协议版本落后于当前 runtime”
- 如果模型切换只改变 UI 文案、不会改变新会话的实际模型,说明它仍是“演示态”,应改为落到 `config.get/config.apply`
---
## 参考资料
### 官方文档
- [OpenClaw 官方文档](https://docs.openclaw.ai/)
- [Gateway 配置参考](https://docs.openclaw.ai/gateway/configuration)
- [Multi-Agent 路由](https://docs.openclaw.ai/concepts/multi-agent)
- [Skills 文档](https://docs.openclaw.ai/tools/skills)
- [Heartbeat 文档](https://docs.openclaw.ai/gateway/heartbeat)
### 社区资源
- [OpenClaw 中文指南](https://yeasy.gitbook.io/openclaw_guide/)
- [awesome-openclaw-skills](https://github.com/VoltAgent/awesome-openclaw-skills)
- [OpenClaw 源码解析](https://www.ququ123.top/2026/03/openclaw-gateway-startup/)
### ZClaw 内部参考
- `docs/openclaw-deep-dive.md` - 深度分析
- `config/openclaw.default.json` - 默认配置
- `plugins/zclaw-ui/index.ts` - 插件实现
- `desktop/src/lib/gateway-client.ts` - 客户端实现