修复: aichat 切换/新建对话缺陷(队列串会话/回切丢消息/审批误终态化/删除复活/切换链路)
This commit is contained in:
@@ -25,7 +25,7 @@ import { aiApi } from '@/api'
|
||||
import { useAppSettingsStore } from '@/stores/appSettings'
|
||||
import { state } from '@/stores/ai'
|
||||
import { t } from '@/i18n/i18n-helpers'
|
||||
import { nextMsgId, findToolCall, startApprovalTimer, clearApprovalTimer, clearAllApprovalTimers, convStates, setConvState } from './aiShared'
|
||||
import { nextMsgId, findToolCall, startApprovalTimer, clearApprovalTimer, clearAllApprovalTimers, convStates, setConvState, switchingConvs, getConvStreamState, setConvCurrentText, setConvStreaming } from './aiShared'
|
||||
// 批4 双轨收口:getConvState 下沉到 aiShared,本模块 re-export 保持消费方
|
||||
// (ChatInput.vue/MaxRoundsCard.vue 等)import 路径不变,组件零改动透明继承。
|
||||
export { getConvState } from './aiShared'
|
||||
@@ -877,15 +877,30 @@ export function handleEvent(event: AiChatEvent) {
|
||||
// 不影响其他态(handleUserMessageEvent 去重幂等)。
|
||||
if (handleUserMessageEvent(event)) return
|
||||
// 事件不属于当前展示对话(生成中切走了)→ 不污染当前视图,仅完成/错误/求助时刷新侧边栏
|
||||
// L1 求助协议(§2.3):AiHelpRequired 同 AiError 后端已 guard.reset 终止 loop,需收敛生成态。
|
||||
const isCurrent = !convId || convId === state.activeConversationId
|
||||
if (!isCurrent) {
|
||||
if (event.type === 'AiCompleted' || event.type === 'AiError' || event.type === 'AiHelpRequired') {
|
||||
// 批4 双轨收口:非当前会话终止事件,收敛 convStates(删 Map 项回 idle/不在生成),
|
||||
// 对齐 :592/:660/:711 当前会话分支语义。非当前会话的 error 态无消费方(MaxRoundsCard/
|
||||
// ChatInput 均读 activeConversationId),回退 null 与停止按钮 streaming 回退行为等价。
|
||||
// 非当前会话终止事件:收敛会话状态(删 Map 项回不在生成)。非当前会话的 error 态无
|
||||
// 消费方(操作卡/输入区均读 activeConversationId),回退 null 与停止按钮回退行为等价。
|
||||
convStates.delete(convId || '')
|
||||
void loadConversations()
|
||||
// 后台会话终止也触发队列续发/清队(原 isCurrent 守卫拦截导致非当前会话排队消息永不
|
||||
// drain,切回后队列卡死)。完成触发续发;错误终止对齐当前会话分支清该会话队列。
|
||||
if (event.type === 'AiCompleted') {
|
||||
emit('ai-drain-queue', { conversationId: event.conversation_id })
|
||||
} else if (event.type === 'AiError') {
|
||||
if (event.conversation_id) {
|
||||
state.queue = state.queue.filter(q => q.conversationId !== event.conversation_id)
|
||||
} else {
|
||||
state.queue = []
|
||||
}
|
||||
}
|
||||
} else if (event.type === 'AiTextDelta' && convId && switchingConvs.has(convId)) {
|
||||
// 切换中缓冲:目标会话正被 switchConversation 拉取,该会话的 delta 累积到其 per-conv
|
||||
// 流式态(而非丢弃),切换完成后由渲染层续显,避免切换窗口丢可见内容。不做气泡/工具
|
||||
// 副作用(消息视图尚未切到目标会话,避免污染当前视图)。
|
||||
setConvStreaming(convId, true)
|
||||
setConvCurrentText(convId, (getConvStreamState(convId)?.currentText ?? '') + (event.delta ?? ''))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user