重构: 巨函数拆分 + 清理历史标记注释 + custom_prompt/停止按钮/tunnel 改进
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
//!
|
||||
//! 触发条件:history_tokens > budget*0.6 且 保护区外有可压缩消息 且 未在压缩中。
|
||||
//!
|
||||
//! 流程(对齐阶段2 ai_chat_compress_context IPC 的 read-but-don't-mutate 模式):
|
||||
//! 流程(对齐 ai_chat_compress_context IPC 的 read-but-don't-mutate 模式):
|
||||
//! ① 读 active 克隆(不改 status / 不扣 token)→ 喂 LLM 出摘要;
|
||||
//! ② LLM 成功 → compress_old_messages(标 compressed + 扣 token)+ insert_at(摘要 system);
|
||||
//! ③ LLM 失败 → 消息状态完全不变(未改 status / 未扣 token),降级走原 build_for_request 裁剪。
|
||||
@@ -17,11 +17,11 @@
|
||||
//! 注:延迟 mutate 的窗口(active_msgs 读出→LLM 出摘要期间)不持锁,但 loop 串行无并发
|
||||
//! (本函数独占 session_arc,工具执行/审批分支在 stream 之后),故此窗口内 messages 不变。
|
||||
//!
|
||||
//! 安全(FR-S1):复用 loop 顶部已 build+验证 的 provider(不再 build_provider_for 重复 resolve
|
||||
//! 安全:复用 loop 顶部已 build+验证 的 provider(不再 build_provider_for 重复 resolve
|
||||
//! keyring),api_key 经 df_storage::secret 闭环;summary/error payload/日志均不含 api_key。
|
||||
//! is_compressing 防重入:set_compressing(true/false) 成对(LLM 调用前后均复位)。
|
||||
//! 单轮问答(history_tokens 未超 0.6*budget)不触发,零行为变化。
|
||||
//! F-260616-09 B 批2:messages 操作改 per_conv(设计 §4.2)。
|
||||
//! messages 操作改 per_conv。
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -51,7 +51,7 @@ const PROTECT_COUNT: usize = 6;
|
||||
/// 排障/对比用:置 false 即可观察无兜底时的裁剪效果。
|
||||
const KEYWORD_FALLBACK_ENABLED: bool = true;
|
||||
|
||||
/// F-15 阶段3: 自动压缩(智能裁剪)——在 build_for_request 之前预处理。
|
||||
/// 自动压缩(智能裁剪)——在 build_for_request 之前预处理。
|
||||
///
|
||||
/// 从 `run_agentic_loop` 抽取,行为零变更。返回值:
|
||||
/// - `true`:conv 已删除,调用方应立即 `return`(退出整个 loop)。
|
||||
@@ -100,7 +100,7 @@ pub(super) async fn maybe_auto_compress(
|
||||
conversation_id: Some(conv_id.to_string()),
|
||||
};
|
||||
let _ = app_handle.emit("ai-chat-event", ev.clone());
|
||||
// L3 emit 双写:tunnel subscriber(阶段2)透传 miniapp
|
||||
// L3 emit 双写:tunnel subscriber透传 miniapp
|
||||
let _ = app_handle.state::<AppState>().ai_event_bus.publish_event(ev);
|
||||
let (active_msgs, lang) = {
|
||||
let mut session = session_arc.lock().await;
|
||||
@@ -168,7 +168,7 @@ pub(super) async fn maybe_auto_compress(
|
||||
summary: summary.nl_summary,
|
||||
};
|
||||
let _ = app_handle.emit("ai-chat-event", ev.clone());
|
||||
// L3 emit 双写:tunnel subscriber(阶段2)透传 miniapp
|
||||
// L3 emit 双写:tunnel subscriber透传 miniapp
|
||||
let _ = app_handle.state::<AppState>().ai_event_bus.publish_event(ev);
|
||||
}
|
||||
Ok(None) => {
|
||||
@@ -216,7 +216,7 @@ pub(super) async fn maybe_auto_compress(
|
||||
);
|
||||
}
|
||||
}
|
||||
// BUG-260624-05:压缩失败不发 AiError——前端 AiError case 无条件 setStreaming(false)
|
||||
// 压缩失败不发 AiError——前端 AiError case 无条件 setStreaming(false)
|
||||
// 误判生成结束(后端 loop 实际继续),致"压缩后停止"。降级为 warn(上方 line 957 已有)
|
||||
// + compress_old_messages 兜底释放 token + build_for_request 裁剪,loop 继续 stream_llm,
|
||||
// 用户自然看到后续回复。压缩降级对用户透明(非致命错误,不该停流)。
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
//! - **读侧收敛**:停止按钮三态(可停 / 停中 / 停失败可重试)、MaxRoundsCard 是否弹等
|
||||
//! 判别逻辑由 `ConvState` 变体直接表达,不再靠多变量组合反推。
|
||||
//!
|
||||
//! # 收口后(批3+)
|
||||
//! # 当前架构
|
||||
//!
|
||||
//! 本模块是**纯逻辑、无 IO**的 enum + 转换守卫。批3 双轨收口后 `generating` bool
|
||||
//! 本模块是**纯逻辑、无 IO**的 enum + 转换守卫。`generating` bool
|
||||
//! 与 `CONV_STATE_ENABLED` 开关已退役,`ConvState` 成为唯一真相源:guard 接入点
|
||||
//! (`GeneratingGuard` new/reset/drop 时同步迁移 `ConvState`)无条件执行迁移 + emit。
|
||||
//!
|
||||
@@ -52,7 +52,7 @@ use serde::{Deserialize, Serialize};
|
||||
/// `ConvState` 是面向「生成生命周期」的写侧真相(写收敛)。两者正交:如 `Generating` 态
|
||||
/// 同时有审批挂起时,`ConvState=Generating` 而 `SessionState=AwaitingApproval`。
|
||||
///
|
||||
/// 序列化(`Serialize`/`Deserialize`):批3 前端经事件总线读 enum 视图时使用(本批未接,
|
||||
/// 序列化(`Serialize`/`Deserialize`):前端经事件总线读 enum 视图时使用(本批未接,
|
||||
/// 预留,避免后续改动序列化兼容性)。
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@@ -150,9 +150,7 @@ impl ConvState {
|
||||
/// 审批挂起(读视图 `SessionState::AwaitingApproval`)期间 `ConvState` 仍是 `Generating`,
|
||||
/// 故本方法返回 true——审批挂起不算「停止生成」。
|
||||
///
|
||||
/// 预留:批2+ 读侧迁移(try_continue / ai_chat_stop / 前端停止三态)消费。
|
||||
/// L2 读侧迁移(2026-06-22):已接入 ai_is_generating / ai_chat_stop / try_continue_agent_loop,
|
||||
/// 不再标 allow(dead_code)(有真实消费方)。
|
||||
/// 已接入 ai_is_generating / ai_chat_stop / try_continue_agent_loop,不再标 allow(dead_code)。
|
||||
pub fn is_active(self) -> bool {
|
||||
matches!(self, ConvState::Generating | ConvState::Compressed)
|
||||
}
|
||||
@@ -162,8 +160,8 @@ impl ConvState {
|
||||
/// 读侧便利方法:用于 `ai_conversation_create` / `ai_chat_send` 等入口判断
|
||||
/// 「能否接新请求」。`Error` 态视为可接(用户重试即从 Error 起步)。
|
||||
///
|
||||
/// 双轨收口批1(2026-06-25):chat 域入口拦截(ai_regenerate / ai_chat_send /
|
||||
/// ai_chat_edit)已接入,作真实读侧方法消费。删除 `allow(dead_code)` 标注。
|
||||
/// chat 域入口拦截(ai_regenerate / ai_chat_send /
|
||||
/// ai_chat_edit)已接入,作真实读侧方法消费。
|
||||
pub fn can_accept_request(self) -> bool {
|
||||
matches!(self, ConvState::Idle | ConvState::Error)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::commands::ai::knowledge_inject::inject_knowledge_into_prompt;
|
||||
use crate::commands::ai::{AiChatEvent, ErrorType, SessionState, GoalEntry};
|
||||
use super::conv_state::ConvState;
|
||||
|
||||
/// BUG-260617-05: try_continue_agent_loop 续跑判定所需 session 字段的一次性快照。
|
||||
/// try_continue_agent_loop 续跑判定所需 session 字段的一次性快照。
|
||||
struct ContinueSnapshot {
|
||||
is_generating: bool,
|
||||
has_pending: bool,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user