[feat] 统一 Block 模型 - 会话持久化重构
问题描述
当前 DivineSense 的普通模式和 CC 连接模式(极客/进化)存在根本不同的会话数据结构:
维度
普通模式
CC 模式
会话存储
ai_message 表(累加式)
agent_session_stats 表(摘要式)
消息结构
ConversationMessage(role + content)
StreamMessage(type + content + metadata)
持久化时机
每条消息独立保存
会话结束统一保存
历史恢复
数据库完整历史
CC CLI 会话文件
前端展示
配对成 UnifiedMessageBlock
流式事件渲染到 Block
这导致:
Warp Block UI(Issue [feature-web] Warp Block 风格统一聊天界面 #69 已完成)的内容无法完整持久化
三种模式的 Block 渲染风格未独立(会随页面全局 mode 变化)
CC 模式的增量输入特性无法支持(Issue [feat] 会话嵌套模型 - 母会话与子会话(Geek/Evolution)的统一架构 #57 的追加式输入)
解决方案
核心理念
将 Block 作为"对话回合"(Conversation Turn)的一等公民持久化单元 ,而不是当前的"消息"(Message)单元。
功能范围
包含 :
新增 ai_block 表作为核心持久化单元
Block 包含 mode 字段(创建时确定,决定渲染风格)
支持用户输入追加(CC 模式特有)
更新三种模式的主题色(琥珀/石板蓝/翠绿)
前端组件适配 UnifiedMessageBlock
不包含 (未来迭代):
Block 导出/分享功能
Block 级别的搜索/导航
Block 之间的引用关系
技术方案
后端
数据库迁移 :
创建 ai_block 表
字段:conversation_id, round_number, mode, user_inputs, event_stream, session_stats, cc_session_id, status
约束:同一会话内的 round_number 唯一
Proto 定义 :
新增 Block 消息类型
新增 CreateBlock, AppendToBlock, UpdateBlockEventStream, CompleteBlock, ListBlocks RPC
Store 接口 :
BlockStore 接口定义
PostgreSQL 实现
Chat Handler 改造 :
判断逻辑:status !== 'completed' 可追加,否则创建新 Block
CC 模式:追加输入直接发送到 CC CLI
前端
类型定义 (web/src/types/aichat.ts):
新增 ConversationBlock, UserInput, StreamEvent 类型
Conversation 的 messages 改为 blocks
主题色更新 (web/src/types/parrot.ts):
Normal :琥珀色 (amber) - 寓意:闪念如琥珀般珍贵保存
Geek :石板蓝 (sky + slate) - 寓意:代码如石板般精确
Evolution :翠绿色 (emerald) - 寓意:系统如植物般向上生长
组件适配 :
UnifiedMessageBlock:从 Block 读取 mode 决定渲染风格
ChatMessages:每个 Block 使用自己的 mode,而非页面全局 mode
支持 user_inputs 数组展示多条用户输入
关键设计决策
1. Block 状态机
pending → streaming → completed
↑
[用户追加输入]
2. 用户输入判断
if ( latestBlock . status !== 'completed' ) {
appendToBlock ( ) ; // 追加到当前 Block
} else {
createNewBlock ( ) ; // 创建新 Block
}
3. Block Mode 独立性
Block 的 mode 在创建时确定,存储在数据库
前端渲染时从 Block 读取 mode,而非页面的全局 currentMode
页面 currentMode 只影响:输入框显示 + 新 Block 的默认 mode
4. CC 会话映射
同一 conversation 的所有 geek/evolution Block 共享一个 cc_session_id
cc_session_id = UUID v5(conversation_id)
CC 会话文件由 CC CLI 管理,DS 只存储映射
复杂度
验收标准
相关资源
调研时间 : 2026-02-04
调研版本 : v1.0
Co-Authored-By : Claude Opus 4.5 noreply@anthropic.com
[feat] 统一 Block 模型 - 会话持久化重构
问题描述
当前 DivineSense 的普通模式和 CC 连接模式(极客/进化)存在根本不同的会话数据结构:
ai_message表(累加式)agent_session_stats表(摘要式)ConversationMessage(role + content)StreamMessage(type + content + metadata)UnifiedMessageBlock这导致:
解决方案
核心理念
将 Block 作为"对话回合"(Conversation Turn)的一等公民持久化单元,而不是当前的"消息"(Message)单元。
功能范围
包含:
ai_block表作为核心持久化单元mode字段(创建时确定,决定渲染风格)UnifiedMessageBlock不包含(未来迭代):
技术方案
后端
数据库迁移:
ai_block表conversation_id,round_number,mode,user_inputs,event_stream,session_stats,cc_session_id,statusround_number唯一Proto 定义:
Block消息类型CreateBlock,AppendToBlock,UpdateBlockEventStream,CompleteBlock,ListBlocksRPCStore 接口:
BlockStore接口定义Chat Handler 改造:
status !== 'completed'可追加,否则创建新 Block前端
类型定义 (
web/src/types/aichat.ts):ConversationBlock,UserInput,StreamEvent类型Conversation的messages改为blocks主题色更新 (
web/src/types/parrot.ts):amber) - 寓意:闪念如琥珀般珍贵保存sky+slate) - 寓意:代码如石板般精确emerald) - 寓意:系统如植物般向上生长组件适配:
UnifiedMessageBlock:从 Block 读取mode决定渲染风格ChatMessages:每个 Block 使用自己的 mode,而非页面全局 modeuser_inputs数组展示多条用户输入关键设计决策
1. Block 状态机
2. 用户输入判断
3. Block Mode 独立性
mode在创建时确定,存储在数据库mode,而非页面的全局currentModecurrentMode只影响:输入框显示 + 新 Block 的默认 mode4. CC 会话映射
cc_session_idcc_session_id= UUID v5(conversation_id)复杂度
验收标准
make check-all通过UnifiedMessageBlock根据 Block.mode 渲染docs/dev-guides/FRONTEND.md相关资源
docs/research/event-type-ui-research.mddocs/research/cc-runner-message-handling-research.md调研时间: 2026-02-04
调研版本: v1.0
Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com