diff --git a/src/composables/ai/useAiWindow.ts b/src/composables/ai/useAiWindow.ts index feacbe1..0f915c8 100644 --- a/src/composables/ai/useAiWindow.ts +++ b/src/composables/ai/useAiWindow.ts @@ -4,13 +4,12 @@ //! - _unlistenMove / _unlistenResize: 主窗口 move/resize 跟随的 unlistener //! //! 耦合: -//! - detachPanel/resumeInDetached 调 useAiConversations.switchConversation -//! - resumeInDetached 调 aiShared.nextMsgId 占位 ai 气泡 +//! - resumeInDetached 调 aiShared.nextMsgId 占位 ai 气泡 + invoke('ai_is_generating') 核对后端真值 //! - reattachPanel/detachPanel 调 useAiPanel.persistUiState +import { invoke } from '@tauri-apps/api/core' import { state } from '../../stores/ai' import { nextMsgId } from './aiShared' -import { switchConversation } from './useAiConversations' import { persistUiState } from './useAiPanel' // ── 主窗口事件跟随 unlistener ── @@ -54,6 +53,8 @@ async function detachPanel() { win.once('tauri://destroyed', () => { state.detached = false state.docked = false + // R3: X 关分离窗口后主面板自动恢复,无需手动 Ctrl+I + state.panelOpen = true stopFollowMain() }) state.detached = true @@ -77,10 +78,26 @@ async function reattachPanel() { /** 分离窗口挂载时接管主窗口当前对话(含生成中态) */ async function resumeInDetached(convId: string | null) { - const id = convId || state.activeConversationId - if (id) await switchConversation(id) + // R5: 不自动 switchConversation —— 分离窗口可看历史列表,但不主动覆盖主窗口 activeConversationId + // (避免主窗口期间发消息落错会话)。若需切换会话,由用户在分离窗口显式操作触发。 + void convId const gen = localStorage.getItem('df-ai-gen') if (gen) { + // R4: 先核对后端 ai_is_generating 真值,generating=true 才重建生成态, + // 避免 df-ai-gen 残留导致假气泡 + 130s 后 watchdog 假超时 + let backendGenerating = false + try { + backendGenerating = await invoke('ai_is_generating') + } catch (e) { + console.error('[AI] resumeInDetached: 核对 ai_is_generating 失败,跳过重建生成态', e) + return + } + if (!backendGenerating) { + // 后端已不再生成,清残留快照,不重建 + localStorage.removeItem('df-ai-gen') + localStorage.removeItem('df-ai-text') + return + } // 接管正在生成的对话:恢复已生成文本并补占位,后续 delta 继续追加 state.currentText = localStorage.getItem('df-ai-text') || '' state.messages.push({