重构: aichat 双轨状态机收口 + AiCompressed 事件拆分

- generating bool + CONV_STATE_ENABLED 开关双轨退役,ConvState enum 单一真相源
- can_accept_request 接入 chat 域入口(覆盖 Stopping 竞态,严谨于 is_active)
- AiCompressed 拆 AiManualCompressed/AiAutoCompressed(治自动压缩误触桌面toast+刷新)
- convStates/getConvState 下沉 aiShared.ts 破循环依赖
This commit is contained in:
lxy
2026-06-25 03:20:42 +08:00
parent fc705443bd
commit c011f864fd
22 changed files with 526 additions and 428 deletions
@@ -15,33 +15,17 @@
//! - **读侧收敛**:停止按钮三态(可停 / 停中 / 停失败可重试)、MaxRoundsCard 是否弹等
//! 判别逻辑由 `ConvState` 变体直接表达,不再靠多变量组合反推。
//!
//! # 渐进第一步(本批范围)
//! # 收口后(批3+)
//!
//! 本模块是**纯逻辑、无 IO**的 enum + 转换守卫,不替代 `PerConvState.generating`
//! 字段(渐进不一次全换)。guard 接入点(`GeneratingGuard` set/reset 时同步 `ConvState`
//! 转换)作为视图层;开关 [`CONV_STATE_ENABLED`](constant.CONV_STATE_ENABLED.html)
//! 默认 on,off 降级纯旧 bool 行为(可回退)。
//! 本模块是**纯逻辑、无 IO**的 enum + 转换守卫。批3 双轨收口后 `generating` bool
//! 与 `CONV_STATE_ENABLED` 开关已退役,`ConvState` 成为唯一真相源:guard 接入点
//! (`GeneratingGuard` new/reset/drop 时同步迁移 `ConvState`)无条件执行迁移 + emit。
//!
//! 后续(批2+):把散落判别点(`try_continue` / `ai_chat_stop` / MaxRoundsCard)逐个迁到
//! `ConvState`,并视情况把 `generating` bool 退役(状态字段由 enum 单一持有)
//! 散落判别点(`try_continue` / `ai_chat_stop` / MaxRoundsCard)逐个迁到
//! `ConvState`(`is_active()` / `can_accept_request()`),不再回退旧 bool
use serde::{Deserialize, Serialize};
// ============================================================
// 开关
// ============================================================
/// L2 状态机总开关(默认 on)。
///
/// - **on(默认)**:`GeneratingGuard` set/reset 时同步迁移 [`ConvState`](enum.ConvState.html)
/// 作视图层,前后端可读统一状态;guard 失败兜底仍走旧 bool 复位(`generating=false`),
/// 不影响语义(状态机层失败不阻断核心复位)。
/// - **off(降级)**:guard 不写 `ConvState`,纯旧 `generating` bool 行为(排障 / 对比 / 临时
/// 回退用)。设为 false 即可观察无状态机接入的效果,语义等价改动前。
///
/// 机制优先 prompt 说教:每改进配开关 + 兜底,分阶段可回退(对齐 AI 改进方案三原则)。
pub const CONV_STATE_ENABLED: bool = true;
// ============================================================
// ConvState enum
// ============================================================
@@ -169,8 +153,8 @@ impl ConvState {
/// 读侧便利方法:用于 `ai_conversation_create` / `ai_chat_send` 等入口判断
/// 「能否接新请求」。`Error` 态视为可接(用户重试即从 Error 起步)。
///
/// 预留:批2+ 读侧迁移(入口能否接新请求判断)消费。本批无消费方,标 `allow(dead_code)` 保留。
#[allow(dead_code)]
/// 双轨收口批1(2026-06-25):chat 域入口拦截(ai_regenerate / ai_chat_send /
/// ai_chat_edit)已接入,作真实读侧方法消费。删除 `allow(dead_code)` 标注。
pub fn can_accept_request(self) -> bool {
matches!(self, ConvState::Idle | ConvState::Error)
}