diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.tsx index 6551cf0e6d7..0d9c1042470 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.tsx @@ -1,11 +1,12 @@ "use client"; import React, { useEffect, useMemo, useState } from "react"; -import { Collapse } from "antd"; +import { Info } from "lucide-react"; import { AreaChart, BarChart, CustomLegend, DonutChart, SEQUENTIAL_COLOR_RAMP } from "@/components/shared/charts"; import AdvancedDatePicker from "@/components/shared/advanced_date_picker"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { getToolSpend, ToolSpendResponse } from "@/components/networking"; import { SpendMetrics } from "@/components/UsagePage/types"; import { formatNumberWithCommas } from "@/utils/dataUtils"; @@ -33,45 +34,24 @@ const compressionOf = (m: SpendMetrics): number => m.compression_savings_spend ? const cachingOf = (m: SpendMetrics): number => m.prompt_caching_savings_spend ?? 0; const savedTokensOf = (m: SpendMetrics): number => m.compression_saved_tokens ?? 0; -const MethodologyNote = () => ( - How savings are calculated, - children: ( -
-

- Savings are computed for each request when it is logged, using the provider's reported usage and the - model's pricing, then summed into a daily rollup. Totals below are read from that rollup over the - selected date range, so the numbers never require a scan of raw request logs. -

-

- Compression savings are the tokens Headroom removed before the call, priced at the model's input - rate: compression_saved_tokens * input_cost_per_token -

-

- Prompt caching savings are the tokens the provider served from cache (Anthropic{" "} - cache_read_input_tokens, or OpenAI-style prompt_tokens_details.cached_tokens), - priced at the discount between the normal input rate and the cache-read rate:{" "} - cache_read_input_tokens * max(input_cost_per_token - cache_read_input_token_cost, 0) -

-

- Total saved is the sum of both drivers. Models without a separate cache-read price in the pricing map - contribute zero caching savings rather than erroring. -

-
- ), - }, - ]} - /> -); - -const SummaryCard = ({ label, value, hint }: { label: string; value: string; hint?: string }) => ( +const SummaryCard = ({ label, value, hint, info }: { label: string; value: string; hint?: string; info?: string }) => ( - + {label} + {info && ( + + + + + + {info} + + + )}

{value}

@@ -150,8 +130,7 @@ const UsageTab: React.FC = ({ accessToken, activity }) => { return (
-
- +
@@ -165,8 +144,14 @@ const UsageTab: React.FC = ({ accessToken, activity }) => { label="Compression savings" value={usd(compressionTotal)} hint={`${formatNumberWithCommas(savedTokensTotal)} tokens compressed`} + info="Tokens Headroom removed before the call, priced at the model's input rate." + /> + -