From 6b96e7712019db9b659d7443909fb5229f550b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AC=E6=98=8E?= <83812544+Ed1s0nZ@users.noreply.github.com> Date: Fri, 5 Jun 2026 10:13:00 +0800 Subject: [PATCH] Add files via upload --- web/static/css/style.css | 16 ++++++++++++++++ web/static/i18n/en-US.json | 1 + web/static/i18n/zh-CN.json | 1 + web/static/js/monitor.js | 29 +++++++++++++++++++---------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/web/static/css/style.css b/web/static/css/style.css index 919996aa..7b8ef752 100644 --- a/web/static/css/style.css +++ b/web/static/css/style.css @@ -6238,6 +6238,7 @@ header { .mcp-stats-kpi__value--rate.is-success { color: #15803d; } .mcp-stats-kpi__value--rate.is-warning { color: #ca8a04; } .mcp-stats-kpi__value--rate.is-danger { color: #dc2626; } +.mcp-stats-kpi__value--rate.is-muted { color: var(--text-muted); } .mcp-stats-kpi__value--time { font-size: 0.875rem; @@ -6281,6 +6282,7 @@ header { .mcp-stats-kpi__status.is-success { color: #15803d; } .mcp-stats-kpi__status.is-warning { color: #ca8a04; } .mcp-stats-kpi__status.is-danger { color: #dc2626; } +.mcp-stats-kpi__status.is-muted { color: var(--text-muted); } /* ── 工具统计 + 调用趋势(合并面板) ── */ .mcp-stats-combined { @@ -7408,6 +7410,20 @@ tr.mcp-stats-tool-row[data-tool-name]:focus-visible { font-size: 0.875rem; } +.mcp-monitor-page .monitor-empty__title { + margin: 0 0 6px; + font-size: 0.875rem; + font-weight: 500; + color: var(--text-secondary); +} + +.mcp-monitor-page .monitor-empty__hint { + margin: 0; + font-size: 0.8125rem; + color: var(--text-muted); + line-height: 1.5; +} + .monitor-table { width: 100%; border-collapse: collapse; diff --git a/web/static/i18n/en-US.json b/web/static/i18n/en-US.json index b4230512..fa270f71 100644 --- a/web/static/i18n/en-US.json +++ b/web/static/i18n/en-US.json @@ -1499,6 +1499,7 @@ "loading": "Loading...", "noStatsData": "No statistical data", "noExecutions": "No execution records", + "emptyHint": "Execution records will appear here after you invoke MCP tools in chat or tasks", "noRecordsWithFilter": "No records with current filter", "paginationInfo": "Show {{start}}-{{end}} of {{total}} records", "perPageLabel": "Per page", diff --git a/web/static/i18n/zh-CN.json b/web/static/i18n/zh-CN.json index ab653a16..59d7a337 100644 --- a/web/static/i18n/zh-CN.json +++ b/web/static/i18n/zh-CN.json @@ -1488,6 +1488,7 @@ "loading": "加载中...", "noStatsData": "暂无统计数据", "noExecutions": "暂无执行记录", + "emptyHint": "在对话或任务中调用 MCP 工具后,执行记录将显示在此处", "noRecordsWithFilter": "当前筛选条件下暂无记录", "paginationInfo": "显示 {{start}}-{{end}} / 共 {{total}} 条记录", "perPageLabel": "每页显示", diff --git a/web/static/js/monitor.js b/web/static/js/monitor.js index a3d65ef8..e08b84e1 100644 --- a/web/static/js/monitor.js +++ b/web/static/js/monitor.js @@ -4387,12 +4387,13 @@ function bindMonitorStatsPanelEvents() { monitorStatsPanelEventsBound = true; } -function renderMcpStatsMetricsBar(totals, successRate, rateTone, rateSubText, lastCallText) { +function renderMcpStatsMetricsBar(totals, successRate, rateTone, rateSubText, lastCallText, hasCalls = true) { const totalCallsLabel = mcpMonitorT('totalCalls') || '总调用次数'; const successRateLabel = mcpMonitorT('successRate') || '成功率'; const lastCallLabel = mcpMonitorT('lastCall') || '最近一次调用'; const successPill = mcpMonitorT('successCount', { n: totals.success }) || `成功 ${totals.success}`; const failedPill = mcpMonitorT('failedCount', { n: totals.failed }) || `失败 ${totals.failed}`; + const rateValue = hasCalls ? `${successRate}%` : successRate; return `
@@ -4411,7 +4412,7 @@ function renderMcpStatsMetricsBar(totals, successRate, rateTone, rateSubText, la
${escapeHtml(successRateLabel)} - ${successRate}% + ${rateValue} ${escapeHtml(rateSubText)}
@@ -4666,18 +4667,22 @@ function renderMonitorStats(statsMap = {}, lastFetchedAt = null) { { total: 0, success: 0, failed: 0, lastCallTime: null } ); - const successRateNum = totals.total > 0 ? (totals.success / totals.total) * 100 : 0; - const successRate = successRateNum.toFixed(1); + const hasCalls = totals.total > 0; + const successRateNum = hasCalls ? (totals.success / totals.total) * 100 : 0; + const successRate = hasCalls ? successRateNum.toFixed(1) : '-'; const locale = (typeof window.__locale === 'string' && window.__locale.startsWith('zh')) ? 'zh-CN' : 'en-US'; const noCallsYet = mcpMonitorT('noCallsYet') || '暂无调用'; const lastCallText = totals.lastCallTime ? (totals.lastCallTime.toLocaleString ? totals.lastCallTime.toLocaleString(locale) : String(totals.lastCallTime)) : noCallsYet; - const rateTone = getMcpStatsRateTone(successRateNum); - let rateSubText = mcpMonitorT('rateHealthy') || '运行平稳'; - if (successRateNum < 80) rateSubText = mcpMonitorT('rateCritical') || '失败率偏高'; - else if (successRateNum < 95) rateSubText = mcpMonitorT('rateWarning') || '存在失败调用'; + const rateTone = hasCalls ? getMcpStatsRateTone(successRateNum) : 'is-muted'; + let rateSubText = noCallsYet; + if (hasCalls) { + rateSubText = mcpMonitorT('rateHealthy') || '运行平稳'; + if (successRateNum < 80) rateSubText = mcpMonitorT('rateCritical') || '失败率偏高'; + else if (successRateNum < 95) rateSubText = mcpMonitorT('rateWarning') || '存在失败调用'; + } const toolFilterEl = document.getElementById('monitor-tool-filter'); const activeToolFilter = toolFilterEl ? toolFilterEl.value.trim() : ''; @@ -4691,7 +4696,7 @@ function renderMonitorStats(statsMap = {}, lastFetchedAt = null) { const showCombined = showTimeline || topTools.length > 0; const html = `
- ${renderMcpStatsMetricsBar(totals, successRate, rateTone, rateSubText, lastCallText)} + ${renderMcpStatsMetricsBar(totals, successRate, rateTone, rateSubText, lastCallText, hasCalls)} ${showCombined ? renderMcpStatsCombinedSection( topTools, totals, @@ -4730,7 +4735,11 @@ function renderMonitorExecutions(executions = [], statusFilter = 'all') { if (hasFilter) { container.innerHTML = '
' + escapeHtml(noRecordsFilter) + '
'; } else { - container.innerHTML = '
' + escapeHtml(noExecutions) + '
'; + const emptyHint = typeof window.t === 'function' ? window.t('mcpMonitor.emptyHint') : '在对话或任务中调用 MCP 工具后,执行记录将显示在此处'; + container.innerHTML = `
+

${escapeHtml(noExecutions)}

+

${escapeHtml(emptyHint)}

+
`; } // 隐藏批量操作栏 const batchActions = document.getElementById('monitor-batch-actions');