From 293be19a7bb625dfb5d747f8a69b219ff7087bc9 Mon Sep 17 00:00:00 2001 From: moe-berri Date: Wed, 30 Sep 2026 11:12:02 -0700 Subject: [PATCH] fix(roi): preserve reports during metadata outages --- .../19-matching-calculator-icons.png | Bin 0 -> 60252 bytes litellm/proxy/roi_calculator/sync.py | 24 +++++++++++++----- tests/unit/proxy/roi_calculator/test_sync.py | 18 ++++++------- .../_components/ROICalculatorView.tsx | 4 +-- 4 files changed, 28 insertions(+), 18 deletions(-) create mode 100644 .github/assets/roi-calculator/19-matching-calculator-icons.png diff --git a/.github/assets/roi-calculator/19-matching-calculator-icons.png b/.github/assets/roi-calculator/19-matching-calculator-icons.png new file mode 100644 index 0000000000000000000000000000000000000000..af12106e3155098738f15a12a1c1f8a0933f9603 GIT binary patch literal 60252 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 D70N+$ literal 0 HcmV?d00001 diff --git a/litellm/proxy/roi_calculator/sync.py b/litellm/proxy/roi_calculator/sync.py index 645d9ea60a8..bd909c9a036 100644 --- a/litellm/proxy/roi_calculator/sync.py +++ b/litellm/proxy/roi_calculator/sync.py @@ -4,7 +4,7 @@ from contextlib import suppress from datetime import date, datetime, timedelta, timezone from itertools import chain from types import MappingProxyType -from typing import Final, Literal, Protocol, runtime_checkable +from typing import Final, Literal, NamedTuple, Protocol, runtime_checkable from uuid import uuid4 import httpx @@ -239,6 +239,12 @@ async def _unavailable_record(github: GitHub, repo: str, pull: GitHubPullListIte ) +class _ProcessedPull(NamedTuple): + position: int + record: ROIPullRecord + metadata_unavailable: bool = False + + class SyncManager: def __init__( self, @@ -398,7 +404,7 @@ class SyncManager: async def process( item: tuple[int, str, GitHubPullListItem, str | None], - ) -> tuple[int, ROIPullRecord]: + ) -> _ProcessedPull: index, repo, pull, key = item saved: Final = await repository.get_param("roi_calculator_pull_" + key) if key is not None else None cached_pull: Final = ( @@ -426,13 +432,13 @@ class SyncManager: ) ) self._update_estimate_progress(cached_record["estimate"]) - return index, cached_record + return _ProcessedPull(index, cached_record) try: evidence: Final = await github.evidence(repo, pull) except SourceError as exc: unavailable: Final = await _unavailable_record(github, repo, pull, exc) self._update_estimate_progress(unavailable["estimate"]) - return index, unavailable + return _ProcessedPull(index, unavailable, metadata_unavailable=True) estimate: Final = await _estimate_with_fallback(estimator, evidence) evidence_item: Final = GitHubPullListItem.model_validate( MappingProxyType( @@ -457,9 +463,9 @@ class SyncManager: ), ) self._update_estimate_progress(estimate) - return index, record + return _ProcessedPull(index, record) - async def worker(offset: int) -> tuple[tuple[int, ROIPullRecord], ...]: + async def worker(offset: int) -> tuple[_ProcessedPull, ...]: return tuple( [await process(indexed_queue[index]) for index in range(offset, len(indexed_queue), PR_CONCURRENCY)] ) @@ -473,8 +479,12 @@ class SyncManager: if not worker_task.done(): worker_task.cancel() await asyncio.gather(*workers, return_exceptions=True) + if processed and all(item.metadata_unavailable for item in processed): + raise SourceError( + "GitHub could not provide PR metadata. No new report was published; try analysis again later." + ) processed_by_index: Final[Mapping[int, ROIPullRecord]] = MappingProxyType( - {index: pull for index, pull in processed} + {item.position: item.record for item in processed} ) report: Final = ROIReport( mode="live", diff --git a/tests/unit/proxy/roi_calculator/test_sync.py b/tests/unit/proxy/roi_calculator/test_sync.py index 9b80ae54e5a..4e827a7d1da 100644 --- a/tests/unit/proxy/roi_calculator/test_sync.py +++ b/tests/unit/proxy/roi_calculator/test_sync.py @@ -275,12 +275,15 @@ async def test_read_spend_joins_user_emails_and_preserves_unmatched_identities() @pytest.mark.asyncio -async def test_unreadable_pr_is_reported_and_retried_on_next_run() -> None: +async def test_metadata_outage_keeps_previous_report_and_retries_on_next_run() -> None: repository: Final = _ReportRepository() manager: Final = SyncManager(clock=_fixed_now) + assert await manager.start(_settings(), repository, _spend_reader(), _completion(), _transport()) + await _wait_until_finished(manager) + previous: Final = repository.values["roi_calculator_report"] assert await manager.start( - _settings(), + _settings(estimator_prompt="New prompt invalidates saved estimates"), repository, _spend_reader(), _completion(), @@ -288,19 +291,16 @@ async def test_unreadable_pr_is_reported_and_retried_on_next_run() -> None: ) await _wait_until_finished(manager) - assert manager.status.phase == "complete" + assert manager.status.phase == "error" assert manager.status.needs_attention == 1 - failed: Final = TypeAdapter(ROIReport).validate_python(repository.values["roi_calculator_report"]) - assert failed["pulls"][0]["estimate"]["status"] == "needs_review" - assert failed["pulls"][0]["estimate"]["hours"] is None - assert failed["pulls"][0]["incomplete_metadata"] is True - assert failed["pulls"][0]["cache_key"] is None + assert manager.status.error is not None and "No new report was published" in manager.status.error + assert repository.values["roi_calculator_report"] == previous assert await manager.start(_settings(), repository, _spend_reader(), _completion(), _transport()) await _wait_until_finished(manager) recovered: Final = TypeAdapter(ROIReport).validate_python(repository.values["roi_calculator_report"]) assert recovered["pulls"][0]["estimate"]["status"] == "estimated" assert recovered["pulls"][0]["estimate"]["hours"] == 4 - assert manager.status.reused == 0 + assert manager.status.reused == 1 @pytest.mark.asyncio diff --git a/ui/litellm-dashboard/src/app/(dashboard)/roi-calculator/_components/ROICalculatorView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/roi-calculator/_components/ROICalculatorView.tsx index 1d1bfca559c..1f5b136dbb7 100644 --- a/ui/litellm-dashboard/src/app/(dashboard)/roi-calculator/_components/ROICalculatorView.tsx +++ b/ui/litellm-dashboard/src/app/(dashboard)/roi-calculator/_components/ROICalculatorView.tsx @@ -1,7 +1,7 @@ "use client"; import React from "react"; -import { BarChart3, RefreshCw } from "lucide-react"; +import { Calculator, RefreshCw } from "lucide-react"; import { apiClient } from "@/components/networking"; import { PageHeader } from "@/components/shared/PageHeader"; @@ -220,7 +220,7 @@ export default function ROICalculatorView({ return (
} + icon={} title="ROI Calculator" subtitle={ <>