重构: 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

@@ -50,6 +50,8 @@ const MESSAGE_CAP = 200
const PARTS_SIZE_BUDGET = 50 * 1024 * 1024 // 50MB(base64 char 计)
import { useAiEvents } from '@/composables/ai/useAiEvents'
import { useAiStream } from '@/composables/ai/useAiStream'
// 批4 双轨收口:getConvState 从 aiShared 取(下沉破环,避免 stores/ai↔useAiEvents 反向环)。
import { getConvState } from '@/composables/ai/aiShared'
import { useAiSend, initDrainQueueListener } from '@/composables/ai/useAiSend'
import { useAiApproval } from '@/composables/ai/useAiApproval'
import { useAiConversations } from '@/composables/ai/useAiConversations'
@@ -63,11 +65,9 @@ export const state = reactive({
streaming: false,
currentText: '',
pendingApprovals: [] as AiToolCallInfo[],
// 正在生成的会话集合(F-09 多会话并发):后端 per-conv 已支持多会话同时生成,
// 前端用 Set 表达"多会话同时生成"态。生成中切走时用于路由,后台事件不污染当前视图
// isGenerating(convId)/addGenerating/removeGenerating helper 经 useAiStore 暴露
// 单会话场景行为不变(Set 含 0 或 1 元素)。
generatingConvs: new Set<string>(),
// 批4 双轨收口:generatingConvs(Set,bool 轨)已退役。会话生成态真相归 convStates
// (reactive Map,enum 轨),定义于 composables/ai/aiShared.ts(下沉破环)
// 消费方经 isGenerating(convId) helper 或直接 getConvState(convId) 读,不再读 state.xxx
providers: [] as AiProviderConfig[],
activeProvider: null as string | null,
panelOpen: true,
@@ -189,20 +189,20 @@ const filteredConversations = computed<AiConversationSummary[] | null>(() => {
})
/**
* F-09 多会话并发:生成态 Set helper。
* F-09 多会话并发:生成态 helper(批4 双轨收口后改为派生)
*
* Vue 3 reactive 对 Set 的 has/add/delete 均有 proxy 跟踪,在 computed/template
* 内调用 isGenerating(convId) 会建立响应式依赖,Set 变更时自动触发更新。
* 单会话场景:Set 含 0 或 1 元素,行为与原单值 generatingConvId 等价
* 批4 收口:generatingConvs(Set,bool 轨)已退役,生成态真相归 convStates(enum Map,定义于
* aiShared.ts)。本 helper 改派生自 getConvState:conv_state∈{generating,stopping,compressed}
* (非终止三态)视为生成中,idle/error/null 视为不在生成。桥接语义对齐原 bool 轨 has() 判定
*
* Vue 3 reactive 对 Map 的 get 有 proxy 跟踪,在 computed/template 内调用 isGenerating(convId)
* 仍建立响应式依赖,convStates 变更时自动触发更新(等价原 Set 行为)。
* addGenerating/removeGenerating 写 helper 已删(写收敛到 useAiEvents setConvState 唯一入口)。
*/
function addGenerating(convId: string): void {
state.generatingConvs.add(convId)
}
function removeGenerating(convId: string): void {
state.generatingConvs.delete(convId)
}
function isGenerating(convId: string | null | undefined): boolean {
return !!convId && state.generatingConvs.has(convId)
if (!convId) return false
const cs = getConvState(convId)
return cs === 'generating' || cs === 'stopping' || cs === 'compressed'
}
/**
@@ -217,9 +217,8 @@ export function useAiStore() {
return {
state,
filteredConversations,
// F-09: 生成态 Set helper(替代单值 generatingConvId 的读写)
addGenerating,
removeGenerating,
// F-09: 生成态 helper(批4 双轨收口:仅读 isGenerating 派生自 getConvState;
// addGenerating/removeGenerating 写 helper 已删,写收敛到 useAiEvents setConvState)
isGenerating,
...useAiEvents(),
...useAiStream(),