diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/AutoRouterBenchmarksTab.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/AutoRouterBenchmarksTab.test.tsx index 51e9e125cb9..a5767383307 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/AutoRouterBenchmarksTab.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/AutoRouterBenchmarksTab.test.tsx @@ -155,21 +155,45 @@ describe("AutoRouterBenchmarksTab", () => { expect(screen.getByText(/turns measured/)).toBeInTheDocument(); }); - it("recomputes the expired-miss share from the miss counts", () => { + it("computes the expired-miss share over every measured turn, not just return-to-tier misses", () => { mockHook({ data: response([group()]) }); renderTab(); expect(screen.getByText("Expired-miss")).toBeInTheDocument(); - expect(screen.getByText("27.1%")).toBeInTheDocument(); + expect(screen.getByText("2.3%")).toBeInTheDocument(); }); - it("hides the expired-miss row when every return turn hit", () => { + it("exposes the whole expired-miss row as a focusable tooltip trigger", () => { + mockHook({ data: response([group()]) }); + renderTab(); + + const trigger = screen.getByRole("button", { name: /Expired-miss/ }); + expect(trigger).toHaveTextContent("2.3%"); + }); + + it("shows a zero expired-miss share, rather than hiding the row, when every return turn hit", () => { const allHits = totals({ cache: cache({ return_to_tier: { turns: 381, hits: 381, hit_rate_pct: 100 }, return_misses_expired: 0 }), }); mockHook({ data: response([group(allHits)], allHits) }); renderTab(); + const trigger = screen.getByRole("button", { name: /Expired-miss/ }); + expect(trigger).toHaveTextContent("0.0%"); + }); + + it("hides the expired-miss row only when no turns were measured at all", () => { + const empty = { turns: 0, hits: 0, hit_rate_pct: 0 }; + const nothingMeasured = { + same_model: empty, + first_visit: empty, + return_to_tier: empty, + return_misses_expired: 0, + }; + const noTurns = totals({ cache: cache(nothingMeasured) }); + mockHook({ data: response([group(noTurns)], noTurns) }); + renderTab(); + expect(screen.queryByText("Expired-miss")).not.toBeInTheDocument(); }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/AutoRouterBenchmarksTab.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/AutoRouterBenchmarksTab.tsx index 2b71c36c597..ff0f52940b2 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/AutoRouterBenchmarksTab.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/AutoRouterBenchmarksTab.tsx @@ -183,23 +183,27 @@ const CachingCard: React.FC<{ cache: AutoRouterCacheStats }> = ({ cache }) => {

{pctLabel(cache.hit_rate_pct)}

{expiredMissPct === null ? null : ( -
- - - - Expired-miss -

- } - /> - - percentage of return-to-tier cache misses caused by cache expiring - -
-
-

{pctLabel(expiredMissPct)}

-
+ + + + } + > + + Expired-miss + + {pctLabel(expiredMissPct)} + + + share of all measured turns that missed cache because a return to an earlier tier came after its TTL + lapsed + + + )} diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.test.tsx index 96ef75e8dd1..33c64ecf18a 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.test.tsx @@ -17,21 +17,21 @@ describe("CostOptimizationView", () => { it("renders the four cost-optimization tabs", () => { const { getByText } = renderView(); - expect(getByText("Usage")).toBeInTheDocument(); + expect(getByText("Overall")).toBeInTheDocument(); expect(getByText("Prompt Compression")).toBeInTheDocument(); expect(getByText("Prompt Caching")).toBeInTheDocument(); - expect(getByText("Auto-Router Usage")).toBeInTheDocument(); + expect(getByText("Auto-Router")).toBeInTheDocument(); }); - it("defaults to the Usage tab and switches the active tab on click", () => { + it("defaults to the Overall tab and switches the active tab on click", () => { const { getByRole } = renderView(); - expect(getByRole("tab", { name: "Usage" })).toHaveAttribute("aria-selected", "true"); + expect(getByRole("tab", { name: "Overall" })).toHaveAttribute("aria-selected", "true"); expect(getByRole("tab", { name: "Prompt Compression" })).toHaveAttribute("aria-selected", "false"); fireEvent.click(getByRole("tab", { name: "Prompt Compression" })); - expect(getByRole("tab", { name: "Usage" })).toHaveAttribute("aria-selected", "false"); + expect(getByRole("tab", { name: "Overall" })).toHaveAttribute("aria-selected", "false"); expect(getByRole("tab", { name: "Prompt Compression" })).toHaveAttribute("aria-selected", "true"); }); }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.tsx index 0d986fdcaa8..6af1e8d0441 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/CostOptimizationView.tsx @@ -22,7 +22,7 @@ const CostOptimizationView: React.FC = ({ accessToken const items = [ { key: "usage", - label: "Usage", + label: "Overall", children: , }, { @@ -37,7 +37,7 @@ const CostOptimizationView: React.FC = ({ accessToken }, { key: "autorouter-usage", - label: "Auto-Router Usage", + label: "Auto-Router", children: , }, ]; diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/autoRouterBenchmarks.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/autoRouterBenchmarks.test.ts index 201a71ae4be..57c059b5524 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/autoRouterBenchmarks.test.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/autoRouterBenchmarks.test.ts @@ -131,12 +131,25 @@ describe("bucketRows", () => { }); describe("expiredMissShare", () => { - it("recomputes the expired share from the miss counts", () => { - expect(expiredMissShare(cache())).toBeCloseTo((100 * 19) / 70); + it("computes the expired share over every measured turn, not just return-to-tier misses", () => { + expect(expiredMissShare(cache())).toBeCloseTo((100 * 19) / 818); }); - it("is absent when every return turn hit", () => { - expect(expiredMissShare(cache({ return_to_tier: { turns: 10, hits: 10, hit_rate_pct: 100 } }))).toBeNull(); + it("is zero, not absent, when every return turn hit", () => { + expect( + expiredMissShare(cache({ return_to_tier: { turns: 10, hits: 10, hit_rate_pct: 100 }, return_misses_expired: 0 })), + ).toBe(0); + }); + + it("is absent only when no turns were measured at all", () => { + const empty = { turns: 0, hits: 0, hit_rate_pct: 0 }; + const nothingMeasured = { + same_model: empty, + first_visit: empty, + return_to_tier: empty, + return_misses_expired: 0, + }; + expect(expiredMissShare(cache(nothingMeasured))).toBeNull(); }); }); diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/autoRouterBenchmarks.ts b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/autoRouterBenchmarks.ts index 8b6a4fa4105..00793548278 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/autoRouterBenchmarks.ts +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/autoRouterBenchmarks.ts @@ -91,9 +91,9 @@ export const bucketRows = (cache: AutoRouterCacheStats): BucketRow[] => { }; export const expiredMissShare = (cache: AutoRouterCacheStats): number | null => { - const misses = cache.return_to_tier.turns - cache.return_to_tier.hits; - if (misses <= 0) return null; - return (100 * cache.return_misses_expired) / misses; + const total = bucketTurnsTotal(cache); + if (total <= 0) return null; + return (100 * cache.return_misses_expired) / total; }; export const pctLabel = (value: number, digits: number = 1): string => `${value.toFixed(digits)}%`;