重构: 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:
2026-06-25 03:20:42 +08:00
parent fc705443bd
commit c011f864fd
22 changed files with 526 additions and 428 deletions

View File

@@ -339,9 +339,11 @@ export type AiErrorType = 'auth' | 'network' | 'timeout' | 'provider_config' | '
* - error:出错(用户可重试回 generating)
* - compressed:压缩中(Generating/Idle 期间瞬态派生,压缩完成回原态)
*
* 后端开关 CONV_STATE_ENABLED 门控:on 时 GeneratingGuard set/reset 同步迁移并发
* AiConvStateChanged 事件;off 时纯旧 generating bool 行为(可回退)。前端 conv_state
* 新增派生源,旧 streaming/generating bool 双轨过渡保留,不强制全替(防回归)。
* 批4 双轨收口后(2026-06-25):convStates(enum Map)是「会话是否生成中」的唯一真相源,
* 旧 generatingConvs bool 轨已退役。CONV_STATE_ENABLED=off 或老后端不发 AiConvStateChanged 时,
* useAiEvents.handleEvent 活跃事件兜底写 setConvState('generating') 作为 enum 写入口
* (替代旧 bool 轨 add),消费方不再回退 bool 判断。streaming 单值是另一条过渡态
* (F-09 per-conv streaming 收口前保留),不在本状态机口径内。
*/
export type ConvState = 'idle' | 'generating' | 'stopping' | 'error' | 'compressed'
@@ -400,8 +402,9 @@ export type AiChatEvent = ({
// L2 统一状态机(批2 1b/1c):ConvState 经 AiChatEvent 推前端,供 status union 消费。
// conv_state 值为 idle|generating|stopping|error|compressed(snake_case,对齐后端 ConvState serde)。
// 后端在 conv_state 变化时(入口→generating / reset·drop→idle)emit;conversation_id 标识
// 哪个会话的状态变了(F-09 多会话并发下前端按 convId 路由)。CONV_STATE_ENABLED 门控:off
// 后端不 emit,前端 conv_state 收不到 → 消费方须回退旧 streaming/generating bool 判断(双轨过渡)。
// 哪个会话的状态变了(F-09 多会话并发下前端按 convId 路由)。批4 双轨收口后:CONV_STATE_ENABLED=off
// 或老后端不发本事件时,useAiEvents.handleEvent 活跃事件兜底写 setConvState('generating') 作为
// enum 写入口(替代旧 bool 轨 add),消费方不再回退 streaming/generating bool 判断。
type: 'AiConvStateChanged'; conv_state: ConvState
} | {
// F-260616-07: 流式调用自动重试提示(前端可在错误气泡内显示「重试 n/m」)