重构: F-09 batch4 启用多会话上线(决策e真并发·F-09完整)

- IPC签名加conv_id: ai_is_generating/ai_chat_send/ai_chat_force_send/ai_chat_stop + 内部移除active一致性校验(后台conv可操作)
- 删switch readonly分支 + 删ai_conversation_create强制结束旧loop(决策e,切走旧loop不退出)
- 删双写桥接+顶层字段: messages/generating/stop_flag/notify/iteration_used/agent_language/model_override/session_trust全删,per_conv唯一真相源 + 删双写代码(全模块)+ 删fallback读 + pending_approvals retain目标conv
- 前端: api/ai.ts+useAiSend/useAiWindow传conv_id
保留: session_state(SW预留标allow)/readonly(前端不读);零调用方预留按用户指导保留
主代兜底: cargo check --workspace 0 + vue-tsc 0 + test 98 + grep顶层删除/per_conv唯一印证
F-09完整(batch1 PerConvState+batch2迁移+batch5限流调整+batch8恢复+batch4上线);双会话人工验收留用户
This commit is contained in:
2026-06-19 03:03:48 +08:00
parent 2b40f65ef2
commit d899c58682
10 changed files with 345 additions and 522 deletions

View File

@@ -145,16 +145,13 @@ pub(crate) async fn save_conversation(
// list_directory 13782 项)落库后每轮重发累积致 token 暴增。仅影响持久化视图,不污染
// 内存真相源(ContextManager)——build_for_request 仍读全量 messages。
//
// F-260616-09 B 批2:读 per_conv.messages(conv_id 来源:本函数入参,与 save 落库的 conv 一致)。
// F-260616-09 B 批4:per_conv.messages 唯一真相源(conv_id 来源:本函数入参,与 save 落库的 conv 一致)。
// loop 内 save 由 run_agentic_loop 入参 conv_id 透传;IPC 路径(commands.rs)save 也传 conv_id。
// per_conv 未建时 fallback 顶层 messages(兼容批2 桥接未覆盖的边缘路径,如 ai_chat_clear 后
// 无 per_conv 但顶层有,虽然 clear 已清空,fallback 顶层也是空,行为一致)。
// conv() 惰性建:save 路径 conv 必然已建(send/regenerate/edit/switch 均先 conv());若极端
// 未建(如启动恢复无 live conv),conv() 建空 PerConvState,save 空 messages(幂等不污染)。
let (messages_json, provider_id, created_at) = {
let session = session_arc.lock().await;
let mut msgs = match session.conv_read(conv_id) {
Some(c) => c.messages.all_messages_clone(),
None => session.messages.all_messages_clone(),
};
let mut session = session_arc.lock().await;
let mut msgs = session.conv(conv_id).messages.all_messages_clone();
for m in &mut msgs {
m.content = truncate_for_persist(&m.content);
// F-260614-05 Phase 2a: parts(Image base64) 同样截断(替换占位 Text 片),