Files
zclaw_openfang/wiki/chat.md
iven ed77095a37
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
docs(wiki): 系统性更新 — L0速览+L1模块标准化+L2功能链路映射(33条)
三层架构增强:
- L0 index.md: 用户功能清单+跨模块数据流全景图+导航树增强 (92→143行)
- L1 8个模块页标准化: 功能清单/API接口/测试链路/已知问题
  routing(252→326) chat(101→157) saas(153→230) memory(182→333)
  butler(137→179) middleware(121→159) hands-skills(218→257) pipeline(111→156)
- L1 新增2页: security.md(157行) data-model.md(180行)
- L2 feature-map.md: 33条端到端功能链路映射(408行)

维护机制: CLAUDE.md §8.3 wiki触发规则 5→9条
设计文档: docs/superpowers/specs/2026-04-21-wiki-systematic-overhaul-design.md
2026-04-21 23:48:19 +08:00

6.2 KiB
Raw Blame History

title, updated, status, tags
title updated status tags
聊天系统 2026-04-21 active
module
chat
stream

聊天系统

index 导航。关联模块: routing saas butler

设计思想

核心问题: 3 种运行环境需要 3 种 ChatStream 实现。

环境 实现 传输 为什么
桌面端 (Tauri) KernelClient Tauri Event 内置 Kernel但 baseUrl 可指向 SaaS relay
桌面端 (Tauri + SaaS) KernelClient + relay Tauri Event → SaaS 主路径: Token Pool 中转
浏览器端 SaaSRelayGatewayClient HTTP SSE 无 Tauri 运行时
外部 Gateway GatewayClient WebSocket 独立进程部署

统一接口: 3 种实现共享同一套回调:

{ onDelta, onThinkingDelta, onTool, onHand, onComplete, onError }

功能清单

功能 描述 入口文件 状态
发送消息 流式/非流式,支持 thinking streamStore.ts
流式响应 SSE/Tauri Event 实时推送 streamStore.ts
模型切换 运行时切换 LLM 模型 conversationStore.ts
上下文管理 会话持久化 + 跨会话恢复 conversationStore.ts
取消流式 原子标志位中断 kernel-chat.ts
Agent 聊天 指定 agent_id 独立对话 streamStore.ts
课堂聊天 教育场景专用 classroomStore.ts
消息持久化 IndexedDB 存储 messageStore.ts
聊天产物 附件/代码块管理 artifactStore.ts

代码逻辑

发送消息流

入口: streamStore.sendMessage(content)store/chat/streamStore.ts

sendMessage(content)
  → effectiveSessionKey = conversationStore.sessionKey || uuid()
  → effectiveAgentId = resolveGatewayAgentId(currentAgent)
  → client.chatStream(content, callbacks, { sessionKey, agentId, chatMode })
    → KernelClient: Tauri invoke('kernel_chat', ...)
      → Kernel → loop_runner → LLM Driver
        → 如果 baseUrl 指向 SaaS relay → 请求发往 Token Pool → LLM
        → 如果 baseUrl 指向 LLM 直连 → 请求直接发往 LLM
      → Tauri Event emit('chat-response-delta', ...)
        → onDelta(text) → streamStore 追加 delta
        → onTool(tool) → toolStore 更新
        → onHand(hand) → handStore 更新
        → onComplete() → conversationStore 持久化
    → SaaSRelay: HTTP POST /api/v1/relay/chat/completions → SSE
    → GatewayClient: WebSocket send → onmessage
  → 5 分钟超时守护 (kernel-chat.ts:76) 防止流挂起

Store 拆分 (5 Store)

原来 908 行的 ChatStore 已拆分为:

Store 文件 职责
streamStore store/chat/streamStore.ts 流式消息编排、发送、取消
conversationStore store/chat/conversationStore.ts 会话管理、当前模型
messageStore store/chat/messageStore.ts 消息持久化
chatStore store/chat/chatStore.ts 聊天通用状态
artifactStore store/chat/artifactStore.ts 聊天产物/附件

前端 Tauri 命令映射

kernel_chat / agent_chat / agent_chat_stream  → 发送消息
cancel_stream                                  → 取消流式响应

模型切换

UI 选择模型 → conversationStore.currentModel = newModel
  → 下次 sendMessage 时connectionStore 读取 currentModel
  → SaaS 模式: relay 白名单验证 → 可用则切换
  → 本地模式: 直接使用用户配置的模型

API 接口

Tauri 命令

聊天核心 (desktop/src-tauri/src/kernel_commands/chat.rs):

命令 参数 返回值 说明
agent_chat ChatRequest { agent_id, message, thinking_enabled?, model? } ChatResponse 非流式聊天
agent_chat_stream StreamChatRequest { +session_id } Tauri Event 流 流式聊天(主路径)
cancel_stream session_id () 取消当前流式

课堂聊天 (desktop/src-tauri/src/classroom_commands/chat.rs):

命令 参数 返回值 说明
classroom_chat { classroom_id, user_message, scene_context? } Vec<ClassroomChatMessage> 课堂对话
classroom_chat_history classroom_id Vec<ClassroomChatMessage> 历史消息

流式事件类型 (agent_chat_stream emit): Delta / ThinkingDelta / ToolStart / ToolEnd / HandStart / HandEnd / SubtaskStatus / IterationStart / Complete / Error

SaaS Relay 路由

方法 路径 说明
POST /api/v1/relay/chat/completions OpenAI 兼容格式,支持 session_key/agent_id 透传

测试链路

功能 测试文件 测试数 覆盖状态
ChatStore 完整流程 tests/desktop/chatStore.test.ts 11 sendMessage/sessionKey/agent隔离/stream相关
类型契约测试 tests/seam/chat-seam.test.ts 8 StreamChatRequest/ChatResponse camelCase/Event tagged union

关联模块

  • routing — 路由决定使用哪种 client
  • saas — Token Pool 提供模型和 API Key
  • butler — ButlerRouter 中间件增强 system prompt
  • middleware — 消息经过 15 层 runtime 中间件处理
  • memory — 对话内容可能触发记忆提取

关键文件

文件 职责
desktop/src/store/chat/streamStore.ts 流式消息编排
desktop/src/store/chat/conversationStore.ts 会话管理
desktop/src/store/chat/artifactStore.ts 聊天产物管理
desktop/src/lib/kernel-chat.ts Kernel ChatStream (Tauri)
desktop/src/lib/saas-relay-client.ts SaaS Relay ChatStream
desktop/src/lib/gateway-client.ts Gateway ChatStream (WS)
desktop/src/components/ChatArea.tsx 聊天区域 UI
crates/zclaw-runtime/src/loop_runner.rs Rust 主聊天循环

已知问题

  • ⚠️ B-CHAT-07: 混合域截断 — P2 Open。跨域消息时可能截断上下文
  • SSE Token 统计为 0 — P2 已修复 (SseUsageCapture stream_done flag)
  • Tauri invoke 参数名 snake_case — P1 已修复 (commit f6c5dd2)
  • Provider Key 解密致 relay 500 — P1 已修复 (commit b69dc61)