diff --git a/ell-studio/src/pages/Invocations.js b/ell-studio/src/pages/Invocations.js index 6571dd54..bfa177d7 100644 --- a/ell-studio/src/pages/Invocations.js +++ b/ell-studio/src/pages/Invocations.js @@ -1,7 +1,8 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { FiCopy, FiZap, FiEdit2, FiFilter, FiClock, FiColumns, FiPause, FiPlay } from 'react-icons/fi'; import InvocationsTable from '../components/invocations/InvocationsTable'; import InvocationsLayout from '../components/invocations/InvocationsLayout'; +import MetricChart from '../components/MetricChart'; import { useNavigate, useLocation } from 'react-router-dom'; import { useInvocationsFromLMP } from '../hooks/useBackend'; @@ -11,13 +12,10 @@ const Traces = () => { const navigate = useNavigate(); const location = useLocation(); - - // TODO Unify invocation search behaviour with the LMP page. const [currentPage, setCurrentPage] = useState(0); const pageSize = 50; const { data: invocations , isLoading } = useInvocationsFromLMP(null, null, currentPage, pageSize); - useEffect(() => { const searchParams = new URLSearchParams(location.search); @@ -39,45 +37,44 @@ const Traces = () => { navigate(`?i=${trace.id}`); }; + const chartData = useMemo(() => { + if (!invocations || invocations.length === 0) return []; + + return invocations + .map(inv => ({ + date: new Date(inv.created_at), + count: 1, + latency: inv.latency_ms + })) + .sort((a, b) => new Date(a.date) - new Date(b.date)); + }, [invocations]); + + const totalInvocations = useMemo(() => invocations?.length || 0, [invocations]); + const avgLatency = useMemo(() => { + if (!invocations || invocations.length === 0) return 0; + const sum = invocations.reduce((acc, inv) => acc + inv.latency_ms, 0); + return sum / invocations.length; + }, [invocations]); + if (isLoading) { return