From 30b7fd16f0f75251e72f3e87a54d97d3550893f7 Mon Sep 17 00:00:00 2001 From: Tin Chi Lo Date: Fri, 24 Jul 2026 17:31:00 -0700 Subject: [PATCH] fix(proxy): label the tool spend clamp accurately (start capped at 30 days before end) The clamp floor is end_date minus 30 days, serving up to 31 calendar dates inclusive: deliberately the same width as the endpoint's default window, so the dashboard's own default range never triggers the clamp note. The docstring, card note, and test name now state that invariant instead of the misleading 'most recent 30 days'. Co-Authored-By: Claude Fable 5 --- litellm/proxy/_lazy_openapi_snapshot.json | 2 +- .../management_endpoints/tool_management_endpoints.py | 7 ++++--- .../management_endpoints/test_tool_management_endpoints.py | 5 ++++- .../cost-optimization/_components/UsageTab.test.tsx | 4 ++-- .../(dashboard)/cost-optimization/_components/UsageTab.tsx | 3 ++- ui/litellm-dashboard/src/lib/http/schema.d.ts | 7 ++++--- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/litellm/proxy/_lazy_openapi_snapshot.json b/litellm/proxy/_lazy_openapi_snapshot.json index 6be003927d6..972c831073f 100644 --- a/litellm/proxy/_lazy_openapi_snapshot.json +++ b/litellm/proxy/_lazy_openapi_snapshot.json @@ -27417,7 +27417,7 @@ }, "/v1/tool/spend": { "get": { - "description": "Spend attributed to each tool over a date range, for the Cost Optimization dashboard.\n\nJoins ``LiteLLM_SpendLogToolIndex`` (which tool names ran on which request) to\n``LiteLLM_SpendLogs`` (what the request cost). A request that used multiple tools\ncounts its full spend toward each of those tools, so per-tool numbers are\nattributions. ``total_spend`` is the deduplicated spend of every request that\ncalled at least one tool in the window, so it never double counts.\n\nThe window is capped at the most recent 30 days ending at ``end_date``: a wider\nrequested range is clamped, and the response's ``start_date`` reflects the\neffective window actually served.", + "description": "Spend attributed to each tool over a date range, for the Cost Optimization dashboard.\n\nJoins ``LiteLLM_SpendLogToolIndex`` (which tool names ran on which request) to\n``LiteLLM_SpendLogs`` (what the request cost). A request that used multiple tools\ncounts its full spend toward each of those tools, so per-tool numbers are\nattributions. ``total_spend`` is the deduplicated spend of every request that\ncalled at least one tool in the window, so it never double counts.\n\n``start_date`` is clamped to at most 30 days before ``end_date`` (serving up to\n31 calendar dates inclusive, the same width as the endpoint's default window):\na wider requested range is clamped, and the response's ``start_date`` reflects\nthe effective window actually served.", "operationId": "get_tool_spend_v1_tool_spend_get", "parameters": [ { diff --git a/litellm/proxy/management_endpoints/tool_management_endpoints.py b/litellm/proxy/management_endpoints/tool_management_endpoints.py index 6d9748332bc..3f528c8c489 100644 --- a/litellm/proxy/management_endpoints/tool_management_endpoints.py +++ b/litellm/proxy/management_endpoints/tool_management_endpoints.py @@ -211,9 +211,10 @@ async def get_tool_spend( attributions. ``total_spend`` is the deduplicated spend of every request that called at least one tool in the window, so it never double counts. - The window is capped at the most recent 30 days ending at ``end_date``: a wider - requested range is clamped, and the response's ``start_date`` reflects the - effective window actually served. + ``start_date`` is clamped to at most 30 days before ``end_date`` (serving up to + 31 calendar dates inclusive, the same width as the endpoint's default window): + a wider requested range is clamped, and the response's ``start_date`` reflects + the effective window actually served. """ from litellm.proxy.proxy_server import prisma_client diff --git a/tests/test_litellm/proxy/management_endpoints/test_tool_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_tool_management_endpoints.py index f420eed6a33..150499dfbf1 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_tool_management_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_tool_management_endpoints.py @@ -203,7 +203,10 @@ class TestToolManagementEndpoints: assert tuple(call.args[1:]) == expected_binds assert resp.json()["end_date"] == "2026-07-02" - def test_tool_spend_window_clamped_to_most_recent_30_days(self): + def test_tool_spend_start_clamped_to_30_days_before_end(self): + # Clamped floor is end_date minus 30 days, serving up to 31 calendar dates + # inclusive: deliberately the same width as the endpoint's default window, + # so the dashboard's default range never triggers the clamp. prisma = MagicMock() prisma.db.query_raw = AsyncMock(return_value=[]) with patch("litellm.proxy.proxy_server.prisma_client", prisma): diff --git a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx index 27c79c8a9ce..ab1cd146adc 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/cost-optimization/_components/UsageTab.test.tsx @@ -148,7 +148,7 @@ describe("UsageTab", () => { }; const { findByText } = renderWith([day("2026-07-12", {})], toolSpend); - expect(await findByText(/most recent 30 days of the selected range/)).toBeInTheDocument(); + expect(await findByText(/capped at 30 days before the end of the selected range/)).toBeInTheDocument(); }); it("shows no cap note when the served window matches the request", async () => { @@ -162,6 +162,6 @@ describe("UsageTab", () => { const { findAllByTestId, queryByText } = renderWith([day("2026-07-12", {})], toolSpend); await findAllByTestId("bar-chart"); - expect(queryByText(/most recent 30 days of the selected range/)).not.toBeInTheDocument(); + expect(queryByText(/capped at 30 days before the end of the selected range/)).not.toBeInTheDocument(); }); }); 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 a069c80a201..6e2da4456d3 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 @@ -214,7 +214,8 @@ const UsageTab: React.FC = ({ accessToken, activity }) => {

{toolSpendWindowClamped && (

- Tool spend is limited to the most recent 30 days of the selected range (since {toolSpend?.start_date}). + Tool spend is capped at 30 days before the end of the selected range; showing spend since{" "} + {toolSpend?.start_date}.

)} diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index e420da55e77..c1141db7852 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -17977,9 +17977,10 @@ export interface paths { * attributions. ``total_spend`` is the deduplicated spend of every request that * called at least one tool in the window, so it never double counts. * - * The window is capped at the most recent 30 days ending at ``end_date``: a wider - * requested range is clamped, and the response's ``start_date`` reflects the - * effective window actually served. + * ``start_date`` is clamped to at most 30 days before ``end_date`` (serving up to + * 31 calendar dates inclusive, the same width as the endpoint's default window): + * a wider requested range is clamped, and the response's ``start_date`` reflects + * the effective window actually served. */ get: operations["get_tool_spend_v1_tool_spend_get"]; put?: never;