diff --git a/web/src/app/home/monitoring/components/TokenMonitoring.tsx b/web/src/app/home/monitoring/components/TokenMonitoring.tsx index 1571fdb0a..129f5f713 100644 --- a/web/src/app/home/monitoring/components/TokenMonitoring.tsx +++ b/web/src/app/home/monitoring/components/TokenMonitoring.tsx @@ -164,7 +164,7 @@ export default function TokenMonitoring({ }, [fetchStats]); const chartData = useMemo(() => { - if (!stats) return []; + if (!stats || !Array.isArray(stats.timeseries)) return []; return stats.timeseries.map((p) => ({ bucket: p.bucket, input: p.input_tokens, @@ -198,7 +198,7 @@ export default function TokenMonitoring({ ); } - if (!stats || stats.summary.total_calls === 0) { + if (!stats || !stats.summary || stats.summary.total_calls === 0) { return (
@@ -209,7 +209,8 @@ export default function TokenMonitoring({ ); } - const { summary, by_model } = stats; + const summary = stats.summary; + const by_model = Array.isArray(stats.by_model) ? stats.by_model : []; return (
diff --git a/web/src/app/home/monitoring/components/overview-cards/SystemStatusCards.tsx b/web/src/app/home/monitoring/components/overview-cards/SystemStatusCards.tsx index 872bc90fc..9e8c916e9 100644 --- a/web/src/app/home/monitoring/components/overview-cards/SystemStatusCards.tsx +++ b/web/src/app/home/monitoring/components/overview-cards/SystemStatusCards.tsx @@ -74,7 +74,7 @@ export default function SystemStatusCard({ : await httpClient.getBoxSessions().catch(() => [] as BoxSessionInfo[]); setPluginStatus(plugin); setBoxStatus(box); - setBoxSessions(sessions); + setBoxSessions(Array.isArray(sessions) ? sessions : []); } finally { setLoading(false); } diff --git a/web/src/app/home/monitoring/components/overview-cards/TrafficChart.tsx b/web/src/app/home/monitoring/components/overview-cards/TrafficChart.tsx index 827623bf3..674c140e2 100644 --- a/web/src/app/home/monitoring/components/overview-cards/TrafficChart.tsx +++ b/web/src/app/home/monitoring/components/overview-cards/TrafficChart.tsx @@ -34,14 +34,16 @@ export default function TrafficChart({ const { t } = useTranslation(); const chartData = useMemo(() => { - if (!messages.length && !llmCalls.length) { + const safeMessages = Array.isArray(messages) ? messages : []; + const safeLlmCalls = Array.isArray(llmCalls) ? llmCalls : []; + if (!safeMessages.length && !safeLlmCalls.length) { return []; } // Combine all timestamps and find the range const allTimestamps = [ - ...messages.map((m) => m.timestamp.getTime()), - ...llmCalls.map((c) => c.timestamp.getTime()), + ...safeMessages.map((m) => m.timestamp.getTime()), + ...safeLlmCalls.map((c) => c.timestamp.getTime()), ]; if (allTimestamps.length === 0) return []; @@ -99,7 +101,7 @@ export default function TrafficChart({ } // Count messages per bucket - messages.forEach((msg) => { + safeMessages.forEach((msg) => { const bucket = Math.floor(msg.timestamp.getTime() / bucketSize) * bucketSize; const point = buckets.get(bucket); @@ -109,7 +111,7 @@ export default function TrafficChart({ }); // Count LLM calls per bucket - llmCalls.forEach((call) => { + safeLlmCalls.forEach((call) => { const bucket = Math.floor(call.timestamp.getTime() / bucketSize) * bucketSize; const point = buckets.get(bucket); diff --git a/web/src/app/home/monitoring/hooks/useMonitoringData.ts b/web/src/app/home/monitoring/hooks/useMonitoringData.ts index 315cd5bb5..7d69e586c 100644 --- a/web/src/app/home/monitoring/hooks/useMonitoringData.ts +++ b/web/src/app/home/monitoring/hooks/useMonitoringData.ts @@ -92,18 +92,46 @@ export function useMonitoringData(filterState: FilterState) { limit: 50, }); + const overview = response?.overview ?? { + total_messages: 0, + llm_calls: 0, + embedding_calls: 0, + model_calls: 0, + success_rate: 100, + active_sessions: 0, + }; + const messages = Array.isArray(response?.messages) + ? response.messages + : []; + const llmCalls = Array.isArray(response?.llmCalls) + ? response.llmCalls + : []; + const embeddingCalls = Array.isArray(response?.embeddingCalls) + ? response.embeddingCalls + : []; + const sessions = Array.isArray(response?.sessions) + ? response.sessions + : []; + const errors = Array.isArray(response?.errors) ? response.errors : []; + const totalCount = response?.totalCount ?? { + messages: messages.length, + llmCalls: llmCalls.length, + embeddingCalls: embeddingCalls.length, + sessions: sessions.length, + errors: errors.length, + }; + // Transform the response to match MonitoringData interface const transformedData: MonitoringData = { overview: { - totalMessages: response.overview.total_messages, - llmCalls: response.overview.llm_calls, - embeddingCalls: response.overview.embedding_calls || 0, - modelCalls: - response.overview.model_calls || response.overview.llm_calls, - successRate: response.overview.success_rate, - activeSessions: response.overview.active_sessions, + totalMessages: overview.total_messages, + llmCalls: overview.llm_calls, + embeddingCalls: overview.embedding_calls || 0, + modelCalls: overview.model_calls || overview.llm_calls, + successRate: overview.success_rate, + activeSessions: overview.active_sessions, }, - messages: response.messages.map( + messages: messages.map( (msg: { id: string; timestamp: string; @@ -136,7 +164,7 @@ export function useMonitoringData(filterState: FilterState) { variables: msg.variables, }), ), - llmCalls: response.llmCalls.map( + llmCalls: llmCalls.map( (call: { id: string; timestamp: string; @@ -173,7 +201,7 @@ export function useMonitoringData(filterState: FilterState) { messageId: call.message_id, }), ), - embeddingCalls: (response.embeddingCalls || []).map( + embeddingCalls: embeddingCalls.map( (call: { id: string; timestamp: string; @@ -208,7 +236,7 @@ export function useMonitoringData(filterState: FilterState) { ), // Create merged modelCalls array from llmCalls and embeddingCalls modelCalls: [] as ModelCall[], // Will be populated after transform - sessions: response.sessions.map( + sessions: sessions.map( (session: { session_id: string; bot_id: string; @@ -236,7 +264,7 @@ export function useMonitoringData(filterState: FilterState) { userId: session.user_id, }), ), - errors: response.errors.map( + errors: errors.map( (error: { id: string; timestamp: string; @@ -264,11 +292,11 @@ export function useMonitoringData(filterState: FilterState) { }), ), totalCount: { - messages: response.totalCount.messages, - llmCalls: response.totalCount.llmCalls, - embeddingCalls: response.totalCount.embeddingCalls || 0, - sessions: response.totalCount.sessions, - errors: response.totalCount.errors, + messages: totalCount.messages, + llmCalls: totalCount.llmCalls, + embeddingCalls: totalCount.embeddingCalls || 0, + sessions: totalCount.sessions, + errors: totalCount.errors, }, };