Major changes: - Shift from "OpenFang desktop client" to "independent AI Agent desktop app" - Add decision principle: "Is this useful for ZCLAW? Does it affect ZCLAW?" - Simplify project structure and tech stack sections - Replace OpenClaw vs OpenFang comparison with unified backend approach - Consolidate troubleshooting from scattered sections into organized FAQ - Update Hands system documentation with 8 capabilities and status - Stream
5.6 KiB
5.6 KiB
OpenFang WebSocket 协议实际实现
重要: OpenFang 实际的 WebSocket 协议与官方文档有差异。本文档记录实际测试验证的协议格式。
测试日期: 2026-03-14 OpenFang 版本: 0.4.0 测试环境: Windows 11, Node.js v24
1. WebSocket 连接
端点 URL
ws://127.0.0.1:50051/api/agents/{agentId}/ws
- 端口: 50051 (非文档中的 4200)
- agentId: 必须是真实的 Agent UUID,不能使用 "default"
获取 Agent ID
curl http://127.0.0.1:50051/api/agents
返回示例:
[
{
"id": "f77004c8-418f-4132-b7d4-7ecb9d66f44c",
"name": "General Assistant",
"model_provider": "zhipu",
"model_name": "glm-4-flash",
"state": "Running"
}
]
2. 消息格式
发送消息 (实际格式)
{
"type": "message",
"content": "Hello, how are you?",
"session_id": "session_123"
}
文档中的格式 (错误)
// ❌ 这是错误的格式,不要使用
{
"type": "chat",
"message": {
"role": "user",
"content": "Hello"
}
}
3. 事件类型
连接事件
| 事件类型 | 说明 | 数据格式 |
|---|---|---|
connected |
连接成功 | {"agent_id": "uuid", "type": "connected"} |
agents_updated |
Agent 列表更新 | {"agents": [...], "type": "agents_updated"} |
聊天事件
| 事件类型 | 说明 | 数据格式 |
|---|---|---|
typing |
输入状态 | {"state": "start" 或 "stop", "type": "typing"} |
phase |
阶段变化 | {"phase": "streaming" 或 "done", "type": "phase"} |
text_delta |
文本增量 | {"content": "文本内容", "type": "text_delta"} |
response |
完整响应 | {"content": "...", "input_tokens": 100, "output_tokens": 50, "type": "response"} |
error |
错误 | {"content": "错误信息", "type": "error"} |
文档中的事件 (错误)
| 文档事件 | 实际事件 |
|---|---|
stream.delta.content |
text_delta.content |
stream.phase |
phase |
4. 事件序列
完整的聊天事件序列:
1. connected - 连接成功
2. typing (start) - 开始输入
3. agents_updated - Agent 状态更新
4. phase (streaming)- 流式输出开始
5. text_delta - 文本增量 (可能多次)
6. phase (done) - 流式输出完成
7. typing (stop) - 输入结束
8. response - 完整响应 (含 token 统计)
5. 代码示例
Node.js WebSocket 客户端
const WebSocket = require('ws');
const agentId = 'f77004c8-418f-4132-b7d4-7ecb9d66f44c';
const ws = new WebSocket(`ws://127.0.0.1:50051/api/agents/${agentId}/ws`);
let fullContent = '';
ws.on('open', () => {
// 发送消息 - 使用正确的格式
ws.send(JSON.stringify({
type: 'message',
content: 'Hello!',
session_id: 'test_session'
}));
});
ws.on('message', (data) => {
const event = JSON.parse(data.toString());
switch (event.type) {
case 'text_delta':
// 累积文本内容
fullContent += event.content || '';
break;
case 'response':
console.log('Complete:', fullContent);
console.log('Tokens:', event.input_tokens, event.output_tokens);
break;
case 'error':
console.error('Error:', event.content);
break;
}
});
React + Zustand 集成
// chatStore.ts
sendMessage: async (content: string) => {
const client = getGatewayClient();
if (client.getState() === 'connected') {
await client.chatStream(content, {
onDelta: (delta: string) => {
// 更新消息内容
set((state) => ({
messages: state.messages.map((m) =>
m.id === assistantId
? { ...m, content: m.content + delta }
: m
),
}));
},
onComplete: () => {
set({ isStreaming: false });
},
onError: (error: string) => {
// 处理错误
},
});
}
}
6. Vite 代理配置
必须启用 WebSocket 代理:
// vite.config.ts
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:50051',
changeOrigin: true,
secure: false,
ws: true, // ✅ 必须启用
},
},
},
});
7. 常见错误
错误: "Unexpected server response: 400"
原因: Agent ID 无效或格式错误
解决: 使用真实的 Agent UUID,不要使用 "default"
错误: "Missing API key: No LLM provider configured"
原因: Agent 使用的 LLM 提供商未配置 API Key
解决:
- 检查
~/.openfang/.env文件 - 确保对应提供商的 API Key 已设置
- 或使用已配置的 Agent (如 General Assistant - zhipu)
错误: WebSocket 连接成功但无响应
原因: 消息格式错误
解决: 确保使用 { type: 'message', content, session_id } 格式
8. REST API 端点
健康检查
GET /api/health
# {"status":"ok","version":"0.4.0"}
Agent 列表
GET /api/agents
# 返回所有 Agent 数组
Hands 列表
GET /api/hands
# 返回所有 Hands 数组
REST 聊天 (非流式)
POST /api/agents/{agentId}/message
Content-Type: application/json
{"message": "Hello"}
9. 相关文件
| 文件 | 说明 |
|---|---|
desktop/src/lib/gateway-client.ts |
WebSocket 客户端实现 |
desktop/src/store/chatStore.ts |
聊天状态管理 |
desktop/vite.config.ts |
Vite 代理配置 |
更新历史
| 日期 | 变更 |
|---|---|
| 2026-03-14 | 初始版本,记录协议差异和实际实现 |