// @ts-nocheck import { debugLog, goalModeDebugLog } from '../common'; import { useTaskStore } from '../../../stores/task'; import { getMessageVisibility, messageStartsWork } from '../../../utils/messageVisibility'; import { debugNotifyLog, keyNotifyLog, jsonDebug, userMDebug, isRestoreDebugEnabled, restoreDebugLog, isSystemAutoUserMessagePayload, isRuntimeModeNoticePayload, resolveUserMessageSource, resolveUserMessageMetadata, isEmptyAssistantPlaceholderMessage, getOptimisticUserEchoTarget, findRecentMatchingUserMessage, } from './shared'; export const probeMethods = { scheduleTodoListRefresh(delayMs = 120) { const delay = Number.isFinite(delayMs) ? Math.max(0, Number(delayMs)) : 120; if (this._todoRefreshTimer) { clearTimeout(this._todoRefreshTimer); this._todoRefreshTimer = null; } this._todoRefreshTimer = setTimeout(() => { this._todoRefreshTimer = null; if (typeof this.fetchTodoList === 'function') { Promise.resolve(this.fetchTodoList()).catch(() => {}); } }, delay); }, stopWaitingTaskProbe() { if (this.waitingTaskProbeTimer) { debugNotifyLog('[DEBUG_NOTIFY][ui] stopWaitingTaskProbe'); clearInterval(this.waitingTaskProbeTimer); this.waitingTaskProbeTimer = null; } this._waitingProbeStableEmptyCount = 0; }, startWaitingTaskProbe() { if (this.waitingTaskProbeTimer) { debugNotifyLog('[DEBUG_NOTIFY][ui] startWaitingTaskProbe:already-started'); return; } debugNotifyLog('[DEBUG_NOTIFY][ui] startWaitingTaskProbe'); keyNotifyLog('[DEBUG_NOTIFY_KEY][ui] startWaitingTaskProbe', { conversationId: this.currentConversationId }); this.waitingTaskProbeTimer = setInterval(async () => { if (!this.waitingForSubAgent) { this.stopWaitingTaskProbe(); return; } const resumed = await this.tryResumeWaitingNoticeTask(); if (resumed) { debugNotifyLog('[DEBUG_NOTIFY][ui] waitingTaskProbe:resumed-and-stop'); keyNotifyLog('[DEBUG_NOTIFY_KEY][ui] waitingTaskProbe:resumed-and-stop'); this.stopWaitingTaskProbe(); return; } const state = await this.inspectWaitingCompletionState(); if (state.hasPending) { this._waitingProbeStableEmptyCount = 0; this.waitingForBackgroundCommand = !!state.hasBackgroundPending; return; } this._waitingProbeStableEmptyCount = (this._waitingProbeStableEmptyCount || 0) + 1; if (this._waitingProbeStableEmptyCount >= 2) { debugLog('[TaskPolling] 等待态兜底清理:未发现运行中的后台子智能体/后台指令'); this.streamingMessage = false; this.taskInProgress = false; this.stopRequested = false; this.waitingForSubAgent = false; this.waitingForBackgroundCommand = false; if (typeof this.clearPendingTools === 'function') { this.clearPendingTools('waiting_probe_auto_clear'); } this.clearTaskState(); this.stopWaitingTaskProbe(); this.$forceUpdate(); } }, 1000); }, // ---------- 多智能体任务探测 ---------- stopMultiAgentTaskProbe() { if (this.multiAgentTaskProbeTimer) { debugNotifyLog('[DEBUG_NOTIFY][ui] stopMultiAgentTaskProbe'); goalModeDebugLog('probe.stopMultiAgentTaskProbe', { conversationId: this.currentConversationId, taskInProgress: this.taskInProgress }); clearInterval(this.multiAgentTaskProbeTimer); this.multiAgentTaskProbeTimer = null; } }, startMultiAgentTaskProbe() { if (this.multiAgentTaskProbeTimer) { debugNotifyLog('[DEBUG_NOTIFY][ui] startMultiAgentTaskProbe:already-started'); return; } debugNotifyLog('[DEBUG_NOTIFY][ui] startMultiAgentTaskProbe'); keyNotifyLog('[DEBUG_NOTIFY_KEY][ui] startMultiAgentTaskProbe', { conversationId: this.currentConversationId }); goalModeDebugLog('probe.startMultiAgentTaskProbe', { conversationId: this.currentConversationId, taskInProgress: this.taskInProgress }); this.multiAgentTaskProbeTimer = setInterval(async () => { if (!this.taskInProgress || !this.currentConversationId) { debugNotifyLog('[DEBUG_NOTIFY][ui] multiAgentTaskProbe:stop-no-task-in-progress'); goalModeDebugLog('probe.multiAgentTaskProbe_stop', { reason: 'no_task_in_progress', taskInProgress: this.taskInProgress, currentConversationId: this.currentConversationId }); this.stopMultiAgentTaskProbe(); return; } goalModeDebugLog('probe.multiAgentTaskProbe_tick', { currentConversationId: this.currentConversationId }); const resumed = await this.tryResumeRunningTask(); if (resumed) { debugNotifyLog('[DEBUG_NOTIFY][ui] multiAgentTaskProbe:resumed-and-stop'); keyNotifyLog('[DEBUG_NOTIFY_KEY][ui] multiAgentTaskProbe:resumed-and-stop'); this.stopMultiAgentTaskProbe(); } }, 1000); }, async tryResumeRunningTask() { if (!this.currentConversationId) { return false; } try { const { useTaskStore } = await import('../../../stores/task'); const taskStore = useTaskStore(); if (taskStore.hasActiveTask) { debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeRunningTask:already-active', { taskId: taskStore.currentTaskId, status: taskStore.taskStatus }); return true; } const resp = await fetch('/api/tasks'); if (!resp.ok) { debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeRunningTask:tasks-api-not-ok', { status: resp.status }); return false; } const result = await resp.json().catch(() => ({})); const tasks = Array.isArray(result?.data) ? result.data : []; debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeRunningTask:tasks', { currentConversationId: this.currentConversationId, count: tasks.length, running: tasks .filter((t: any) => t?.status === 'running') .map((t: any) => ({ task_id: t?.task_id, conversation_id: t?.conversation_id, status: t?.status })) }); const runningTask = tasks.find( (task: any) => (task?.status === 'running' || task?.status === 'pending') && task?.conversation_id === this.currentConversationId && (!(this.versioningHostMode || this.dockerProjectMode) || !this.currentHostWorkspaceId || task?.workspace_id === this.currentHostWorkspaceId) ); if (!runningTask?.task_id) { debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeRunningTask:no-matched-task'); goalModeDebugLog('probe.tryResumeRunningTask_no_match', { currentConversationId: this.currentConversationId, tasksCount: tasks.length }); return false; } debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeRunningTask:resume', { task_id: runningTask.task_id }); goalModeDebugLog('probe.tryResumeRunningTask_resume', { taskId: runningTask.task_id, conversationId: this.currentConversationId }); keyNotifyLog('[DEBUG_NOTIFY_KEY][ui] tryResumeRunningTask:resume', { task_id: runningTask.task_id, conversationId: this.currentConversationId }); if (typeof this.clearProcessedEvents === 'function') { this.clearProcessedEvents(); } taskStore.resumeTask(runningTask.task_id, { status: 'running', resetOffset: true, eventHandler: (event: any) => this.handleTaskEvent(event) }); return true; } catch (error) { console.warn('[TaskPolling] 接管运行中任务失败:', error); return false; } }, async inspectWaitingCompletionState() { const terminalStatuses = new Set(['completed', 'failed', 'timeout', 'terminated', 'cancelled']); let hasSubAgentPending = false; let hasBackgroundPending = false; let resolved = true; try { const [subResp, bgResp] = await Promise.all([ fetch('/api/sub_agents'), fetch('/api/background_commands?limit=200') ]); if (subResp.ok) { const subResult = await subResp.json().catch(() => ({})); const tasks = Array.isArray(subResult?.data) ? subResult.data : []; const relevantTasks = tasks.filter((task: any) => { if (!task) return false; if (task.conversation_id && task.conversation_id !== this.currentConversationId) return false; return true; }); hasSubAgentPending = relevantTasks.some((task: any) => { if (!task?.run_in_background) return false; const status = String(task?.status || '').toLowerCase(); return !terminalStatuses.has(status) || !!task?.notice_pending; }); } else { resolved = false; } if (bgResp.ok) { const bgResult = await bgResp.json().catch(() => ({})); const commands = Array.isArray(bgResult?.data) ? bgResult.data : []; hasBackgroundPending = commands.some((command: any) => { if (!command) return false; const status = String(command?.status || '').toLowerCase(); return !terminalStatuses.has(status) || !!command?.notice_pending; }); } else { resolved = false; } } catch (error) { debugNotifyLog('[DEBUG_NOTIFY][ui] inspectWaitingCompletionState:error', { error: error?.message || String(error) }); return { resolved: false, hasPending: true, hasBackgroundPending: this.waitingForBackgroundCommand }; } return { resolved, hasPending: !resolved || hasSubAgentPending || hasBackgroundPending, hasBackgroundPending }; }, async tryResumeWaitingNoticeTask() { if (!this.waitingForSubAgent || !this.currentConversationId) { debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeWaitingNoticeTask:skip', { waitingForSubAgent: this.waitingForSubAgent, currentConversationId: this.currentConversationId }); return false; } try { const { useTaskStore } = await import('../../../stores/task'); const taskStore = useTaskStore(); if (taskStore.hasActiveTask) { debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeWaitingNoticeTask:already-active', { taskId: taskStore.currentTaskId, status: taskStore.taskStatus }); return true; } const resp = await fetch('/api/tasks'); if (!resp.ok) { debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeWaitingNoticeTask:tasks-api-not-ok', { status: resp.status }); return false; } const result = await resp.json().catch(() => ({})); const tasks = Array.isArray(result?.data) ? result.data : []; debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeWaitingNoticeTask:tasks', { currentConversationId: this.currentConversationId, count: tasks.length, running: tasks .filter((t: any) => t?.status === 'running') .map((t: any) => ({ task_id: t?.task_id, conversation_id: t?.conversation_id, status: t?.status })) }); const runningTask = tasks.find( (task: any) => task?.status === 'running' && task?.conversation_id === this.currentConversationId && (!(this.versioningHostMode || this.dockerProjectMode) || !this.currentHostWorkspaceId || task?.workspace_id === this.currentHostWorkspaceId) ); if (!runningTask?.task_id) { debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeWaitingNoticeTask:no-matched-task'); return false; } debugNotifyLog('[DEBUG_NOTIFY][ui] tryResumeWaitingNoticeTask:resume', { task_id: runningTask.task_id }); keyNotifyLog('[DEBUG_NOTIFY_KEY][ui] tryResumeWaitingNoticeTask:resume', { task_id: runningTask.task_id, conversationId: this.currentConversationId }); // 关键修复:切到新的通知任务前,清空旧任务事件去重索引。 // 否则新任务 event idx 与旧任务重叠时会被误判为“重复事件”而丢失 user_message。 if (typeof this.clearProcessedEvents === 'function') { this.clearProcessedEvents(); } taskStore.resumeTask(runningTask.task_id, { status: 'running', resetOffset: true, eventHandler: (event: any) => this.handleTaskEvent(event) }); return true; } catch (error) { console.warn('[TaskPolling] 接管等待任务失败:', error); return false; } }, async restoreSubAgentWaitingState(retry = 0) { try { if (!this.currentConversationId) { if (retry < 5) { setTimeout(() => { this.restoreSubAgentWaitingState(retry + 1); }, 300); } return; } const response = await fetch('/api/sub_agents'); if (!response.ok) { debugLog('[TaskPolling] 获取子智能体状态失败'); return; } const result = await response.json(); if (!result.success) { debugLog('[TaskPolling] 子智能体状态响应无效'); return; } const tasks = Array.isArray(result.data) ? result.data : []; debugLog('[TaskPolling] 子智能体状态响应', { total: tasks.length, currentConversationId: this.currentConversationId, tasks: tasks.map((task: any) => ({ task_id: task?.task_id, status: task?.status, run_in_background: task?.run_in_background, notice_pending: task?.notice_pending, conversation_id: task?.conversation_id })) }); const terminalStatuses = new Set(['completed', 'failed', 'timeout', 'terminated']); const relevant = tasks.filter((task: any) => { if (task && task.conversation_id && task.conversation_id !== this.currentConversationId) { return false; } return true; }); const running = relevant.filter( (task: any) => task?.run_in_background && !terminalStatuses.has(task?.status) ); const pendingNotice = relevant.filter((task: any) => task?.notice_pending); let backgroundPending = false; try { const bgResp = await fetch('/api/background_commands?limit=200'); if (bgResp.ok) { const bgResult = await bgResp.json().catch(() => ({})); const bgCommands = Array.isArray(bgResult?.data) ? bgResult.data : []; backgroundPending = bgCommands.some((command: any) => { if (!command) return false; const status = String(command?.status || '').toLowerCase(); return !terminalStatuses.has(status) || !!command?.notice_pending; }); } } catch (bgErr) { console.warn('[TaskPolling] 获取后台指令状态失败:', bgErr); } if (running.length || pendingNotice.length || backgroundPending) { debugLog('[TaskPolling] 恢复子智能体等待状态', { running: running.length, pendingNotice: pendingNotice.length, backgroundPending, runningTasks: running.map((task: any) => ({ task_id: task?.task_id, status: task?.status })), pendingTasks: pendingNotice.map((task: any) => ({ task_id: task?.task_id, status: task?.status })) }); this.waitingForSubAgent = true; this.waitingForBackgroundCommand = backgroundPending; this.taskInProgress = true; this.streamingMessage = false; this.stopRequested = false; this.startWaitingTaskProbe(); this.$forceUpdate(); } else { this.waitingForSubAgent = false; this.waitingForBackgroundCommand = false; this.stopWaitingTaskProbe(); if (!this.streamingMessage) { this.taskInProgress = false; } this.$forceUpdate(); } } catch (error) { console.error('[TaskPolling] 恢复子智能体等待状态失败:', error); } }, clearProcessedEvents() { if (this._processedEventIndices) { this._processedEventIndices.clear(); } } };