From b6a6009629f88d51ab4f377056aacdedb3c651af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AC=E6=98=8E?= <83812544+Ed1s0nZ@users.noreply.github.com> Date: Wed, 24 Jun 2026 17:15:34 +0800 Subject: [PATCH] Add files via upload --- web/static/js/chat.js | 41 +++++++++++++++++++++++++++++++--------- web/static/js/monitor.js | 36 +++++++++++++++++++++++++++++++++++ web/static/js/router.js | 3 +++ 3 files changed, 71 insertions(+), 9 deletions(-) diff --git a/web/static/js/chat.js b/web/static/js/chat.js index 6bee7b80..45c1a084 100644 --- a/web/static/js/chat.js +++ b/web/static/js/chat.js @@ -3110,15 +3110,26 @@ async function cancelMCPToolExecutionSubmit(executionId, userNote, options = {}) if (!executionId) { return; } + let conversationId = ''; + if (typeof monitorState !== 'undefined' && Array.isArray(monitorState.executions)) { + const exec = monitorState.executions.find(e => e && e.id === executionId); + if (exec) { + conversationId = (exec.conversationId || '').trim(); + } + } try { - const res = await apiFetch(`/api/monitor/execution/${encodeURIComponent(executionId)}/cancel`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ note: userNote || '' }), - }); - const body = await res.json().catch(() => ({})); - if (!res.ok) { - throw new Error(body.error || body.message || res.statusText); + if (conversationId && typeof requestCancelWithContinue === 'function') { + await requestCancelWithContinue(conversationId, userNote || ''); + } else { + const res = await apiFetch(`/api/monitor/execution/${encodeURIComponent(executionId)}/cancel`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ note: userNote || '' }), + }); + const body = await res.json().catch(() => ({})); + if (!res.ok) { + throw new Error(body.error || body.message || res.statusText); + } } const okMsg = typeof window.t === 'function' ? window.t('mcpDetailModal.abortSuccess') : '已发送终止请求'; alert(okMsg); @@ -3136,7 +3147,7 @@ async function cancelMCPToolExecutionSubmit(executionId, userNote, options = {}) } /** - * 取消单次 MCP 工具执行(监控页「终止」)。弹出说明框后提交;仅取消该次 tools/call,不停止整条对话/迭代任务。 + * 取消单次 MCP 工具执行(监控页「终止」)。有 conversationId 时复用对话页「中断并继续」弹窗与 API。 * @param {string} executionId * @param {{ refreshDetail?: boolean }} [options] */ @@ -3144,6 +3155,18 @@ async function cancelMCPToolExecution(executionId, options = {}) { if (!executionId) { return; } + let conversationId = ''; + if (typeof monitorState !== 'undefined' && Array.isArray(monitorState.executions)) { + const exec = monitorState.executions.find(e => e && e.id === executionId); + if (exec) { + conversationId = (exec.conversationId || '').trim(); + } + } + if (conversationId && typeof openUserInterruptModal === 'function') { + openUserInterruptModal(null, conversationId); + window.__monitorInterruptContext = { executionId: executionId, options: options || {} }; + return; + } openMcpToolAbortModal(executionId, options); } diff --git a/web/static/js/monitor.js b/web/static/js/monitor.js index 089b36f4..a6c920ff 100644 --- a/web/static/js/monitor.js +++ b/web/static/js/monitor.js @@ -1003,6 +1003,7 @@ function openUserInterruptModal(progressId, conversationId) { function closeUserInterruptModal() { userInterruptModalPending = null; + window.__monitorInterruptContext = null; closeAppModal('user-interrupt-modal'); } @@ -1012,6 +1013,7 @@ async function submitUserInterruptContinue() { } const reason = (document.getElementById('user-interrupt-reason') && document.getElementById('user-interrupt-reason').value || '').trim(); const { progressId, conversationId } = userInterruptModalPending; + const monitorCtx = window.__monitorInterruptContext; closeUserInterruptModal(); const stopBtn = progressId ? document.getElementById(`${progressId}-stop-btn`) : null; try { @@ -1020,6 +1022,13 @@ async function submitUserInterruptContinue() { stopBtn.textContent = typeof window.t === 'function' ? window.t('tasks.interruptSubmitting') : '提交中...'; } await requestCancelWithContinue(conversationId, reason); + if (monitorCtx && monitorCtx.executionId && typeof refreshMonitorPanel === 'function') { + const page = (typeof monitorState !== 'undefined' && monitorState.pagination && monitorState.pagination.page) + ? monitorState.pagination.page + : 1; + await refreshMonitorPanel(page); + window.__monitorInterruptContext = null; + } loadActiveTasks(); } catch (error) { console.error('中断并继续失败:', error); @@ -3536,6 +3545,33 @@ const monitorState = { } }; +let monitorPollTimer = null; +const MONITOR_POLL_INTERVAL_MS = 3000; + +function startMonitorPoll() { + stopMonitorPoll(); + monitorPollTimer = setInterval(function () { + const page = document.getElementById('page-mcp-monitor'); + if (!page || !page.classList.contains('active')) { + stopMonitorPoll(); + return; + } + if (document.hidden) { + return; + } + if (typeof refreshMonitorPanel === 'function') { + refreshMonitorPanel().catch(function () { /* ignore */ }); + } + }, MONITOR_POLL_INTERVAL_MS); +} + +function stopMonitorPoll() { + if (monitorPollTimer) { + clearInterval(monitorPollTimer); + monitorPollTimer = null; + } +} + function openMonitorPanel() { // 切换到MCP监控页面 if (typeof switchPage === 'function') { diff --git a/web/static/js/router.js b/web/static/js/router.js index ddfeecd3..235db0d9 100644 --- a/web/static/js/router.js +++ b/web/static/js/router.js @@ -356,6 +356,9 @@ async function initPage(pageId) { if (typeof refreshMonitorPanel === 'function') { refreshMonitorPanel(); } + if (typeof startMonitorPoll === 'function') { + startMonitorPoll(); + } break; case 'mcp-management': // 初始化MCP管理