新增: 消息级溯源 P0 地基(ChatMessage.id + ai_messages 拆表 + 迁移 + Repo)

依据消息拆分存储设计 + 消息级溯源设计 P0(地基,P1 溯源/P2 切读待后续):
- df-ai-core ChatMessage 加 id 字段(Option<String> serde 向前兼容)+ new_message_id(AtomicU64+ts 并发安全)
- 6 构造器生成 id,老 JSON 无 id → None 兼容
- df-storage V21 一次原子迁移:建 ai_messages 表 + ai_tool_executions.message_id 列 + 全量数据迁移(分批+坏数据容错+COUNT 幂等)
- AiMessageRecord + AiMessageRepo(insert_batch/list_by_conversation/delete_range/update_status/update_content_by_tool_call_id)
- audit message_id 列补建(conversation_repo/settings 白名单)
- src-tauri title.rs/finalize.rs 字面量占位(P1 接真值)

自验: df-storage 45 passed + df-ai-core 28 passed + workspace EXIT 0
This commit is contained in:
2026-06-19 19:24:02 +08:00
parent 44d1c6a00c
commit e981c1492a
10 changed files with 953 additions and 16 deletions

View File

@@ -204,6 +204,11 @@ pub struct AiConversationRecord {
pub struct AiToolExecutionRecord {
pub id: String,
pub conversation_id: Option<String>,
/// 消息级溯源:工具调用所属的 ChatMessage.id(F-260619-04)。
/// NULL = 老库行 / 消息级溯源未启用期的记录 / 无法关联的调用。
/// 升级后,audit 写入从 ContextManager 取当前 assistant 消息 id 填入(P1 接入,P0 只建列)。
#[serde(default, skip_serializing_if = "Option::is_none")]
pub message_id: Option<String>,
pub tool_call_id: String,
pub tool_name: String,
pub arguments: String,
@@ -215,6 +220,42 @@ pub struct AiToolExecutionRecord {
pub decided_by: Option<String>, // human/auto
}
/// 消息记录(ai_messages 表,F-260619-03 消息拆分存储)。
///
/// 每条 ChatMessage 一行,替代 `ai_conversations.messages` 的整对话 JSON 列存。
/// 主键 `id` = ChatMessage.id(构造时 ULID 风格生成),(conversation_id, seq) UNIQUE
/// 保证对话内序号唯一。本结构仅承载持久化映射,P0 阶段 ContextManager 仍走旧 JSON 列,
/// 切读策略待用户决策(P2)。
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AiMessageRecord {
/// 消息全局唯一 ID(= ChatMessage.id),主键
pub id: String,
/// 关联对话 ID
pub conversation_id: String,
/// 对话内序号(排序用,从 0 起)
pub seq: i64,
/// 消息角色:system/user/assistant/tool
pub role: String,
/// 文本内容(parts 的 Text 片与 content 一致)
pub content: String,
/// 多模态 parts JSON(可空)
pub parts: Option<String>,
/// 工具调用 ID(role=Tool 时必填)
pub tool_call_id: Option<String>,
/// AI 发起的工具调用 JSON(可空)
pub tool_calls: Option<String>,
/// 生成该消息的 model(仅 assistant)
pub model: Option<String>,
/// 消息状态:active/compressed/archived_segment/truncated(默认 active)
pub status: String,
/// DeepSeek thinking 推理内容(可空)
pub reasoning_content: Option<String>,
/// 消息创建时间(Unix 毫秒,可空)
pub timestamp: Option<i64>,
/// 落库时间字符串(迁移期 fallback 到对话 created_at)
pub created_at: String,
}
// ============================================================
// 知识库模型 (V7)
// ============================================================