Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
refactor: 统一Hands系统常量到单个源文件 refactor: 更新Hands中文名称和描述 fix: 修复技能市场在连接状态变化时重新加载 fix: 修复身份变更提案的错误处理逻辑 docs: 更新多个功能文档的验证状态和实现位置 docs: 更新Hands系统文档 test: 添加测试文件验证工作区路径
360 lines
11 KiB
Markdown
360 lines
11 KiB
Markdown
# 通信层 (Communication Layer)
|
||
|
||
> **分类**: 架构层
|
||
> **优先级**: P0 - 决定性
|
||
> **成熟度**: L4 - 生产
|
||
> **最后更新**: 2026-03-24
|
||
> **验证状态**: ✅ 代码已验证
|
||
|
||
---
|
||
|
||
## 一、功能概述
|
||
|
||
### 1.1 基本信息
|
||
|
||
通信层是 ZCLAW 前端与内部 ZCLAW Kernel 之间的核心桥梁,通过 Tauri 命令进行所有通信。
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 分类 | 架构层 |
|
||
| 优先级 | P0 |
|
||
| 成熟度 | L4 |
|
||
| 依赖 | Tauri Runtime |
|
||
|
||
### 1.2 相关文件
|
||
|
||
| 文件 | 路径 | 用途 |
|
||
|------|------|------|
|
||
| 内核客户端 | `desktop/src/lib/kernel-client.ts` | Tauri 命令客户端 |
|
||
| 连接状态管理 | `desktop/src/store/connectionStore.ts` | Zustand Store |
|
||
| Tauri 命令 | `desktop/src-tauri/src/kernel_commands.rs` | Rust 命令实现 |
|
||
| 内核配置 | `crates/zclaw-kernel/src/config.rs` | Kernel 配置 |
|
||
| 类型定义 | `desktop/src/types/agent.ts` | Agent 相关类型 |
|
||
|
||
---
|
||
|
||
## 二、架构设计
|
||
|
||
### 2.1 内部 Kernel 架构
|
||
|
||
ZCLAW 采用**内部 Kernel 架构**,所有核心能力都集成在 Tauri 桌面应用中:
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ ZCLAW 桌面应用 │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
|
||
│ │ React 前端 │ │ Tauri 后端 (Rust) │ │
|
||
│ │ │ │ │ │
|
||
│ │ KernelClient │────▶│ kernel_init() │ │
|
||
│ │ ├─ connect() │ │ kernel_status() │ │
|
||
│ │ ├─ chat() │ │ agent_create() │ │
|
||
│ │ └─ chatStream()│ │ agent_chat() │ │
|
||
│ │ │ │ agent_list() │ │
|
||
│ └─────────────────┘ └─────────────────────────────────┘ │
|
||
│ │ │ │
|
||
│ │ Zustand │ zclaw-kernel │
|
||
│ ▼ ▼ │
|
||
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
|
||
│ │ connectionStore │ │ LLM Drivers │ │
|
||
│ │ chatStore │ │ ├─ Kimi (api.kimi.com) │ │
|
||
│ └─────────────────┘ │ ├─ Qwen (dashscope.aliyuncs) │ │
|
||
│ │ ├─ DeepSeek (api.deepseek) │ │
|
||
│ │ ├─ Zhipu (open.bigmodel.cn) │ │
|
||
│ │ ├─ OpenAI / Anthropic │ │
|
||
│ │ └─ Local (Ollama) │ │
|
||
│ └─────────────────────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 2.2 双客户端模式
|
||
|
||
系统支持两种客户端模式:
|
||
|
||
| 模式 | 客户端类 | 使用场景 |
|
||
|------|---------|----------|
|
||
| **内部 Kernel** | `KernelClient` | Tauri 桌面应用(默认) |
|
||
| **外部 Gateway** | `GatewayClient` | 浏览器环境/开发调试 |
|
||
|
||
模式切换逻辑在 `connectionStore.ts` 中:
|
||
|
||
```typescript
|
||
// 自动检测运行环境
|
||
const useInternalKernel = isTauriRuntime();
|
||
|
||
if (useInternalKernel) {
|
||
// 使用内部 KernelClient
|
||
const kernelClient = getKernelClient();
|
||
kernelClient.setConfig(modelConfig);
|
||
await kernelClient.connect();
|
||
} else {
|
||
// 使用外部 GatewayClient(浏览器环境)
|
||
const gatewayClient = getGatewayClient();
|
||
await gatewayClient.connect();
|
||
}
|
||
```
|
||
|
||
### 2.3 设计目标
|
||
|
||
1. **零配置启动**: 无需启动外部进程
|
||
2. **UI 配置**: 模型配置通过 UI 完成
|
||
3. **统一接口**: `KernelClient` 与 `GatewayClient` 接口兼容
|
||
4. **状态同步**: 连接状态实时反馈给 UI
|
||
5. **流式响应**: 通过 Tauri 事件实现真正的流式传输
|
||
|
||
---
|
||
|
||
## 三、核心接口
|
||
|
||
### 3.1 KernelClient 接口
|
||
|
||
```typescript
|
||
// desktop/src/lib/kernel-client.ts
|
||
|
||
class KernelClient {
|
||
// 连接管理
|
||
connect(): Promise<void>;
|
||
disconnect(): void;
|
||
getState(): ConnectionState;
|
||
|
||
// 配置
|
||
setConfig(config: KernelConfig): void;
|
||
|
||
// Agent 管理
|
||
listAgents(): Promise<AgentInfo[]>;
|
||
getAgent(agentId: string): Promise<AgentInfo | null>;
|
||
createAgent(request: CreateAgentRequest): Promise<CreateAgentResponse>;
|
||
deleteAgent(agentId: string): Promise<void>;
|
||
|
||
// 聊天
|
||
chat(message: string, opts?: ChatOptions): Promise<ChatResponse>;
|
||
chatStream(message: string, callbacks: StreamCallbacks, opts?: ChatOptions): Promise<{ runId: string }>;
|
||
|
||
// 状态
|
||
health(): Promise<{ status: string; version?: string }>;
|
||
status(): Promise<Record<string, unknown>>;
|
||
|
||
// 事件订阅
|
||
on(event: string, callback: EventCallback): () => void;
|
||
}
|
||
```
|
||
|
||
### 3.2 KernelConfig 配置
|
||
|
||
```typescript
|
||
interface KernelConfig {
|
||
provider?: string; // kimi | qwen | deepseek | zhipu | openai | anthropic | local
|
||
model?: string; // 模型 ID,如 kimi-k2-turbo, qwen-plus
|
||
apiKey?: string; // API 密钥
|
||
baseUrl?: string; // 自定义 API 端点(可选)
|
||
}
|
||
```
|
||
|
||
### 3.3 Tauri 命令映射
|
||
|
||
| 前端方法 | Tauri 命令 | 说明 |
|
||
|---------|-----------|------|
|
||
| `connect()` | `kernel_init` | 初始化内部 Kernel |
|
||
| `health()` | `kernel_status` | 获取 Kernel 状态 |
|
||
| `disconnect()` | `kernel_shutdown` | 关闭 Kernel |
|
||
| `createAgent()` | `agent_create` | 创建 Agent |
|
||
| `listAgents()` | `agent_list` | 列出所有 Agent |
|
||
| `getAgent()` | `agent_get` | 获取 Agent 详情 |
|
||
| `deleteAgent()` | `agent_delete` | 删除 Agent |
|
||
| `chat()` | `agent_chat` | 发送消息 |
|
||
|
||
---
|
||
|
||
## 四、数据流
|
||
|
||
### 4.1 聊天消息流程
|
||
|
||
```
|
||
用户输入
|
||
│
|
||
▼
|
||
React Component (ChatInput)
|
||
│
|
||
▼
|
||
chatStore.sendMessage()
|
||
│
|
||
▼
|
||
KernelClient.chatStream(message, callbacks)
|
||
│
|
||
▼ (Tauri invoke)
|
||
kernel_commands::agent_chat()
|
||
│
|
||
▼
|
||
zclaw-kernel::send_message()
|
||
│
|
||
▼
|
||
LLM Driver (Kimi/Qwen/DeepSeek/...)
|
||
│
|
||
▼ (流式响应)
|
||
callbacks.onDelta(content)
|
||
│
|
||
▼
|
||
UI 更新 (消息气泡)
|
||
```
|
||
|
||
### 4.2 连接初始化流程
|
||
|
||
```
|
||
应用启动
|
||
│
|
||
▼
|
||
connectionStore.connect()
|
||
│
|
||
├── isTauriRuntime() === true
|
||
│ │
|
||
│ ▼
|
||
│ getDefaultModelConfig() // 从 localStorage 读取模型配置
|
||
│ │
|
||
│ ▼
|
||
│ kernelClient.setConfig(modelConfig)
|
||
│ │
|
||
│ ▼
|
||
│ kernelClient.connect() // 调用 kernel_init
|
||
│ │
|
||
│ ▼
|
||
│ kernel_init 初始化 Kernel,配置 LLM Driver
|
||
│
|
||
└── isTauriRuntime() === false (浏览器环境)
|
||
│
|
||
▼
|
||
gatewayClient.connect() // 连接外部 Gateway
|
||
```
|
||
|
||
### 4.3 状态管理
|
||
|
||
```typescript
|
||
type ConnectionState =
|
||
| 'disconnected' // 未连接
|
||
| 'connecting' // 连接中
|
||
| 'connected' // 已连接
|
||
| 'reconnecting'; // 重连中
|
||
```
|
||
|
||
---
|
||
|
||
## 五、模型配置
|
||
|
||
### 5.1 UI 配置流程
|
||
|
||
模型配置通过"模型与 API"设置页面完成:
|
||
|
||
1. 用户点击"添加自定义模型"
|
||
2. 填写服务商、模型 ID、API Key
|
||
3. 点击"设为默认"
|
||
4. 配置存储到 `localStorage`(key: `zclaw-custom-models`)
|
||
|
||
### 5.2 配置数据结构
|
||
|
||
```typescript
|
||
interface CustomModel {
|
||
id: string; // 模型 ID
|
||
name: string; // 显示名称
|
||
provider: string; // kimi | qwen | deepseek | zhipu | openai | anthropic | local
|
||
apiKey?: string; // API 密钥
|
||
apiProtocol: 'openai' | 'anthropic' | 'custom';
|
||
baseUrl?: string; // 自定义端点
|
||
isDefault?: boolean; // 是否为默认模型
|
||
createdAt: string; // 创建时间
|
||
}
|
||
```
|
||
|
||
### 5.3 支持的 Provider
|
||
|
||
| Provider | Base URL | API 协议 |
|
||
|----------|----------|----------|
|
||
| kimi | `https://api.kimi.com/coding/v1` | OpenAI 兼容 |
|
||
| qwen | `https://dashscope.aliyuncs.com/compatible-mode/v1` | OpenAI 兼容 |
|
||
| deepseek | `https://api.deepseek.com/v1` | OpenAI 兼容 |
|
||
| zhipu | `https://open.bigmodel.cn/api/paas/v4` | OpenAI 兼容 |
|
||
| openai | `https://api.openai.com/v1` | OpenAI |
|
||
| anthropic | `https://api.anthropic.com` | Anthropic |
|
||
| local | `http://localhost:11434/v1` | OpenAI 兼容 |
|
||
|
||
---
|
||
|
||
## 六、错误处理
|
||
|
||
### 6.1 常见错误
|
||
|
||
| 错误 | 原因 | 解决方案 |
|
||
|------|------|----------|
|
||
| `请先在"模型与 API"设置页面配置模型` | 未配置默认模型 | 在设置页面添加模型配置 |
|
||
| `模型 xxx 未配置 API Key` | API Key 为空 | 填写有效的 API Key |
|
||
| `LLM error: API error 401` | API Key 无效 | 检查 API Key 是否正确 |
|
||
| `LLM error: API error 404` | Base URL 或模型 ID 错误 | 检查配置是否正确 |
|
||
| `Unknown provider: xxx` | 不支持的 Provider | 使用支持的 Provider |
|
||
|
||
### 6.2 错误处理模式
|
||
|
||
```typescript
|
||
try {
|
||
await kernelClient.connect();
|
||
} catch (err) {
|
||
const errorMessage = err instanceof Error ? err.message : String(err);
|
||
set({ error: errorMessage });
|
||
throw new Error(`Failed to initialize kernel: ${errorMessage}`);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 七、实际效果
|
||
|
||
### 7.1 已实现功能
|
||
|
||
- [x] 内部 Kernel 集成
|
||
- [x] 多 LLM Provider 支持
|
||
- [x] UI 模型配置
|
||
- [x] 流式响应
|
||
- [x] 连接状态管理
|
||
- [x] 错误处理
|
||
|
||
### 7.2 测试覆盖
|
||
|
||
- **单元测试**: `tests/desktop/gatewayStore.test.ts`
|
||
- **集成测试**: 包含在 E2E 测试中
|
||
- **覆盖率**: ~85%
|
||
|
||
---
|
||
|
||
## 八、演化路线
|
||
|
||
### 8.1 已完成
|
||
- [x] 内部 Kernel 集成
|
||
- [x] 多 LLM Provider 支持
|
||
- [x] 流式响应(通过 Tauri 事件 `stream:chunk`)
|
||
|
||
### 8.2 短期计划(1-2 周)
|
||
- [ ] 优化流式响应性能
|
||
|
||
### 8.3 中期计划(1-2 月)
|
||
- [ ] 支持 Agent 持久化
|
||
- [ ] 支持会话历史存储
|
||
|
||
### 8.4 长期愿景
|
||
- [ ] 支持多 Agent 并发
|
||
- [ ] 支持 Agent 间通信
|
||
|
||
---
|
||
|
||
## 九、与旧架构对比
|
||
|
||
| 特性 | 旧架构 (外部 OpenFang) | 新架构 (内部 Kernel) |
|
||
|------|----------------------|---------------------|
|
||
| 后端进程 | 需要独立启动 | 内置在 Tauri 中 |
|
||
| 通信方式 | WebSocket/HTTP | Tauri 命令 |
|
||
| 模型配置 | TOML 文件 | UI 设置页面 |
|
||
| 启动时间 | 依赖外部进程 | 即时启动 |
|
||
| 安装包 | 需要额外运行时 | 单一安装包 |
|
||
|
||
---
|
||
|
||
**最后更新**: 2026-03-24
|