Analytics and AI Chat
Introduction
This document describes the security analytics dashboard, OpenSearch API integration, URL filters, PDF export, optional analytics AI chat, and the free enrichment v1 flow that augments chat responses with MISP, historical recurrence, and local playbook guidance.
Main Files
| File | Responsibility |
|---|---|
modules/analytics/pages/AnalyticsDashboardPage.tsx | Main analytics route orchestration, data fetching, filters, export, and chat state |
modules/analytics/partials/AnalyticsWorkspaceShell.tsx | Workspace layout, scroll boundary, and overlay/sheet chat container |
modules/analytics/partials/AnalyticsHeader.tsx | Analytics title, filters, active filter chips, refresh, export, and AI chat launcher |
modules/analytics/partials/AnalyticsSummaryCards.tsx | Summary card grid |
modules/analytics/partials/AnalyticsChartsGrid.tsx | Timeline, priority, protocol, and classification charts |
modules/analytics/partials/AnalyticsInsightPanels.tsx | Top source/destination IPs, IP flow list, and sensor panels |
modules/analytics/partials/AnalyticsAlertsTable.tsx | Alert details table, sorting controls, and pagination |
modules/analytics/chat/AnalyticsChatShell.tsx | AI chat overlay/sheet shell, resize boundary, and panel container |
modules/analytics/chat/AnalyticsChatSidebar.tsx | Saved investigations, availability messaging, and enrichment capability chips |
modules/analytics/chat/components/CitationList.tsx | Source-aware citation rendering for analytics, MISP, history, and playbook context |
lib/analyticsFilters.ts | URL search param parsing/building and filter helpers |
lib/analyticsChat.ts | Streaming client for analytics chat SSE-style responses |
lib/pdfReport.ts | Security summary and detailed alert PDF generation |
lib/api.ts | opensearch, analyticsChat, and analyticsVirtualSensors endpoint groups |
types/index.ts | Analytics filters, chat payloads, citations, and virtual sensor types |
Analytics Route
- Route:
/dashboard/analytics - Component:
AnalyticsDashboard
The dashboard renders:
- Time range selector.
- Virtual sensor filter.
- Priority, protocol, classification, source IP, and destination IP filters.
- Summary cards.
- Alert priority/protocol/classification charts.
- Timeline chart.
- Top sources and destinations.
- IP flow visualization/table.
- Alert list with sorting and pagination.
- PDF export actions.
- Optional AI chat entry point.
Filter Model
The supported time ranges are:
'15m' | '1h' | '6h' | '24h' | '7d' | '30d'
The supported filters are:
interface AnalyticsDashboardFilters {
virtualSensorId: string | null;
priority: string[];
protocol: string[];
classification: string[];
srcAddr: string[];
dstAddr: string[];
}
analyticsFilters.ts keeps dashboard state and the URL in sync:
parseAnalyticsSearchParams()buildAnalyticsSearchParams()buildAnalyticsRequestParams()toggleAnalyticsFilterValue()hasActiveAnalyticsFilters()clearAnalyticsFilters()
Array filters are serialized as repeated query params.
OpenSearch API Calls
The analytics dashboard uses api.opensearch.
| API Method | Backend Path | Purpose |
|---|---|---|
getDashboardSummary | /opensearch/dashboard/summary | Summary counts and grouped analytics |
getTotalAlerts | /opensearch/alerts/count | Alert count |
getAlertsByPriority | /opensearch/alerts/by-priority | Priority chart |
getAlertsByClassification | /opensearch/alerts/by-classification | Classification chart |
getAlertsByProtocol | /opensearch/alerts/by-protocol | Protocol chart |
getAlertsTimeline | /opensearch/alerts/timeline | Time-series chart |
getTopSources | /opensearch/alerts/top-sources | Top source IPs |
getTopDestinations | /opensearch/alerts/top-destinations | Top destination IPs |
getTopSourceCountries | /opensearch/alerts/top-source-countries | Source country map data |
getTopDestinationCountries | /opensearch/alerts/top-destination-countries | Destination country map data |
getAlertsBySensor | /opensearch/alerts/by-sensor | Alerts grouped by sensor |
getIpFlow | /opensearch/alerts/ip-flow | Source-to-destination flow |
getAlertsList | /opensearch/alerts/list | Paginated alert table |
getGeoMap | /opensearch/alerts/geo-map | Geographic alert map data |
Alert Table
The table supports client-controlled state for:
- Current page.
- Page size through backend response payload.
- Sort field.
- Sort direction.
- Highlighting from AI chat citations.
Supported sort fields in component state:
'timestamp' | 'priority' | 'src_addr' | 'dst_addr'
The alert list fetch path uses the current time range, filters, page, and sort options.
PDF Export
PDF exports are implemented in src/lib/pdfReport.ts.
Supported reports:
| Function | Purpose |
|---|---|
generateSecurityReport | Summary analytics report |
generateAlertsReport | Detailed alert list report |
AnalyticsDashboard can fetch all alert pages for export using ALERTS_EXPORT_PAGE_SIZE = 200, then pass the assembled list to the report generator.
AI Chat Feature Flag
Analytics AI chat appears only when:
appConfig.VITE_ANALYTICS_AI_CHAT_ENABLED === true
The chat sheet still calls backend status with:
api.analyticsChat.getStatus()
This allows the UI feature flag and backend capability to both participate in availability.
AI Chat API
Saved conversation API methods:
| API Method | Backend Path |
|---|---|
getStatus | /analytics/chat/status |
listConversations | /analytics/chat/conversations |
createConversation | /analytics/chat/conversations |
getConversation | /analytics/chat/conversations/:conversationId |
deleteConversation | /analytics/chat/conversations/:conversationId |
Streaming endpoint: POST /analytics/chat/conversations/:conversationId/stream
The streaming client supports:
onStartonChunkonCompleteonError- Abort through
AbortSignal
The backend status payload also exposes enrichment capability flags:
interface AnalyticsChatStatus {
enabled: boolean;
reason?: string | null;
model?: string | null;
capabilities?: AnalyticsChatCapabilities;
}
interface AnalyticsChatCapabilities {
savedChats: boolean;
guidance: boolean;
threatIntel: boolean;
historicalEnrichment: boolean;
playbooks: boolean;
}
The chat controller uses these flags to decide whether chat is available and which enrichment modules are surfaced in the UI.
Free Enrichment v1
Analytics chat remains analytics-first and snapshot-grounded.
Current v1 enrichment is appended by the backend before the LLM call:
Threat intelfrom a self-hosted MISP instance over direct REST APIHistorical enrichmentfrom internal OpenSearch recurrence queriesPlaybook guidancefrom a local backend JSON file
Important behavior:
- The frontend never calls MISP directly
- MISP is supporting context, not primary evidence
- If MISP is unavailable, chat can still operate with history, playbooks, or analytics-only evidence
- Availability chips shown in the sidebar come from backend status rather than runtime config
Citations and Context
AI chat responses can include citations with this shape:
interface AnalyticsChatCitation {
sourceId: string;
label: string;
panel?: 'summary' | 'top-sources' | 'top-destinations' | 'alerts-list' | 'ip-flow' | null;
detail: string;
sourceType?: 'analytics' | 'misp' | 'history' | 'playbook';
url?: string | null;
}
Citation behavior is source-aware:
analyticscitations keep the scroll-to-panel behaviormispcitations open an external event link whenurlis presenthistoryandplaybookcitations render as read-only badges with detail tooltips- Non-analytics citations do not attempt dashboard scrolling
Failure Modes
| Scenario | Frontend Behavior |
|---|---|
| OpenSearch summary/list fails | Loading ends and errors are logged or surfaced in UI state |
| Filter URL has invalid time range | Falls back to 15m |
| Chat feature flag is false | Chat UI is hidden |
| Chat status says disabled | Chat panel reports disabled state |
Chat is enabled but capabilities.threatIntel is false | Chat remains usable without MISP capability chips or threat-intel citations |
Chat stream returns 401 | Auth is cleared and browser redirects to / |
| Chat stream body is missing | AnalyticsChatStreamError is thrown |
| Chat stream is aborted | isAbortError() identifies aborts for quiet handling |