mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
refactor(ui): derive drilldown validity and drop Map mutation in bucket grouping
The drilldown now self-dismisses when refetched activity has no failures for its call_type, instead of holding a selection the chart no longer shows. groupErrorBuckets is rewritten as pure filter/map/sort over the already-grouped SQL rows.
This commit is contained in:
parent
0de0e1cef6
commit
a5c81e525b
3 changed files with 45 additions and 17 deletions
|
|
@ -24,21 +24,18 @@ export type ErrorCodeDatum = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const groupErrorBuckets = (buckets: readonly CacheActivityErrorBucket[], callType: string): ErrorCodeDatum[] => {
|
export const groupErrorBuckets = (buckets: readonly CacheActivityErrorBucket[], callType: string): ErrorCodeDatum[] => {
|
||||||
const byCode = new Map<string, Map<string, number>>();
|
const rows = buckets.filter((bucket) => bucket.call_type === callType);
|
||||||
for (const bucket of buckets) {
|
return [...new Set(rows.map((row) => row.error_code))]
|
||||||
if (bucket.call_type !== callType) continue;
|
.map((errorCode) => {
|
||||||
const classes = byCode.get(bucket.error_code) ?? new Map<string, number>();
|
const codeRows = rows.filter((row) => row.error_code === errorCode);
|
||||||
classes.set(bucket.error_class, (classes.get(bucket.error_class) ?? 0) + bucket.count);
|
return {
|
||||||
byCode.set(bucket.error_code, classes);
|
error_code: errorCode,
|
||||||
}
|
[FAILED_REQUESTS_SERIES]: codeRows.reduce((total, row) => total + row.count, 0),
|
||||||
return [...byCode.entries()]
|
classes: codeRows
|
||||||
.map(([errorCode, classes]) => ({
|
.map((row) => ({ error_class: row.error_class, count: row.count }))
|
||||||
error_code: errorCode,
|
.sort((a, b) => b.count - a.count),
|
||||||
[FAILED_REQUESTS_SERIES]: [...classes.values()].reduce((total, count) => total + count, 0),
|
};
|
||||||
classes: [...classes.entries()]
|
})
|
||||||
.map(([errorClass, count]) => ({ error_class: errorClass, count }))
|
|
||||||
.sort((a, b) => b.count - a.count),
|
|
||||||
}))
|
|
||||||
.sort((a, b) => b[FAILED_REQUESTS_SERIES] - a[FAILED_REQUESTS_SERIES]);
|
.sort((a, b) => b[FAILED_REQUESTS_SERIES] - a[FAILED_REQUESTS_SERIES]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,31 @@ describe("CacheDashboard cache analytics charts", () => {
|
||||||
expect(screen.queryByText(/Failed requests by error code/)).not.toBeInTheDocument();
|
expect(screen.queryByText(/Failed requests by error code/)).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("dismisses an open drilldown when refetched data no longer has failures for that call_type", async () => {
|
||||||
|
const { rerender } = renderDashboard();
|
||||||
|
const { requestsCard } = await findChartCards();
|
||||||
|
|
||||||
|
const redBar = Array.from(requestsCard.querySelectorAll(".recharts-bar")).find((bar) =>
|
||||||
|
bar.querySelector("path.recharts-rectangle")?.getAttribute("fill")?.includes("red"),
|
||||||
|
);
|
||||||
|
fireEvent.click(redBar!.querySelectorAll("path.recharts-rectangle")[0]);
|
||||||
|
expect(screen.getByText("Failed requests by error code: acompletion")).toBeInTheDocument();
|
||||||
|
|
||||||
|
useCacheActivity.mockReturnValue({
|
||||||
|
data: {
|
||||||
|
...cacheActivity,
|
||||||
|
groups: cacheActivity.groups.map((group) =>
|
||||||
|
group.call_type === "acompletion" ? { ...group, failed_requests: 0 } : group,
|
||||||
|
),
|
||||||
|
error_breakdown: cacheActivity.error_breakdown.filter((bucket) => bucket.call_type !== "acompletion"),
|
||||||
|
},
|
||||||
|
refetch: vi.fn(),
|
||||||
|
});
|
||||||
|
rerender(<CacheDashboard accessToken="sk-test" token="tok" userRole="Admin" userID="u1" premiumUser={false} />);
|
||||||
|
|
||||||
|
expect(screen.queryByText(/Failed requests by error code/)).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
it("formats y-axis ticks with compact notation", async () => {
|
it("formats y-axis ticks with compact notation", async () => {
|
||||||
renderDashboard();
|
renderDashboard();
|
||||||
const { requestsCard, tokensCard } = await findChartCards();
|
const { requestsCard, tokensCard } = await findChartCards();
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,11 @@ const formatDateWithoutTZ = (date: Date | undefined) => {
|
||||||
return date.toISOString().split("T")[0];
|
return date.toISOString().split("T")[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resolveDrilldownCallType = (selected: string | null, groups: readonly CacheActivityGroup[]): string | null =>
|
||||||
|
selected !== null && groups.some((group) => group.call_type === selected && group.failed_requests > 0)
|
||||||
|
? selected
|
||||||
|
: null;
|
||||||
|
|
||||||
function valueFormatterNumbers(number: number) {
|
function valueFormatterNumbers(number: number) {
|
||||||
const formatter = new Intl.NumberFormat("en-US", {
|
const formatter = new Intl.NumberFormat("en-US", {
|
||||||
maximumFractionDigits: 0,
|
maximumFractionDigits: 0,
|
||||||
|
|
@ -98,6 +103,7 @@ const CacheDashboard: React.FC<CachePageProps> = ({ accessToken, token, userRole
|
||||||
const uniqueApiKeys = activity?.filter_options.key_aliases ?? [];
|
const uniqueApiKeys = activity?.filter_options.key_aliases ?? [];
|
||||||
const uniqueModels = activity?.filter_options.models ?? [];
|
const uniqueModels = activity?.filter_options.models ?? [];
|
||||||
const chartData = (activity?.groups ?? []).map(toChartDatum);
|
const chartData = (activity?.groups ?? []).map(toChartDatum);
|
||||||
|
const activeDrilldownCallType = resolveDrilldownCallType(errorDrilldownCallType, activity?.groups ?? []);
|
||||||
|
|
||||||
const handleRefreshClick = () => {
|
const handleRefreshClick = () => {
|
||||||
refetch();
|
refetch();
|
||||||
|
|
@ -298,9 +304,9 @@ const CacheDashboard: React.FC<CachePageProps> = ({ accessToken, token, userRole
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{errorDrilldownCallType !== null && (
|
{activeDrilldownCallType !== null && (
|
||||||
<ErrorDrilldownCard
|
<ErrorDrilldownCard
|
||||||
callType={errorDrilldownCallType}
|
callType={activeDrilldownCallType}
|
||||||
buckets={activity?.error_breakdown ?? []}
|
buckets={activity?.error_breakdown ?? []}
|
||||||
valueFormatter={valueFormatterNumbers}
|
valueFormatter={valueFormatterNumbers}
|
||||||
onClose={() => setErrorDrilldownCallType(null)}
|
onClose={() => setErrorDrilldownCallType(null)}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue