Skip to content

[feat] 统一 Block 模型 - 会话持久化重构 #71

@hrygo

Description

@hrygo

[feat] 统一 Block 模型 - 会话持久化重构

问题描述

当前 DivineSense 的普通模式和 CC 连接模式(极客/进化)存在根本不同的会话数据结构:

维度 普通模式 CC 模式
会话存储 ai_message 表(累加式) agent_session_stats 表(摘要式)
消息结构 ConversationMessage(role + content) StreamMessage(type + content + metadata)
持久化时机 每条消息独立保存 会话结束统一保存
历史恢复 数据库完整历史 CC CLI 会话文件
前端展示 配对成 UnifiedMessageBlock 流式事件渲染到 Block

这导致:

  1. Warp Block UI(Issue [feature-web] Warp Block 风格统一聊天界面 #69 已完成)的内容无法完整持久化
  2. 三种模式的 Block 渲染风格未独立(会随页面全局 mode 变化)
  3. 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 类型
  • Conversationmessages 改为 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 只存储映射

复杂度


验收标准

  • make check-all 通过
  • 数据库迁移脚本执行成功
  • 后端 BlockStore 接口实现完成
  • 前端三种模式主题色更新完成
  • UnifiedMessageBlock 根据 Block.mode 渲染
  • 支持用户输入追加(CC 模式)
  • 更新 docs/dev-guides/FRONTEND.md

相关资源


调研时间: 2026-02-04
调研版本: v1.0
Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestrefactorCode refactoring

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions