From f45c275e20dc3d7e22ea3f8a568289217cf551f6f615ce52b12c4b7e47231e6a Mon Sep 17 00:00:00 2001 From: larssand Date: Thu, 2 Jul 2026 21:14:43 +0200 Subject: [PATCH] change poll mcp again status --- src/fgai/dashboard.py | 18 +++++++++++++++++- tests/test_dashboard.py | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/fgai/dashboard.py b/src/fgai/dashboard.py index 6a2188e..93fa091 100644 --- a/src/fgai/dashboard.py +++ b/src/fgai/dashboard.py @@ -226,6 +226,21 @@ function table(rows, columns, id = '') { return `
${head}${body}
`; } function capability(label, state, detail) { return `${esc(label)}: ${esc(detail)}`; } +function mcpCapability(mcp, configuration, pollRunningSeconds=0) { + if (configuration.log_source !== 'graylog_mcp') return {state: 'warn', detail: 'not selected'}; + const status = String(mcp.status || 'checking'); + if (status === 'connected') return {state: 'on', detail: 'connected'}; + if (status === 'partial') return {state: 'warn', detail: 'partial'}; + if (status === 'refreshing') { + const previous = String(mcp.previous_status || ''); + if (['connected', 'partial'].includes(previous) || Number(mcp.previous_events_fetched || mcp.events_fetched || 0) > 0 || Number(mcp.previous_aggregate_events || mcp.aggregate_events || 0) > 0) { + const suffix = pollRunningSeconds ? `polling ${pollRunningSeconds}s` : 'polling'; + return {state: 'on', detail: previous === 'partial' ? `partial, ${suffix}` : `connected, ${suffix}`}; + } + return {state: 'warn', detail: 'starting poll'}; + } + return {state: 'warn', detail: status}; +} function actionItem(severity, title, detail, action) { return `
${esc(title)}
${esc(detail)}
Next: ${esc(action)}
`; } @@ -560,11 +575,12 @@ async function refresh() { ].join(''); const llm = data.llm_assessment || {}; const llmEnabled = Boolean(llm.enabled || configuration.llm_enabled); + const mcpBadge = mcpCapability(mcp, configuration, pollRunningSeconds); document.getElementById('capabilities').innerHTML = [ capability('Baseline', baseline.enabled ? 'on' : 'warn', baseline.enabled ? `${baseline.sources_ready || 0} sources ready` : 'disabled'), capability('Ollama', llmEnabled && llm.status !== 'error' ? 'on' : 'warn', llmEnabled ? (llm.status || 'starting') : 'disabled'), capability('Threat Intel', threat.enabled && threat.configured ? 'on' : 'warn', threat.enabled ? `${threat.provider || 'unknown'}${threat.configured ? '' : ', key missing'}` : 'disabled'), - capability('Graylog MCP', mcp.status === 'connected' ? 'on' : 'warn', configuration.log_source === 'graylog_mcp' ? (mcp.status || 'checking') : 'not selected') + capability('Graylog MCP', mcpBadge.state, mcpBadge.detail) ].join(''); document.getElementById('liveStatus').innerHTML = [ data.stale ? `Showing cached dashboard data because live MCP fetch failed.` : '', diff --git a/tests/test_dashboard.py b/tests/test_dashboard.py index 2241386..2ee06d2 100644 --- a/tests/test_dashboard.py +++ b/tests/test_dashboard.py @@ -49,6 +49,10 @@ class DashboardTests(unittest.TestCase): self.assertIn("function renderCorrelationExplorer", HTML) self.assertIn("correlationHitboxes", HTML) + def test_dashboard_shows_refreshing_mcp_as_polling_badge(self): + self.assertIn("function mcpCapability", HTML) + self.assertIn("connected, ${suffix}", HTML) + if __name__ == "__main__": unittest.main()