From bde3f6ae4605d356ac298ce470396c1b89ec535d Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Fri, 4 Sep 2026 19:35:43 -0700
Subject: [PATCH 01/35] feat(ui): show guardrail usage units and cost on the
Guardrails Monitor
The overview table gains Usage Units and Cost columns plus a Guardrail Cost
card, and the detail page gains a Usage & Cost section that breaks units and
cost down by counter, team and key. Units the cost map could not price are
called out next to the cost they are left out of.
Both pages now read /guardrails/usage/* through $api.useQuery so the rows are
typed from schema.d.ts; the hand-written PerformanceRow and the untyped fetch
helpers are gone. fetchClient resolves fetch per request so integration tests
that stub the global see typed-client calls too.
Refs LIT-5652
---
.../_components/GuardrailDetail.test.tsx | 59 +++--
.../_components/GuardrailDetail.tsx | 12 +-
.../GuardrailUsageBreakdown.test.tsx | 114 ++++++++++
.../_components/GuardrailUsageBreakdown.tsx | 159 ++++++++++++++
.../GuardrailsMonitorView.test.tsx | 20 +-
.../_components/GuardrailsOverview.test.tsx | 204 +++++++++++++-----
.../_components/GuardrailsOverview.tsx | 121 ++++++++---
.../page.integration.test.tsx | 27 ++-
.../guardrails/useGuardrailsUsage.test.ts | 81 +++++++
.../hooks/guardrails/useGuardrailsUsage.ts | 38 ++++
.../GuardrailsMonitor/MetricCard.tsx | 2 +-
.../components/GuardrailsMonitor/mockData.ts | 33 ---
.../GuardrailsMonitor/usageUnits.test.ts | 55 +++++
.../GuardrailsMonitor/usageUnits.ts | 21 ++
.../src/components/networking.tsx | 57 -----
ui/litellm-dashboard/src/lib/http/api.ts | 12 +-
16 files changed, 789 insertions(+), 226 deletions(-)
create mode 100644 ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
create mode 100644 ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
create mode 100644 ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
create mode 100644 ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
create mode 100644 ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
create mode 100644 ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
index c7567aa80bb..bbcb8138d52 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
@@ -2,12 +2,16 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
import userEvent from "@testing-library/user-event";
import { render, screen, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import type { GuardrailUsageDetail } from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
import { GuardrailDetail } from "./GuardrailDetail";
-const mockGetGuardrailsUsageDetail = vi.fn();
+const mockUseGuardrailsUsageDetail = vi.fn();
+vi.mock("@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage", () => ({
+ useGuardrailsUsageDetail: (...args: unknown[]) => mockUseGuardrailsUsageDetail(...args),
+}));
+
const mockGetGuardrailsUsageLogs = vi.fn();
vi.mock("@/components/networking", () => ({
- getGuardrailsUsageDetail: (...args: unknown[]) => mockGetGuardrailsUsageDetail(...args),
getGuardrailsUsageLogs: (...args: unknown[]) => mockGetGuardrailsUsageLogs(...args),
}));
@@ -19,7 +23,8 @@ vi.mock("./EvaluationSettingsModal", () => ({
EvaluationSettingsModal: ({ open }: { open: boolean }) => (open ?
: null),
}));
-const detail = {
+const detail: GuardrailUsageDetail = {
+ guardrail_id: "pii-detector",
guardrail_name: "pii-detector",
description: "Blocks personally identifiable information",
status: "warning",
@@ -29,12 +34,25 @@ const detail = {
failRate: 20,
avgScore: 0.4,
avgLatency: 180,
+ trend: "stable",
+ time_series: [],
+ usage_units: { sensitiveInformationPolicyUnits: 4 },
+ usage_units_daily: [],
+ usage_units_by_team: { "": { sensitiveInformationPolicyUnits: 4 } },
+ usage_units_by_key: { "hash-1": { sensitiveInformationPolicyUnits: 4 } },
+ cost: 0.0004,
+ cost_by_unit: { sensitiveInformationPolicyUnits: 0.0004 },
+ cost_by_team: { "": 0.0004 },
+ cost_by_key: { "hash-1": 0.0004 },
+ untracked_usage_units: {},
};
+const loaded = (data: GuardrailUsageDetail | undefined) => ({ data, isLoading: false, error: null });
+
const defaultProps = {
guardrailId: "pii-detector",
onBack: vi.fn(),
- accessToken: "test-token",
+ accessToken: "test-token" as string | null,
startDate: "2026-07-01",
endDate: "2026-07-24",
};
@@ -49,19 +67,19 @@ function renderDetail(props: Partial = {}) {
describe("GuardrailDetail", () => {
beforeEach(() => {
vi.clearAllMocks();
- mockGetGuardrailsUsageDetail.mockResolvedValue(detail);
+ mockUseGuardrailsUsageDetail.mockReturnValue(loaded(detail));
mockGetGuardrailsUsageLogs.mockResolvedValue({ logs: [], total: 0 });
});
it("should show a busy indicator while the detail request is in flight", () => {
- mockGetGuardrailsUsageDetail.mockReturnValue(new Promise(() => {}));
+ mockUseGuardrailsUsageDetail.mockReturnValue({ data: undefined, isLoading: true, error: null });
renderDetail();
expect(document.querySelector('[aria-busy="true"]')).toBeInTheDocument();
expect(screen.queryByText("pii-detector")).not.toBeInTheDocument();
});
it("should show an error message and a way back when the detail request fails", async () => {
- mockGetGuardrailsUsageDetail.mockRejectedValue(new Error("boom"));
+ mockUseGuardrailsUsageDetail.mockReturnValue({ data: undefined, isLoading: false, error: new Error("boom") });
renderDetail();
expect(await screen.findByText("Failed to load guardrail details.")).toBeInTheDocument();
expect(screen.getByRole("button", { name: /back to overview/i })).toBeInTheDocument();
@@ -69,14 +87,13 @@ describe("GuardrailDetail", () => {
it("should request the detail and the logs for the guardrail and date range", async () => {
renderDetail();
- await waitFor(() =>
- expect(mockGetGuardrailsUsageDetail).toHaveBeenCalledWith(
- "test-token",
- "pii-detector",
- "2026-07-01",
- "2026-07-24",
- ),
- );
+ expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith({
+ accessToken: "test-token",
+ guardrailId: "pii-detector",
+ startDate: "2026-07-01",
+ endDate: "2026-07-24",
+ });
+ await waitFor(() => expect(mockGetGuardrailsUsageLogs).toHaveBeenCalled());
expect(mockGetGuardrailsUsageLogs).toHaveBeenCalledWith(
"test-token",
expect.objectContaining({ guardrailId: "pii-detector", startDate: "2026-07-01", endDate: "2026-07-24" }),
@@ -100,11 +117,18 @@ describe("GuardrailDetail", () => {
});
it("should show a placeholder when no latency has been recorded", async () => {
- mockGetGuardrailsUsageDetail.mockResolvedValue({ ...detail, avgLatency: null });
+ mockUseGuardrailsUsageDetail.mockReturnValue(loaded({ ...detail, avgLatency: null }));
renderDetail();
expect(await screen.findByText("No data")).toBeInTheDocument();
});
+ it("should show the usage and cost breakdown for the guardrail on the overview tab", async () => {
+ renderDetail();
+ const section = await screen.findByRole("region", { name: "Usage and cost" });
+ expect(section).toHaveTextContent("$0.0004");
+ expect(section).toHaveTextContent("Sensitive Information Policy");
+ });
+
it("should call onBack when 'Back to Overview' is clicked", async () => {
const user = userEvent.setup();
const onBack = vi.fn();
@@ -138,8 +162,9 @@ describe("GuardrailDetail", () => {
});
it("should not request anything without an access token", () => {
+ mockUseGuardrailsUsageDetail.mockReturnValue(loaded(undefined));
renderDetail({ accessToken: null });
- expect(mockGetGuardrailsUsageDetail).not.toHaveBeenCalled();
+ expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith(expect.objectContaining({ accessToken: null }));
expect(mockGetGuardrailsUsageLogs).not.toHaveBeenCalled();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
index 253477ffeac..1e82f1fee85 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
@@ -1,13 +1,15 @@
import { useQuery } from "@tanstack/react-query";
import { ArrowLeft, Settings, Shield, TriangleAlert } from "lucide-react";
import React, { useMemo, useState } from "react";
-import { getGuardrailsUsageDetail, getGuardrailsUsageLogs } from "@/components/networking";
+import { getGuardrailsUsageLogs } from "@/components/networking";
+import { useGuardrailsUsageDetail } from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
import { StatusBadge, type StatusTone } from "@/components/shared/table_cells/status_badge";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
import { EvaluationSettingsModal } from "./EvaluationSettingsModal";
+import { GuardrailUsageBreakdown } from "./GuardrailUsageBreakdown";
import { LogViewer } from "@/components/GuardrailsMonitor/LogViewer";
import { MetricCard } from "@/components/GuardrailsMonitor/MetricCard";
import type { LogEntry } from "@/components/GuardrailsMonitor/mockData";
@@ -36,11 +38,7 @@ export function GuardrailDetail({ guardrailId, onBack, accessToken = null, start
data: detailData,
isLoading: detailLoading,
error: detailError,
- } = useQuery({
- queryKey: ["guardrails-usage-detail", guardrailId, startDate, endDate],
- queryFn: () => getGuardrailsUsageDetail(accessToken!, guardrailId, startDate, endDate),
- enabled: !!accessToken && !!guardrailId,
- });
+ } = useGuardrailsUsageDetail({ accessToken, guardrailId, startDate, endDate });
const { data: logsData, isLoading: logsLoading } = useQuery({
queryKey: ["guardrails-usage-logs", guardrailId, logsPage, logsPageSize],
queryFn: () =>
@@ -194,6 +192,8 @@ export function GuardrailDetail({ guardrailId, onBack, accessToken = null, start
/>
+ {detailData && }
+
{logViewer("all")}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
new file mode 100644
index 00000000000..3b24185f0b6
--- /dev/null
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
@@ -0,0 +1,114 @@
+import { render, screen, within } from "@testing-library/react";
+import { describe, expect, it } from "vitest";
+import type { GuardrailUsageDetail } from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
+import { GuardrailUsageBreakdown } from "./GuardrailUsageBreakdown";
+
+const detail: GuardrailUsageDetail = {
+ guardrail_id: "bedrock-pii-mask",
+ guardrail_name: "bedrock-pii-mask",
+ type: "pii",
+ provider: "Bedrock",
+ requestsEvaluated: 5,
+ failRate: 0,
+ avgScore: null,
+ avgLatency: 120,
+ status: "healthy",
+ trend: "stable",
+ description: null,
+ time_series: [],
+ usage_units: { contentPolicyUnits: 1000, sensitiveInformationPolicyUnits: 300, someFutureCounter: 7 },
+ usage_units_daily: [],
+ usage_units_by_team: {
+ "team-a": { contentPolicyUnits: 900, sensitiveInformationPolicyUnits: 300 },
+ "": { contentPolicyUnits: 100, someFutureCounter: 7 },
+ },
+ usage_units_by_key: {
+ "hash-1": { contentPolicyUnits: 1000, sensitiveInformationPolicyUnits: 300 },
+ "hash-2": { someFutureCounter: 7 },
+ },
+ cost: 0.18,
+ cost_by_unit: { contentPolicyUnits: 0.15, sensitiveInformationPolicyUnits: 0.03, someFutureCounter: null },
+ cost_by_team: { "team-a": 0.165, "": 0.015 },
+ cost_by_key: { "hash-1": 0.18, "hash-2": null },
+ untracked_usage_units: { someFutureCounter: 7 },
+};
+
+const rowNamed = (name: string) => screen.getByRole("row", { name: new RegExp(name) });
+
+describe("GuardrailUsageBreakdown", () => {
+ it("totals the units and the cost, and says how many units the cost leaves out", () => {
+ render( );
+
+ const cost = screen.getByRole("group", { name: "Cost" });
+ expect(cost).toHaveTextContent("$0.1800");
+ expect(cost).toHaveTextContent("7 units unpriced");
+
+ const units = screen.getByRole("group", { name: "Usage Units" });
+ expect(units).toHaveTextContent("1,307");
+ expect(units).toHaveTextContent("3 counters");
+ });
+
+ it("lists each counter with its units, cost and unpriced share", () => {
+ render( );
+
+ const content = rowNamed("Content Policy");
+ expect(within(content).getByText("1,000")).toBeInTheDocument();
+ expect(within(content).getByText("$0.1500")).toBeInTheDocument();
+ expect(within(content).getByText("—")).toBeInTheDocument();
+
+ const future = rowNamed("Some Future Counter");
+ expect(within(future).getByText("7", { selector: ".text-warning" })).toBeInTheDocument();
+ expect(within(future).getByText("—")).toBeInTheDocument();
+ });
+
+ it("breaks units and cost down by team and by key, naming the rows without one", () => {
+ render( );
+
+ expect(screen.getByRole("heading", { name: "By team" })).toBeInTheDocument();
+ expect(screen.getByRole("heading", { name: "By key" })).toBeInTheDocument();
+ const teamA = rowNamed("team-a");
+ expect(within(teamA).getByText("1,200")).toBeInTheDocument();
+ expect(within(teamA).getByText("$0.1650")).toBeInTheDocument();
+
+ const noTeam = rowNamed("No team");
+ expect(within(noTeam).getByText("107")).toBeInTheDocument();
+ expect(within(noTeam).getByText("$0.0150")).toBeInTheDocument();
+
+ const unpricedKey = rowNamed("hash-2");
+ expect(within(unpricedKey).getByText("7")).toBeInTheDocument();
+ expect(within(unpricedKey).getByText("—")).toBeInTheDocument();
+ });
+
+ it("orders teams and keys by units, largest first", () => {
+ render( );
+
+ const rows = screen.getAllByRole("row").map((row) => row.textContent ?? "");
+ expect(rows.findIndex((text) => text.includes("team-a"))).toBeLessThan(
+ rows.findIndex((text) => text.includes("No team")),
+ );
+ expect(rows.findIndex((text) => text.includes("hash-1"))).toBeLessThan(
+ rows.findIndex((text) => text.includes("hash-2")),
+ );
+ });
+
+ it("says so when the window has no billable units instead of rendering empty tables", () => {
+ render(
+ ,
+ );
+
+ expect(screen.getByText("No billable usage units were recorded in this period.")).toBeInTheDocument();
+ expect(screen.queryByRole("table")).not.toBeInTheDocument();
+ });
+});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
new file mode 100644
index 00000000000..1eaab86c506
--- /dev/null
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
@@ -0,0 +1,159 @@
+import type { ColumnDef } from "@tanstack/react-table";
+import { CircleDollarSign } from "lucide-react";
+import React from "react";
+import type { GuardrailUsageDetail } from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
+import { MetricCard } from "@/components/GuardrailsMonitor/MetricCard";
+import { counterLabel, formatCost, totalUnits, unpricedSummary } from "@/components/GuardrailsMonitor/usageUnits";
+import { DataTable } from "@/components/shared/DataTable";
+import { IdCell } from "@/components/shared/table_cells/id_cell";
+import { MoneyCell } from "@/components/shared/table_cells/money_cell";
+
+interface CounterRow {
+ counter: string;
+ units: number;
+ cost: number | null;
+ unpriced: number;
+}
+
+interface GroupRow {
+ id: string;
+ units: number;
+ cost: number | null;
+}
+
+const counterRows = (detail: GuardrailUsageDetail): CounterRow[] =>
+ Object.entries(detail.usage_units).map(([counter, units]) => ({
+ counter,
+ units,
+ cost: detail.cost_by_unit[counter] ?? null,
+ unpriced: detail.untracked_usage_units[counter] ?? 0,
+ }));
+
+const groupRows = (
+ unitsByGroup: GuardrailUsageDetail["usage_units_by_team"],
+ costByGroup: GuardrailUsageDetail["cost_by_team"],
+): GroupRow[] =>
+ Object.entries(unitsByGroup)
+ .map(([id, units]) => ({ id, units: totalUnits(units), cost: costByGroup[id] ?? null }))
+ .sort((a, b) => b.units - a.units);
+
+const counterColumns: ColumnDef[] = [
+ { header: "Counter", accessorKey: "counter", cell: ({ row }) => counterLabel(row.original.counter) },
+ {
+ header: "Units",
+ accessorKey: "units",
+ meta: { numeric: true },
+ cell: ({ row }) => row.original.units.toLocaleString(),
+ },
+ {
+ header: "Cost",
+ accessorKey: "cost",
+ meta: { numeric: true },
+ cell: ({ row }) => ,
+ },
+ {
+ header: "Unpriced Units",
+ accessorKey: "unpriced",
+ meta: { numeric: true },
+ cell: ({ row }) =>
+ row.original.unpriced > 0 ? (
+ {row.original.unpriced.toLocaleString()}
+ ) : (
+ —
+ ),
+ },
+];
+
+const groupColumns = (label: string, emptyLabel: string): ColumnDef[] => [
+ {
+ header: label,
+ accessorKey: "id",
+ cell: ({ row }) =>
+ row.original.id ? (
+
+ ) : (
+ {emptyLabel}
+ ),
+ },
+ {
+ header: "Units",
+ accessorKey: "units",
+ meta: { numeric: true },
+ cell: ({ row }) => row.original.units.toLocaleString(),
+ },
+ {
+ header: "Cost",
+ accessorKey: "cost",
+ meta: { numeric: true },
+ cell: ({ row }) => ,
+ },
+];
+
+const teamColumns = groupColumns("Team", "No team");
+const keyColumns = groupColumns("Key", "No key");
+
+const TableHeading = ({ title }: { title: string }) => (
+ {title}
+);
+
+export function GuardrailUsageBreakdown({ detail }: { detail: GuardrailUsageDetail }) {
+ const counters = counterRows(detail);
+ const unpriced = unpricedSummary(detail.untracked_usage_units);
+
+ return (
+
+
+
Usage & Cost
+
+ Billable units the provider reported for this guardrail and what LiteLLM priced them at
+
+
+
+ {counters.length === 0 ? (
+ No billable usage units were recorded in this period.
+ ) : (
+ <>
+
+ }
+ subtitle={unpriced ?? undefined}
+ />
+
+
+
+ row.counter}
+ size="compact"
+ toolbar={() => }
+ />
+
+
+
row.id || "no-team"}
+ size="compact"
+ toolbar={() => }
+ />
+ row.id || "no-key"}
+ size="compact"
+ toolbar={() => }
+ />
+
+ >
+ )}
+
+ );
+}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
index 9f27daab6b3..83b3a8f5d58 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
@@ -2,14 +2,15 @@ import { render, screen, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { describe, expect, it, vi } from "vitest";
import GuardrailsMonitorView from "./GuardrailsMonitorView";
-import * as networking from "@/components/networking";
vi.mock("@/components/networking", () => ({
- getGuardrailsUsageOverview: vi.fn(),
formatDate: vi.fn((d: Date) => d.toISOString().slice(0, 10)),
}));
-const mockGetGuardrailsUsageOverview = vi.mocked(networking.getGuardrailsUsageOverview);
+const mockUseGuardrailsUsageOverview = vi.fn();
+vi.mock("@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage", () => ({
+ useGuardrailsUsageOverview: (...args: unknown[]) => mockUseGuardrailsUsageOverview(...args),
+}));
function wrapper({ children }: { children: React.ReactNode }) {
const queryClient = new QueryClient({
@@ -22,23 +23,20 @@ function wrapper({ children }: { children: React.ReactNode }) {
describe("GuardrailsMonitorView", () => {
it("should render overview and fetch guardrails usage when accessToken is provided", async () => {
- mockGetGuardrailsUsageOverview.mockResolvedValue({
- rows: [],
- chart: [],
- totalRequests: 0,
- totalBlocked: 0,
- passRate: 100,
- });
+ mockUseGuardrailsUsageOverview.mockReturnValue({ data: undefined, isLoading: true, error: null });
render( , { wrapper });
expect(await screen.findByRole("heading", { name: /Guardrails Monitor/i })).toBeInTheDocument();
await waitFor(() => {
- expect(mockGetGuardrailsUsageOverview).toHaveBeenCalled();
+ expect(mockUseGuardrailsUsageOverview).toHaveBeenCalledWith(
+ expect.objectContaining({ accessToken: "test-token", startDate: expect.any(String) }),
+ );
});
});
it("should render without crashing when accessToken is null", async () => {
+ mockUseGuardrailsUsageOverview.mockReturnValue({ data: undefined, isLoading: false, error: null });
render( , { wrapper });
expect(await screen.findByRole("heading", { name: /Guardrails Monitor/i })).toBeInTheDocument();
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
index c62505cc74f..3a56667b156 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
@@ -1,12 +1,15 @@
-import { render, screen, waitFor } from "@testing-library/react";
-import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { render, screen, waitFor, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { beforeEach, describe, expect, it, vi } from "vitest";
-import * as networking from "@/components/networking";
+import type {
+ GuardrailUsageOverview,
+ GuardrailUsageOverviewRow,
+} from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
import { GuardrailsOverview } from "./GuardrailsOverview";
-vi.mock("@/components/networking", () => ({
- getGuardrailsUsageOverview: vi.fn(),
+const useGuardrailsUsageOverviewMock = vi.fn();
+vi.mock("@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage", () => ({
+ useGuardrailsUsageOverview: (...args: unknown[]) => useGuardrailsUsageOverviewMock(...args),
}));
vi.mock("./ScoreChart", () => ({
@@ -17,16 +20,63 @@ vi.mock("./EvaluationSettingsModal", () => ({
EvaluationSettingsModal: ({ open }: { open: boolean }) => (open ? Evaluation settings modal
: null),
}));
-const mockGetGuardrailsUsageOverview = vi.mocked(networking.getGuardrailsUsageOverview);
+const row = (overrides: Partial): GuardrailUsageOverviewRow => ({
+ id: "guardrail",
+ name: "Guardrail",
+ type: "content_filter",
+ provider: "LiteLLM",
+ requestsEvaluated: 0,
+ failRate: 0,
+ avgScore: null,
+ avgLatency: null,
+ status: "healthy",
+ trend: "stable",
+ usageUnits: {},
+ cost: null,
+ untrackedUsageUnits: {},
+ ...overrides,
+});
-function wrapper({ children }: { children: React.ReactNode }) {
- const queryClient = new QueryClient({
- defaultOptions: {
- queries: { retry: false },
- },
- });
- return {children} ;
-}
+const overview: GuardrailUsageOverview = {
+ rows: [
+ row({
+ id: "guardrail-low",
+ name: "Low Failure Guardrail",
+ requestsEvaluated: 1200,
+ failRate: 2.5,
+ avgLatency: 45,
+ trend: "down",
+ }),
+ row({
+ id: "guardrail-high",
+ name: "High Failure Guardrail",
+ provider: "Bedrock",
+ requestsEvaluated: 300,
+ failRate: 18,
+ status: "warning",
+ trend: "up",
+ usageUnits: { contentPolicyUnits: 1000, sensitiveInformationPolicyUnits: 250 },
+ cost: 0.15,
+ untrackedUsageUnits: { sensitiveInformationPolicyUnits: 250 },
+ }),
+ row({
+ id: "guardrail-free",
+ name: "Free Bedrock Guardrail",
+ provider: "Bedrock",
+ requestsEvaluated: 10,
+ failRate: 0,
+ usageUnits: { contentPolicyUnits: 40 },
+ cost: 0,
+ }),
+ ],
+ chart: [],
+ totalRequests: 1510,
+ totalBlocked: 84,
+ passRate: 94.4,
+ totalUsageUnits: { contentPolicyUnits: 1040, sensitiveInformationPolicyUnits: 250 },
+ totalCost: 0.15,
+ totalUntrackedUsageUnits: { sensitiveInformationPolicyUnits: 250 },
+};
function renderOverview(onSelectGuardrail = vi.fn()) {
return render(
@@ -36,41 +86,24 @@ function renderOverview(onSelectGuardrail = vi.fn()) {
endDate="2026-08-12"
onSelectGuardrail={onSelectGuardrail}
/>,
- { wrapper },
);
}
+const rowNamed = (name: string) => screen.getByRole("row", { name: new RegExp(name) });
+
describe("GuardrailsOverview", () => {
beforeEach(() => {
vi.clearAllMocks();
- mockGetGuardrailsUsageOverview.mockResolvedValue({
- rows: [
- {
- id: "guardrail-low",
- name: "Low Failure Guardrail",
- type: "content_filter",
- provider: "LiteLLM",
- requestsEvaluated: 1200,
- failRate: 2.5,
- avgLatency: 45,
- status: "healthy",
- trend: "down",
- },
- {
- id: "guardrail-high",
- name: "High Failure Guardrail",
- type: "content_filter",
- provider: "Bedrock",
- requestsEvaluated: 300,
- failRate: 18,
- status: "warning",
- trend: "up",
- },
- ],
- chart: [],
- totalRequests: 1500,
- totalBlocked: 84,
- passRate: 94.4,
+ useGuardrailsUsageOverviewMock.mockReturnValue({ data: overview, isLoading: false, error: null });
+ });
+
+ it("asks for the usage overview of the selected window", () => {
+ renderOverview();
+
+ expect(useGuardrailsUsageOverviewMock).toHaveBeenCalledWith({
+ accessToken: "test-token",
+ startDate: "2026-08-01",
+ endDate: "2026-08-12",
});
});
@@ -78,15 +111,7 @@ describe("GuardrailsOverview", () => {
const onSelectGuardrail = vi.fn();
const user = userEvent.setup();
- render(
- ,
- { wrapper },
- );
+ renderOverview(onSelectGuardrail);
expect(await screen.findByRole("columnheader", { name: "Guardrail" })).toBeInTheDocument();
expect(screen.getByRole("columnheader", { name: /Requests/ })).toBeInTheDocument();
@@ -105,6 +130,46 @@ describe("GuardrailsOverview", () => {
expect(onSelectGuardrail).toHaveBeenCalledWith("guardrail-low");
});
+ it("shows each guardrail's usage units and cost, marking the units cost leaves out", async () => {
+ renderOverview();
+
+ expect(await screen.findByRole("columnheader", { name: "Usage Units" })).toBeInTheDocument();
+ expect(screen.getByRole("columnheader", { name: /Cost/ })).toBeInTheDocument();
+
+ const priced = rowNamed("High Failure Guardrail");
+ expect(within(priced).getByText("1,250")).toBeInTheDocument();
+ expect(within(priced).getByText("$0.1500")).toBeInTheDocument();
+ expect(within(priced).getByLabelText("250 units unpriced")).toBeInTheDocument();
+
+ const free = rowNamed("Free Bedrock Guardrail");
+ expect(within(free).getByText("40")).toBeInTheDocument();
+ expect(within(free).getByText("$0.0000")).toBeInTheDocument();
+ expect(within(free).queryByLabelText(/unpriced/)).not.toBeInTheDocument();
+
+ const unmetered = rowNamed("Low Failure Guardrail");
+ expect(within(unmetered).getAllByText("—")).toHaveLength(2);
+ });
+
+ it("breaks the usage units down per counter on hover", async () => {
+ const user = userEvent.setup();
+ renderOverview();
+
+ await user.hover(within(rowNamed("High Failure Guardrail")).getByText("1,250"));
+
+ expect(await screen.findByText("Content Policy: 1,000")).toBeInTheDocument();
+ expect(screen.getByText("Sensitive Information Policy: 250")).toBeInTheDocument();
+ });
+
+ it("sorts by cost when its header is clicked", async () => {
+ const user = userEvent.setup();
+ renderOverview();
+
+ await user.click(await screen.findByRole("button", { name: /Cost/ }));
+
+ await waitFor(() => expect(screen.getAllByRole("row")[1]).toHaveTextContent("Low Failure Guardrail"));
+ expect(screen.getAllByRole("row")[3]).toHaveTextContent("High Failure Guardrail");
+ });
+
it("renders the page header and the export action", async () => {
renderOverview();
@@ -117,15 +182,36 @@ describe("GuardrailsOverview", () => {
it("renders every summary metric card", async () => {
renderOverview();
- expect(await screen.findByText("1,500")).toBeInTheDocument();
+ expect(await screen.findByText("1,510")).toBeInTheDocument();
expect(screen.getByText("Total Evaluations")).toBeInTheDocument();
expect(screen.getByText("Blocked Requests")).toBeInTheDocument();
expect(screen.getByText("84")).toBeInTheDocument();
expect(screen.getByText("Pass Rate")).toBeInTheDocument();
expect(screen.getByText("94.4%")).toBeInTheDocument();
- expect(screen.getByText("23ms")).toBeInTheDocument();
+ expect(screen.getByText("15ms")).toBeInTheDocument();
expect(screen.getByText("Active Guardrails")).toBeInTheDocument();
- expect(screen.getByText("2")).toBeInTheDocument();
+ expect(screen.getByText("3")).toBeInTheDocument();
+ });
+
+ it("totals guardrail cost across the window and says how many units it leaves out", async () => {
+ renderOverview();
+
+ const card = await screen.findByRole("group", { name: "Guardrail Cost" });
+ expect(card).toHaveTextContent("$0.1500");
+ expect(card).toHaveTextContent("250 units unpriced");
+ });
+
+ it("shows a dash for guardrail cost when nothing in the window was priced", async () => {
+ useGuardrailsUsageOverviewMock.mockReturnValue({
+ data: { ...overview, totalCost: null, totalUntrackedUsageUnits: {} },
+ isLoading: false,
+ error: null,
+ });
+ renderOverview();
+
+ const card = await screen.findByRole("group", { name: "Guardrail Cost" });
+ expect(card).toHaveTextContent("—");
+ expect(card).not.toHaveTextContent("unpriced");
});
it("renders the table toolbar heading and its description", async () => {
@@ -147,14 +233,18 @@ describe("GuardrailsOverview", () => {
});
it("marks the overview busy while the usage request is in flight", async () => {
- mockGetGuardrailsUsageOverview.mockReturnValue(new Promise(() => {}));
+ useGuardrailsUsageOverviewMock.mockReturnValue({ data: undefined, isLoading: true, error: null });
renderOverview();
await waitFor(() => expect(document.querySelector('[aria-busy="true"]')).toBeInTheDocument());
});
it("shows a failure message when the usage request rejects", async () => {
- mockGetGuardrailsUsageOverview.mockRejectedValue(new Error("network down"));
+ useGuardrailsUsageOverviewMock.mockReturnValue({
+ data: undefined,
+ isLoading: false,
+ error: new Error("network down"),
+ });
renderOverview();
expect(await screen.findByText("Failed to load data. Try again.")).toBeInTheDocument();
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
index 5bc9eb16cee..67630fef13a 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
@@ -1,10 +1,14 @@
-import { useQuery } from "@tanstack/react-query";
import type { ColumnDef, OnChangeFn, SortingState } from "@tanstack/react-table";
-import { Download, HeartPulse, Settings, TrendingUp, TriangleAlert } from "lucide-react";
+import { CircleDollarSign, Download, HeartPulse, Settings, TrendingUp, TriangleAlert } from "lucide-react";
import React, { useMemo, useState } from "react";
import { DataTable, DataTableSortHeader } from "@/components/shared/DataTable";
-import { getGuardrailsUsageOverview } from "@/components/networking";
-import { type PerformanceRow } from "@/components/GuardrailsMonitor/mockData";
+import { MoneyCell } from "@/components/shared/table_cells/money_cell";
+import { CellTooltip } from "@/components/shared/table_cells/cell_tooltip";
+import {
+ type GuardrailUsageOverviewRow,
+ useGuardrailsUsageOverview,
+} from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
+import { counterLabel, formatCost, totalUnits, unpricedSummary } from "@/components/GuardrailsMonitor/usageUnits";
import { Button } from "@/components/ui/button";
import { PageHeader } from "@/components/shared/PageHeader";
import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
@@ -20,7 +24,7 @@ interface GuardrailsOverviewProps {
dateRangeControl?: React.ReactNode;
}
-type SortKey = "failRate" | "requestsEvaluated" | "avgLatency" | "falsePositiveRate" | "falseNegativeRate";
+type SortKey = "failRate" | "requestsEvaluated" | "avgLatency" | "cost";
const providerColors: Record = {
Bedrock: "bg-warning/15 text-warning border-warning/20",
@@ -30,14 +34,48 @@ const providerColors: Record = {
Custom: "bg-muted text-muted-foreground border-border",
};
-function computeMetricsFromRows(data: PerformanceRow[]) {
- const totalRequests = data.reduce((sum, r) => sum + r.requestsEvaluated, 0);
- const totalBlocked = data.reduce((sum, r) => sum + Math.round((r.requestsEvaluated * r.failRate) / 100), 0);
- const passRate = totalRequests > 0 ? ((1 - totalBlocked / totalRequests) * 100).toFixed(1) : "0";
- const withLat = data.filter((r) => r.avgLatency != null);
- const avgLatency =
- withLat.length > 0 ? Math.round(withLat.reduce((sum, r) => sum + (r.avgLatency ?? 0), 0) / withLat.length) : 0;
- return { totalRequests, totalBlocked, passRate, avgLatency, count: data.length };
+const EMPTY_METRICS = {
+ totalRequests: 0,
+ totalBlocked: 0,
+ passRate: "0",
+ avgLatency: 0,
+ count: 0,
+ totalCost: null as number | null,
+ unpriced: null as string | null,
+};
+
+function UsageUnitsCell({ units }: { units: GuardrailUsageOverviewRow["usageUnits"] }) {
+ const counters = Object.entries(units);
+ if (counters.length === 0) return — ;
+ return (
+
+ {counters.map(([counter, n]) => (
+
+ {counterLabel(counter)}: {n.toLocaleString()}
+
+ ))}
+
+ }
+ trigger={{totalUnits(units).toLocaleString()} }
+ />
+ );
+}
+
+function CostCell({ row }: { row: GuardrailUsageOverviewRow }) {
+ const unpriced = unpricedSummary(row.untrackedUsageUnits);
+ return (
+
+ {unpriced && (
+ }
+ />
+ )}
+
+
+ );
}
export function GuardrailsOverview({
@@ -55,26 +93,22 @@ export function GuardrailsOverview({
data: guardrailsData,
isLoading: guardrailsLoading,
error: guardrailsError,
- } = useQuery({
- queryKey: ["guardrails-usage-overview", startDate, endDate],
- queryFn: () => getGuardrailsUsageOverview(accessToken!, startDate, endDate),
- enabled: !!accessToken,
- });
+ } = useGuardrailsUsageOverview({ accessToken, startDate, endDate });
- const activeData: PerformanceRow[] = guardrailsData?.rows ?? [];
+ const activeData: GuardrailUsageOverviewRow[] = useMemo(() => guardrailsData?.rows ?? [], [guardrailsData]);
const metrics = useMemo(() => {
- if (guardrailsData) {
- return {
- totalRequests: guardrailsData.totalRequests ?? 0,
- totalBlocked: guardrailsData.totalBlocked ?? 0,
- passRate: String(guardrailsData.passRate ?? 0),
- avgLatency: activeData.length
- ? Math.round(activeData.reduce((s, r) => s + (r.avgLatency ?? 0), 0) / activeData.length)
- : 0,
- count: activeData.length,
- };
- }
- return computeMetricsFromRows(activeData);
+ if (!guardrailsData) return EMPTY_METRICS;
+ return {
+ totalRequests: guardrailsData.totalRequests,
+ totalBlocked: guardrailsData.totalBlocked,
+ passRate: String(guardrailsData.passRate),
+ avgLatency: activeData.length
+ ? Math.round(activeData.reduce((s, r) => s + (r.avgLatency ?? 0), 0) / activeData.length)
+ : 0,
+ count: activeData.length,
+ totalCost: guardrailsData.totalCost,
+ unpriced: unpricedSummary(guardrailsData.totalUntrackedUsageUnits),
+ };
}, [guardrailsData, activeData]);
const chartData = guardrailsData?.chart;
const sorted = useMemo(() => {
@@ -88,7 +122,7 @@ export function GuardrailsOverview({
const isLoading = guardrailsLoading;
const error = guardrailsError;
- const columns: ColumnDef[] = [
+ const columns: ColumnDef[] = [
{
header: "Guardrail",
accessorKey: "name",
@@ -166,6 +200,20 @@ export function GuardrailsOverview({
),
},
+ {
+ header: "Usage Units",
+ accessorKey: "usageUnits",
+ enableSorting: false,
+ meta: { numeric: true },
+ cell: ({ row }) => ,
+ },
+ {
+ header: ({ column }) => ,
+ accessorKey: "cost",
+ meta: { numeric: true },
+ sortDescFirst: false,
+ cell: ({ row }) => ,
+ },
{
header: "Status",
accessorKey: "status",
@@ -187,7 +235,7 @@ export function GuardrailsOverview({
},
];
- const sortableKeys: SortKey[] = ["failRate", "requestsEvaluated", "avgLatency"];
+ const sortableKeys: SortKey[] = ["failRate", "requestsEvaluated", "avgLatency", "cost"];
const sorting = useMemo(() => [{ id: sortBy, desc: sortDir === "desc" }], [sortBy, sortDir]);
const handleSortingChange: OnChangeFn = (updater) => {
const nextSorting = typeof updater === "function" ? updater(sorting) : updater;
@@ -236,6 +284,13 @@ export function GuardrailsOverview({
metrics.avgLatency > 150 ? "text-destructive" : metrics.avgLatency > 50 ? "text-warning" : "text-success"
}
/>
+ }
+ subtitle={metrics.unpriced ?? undefined}
+ />
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.integration.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.integration.test.tsx
index fb521c0b8a3..ce8fda0ea69 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.integration.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/page.integration.test.tsx
@@ -11,7 +11,23 @@ vi.mock("@/app/(dashboard)/hooks/useAuthorized", () => ({
const fetchMock = vi.fn();
-const requestedUrls = () => fetchMock.mock.calls.map(([url]) => String(url));
+const requestUrl = (input: RequestInfo | URL) => (input instanceof Request ? input.url : String(input));
+
+const requestedUrls = () => fetchMock.mock.calls.map(([input]) => requestUrl(input));
+
+const emptyOverview = {
+ rows: [],
+ chart: [],
+ totalRequests: 0,
+ totalBlocked: 0,
+ passRate: 100,
+ totalUsageUnits: {},
+ totalCost: null,
+ totalUntrackedUsageUnits: {},
+};
+
+const jsonResponse = (body: unknown) =>
+ new Response(JSON.stringify(body), { status: 200, headers: { "Content-Type": "application/json" } });
const renderAs = (userRole: string) => {
useAuthorizedMock.mockReturnValue({ accessToken: "sk-test", userId: "u1", userRole });
@@ -25,12 +41,9 @@ describe("Guardrails Monitor page access by role", () => {
beforeEach(() => {
testQueryClient.clear();
vi.clearAllMocks();
- fetchMock.mockResolvedValue({
- ok: true,
- status: 200,
- statusText: "OK",
- json: async () => ({ rows: [], chart: [], totalRequests: 0, totalBlocked: 0, passRate: 100 }),
- });
+ fetchMock.mockImplementation(async (input: RequestInfo | URL) =>
+ jsonResponse(requestUrl(input).includes("/guardrails/usage/overview") ? emptyOverview : []),
+ );
vi.stubGlobal("fetch", fetchMock);
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
new file mode 100644
index 00000000000..f0b2709484d
--- /dev/null
+++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
@@ -0,0 +1,81 @@
+import { renderHook } from "@testing-library/react";
+import { beforeEach, describe, expect, it, vi } from "vitest";
+import { useGuardrailsUsageDetail, useGuardrailsUsageOverview } from "./useGuardrailsUsage";
+
+const useQueryMock = vi.fn();
+vi.mock("@/lib/http/api", () => ({
+ $api: { useQuery: (...args: unknown[]) => useQueryMock(...args) },
+}));
+
+const lastCall = () => {
+ const calls = useQueryMock.mock.calls;
+ return calls[calls.length - 1] as [string, string, unknown, { enabled: boolean }];
+};
+
+describe("useGuardrailsUsageOverview", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ useQueryMock.mockReturnValue({ data: undefined });
+ });
+
+ it("queries GET /guardrails/usage/overview with the window as query params", () => {
+ renderHook(() => useGuardrailsUsageOverview({ accessToken: "sk", startDate: "2026-09-01", endDate: "2026-09-04" }));
+
+ expect(lastCall().slice(0, 3)).toEqual([
+ "get",
+ "/guardrails/usage/overview",
+ { params: { query: { start_date: "2026-09-01", end_date: "2026-09-04" } } },
+ ]);
+ expect(lastCall()[3].enabled).toBe(true);
+ });
+
+ it("omits blank dates so the proxy applies its default window", () => {
+ renderHook(() => useGuardrailsUsageOverview({ accessToken: "sk", startDate: "", endDate: "" }));
+
+ expect(lastCall()[2]).toEqual({ params: { query: { start_date: undefined, end_date: undefined } } });
+ });
+
+ it("stays disabled without an access token", () => {
+ renderHook(() => useGuardrailsUsageOverview({ accessToken: null, startDate: "2026-09-01", endDate: "2026-09-04" }));
+
+ expect(lastCall()[3].enabled).toBe(false);
+ });
+});
+
+describe("useGuardrailsUsageDetail", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ useQueryMock.mockReturnValue({ data: undefined });
+ });
+
+ it("queries GET /guardrails/usage/detail/{guardrail_id} with the id as a path param", () => {
+ renderHook(() =>
+ useGuardrailsUsageDetail({
+ accessToken: "sk",
+ guardrailId: "bedrock-pii-mask",
+ startDate: "2026-09-01",
+ endDate: "2026-09-04",
+ }),
+ );
+
+ expect(lastCall().slice(0, 3)).toEqual([
+ "get",
+ "/guardrails/usage/detail/{guardrail_id}",
+ {
+ params: {
+ path: { guardrail_id: "bedrock-pii-mask" },
+ query: { start_date: "2026-09-01", end_date: "2026-09-04" },
+ },
+ },
+ ]);
+ expect(lastCall()[3].enabled).toBe(true);
+ });
+
+ it("stays disabled without a guardrail id", () => {
+ renderHook(() =>
+ useGuardrailsUsageDetail({ accessToken: "sk", guardrailId: "", startDate: "2026-09-01", endDate: "2026-09-04" }),
+ );
+
+ expect(lastCall()[3].enabled).toBe(false);
+ });
+});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
new file mode 100644
index 00000000000..dc7f58fbc8f
--- /dev/null
+++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
@@ -0,0 +1,38 @@
+import { $api } from "@/lib/http/api";
+import type { components } from "@/lib/http/schema";
+
+export type GuardrailUsageOverview = components["schemas"]["UsageOverviewResponse"];
+export type GuardrailUsageOverviewRow = components["schemas"]["UsageOverviewRow"];
+export type GuardrailUsageDetail = components["schemas"]["UsageDetailResponse"];
+
+export interface GuardrailsUsageWindow {
+ accessToken: string | null;
+ startDate: string;
+ endDate: string;
+}
+
+const dateQuery = (startDate: string, endDate: string) => ({
+ start_date: startDate || undefined,
+ end_date: endDate || undefined,
+});
+
+export const useGuardrailsUsageOverview = ({ accessToken, startDate, endDate }: GuardrailsUsageWindow) =>
+ $api.useQuery(
+ "get",
+ "/guardrails/usage/overview",
+ { params: { query: dateQuery(startDate, endDate) } },
+ { enabled: Boolean(accessToken) },
+ );
+
+export const useGuardrailsUsageDetail = ({
+ accessToken,
+ guardrailId,
+ startDate,
+ endDate,
+}: GuardrailsUsageWindow & { guardrailId: string }) =>
+ $api.useQuery(
+ "get",
+ "/guardrails/usage/detail/{guardrail_id}",
+ { params: { path: { guardrail_id: guardrailId }, query: dateQuery(startDate, endDate) } },
+ { enabled: Boolean(accessToken && guardrailId) },
+ );
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx b/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
index d5d249e4799..c0b5e0a50d1 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
@@ -10,7 +10,7 @@ interface MetricCardProps {
export function MetricCard({ label, value, valueColor = "text-foreground", icon, subtitle }: MetricCardProps) {
return (
-
+
{label}
{icon &&
{icon} }
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/mockData.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/mockData.ts
index 7d99ebe7c44..2b42f7907f1 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/mockData.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/mockData.ts
@@ -2,39 +2,6 @@
* Types for Guardrails Monitor dashboard (data from usage API).
*/
-export interface PerformanceRow {
- id: string;
- name: string;
- type: string;
- provider: string;
- requestsEvaluated: number;
- failRate: number;
- avgScore?: number;
- avgLatency?: number;
- p95Latency?: number;
- falsePositiveRate?: number;
- falseNegativeRate?: number;
- status: "healthy" | "warning" | "critical";
- trend: "up" | "down" | "stable";
-}
-
-export interface GuardrailDetailRecord {
- name: string;
- type: string;
- provider: string;
- requestsEvaluated: number;
- failRate: number;
- avgScore?: number;
- avgLatency?: number;
- p95Latency?: number;
- falsePositiveRate?: number;
- falsePositiveCount?: number;
- falseNegativeRate?: number;
- falseNegativeCount?: number;
- status: string;
- description: string;
-}
-
export interface LogEntry {
id: string;
timestamp: string;
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
new file mode 100644
index 00000000000..29362cc3701
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
@@ -0,0 +1,55 @@
+import { describe, expect, it } from "vitest";
+import { counterLabel, formatCost, totalUnits, unpricedSummary } from "./usageUnits";
+
+describe("formatCost", () => {
+ it("renders a dash when nothing was priced", () => {
+ expect(formatCost(null)).toBe("—");
+ expect(formatCost(undefined)).toBe("—");
+ });
+
+ it("keeps an explicit zero as a real price rather than a dash", () => {
+ expect(formatCost(0)).toBe("$0.0000");
+ });
+
+ it("shows four decimals for the sub-cent amounts guardrail units cost", () => {
+ expect(formatCost(0.0003)).toBe("$0.0003");
+ expect(formatCost(12.5)).toBe("$12.5000");
+ });
+
+ it("flags amounts below the displayed precision instead of rounding them to zero", () => {
+ expect(formatCost(0.00001)).toBe("< $0.0001");
+ });
+});
+
+describe("totalUnits", () => {
+ it("sums every counter", () => {
+ expect(totalUnits({ contentPolicyUnits: 3, sensitiveInformationPolicyUnits: 4 })).toBe(7);
+ });
+
+ it("is zero for no counters", () => {
+ expect(totalUnits({})).toBe(0);
+ });
+});
+
+describe("counterLabel", () => {
+ it("turns a Bedrock counter name into words without the Units suffix", () => {
+ expect(counterLabel("sensitiveInformationPolicyUnits")).toBe("Sensitive Information Policy");
+ expect(counterLabel("contentPolicyUnits")).toBe("Content Policy");
+ });
+
+ it("leaves a name it cannot split alone apart from capitalising it", () => {
+ expect(counterLabel("units")).toBe("Units");
+ });
+});
+
+describe("unpricedSummary", () => {
+ it("is null when every unit was priced", () => {
+ expect(unpricedSummary({})).toBeNull();
+ expect(unpricedSummary({ contentPolicyUnits: 0 })).toBeNull();
+ });
+
+ it("counts unpriced units across counters with a pluralised label", () => {
+ expect(unpricedSummary({ contentPolicyUnits: 1200, someFutureCounter: 34 })).toBe("1,234 units unpriced");
+ expect(unpricedSummary({ someFutureCounter: 1 })).toBe("1 unit unpriced");
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
new file mode 100644
index 00000000000..f3a5e9d7140
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
@@ -0,0 +1,21 @@
+import { formatNumberWithCommas, getSpendString } from "@/utils/dataUtils";
+
+export type UsageUnits = Readonly
>;
+
+export const formatCost = (cost: number | null | undefined): string => {
+ if (cost == null) return "—";
+ return cost === 0 ? `$${formatNumberWithCommas(0, 4)}` : getSpendString(cost, 4);
+};
+
+export const totalUnits = (units: UsageUnits): number => Object.values(units).reduce((sum, n) => sum + n, 0);
+
+export const counterLabel = (counter: string): string =>
+ counter
+ .replace(/Units$/, "")
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
+ .replace(/^./, (c) => c.toUpperCase());
+
+export const unpricedSummary = (untracked: UsageUnits): string | null => {
+ const total = totalUnits(untracked);
+ return total > 0 ? `${total.toLocaleString()} ${total === 1 ? "unit" : "units"} unpriced` : null;
+};
diff --git a/ui/litellm-dashboard/src/components/networking.tsx b/ui/litellm-dashboard/src/components/networking.tsx
index e06d457cfa9..ccf4bd748e5 100644
--- a/ui/litellm-dashboard/src/components/networking.tsx
+++ b/ui/litellm-dashboard/src/components/networking.tsx
@@ -3956,63 +3956,6 @@ export const rejectGuardrailSubmission = async (
};
// Guardrails / Policies usage (dashboard)
-export const getGuardrailsUsageOverview = async (accessToken: string, startDate?: string, endDate?: string) => {
- try {
- let url = proxyBaseUrl ? `${proxyBaseUrl}/guardrails/usage/overview` : `/guardrails/usage/overview`;
- const params = new URLSearchParams();
- if (startDate) params.append("start_date", startDate);
- if (endDate) params.append("end_date", endDate);
- if (params.toString()) url += `?${params.toString()}`;
- const response = await fetch(url, {
- method: "GET",
- headers: {
- [globalLitellmHeaderName]: `Bearer ${accessToken}`,
- "Content-Type": "application/json",
- },
- });
- if (!response.ok) {
- const errorData = await response.json();
- throw new Error(deriveErrorMessage(errorData));
- }
- return response.json();
- } catch (error) {
- console.error("Failed to get guardrails usage overview:", error);
- throw error;
- }
-};
-
-export const getGuardrailsUsageDetail = async (
- accessToken: string,
- guardrailId: string,
- startDate?: string,
- endDate?: string,
-) => {
- try {
- let url = proxyBaseUrl
- ? `${proxyBaseUrl}/guardrails/usage/detail/${encodeURIComponent(guardrailId)}`
- : `/guardrails/usage/detail/${encodeURIComponent(guardrailId)}`;
- const params = new URLSearchParams();
- if (startDate) params.append("start_date", startDate);
- if (endDate) params.append("end_date", endDate);
- if (params.toString()) url += `?${params.toString()}`;
- const response = await fetch(url, {
- method: "GET",
- headers: {
- [globalLitellmHeaderName]: `Bearer ${accessToken}`,
- "Content-Type": "application/json",
- },
- });
- if (!response.ok) {
- const errorData = await response.json();
- throw new Error(deriveErrorMessage(errorData));
- }
- return response.json();
- } catch (error) {
- console.error("Failed to get guardrails usage detail:", error);
- throw error;
- }
-};
-
export const getGuardrailsUsageLogs = async (
accessToken: string,
options: {
diff --git a/ui/litellm-dashboard/src/lib/http/api.ts b/ui/litellm-dashboard/src/lib/http/api.ts
index 508a27db78d..904e4e4f3ab 100644
--- a/ui/litellm-dashboard/src/lib/http/api.ts
+++ b/ui/litellm-dashboard/src/lib/http/api.ts
@@ -43,11 +43,15 @@ const middleware: Middleware = {
*
* The base URL is injected, not fixed at import: every request is built against
* whatever registerBaseUrlGetter supplies at call time (a split-origin proxy or
- * worker URL), falling back to the current origin. The middleware injects the
- * auth header and maps non-2xx responses to ApiError so query functions can just
- * read `.data`.
+ * worker URL), falling back to the current origin. `fetch` is looked up per
+ * request for the same reason, so a test that stubs the global sees these calls
+ * too. The middleware injects the auth header and maps non-2xx responses to
+ * ApiError so query functions can just read `.data`.
*/
-export const fetchClient = createFetchClient({ Request: BaseAwareRequest });
+export const fetchClient = createFetchClient({
+ Request: BaseAwareRequest,
+ fetch: (request) => globalThis.fetch(request),
+});
fetchClient.use(middleware);
/**
From 1d375d8ada91eb6f6aeceb8af8bc649a031a5012 Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Fri, 4 Sep 2026 19:46:14 -0700
Subject: [PATCH 02/35] fix(guardrails): flag unpriced units per team and key,
sort unknown cost last
The detail endpoint now returns untracked_usage_units_by_team and
untracked_usage_units_by_key next to the cost breakdowns, and the By team and
By key tables show them in an Unpriced Units column, so a row that pairs its
total units with a partial cost says how many units that cost leaves out.
The overview comparator no longer treats a missing cost as zero: guardrails
with no known cost sort last in both directions instead of mixing in with
genuinely free ones.
Refs LIT-5652
---
litellm/proxy/_lazy_openapi_snapshot.json | 24 ++++++++++-
litellm/proxy/guardrails/usage_endpoints.py | 20 ++++++++--
.../proxy/guardrails/test_usage_endpoints.py | 8 ++++
.../_components/GuardrailDetail.test.tsx | 2 +
.../GuardrailUsageBreakdown.test.tsx | 11 ++++-
.../_components/GuardrailUsageBreakdown.tsx | 40 ++++++++++++-------
.../_components/GuardrailsOverview.test.tsx | 16 ++++++--
.../_components/GuardrailsOverview.tsx | 9 +++--
ui/litellm-dashboard/src/lib/http/schema.d.ts | 12 ++++++
9 files changed, 114 insertions(+), 28 deletions(-)
diff --git a/litellm/proxy/_lazy_openapi_snapshot.json b/litellm/proxy/_lazy_openapi_snapshot.json
index c24eea968f8..ddf6a59bea7 100644
--- a/litellm/proxy/_lazy_openapi_snapshot.json
+++ b/litellm/proxy/_lazy_openapi_snapshot.json
@@ -13218,6 +13218,26 @@
"title": "Untracked Usage Units",
"type": "object"
},
+ "untracked_usage_units_by_key": {
+ "additionalProperties": {
+ "additionalProperties": {
+ "type": "integer"
+ },
+ "type": "object"
+ },
+ "title": "Untracked Usage Units By Key",
+ "type": "object"
+ },
+ "untracked_usage_units_by_team": {
+ "additionalProperties": {
+ "additionalProperties": {
+ "type": "integer"
+ },
+ "type": "object"
+ },
+ "title": "Untracked Usage Units By Team",
+ "type": "object"
+ },
"usage_units": {
"additionalProperties": {
"type": "integer"
@@ -13274,7 +13294,9 @@
"cost_by_unit",
"cost_by_team",
"cost_by_key",
- "untracked_usage_units"
+ "untracked_usage_units",
+ "untracked_usage_units_by_team",
+ "untracked_usage_units_by_key"
],
"title": "UsageDetailResponse",
"type": "object"
diff --git a/litellm/proxy/guardrails/usage_endpoints.py b/litellm/proxy/guardrails/usage_endpoints.py
index 0390a2b5013..d3bd09f7d27 100644
--- a/litellm/proxy/guardrails/usage_endpoints.py
+++ b/litellm/proxy/guardrails/usage_endpoints.py
@@ -156,6 +156,14 @@ def _counter_name(row: "prisma_models.LiteLLM_DailyGuardrailUsageUnits") -> str:
return row.usage_unit
+def _team_of(row: "prisma_models.LiteLLM_DailyGuardrailUsageUnits") -> str:
+ return row.team_id
+
+
+def _key_of(row: "prisma_models.LiteLLM_DailyGuardrailUsageUnits") -> str:
+ return row.api_key
+
+
def _row_untracked_units(row: "prisma_models.LiteLLM_DailyGuardrailUsageUnits") -> int:
"""A row written before the cost column carries NULL cost and is untracked in full."""
return int(row.units) if row.cost is None else int(row.untracked_units)
@@ -308,6 +316,8 @@ class UsageDetailResponse(BaseModel):
cost_by_team: Mapping[str, float | None]
cost_by_key: Mapping[str, float | None]
untracked_usage_units: Mapping[str, int]
+ untracked_usage_units_by_team: Mapping[str, Mapping[str, int]]
+ untracked_usage_units_by_key: Mapping[str, Mapping[str, int]]
class UsageLogEntry(BaseModel):
@@ -705,13 +715,15 @@ async def guardrails_usage_detail(
time_series=time_series,
usage_units=_sum_counter_units(units_rows),
usage_units_daily=units_daily,
- usage_units_by_team=_by(units_rows, lambda r: r.team_id, _sum_counter_units),
- usage_units_by_key=_by(units_rows, lambda r: r.api_key, _sum_counter_units),
+ usage_units_by_team=_by(units_rows, _team_of, _sum_counter_units),
+ usage_units_by_key=_by(units_rows, _key_of, _sum_counter_units),
cost=_sum_tracked_cost(units_rows),
cost_by_unit=_by(units_rows, _counter_name, _sum_tracked_cost),
- cost_by_team=_by(units_rows, lambda r: r.team_id, _sum_tracked_cost),
- cost_by_key=_by(units_rows, lambda r: r.api_key, _sum_tracked_cost),
+ cost_by_team=_by(units_rows, _team_of, _sum_tracked_cost),
+ cost_by_key=_by(units_rows, _key_of, _sum_tracked_cost),
untracked_usage_units=_sum_untracked_units(units_rows),
+ untracked_usage_units_by_team=_by(units_rows, _team_of, _sum_untracked_units),
+ untracked_usage_units_by_key=_by(units_rows, _key_of, _sum_untracked_units),
)
diff --git a/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py b/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py
index ebb2be6edc2..1ff33c76035 100644
--- a/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py
+++ b/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py
@@ -430,6 +430,13 @@ async def test_detail_breaks_cost_down_by_unit_day_team_and_key():
assert resp.cost_by_team.keys() == resp.usage_units_by_team.keys()
assert resp.cost_by_key.keys() == resp.usage_units_by_key.keys()
assert resp.untracked_usage_units == {"contentPolicyUnits": 50, "topicPolicyUnits": 10}
+ assert resp.untracked_usage_units_by_team == {"team-a": {"topicPolicyUnits": 10}, "": {"contentPolicyUnits": 50}}
+ assert resp.untracked_usage_units_by_key == {
+ "hash-1": {"topicPolicyUnits": 10},
+ "hash-2": {"contentPolicyUnits": 50},
+ }
+ assert resp.untracked_usage_units_by_team.keys() == resp.usage_units_by_team.keys()
+ assert resp.untracked_usage_units_by_key.keys() == resp.usage_units_by_key.keys()
@pytest.mark.asyncio
@@ -451,6 +458,7 @@ async def test_detail_degrades_units_to_empty_when_units_table_is_missing():
)
assert (resp.cost, resp.cost_by_unit, resp.cost_by_team, resp.cost_by_key) == (None, {}, {}, {})
assert resp.untracked_usage_units == {}
+ assert (resp.untracked_usage_units_by_team, resp.untracked_usage_units_by_key) == ({}, {})
# ---- logs -------------------------------------------------------------------
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
index bbcb8138d52..3d00e29245d 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
@@ -45,6 +45,8 @@ const detail: GuardrailUsageDetail = {
cost_by_team: { "": 0.0004 },
cost_by_key: { "hash-1": 0.0004 },
untracked_usage_units: {},
+ untracked_usage_units_by_team: {},
+ untracked_usage_units_by_key: {},
};
const loaded = (data: GuardrailUsageDetail | undefined) => ({ data, isLoading: false, error: null });
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
index 3b24185f0b6..7929b97b000 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
@@ -31,6 +31,8 @@ const detail: GuardrailUsageDetail = {
cost_by_team: { "team-a": 0.165, "": 0.015 },
cost_by_key: { "hash-1": 0.18, "hash-2": null },
untracked_usage_units: { someFutureCounter: 7 },
+ untracked_usage_units_by_team: { "team-a": {}, "": { someFutureCounter: 7 } },
+ untracked_usage_units_by_key: { "hash-1": {}, "hash-2": { someFutureCounter: 7 } },
};
const rowNamed = (name: string) => screen.getByRole("row", { name: new RegExp(name) });
@@ -61,7 +63,7 @@ describe("GuardrailUsageBreakdown", () => {
expect(within(future).getByText("—")).toBeInTheDocument();
});
- it("breaks units and cost down by team and by key, naming the rows without one", () => {
+ it("breaks units and cost down by team and by key, flagging the unpriced share of each row", () => {
render( );
expect(screen.getByRole("heading", { name: "By team" })).toBeInTheDocument();
@@ -69,14 +71,17 @@ describe("GuardrailUsageBreakdown", () => {
const teamA = rowNamed("team-a");
expect(within(teamA).getByText("1,200")).toBeInTheDocument();
expect(within(teamA).getByText("$0.1650")).toBeInTheDocument();
+ expect(within(teamA).getByText("—")).toBeInTheDocument();
+ expect(within(teamA).queryByText("7")).not.toBeInTheDocument();
const noTeam = rowNamed("No team");
expect(within(noTeam).getByText("107")).toBeInTheDocument();
expect(within(noTeam).getByText("$0.0150")).toBeInTheDocument();
+ expect(within(noTeam).getByText("7", { selector: ".text-warning" })).toBeInTheDocument();
const unpricedKey = rowNamed("hash-2");
- expect(within(unpricedKey).getByText("7")).toBeInTheDocument();
expect(within(unpricedKey).getByText("—")).toBeInTheDocument();
+ expect(within(unpricedKey).getByText("7", { selector: ".text-warning" })).toBeInTheDocument();
});
it("orders teams and keys by units, largest first", () => {
@@ -104,6 +109,8 @@ describe("GuardrailUsageBreakdown", () => {
cost_by_team: {},
cost_by_key: {},
untracked_usage_units: {},
+ untracked_usage_units_by_team: {},
+ untracked_usage_units_by_key: {},
}}
/>,
);
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
index 1eaab86c506..6e8b725aa2e 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
@@ -19,6 +19,7 @@ interface GroupRow {
id: string;
units: number;
cost: number | null;
+ unpriced: number;
}
const counterRows = (detail: GuardrailUsageDetail): CounterRow[] =>
@@ -32,11 +33,31 @@ const counterRows = (detail: GuardrailUsageDetail): CounterRow[] =>
const groupRows = (
unitsByGroup: GuardrailUsageDetail["usage_units_by_team"],
costByGroup: GuardrailUsageDetail["cost_by_team"],
+ untrackedByGroup: GuardrailUsageDetail["untracked_usage_units_by_team"],
): GroupRow[] =>
Object.entries(unitsByGroup)
- .map(([id, units]) => ({ id, units: totalUnits(units), cost: costByGroup[id] ?? null }))
+ .map(([id, units]) => ({
+ id,
+ units: totalUnits(units),
+ cost: costByGroup[id] ?? null,
+ unpriced: totalUnits(untrackedByGroup[id] ?? {}),
+ }))
.sort((a, b) => b.units - a.units);
+const UnpricedUnitsCell = ({ unpriced }: { unpriced: number }) =>
+ unpriced > 0 ? (
+ {unpriced.toLocaleString()}
+ ) : (
+ —
+ );
+
+const unpricedColumn = (): ColumnDef => ({
+ header: "Unpriced Units",
+ accessorKey: "unpriced",
+ meta: { numeric: true },
+ cell: ({ row }) => ,
+});
+
const counterColumns: ColumnDef[] = [
{ header: "Counter", accessorKey: "counter", cell: ({ row }) => counterLabel(row.original.counter) },
{
@@ -51,17 +72,7 @@ const counterColumns: ColumnDef[] = [
meta: { numeric: true },
cell: ({ row }) => ,
},
- {
- header: "Unpriced Units",
- accessorKey: "unpriced",
- meta: { numeric: true },
- cell: ({ row }) =>
- row.original.unpriced > 0 ? (
- {row.original.unpriced.toLocaleString()}
- ) : (
- —
- ),
- },
+ unpricedColumn(),
];
const groupColumns = (label: string, emptyLabel: string): ColumnDef[] => [
@@ -87,6 +98,7 @@ const groupColumns = (label: string, emptyLabel: string): ColumnDef[]
meta: { numeric: true },
cell: ({ row }) => ,
},
+ unpricedColumn(),
];
const teamColumns = groupColumns("Team", "No team");
@@ -139,14 +151,14 @@ export function GuardrailUsageBreakdown({ detail }: { detail: GuardrailUsageDeta
row.id || "no-team"}
size="compact"
toolbar={() => }
/>
row.id || "no-key"}
size="compact"
toolbar={() => }
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
index 3a56667b156..c52645def70 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
@@ -160,14 +160,24 @@ describe("GuardrailsOverview", () => {
expect(screen.getByText("Sensitive Information Policy: 250")).toBeInTheDocument();
});
- it("sorts by cost when its header is clicked", async () => {
+ it("sorts by cost when its header is clicked, keeping guardrails with no known cost last either way", async () => {
const user = userEvent.setup();
renderOverview();
+ const rowNames = () =>
+ screen
+ .getAllByRole("row")
+ .slice(1)
+ .map((r) => r.textContent ?? "");
await user.click(await screen.findByRole("button", { name: /Cost/ }));
+ await waitFor(() => expect(rowNames()[0]).toContain("Free Bedrock Guardrail"));
+ expect(rowNames()[1]).toContain("High Failure Guardrail");
+ expect(rowNames()[2]).toContain("Low Failure Guardrail");
- await waitFor(() => expect(screen.getAllByRole("row")[1]).toHaveTextContent("Low Failure Guardrail"));
- expect(screen.getAllByRole("row")[3]).toHaveTextContent("High Failure Guardrail");
+ await user.click(screen.getByRole("button", { name: /Cost/ }));
+ await waitFor(() => expect(rowNames()[0]).toContain("High Failure Guardrail"));
+ expect(rowNames()[1]).toContain("Free Bedrock Guardrail");
+ expect(rowNames()[2]).toContain("Low Failure Guardrail");
});
it("renders the page header and the export action", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
index 67630fef13a..0bbda6015b4 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
@@ -112,11 +112,12 @@ export function GuardrailsOverview({
}, [guardrailsData, activeData]);
const chartData = guardrailsData?.chart;
const sorted = useMemo(() => {
+ const mult = sortDir === "desc" ? -1 : 1;
return [...activeData].sort((a, b) => {
- const mult = sortDir === "desc" ? -1 : 1;
- const aVal = a[sortBy] ?? 0;
- const bVal = b[sortBy] ?? 0;
- return (Number(aVal) - Number(bVal)) * mult;
+ const aVal = a[sortBy];
+ const bVal = b[sortBy];
+ if (aVal == null || bVal == null) return Number(aVal == null) - Number(bVal == null);
+ return (aVal - bVal) * mult;
});
}, [activeData, sortBy, sortDir]);
const isLoading = guardrailsLoading;
diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts
index 427e5deb555..c1f65299c52 100644
--- a/ui/litellm-dashboard/src/lib/http/schema.d.ts
+++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts
@@ -38461,6 +38461,18 @@ export interface components {
untracked_usage_units: {
[key: string]: number;
};
+ /** Untracked Usage Units By Key */
+ untracked_usage_units_by_key: {
+ [key: string]: {
+ [key: string]: number;
+ };
+ };
+ /** Untracked Usage Units By Team */
+ untracked_usage_units_by_team: {
+ [key: string]: {
+ [key: string]: number;
+ };
+ };
/** Usage Units */
usage_units: {
[key: string]: number;
From f73e6838000d7bca1af751fcbcf83fc59d663a9b Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Fri, 4 Sep 2026 20:26:13 -0700
Subject: [PATCH 03/35] chore(ui): drop the fetch lookup note from the
fetchClient docblock
---
ui/litellm-dashboard/src/lib/http/api.ts | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/ui/litellm-dashboard/src/lib/http/api.ts b/ui/litellm-dashboard/src/lib/http/api.ts
index 904e4e4f3ab..9aa6bddf704 100644
--- a/ui/litellm-dashboard/src/lib/http/api.ts
+++ b/ui/litellm-dashboard/src/lib/http/api.ts
@@ -43,10 +43,9 @@ const middleware: Middleware = {
*
* The base URL is injected, not fixed at import: every request is built against
* whatever registerBaseUrlGetter supplies at call time (a split-origin proxy or
- * worker URL), falling back to the current origin. `fetch` is looked up per
- * request for the same reason, so a test that stubs the global sees these calls
- * too. The middleware injects the auth header and maps non-2xx responses to
- * ApiError so query functions can just read `.data`.
+ * worker URL), falling back to the current origin. The middleware injects the
+ * auth header and maps non-2xx responses to ApiError so query functions can just
+ * read `.data`.
*/
export const fetchClient = createFetchClient({
Request: BaseAwareRequest,
From 842623529048ceb836c746f8b99835260142a229 Mon Sep 17 00:00:00 2001
From: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Date: Fri, 4 Sep 2026 21:25:46 -0700
Subject: [PATCH 04/35] feat(ocr): add Cohere Parse support for cohere and
azure_ai
---
litellm/llms/azure_ai/ocr/__init__.py | 2 +
.../ocr/cohere_parse_transformation.py | 91 ++++++
litellm/llms/azure_ai/ocr/common_utils.py | 9 +
litellm/llms/base_llm/ocr/transformation.py | 4 +
litellm/llms/cohere/ocr/__init__.py | 3 +
litellm/llms/cohere/ocr/transformation.py | 292 ++++++++++++++++++
...odel_prices_and_context_window_backup.json | 19 ++
litellm/ocr/main.py | 2 +
litellm/utils.py | 5 +
model_prices_and_context_window.json | 19 ++
...st_azure_ai_cohere_parse_transformation.py | 166 ++++++++++
.../llms/cohere/ocr/test_cohere_parse_cost.py | 58 ++++
.../ocr/test_cohere_parse_transformation.py | 217 +++++++++++++
.../ocr/test_ocr_native_format.py | 10 +
14 files changed, 897 insertions(+)
create mode 100644 litellm/llms/azure_ai/ocr/cohere_parse_transformation.py
create mode 100644 litellm/llms/cohere/ocr/__init__.py
create mode 100644 litellm/llms/cohere/ocr/transformation.py
create mode 100644 tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
create mode 100644 tests/test_litellm/llms/cohere/ocr/test_cohere_parse_cost.py
create mode 100644 tests/test_litellm/llms/cohere/ocr/test_cohere_parse_transformation.py
diff --git a/litellm/llms/azure_ai/ocr/__init__.py b/litellm/llms/azure_ai/ocr/__init__.py
index ade1165b848..998d0570882 100644
--- a/litellm/llms/azure_ai/ocr/__init__.py
+++ b/litellm/llms/azure_ai/ocr/__init__.py
@@ -1,5 +1,6 @@
"""Azure AI OCR module."""
+from .cohere_parse_transformation import AzureAICohereParseConfig
from .common_utils import get_azure_ai_ocr_config
from .document_intelligence.transformation import (
AzureDocumentIntelligenceOCRConfig,
@@ -7,6 +8,7 @@ from .document_intelligence.transformation import (
from .transformation import AzureAIOCRConfig
__all__ = [
+ "AzureAICohereParseConfig",
"AzureAIOCRConfig",
"AzureDocumentIntelligenceOCRConfig",
"get_azure_ai_ocr_config",
diff --git a/litellm/llms/azure_ai/ocr/cohere_parse_transformation.py b/litellm/llms/azure_ai/ocr/cohere_parse_transformation.py
new file mode 100644
index 00000000000..121f970c59b
--- /dev/null
+++ b/litellm/llms/azure_ai/ocr/cohere_parse_transformation.py
@@ -0,0 +1,91 @@
+"""Cohere Parse served from Azure AI Foundry (`/providers/cohere/v2/parse`)."""
+
+from collections.abc import Mapping
+from typing import Final
+
+import httpx
+
+from litellm.litellm_core_utils.prompt_templates.image_handling import (
+ async_convert_url_to_base64,
+ convert_url_to_base64,
+)
+from litellm.llms.azure_ai.common_utils import get_azure_ai_auth_headers
+from litellm.llms.cohere.ocr.transformation import COHERE_PARSE_PATH, CohereParseConfig
+from litellm.secret_managers.main import get_secret_str
+
+AZURE_AI_API_KEY_ENV_VAR: Final = "AZURE_AI_API_KEY"
+AZURE_AI_API_BASE_ENV_VAR: Final = "AZURE_AI_API_BASE"
+AZURE_AI_COHERE_PROVIDER_PATH: Final = "/providers/cohere"
+AZURE_AI_MODELS_PATH_SUFFIX: Final = "/models"
+
+
+class AzureAICohereParseConfig(CohereParseConfig):
+ """Same request and response shape as Cohere Parse, behind Azure AI auth and URL layout.
+
+ Foundry cannot fetch external URLs, so remote images are inlined as base64 data URIs.
+ """
+
+ def get_api_key_env_var(self) -> str | None:
+ return AZURE_AI_API_KEY_ENV_VAR
+
+ def _llm_provider(self) -> str:
+ return "azure_ai"
+
+ def validate_environment(
+ self,
+ headers: Mapping[str, str],
+ model: str,
+ api_key: str | None = None,
+ api_base: str | None = None,
+ litellm_params: Mapping[str, object] | None = None,
+ **kwargs: object, # kwargs-ok: BaseOCRConfig.validate_environment signature
+ ) -> dict[str, str]: # mutable-ok: BaseOCRConfig signature
+ resolved_base: Final = api_base or get_secret_str(AZURE_AI_API_BASE_ENV_VAR)
+ if resolved_base is None:
+ raise ValueError(
+ f"Missing Azure AI API Base - Set {AZURE_AI_API_BASE_ENV_VAR} environment variable "
+ "or pass api_base parameter"
+ )
+ resolved_key: Final = api_key or get_secret_str(AZURE_AI_API_KEY_ENV_VAR)
+ return { # mutable-ok: BaseOCRConfig signature
+ **get_azure_ai_auth_headers(api_key=resolved_key, litellm_params=litellm_params),
+ "Content-Type": "application/json",
+ **headers,
+ }
+
+ def get_complete_url(
+ self,
+ api_base: str | None,
+ model: str,
+ optional_params: Mapping[str, object],
+ litellm_params: Mapping[str, object] | None = None,
+ **kwargs: object, # kwargs-ok: BaseOCRConfig.get_complete_url signature
+ ) -> str:
+ resolved_base: Final = api_base or get_secret_str(AZURE_AI_API_BASE_ENV_VAR)
+ if resolved_base is None:
+ raise ValueError(
+ f"Missing Azure AI API Base - Set {AZURE_AI_API_BASE_ENV_VAR} environment variable "
+ "or pass api_base parameter"
+ )
+ url: Final = httpx.URL(resolved_base)
+ if not url.is_absolute_url:
+ raise ValueError(
+ "Azure AI API Base must be an absolute URL including scheme (e.g. "
+ f"'https://.services.ai.azure.com'). Got api_base={resolved_base!r}."
+ )
+ path: Final = url.path.rstrip("/")
+ if path.endswith(COHERE_PARSE_PATH):
+ return str(url.copy_with(path=path))
+ if path.endswith(f"{AZURE_AI_COHERE_PROVIDER_PATH}/v2"):
+ return str(url.copy_with(path=f"{path}/parse"))
+ return str(
+ url.copy_with(
+ path=f"{path.removesuffix(AZURE_AI_MODELS_PATH_SUFFIX)}{AZURE_AI_COHERE_PROVIDER_PATH}{COHERE_PARSE_PATH}"
+ )
+ )
+
+ def _resolve_image_url_sync(self, image_url: str) -> str:
+ return convert_url_to_base64(image_url)
+
+ async def _resolve_image_url_async(self, image_url: str) -> str:
+ return await async_convert_url_to_base64(image_url)
diff --git a/litellm/llms/azure_ai/ocr/common_utils.py b/litellm/llms/azure_ai/ocr/common_utils.py
index ac1a1f5af0a..a4cd0c7a30b 100644
--- a/litellm/llms/azure_ai/ocr/common_utils.py
+++ b/litellm/llms/azure_ai/ocr/common_utils.py
@@ -24,6 +24,10 @@ def is_azure_document_intelligence_model(model: str) -> bool:
return "doc-intelligence" in lowered or "documentintelligence" in lowered
+def is_azure_cohere_parse_model(model: str) -> bool:
+ return "parse" in model.lower()
+
+
def get_azure_ai_ocr_config(model: str) -> Optional["BaseOCRConfig"]:
"""
Determine which Azure AI OCR configuration to use based on the model name.
@@ -46,6 +50,7 @@ def get_azure_ai_ocr_config(model: str) -> Optional["BaseOCRConfig"]:
>>> get_azure_ai_ocr_config("azure_ai/pixtral-12b-2409")
"""
+ from litellm.llms.azure_ai.ocr.cohere_parse_transformation import AzureAICohereParseConfig
from litellm.llms.azure_ai.ocr.document_intelligence.transformation import (
AzureDocumentIntelligenceOCRConfig,
)
@@ -56,6 +61,10 @@ def get_azure_ai_ocr_config(model: str) -> Optional["BaseOCRConfig"]:
verbose_logger.debug("Routing %s to Azure Document Intelligence OCR config", model)
return AzureDocumentIntelligenceOCRConfig()
+ if is_azure_cohere_parse_model(model):
+ verbose_logger.debug("Routing %s to Azure AI Cohere Parse config", model)
+ return AzureAICohereParseConfig()
+
# Default to Mistral-based OCR for other azure_ai models
verbose_logger.debug("Routing %s to Azure AI (Mistral) OCR config", model)
return AzureAIOCRConfig()
diff --git a/litellm/llms/base_llm/ocr/transformation.py b/litellm/llms/base_llm/ocr/transformation.py
index 75306cd572a..08ae077cb2f 100644
--- a/litellm/llms/base_llm/ocr/transformation.py
+++ b/litellm/llms/base_llm/ocr/transformation.py
@@ -142,6 +142,10 @@ class BaseOCRConfig:
"""
return None
+ def supports_rust_bridge(self) -> bool:
+ """Whether the Rust OCR bridge may serve this config when it is enabled for the provider."""
+ return True
+
def map_ocr_params(
self,
non_default_params: dict,
diff --git a/litellm/llms/cohere/ocr/__init__.py b/litellm/llms/cohere/ocr/__init__.py
new file mode 100644
index 00000000000..7742c7e0035
--- /dev/null
+++ b/litellm/llms/cohere/ocr/__init__.py
@@ -0,0 +1,3 @@
+from litellm.llms.cohere.ocr.transformation import CohereParseConfig
+
+__all__ = ("CohereParseConfig",)
diff --git a/litellm/llms/cohere/ocr/transformation.py b/litellm/llms/cohere/ocr/transformation.py
new file mode 100644
index 00000000000..87454980aa4
--- /dev/null
+++ b/litellm/llms/cohere/ocr/transformation.py
@@ -0,0 +1,292 @@
+"""Cohere Parse (`POST /v2/parse`) exposed through LiteLLM's OCR interface."""
+
+from collections.abc import Mapping, Sequence
+from types import MappingProxyType
+from typing import TYPE_CHECKING, Final, Literal
+
+import httpx
+from pydantic import BaseModel, ConfigDict, TypeAdapter
+from typing_extensions import ReadOnly, TypedDict
+
+from litellm.exceptions import BadRequestError, UnsupportedParamsError
+from litellm.llms.base_llm.ocr.transformation import (
+ OCR_REQUEST_FORMAT_PARAM,
+ BaseOCRConfig,
+ DocumentType,
+ OCRPage,
+ OCRPageImage,
+ OCRRequestData,
+ OCRRequestFormat,
+ OCRResponse,
+ OCRUsageInfo,
+ parse_ocr_request_format,
+)
+from litellm.llms.cohere.common_utils import CohereError
+from litellm.secret_managers.main import get_secret_str
+
+if TYPE_CHECKING:
+ from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
+
+COHERE_API_KEY_ENV_VAR: Final = "COHERE_API_KEY"
+COHERE_PARSE_API_BASE: Final = "https://api.cohere.com"
+COHERE_PARSE_PATH: Final = "/v2/parse"
+COHERE_PARSE_OUTPUT_FORMAT_PARAM: Final = "output_format"
+COHERE_PARSE_OUTPUT_FORMATS: Final = ("markdown", "blocks")
+COHERE_PARSE_DEFAULT_OUTPUT_FORMAT: Final = "markdown"
+COHERE_PARSE_SUPPORTED_PARAMS: Final = (COHERE_PARSE_OUTPUT_FORMAT_PARAM, OCR_REQUEST_FORMAT_PARAM)
+COHERE_PARSE_IMAGE_ONLY_MESSAGE: Final = (
+ "Cohere Parse only accepts `image_url` documents (an image URL or a base64 image data URI); "
+ "`document_url` and PDF inputs are not supported."
+)
+
+_NATIVE_RESPONSE_ADAPTER: Final = TypeAdapter(dict[str, object])
+_BOUNDING_BOX_ADAPTER: Final = TypeAdapter(Mapping[str, object])
+
+
+class _CohereParseDocument(TypedDict):
+ type: ReadOnly[Literal["image_url"]]
+ image_url: ReadOnly[str]
+
+
+class _CohereParseRequestBody(TypedDict):
+ model: ReadOnly[str]
+ document: ReadOnly[_CohereParseDocument]
+ output_format: ReadOnly[str]
+
+
+class _MarkdownPage(TypedDict):
+ index: ReadOnly[int]
+ markdown: ReadOnly[str]
+ images: ReadOnly[Sequence[OCRPageImage] | None]
+
+
+class _BlocksPage(_MarkdownPage):
+ blocks: ReadOnly[Sequence[Mapping[str, object]]]
+
+
+class _CohereParseMarkdown(BaseModel):
+ model_config = ConfigDict(frozen=True, extra="allow")
+
+ content: str = ""
+ images: Sequence[Mapping[str, object]] | None = None
+
+
+class _CohereParsePage(BaseModel):
+ model_config = ConfigDict(frozen=True, extra="allow")
+
+ index: int | None = None
+ markdown: _CohereParseMarkdown | None = None
+ blocks: Sequence[Mapping[str, object]] | None = None
+
+
+class _CohereParseBilledUnits(BaseModel):
+ model_config = ConfigDict(frozen=True, extra="allow")
+
+ pages: int | None = None
+
+
+class _CohereParseMeta(BaseModel):
+ model_config = ConfigDict(frozen=True, extra="allow")
+
+ billed_units: _CohereParseBilledUnits | None = None
+
+
+class _CohereParseResponse(BaseModel):
+ model_config = ConfigDict(frozen=True, extra="allow")
+
+ pages: Sequence[_CohereParsePage] = ()
+ meta: _CohereParseMeta | None = None
+
+
+def _requested_format(optional_params: Mapping[str, object] | None) -> OCRRequestFormat:
+ if optional_params is None:
+ return "litellm"
+ return "native" if optional_params.get(OCR_REQUEST_FORMAT_PARAM) == "native" else "litellm"
+
+
+def _page_image(image: Mapping[str, object]) -> OCRPageImage:
+ bounding_box: Final = image.get("bounding_box")
+ if not isinstance(bounding_box, Mapping):
+ return OCRPageImage.model_validate(image)
+ bbox: Final = _BOUNDING_BOX_ADAPTER.validate_python(bounding_box)
+ return OCRPageImage.model_validate(MappingProxyType({**image, "bbox": bbox}))
+
+
+def _normalize_page(page: _CohereParsePage, position: int) -> OCRPage:
+ markdown: Final = page.markdown
+ images: Final = tuple(_page_image(image) for image in markdown.images) if markdown and markdown.images else None
+ normalized: Final[_MarkdownPage] = {
+ "index": page.index if page.index is not None else position,
+ "markdown": markdown.content if markdown else "",
+ "images": images,
+ }
+ if page.blocks is None:
+ return OCRPage.model_validate(normalized)
+ with_blocks: Final[_BlocksPage] = {**normalized, "blocks": page.blocks}
+ return OCRPage.model_validate(with_blocks)
+
+
+def _billed_pages(parsed: _CohereParseResponse) -> int | None:
+ if parsed.meta is None or parsed.meta.billed_units is None:
+ return None
+ return parsed.meta.billed_units.pages
+
+
+class CohereParseConfig(BaseOCRConfig):
+ """Cohere Parse, an image-only document understanding endpoint returning markdown or blocks."""
+
+ def get_supported_ocr_params(self, model: str) -> list[str]: # mutable-ok: BaseOCRConfig signature
+ return list(COHERE_PARSE_SUPPORTED_PARAMS) # mutable-ok: BaseOCRConfig signature
+
+ def get_api_key_env_var(self) -> str | None:
+ return COHERE_API_KEY_ENV_VAR
+
+ def supports_rust_bridge(self) -> bool:
+ return False
+
+ def _llm_provider(self) -> str:
+ return "cohere"
+
+ def map_ocr_params(
+ self,
+ non_default_params: Mapping[str, object],
+ optional_params: Mapping[str, object],
+ model: str,
+ ) -> dict[str, object]: # mutable-ok: BaseOCRConfig signature
+ output_format: Final = non_default_params.get(COHERE_PARSE_OUTPUT_FORMAT_PARAM)
+ if output_format is not None and output_format not in COHERE_PARSE_OUTPUT_FORMATS:
+ raise UnsupportedParamsError(
+ message=(
+ f"Invalid `{COHERE_PARSE_OUTPUT_FORMAT_PARAM}`: {output_format!r}. "
+ f"Expected one of {', '.join(COHERE_PARSE_OUTPUT_FORMATS)}."
+ ),
+ model=model,
+ llm_provider=self._llm_provider(),
+ )
+ requested_format: Final = non_default_params.get(OCR_REQUEST_FORMAT_PARAM)
+ request_format: Final = parse_ocr_request_format(requested_format) if requested_format is not None else None
+ overrides: Final = tuple(
+ (key, value)
+ for key, value in (
+ (COHERE_PARSE_OUTPUT_FORMAT_PARAM, output_format),
+ (OCR_REQUEST_FORMAT_PARAM, request_format),
+ )
+ if value is not None
+ )
+ return {**optional_params, **dict(overrides)} # mutable-ok: BaseOCRConfig signature
+
+ def validate_environment(
+ self,
+ headers: Mapping[str, str],
+ model: str,
+ api_key: str | None = None,
+ api_base: str | None = None,
+ litellm_params: Mapping[str, object] | None = None,
+ **kwargs: object, # kwargs-ok: BaseOCRConfig.validate_environment signature
+ ) -> dict[str, str]: # mutable-ok: BaseOCRConfig signature
+ resolved_key: Final = api_key or get_secret_str(COHERE_API_KEY_ENV_VAR)
+ if resolved_key is None:
+ raise ValueError(
+ f"Missing {COHERE_API_KEY_ENV_VAR} - set it in the environment or pass api_key to "
+ "litellm.ocr()/litellm.aocr()"
+ )
+ return { # mutable-ok: BaseOCRConfig signature
+ "Authorization": f"Bearer {resolved_key}",
+ "Content-Type": "application/json",
+ **headers,
+ }
+
+ def get_complete_url(
+ self,
+ api_base: str | None,
+ model: str,
+ optional_params: Mapping[str, object],
+ litellm_params: Mapping[str, object] | None = None,
+ **kwargs: object, # kwargs-ok: BaseOCRConfig.get_complete_url signature
+ ) -> str:
+ url: Final = httpx.URL(api_base or COHERE_PARSE_API_BASE)
+ path: Final = url.path.rstrip("/")
+ if path.endswith(COHERE_PARSE_PATH):
+ return str(url.copy_with(path=path))
+ if path.endswith("/v2"):
+ return str(url.copy_with(path=f"{path}/parse"))
+ return str(url.copy_with(path=f"{path}{COHERE_PARSE_PATH}"))
+
+ def _image_url(self, document: DocumentType, model: str) -> str:
+ image_url: Final = document.get("image_url", "")
+ if document.get("type") != "image_url" or not image_url or image_url.startswith("data:application/pdf"):
+ raise BadRequestError(
+ message=COHERE_PARSE_IMAGE_ONLY_MESSAGE,
+ model=model,
+ llm_provider=self._llm_provider(),
+ )
+ return image_url
+
+ def _resolve_image_url_sync(self, image_url: str) -> str:
+ return image_url
+
+ async def _resolve_image_url_async(self, image_url: str) -> str:
+ return image_url
+
+ def _build_request(self, model: str, image_url: str, optional_params: Mapping[str, object]) -> OCRRequestData:
+ body: Final[_CohereParseRequestBody] = {
+ "model": model,
+ "document": {"type": "image_url", "image_url": image_url},
+ "output_format": str(
+ optional_params.get(COHERE_PARSE_OUTPUT_FORMAT_PARAM, COHERE_PARSE_DEFAULT_OUTPUT_FORMAT)
+ ),
+ }
+ return OCRRequestData(data=dict(body), files=None) # mutable-ok: OCRRequestData.data is a dict
+
+ def transform_ocr_request(
+ self,
+ model: str,
+ document: DocumentType,
+ optional_params: Mapping[str, object],
+ headers: Mapping[str, str],
+ **kwargs: object, # kwargs-ok: BaseOCRConfig.transform_ocr_request signature
+ ) -> OCRRequestData:
+ image_url: Final = self._resolve_image_url_sync(self._image_url(document, model))
+ return self._build_request(model=model, image_url=image_url, optional_params=optional_params)
+
+ async def async_transform_ocr_request(
+ self,
+ model: str,
+ document: DocumentType,
+ optional_params: Mapping[str, object],
+ headers: Mapping[str, str],
+ **kwargs: object, # kwargs-ok: BaseOCRConfig.async_transform_ocr_request signature
+ ) -> OCRRequestData:
+ image_url: Final = await self._resolve_image_url_async(self._image_url(document, model))
+ return self._build_request(model=model, image_url=image_url, optional_params=optional_params)
+
+ def transform_ocr_response(
+ self,
+ model: str,
+ raw_response: httpx.Response,
+ logging_obj: "LiteLLMLoggingObj",
+ optional_params: Mapping[str, object] | None = None,
+ **kwargs: object, # kwargs-ok: BaseOCRConfig.transform_ocr_response signature
+ ) -> OCRResponse:
+ native: Final = _NATIVE_RESPONSE_ADAPTER.validate_python(raw_response.json())
+ parsed: Final = _CohereParseResponse.model_validate(native)
+ pages: Final = [ # mutable-ok: OCRResponse.pages is a list
+ _normalize_page(page, position) for position, page in enumerate(parsed.pages)
+ ]
+ billed_pages: Final = _billed_pages(parsed)
+ response: Final = OCRResponse(
+ pages=pages,
+ model=model,
+ usage_info=OCRUsageInfo(pages_processed=billed_pages if billed_pages is not None else len(pages)),
+ )
+ if _requested_format(optional_params) == "native":
+ response.set_provider_native_response(native)
+ return response
+
+ def get_error_class(
+ self,
+ error_message: str,
+ status_code: int,
+ headers: Mapping[str, str],
+ ) -> Exception:
+ return CohereError(status_code=status_code, message=error_message)
diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json
index 2459ed940e0..4273ec54472 100644
--- a/litellm/model_prices_and_context_window_backup.json
+++ b/litellm/model_prices_and_context_window_backup.json
@@ -10243,6 +10243,16 @@
],
"source": "https://azure.microsoft.com/en-us/pricing/details/ai-foundry-models/mistral/"
},
+ "azure_ai/Cohere-parse-v5": {
+ "deprecation_date": "2026-12-15",
+ "litellm_provider": "azure_ai",
+ "mode": "ocr",
+ "ocr_cost_per_page": 0.0015,
+ "source": "https://cohere.com/blog/parse",
+ "supported_endpoints": [
+ "/v1/ocr"
+ ]
+ },
"azure_ai/doc-intelligence/prebuilt-read": {
"litellm_provider": "azure_ai",
"ocr_cost_per_page": 0.0015,
@@ -14116,6 +14126,15 @@
"output_vector_size": 1536,
"supports_embedding_image_input": true
},
+ "cohere/parse-v5.0": {
+ "litellm_provider": "cohere",
+ "mode": "ocr",
+ "ocr_cost_per_page": 0.0015,
+ "source": "https://cohere.com/blog/parse",
+ "supported_endpoints": [
+ "/v1/ocr"
+ ]
+ },
"cohere.rerank-v3-5:0": {
"input_cost_per_query": 0.002,
"input_cost_per_token": 0.0,
diff --git a/litellm/ocr/main.py b/litellm/ocr/main.py
index b260ec6e06f..6c68971f8d5 100644
--- a/litellm/ocr/main.py
+++ b/litellm/ocr/main.py
@@ -191,6 +191,8 @@ def _prepare_ocr_request(
def _rust_ocr_supported(prepared_request: _PreparedOCRRequest) -> bool:
if prepared_request.optional_params.get(OCR_REQUEST_FORMAT_PARAM) == "native":
return False
+ if not prepared_request.provider_config.supports_rust_bridge():
+ return False
return prepared_request.custom_llm_provider in _RUST_OCR_PROVIDERS
diff --git a/litellm/utils.py b/litellm/utils.py
index 9d20d32d147..52c1859b525 100644
--- a/litellm/utils.py
+++ b/litellm/utils.py
@@ -9294,6 +9294,11 @@ class ProviderConfigManager:
return get_vertex_ai_ocr_config(model=model)
+ if provider == litellm.LlmProviders.COHERE:
+ from litellm.llms.cohere.ocr.transformation import CohereParseConfig
+
+ return CohereParseConfig()
+
if provider == litellm.LlmProviders.REDUCTO:
from litellm.llms.reducto.ocr.transformation import (
ReductoParseLegacyConfig,
diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json
index 2459ed940e0..4273ec54472 100644
--- a/model_prices_and_context_window.json
+++ b/model_prices_and_context_window.json
@@ -10243,6 +10243,16 @@
],
"source": "https://azure.microsoft.com/en-us/pricing/details/ai-foundry-models/mistral/"
},
+ "azure_ai/Cohere-parse-v5": {
+ "deprecation_date": "2026-12-15",
+ "litellm_provider": "azure_ai",
+ "mode": "ocr",
+ "ocr_cost_per_page": 0.0015,
+ "source": "https://cohere.com/blog/parse",
+ "supported_endpoints": [
+ "/v1/ocr"
+ ]
+ },
"azure_ai/doc-intelligence/prebuilt-read": {
"litellm_provider": "azure_ai",
"ocr_cost_per_page": 0.0015,
@@ -14116,6 +14126,15 @@
"output_vector_size": 1536,
"supports_embedding_image_input": true
},
+ "cohere/parse-v5.0": {
+ "litellm_provider": "cohere",
+ "mode": "ocr",
+ "ocr_cost_per_page": 0.0015,
+ "source": "https://cohere.com/blog/parse",
+ "supported_endpoints": [
+ "/v1/ocr"
+ ]
+ },
"cohere.rerank-v3-5:0": {
"input_cost_per_query": 0.002,
"input_cost_per_token": 0.0,
diff --git a/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py b/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
new file mode 100644
index 00000000000..01e1f59184c
--- /dev/null
+++ b/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
@@ -0,0 +1,166 @@
+import base64
+import json
+
+import pytest
+
+import litellm
+from litellm.llms.azure_ai.ocr.cohere_parse_transformation import AzureAICohereParseConfig
+from litellm.llms.azure_ai.ocr.common_utils import get_azure_ai_ocr_config
+from litellm.llms.azure_ai.ocr.document_intelligence.transformation import AzureDocumentIntelligenceOCRConfig
+from litellm.llms.azure_ai.ocr.transformation import AzureAIOCRConfig
+
+MODEL = "azure_ai/Cohere-parse-v5"
+API_BASE = "https://resource.services.ai.azure.com"
+PARSE_URL = f"{API_BASE}/providers/cohere/v2/parse"
+IMAGE_URL = "https://example.com/receipt.png"
+PNG_BYTES = base64.b64decode(
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
+)
+PNG_DATA_URI = f"data:image/png;base64,{base64.b64encode(PNG_BYTES).decode()}"
+
+
+def _parse_response() -> dict:
+ return {
+ "id": "882bf973-9dfa-4d02-9d30-709247008efd",
+ "pages": [{"index": 0, "type": "markdown", "markdown": {"content": "# Receipt\n\nTotal Due: $4.00"}}],
+ "meta": {"api_version": {"version": "2"}, "billed_units": {"pages": 1}},
+ }
+
+
+@pytest.fixture()
+def disable_aiohttp_transport(monkeypatch):
+ monkeypatch.setattr(litellm, "disable_aiohttp_transport", True)
+ litellm.in_memory_llm_clients_cache.flush_cache()
+ yield
+ litellm.in_memory_llm_clients_cache.flush_cache()
+
+
+@pytest.mark.parametrize(
+ "model, expected_config",
+ [
+ ("Cohere-parse-v5", AzureAICohereParseConfig),
+ ("cohere-parse-v5", AzureAICohereParseConfig),
+ ("parse-v5", AzureAICohereParseConfig),
+ ("mistral-ocr-4-0", AzureAIOCRConfig),
+ ("mistral-document-ai-2512", AzureAIOCRConfig),
+ ("doc-intelligence/prebuilt-read", AzureDocumentIntelligenceOCRConfig),
+ ],
+)
+def test_azure_ai_ocr_routing(model: str, expected_config: type) -> None:
+ assert type(get_azure_ai_ocr_config(model)) is expected_config
+
+
+@pytest.mark.parametrize(
+ "api_base, expected_url",
+ [
+ (API_BASE, PARSE_URL),
+ (f"{API_BASE}/", PARSE_URL),
+ (f"{API_BASE}/models", PARSE_URL),
+ (f"{API_BASE}/providers/cohere/v2", PARSE_URL),
+ (f"{API_BASE}/providers/cohere/v2/parse", PARSE_URL),
+ ],
+)
+def test_get_complete_url_targets_the_cohere_provider_route(api_base: str, expected_url: str) -> None:
+ url = AzureAICohereParseConfig().get_complete_url(api_base=api_base, model="Cohere-parse-v5", optional_params={})
+
+ assert url == expected_url
+
+
+def test_get_complete_url_falls_back_to_env_api_base(monkeypatch) -> None:
+ monkeypatch.setenv("AZURE_AI_API_BASE", API_BASE)
+
+ url = AzureAICohereParseConfig().get_complete_url(api_base=None, model="Cohere-parse-v5", optional_params={})
+
+ assert url == PARSE_URL
+
+
+def test_get_complete_url_requires_api_base(monkeypatch) -> None:
+ monkeypatch.delenv("AZURE_AI_API_BASE", raising=False)
+
+ with pytest.raises(ValueError, match="AZURE_AI_API_BASE"):
+ AzureAICohereParseConfig().get_complete_url(api_base=None, model="Cohere-parse-v5", optional_params={})
+
+
+def test_get_complete_url_rejects_relative_api_base() -> None:
+ with pytest.raises(ValueError, match="absolute URL"):
+ AzureAICohereParseConfig().get_complete_url(
+ api_base="resource.services.ai.azure.com", model="Cohere-parse-v5", optional_params={}
+ )
+
+
+def test_validate_environment_requires_api_base(monkeypatch) -> None:
+ monkeypatch.delenv("AZURE_AI_API_BASE", raising=False)
+
+ with pytest.raises(ValueError, match="AZURE_AI_API_BASE"):
+ AzureAICohereParseConfig().validate_environment(headers={}, model="Cohere-parse-v5", api_key="key")
+
+
+@pytest.mark.asyncio
+async def test_aocr_inlines_remote_image_and_posts_to_foundry(disable_aiohttp_transport, respx_mock):
+ respx_mock.get(IMAGE_URL).respond(content=PNG_BYTES, headers={"Content-Type": "image/png"})
+ route = respx_mock.post(PARSE_URL).respond(json=_parse_response())
+
+ response = await litellm.aocr(
+ model=MODEL,
+ document={"type": "image_url", "image_url": IMAGE_URL},
+ api_base=API_BASE,
+ api_key="azure-key",
+ )
+
+ request = route.calls.last.request
+ assert request.headers["Authorization"] == "Bearer azure-key"
+ assert json.loads(request.content) == {
+ "model": "Cohere-parse-v5",
+ "document": {"type": "image_url", "image_url": PNG_DATA_URI},
+ "output_format": "markdown",
+ }
+ assert response.pages[0].markdown == "# Receipt\n\nTotal Due: $4.00"
+ assert response.usage_info.pages_processed == 1
+
+
+@pytest.mark.asyncio
+async def test_aocr_passes_data_uri_through_without_fetching(disable_aiohttp_transport, respx_mock):
+ route = respx_mock.post(PARSE_URL).respond(json=_parse_response())
+
+ await litellm.aocr(
+ model=MODEL,
+ document={"type": "image_url", "image_url": PNG_DATA_URI},
+ api_base=API_BASE,
+ api_key="azure-key",
+ output_format="blocks",
+ )
+
+ body = json.loads(route.calls.last.request.content)
+ assert body["document"]["image_url"] == PNG_DATA_URI
+ assert body["output_format"] == "blocks"
+
+
+def test_ocr_sync_inlines_remote_image(respx_mock):
+ respx_mock.get(IMAGE_URL).respond(content=PNG_BYTES, headers={"Content-Type": "image/png"})
+ route = respx_mock.post(PARSE_URL).respond(json=_parse_response())
+
+ response = litellm.ocr(
+ model=MODEL,
+ document={"type": "image_url", "image_url": IMAGE_URL},
+ api_base=API_BASE,
+ api_key="azure-key",
+ )
+
+ assert json.loads(route.calls.last.request.content)["document"]["image_url"] == PNG_DATA_URI
+ assert response.pages[0].markdown == "# Receipt\n\nTotal Due: $4.00"
+
+
+@pytest.mark.asyncio
+async def test_aocr_rejects_pdf_before_calling_foundry(disable_aiohttp_transport, respx_mock):
+ route = respx_mock.post(PARSE_URL).respond(json=_parse_response())
+
+ with pytest.raises(litellm.BadRequestError, match="only accepts `image_url` documents") as exc_info:
+ await litellm.aocr(
+ model=MODEL,
+ document={"type": "document_url", "document_url": "https://example.com/doc.pdf"},
+ api_base=API_BASE,
+ api_key="azure-key",
+ )
+
+ assert exc_info.value.llm_provider == "azure_ai"
+ assert not route.called
diff --git a/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_cost.py b/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_cost.py
new file mode 100644
index 00000000000..dfa3c7a056e
--- /dev/null
+++ b/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_cost.py
@@ -0,0 +1,58 @@
+import json
+from pathlib import Path
+
+import pytest
+
+import litellm
+from litellm.cost_calculator import completion_cost
+from litellm.llms.base_llm.ocr.transformation import OCRPage, OCRResponse, OCRUsageInfo
+
+COST_PER_PAGE = 0.0015
+REPO_ROOT = Path(__file__).parents[5]
+COST_MAPS = [
+ REPO_ROOT / "model_prices_and_context_window.json",
+ REPO_ROOT / "litellm" / "model_prices_and_context_window_backup.json",
+]
+MODELS = [("cohere/parse-v5.0", "cohere"), ("azure_ai/Cohere-parse-v5", "azure_ai")]
+
+
+def _ocr_response(model: str, pages_processed: int) -> OCRResponse:
+ return OCRResponse(
+ pages=[OCRPage(index=i, markdown=f"page {i}") for i in range(pages_processed)],
+ model=model,
+ usage_info=OCRUsageInfo(pages_processed=pages_processed),
+ )
+
+
+@pytest.mark.parametrize("cost_map_path", COST_MAPS, ids=lambda path: path.name)
+@pytest.mark.parametrize("model, provider", MODELS)
+def test_pricing_entry(cost_map_path: Path, model: str, provider: str) -> None:
+ with open(cost_map_path) as f:
+ info = json.load(f).get(model)
+
+ assert info is not None, f"{model} missing from {cost_map_path.name}"
+ assert info["litellm_provider"] == provider
+ assert info["mode"] == "ocr"
+ assert info["supported_endpoints"] == ["/v1/ocr"]
+ assert info["ocr_cost_per_page"] == COST_PER_PAGE
+
+
+@pytest.mark.parametrize("model, provider", MODELS)
+def test_model_info_resolves_ocr_mode_and_price(local_model_cost_map, model: str, provider: str) -> None:
+ info = litellm.get_model_info(model=model, custom_llm_provider=provider)
+
+ assert info["mode"] == "ocr"
+ assert info["ocr_cost_per_page"] == COST_PER_PAGE
+
+
+@pytest.mark.parametrize("model, provider", MODELS)
+@pytest.mark.parametrize("pages_processed", [1, 3])
+def test_cost_scales_with_billed_pages(local_model_cost_map, model: str, provider: str, pages_processed: int) -> None:
+ cost = completion_cost(
+ completion_response=_ocr_response(model.split("/", 1)[1], pages_processed),
+ model=model,
+ custom_llm_provider=provider,
+ call_type="ocr",
+ )
+
+ assert cost == pytest.approx(COST_PER_PAGE * pages_processed)
diff --git a/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_transformation.py b/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_transformation.py
new file mode 100644
index 00000000000..64f2bb383c2
--- /dev/null
+++ b/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_transformation.py
@@ -0,0 +1,217 @@
+import json
+
+import pytest
+
+import litellm
+
+PARSE_URL = "https://api.cohere.com/v2/parse"
+MODEL = "cohere/parse-v5.0"
+IMAGE_DOCUMENT = {"type": "image_url", "image_url": "https://example.com/receipt.png"}
+BOUNDING_BOX = {"top_left_x": 0, "top_left_y": 0, "bottom_right_x": 32, "bottom_right_y": 32}
+
+
+def _markdown_response(billed_pages: int | None = 2) -> dict:
+ return {
+ "id": "272900cc-04c0-4da2-a505-2cea58d231bf",
+ "pages": [
+ {
+ "index": 0,
+ "type": "markdown",
+ "markdown": {
+ "content": "# Receipt\n\nTotal Due: $4.00",
+ "images": [
+ {
+ "id": "img-0",
+ "description": "A parking receipt",
+ "category": "other",
+ "bounding_box": BOUNDING_BOX,
+ "bounding_box_normalized": {
+ "top_left_x": 0,
+ "top_left_y": 0,
+ "bottom_right_x": 1,
+ "bottom_right_y": 1,
+ },
+ }
+ ],
+ },
+ },
+ {"index": 1, "type": "markdown", "markdown": {"content": "Page two"}},
+ ],
+ **(
+ {"meta": {"api_version": {"version": "2"}, "billed_units": {"pages": billed_pages}}} if billed_pages else {}
+ ),
+ }
+
+
+def _blocks_response() -> dict:
+ return {
+ "id": "94474f83-e30d-4763-b4bc-52af6e12c4f7",
+ "pages": [
+ {
+ "index": 0,
+ "type": "blocks",
+ "blocks": [{"type": "text", "text": "Total Due: $4.00"}],
+ }
+ ],
+ "meta": {"api_version": {"version": "2"}, "billed_units": {"pages": 1}},
+ }
+
+
+@pytest.fixture()
+def disable_aiohttp_transport(monkeypatch):
+ monkeypatch.setattr(litellm, "disable_aiohttp_transport", True)
+ litellm.in_memory_llm_clients_cache.flush_cache()
+ yield
+ litellm.in_memory_llm_clients_cache.flush_cache()
+
+
+@pytest.mark.asyncio
+async def test_aocr_sends_markdown_parse_request_and_normalizes_pages(disable_aiohttp_transport, respx_mock):
+ route = respx_mock.post(PARSE_URL).respond(json=_markdown_response())
+
+ response = await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT, api_key="test-key")
+
+ request = route.calls.last.request
+ assert request.headers["Authorization"] == "Bearer test-key"
+ assert json.loads(request.content) == {
+ "model": "parse-v5.0",
+ "document": IMAGE_DOCUMENT,
+ "output_format": "markdown",
+ }
+ assert response.object == "ocr"
+ assert [page.index for page in response.pages] == [0, 1]
+ assert response.pages[0].markdown == "# Receipt\n\nTotal Due: $4.00"
+ assert response.pages[1].markdown == "Page two"
+ assert response.pages[1].images is None
+ image = response.pages[0].images[0]
+ assert image.bbox == BOUNDING_BOX
+ assert image.model_extra["description"] == "A parking receipt"
+ assert image.model_extra["bounding_box_normalized"]["bottom_right_x"] == 1
+ assert response.usage_info.pages_processed == 2
+ assert response.get_provider_native_response() is None
+
+
+@pytest.mark.asyncio
+async def test_aocr_usage_prefers_billed_units_over_page_count(disable_aiohttp_transport, respx_mock):
+ respx_mock.post(PARSE_URL).respond(json=_markdown_response(billed_pages=3))
+
+ response = await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT, api_key="test-key")
+
+ assert response.usage_info.pages_processed == 3
+
+
+@pytest.mark.asyncio
+async def test_aocr_usage_falls_back_to_page_count_without_meta(disable_aiohttp_transport, respx_mock):
+ respx_mock.post(PARSE_URL).respond(json=_markdown_response(billed_pages=None))
+
+ response = await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT, api_key="test-key")
+
+ assert response.usage_info.pages_processed == 2
+
+
+@pytest.mark.asyncio
+async def test_aocr_blocks_output_format_forwards_param_and_keeps_blocks(disable_aiohttp_transport, respx_mock):
+ route = respx_mock.post(PARSE_URL).respond(json=_blocks_response())
+
+ response = await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT, api_key="test-key", output_format="blocks")
+
+ assert json.loads(route.calls.last.request.content)["output_format"] == "blocks"
+ assert response.pages[0].markdown == ""
+ assert response.pages[0].model_extra["blocks"] == [{"type": "text", "text": "Total Due: $4.00"}]
+ assert response.usage_info.pages_processed == 1
+
+
+@pytest.mark.asyncio
+async def test_aocr_native_format_carries_provider_payload(disable_aiohttp_transport, respx_mock):
+ payload = _markdown_response()
+ route = respx_mock.post(PARSE_URL).respond(json=payload)
+
+ response = await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT, api_key="test-key", req_format="native")
+
+ assert "req_format" not in json.loads(route.calls.last.request.content)
+ assert response.get_provider_native_response() == payload
+ assert response.pages[0].markdown == "# Receipt\n\nTotal Due: $4.00"
+
+
+@pytest.mark.asyncio
+async def test_aocr_rejects_unknown_output_format_before_calling_provider(disable_aiohttp_transport, respx_mock):
+ route = respx_mock.post(PARSE_URL).respond(json=_markdown_response())
+
+ with pytest.raises(litellm.BadRequestError, match="Invalid `output_format`: 'html'") as exc_info:
+ await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT, api_key="test-key", output_format="html")
+
+ assert exc_info.value.status_code == 400
+ assert not route.called
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+ "document",
+ [
+ {"type": "document_url", "document_url": "https://example.com/doc.pdf"},
+ {"type": "image_url", "image_url": "data:application/pdf;base64,JVBERi0="},
+ {"type": "image_url", "image_url": ""},
+ ],
+)
+async def test_aocr_rejects_non_image_documents_before_calling_provider(
+ disable_aiohttp_transport, respx_mock, document
+):
+ route = respx_mock.post(PARSE_URL).respond(json=_markdown_response())
+
+ with pytest.raises(litellm.BadRequestError, match="only accepts `image_url` documents") as exc_info:
+ await litellm.aocr(model=MODEL, document=document, api_key="test-key")
+
+ assert exc_info.value.status_code == 400
+ assert not route.called
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+ "api_base, expected_url",
+ [
+ ("https://gateway.example.com", "https://gateway.example.com/v2/parse"),
+ ("https://gateway.example.com/cohere/", "https://gateway.example.com/cohere/v2/parse"),
+ ("https://gateway.example.com/v2", "https://gateway.example.com/v2/parse"),
+ ("https://gateway.example.com/v2/parse", "https://gateway.example.com/v2/parse"),
+ ],
+)
+async def test_aocr_posts_to_api_base_variants(disable_aiohttp_transport, respx_mock, api_base, expected_url):
+ route = respx_mock.post(expected_url).respond(json=_markdown_response())
+
+ await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT, api_key="test-key", api_base=api_base)
+
+ assert route.called
+
+
+@pytest.mark.asyncio
+async def test_aocr_surfaces_provider_error_with_its_status_and_message(disable_aiohttp_transport, respx_mock):
+ respx_mock.post(PARSE_URL).respond(
+ status_code=400, json={"id": "83b0d95e", "message": "output_format must be `blocks` or `markdown`"}
+ )
+
+ with pytest.raises(litellm.BadRequestError, match="output_format must be") as exc_info:
+ await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT, api_key="test-key")
+
+ assert exc_info.value.status_code == 400
+
+
+@pytest.mark.asyncio
+async def test_aocr_reads_api_key_from_environment(disable_aiohttp_transport, respx_mock, monkeypatch):
+ monkeypatch.setenv("COHERE_API_KEY", "env-key")
+ route = respx_mock.post(PARSE_URL).respond(json=_markdown_response())
+
+ await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT)
+
+ assert route.calls.last.request.headers["Authorization"] == "Bearer env-key"
+
+
+@pytest.mark.asyncio
+async def test_aocr_without_api_key_names_the_env_var(disable_aiohttp_transport, respx_mock, monkeypatch):
+ monkeypatch.delenv("COHERE_API_KEY", raising=False)
+ monkeypatch.setattr(litellm, "cohere_key", None)
+ route = respx_mock.post(PARSE_URL).respond(json=_markdown_response())
+
+ with pytest.raises(Exception, match="Missing COHERE_API_KEY"):
+ await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT)
+
+ assert not route.called
diff --git a/tests/test_litellm/ocr/test_ocr_native_format.py b/tests/test_litellm/ocr/test_ocr_native_format.py
index 463213a2071..249fbda713e 100644
--- a/tests/test_litellm/ocr/test_ocr_native_format.py
+++ b/tests/test_litellm/ocr/test_ocr_native_format.py
@@ -4,11 +4,14 @@ providers that don't support a native response must reject it, and the Rust
bridge (which only returns the normalized shape) must not serve native requests.
"""
+import dataclasses
from unittest.mock import MagicMock
import pytest
import litellm
+from litellm.llms.azure_ai.ocr.cohere_parse_transformation import AzureAICohereParseConfig
+from litellm.llms.cohere.ocr.transformation import CohereParseConfig
from litellm.ocr.main import _PreparedOCRRequest, _rust_ocr_supported
DOCUMENT = {"type": "document_url", "document_url": "https://example.com/doc.pdf"}
@@ -39,6 +42,13 @@ def test_rust_ocr_skipped_for_native_format():
assert _rust_ocr_supported(_prepared({"req_format": "native"})) is False
+@pytest.mark.parametrize("provider_config", [CohereParseConfig(), AzureAICohereParseConfig()])
+def test_rust_ocr_skipped_for_configs_without_bridge_support(provider_config):
+ prepared = dataclasses.replace(_prepared({}), provider_config=provider_config)
+
+ assert _rust_ocr_supported(prepared) is False
+
+
@pytest.mark.asyncio
async def test_native_format_rejected_for_provider_without_support_as_bad_request():
with pytest.raises(litellm.BadRequestError, match="not supported for provider") as exc_info:
From d3a179f98871abdacd3b50d041aa61205cfec564 Mon Sep 17 00:00:00 2001
From: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Date: Fri, 4 Sep 2026 22:07:26 -0700
Subject: [PATCH 05/35] fix(azure_ai): route only cohere parse deployment names
to Cohere Parse
---
litellm/llms/azure_ai/ocr/common_utils.py | 3 ++-
.../azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/litellm/llms/azure_ai/ocr/common_utils.py b/litellm/llms/azure_ai/ocr/common_utils.py
index a4cd0c7a30b..2ca2ad9ec2f 100644
--- a/litellm/llms/azure_ai/ocr/common_utils.py
+++ b/litellm/llms/azure_ai/ocr/common_utils.py
@@ -25,7 +25,8 @@ def is_azure_document_intelligence_model(model: str) -> bool:
def is_azure_cohere_parse_model(model: str) -> bool:
- return "parse" in model.lower()
+ lowered: Final = model.lower()
+ return "cohere" in lowered and "parse" in lowered
def get_azure_ai_ocr_config(model: str) -> Optional["BaseOCRConfig"]:
diff --git a/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py b/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
index 01e1f59184c..8c4dd25aa77 100644
--- a/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
+++ b/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
@@ -40,7 +40,9 @@ def disable_aiohttp_transport(monkeypatch):
[
("Cohere-parse-v5", AzureAICohereParseConfig),
("cohere-parse-v5", AzureAICohereParseConfig),
- ("parse-v5", AzureAICohereParseConfig),
+ ("cohere/parse-v5", AzureAICohereParseConfig),
+ ("invoice-parser", AzureAIOCRConfig),
+ ("parse-v5", AzureAIOCRConfig),
("mistral-ocr-4-0", AzureAIOCRConfig),
("mistral-document-ai-2512", AzureAIOCRConfig),
("doc-intelligence/prebuilt-read", AzureDocumentIntelligenceOCRConfig),
From 004a8201167eb0bd85d52e86473adb9b9b8d1ee7 Mon Sep 17 00:00:00 2001
From: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Date: Fri, 4 Sep 2026 22:52:12 -0700
Subject: [PATCH 06/35] fix(ocr): send each provider a health-check document it
accepts
Health checks probed every OCR deployment with a PDF, which Cohere Parse
rejects, so /health, background health checks, and the UI Test Connection
button marked Cohere Parse deployments unhealthy. BaseOCRConfig gains a
get_health_check_document hook (PDF by default) that CohereParseConfig
overrides with a 1x1 PNG data URI. cohere also gains ocr in the provider
endpoint matrix
---
.../health_check_helpers.py | 18 +++++++-----
litellm/llms/base_llm/ocr/transformation.py | 8 +++++
litellm/llms/cohere/ocr/transformation.py | 9 ++++++
.../provider_endpoints_support_backup.json | 1 +
provider_endpoints_support.json | 1 +
.../test_health_check_helpers.py | 29 +++++++++++++++++++
...st_azure_ai_cohere_parse_transformation.py | 16 ++++++++++
.../ocr/test_cohere_parse_transformation.py | 12 ++++++++
8 files changed, 87 insertions(+), 7 deletions(-)
diff --git a/litellm/litellm_core_utils/health_check_helpers.py b/litellm/litellm_core_utils/health_check_helpers.py
index c745bbea5c4..9f8878d36f0 100644
--- a/litellm/litellm_core_utils/health_check_helpers.py
+++ b/litellm/litellm_core_utils/health_check_helpers.py
@@ -6,14 +6,13 @@ import base64
from collections.abc import Awaitable, Callable
from typing import TYPE_CHECKING, Final, Literal
-from litellm.types.utils import LIST_BATCHES_SUPPORTED_PROVIDERS
+from litellm.llms.base_llm.ocr.transformation import BaseOCRConfig, DocumentType
+from litellm.types.utils import LIST_BATCHES_SUPPORTED_PROVIDERS, LlmProviders
if TYPE_CHECKING:
from litellm.litellm_core_utils.litellm_logging import Logging
from litellm.types.utils import ImageResponse
-# Minimal PDF for health checks - base64 encoded 1-page PDF with just "test"
-TEST_PDF_URL = "data:application/pdf;base64,JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL01lZGlhQm94IFswIDAgNjEyIDc5Ml0KL0NvbnRlbnRzIDQgMCBSCi9SZXNvdXJjZXMgPDwvRm9udCA8PC9GMSAyIDAgUj4+Pj4+PgplbmRvYmoKNCAwIG9iago8PC9MZW5ndGggNDQ+PgpzdHJlYW0KQlQKL0YxIDI0IFRmCjEwMCA3MDAgVGQKKHRlc3QpIFRqCkVUCmVuZHN0cmVhbQplbmRvYmoKMiAwIG9iago8PC9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMQovQmFzZUZvbnQgL0hlbHZldGljYT4+CmVuZG9iagoxIDAgb2JqCjw8L1R5cGUgL1BhZ2VzCi9LaWRzIFszIDAgUl0KL0NvdW50IDE+PgplbmRvYmoKNSAwIG9iago8PC9UeXBlIC9DYXRhbG9nCi9QYWdlcyAxIDAgUj4+CmVuZG9iagp0cmFpbGVyCjw8L1NpemUgNgovUm9vdCA1IDAgUj4+CnN0YXJ0eHJlZgozMjQKJSVFT0Y="
# Minimal image for health checks - base64 encoded 512x512 blue circle on a white background PNG
TEST_IMAGE_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAIAAAB7GkOtAAAJk0lEQVR42u3VQREAIRADwVWCOmTjBVzwSLorCri6nbkAVBpPACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAAAgAAAIAZdY+HgEBgIRr/meeGgGA8EMvDAgAuPh6gACAi68HCAA4+mKAAICjLwYIALj7SoAAgLuvBAgA7r4pAQKAu29KgADg7psSIAA4/SYDCADuvikBAoDTbzKAAOD0mwwgADj9JgMIAE6/yQACgNNvMoAA4PSbDCAAOP0mAwgATr/JAAKA668BIAA4/TKAAOD0mwwgALj+pgEIAE6/yQACgOtvGoAA4PSbDCAAuP6mAQgATr/JAAKA628agADg9JsMIAC4/qYBCACuv2kAAoDrbxqAAOD0mwwgALj+pgEIAK6/aQACgOtvGoAA4PqbBiAArr+ZBiAATr+ZDCAArr+ZBiAArr+ZBiAArr+ZBiAArr+ZBggArr+ZBggArr+ZBggArr+ZBggArr+ZBggArr+ZBggArr+ZBggAAmAmAAKA62+mAQKA62+mAQKA62/m1xYAXH/TAAQA1980AAHA9TcNQAAEwEwAEADX30wDEADX30wDEADX30wDEADX30wDEAABMBMABMD1N9MABMD1N9MABEAAzAQAAXD9zTQAAXD9zTRAABAAMwEQAFx/Mw0QAFx/Mw0QAATATAAEANffTAMEANffTAMEAAEwEwABwPU30wABQADMBEAAXH8z0wABcP3NTAMEQADMTAAEwPU3Mw0QAAEwMwEQANffTAMQAAEwEwAEwPU30wAEQADMBAABcP3NNAABEAAzAUAAXH8zDUAABMBMABAA199MAwQAATATAAHA9TfTAAFAAMwEQABw/c00QAAQADMBEAAEwEwABMD1NzMNEAABMDMBEADX38w0QAAEwMwEQAAEwMwEQABcfzPTAAEQADMTAAEQADMTAAFw/c1MAwRAAMxMAARAAMxMAATA9TczDRAAATATAARAAMwEAAFw/c00AAEQADMBQAAEwEwAEADX30wDBAABMBMAAUAAzARAABAAMwEQAFx/Mw0QAAEwMwEQAAEwMwEQAAEwMwEQANffzDRAAATAzARAAATAzARAAATAzARAAATAzARAAFx/M9MAARAAMxMAARAAMxMAARAAMxMAARAAMxMAAXD9zUwDBEAAzEwABEAAzAQAARAAMwFAAATATAAQAAEwEwABQADMBEAAEAAzARAAXH8zDRAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAAATAzARAA19/MNEAANMDM9UcABMBMABAAATATAAHwBAJgJgACgACYCYAAIABmAiAA+IvMBEAABMDMBEAABMDMBEAABMDMBEAABMDMBEAABMDMBEAABMDMBEAABMDMBEAABMDMBEAABMDMBEAABMDMBEAANMDMXH8BEAAzEwABEAAzEwABEAAzEwABEAAzEwABEAAzEwABEAAzAUAABMBMABAADTBz/REAATATAAFAAMwEQAAQADMBEAAEwEwABAANMHP9BUAAzEwABEAAzEwABEAAzEwABEAAzEwABEADzMz1FwABMDMBEAABMDMBEAABMDMBEAANMDPXXwAEwMwEQAAEwMwEQAAEwMwEQAA0wMxcfwEQADMTAAEQADMBQAA0wMz1RwAEwEwAEAABMBMABEADzFx/AUAAzARAABAAMwEQADTAzPUXAATATAAEAAEwEwABQAPMXH8BEAAzEwABEAAzEwAB0AAzc/0FQADMTAAEQAPMzPUXAAEwMwEQAAEwMwEQAA0wM9dfAATAzARAADTAzFx/ARAAMwFAADTAzPVHAATATAAQAA0wc/0RAAEwEwAEQAPMXH8EQADMBAAB0AAz118AEAAzARAANMDM9RcABMBMAAQADTBz/QUAATATAAFAA8xcfwFAA8xcfwFAAMwEQADQADPXXwAEwMwEQAA0wMxcfwHQADNz/QVAAMxMAARAA8xcfwRAA8xcfwRAAMwEAAHQADPXHwHQADPXHwEQADMBQAA0wMz1RwA0wMz1RwAEwEwAEAANMHP9BQANMHP9BQANMHP9BQANMHP9BQABMBMAAUADzFx/AUADzFx/AUADzFx/AUADzFx/AUADzFx/AUADzPVHABAAEwAEAA0w1x8BQAPM9UcA0ABz/REANMBcfwQADTDXHwHQADPXHwHQADPXHwHQADPXHwHQADPXHwHQADPXHwGQATOnHwHQADPXHwHQADPXXwDQADPXXwDQADPXXwDQADPXXwCQAXP6EQA0wFx/BAANMNcfAUADzPVHAJABc/oRADTAXH8EABkwpx8BQAPM9UcAkAFz+hEANMBcfwQAGTCnHwFAA8z1RwCQAXP6EQBkwJx+BAANMNcfAUAGzOlHAJABc/oRAGTA6QcBQAacfhAAZMDpRwBABpx+BABkwOlHAEAGnH4EAJTA3UcAQAacfgQAlMDdRwBACdx9BACUwN1HAEAJ3H0EAJTA3UcAQAwcfQQAmmLgsyIA0NIDHw4BgJYe+DQIAISHwVMjAJDQDI+AAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACACAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAgAAAIAAACAIAAACAAAAgAAAIAgAAAIAAACAAAAgCAAAAIAABNHpialFcmLajuAAAAAElFTkSuQmCC"
@@ -29,6 +28,14 @@ def get_image_file_for_health_check() -> bytes:
return base64.b64decode(TEST_IMAGE_BASE64)
+def _ocr_health_check_document(model: str, custom_llm_provider: str) -> DocumentType:
+ from litellm.utils import ProviderConfigManager
+
+ provider: Final = next((known for known in LlmProviders if known.value == custom_llm_provider), None)
+ config: Final = ProviderConfigManager.get_provider_ocr_config(model=model, provider=provider) if provider else None
+ return (config or BaseOCRConfig()).get_health_check_document()
+
+
class HealthCheckHelpers:
@staticmethod
async def ahealth_check_wildcard_models(
@@ -247,9 +254,6 @@ class HealthCheckHelpers:
),
"ocr": lambda: litellm.aocr(
**_filter_model_params(model_params=model_params),
- document={
- "type": "document_url",
- "document_url": TEST_PDF_URL,
- },
+ document=_ocr_health_check_document(model=model, custom_llm_provider=custom_llm_provider),
),
}
diff --git a/litellm/llms/base_llm/ocr/transformation.py b/litellm/llms/base_llm/ocr/transformation.py
index 08ae077cb2f..8111f9a194a 100644
--- a/litellm/llms/base_llm/ocr/transformation.py
+++ b/litellm/llms/base_llm/ocr/transformation.py
@@ -33,6 +33,8 @@ OCR_REQUEST_FORMAT_HEADER: Final = "x-req-format"
PROVIDER_NATIVE_RESPONSE_KEY: Final = "provider_native_response"
+HEALTH_CHECK_PDF_DATA_URI: Final = "data:application/pdf;base64,JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL01lZGlhQm94IFswIDAgNjEyIDc5Ml0KL0NvbnRlbnRzIDQgMCBSCi9SZXNvdXJjZXMgPDwvRm9udCA8PC9GMSAyIDAgUj4+Pj4+PgplbmRvYmoKNCAwIG9iago8PC9MZW5ndGggNDQ+PgpzdHJlYW0KQlQKL0YxIDI0IFRmCjEwMCA3MDAgVGQKKHRlc3QpIFRqCkVUCmVuZHN0cmVhbQplbmRvYmoKMiAwIG9iago8PC9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMQovQmFzZUZvbnQgL0hlbHZldGljYT4+CmVuZG9iagoxIDAgb2JqCjw8L1R5cGUgL1BhZ2VzCi9LaWRzIFszIDAgUl0KL0NvdW50IDE+PgplbmRvYmoKNSAwIG9iago8PC9UeXBlIC9DYXRhbG9nCi9QYWdlcyAxIDAgUj4+CmVuZG9iagp0cmFpbGVyCjw8L1NpemUgNgovUm9vdCA1IDAgUj4+CnN0YXJ0eHJlZgozMjQKJSVFT0Y="
+
def parse_ocr_request_format(value: object) -> OCRRequestFormat:
if value == "litellm":
@@ -146,6 +148,12 @@ class BaseOCRConfig:
"""Whether the Rust OCR bridge may serve this config when it is enabled for the provider."""
return True
+ def get_health_check_document(self) -> DocumentType:
+ return { # mutable-ok: litellm.aocr rejects any document that is not a dict
+ "type": "document_url",
+ "document_url": HEALTH_CHECK_PDF_DATA_URI,
+ }
+
def map_ocr_params(
self,
non_default_params: dict,
diff --git a/litellm/llms/cohere/ocr/transformation.py b/litellm/llms/cohere/ocr/transformation.py
index 87454980aa4..dd15d5360a6 100644
--- a/litellm/llms/cohere/ocr/transformation.py
+++ b/litellm/llms/cohere/ocr/transformation.py
@@ -34,6 +34,9 @@ COHERE_PARSE_OUTPUT_FORMAT_PARAM: Final = "output_format"
COHERE_PARSE_OUTPUT_FORMATS: Final = ("markdown", "blocks")
COHERE_PARSE_DEFAULT_OUTPUT_FORMAT: Final = "markdown"
COHERE_PARSE_SUPPORTED_PARAMS: Final = (COHERE_PARSE_OUTPUT_FORMAT_PARAM, OCR_REQUEST_FORMAT_PARAM)
+COHERE_PARSE_HEALTH_CHECK_IMAGE_DATA_URI: Final = (
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4//8/AAX+Av4N70a4AAAAAElFTkSuQmCC"
+)
COHERE_PARSE_IMAGE_ONLY_MESSAGE: Final = (
"Cohere Parse only accepts `image_url` documents (an image URL or a base64 image data URI); "
"`document_url` and PDF inputs are not supported."
@@ -144,6 +147,12 @@ class CohereParseConfig(BaseOCRConfig):
def supports_rust_bridge(self) -> bool:
return False
+ def get_health_check_document(self) -> DocumentType:
+ return { # mutable-ok: litellm.aocr rejects any document that is not a dict
+ "type": "image_url",
+ "image_url": COHERE_PARSE_HEALTH_CHECK_IMAGE_DATA_URI,
+ }
+
def _llm_provider(self) -> str:
return "cohere"
diff --git a/litellm/provider_endpoints_support_backup.json b/litellm/provider_endpoints_support_backup.json
index 9d6b1e18f59..dbeaccdda2d 100644
--- a/litellm/provider_endpoints_support_backup.json
+++ b/litellm/provider_endpoints_support_backup.json
@@ -559,6 +559,7 @@
"moderations": false,
"batches": false,
"rerank": true,
+ "ocr": true,
"a2a": true,
"interactions": true
}
diff --git a/provider_endpoints_support.json b/provider_endpoints_support.json
index 41ed8e1d975..c71f4a82a4a 100644
--- a/provider_endpoints_support.json
+++ b/provider_endpoints_support.json
@@ -594,6 +594,7 @@
"moderations": false,
"batches": false,
"rerank": true,
+ "ocr": true,
"a2a": true,
"interactions": true
}
diff --git a/tests/test_litellm/litellm_core_utils/test_health_check_helpers.py b/tests/test_litellm/litellm_core_utils/test_health_check_helpers.py
index ee2a31beff7..89b377af3a0 100644
--- a/tests/test_litellm/litellm_core_utils/test_health_check_helpers.py
+++ b/tests/test_litellm/litellm_core_utils/test_health_check_helpers.py
@@ -453,3 +453,32 @@ async def test_realtime_health_check_uses_model_level_vertex_params():
"Authorization": "Bearer model-level-token",
"x-goog-user-project": "model-level-project",
}
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+ "model, custom_llm_provider, expected_document_type, expected_uri_prefix",
+ [
+ ("mistral/mistral-ocr-latest", "mistral", "document_url", "data:application/pdf;base64,"),
+ ("azure_ai/mistral-document-ai-2512", "azure_ai", "document_url", "data:application/pdf;base64,"),
+ ("cohere/parse-v5.0", "cohere", "image_url", "data:image/png;base64,"),
+ ("azure_ai/Cohere-parse-v5", "azure_ai", "image_url", "data:image/png;base64,"),
+ ],
+)
+async def test_ocr_health_check_sends_the_document_kind_the_provider_config_accepts(
+ model, custom_llm_provider, expected_document_type, expected_uri_prefix
+):
+ handlers = HealthCheckHelpers.get_mode_handlers(
+ model=model,
+ custom_llm_provider=custom_llm_provider,
+ model_params={"model": model, "api_key": "sk-test"},
+ )
+
+ with patch( # test-quality-ok: the public health-check path has no dependency injection seam
+ "litellm.aocr", new_callable=AsyncMock, return_value={}
+ ) as mock_aocr:
+ await handlers["ocr"]()
+
+ document = mock_aocr.call_args.kwargs["document"]
+ assert document["type"] == expected_document_type
+ assert document[expected_document_type].startswith(expected_uri_prefix)
diff --git a/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py b/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
index 8c4dd25aa77..3f98e9b6a2d 100644
--- a/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
+++ b/tests/test_litellm/llms/azure_ai/ocr/test_azure_ai_cohere_parse_transformation.py
@@ -166,3 +166,19 @@ async def test_aocr_rejects_pdf_before_calling_foundry(disable_aiohttp_transport
assert exc_info.value.llm_provider == "azure_ai"
assert not route.called
+
+
+@pytest.mark.asyncio
+async def test_ahealth_check_ocr_sends_an_image_to_the_foundry_cohere_parse_deployment(
+ disable_aiohttp_transport, respx_mock
+):
+ route = respx_mock.post(PARSE_URL).respond(json=_parse_response())
+
+ result = await litellm.ahealth_check(
+ model_params={"model": MODEL, "api_base": API_BASE, "api_key": "test-key"}, mode="ocr"
+ )
+
+ document = json.loads(route.calls.last.request.content)["document"]
+ assert document["type"] == "image_url"
+ assert document["image_url"].startswith("data:image/png;base64,")
+ assert "error" not in result
diff --git a/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_transformation.py b/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_transformation.py
index 64f2bb383c2..cb9af56f5e0 100644
--- a/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_transformation.py
+++ b/tests/test_litellm/llms/cohere/ocr/test_cohere_parse_transformation.py
@@ -215,3 +215,15 @@ async def test_aocr_without_api_key_names_the_env_var(disable_aiohttp_transport,
await litellm.aocr(model=MODEL, document=IMAGE_DOCUMENT)
assert not route.called
+
+
+@pytest.mark.asyncio
+async def test_ahealth_check_ocr_sends_an_image_cohere_parse_accepts(disable_aiohttp_transport, respx_mock):
+ route = respx_mock.post(PARSE_URL).respond(json=_markdown_response())
+
+ result = await litellm.ahealth_check(model_params={"model": MODEL, "api_key": "test-key"}, mode="ocr")
+
+ document = json.loads(route.calls.last.request.content)["document"]
+ assert document["type"] == "image_url"
+ assert document["image_url"].startswith("data:image/png;base64,")
+ assert "error" not in result
From 5a22edb6c3e223f1fecd08eeb966b4ce65b7b3ce Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Sat, 5 Sep 2026 12:07:48 -0700
Subject: [PATCH 07/35] feat(ui): explain how guardrail usage and cost are
calculated
Adds a "How is this calculated?" hover to the Guardrail Cost card on the
overview and to the Cost and Usage Units cards on the detail page. The
overview hint lists each guardrail's cost and the total; the detail cost
hint shows units x per-unit price per counter with unpriced units called
out, and the units hint shows the per-counter sum. Also moves the Status
column to the front of the overview table.
Refs LIT-5652
---
.../GuardrailUsageBreakdown.test.tsx | 32 +++++++++
.../_components/GuardrailUsageBreakdown.tsx | 31 +++++++-
.../_components/GuardrailsOverview.test.tsx | 14 ++++
.../_components/GuardrailsOverview.tsx | 67 ++++++++++++-----
.../GuardrailsMonitor/MetricCard.tsx | 25 ++++++-
.../GuardrailsMonitor/usageUnits.test.ts | 71 ++++++++++++++++++-
.../GuardrailsMonitor/usageUnits.ts | 32 +++++++++
7 files changed, 250 insertions(+), 22 deletions(-)
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
index 7929b97b000..ba90ca8e6ff 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
@@ -1,4 +1,5 @@
import { render, screen, within } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
import { describe, expect, it } from "vitest";
import type { GuardrailUsageDetail } from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
import { GuardrailUsageBreakdown } from "./GuardrailUsageBreakdown";
@@ -84,6 +85,37 @@ describe("GuardrailUsageBreakdown", () => {
expect(within(unpricedKey).getByText("7", { selector: ".text-warning" })).toBeInTheDocument();
});
+ it("explains the cost math per counter on hover", async () => {
+ const user = userEvent.setup();
+ render( );
+
+ await user.hover(
+ within(screen.getByRole("group", { name: "Cost" })).getByRole("button", { name: /How is this calculated/ }),
+ );
+
+ expect(await screen.findByText("Content Policy: 1,000 × $0.00015 = $0.1500")).toBeInTheDocument();
+ expect(screen.getByText("Sensitive Information Policy: 300 × $0.0001 = $0.0300")).toBeInTheDocument();
+ expect(screen.getByText("Some Future Counter: 7 units with no known price, left out")).toBeInTheDocument();
+ expect(screen.getByText("Total: $0.1800")).toBeInTheDocument();
+ });
+
+ it("explains the units sum on hover", async () => {
+ const user = userEvent.setup();
+ render( );
+
+ await user.hover(
+ within(screen.getByRole("group", { name: "Usage Units" })).getByRole("button", {
+ name: /How is this calculated/,
+ }),
+ );
+
+ expect(
+ await screen.findByText(
+ "Content Policy 1,000 + Sensitive Information Policy 300 + Some Future Counter 7 = 1,307",
+ ),
+ ).toBeInTheDocument();
+ });
+
it("orders teams and keys by units, largest first", () => {
render( );
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
index 6e8b725aa2e..01dd8f79ce4 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
@@ -3,7 +3,14 @@ import { CircleDollarSign } from "lucide-react";
import React from "react";
import type { GuardrailUsageDetail } from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
import { MetricCard } from "@/components/GuardrailsMonitor/MetricCard";
-import { counterLabel, formatCost, totalUnits, unpricedSummary } from "@/components/GuardrailsMonitor/usageUnits";
+import {
+ counterLabel,
+ counterMathLine,
+ formatCost,
+ totalUnits,
+ unitsSumLine,
+ unpricedSummary,
+} from "@/components/GuardrailsMonitor/usageUnits";
import { DataTable } from "@/components/shared/DataTable";
import { IdCell } from "@/components/shared/table_cells/id_cell";
import { MoneyCell } from "@/components/shared/table_cells/money_cell";
@@ -104,6 +111,26 @@ const groupColumns = (label: string, emptyLabel: string): ColumnDef[]
const teamColumns = groupColumns("Team", "No team");
const keyColumns = groupColumns("Key", "No key");
+const CostMath = ({ counters, total }: { counters: CounterRow[]; total: number | null }) => (
+
+ {counters.map((row) => (
+
{counterMathLine(row)}
+ ))}
+
Total: {formatCost(total)}
+
Per-unit prices come from the bedrock/guardrails entry in the cost map.
+
+);
+
+const UnitsMath = ({ units }: { units: GuardrailUsageDetail["usage_units"] }) => (
+
+
{unitsSumLine(units)}
+
+ Bedrock reports one unit per 1,000 characters of the message for each policy the guardrail has on, on every call,
+ blocked or not.
+
+
+);
+
const TableHeading = ({ title }: { title: string }) => (
{title}
);
@@ -132,11 +159,13 @@ export function GuardrailUsageBreakdown({ detail }: { detail: GuardrailUsageDeta
valueColor={detail.cost != null ? "text-foreground" : "text-muted-foreground"}
icon={ }
subtitle={unpriced ?? undefined}
+ hint={ }
/>
}
/>
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
index c52645def70..14e070afc0d 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
@@ -211,6 +211,20 @@ describe("GuardrailsOverview", () => {
expect(card).toHaveTextContent("250 units unpriced");
});
+ it("explains the guardrail cost total on hover", async () => {
+ const user = userEvent.setup();
+ renderOverview();
+
+ const card = await screen.findByRole("group", { name: "Guardrail Cost" });
+ await user.hover(within(card).getByRole("button", { name: /How is this calculated/ }));
+
+ expect(await screen.findByText("High Failure Guardrail: $0.1500")).toBeInTheDocument();
+ expect(screen.getByText("Free Bedrock Guardrail: $0.0000")).toBeInTheDocument();
+ expect(screen.queryByText(/Low Failure Guardrail: /)).not.toBeInTheDocument();
+ expect(screen.getByText("Total: $0.1500")).toBeInTheDocument();
+ expect(screen.getByText(/250 units unpriced had no known price and are left out/)).toBeInTheDocument();
+ });
+
it("shows a dash for guardrail cost when nothing in the window was priced", async () => {
useGuardrailsUsageOverviewMock.mockReturnValue({
data: { ...overview, totalCost: null, totalUntrackedUsageUnits: {} },
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
index 0bbda6015b4..3df7058baba 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
@@ -63,6 +63,34 @@ function UsageUnitsCell({ units }: { units: GuardrailUsageOverviewRow["usageUnit
);
}
+function TotalCostMath({
+ rows,
+ total,
+ unpriced,
+}: {
+ rows: GuardrailUsageOverviewRow[];
+ total: number | null;
+ unpriced: string | null;
+}) {
+ return (
+
+ {rows
+ .filter((row) => row.cost != null)
+ .map((row) => (
+
+ {row.name}: {formatCost(row.cost)}
+
+ ))}
+
Total: {formatCost(total)}
+
+ {`Each guardrail's cost is its units per policy × that policy's per-unit price from the cost map, added up${
+ unpriced ? `; ${unpriced} had no known price and are left out` : ""
+ }. Open a guardrail for its per-policy math.`}
+
+
+ );
+}
+
function CostCell({ row }: { row: GuardrailUsageOverviewRow }) {
const unpriced = unpricedSummary(row.untrackedUsageUnits);
return (
@@ -124,6 +152,25 @@ export function GuardrailsOverview({
const error = guardrailsError;
const columns: ColumnDef[] = [
+ {
+ header: "Status",
+ accessorKey: "status",
+ enableSorting: false,
+ cell: ({ row }) => (
+
+
+ {row.original.status}
+
+ ),
+ },
{
header: "Guardrail",
accessorKey: "name",
@@ -215,25 +262,6 @@ export function GuardrailsOverview({
sortDescFirst: false,
cell: ({ row }) => ,
},
- {
- header: "Status",
- accessorKey: "status",
- enableSorting: false,
- cell: ({ row }) => (
-
-
- {row.original.status}
-
- ),
- },
];
const sortableKeys: SortKey[] = ["failRate", "requestsEvaluated", "avgLatency", "cost"];
@@ -291,6 +319,7 @@ export function GuardrailsOverview({
valueColor={metrics.totalCost != null ? "text-foreground" : "text-muted-foreground"}
icon={ }
subtitle={metrics.unpriced ?? undefined}
+ hint={ }
/>
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx b/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
index c0b5e0a50d1..1805dc797e4 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
@@ -1,4 +1,6 @@
+import { CircleHelp } from "lucide-react";
import React, { type ReactNode } from "react";
+import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
interface MetricCardProps {
label: string;
@@ -6,9 +8,10 @@ interface MetricCardProps {
valueColor?: string;
icon?: ReactNode;
subtitle?: string;
+ hint?: ReactNode;
}
-export function MetricCard({ label, value, valueColor = "text-foreground", icon, subtitle }: MetricCardProps) {
+export function MetricCard({ label, value, valueColor = "text-foreground", icon, subtitle, hint }: MetricCardProps) {
return (
@@ -17,6 +20,26 @@ export function MetricCard({ label, value, valueColor = "text-foreground", icon,
{value}
{subtitle &&
{subtitle}
}
+ {hint && (
+
+
+
+
+ How is this calculated?
+
+ }
+ />
+
+ {hint}
+
+
+
+ )}
);
}
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
index 29362cc3701..560010bd852 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
@@ -1,5 +1,14 @@
import { describe, expect, it } from "vitest";
-import { counterLabel, formatCost, totalUnits, unpricedSummary } from "./usageUnits";
+import {
+ counterLabel,
+ counterMathLine,
+ formatCost,
+ formatUnitPrice,
+ totalUnits,
+ unitPrice,
+ unitsSumLine,
+ unpricedSummary,
+} from "./usageUnits";
describe("formatCost", () => {
it("renders a dash when nothing was priced", () => {
@@ -53,3 +62,63 @@ describe("unpricedSummary", () => {
expect(unpricedSummary({ someFutureCounter: 1 })).toBe("1 unit unpriced");
});
});
+
+describe("unitPrice", () => {
+ it("backs the per-unit price out of the priced share only", () => {
+ expect(unitPrice({ counter: "contentPolicyUnits", units: 1200, unpriced: 200, cost: 0.15 })).toBeCloseTo(
+ 0.00015,
+ 10,
+ );
+ });
+
+ it("is null when nothing was priced", () => {
+ expect(unitPrice({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: null })).toBeNull();
+ expect(unitPrice({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: 0 })).toBeNull();
+ });
+});
+
+describe("formatUnitPrice", () => {
+ it("keeps the significant decimals and drops trailing zeros", () => {
+ expect(formatUnitPrice(0.0001)).toBe("$0.0001");
+ expect(formatUnitPrice(0.00015)).toBe("$0.00015");
+ expect(formatUnitPrice(0)).toBe("$0");
+ expect(formatUnitPrice(1)).toBe("$1");
+ });
+});
+
+describe("counterMathLine", () => {
+ it("shows units × price = cost for a fully priced counter", () => {
+ expect(counterMathLine({ counter: "contentPolicyUnits", units: 1000, unpriced: 0, cost: 0.15 })).toBe(
+ "Content Policy: 1,000 × $0.00015 = $0.1500",
+ );
+ });
+
+ it("prices only the priced share and calls out the rest", () => {
+ expect(counterMathLine({ counter: "sensitiveInformationPolicyUnits", units: 8, unpriced: 2, cost: 0.0006 })).toBe(
+ "Sensitive Information Policy: 6 × $0.0001 = $0.0006 (2 unpriced left out)",
+ );
+ });
+
+ it("says so when a counter has no known price at all", () => {
+ expect(counterMathLine({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: null })).toBe(
+ "Some Future Counter: 7 units with no known price, left out",
+ );
+ expect(counterMathLine({ counter: "someFutureCounter", units: 1, unpriced: 1, cost: null })).toBe(
+ "Some Future Counter: 1 unit with no known price, left out",
+ );
+ });
+
+ it("shows a free counter as × $0", () => {
+ expect(counterMathLine({ counter: "wordPolicyUnits", units: 2, unpriced: 0, cost: 0 })).toBe(
+ "Word Policy: 2 × $0 = $0.0000",
+ );
+ });
+});
+
+describe("unitsSumLine", () => {
+ it("adds the counters up in order", () => {
+ expect(unitsSumLine({ contentPolicyUnits: 2, topicPolicyUnits: 2, wordPolicyUnits: 1200 })).toBe(
+ "Content Policy 2 + Topic Policy 2 + Word Policy 1,200 = 1,204",
+ );
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
index f3a5e9d7140..05e046aaace 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
@@ -19,3 +19,35 @@ export const unpricedSummary = (untracked: UsageUnits): string | null => {
const total = totalUnits(untracked);
return total > 0 ? `${total.toLocaleString()} ${total === 1 ? "unit" : "units"} unpriced` : null;
};
+
+export interface CounterMath {
+ readonly counter: string;
+ readonly units: number;
+ readonly unpriced: number;
+ readonly cost: number | null;
+}
+
+export const pricedUnits = ({ units, unpriced }: Pick
): number =>
+ Math.max(units - unpriced, 0);
+
+export const unitPrice = (row: CounterMath): number | null => {
+ const priced = pricedUnits(row);
+ return row.cost != null && priced > 0 ? row.cost / priced : null;
+};
+
+export const formatUnitPrice = (price: number): string => `$${price.toFixed(6).replace(/\.?0+$/, "")}`;
+
+export const counterMathLine = (row: CounterMath): string => {
+ const label = counterLabel(row.counter);
+ const price = unitPrice(row);
+ if (price == null) {
+ return `${label}: ${row.units.toLocaleString()} ${row.units === 1 ? "unit" : "units"} with no known price, left out`;
+ }
+ const line = `${label}: ${pricedUnits(row).toLocaleString()} × ${formatUnitPrice(price)} = ${formatCost(row.cost)}`;
+ return row.unpriced > 0 ? `${line} (${row.unpriced.toLocaleString()} unpriced left out)` : line;
+};
+
+export const unitsSumLine = (units: UsageUnits): string =>
+ `${Object.entries(units)
+ .map(([counter, n]) => `${counterLabel(counter)} ${n.toLocaleString()}`)
+ .join(" + ")} = ${totalUnits(units).toLocaleString()}`;
From e66ba0533fe43a626b8a157fae59f507894aa13b Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Sat, 5 Sep 2026 12:23:07 -0700
Subject: [PATCH 08/35] fix(ui): keep guardrail cost hints provider neutral and
link to a pricing request
The hint copy described Bedrock's unit semantics and cost map entry even
though any provider's units reach this view, so it now explains the math
in provider-neutral terms. When units have no known price, the hint says
so and links to a prefilled GitHub feature request (provider and counter
names filled in) so the reader can ask for pricing. Per-unit prices below
$0.000001 now read "< $0.000001" instead of "$0".
Refs LIT-5652
---
.../GuardrailUsageBreakdown.test.tsx | 28 +++++++++++++++++++
.../_components/GuardrailUsageBreakdown.tsx | 15 +++++-----
.../_components/GuardrailsOverview.test.tsx | 6 +++-
.../_components/GuardrailsOverview.tsx | 26 ++++++++++-------
.../GuardrailsMonitor/UnpricedNote.tsx | 21 ++++++++++++++
.../GuardrailsMonitor/usageUnits.test.ts | 22 +++++++++++++++
.../GuardrailsMonitor/usageUnits.ts | 15 +++++++++-
7 files changed, 113 insertions(+), 20 deletions(-)
create mode 100644 ui/litellm-dashboard/src/components/GuardrailsMonitor/UnpricedNote.tsx
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
index ba90ca8e6ff..3a0a4c38ecb 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
@@ -97,6 +97,34 @@ describe("GuardrailUsageBreakdown", () => {
expect(screen.getByText("Sensitive Information Policy: 300 × $0.0001 = $0.0300")).toBeInTheDocument();
expect(screen.getByText("Some Future Counter: 7 units with no known price, left out")).toBeInTheDocument();
expect(screen.getByText("Total: $0.1800")).toBeInTheDocument();
+ expect(screen.getByText(/7 units with no known price are left out of the cost/)).toBeInTheDocument();
+ const issueLink = screen.getByRole("link", { name: "Request pricing on GitHub" });
+ expect(issueLink).toHaveAttribute("target", "_blank");
+ const issueUrl = new URL(issueLink.getAttribute("href") ?? "");
+ expect(issueUrl.searchParams.get("title")).toBe("[Feature]: add Bedrock guardrail pricing to the cost map");
+ expect(issueUrl.searchParams.get("the-feature")).toContain("someFutureCounter");
+ });
+
+ it("does not ask for pricing when every unit was priced", async () => {
+ const user = userEvent.setup();
+ render(
+ ,
+ );
+
+ await user.hover(
+ within(screen.getByRole("group", { name: "Cost" })).getByRole("button", { name: /How is this calculated/ }),
+ );
+
+ expect(await screen.findByText("Total: $0.1500")).toBeInTheDocument();
+ expect(screen.queryByRole("link", { name: "Request pricing on GitHub" })).not.toBeInTheDocument();
});
it("explains the units sum on hover", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
index 01dd8f79ce4..e67425adb10 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
@@ -3,6 +3,7 @@ import { CircleDollarSign } from "lucide-react";
import React from "react";
import type { GuardrailUsageDetail } from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
import { MetricCard } from "@/components/GuardrailsMonitor/MetricCard";
+import { UnpricedNote } from "@/components/GuardrailsMonitor/UnpricedNote";
import {
counterLabel,
counterMathLine,
@@ -111,23 +112,21 @@ const groupColumns = (label: string, emptyLabel: string): ColumnDef[]
const teamColumns = groupColumns("Team", "No team");
const keyColumns = groupColumns("Key", "No key");
-const CostMath = ({ counters, total }: { counters: CounterRow[]; total: number | null }) => (
+const CostMath = ({ counters, detail }: { counters: CounterRow[]; detail: GuardrailUsageDetail }) => (
{counters.map((row) => (
{counterMathLine(row)}
))}
-
Total: {formatCost(total)}
-
Per-unit prices come from the bedrock/guardrails entry in the cost map.
+
Total: {formatCost(detail.cost)}
+
Each counter is its priced units × the per-unit price LiteLLM has for it in the cost map.
+
);
const UnitsMath = ({ units }: { units: GuardrailUsageDetail["usage_units"] }) => (
{unitsSumLine(units)}
-
- Bedrock reports one unit per 1,000 characters of the message for each policy the guardrail has on, on every call,
- blocked or not.
-
+
Units are the billable counters the provider reported for this guardrail, added up over every call.
);
@@ -159,7 +158,7 @@ export function GuardrailUsageBreakdown({ detail }: { detail: GuardrailUsageDeta
valueColor={detail.cost != null ? "text-foreground" : "text-muted-foreground"}
icon={ }
subtitle={unpriced ?? undefined}
- hint={ }
+ hint={ }
/>
{
expect(screen.getByText("Free Bedrock Guardrail: $0.0000")).toBeInTheDocument();
expect(screen.queryByText(/Low Failure Guardrail: /)).not.toBeInTheDocument();
expect(screen.getByText("Total: $0.1500")).toBeInTheDocument();
- expect(screen.getByText(/250 units unpriced had no known price and are left out/)).toBeInTheDocument();
+ expect(screen.getByText(/250 units with no known price are left out of the cost/)).toBeInTheDocument();
+ const issueLink = screen.getByRole("link", { name: "Request pricing on GitHub" });
+ const issueUrl = new URL(issueLink.getAttribute("href") ?? "");
+ expect(issueUrl.searchParams.get("template")).toBe("feature_request.yml");
+ expect(issueUrl.searchParams.get("the-feature")).toContain("sensitiveInformationPolicyUnits");
});
it("shows a dash for guardrail cost when nothing in the window was priced", async () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
index 3df7058baba..33be85f3c81 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
@@ -8,7 +8,14 @@ import {
type GuardrailUsageOverviewRow,
useGuardrailsUsageOverview,
} from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
-import { counterLabel, formatCost, totalUnits, unpricedSummary } from "@/components/GuardrailsMonitor/usageUnits";
+import { UnpricedNote } from "@/components/GuardrailsMonitor/UnpricedNote";
+import {
+ counterLabel,
+ formatCost,
+ totalUnits,
+ unpricedSummary,
+ type UsageUnits,
+} from "@/components/GuardrailsMonitor/usageUnits";
import { Button } from "@/components/ui/button";
import { PageHeader } from "@/components/shared/PageHeader";
import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
@@ -41,7 +48,7 @@ const EMPTY_METRICS = {
avgLatency: 0,
count: 0,
totalCost: null as number | null,
- unpriced: null as string | null,
+ untracked: {} as UsageUnits,
};
function UsageUnitsCell({ units }: { units: GuardrailUsageOverviewRow["usageUnits"] }) {
@@ -66,11 +73,11 @@ function UsageUnitsCell({ units }: { units: GuardrailUsageOverviewRow["usageUnit
function TotalCostMath({
rows,
total,
- unpriced,
+ untracked,
}: {
rows: GuardrailUsageOverviewRow[];
total: number | null;
- unpriced: string | null;
+ untracked: UsageUnits;
}) {
return (
@@ -83,10 +90,9 @@ function TotalCostMath({
))}
Total: {formatCost(total)}
- {`Each guardrail's cost is its units per policy × that policy's per-unit price from the cost map, added up${
- unpriced ? `; ${unpriced} had no known price and are left out` : ""
- }. Open a guardrail for its per-policy math.`}
+ {`Each guardrail's cost is its units per counter × that counter's per-unit price from the cost map, added up. Open a guardrail for its per-counter math.`}
+
);
}
@@ -135,7 +141,7 @@ export function GuardrailsOverview({
: 0,
count: activeData.length,
totalCost: guardrailsData.totalCost,
- unpriced: unpricedSummary(guardrailsData.totalUntrackedUsageUnits),
+ untracked: guardrailsData.totalUntrackedUsageUnits,
};
}, [guardrailsData, activeData]);
const chartData = guardrailsData?.chart;
@@ -318,8 +324,8 @@ export function GuardrailsOverview({
value={formatCost(metrics.totalCost)}
valueColor={metrics.totalCost != null ? "text-foreground" : "text-muted-foreground"}
icon={ }
- subtitle={metrics.unpriced ?? undefined}
- hint={ }
+ subtitle={unpricedSummary(metrics.untracked) ?? undefined}
+ hint={ }
/>
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/UnpricedNote.tsx b/ui/litellm-dashboard/src/components/GuardrailsMonitor/UnpricedNote.tsx
new file mode 100644
index 00000000000..174124d18aa
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/UnpricedNote.tsx
@@ -0,0 +1,21 @@
+import React from "react";
+import { pricingIssueUrl, totalUnits, type UsageUnits } from "./usageUnits";
+
+export function UnpricedNote({ unpriced, provider }: { unpriced: UsageUnits; provider?: string }) {
+ const total = totalUnits(unpriced);
+ if (total === 0) return null;
+ const [noun, verb] = total === 1 ? ["unit", "is"] : ["units", "are"];
+ return (
+
+ );
+}
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
index 560010bd852..9b45eefaf54 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
@@ -4,6 +4,7 @@ import {
counterMathLine,
formatCost,
formatUnitPrice,
+ pricingIssueUrl,
totalUnits,
unitPrice,
unitsSumLine,
@@ -84,6 +85,10 @@ describe("formatUnitPrice", () => {
expect(formatUnitPrice(0)).toBe("$0");
expect(formatUnitPrice(1)).toBe("$1");
});
+
+ it("never shows a positive price as free", () => {
+ expect(formatUnitPrice(0.0000002)).toBe("< $0.000001");
+ });
});
describe("counterMathLine", () => {
@@ -122,3 +127,20 @@ describe("unitsSumLine", () => {
);
});
});
+
+describe("pricingIssueUrl", () => {
+ it("prefills the feature request with the provider and the unpriced counters", () => {
+ const url = new URL(pricingIssueUrl({ text_records: 5, someFutureCounter: 7 }, "azure/prompt_shield"));
+
+ expect(url.origin + url.pathname).toBe("https://github.com/BerriAI/litellm/issues/new");
+ expect(url.searchParams.get("template")).toBe("feature_request.yml");
+ expect(url.searchParams.get("title")).toBe("[Feature]: add azure/prompt_shield guardrail pricing to the cost map");
+ expect(url.searchParams.get("the-feature")).toContain("text_records, someFutureCounter");
+ });
+
+ it("stays generic when no provider is known", () => {
+ const url = new URL(pricingIssueUrl({ text_records: 5 }));
+
+ expect(url.searchParams.get("title")).toBe("[Feature]: add guardrail pricing to the cost map");
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
index 05e046aaace..f914a3e9698 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
@@ -35,7 +35,10 @@ export const unitPrice = (row: CounterMath): number | null => {
return row.cost != null && priced > 0 ? row.cost / priced : null;
};
-export const formatUnitPrice = (price: number): string => `$${price.toFixed(6).replace(/\.?0+$/, "")}`;
+export const formatUnitPrice = (price: number): string => {
+ const fixed = price.toFixed(6).replace(/\.?0+$/, "");
+ return price > 0 && Number(fixed) === 0 ? "< $0.000001" : `$${fixed}`;
+};
export const counterMathLine = (row: CounterMath): string => {
const label = counterLabel(row.counter);
@@ -51,3 +54,13 @@ export const unitsSumLine = (units: UsageUnits): string =>
`${Object.entries(units)
.map(([counter, n]) => `${counterLabel(counter)} ${n.toLocaleString()}`)
.join(" + ")} = ${totalUnits(units).toLocaleString()}`;
+
+export const pricingIssueUrl = (unpriced: UsageUnits, provider?: string): string => {
+ const subject = provider ? `${provider} guardrail` : "guardrail";
+ const params = new URLSearchParams({
+ template: "feature_request.yml",
+ title: `[Feature]: add ${subject} pricing to the cost map`,
+ "the-feature": `LiteLLM has no price for these ${subject} usage units, so the Guardrails Monitor leaves them out of the cost: ${Object.keys(unpriced).join(", ")}`,
+ });
+ return `https://github.com/BerriAI/litellm/issues/new?${params.toString()}`;
+};
From def734923f683055f04fc5e46d9ef78ecf912381 Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 12:55:30 -0700
Subject: [PATCH 09/35] test(e2e): prove Vertex context caching on the first
cold call and on the spend row
---
.../e2e/llm_translation/test_cache_control.py | 76 +++++++++++++++++--
tests/e2e/models.py | 1 +
2 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/tests/e2e/llm_translation/test_cache_control.py b/tests/e2e/llm_translation/test_cache_control.py
index 0d224061381..3ad98bc6072 100644
--- a/tests/e2e/llm_translation/test_cache_control.py
+++ b/tests/e2e/llm_translation/test_cache_control.py
@@ -8,8 +8,12 @@ Each case asserts the feature actually happened, not just a 200. Coverage matrix
cache-read usage tokens > 0. service_tier is out of scope for Bedrock; AWS
Bedrock does not expose an OpenAI-style request service tier, so that cell is
intentionally not covered here.
-- Vertex (gemini-2.5-flash): prompt caching via ``cache_control`` context
- caching; the second identical call must report cached prompt tokens > 0.
+- Vertex (gemini-2.5-flash): explicit context caching via ``cache_control``
+ with a 5-minute ttl. litellm builds the Vertex cache before the generate
+ call, so a never-seen prefix must come back cached on its very first call
+ (Gemini's implicit caching cannot hit a cold prefix), the cached count must
+ cover the marked block, and the spend row must be billed below the uncached
+ price of the prompt.
- Anthropic (claude-haiku-4-5, direct): the same ``cache_control`` prefix over
the OpenAI-compatible route; the second call must report cache-read tokens > 0.
- OpenAI (gpt-5.6): automatic prompt caching needs no request marker, so the
@@ -26,7 +30,8 @@ built from the typed content blocks shared in ``endpoints_client.py``.
from __future__ import annotations
import time
-from collections.abc import Callable
+from collections.abc import Callable, Iterator
+from typing import Final
import pytest
from pydantic import BaseModel
@@ -45,6 +50,10 @@ BEDROCK_MODEL = "bedrock/us.anthropic.claude-haiku-4-5-20251001-v1:0"
VERTEX_MODEL = "vertex_ai/gemini-2.5-flash"
ANTHROPIC_MODEL = "anthropic/claude-haiku-4-5-20251001"
OPENAI_MODEL = "openai/gpt-5.6"
+VERTEX_CACHE_TTL: Final = "300s"
+VERTEX_COLD_CALL_ATTEMPTS: Final = 3
+VERTEX_MINIMUM_CACHED_TOKENS: Final = 1024
+CACHED_SHARE_OF_PROMPT: Final = 0.9
class CacheChatBody(BaseModel):
@@ -77,14 +86,14 @@ def _cached_read_tokens(usage: Usage | None) -> int:
def _cache_chat(
- client: PassthroughClient, key: str, model: str, prefix: str
+ client: PassthroughClient, key: str, model: str, prefix: str, ttl: str | None = None
) -> Result[ChatResponse]:
body = CacheChatBody(
model=model,
messages=[
RichMessage(
role="system",
- content=[TextBlock(text=prefix, cache_control=CacheControl())],
+ content=[TextBlock(text=prefix, cache_control=CacheControl(ttl=ttl))],
),
RichMessage(role="user", content=[TextBlock(text="Reply with one word.")]),
],
@@ -138,6 +147,58 @@ def _assert_cache_read_on_second_call(
)
+def _cold_cache_calls(send: Callable[[str], Result[ChatResponse]]) -> Iterator[ChatResponse]:
+ for _ in range(VERTEX_COLD_CALL_ATTEMPTS):
+ yield unwrap(send(_cacheable_prefix()))
+
+
+def _first_cold_call_reads_cache(model: str, send: Callable[[str], Result[ChatResponse]]) -> ChatResponse:
+ completion: Final = next(
+ (
+ candidate
+ for candidate in _cold_cache_calls(send)
+ if _cached_read_tokens(candidate.usage) >= VERTEX_MINIMUM_CACHED_TOKENS
+ ),
+ None,
+ )
+ assert completion is not None, (
+ f"{model}: {VERTEX_COLD_CALL_ATTEMPTS} never-seen prompts marked with cache_control all reported fewer "
+ f"than {VERTEX_MINIMUM_CACHED_TOKENS} cached tokens on their first call; explicit context caching did "
+ "not engage"
+ )
+ assert completion.choices, f"{model}: cached call returned no choices: {completion}"
+ usage: Final = completion.usage
+ cached: Final = _cached_read_tokens(usage)
+ assert usage and usage.prompt_tokens and cached >= CACHED_SHARE_OF_PROMPT * usage.prompt_tokens, (
+ f"{model}: only {cached} of {usage.prompt_tokens if usage else None} prompt tokens were served from the "
+ "cache; the cache_control block was not cached whole"
+ )
+ return completion
+
+
+def _input_rate(client: PassthroughClient, model: str) -> float:
+ entry: Final = next((row for row in client.proxy.model_info() if row.model_name == model), None)
+ assert entry and entry.model_info.input_cost_per_token, f"/model/info resolved no input rate for {model}"
+ return entry.model_info.input_cost_per_token
+
+
+def _assert_billed_below_uncached_prompt(client: PassthroughClient, model: str, completion: ChatResponse) -> None:
+ assert completion.id, f"{model}: cached completion carried no id to find its spend row by"
+ usage: Final = completion.usage
+ assert usage and usage.prompt_tokens, f"{model}: cached completion carried no prompt_tokens: {usage}"
+ rows: Final = client.proxy.poll_logs_for_request_id(completion.id, predicate=lambda rs: (rs[0].spend or 0) > 0)
+ assert rows, f"{model}: no costed /spend/logs row for request {completion.id}"
+ row: Final = rows[0]
+ assert row.prompt_tokens == usage.prompt_tokens, (
+ f"{model}: spend row prompt_tokens {row.prompt_tokens} != response prompt_tokens {usage.prompt_tokens}"
+ )
+ uncached_prompt_cost: Final = usage.prompt_tokens * _input_rate(client, model)
+ assert row.spend is not None and row.spend < uncached_prompt_cost, (
+ f"{model}: spend {row.spend} is not below the uncached price of the prompt alone ({uncached_prompt_cost} for "
+ f"{usage.prompt_tokens} tokens); cache-read pricing was not applied"
+ )
+
+
class TestCacheControl:
@pytest.mark.covers(
"llm.chat_completions.bedrock_converse.prompt_cache_5m.nonstream.works",
@@ -174,7 +235,10 @@ class TestCacheControl:
)
resources.defer(lambda: client.proxy.delete_model(model_id))
key = resources.key()
- _assert_cache_read_on_second_call(model, lambda prefix: _cache_chat(client, key, model, prefix))
+ completion = _first_cold_call_reads_cache(
+ model, lambda prefix: _cache_chat(client, key, model, prefix, ttl=VERTEX_CACHE_TTL)
+ )
+ _assert_billed_below_uncached_prompt(client, model, completion)
@pytest.mark.covers(
"llm.chat_completions.anthropic.prompt_cache_5m.nonstream.works",
diff --git a/tests/e2e/models.py b/tests/e2e/models.py
index 5de49ead3ed..016a9de56b8 100644
--- a/tests/e2e/models.py
+++ b/tests/e2e/models.py
@@ -181,6 +181,7 @@ class ChatMessage(BaseModel):
class CacheControl(BaseModel):
type: str = "ephemeral"
+ ttl: str | None = None
class TextBlock(BaseModel):
From 29b93b57aaa0cef7660da3636df377422a2cd704 Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Sat, 5 Sep 2026 12:58:18 -0700
Subject: [PATCH 10/35] feat(ui): show the guardrail cost math in a popover
table
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The "How is this calculated?" hover was a plain-text tooltip. It is now a
popover (opens on hover or click) with a title, the formula, a table of
one row per counter or guardrail (units, × price, = cost, with unpriced
units called out under the row) and a total row, so the math reads as a
worked sum instead of a sentence.
Refs LIT-5652
---
.../GuardrailUsageBreakdown.test.tsx | 55 ++++++++++-----
.../_components/GuardrailUsageBreakdown.tsx | 26 +++----
.../_components/GuardrailsOverview.test.tsx | 25 ++++---
.../_components/GuardrailsOverview.tsx | 25 ++++---
.../GuardrailsMonitor/CalcPopover.tsx | 67 +++++++++++++++++++
.../GuardrailsMonitor/MetricCard.tsx | 23 +------
.../GuardrailsMonitor/UnpricedNote.tsx | 4 +-
.../GuardrailsMonitor/usageUnits.test.ts | 55 +++++++++------
.../GuardrailsMonitor/usageUnits.ts | 30 ++++++---
9 files changed, 204 insertions(+), 106 deletions(-)
create mode 100644 ui/litellm-dashboard/src/components/GuardrailsMonitor/CalcPopover.tsx
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
index 3a0a4c38ecb..db7855ab0d5 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.test.tsx
@@ -85,20 +85,33 @@ describe("GuardrailUsageBreakdown", () => {
expect(within(unpricedKey).getByText("7", { selector: ".text-warning" })).toBeInTheDocument();
});
- it("explains the cost math per counter on hover", async () => {
+ const cellsOf = (dialog: HTMLElement): string[][] =>
+ within(dialog)
+ .getAllByRole("row")
+ .map((row) =>
+ within(row)
+ .getAllByRole("cell")
+ .map((cell) => cell.textContent ?? ""),
+ );
+
+ it("lays the cost math out per counter as units × price = cost", async () => {
const user = userEvent.setup();
render( );
- await user.hover(
+ await user.click(
within(screen.getByRole("group", { name: "Cost" })).getByRole("button", { name: /How is this calculated/ }),
);
- expect(await screen.findByText("Content Policy: 1,000 × $0.00015 = $0.1500")).toBeInTheDocument();
- expect(screen.getByText("Sensitive Information Policy: 300 × $0.0001 = $0.0300")).toBeInTheDocument();
- expect(screen.getByText("Some Future Counter: 7 units with no known price, left out")).toBeInTheDocument();
- expect(screen.getByText("Total: $0.1800")).toBeInTheDocument();
- expect(screen.getByText(/7 units with no known price are left out of the cost/)).toBeInTheDocument();
- const issueLink = screen.getByRole("link", { name: "Request pricing on GitHub" });
+ const dialog = await screen.findByRole("dialog", { name: "How this cost is calculated" });
+ expect(cellsOf(dialog)).toEqual([
+ ["Content Policy", "1,000", "× $0.00015", "= $0.1500"],
+ ["Sensitive Information Policy", "300", "× $0.0001", "= $0.0300"],
+ ["Some Future Counter", "7", "× —", "= —"],
+ ["no known price, left out"],
+ ["Total", "$0.1800"],
+ ]);
+ expect(within(dialog).getByText(/7 units with no known price are left out of the cost/)).toBeInTheDocument();
+ const issueLink = within(dialog).getByRole("link", { name: "Request pricing on GitHub" });
expect(issueLink).toHaveAttribute("target", "_blank");
const issueUrl = new URL(issueLink.getAttribute("href") ?? "");
expect(issueUrl.searchParams.get("title")).toBe("[Feature]: add Bedrock guardrail pricing to the cost map");
@@ -119,29 +132,35 @@ describe("GuardrailUsageBreakdown", () => {
/>,
);
- await user.hover(
+ await user.click(
within(screen.getByRole("group", { name: "Cost" })).getByRole("button", { name: /How is this calculated/ }),
);
- expect(await screen.findByText("Total: $0.1500")).toBeInTheDocument();
- expect(screen.queryByRole("link", { name: "Request pricing on GitHub" })).not.toBeInTheDocument();
+ const dialog = await screen.findByRole("dialog", { name: "How this cost is calculated" });
+ expect(cellsOf(dialog)).toEqual([
+ ["Content Policy", "1,000", "× $0.00015", "= $0.1500"],
+ ["Total", "$0.1500"],
+ ]);
+ expect(within(dialog).queryByRole("link", { name: "Request pricing on GitHub" })).not.toBeInTheDocument();
});
- it("explains the units sum on hover", async () => {
+ it("lays the units sum out per counter", async () => {
const user = userEvent.setup();
render( );
- await user.hover(
+ await user.click(
within(screen.getByRole("group", { name: "Usage Units" })).getByRole("button", {
name: /How is this calculated/,
}),
);
- expect(
- await screen.findByText(
- "Content Policy 1,000 + Sensitive Information Policy 300 + Some Future Counter 7 = 1,307",
- ),
- ).toBeInTheDocument();
+ const dialog = await screen.findByRole("dialog", { name: "How usage units add up" });
+ expect(cellsOf(dialog)).toEqual([
+ ["Content Policy", "1,000"],
+ ["Sensitive Information Policy", "300"],
+ ["Some Future Counter", "7"],
+ ["Total", "1,307"],
+ ]);
});
it("orders teams and keys by units, largest first", () => {
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
index e67425adb10..27d9ba5162f 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailUsageBreakdown.tsx
@@ -2,14 +2,15 @@ import type { ColumnDef } from "@tanstack/react-table";
import { CircleDollarSign } from "lucide-react";
import React from "react";
import type { GuardrailUsageDetail } from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
+import { CalcPopover, MathTable } from "@/components/GuardrailsMonitor/CalcPopover";
import { MetricCard } from "@/components/GuardrailsMonitor/MetricCard";
import { UnpricedNote } from "@/components/GuardrailsMonitor/UnpricedNote";
import {
counterLabel,
- counterMathLine,
+ counterMathRow,
formatCost,
totalUnits,
- unitsSumLine,
+ unitsMathRows,
unpricedSummary,
} from "@/components/GuardrailsMonitor/usageUnits";
import { DataTable } from "@/components/shared/DataTable";
@@ -113,21 +114,20 @@ const teamColumns = groupColumns("Team", "No team");
const keyColumns = groupColumns("Key", "No key");
const CostMath = ({ counters, detail }: { counters: CounterRow[]; detail: GuardrailUsageDetail }) => (
-
- {counters.map((row) => (
-
{counterMathLine(row)}
- ))}
-
Total: {formatCost(detail.cost)}
-
Each counter is its priced units × the per-unit price LiteLLM has for it in the cost map.
+
+
+ Per-unit prices come from the cost map LiteLLM ships with.
-
+
);
const UnitsMath = ({ units }: { units: GuardrailUsageDetail["usage_units"] }) => (
-
-
{unitsSumLine(units)}
-
Units are the billable counters the provider reported for this guardrail, added up over every call.
-
+
+
+
+ Units are the billable counters the provider reported for this guardrail, added up over every call.
+
+
);
const TableHeading = ({ title }: { title: string }) => (
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
index 16361bdec27..959ed8b172e 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
@@ -211,19 +211,28 @@ describe("GuardrailsOverview", () => {
expect(card).toHaveTextContent("250 units unpriced");
});
- it("explains the guardrail cost total on hover", async () => {
+ it("lays the guardrail cost total out per guardrail", async () => {
const user = userEvent.setup();
renderOverview();
const card = await screen.findByRole("group", { name: "Guardrail Cost" });
- await user.hover(within(card).getByRole("button", { name: /How is this calculated/ }));
+ await user.click(within(card).getByRole("button", { name: /How is this calculated/ }));
- expect(await screen.findByText("High Failure Guardrail: $0.1500")).toBeInTheDocument();
- expect(screen.getByText("Free Bedrock Guardrail: $0.0000")).toBeInTheDocument();
- expect(screen.queryByText(/Low Failure Guardrail: /)).not.toBeInTheDocument();
- expect(screen.getByText("Total: $0.1500")).toBeInTheDocument();
- expect(screen.getByText(/250 units with no known price are left out of the cost/)).toBeInTheDocument();
- const issueLink = screen.getByRole("link", { name: "Request pricing on GitHub" });
+ const dialog = await screen.findByRole("dialog", { name: "How this cost is calculated" });
+ const cells = within(dialog)
+ .getAllByRole("row")
+ .map((row) =>
+ within(row)
+ .getAllByRole("cell")
+ .map((cell) => cell.textContent ?? ""),
+ );
+ expect(cells).toEqual([
+ ["High Failure Guardrail", "$0.1500"],
+ ["Free Bedrock Guardrail", "$0.0000"],
+ ["Total", "$0.1500"],
+ ]);
+ expect(within(dialog).getByText(/250 units with no known price are left out of the cost/)).toBeInTheDocument();
+ const issueLink = within(dialog).getByRole("link", { name: "Request pricing on GitHub" });
const issueUrl = new URL(issueLink.getAttribute("href") ?? "");
expect(issueUrl.searchParams.get("template")).toBe("feature_request.yml");
expect(issueUrl.searchParams.get("the-feature")).toContain("sensitiveInformationPolicyUnits");
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
index 33be85f3c81..468e6967d81 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.tsx
@@ -8,6 +8,7 @@ import {
type GuardrailUsageOverviewRow,
useGuardrailsUsageOverview,
} from "@/app/(dashboard)/hooks/guardrails/useGuardrailsUsage";
+import { CalcPopover, MathTable } from "@/components/GuardrailsMonitor/CalcPopover";
import { UnpricedNote } from "@/components/GuardrailsMonitor/UnpricedNote";
import {
counterLabel,
@@ -80,20 +81,18 @@ function TotalCostMath({
untracked: UsageUnits;
}) {
return (
-
- {rows
- .filter((row) => row.cost != null)
- .map((row) => (
-
- {row.name}: {formatCost(row.cost)}
-
- ))}
-
Total: {formatCost(total)}
-
- {`Each guardrail's cost is its units per counter × that counter's per-unit price from the cost map, added up. Open a guardrail for its per-counter math.`}
-
+
+ row.cost != null)
+ .map((row) => ({ label: row.name, parts: [formatCost(row.cost)], note: null }))}
+ total={formatCost(total)}
+ />
+
+ {`Each guardrail's cost is its units per counter × that counter's per-unit price from the cost map. Open a guardrail for its per-counter math.`}
+
-
+
);
}
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/CalcPopover.tsx b/ui/litellm-dashboard/src/components/GuardrailsMonitor/CalcPopover.tsx
new file mode 100644
index 00000000000..686992a6fb4
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/CalcPopover.tsx
@@ -0,0 +1,67 @@
+import { CircleHelp } from "lucide-react";
+import React, { type ReactNode } from "react";
+import { Popover, PopoverContent, PopoverTitle, PopoverTrigger } from "@/components/ui/popover";
+import type { MathRow } from "./usageUnits";
+
+export function CalcPopover({ title, formula, children }: { title: string; formula: string; children: ReactNode }) {
+ return (
+
+
+ }
+ >
+
+ How is this calculated?
+
+
+ {title}
+ {formula}
+ {children}
+
+
+ );
+}
+
+export function MathTable({ rows, total }: { rows: readonly MathRow[]; total: string }) {
+ const width = 1 + Math.max(...rows.map((row) => row.parts.length), 1);
+ return (
+
+
+ {rows.map((row) => (
+
+
+ {row.label}
+ {row.parts.map((part, i) => (
+
+ {part}
+
+ ))}
+
+ {row.note && (
+
+
+ {row.note}
+
+
+ )}
+
+ ))}
+
+
+
+
+ Total
+
+ {total}
+
+
+
+ );
+}
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx b/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
index 1805dc797e4..008dc279f13 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/MetricCard.tsx
@@ -1,6 +1,4 @@
-import { CircleHelp } from "lucide-react";
import React, { type ReactNode } from "react";
-import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
interface MetricCardProps {
label: string;
@@ -20,26 +18,7 @@ export function MetricCard({ label, value, valueColor = "text-foreground", icon,
{value}
{subtitle && {subtitle}
}
- {hint && (
-
-
-
-
- How is this calculated?
-
- }
- />
-
- {hint}
-
-
-
- )}
+ {hint}
);
}
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/UnpricedNote.tsx b/ui/litellm-dashboard/src/components/GuardrailsMonitor/UnpricedNote.tsx
index 174124d18aa..b43d9d18841 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/UnpricedNote.tsx
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/UnpricedNote.tsx
@@ -6,7 +6,7 @@ export function UnpricedNote({ unpriced, provider }: { unpriced: UsageUnits; pro
if (total === 0) return null;
const [noun, verb] = total === 1 ? ["unit", "is"] : ["units", "are"];
return (
-
+
);
}
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
index 9b45eefaf54..8e2baaaa3c5 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
@@ -1,13 +1,13 @@
import { describe, expect, it } from "vitest";
import {
counterLabel,
- counterMathLine,
+ counterMathRow,
formatCost,
formatUnitPrice,
pricingIssueUrl,
totalUnits,
unitPrice,
- unitsSumLine,
+ unitsMathRows,
unpricedSummary,
} from "./usageUnits";
@@ -91,40 +91,51 @@ describe("formatUnitPrice", () => {
});
});
-describe("counterMathLine", () => {
+describe("counterMathRow", () => {
it("shows units × price = cost for a fully priced counter", () => {
- expect(counterMathLine({ counter: "contentPolicyUnits", units: 1000, unpriced: 0, cost: 0.15 })).toBe(
- "Content Policy: 1,000 × $0.00015 = $0.1500",
- );
+ expect(counterMathRow({ counter: "contentPolicyUnits", units: 1000, unpriced: 0, cost: 0.15 })).toEqual({
+ label: "Content Policy",
+ parts: ["1,000", "× $0.00015", "= $0.1500"],
+ note: null,
+ });
});
it("prices only the priced share and calls out the rest", () => {
- expect(counterMathLine({ counter: "sensitiveInformationPolicyUnits", units: 8, unpriced: 2, cost: 0.0006 })).toBe(
- "Sensitive Information Policy: 6 × $0.0001 = $0.0006 (2 unpriced left out)",
+ expect(counterMathRow({ counter: "sensitiveInformationPolicyUnits", units: 8, unpriced: 2, cost: 0.0006 })).toEqual(
+ {
+ label: "Sensitive Information Policy",
+ parts: ["6", "× $0.0001", "= $0.0006"],
+ note: "2 unpriced units left out",
+ },
);
+ expect(
+ counterMathRow({ counter: "sensitiveInformationPolicyUnits", units: 8, unpriced: 1, cost: 0.0007 }).note,
+ ).toBe("1 unpriced unit left out");
});
it("says so when a counter has no known price at all", () => {
- expect(counterMathLine({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: null })).toBe(
- "Some Future Counter: 7 units with no known price, left out",
- );
- expect(counterMathLine({ counter: "someFutureCounter", units: 1, unpriced: 1, cost: null })).toBe(
- "Some Future Counter: 1 unit with no known price, left out",
- );
+ expect(counterMathRow({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: null })).toEqual({
+ label: "Some Future Counter",
+ parts: ["7", "× —", "= —"],
+ note: "no known price, left out",
+ });
});
it("shows a free counter as × $0", () => {
- expect(counterMathLine({ counter: "wordPolicyUnits", units: 2, unpriced: 0, cost: 0 })).toBe(
- "Word Policy: 2 × $0 = $0.0000",
- );
+ expect(counterMathRow({ counter: "wordPolicyUnits", units: 2, unpriced: 0, cost: 0 }).parts).toEqual([
+ "2",
+ "× $0",
+ "= $0.0000",
+ ]);
});
});
-describe("unitsSumLine", () => {
- it("adds the counters up in order", () => {
- expect(unitsSumLine({ contentPolicyUnits: 2, topicPolicyUnits: 2, wordPolicyUnits: 1200 })).toBe(
- "Content Policy 2 + Topic Policy 2 + Word Policy 1,200 = 1,204",
- );
+describe("unitsMathRows", () => {
+ it("lists the counters in order with their counts", () => {
+ expect(unitsMathRows({ contentPolicyUnits: 2, wordPolicyUnits: 1200 })).toEqual([
+ { label: "Content Policy", parts: ["2"], note: null },
+ { label: "Word Policy", parts: ["1,200"], note: null },
+ ]);
});
});
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
index f914a3e9698..c47442de200 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.ts
@@ -40,20 +40,34 @@ export const formatUnitPrice = (price: number): string => {
return price > 0 && Number(fixed) === 0 ? "< $0.000001" : `$${fixed}`;
};
-export const counterMathLine = (row: CounterMath): string => {
+export interface MathRow {
+ readonly label: string;
+ readonly parts: readonly string[];
+ readonly note: string | null;
+}
+
+export const counterMathRow = (row: CounterMath): MathRow => {
const label = counterLabel(row.counter);
const price = unitPrice(row);
if (price == null) {
- return `${label}: ${row.units.toLocaleString()} ${row.units === 1 ? "unit" : "units"} with no known price, left out`;
+ return { label, parts: [row.units.toLocaleString(), "× —", "= —"], note: "no known price, left out" };
}
- const line = `${label}: ${pricedUnits(row).toLocaleString()} × ${formatUnitPrice(price)} = ${formatCost(row.cost)}`;
- return row.unpriced > 0 ? `${line} (${row.unpriced.toLocaleString()} unpriced left out)` : line;
+ return {
+ label,
+ parts: [pricedUnits(row).toLocaleString(), `× ${formatUnitPrice(price)}`, `= ${formatCost(row.cost)}`],
+ note:
+ row.unpriced > 0
+ ? `${row.unpriced.toLocaleString()} unpriced ${row.unpriced === 1 ? "unit" : "units"} left out`
+ : null,
+ };
};
-export const unitsSumLine = (units: UsageUnits): string =>
- `${Object.entries(units)
- .map(([counter, n]) => `${counterLabel(counter)} ${n.toLocaleString()}`)
- .join(" + ")} = ${totalUnits(units).toLocaleString()}`;
+export const unitsMathRows = (units: UsageUnits): readonly MathRow[] =>
+ Object.entries(units).map(([counter, n]) => ({
+ label: counterLabel(counter),
+ parts: [n.toLocaleString()],
+ note: null,
+ }));
export const pricingIssueUrl = (unpriced: UsageUnits, provider?: string): string => {
const subject = provider ? `${provider} guardrail` : "guardrail";
From b98f8ee2c5be9bbaa1b54297f7cfdcb57ec4e615 Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 13:00:24 -0700
Subject: [PATCH 11/35] test(e2e): retry a fresh prefix when Vertex rejects the
cache create on its minimum-token check
---
tests/e2e/llm_translation/test_cache_control.py | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/tests/e2e/llm_translation/test_cache_control.py b/tests/e2e/llm_translation/test_cache_control.py
index 3ad98bc6072..4e11ad6cec5 100644
--- a/tests/e2e/llm_translation/test_cache_control.py
+++ b/tests/e2e/llm_translation/test_cache_control.py
@@ -37,7 +37,7 @@ import pytest
from pydantic import BaseModel
from e2e_config import unique_marker
-from e2e_http import Result, unwrap
+from e2e_http import Result, UnknownApiError, unwrap
from endpoints_client import CacheControl, RichMessage, TextBlock
from lifecycle import ResourceManager
from models import ChatBody, ChatMessage, ChatResponse, LiteLLMParamsBody, Usage
@@ -54,6 +54,7 @@ VERTEX_CACHE_TTL: Final = "300s"
VERTEX_COLD_CALL_ATTEMPTS: Final = 3
VERTEX_MINIMUM_CACHED_TOKENS: Final = 1024
CACHED_SHARE_OF_PROMPT: Final = 0.9
+VERTEX_CACHE_REJECTION_MARKER: Final = "minimum token count to start explicit caching"
class CacheChatBody(BaseModel):
@@ -149,7 +150,12 @@ def _assert_cache_read_on_second_call(
def _cold_cache_calls(send: Callable[[str], Result[ChatResponse]]) -> Iterator[ChatResponse]:
for _ in range(VERTEX_COLD_CALL_ATTEMPTS):
- yield unwrap(send(_cacheable_prefix()))
+ result = send(_cacheable_prefix())
+ match result:
+ case UnknownApiError(status_code=400, body=body) if VERTEX_CACHE_REJECTION_MARKER in body:
+ continue
+ case _:
+ yield unwrap(result)
def _first_cold_call_reads_cache(model: str, send: Callable[[str], Result[ChatResponse]]) -> ChatResponse:
@@ -162,9 +168,9 @@ def _first_cold_call_reads_cache(model: str, send: Callable[[str], Result[ChatRe
None,
)
assert completion is not None, (
- f"{model}: {VERTEX_COLD_CALL_ATTEMPTS} never-seen prompts marked with cache_control all reported fewer "
- f"than {VERTEX_MINIMUM_CACHED_TOKENS} cached tokens on their first call; explicit context caching did "
- "not engage"
+ f"{model}: {VERTEX_COLD_CALL_ATTEMPTS} never-seen prompts marked with cache_control were each either "
+ f"rejected by Vertex's minimum-token check or served with fewer than {VERTEX_MINIMUM_CACHED_TOKENS} "
+ "cached tokens on their first call; explicit context caching did not engage"
)
assert completion.choices, f"{model}: cached call returned no choices: {completion}"
usage: Final = completion.usage
From 1c0172b477cfbc52c1a74ef55397a6531a999ced Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 13:04:33 -0700
Subject: [PATCH 12/35] style(e2e): annotate the cold-call locals as Final
---
tests/e2e/llm_translation/test_cache_control.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/e2e/llm_translation/test_cache_control.py b/tests/e2e/llm_translation/test_cache_control.py
index 4e11ad6cec5..7530485ad79 100644
--- a/tests/e2e/llm_translation/test_cache_control.py
+++ b/tests/e2e/llm_translation/test_cache_control.py
@@ -150,7 +150,7 @@ def _assert_cache_read_on_second_call(
def _cold_cache_calls(send: Callable[[str], Result[ChatResponse]]) -> Iterator[ChatResponse]:
for _ in range(VERTEX_COLD_CALL_ATTEMPTS):
- result = send(_cacheable_prefix())
+ result: Final = send(_cacheable_prefix())
match result:
case UnknownApiError(status_code=400, body=body) if VERTEX_CACHE_REJECTION_MARKER in body:
continue
@@ -241,7 +241,7 @@ class TestCacheControl:
)
resources.defer(lambda: client.proxy.delete_model(model_id))
key = resources.key()
- completion = _first_cold_call_reads_cache(
+ completion: Final = _first_cold_call_reads_cache(
model, lambda prefix: _cache_chat(client, key, model, prefix, ttl=VERTEX_CACHE_TTL)
)
_assert_billed_below_uncached_prompt(client, model, completion)
From b56e4f80a4e97b60c47b4f177ff22b170ec9fa30 Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 13:05:03 -0700
Subject: [PATCH 13/35] test(e2e): make each cold cache call a
single-assignment helper so its result stays Final
---
.../e2e/llm_translation/test_cache_control.py | 21 +++++++++----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/tests/e2e/llm_translation/test_cache_control.py b/tests/e2e/llm_translation/test_cache_control.py
index 7530485ad79..a18e03c982b 100644
--- a/tests/e2e/llm_translation/test_cache_control.py
+++ b/tests/e2e/llm_translation/test_cache_control.py
@@ -30,7 +30,7 @@ built from the typed content blocks shared in ``endpoints_client.py``.
from __future__ import annotations
import time
-from collections.abc import Callable, Iterator
+from collections.abc import Callable
from typing import Final
import pytest
@@ -148,22 +148,21 @@ def _assert_cache_read_on_second_call(
)
-def _cold_cache_calls(send: Callable[[str], Result[ChatResponse]]) -> Iterator[ChatResponse]:
- for _ in range(VERTEX_COLD_CALL_ATTEMPTS):
- result: Final = send(_cacheable_prefix())
- match result:
- case UnknownApiError(status_code=400, body=body) if VERTEX_CACHE_REJECTION_MARKER in body:
- continue
- case _:
- yield unwrap(result)
+def _cold_cache_call(send: Callable[[str], Result[ChatResponse]]) -> ChatResponse | None:
+ result: Final = send(_cacheable_prefix())
+ match result:
+ case UnknownApiError(status_code=400, body=body) if VERTEX_CACHE_REJECTION_MARKER in body:
+ return None
+ case _:
+ return unwrap(result)
def _first_cold_call_reads_cache(model: str, send: Callable[[str], Result[ChatResponse]]) -> ChatResponse:
completion: Final = next(
(
candidate
- for candidate in _cold_cache_calls(send)
- if _cached_read_tokens(candidate.usage) >= VERTEX_MINIMUM_CACHED_TOKENS
+ for candidate in (_cold_cache_call(send) for _ in range(VERTEX_COLD_CALL_ATTEMPTS))
+ if candidate is not None and _cached_read_tokens(candidate.usage) >= VERTEX_MINIMUM_CACHED_TOKENS
),
None,
)
From 5df0e12e0f2628ed847c8110759a589f3fa1c138 Mon Sep 17 00:00:00 2001
From: "devin-ai-integration[bot]"
<158243242+devin-ai-integration[bot]@users.noreply.github.com>
Date: Sat, 5 Sep 2026 13:08:03 -0700
Subject: [PATCH 14/35] feat(guardrails): add non-blocking flag() verdict to
custom code guardrails (#39728)
Custom code guardrails could only allow(), block(reason) or modify(). This adds flag(reason, metadata={}) which lets the request or response through unchanged and records a guardrail_flagged entry carrying the guardrail name, configured mode, evaluated input_type (request or response), reason and structured metadata. The new status is threaded through the request-level guardrail_status aggregation, the Guardrails Monitor rollup (flagged_count), Request Logs (action=flagged, most severe phase wins when a guardrail runs pre and post call) and the Request Logs detail view in the dashboard, which now renders FLAGGED with warning styling instead of falling into FAILED.
Co-authored-by: yassin
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---
litellm/litellm_core_utils/litellm_logging.py | 2 +
.../custom_code/custom_code_guardrail.py | 27 ++++++
.../guardrail_hooks/custom_code/primitives.py | 28 +++++-
litellm/proxy/guardrails/usage_endpoints.py | 18 ++--
litellm/proxy/guardrails/usage_tracking.py | 6 +-
litellm/types/utils.py | 5 +-
.../test_litellm_logging.py | 18 +++-
.../guardrails/test_custom_code_security.py | 65 +++++++++++++
.../proxy/guardrails/test_usage_endpoints.py | 97 +++++++++++++++++++
.../proxy/guardrails/test_usage_tracking.py | 21 ++++
.../custom_code/CustomCodeModal.tsx | 1 +
.../GuardrailViewer/GuardrailViewer.test.tsx | 16 +++
.../GuardrailViewer/GuardrailViewer.tsx | 95 ++++++++++++------
.../LogDetailContent.test.tsx | 16 ++-
.../LogDetailsDrawer/LogDetailContent.tsx | 31 +++---
15 files changed, 386 insertions(+), 60 deletions(-)
diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py
index 83e0b4d84f1..c31c4323157 100644
--- a/litellm/litellm_core_utils/litellm_logging.py
+++ b/litellm/litellm_core_utils/litellm_logging.py
@@ -5881,6 +5881,7 @@ def _get_status_fields(
# Mapping for legacy guardrail status values to new GuardrailStatus values
GUARDRAIL_STATUS_MAP: Final[dict[str, GuardrailStatus]] = {
"success": "success",
+ "guardrail_flagged": "guardrail_flagged",
"blocked": "guardrail_intervened", # legacy
"guardrail_intervened": "guardrail_intervened", # direct
"failure": "guardrail_failed_to_respond", # legacy
@@ -5902,6 +5903,7 @@ def _get_status_fields(
GUARDRAIL_STATUS_SEVERITY: Final[tuple[GuardrailStatus, ...]] = (
"not_run",
"success",
+ "guardrail_flagged",
"guardrail_failed_to_respond",
"guardrail_intervened",
)
diff --git a/litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py b/litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py
index 830dec8d80d..d5ef1e949b8 100644
--- a/litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py
+++ b/litellm/proxy/guardrails/guardrail_hooks/custom_code/custom_code_guardrail.py
@@ -36,6 +36,7 @@ Example: block when response rejects the user (input_type response only):
import asyncio
import threading
+import time
from collections.abc import Callable, Mapping
from typing import TYPE_CHECKING, Any, Final, Literal, Optional, cast
@@ -93,6 +94,7 @@ class CustomCodeGuardrail(CustomGuardrail):
that returns one of:
- allow() - let the request/response through
- block(reason) - reject with a message
+ - flag(reason) - let it through but log a non-blocking violation
- modify(texts=...) - transform the content
Example:
@@ -227,6 +229,7 @@ class CustomCodeGuardrail(CustomGuardrail):
raise CustomCodeExecutionError(f"Custom code guardrail not compiled: {self._compile_error}")
raise CustomCodeExecutionError("Custom code guardrail not compiled")
+ start_time: Final = time.time()
try:
# Prepare inputs dict for the function
@@ -245,6 +248,7 @@ class CustomCodeGuardrail(CustomGuardrail):
inputs=inputs,
request_data=request_data,
input_type=input_type,
+ start_time=start_time,
)
except HTTPException:
@@ -290,6 +294,7 @@ class CustomCodeGuardrail(CustomGuardrail):
inputs: GenericGuardrailAPIInputs,
request_data: dict[str, object],
input_type: Literal["request", "response"],
+ start_time: float,
) -> GenericGuardrailAPIInputs:
"""
Process the result from the custom code function.
@@ -299,6 +304,7 @@ class CustomCodeGuardrail(CustomGuardrail):
inputs: The original inputs
request_data: The request data
input_type: "request" or "response"
+ start_time: Unix timestamp of when the guardrail started running, used for the flagged log entry
Returns:
GenericGuardrailAPIInputs - possibly modified
@@ -348,6 +354,27 @@ class CustomCodeGuardrail(CustomGuardrail):
},
)
+ elif action == "flag":
+ flag_reason: Final = result.get("reason", "Flagged by custom code guardrail")
+ verbose_proxy_logger.info(
+ "Custom code guardrail '%s': Flagging %s - %s", self.guardrail_name, input_type, flag_reason
+ )
+ end_time: Final = time.time()
+ self.add_standard_logging_guardrail_information_to_request_data(
+ guardrail_json_response={ # mutable-ok: logging helper requires a dict
+ "action": "flag",
+ "reason": flag_reason,
+ "input_type": input_type,
+ "metadata": result.get("metadata") or {}, # mutable-ok: logging helper requires a dict
+ },
+ request_data=request_data,
+ guardrail_status="guardrail_flagged",
+ start_time=start_time,
+ end_time=end_time,
+ duration=end_time - start_time,
+ )
+ return inputs
+
elif action == "modify":
verbose_proxy_logger.debug("Custom code guardrail '%s': Modifying %s", self.guardrail_name, input_type)
diff --git a/litellm/proxy/guardrails/guardrail_hooks/custom_code/primitives.py b/litellm/proxy/guardrails/guardrail_hooks/custom_code/primitives.py
index 24801aa2df1..d5dbfaeb84b 100644
--- a/litellm/proxy/guardrails/guardrail_hooks/custom_code/primitives.py
+++ b/litellm/proxy/guardrails/guardrail_hooks/custom_code/primitives.py
@@ -8,7 +8,7 @@ and provide safe, sandboxed functionality for common guardrail operations.
import json
import re
from collections.abc import Mapping, Sequence
-from typing import Final
+from typing import Final, Literal
from urllib.parse import urlparse
import httpx
@@ -51,6 +51,31 @@ def block(reason: str, detection_info: Mapping[str, object] | None = None) -> di
return result
+class FlagResult(TypedDict):
+ action: ReadOnly[Literal["flag"]]
+ reason: ReadOnly[str]
+ metadata: ReadOnly[Mapping[str, object]]
+
+
+def flag(reason: str, metadata: Mapping[str, object] | None = None) -> FlagResult:
+ """
+ Let the request/response proceed unchanged but record a non-blocking violation.
+
+ Args:
+ reason: Human-readable reason for flagging
+ metadata: Optional structured metadata stored alongside the reason
+
+ Returns:
+ Dict indicating the request should be flagged but allowed
+ """
+ result: Final[FlagResult] = {
+ "action": "flag",
+ "reason": reason,
+ "metadata": metadata if metadata is not None else {},
+ }
+ return result
+
+
def modify(
texts: Sequence[str] | None = None,
images: Sequence[object] | None = None,
@@ -787,6 +812,7 @@ def get_custom_code_primitives() -> dict[str, object]:
# Result types
"allow": allow,
"block": block,
+ "flag": flag,
"modify": modify,
# Regex
"regex_match": regex_match,
diff --git a/litellm/proxy/guardrails/usage_endpoints.py b/litellm/proxy/guardrails/usage_endpoints.py
index 62145b9ede9..014ba3d1472 100644
--- a/litellm/proxy/guardrails/usage_endpoints.py
+++ b/litellm/proxy/guardrails/usage_endpoints.py
@@ -17,6 +17,7 @@ from typing_extensions import NotRequired, ReadOnly, TypedDict
from litellm._logging import verbose_proxy_logger
from litellm.proxy._types import UserAPIKeyAuth
from litellm.proxy.auth.user_api_key_auth import user_api_key_auth
+from litellm.proxy.guardrails.usage_tracking import guardrail_status_to_action
from litellm.repositories.prisma_protocols import TableActions
from litellm.repositories.table_repositories import (
DailyGuardrailMetricsRepository,
@@ -41,6 +42,7 @@ if TYPE_CHECKING:
router: Final = APIRouter()
_EMPTY_UNITS: Final[Mapping[str, int]] = MappingProxyType({})
+_ACTION_SEVERITY: Final[Mapping[str, int]] = MappingProxyType({"passed": 0, "flagged": 1, "blocked": 2})
_T = TypeVar("_T")
@@ -759,21 +761,17 @@ def _usage_log_entry_from_row(
except Exception:
meta = {}
guardrail_info_list: Final[Sequence[_GuardrailRunInfo]] = (meta or {}).get("guardrail_information") or []
- entry_for_guardrail: _GuardrailRunInfo | None = None
- for gi in guardrail_info_list:
- if (gi.get("guardrail_id") or gi.get("guardrail_name")) == r.guardrail_id:
- entry_for_guardrail = gi
- break
+ entry_for_guardrail: Final[_GuardrailRunInfo | None] = max(
+ (gi for gi in guardrail_info_list if (gi.get("guardrail_id") or gi.get("guardrail_name")) == r.guardrail_id),
+ key=lambda gi: _ACTION_SEVERITY[guardrail_status_to_action(gi.get("guardrail_status"))],
+ default=None,
+ )
action_val = "passed"
score_val = None
latency_val = None
reason_val = None
if entry_for_guardrail:
- st: Final = (entry_for_guardrail.get("guardrail_status") or "").lower()
- if "intervened" in st or "block" in st:
- action_val = "blocked"
- elif "fail" in st or "error" in st:
- action_val = "flagged"
+ action_val = guardrail_status_to_action(entry_for_guardrail.get("guardrail_status"))
duration: Final = entry_for_guardrail.get("duration")
if duration is not None:
latency_val = round(float(duration) * 1000, 0)
diff --git a/litellm/proxy/guardrails/usage_tracking.py b/litellm/proxy/guardrails/usage_tracking.py
index a20ad3935e5..df967058cf0 100644
--- a/litellm/proxy/guardrails/usage_tracking.py
+++ b/litellm/proxy/guardrails/usage_tracking.py
@@ -190,14 +190,14 @@ async def _upsert_rows_with_retry(
return await _upsert_rows_with_retry(retryable, upsert_row, label, sleep, retries_left - 1)
-def _guardrail_status_to_action(status: str | None) -> str:
+def guardrail_status_to_action(status: str | None) -> str:
"""Map StandardLogging guardrail_status to blocked/passed/flagged."""
if not status:
return "passed"
s: Final = (status or "").lower()
if "intervened" in s or "block" in s:
return "blocked"
- if "fail" in s or "error" in s:
+ if "flagged" in s or "fail" in s or "error" in s:
return "flagged"
return "passed"
@@ -367,7 +367,7 @@ async def process_spend_logs_guardrail_usage(
continue
key = _MetricsKey(guardrail_id, date_key)
daily_guardrail[key]["requests_evaluated"] += 1
- action = _guardrail_status_to_action(entry.get("guardrail_status"))
+ action = guardrail_status_to_action(entry.get("guardrail_status"))
if action == "passed":
daily_guardrail[key]["passed_count"] += 1
elif action == "blocked":
diff --git a/litellm/types/utils.py b/litellm/types/utils.py
index 2118fe77aad..61c2fc8c5a5 100644
--- a/litellm/types/utils.py
+++ b/litellm/types/utils.py
@@ -3078,7 +3078,9 @@ class GuardrailMode(TypedDict, total=False):
default: str | list[str] | None
-GuardrailStatus = Literal["success", "guardrail_intervened", "guardrail_failed_to_respond", "not_run"]
+GuardrailStatus = Literal[
+ "success", "guardrail_flagged", "guardrail_intervened", "guardrail_failed_to_respond", "not_run"
+]
# Fields on a guardrail record whose values can quote the caller's prompt: the payload sent to the
# guardrail, the provider response that echoes it back, and the two first-party hooks that inline
@@ -3320,6 +3322,7 @@ class StandardLoggingPayloadStatusFields(TypedDict, total=False):
"""
Status of guardrail execution:
- 'success': Guardrail ran and allowed content through
+ - 'guardrail_flagged': Guardrail allowed content through but recorded a non-blocking violation
- 'guardrail_intervened': Guardrail blocked or modified content
- 'guardrail_failed_to_respond': Guardrail had technical failure
- 'not_run': No guardrail was run
diff --git a/tests/test_litellm/litellm_core_utils/test_litellm_logging.py b/tests/test_litellm/litellm_core_utils/test_litellm_logging.py
index 1991170707d..16a99713a06 100644
--- a/tests/test_litellm/litellm_core_utils/test_litellm_logging.py
+++ b/tests/test_litellm/litellm_core_utils/test_litellm_logging.py
@@ -16,7 +16,10 @@ from litellm._logging import session_id_var, trace_id_var
from litellm.constants import SENTRY_DENYLIST, SENTRY_PII_DENYLIST
from litellm.integrations.custom_logger import CustomLogger
from litellm.litellm_core_utils.litellm_logging import Logging as LitellmLogging
-from litellm.litellm_core_utils.litellm_logging import set_callbacks
+from litellm.litellm_core_utils.litellm_logging import (
+ _get_status_fields,
+ set_callbacks,
+)
from litellm.types.utils import ModelResponse, TextCompletionResponse
@@ -6441,3 +6444,16 @@ def test_passthrough_embeddings_result_swapped_for_callbacks():
assert isinstance(swapped_result, EmbeddingResponse)
assert swapped_result.data[0]["embedding"] == [0.1, 0.2, 0.3]
+
+
+def test_get_status_fields_ranks_guardrail_flagged_between_success_and_intervened():
+ """LIT-6894: a non-blocking flagged verdict must outrank success in the
+ request-level guardrail_status but never mask an intervention."""
+ flagged = {"guardrail_status": "guardrail_flagged"}
+
+ assert _get_status_fields(
+ "success", [{"guardrail_status": "success"}, flagged], None
+ )["guardrail_status"] == "guardrail_flagged"
+ assert _get_status_fields(
+ "success", [flagged, {"guardrail_status": "guardrail_intervened"}], None
+ )["guardrail_status"] == "guardrail_intervened"
diff --git a/tests/test_litellm/proxy/guardrails/test_custom_code_security.py b/tests/test_litellm/proxy/guardrails/test_custom_code_security.py
index f93ecfc3010..7971cf62c9a 100644
--- a/tests/test_litellm/proxy/guardrails/test_custom_code_security.py
+++ b/tests/test_litellm/proxy/guardrails/test_custom_code_security.py
@@ -197,6 +197,71 @@ async def test_custom_code_post_call_block_raises_http_400():
}
+FLAG_CODE = (
+ "def apply_guardrail(inputs, request_data, input_type):\n"
+ ' return flag("audit hit", metadata={"category": "topic"})\n'
+)
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize("input_type", ["request", "response"])
+async def test_custom_code_flag_passes_content_through_and_records_flagged_entry(input_type):
+ """LIT-6894: flag() must not raise, must return the content unchanged and must log
+ exactly one guardrail_flagged entry (the decorator must not add a second "success")."""
+ guardrail = CustomCodeGuardrail(custom_code=FLAG_CODE, guardrail_name="t", event_hook=["pre_call", "post_call"])
+ request_data = {"model": "test-model", "litellm_metadata": {}}
+
+ result = await guardrail.apply_guardrail(
+ inputs={"texts": ["hello"]},
+ request_data=request_data,
+ input_type=input_type,
+ )
+
+ assert result == {"texts": ["hello"]}
+ entries = request_data["litellm_metadata"]["standard_logging_guardrail_information"]
+ assert len(entries) == 1
+ entry = entries[0]
+ assert entry["guardrail_status"] == "guardrail_flagged"
+ assert entry["guardrail_name"] == "t"
+ assert entry["guardrail_mode"] == ["pre_call", "post_call"]
+ assert entry["guardrail_response"] == {
+ "action": "flag",
+ "reason": "audit hit",
+ "input_type": input_type,
+ "metadata": {"category": "topic"},
+ }
+ assert entry["duration"] is not None and entry["duration"] >= 0
+
+
+@pytest.mark.asyncio
+async def test_custom_code_flag_default_reason_and_empty_metadata():
+ code = "def apply_guardrail(inputs, request_data, input_type):\n return flag('just a note')\n"
+ guardrail = _compile(code)
+ request_data = {"model": "m", "litellm_metadata": {}}
+
+ await guardrail.apply_guardrail(inputs={"texts": ["x"]}, request_data=request_data, input_type="request")
+
+ entry = request_data["litellm_metadata"]["standard_logging_guardrail_information"][0]
+ assert entry["guardrail_response"] == {
+ "action": "flag",
+ "reason": "just a note",
+ "input_type": "request",
+ "metadata": {},
+ }
+
+
+@pytest.mark.asyncio
+async def test_custom_code_allow_still_records_success_not_flagged():
+ code = "def apply_guardrail(inputs, request_data, input_type):\n return allow()\n"
+ guardrail = _compile(code)
+ request_data = {"model": "m", "litellm_metadata": {}}
+
+ await guardrail.apply_guardrail(inputs={"texts": ["x"]}, request_data=request_data, input_type="request")
+
+ entries = request_data["litellm_metadata"]["standard_logging_guardrail_information"]
+ assert [e["guardrail_status"] for e in entries] == ["success"]
+
+
def test_typical_sync_guardrail_still_works():
code = (
"def apply_guardrail(inputs, request_data, input_type):\n"
diff --git a/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py b/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py
index ebb2be6edc2..4e5a7ad4b2b 100644
--- a/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py
+++ b/tests/test_litellm/proxy/guardrails/test_usage_endpoints.py
@@ -477,6 +477,103 @@ async def test_logs_resolves_config_guardrail_logical_name():
assert where["guardrail_id"] == {"in": ["yaml-uuid", "yaml-pii"]}
+def _index_row(request_id: str, guardrail_id: str = "cc-flag") -> Any:
+ r = MagicMock(spec=["request_id", "guardrail_id", "policy_id", "start_time"])
+ r.request_id = request_id
+ r.guardrail_id = guardrail_id
+ return r
+
+
+def _spend_log(request_id: str, *guardrail_statuses: str, guardrail_id: str = "cc-flag") -> Any:
+ sl = MagicMock(spec=["request_id", "metadata", "startTime", "model", "messages", "response"])
+ sl.request_id = request_id
+ sl.startTime = datetime(2026, 4, 25, 12, 0)
+ sl.model = "gpt-4o-mini"
+ sl.messages = [{"role": "user", "content": "hi"}]
+ sl.response = "ok"
+ sl.metadata = {
+ "guardrail_information": [
+ {
+ "guardrail_name": guardrail_id,
+ "guardrail_status": status,
+ "guardrail_response": (
+ {"action": "flag", "reason": "audit hit"} if status == "guardrail_flagged" else "allow"
+ ),
+ "duration": 0.002,
+ }
+ for status in guardrail_statuses
+ ]
+ }
+ return sl
+
+
+@pytest.mark.asyncio
+async def test_logs_reports_flagged_action_for_guardrail_flagged_status():
+ """LIT-6894: Request Logs surface a custom code flag() verdict as flagged with its reason."""
+ prisma = _prisma(index_find_many=[_index_row("r-flag"), _index_row("r-pass"), _index_row("r-block")])
+ prisma.db.litellm_spendlogs.find_many = AsyncMock(
+ return_value=[
+ _spend_log("r-flag", "guardrail_flagged"),
+ _spend_log("r-pass", "success"),
+ _spend_log("r-block", "guardrail_intervened"),
+ ]
+ )
+ p1, p2 = _patches(prisma, _config_handler())
+ with p1, p2:
+ resp = await guardrails_usage_logs(
+ guardrail_id="cc-flag",
+ policy_id=None,
+ page=1,
+ page_size=50,
+ action=None,
+ start_date=START,
+ end_date=END,
+ user_api_key_dict=ADMIN,
+ )
+ flagged_only = await guardrails_usage_logs(
+ guardrail_id="cc-flag",
+ policy_id=None,
+ page=1,
+ page_size=50,
+ action="flagged",
+ start_date=START,
+ end_date=END,
+ user_api_key_dict=ADMIN,
+ )
+ assert [(log.id, log.action) for log in resp.logs] == [
+ ("r-flag", "flagged"),
+ ("r-pass", "passed"),
+ ("r-block", "blocked"),
+ ]
+ assert resp.logs[0].reason == "{'action': 'flag', 'reason': 'audit hit'}"
+ assert [log.id for log in flagged_only.logs] == ["r-flag"]
+
+
+@pytest.mark.asyncio
+async def test_logs_reports_post_call_flag_when_pre_call_allowed():
+ """LIT-6894: a guardrail on mode [pre_call, post_call] that allows the request but flags the response
+ shows as flagged, not hidden behind the pre_call allow entry."""
+ prisma = _prisma(index_find_many=[_index_row("r-post-flag")])
+ prisma.db.litellm_spendlogs.find_many = AsyncMock(
+ return_value=[_spend_log("r-post-flag", "success", "guardrail_flagged")]
+ )
+ p1, p2 = _patches(prisma, _config_handler())
+ with p1, p2:
+ resp = await guardrails_usage_logs(
+ guardrail_id="cc-flag",
+ policy_id=None,
+ page=1,
+ page_size=50,
+ action=None,
+ start_date=START,
+ end_date=END,
+ user_api_key_dict=ADMIN,
+ )
+ assert [(log.id, log.action, log.reason) for log in resp.logs] == [
+ ("r-post-flag", "flagged", "{'action': 'flag', 'reason': 'audit hit'}")
+ ]
+
+
# ---- date window cap (LIT-5762) ---------------------------------------------
diff --git a/tests/test_litellm/proxy/guardrails/test_usage_tracking.py b/tests/test_litellm/proxy/guardrails/test_usage_tracking.py
index ae360b281cb..110de7dbe70 100644
--- a/tests/test_litellm/proxy/guardrails/test_usage_tracking.py
+++ b/tests/test_litellm/proxy/guardrails/test_usage_tracking.py
@@ -105,6 +105,27 @@ async def test_usage_units_rolled_up_by_guardrail_team_key_and_date():
}
+@pytest.mark.asyncio
+async def test_flagged_status_counts_as_flagged_not_passed_or_blocked():
+ """LIT-6894: a custom code flag() verdict lands in flagged_count on the Monitor rollup."""
+ prisma = _prisma()
+ logs = [
+ _payload("r1", guardrail_status="success"),
+ _payload("r2", guardrail_status="guardrail_flagged"),
+ _payload("r3", guardrail_status="guardrail_intervened"),
+ ]
+
+ await process_spend_logs_guardrail_usage(prisma, logs)
+
+ create = prisma.db.litellm_dailyguardrailmetrics.upsert.call_args.kwargs["data"]["create"]
+ assert (create["requests_evaluated"], create["passed_count"], create["flagged_count"], create["blocked_count"]) == (
+ 3,
+ 1,
+ 1,
+ 1,
+ )
+
+
def _fake_sleep() -> tuple[AsyncMock, list[float]]:
delays: list[float] = []
sleep = AsyncMock(side_effect=lambda delay: delays.append(delay))
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx
index a69824f32d3..05a48598859 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx
@@ -112,6 +112,7 @@ const PRIMITIVES = {
"Return Values": [
{ name: "allow()", desc: "Let request/response through" },
{ name: "block(reason)", desc: "Reject with message" },
+ { name: "flag(reason, metadata={})", desc: "Let through, record a non-blocking violation" },
{ name: "modify(texts=[], images=[], tool_calls=[])", desc: "Transform content" },
],
"HTTP Requests (async)": [
diff --git a/ui/litellm-dashboard/src/components/view_logs/GuardrailViewer/GuardrailViewer.test.tsx b/ui/litellm-dashboard/src/components/view_logs/GuardrailViewer/GuardrailViewer.test.tsx
index b5e04c72440..aabac50a661 100644
--- a/ui/litellm-dashboard/src/components/view_logs/GuardrailViewer/GuardrailViewer.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/GuardrailViewer/GuardrailViewer.test.tsx
@@ -33,6 +33,22 @@ describe("GuardrailViewer", () => {
expect(screen.getByText("1235ms")).toBeInTheDocument();
});
+ it("renders guardrail_flagged as FLAGGED (warning), not FAILED", () => {
+ const data = makeGuardrailInformation({
+ guardrail_name: "cc-flag",
+ guardrail_status: "guardrail_flagged",
+ guardrail_provider: "custom_code",
+ });
+ renderWithProviders( );
+
+ expect(screen.getByText(/0 Passed/)).toBeInTheDocument();
+ expect(screen.getByText(/1 Flagged/)).toBeInTheDocument();
+ const badges = screen.getAllByText("FLAGGED");
+ expect(badges.length).toBeGreaterThan(0);
+ expect(badges[0]).toHaveClass("text-warning");
+ expect(screen.queryByText("FAILED")).not.toBeInTheDocument();
+ });
+
it("calculates and displays masked entity totals", async () => {
const user = userEvent.setup();
const data = makeGuardrailInformation({
diff --git a/ui/litellm-dashboard/src/components/view_logs/GuardrailViewer/GuardrailViewer.tsx b/ui/litellm-dashboard/src/components/view_logs/GuardrailViewer/GuardrailViewer.tsx
index 863f4117510..271b8f6ce05 100644
--- a/ui/litellm-dashboard/src/components/view_logs/GuardrailViewer/GuardrailViewer.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/GuardrailViewer/GuardrailViewer.tsx
@@ -133,8 +133,27 @@ const getTotalMasked = (entry: GuardrailInformation): number => {
);
};
-const isEntrySuccess = (entry: GuardrailInformation): boolean => {
- return (entry.guardrail_status ?? "").toLowerCase() === "success";
+type EntryOutcome = "passed" | "flagged" | "failed";
+
+const getEntryOutcome = (entry: GuardrailInformation): EntryOutcome => {
+ const status = (entry.guardrail_status ?? "").toLowerCase();
+ if (status === "success") return "passed";
+ if (status === "guardrail_flagged") return "flagged";
+ return "failed";
+};
+
+const isEntrySuccess = (entry: GuardrailInformation): boolean => getEntryOutcome(entry) === "passed";
+
+const OUTCOME_LABEL: Record = {
+ passed: "PASSED",
+ flagged: "FLAGGED",
+ failed: "FAILED",
+};
+
+const OUTCOME_BADGE_CLASS: Record = {
+ passed: "bg-success/15 text-success border border-success/20",
+ flagged: "bg-warning/15 text-warning border border-warning/20",
+ failed: "bg-destructive/15 text-destructive border border-destructive/20",
};
const getRiskColor = (score: number): string => {
@@ -202,6 +221,19 @@ const FailCircleIcon = ({ className }: { className?: string }) => (
);
+const FlagCircleIcon = ({ className }: { className?: string }) => (
+
+
+
+
+);
+
+const OutcomeIcon = ({ outcome }: { outcome: EntryOutcome }) => {
+ if (outcome === "passed") return ;
+ if (outcome === "flagged") return ;
+ return ;
+};
+
const PlayCircleIcon = () => (
@@ -318,8 +350,7 @@ interface TimelineEntry {
type: "request" | "guardrail" | "llm" | "response";
label: string;
offsetMs: number;
- status?: string;
- isSuccess?: boolean;
+ outcome?: EntryOutcome;
}
const RequestLifecycle = ({ entries }: { entries: GuardrailInformation[] }) => {
@@ -348,8 +379,7 @@ const RequestLifecycle = ({ entries }: { entries: GuardrailInformation[] }) => {
type: "guardrail",
label: `Pre-call guardrail: ${getDisplayName(e)}`,
offsetMs,
- status: isEntrySuccess(e) ? "PASSED" : "FAILED",
- isSuccess: isEntrySuccess(e),
+ outcome: getEntryOutcome(e),
});
}
@@ -372,8 +402,7 @@ const RequestLifecycle = ({ entries }: { entries: GuardrailInformation[] }) => {
type: "guardrail",
label: `During-call guardrail: ${getDisplayName(e)}`,
offsetMs,
- status: isEntrySuccess(e) ? "PASSED" : "FAILED",
- isSuccess: isEntrySuccess(e),
+ outcome: getEntryOutcome(e),
});
}
@@ -384,8 +413,7 @@ const RequestLifecycle = ({ entries }: { entries: GuardrailInformation[] }) => {
type: "guardrail",
label: `Post-call guardrail: ${getDisplayName(e)}`,
offsetMs,
- status: isEntrySuccess(e) ? "PASSED" : "FAILED",
- isSuccess: isEntrySuccess(e),
+ outcome: getEntryOutcome(e),
});
}
@@ -410,10 +438,8 @@ const RequestLifecycle = ({ entries }: { entries: GuardrailInformation[] }) => {
) : item.type === "llm" ? (
- ) : item.isSuccess ? (
-
) : (
-
+
)}
{idx < timeline.length - 1 &&
}
@@ -425,13 +451,11 @@ const RequestLifecycle = ({ entries }: { entries: GuardrailInformation[] }) => {
{item.label}
- {item.status && (
+ {item.outcome && (
- {item.status}
+ {OUTCOME_LABEL[item.outcome]}
)}
T+{item.offsetMs}ms
@@ -455,7 +479,7 @@ const formatGuardrailCost = (cost: number): string => {
const EvaluationCard = ({ entry }: { entry: GuardrailInformation }) => {
const [expanded, setExpanded] = useState(false);
- const success = isEntrySuccess(entry);
+ const outcome = getEntryOutcome(entry);
const totalMasked = getTotalMasked(entry);
const displayName = getDisplayName(entry);
const durationStr = formatDurationMs(entry.duration);
@@ -490,7 +514,9 @@ const EvaluationCard = ({ entry }: { entry: GuardrailInformation }) => {
onClick={() => setExpanded(!expanded)}
>
{/* Status icon */}
- {success ? : }
+
+
+
{/* Name + badges */}
@@ -501,13 +527,9 @@ const EvaluationCard = ({ entry }: { entry: GuardrailInformation }) => {
- {success ? "PASSED" : "FAILED"}
+ {OUTCOME_LABEL[outcome]}
{matchCountStr && (
@@ -528,7 +550,7 @@ const EvaluationCard = ({ entry }: { entry: GuardrailInformation }) => {
)}
- {riskScore != null && success && (
+ {riskScore != null && outcome === "passed" && (
getEntryOutcome(e) === "flagged").length;
const allPassed = passedCount === guardrailEntries.length;
+ const headerOutcome: EntryOutcome = allPassed
+ ? "passed"
+ : passedCount + flaggedCount === guardrailEntries.length
+ ? "flagged"
+ : "failed";
const totalOverheadMs = useMemo(() => {
return Math.round(guardrailEntries.reduce((sum, e) => sum + (e.duration ?? 0), 0) * 1000);
@@ -709,11 +737,7 @@ const GuardrailViewer = ({ data, accessToken, logEntry }: GuardrailViewerProps)
|
{allPassed ? (
@@ -728,6 +752,13 @@ const GuardrailViewer = ({ data, accessToken, logEntry }: GuardrailViewerProps)
) : null}
{passedCount} Passed
+ {flaggedCount > 0 && (
+
+ {flaggedCount} Flagged
+
+ )}
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailContent.test.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailContent.test.tsx
index a679dc49427..2e9bce5048f 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailContent.test.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailContent.test.tsx
@@ -1,7 +1,7 @@
import { render, screen, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { describe, expect, it, vi } from "vitest";
-import { LogDetailContent } from "./LogDetailContent";
+import { GuardrailJumpLink, LogDetailContent } from "./LogDetailContent";
import type { LogEntry } from "../columns";
vi.mock("../GuardrailViewer/GuardrailViewer", () => ({
@@ -489,3 +489,17 @@ describe("LogDetailContent", () => {
expect(within(descriptions).getByText("-")).toBeInTheDocument();
});
});
+
+describe("GuardrailJumpLink", () => {
+ it.each([
+ [["success", "success"], "text-success", "\u2713"],
+ [["success", "guardrail_flagged"], "text-warning", "\u26A0"],
+ [["guardrail_flagged", "guardrail_intervened"], "text-destructive", "\u2717"],
+ ])("styles %j as %s", (statuses, expectedClass, glyph) => {
+ render( ({ guardrail_status: s }))} />);
+
+ const pill = screen.getByText(/2 guardrails evaluated/);
+ expect(pill).toHaveClass(expectedClass);
+ expect(pill).toHaveTextContent(glyph);
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailContent.tsx b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailContent.tsx
index 4c5c7b7b43f..052f1ec8802 100644
--- a/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailContent.tsx
+++ b/ui/litellm-dashboard/src/components/view_logs/LogDetailsDrawer/LogDetailContent.tsx
@@ -635,11 +635,24 @@ function RequestResponseSection({
);
}
+const GUARDRAIL_JUMP_LINK_STYLE = {
+ passed: { className: "border border-success/20 bg-success/10 text-success", glyph: "\u2713" },
+ flagged: { className: "border border-warning/20 bg-warning/10 text-warning", glyph: "\u26A0" },
+ failed: { className: "border border-destructive/20 bg-destructive/10 text-destructive", glyph: "\u2717" },
+} as const;
+
+const isPassedStatus = (status: unknown) => status === "pass" || status === "passed" || status === "success";
+const isFlaggedStatus = (status: unknown) => status === "flagged" || status === "guardrail_flagged";
+
+const guardrailJumpLinkOutcome = (statuses: unknown[]): keyof typeof GUARDRAIL_JUMP_LINK_STYLE => {
+ if (statuses.every(isPassedStatus)) return "passed";
+ if (statuses.every((s) => isPassedStatus(s) || isFlaggedStatus(s))) return "flagged";
+ return "failed";
+};
+
export function GuardrailJumpLink({ guardrailEntries }: { guardrailEntries: any[] }) {
- const allPassed = guardrailEntries.every((e) => {
- const status = e?.guardrail_status || e?.status;
- return status === "pass" || status === "passed" || status === "success";
- });
+ const outcome = guardrailJumpLinkOutcome(guardrailEntries.map((e) => e?.guardrail_status || e?.status));
+ const { className, glyph } = GUARDRAIL_JUMP_LINK_STYLE[outcome];
const handleClick = () => {
const el = document.getElementById("guardrail-section");
@@ -650,11 +663,7 @@ export function GuardrailJumpLink({ guardrailEntries }: { guardrailEntries: any[
- {allPassed ? "\u2713" : "\u2717"} {guardrailEntries.length} guardrail{guardrailEntries.length !== 1 ? "s" : ""}{" "}
- evaluated
+ {glyph} {guardrailEntries.length} guardrail
+ {guardrailEntries.length !== 1 ? "s" : ""} evaluated
{"\u2193"}
From d6bc8fe289271457b733190f8abd9c261599b009 Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 13:23:38 -0700
Subject: [PATCH 15/35] test(e2e): ask the streamed /v1/messages pin for a
reply long enough to span several deltas
Anthropic now returns the 64-token 'count to 20' reply in one to three content_block_delta events, measured directly against api.anthropic.com and through proxies at 7672399 and 49a1145 alike, so the incrementality assertion (at least two deltas) failed in litellm-e2e builds 125, 130 and the 278 rerun with no proxy change behind it. A 'count to 100' reply at max_tokens 400 arrived in five to fifty deltas across every measured run
---
tests/e2e/llm_translation/test_messages_e2e.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/e2e/llm_translation/test_messages_e2e.py b/tests/e2e/llm_translation/test_messages_e2e.py
index e0bedd72eac..a5f36a8cbdd 100644
--- a/tests/e2e/llm_translation/test_messages_e2e.py
+++ b/tests/e2e/llm_translation/test_messages_e2e.py
@@ -169,9 +169,9 @@ class TestAnthropicMessages:
key,
AnthropicMessagesBody(
model=model,
- max_tokens=64,
+ max_tokens=400,
stream=True,
- messages=[ChatMessage(role="user", content="Count from 1 to 20, one number per line.")],
+ messages=[ChatMessage(role="user", content="Count from 1 to 100, one number per line.")],
),
)
require_successful_call(result)
From 80839bb33c318851af40b125c54c262bbe5dc90f Mon Sep 17 00:00:00 2001
From: "devin-ai-integration[bot]"
<158243242+devin-ai-integration[bot]@users.noreply.github.com>
Date: Sat, 5 Sep 2026 13:26:09 -0700
Subject: [PATCH 16/35] feat(proxy): serve Prometheus /metrics from a separate
process via --prometheus_metrics_port (#39889)
* feat(proxy): serve Prometheus /metrics from a separate process via --prometheus_metrics_port
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* style(proxy): ruff format prometheus_metrics_server
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): fail fast when the separate metrics server cannot start and force the multiproc dir whenever it is enabled
- wait for the child's /health before starting uvicorn; raise a ClickException if it exits first (port in use)
- create PROMETHEUS_MULTIPROC_DIR whenever --prometheus_metrics_port is set, so DB-configured prometheus callbacks work
- honour lowercase prometheus_multiproc_dir; validate the port before spawning
- cover main() entry point, readiness, bind failure and wildcard-host probing in tests
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): pin metrics-server readiness to the child pid so another service on the port cannot pass the health check
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor(proxy): probe metrics-server readiness through the shared HTTPHandler instead of bare httpx.get
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor(proxy): serve only /metrics on the prometheus metrics port
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): validate metrics server CLI args with pydantic instead of typing.cast
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(proxy): satisfy metrics server lint gate
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: yassin
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---
basedpyright-code-budget.json | 4 +-
litellm/proxy/prometheus_metrics_server.py | 167 +++++++++++
litellm/proxy/proxy_cli.py | 90 ++++--
.../proxy/test_prometheus_cleanup.py | 40 +++
.../proxy/test_prometheus_metrics_server.py | 259 ++++++++++++++++++
tests/test_litellm/proxy/test_proxy_cli.py | 118 ++++++++
type-discipline-budget.json | 4 +-
7 files changed, 649 insertions(+), 33 deletions(-)
create mode 100644 litellm/proxy/prometheus_metrics_server.py
create mode 100644 tests/test_litellm/proxy/test_prometheus_metrics_server.py
diff --git a/basedpyright-code-budget.json b/basedpyright-code-budget.json
index b876cf2d69a..0b0a61192e6 100644
--- a/basedpyright-code-budget.json
+++ b/basedpyright-code-budget.json
@@ -105,13 +105,13 @@
"limit": 109
},
"reportUnknownMemberType": {
- "limit": 38283
+ "limit": 38271
},
"reportUnknownParameterType": {
"limit": 19584
},
"reportUnknownVariableType": {
- "limit": 29829
+ "limit": 29814
},
"reportUnnecessaryCast": {
"limit": 110
diff --git a/litellm/proxy/prometheus_metrics_server.py b/litellm/proxy/prometheus_metrics_server.py
new file mode 100644
index 00000000000..4a9651d62e1
--- /dev/null
+++ b/litellm/proxy/prometheus_metrics_server.py
@@ -0,0 +1,167 @@
+"""Serve Prometheus `/metrics` from its own process so a scrape never runs on an inference worker.
+
+Workers write their samples to `PROMETHEUS_MULTIPROC_DIR`; this process reads them back with a
+``MultiProcessCollector`` and serves the aggregated output on a separate port. The proxy CLI starts
+it with ``--prometheus_metrics_port``. It can also run as a sidecar sharing the same directory:
+``python -m litellm.proxy.prometheus_metrics_server --host 0.0.0.0 --port 4001``.
+"""
+
+from __future__ import annotations
+
+import argparse
+import atexit
+import os
+import subprocess
+import sys
+import threading
+import time
+from collections.abc import Sequence
+from contextlib import closing
+from types import MappingProxyType
+from typing import Final
+
+import httpx
+from fastapi import FastAPI
+from prometheus_client import CollectorRegistry, multiprocess
+from pydantic import BaseModel, ConfigDict
+from starlette.types import ASGIApp, Message, Receive, Scope, Send
+
+from litellm.integrations.prometheus_metrics_endpoint import make_metrics_asgi_app
+from litellm.llms.custom_httpx.http_handler import HTTPHandler
+
+METRICS_PATH: Final = "/metrics"
+PID_HEADER: Final = "x-litellm-metrics-pid"
+_PARENT_POLL_INTERVAL_SECONDS: Final = 1.0
+_STARTUP_TIMEOUT_SECONDS: Final = 30.0
+_STARTUP_POLL_INTERVAL_SECONDS: Final = 0.1
+_STARTUP_PROBE_TIMEOUT_SECONDS: Final = 1.0
+_WILDCARD_TO_LOOPBACK: Final = MappingProxyType({"0.0.0.0": "127.0.0.1", "::": "::1"})
+
+
+class _CliArgs(BaseModel):
+ model_config = ConfigDict(frozen=True)
+
+ host: str
+ port: int
+ multiproc_dir: str | None
+
+
+class MetricsServerStartupError(RuntimeError):
+ """The metrics process died or never answered on its port before the proxy started serving."""
+
+
+def _add_pid_header(app: ASGIApp) -> ASGIApp:
+ async def app_with_pid(scope: Scope, receive: Receive, send: Send) -> None:
+ async def send_with_pid(message: Message) -> None:
+ if message["type"] == "http.response.start":
+ await send(
+ {
+ **message,
+ "headers": [
+ *message["headers"],
+ (PID_HEADER.encode(), str(os.getpid()).encode()),
+ ],
+ }
+ )
+ return
+ await send(message)
+
+ await app(scope, receive, send_with_pid)
+
+ return app_with_pid
+
+
+def build_metrics_app(multiproc_dir: str) -> FastAPI:
+ registry: Final = CollectorRegistry()
+ multiprocess.MultiProcessCollector(registry, path=multiproc_dir)
+ app: Final = FastAPI(title="LiteLLM Prometheus metrics", docs_url=None, redoc_url=None, openapi_url=None)
+ app.mount(METRICS_PATH, _add_pid_header(make_metrics_asgi_app(registry)))
+
+ return app
+
+
+def _exit_when_parent_dies(parent_pid: int) -> None:
+ def watch() -> None:
+ while os.getppid() == parent_pid:
+ time.sleep(_PARENT_POLL_INTERVAL_SECONDS)
+ os._exit(0)
+
+ threading.Thread(target=watch, name="litellm-metrics-parent-watchdog", daemon=True).start()
+
+
+def run_metrics_server(host: str, port: int, multiproc_dir: str) -> None:
+ import uvicorn
+
+ _exit_when_parent_dies(os.getppid())
+ uvicorn.run(build_metrics_app(multiproc_dir), host=host, port=port, log_level="warning", access_log=False)
+
+
+def metrics_url(host: str, port: int) -> str:
+ probe_host: Final = _WILDCARD_TO_LOOPBACK.get(host, host)
+ netloc: Final = f"[{probe_host}]" if ":" in probe_host else probe_host
+ return f"http://{netloc}:{port}{METRICS_PATH}"
+
+
+def _answered_by(http: HTTPHandler, url: str, pid: int) -> bool:
+ """True only when the metrics response comes from our child, not from whatever else holds the port."""
+ try:
+ response: Final = http.get(url) # pyright: ignore[reportUnknownMemberType] # HTTPHandler.get exposes untyped optional mappings
+ return response.status_code == 200 and response.headers.get(PID_HEADER) == str(pid)
+ except httpx.TransportError:
+ return False
+
+
+def _wait_until_serving(process: subprocess.Popen[bytes], host: str, port: int) -> None:
+ url: Final = metrics_url(host, port)
+ deadline: Final = time.monotonic() + _STARTUP_TIMEOUT_SECONDS
+ with closing(HTTPHandler(timeout=_STARTUP_PROBE_TIMEOUT_SECONDS)) as http:
+ while time.monotonic() < deadline:
+ if (returncode := process.poll()) is not None:
+ raise MetricsServerStartupError(
+ f"Prometheus metrics server exited with code {returncode} before serving {host}:{port}; "
+ "is the port already in use?"
+ )
+ if _answered_by(http, url, process.pid):
+ return
+ time.sleep(_STARTUP_POLL_INTERVAL_SECONDS)
+ process.terminate()
+ raise MetricsServerStartupError(
+ f"Prometheus metrics server did not answer {url} within {_STARTUP_TIMEOUT_SECONDS:.0f}s"
+ )
+
+
+def start_metrics_server_process(host: str, port: int, multiproc_dir: str) -> subprocess.Popen[bytes]:
+ """Spawn the metrics server next to the proxy and block until it answers on its port."""
+ process: Final = subprocess.Popen(
+ (
+ sys.executable,
+ "-m",
+ "litellm.proxy.prometheus_metrics_server",
+ "--host",
+ host,
+ "--port",
+ str(port),
+ "--multiproc_dir",
+ multiproc_dir,
+ )
+ )
+ atexit.register(process.terminate)
+ _wait_until_serving(process, host, port)
+ return process
+
+
+def main(argv: Sequence[str] | None = None) -> None:
+ parser: Final = argparse.ArgumentParser(
+ description="Serve LiteLLM Prometheus metrics from PROMETHEUS_MULTIPROC_DIR"
+ )
+ parser.add_argument("--host", default="0.0.0.0")
+ parser.add_argument("--port", type=int, required=True)
+ parser.add_argument("--multiproc_dir", default=os.environ.get("PROMETHEUS_MULTIPROC_DIR"))
+ args: Final = _CliArgs.model_validate(vars(parser.parse_args(argv)))
+ if not args.multiproc_dir:
+ parser.error("--multiproc_dir or PROMETHEUS_MULTIPROC_DIR is required")
+ run_metrics_server(host=args.host, port=args.port, multiproc_dir=args.multiproc_dir)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/litellm/proxy/proxy_cli.py b/litellm/proxy/proxy_cli.py
index e780beb4410..e245367b1b4 100644
--- a/litellm/proxy/proxy_cli.py
+++ b/litellm/proxy/proxy_cli.py
@@ -7,7 +7,7 @@ import re
import subprocess
import sys
import urllib.parse as urlparse
-from collections.abc import Iterable
+from collections.abc import Iterable, Mapping, Sequence
from pathlib import Path
from typing import TYPE_CHECKING, Any, Final
@@ -610,48 +610,49 @@ class ProxyInitializationHelpers:
return None # Let uvicorn choose the default loop on Windows
return "uvloop"
+ @staticmethod
+ def _prometheus_callback_configured(litellm_settings: Mapping[str, object] | None) -> bool:
+ if litellm_settings is None:
+ return False
+ configured: Final = tuple(
+ litellm_settings.get(key) for key in ("callbacks", "success_callback", "failure_callback")
+ )
+ return any(
+ setting == "prometheus"
+ if isinstance(setting, str)
+ else isinstance(setting, Sequence) and "prometheus" in setting
+ for setting in configured
+ )
+
@staticmethod
def _maybe_setup_prometheus_multiproc_dir(
num_workers: int,
litellm_settings: dict | None,
- ) -> None:
+ prometheus_metrics_port: int | None = None,
+ ) -> str | None:
"""
- Auto-create PROMETHEUS_MULTIPROC_DIR when running with multiple workers
- and prometheus is configured as a callback.
+ Auto-create PROMETHEUS_MULTIPROC_DIR when another process needs to read the samples: extra workers
+ with prometheus configured as a callback in config.yaml, or the separate metrics server (always, since
+ callbacks may also be enabled from the DB after startup).
"""
import tempfile
- if num_workers <= 1 or litellm_settings is None:
- return
-
- # Check if prometheus is in any callback list
- # Each setting can be a list or a single string; normalize to list
- callbacks = litellm_settings.get("callbacks") or []
- success_callbacks = litellm_settings.get("success_callback") or []
- failure_callbacks = litellm_settings.get("failure_callback") or []
- if isinstance(callbacks, str):
- callbacks = [callbacks]
- if isinstance(success_callbacks, str):
- success_callbacks = [success_callbacks]
- if isinstance(failure_callbacks, str):
- failure_callbacks = [failure_callbacks]
- all_callbacks: Final = callbacks + success_callbacks + failure_callbacks
- if "prometheus" not in all_callbacks:
- return
+ if prometheus_metrics_port is None and (
+ num_workers <= 1 or not ProxyInitializationHelpers._prometheus_callback_configured(litellm_settings)
+ ):
+ return None
from litellm.proxy.prometheus_cleanup import wipe_directory
- multiproc_dir = os.environ.get("PROMETHEUS_MULTIPROC_DIR") or os.environ.get("prometheus_multiproc_dir")
-
- auto_created: Final = not multiproc_dir
- if not multiproc_dir:
- multiproc_dir = os.path.join(tempfile.gettempdir(), "litellm_prometheus_multiproc")
- os.environ["PROMETHEUS_MULTIPROC_DIR"] = multiproc_dir
+ configured_dir: Final = os.environ.get("PROMETHEUS_MULTIPROC_DIR") or os.environ.get("prometheus_multiproc_dir")
+ multiproc_dir: Final = configured_dir or os.path.join(tempfile.gettempdir(), "litellm_prometheus_multiproc")
+ os.environ["PROMETHEUS_MULTIPROC_DIR"] = multiproc_dir
os.makedirs(multiproc_dir, exist_ok=True)
wipe_directory(multiproc_dir)
- action: Final = "Auto-created" if auto_created else "Using existing"
+ action: Final = "Using existing" if configured_dir else "Auto-created"
print(f"LiteLLM: {action} PROMETHEUS_MULTIPROC_DIR={multiproc_dir}")
+ return multiproc_dir
@click.command()
@@ -930,6 +931,19 @@ class ProxyInitializationHelpers:
default=False,
help="Enable uvicorn hot reload (dev only). Also reloads when the --config YAML file changes. Incompatible with --num_workers>1, --run_gunicorn, and --run_hypercorn.",
)
+@click.option(
+ "--prometheus_metrics_port",
+ default=None,
+ type=click.IntRange(min=1, max=65535),
+ help=(
+ "Serve Prometheus /metrics from a separate process on this port (bound to --host) so scraping and "
+ "multi-worker aggregation never run on an inference worker's event loop. Samples appear once the "
+ "`prometheus` callback is enabled (config.yaml or DB). /metrics stays mounted on the main port as well; "
+ "the separate port has no virtual-key auth, so keep it off public ingress. Startup fails if the metrics "
+ "server cannot bind."
+ ),
+ envvar="PROMETHEUS_METRICS_PORT",
+)
def run_server(
cli_args,
host,
@@ -980,6 +994,7 @@ def run_server(
enforce_prisma_migration_check: bool,
use_v2_migration_resolver: bool,
reload: bool,
+ prometheus_metrics_port: int | None,
):
if cli_args:
if cli_args == ("xai-oauth", "login"):
@@ -1364,6 +1379,8 @@ def run_server(
)
if port == 4000 and ProxyInitializationHelpers._is_port_in_use(port):
port = random.randint(1024, 49152)
+ if prometheus_metrics_port == port:
+ raise click.UsageError("--prometheus_metrics_port must differ from --port")
import litellm
@@ -1374,9 +1391,10 @@ def run_server(
from litellm.proxy.proxy_server import app
# Auto-create PROMETHEUS_MULTIPROC_DIR for multi-worker setups
- ProxyInitializationHelpers._maybe_setup_prometheus_multiproc_dir(
+ prometheus_multiproc_dir: Final = ProxyInitializationHelpers._maybe_setup_prometheus_multiproc_dir(
num_workers=num_workers,
litellm_settings=litellm_settings if config else None,
+ prometheus_metrics_port=prometheus_metrics_port,
)
# Skip server startup if requested (after all setup is done)
@@ -1384,6 +1402,20 @@ def run_server(
print("LiteLLM: Setup complete. Skipping server startup as requested.")
return
+ if prometheus_metrics_port is not None and prometheus_multiproc_dir is not None:
+ from litellm.proxy.prometheus_metrics_server import MetricsServerStartupError, start_metrics_server_process
+
+ try:
+ metrics_process: Final = start_metrics_server_process(
+ host=host, port=prometheus_metrics_port, multiproc_dir=prometheus_multiproc_dir
+ )
+ except MetricsServerStartupError as error:
+ raise click.ClickException(str(error)) from error
+ print(
+ f"\033[1;32mLiteLLM: Serving Prometheus metrics on {host}:{prometheus_metrics_port}/metrics "
+ f"(pid {metrics_process.pid})\033[0m"
+ )
+
running_uvicorn: Final = run_gunicorn is False and run_hypercorn is False
uvicorn_args: Final = ProxyInitializationHelpers._get_default_unvicorn_init_args(
host=host,
diff --git a/tests/test_litellm/proxy/test_prometheus_cleanup.py b/tests/test_litellm/proxy/test_prometheus_cleanup.py
index ca5476d6af9..93b9b694c2c 100644
--- a/tests/test_litellm/proxy/test_prometheus_cleanup.py
+++ b/tests/test_litellm/proxy/test_prometheus_cleanup.py
@@ -131,3 +131,43 @@ class TestMaybeSetupPrometheusMultiprocDir:
# Cleanup
os.environ.pop("PROMETHEUS_MULTIPROC_DIR", None)
+
+ @pytest.mark.parametrize(
+ "litellm_settings",
+ [
+ {"callbacks": ["prometheus"]},
+ {"callbacks": ["langfuse"]},
+ None,
+ ],
+ )
+ def test_separate_metrics_port_forces_dir_for_single_worker(self, litellm_settings):
+ """The separate metrics process reads the samples, so one worker still needs the shared dir, even when
+ prometheus is not in config.yaml (callbacks can be turned on from the DB after startup)."""
+ with patch.dict(os.environ, {}, clear=False):
+ os.environ.pop("PROMETHEUS_MULTIPROC_DIR", None)
+ os.environ.pop("prometheus_multiproc_dir", None)
+
+ result_dir = ProxyInitializationHelpers._maybe_setup_prometheus_multiproc_dir(
+ num_workers=1,
+ litellm_settings=litellm_settings,
+ prometheus_metrics_port=4001,
+ )
+
+ assert result_dir is not None
+ assert os.environ.get("PROMETHEUS_MULTIPROC_DIR") == result_dir
+ assert os.path.isdir(result_dir)
+
+ os.environ.pop("PROMETHEUS_MULTIPROC_DIR", None)
+
+ def test_lowercase_env_var_is_reused_and_exported_uppercase(self, tmp_path):
+ """prometheus_client honours both spellings; the metrics server only reads the uppercase one."""
+ with patch.dict(os.environ, {"prometheus_multiproc_dir": str(tmp_path)}, clear=False):
+ os.environ.pop("PROMETHEUS_MULTIPROC_DIR", None)
+
+ result_dir = ProxyInitializationHelpers._maybe_setup_prometheus_multiproc_dir(
+ num_workers=4,
+ litellm_settings={"callbacks": "prometheus"},
+ )
+
+ assert result_dir == str(tmp_path)
+ assert os.environ["PROMETHEUS_MULTIPROC_DIR"] == str(tmp_path)
diff --git a/tests/test_litellm/proxy/test_prometheus_metrics_server.py b/tests/test_litellm/proxy/test_prometheus_metrics_server.py
new file mode 100644
index 00000000000..fc1fa381fa4
--- /dev/null
+++ b/tests/test_litellm/proxy/test_prometheus_metrics_server.py
@@ -0,0 +1,259 @@
+"""The separate metrics server must aggregate PROMETHEUS_MULTIPROC_DIR, expose only /metrics, and follow its
+parent's lifetime.
+
+Everything here runs on loopback against a child of this test process; no LLM keys or external network.
+"""
+
+from __future__ import annotations
+
+import os
+import socket
+import subprocess
+import sys
+import threading
+import time
+from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
+from pathlib import Path
+from typing import Final
+from unittest.mock import patch
+
+import httpx
+import pytest
+from fastapi.testclient import TestClient
+from prometheus_client import values
+
+from litellm.proxy.prometheus_metrics_server import (
+ PID_HEADER,
+ MetricsServerStartupError,
+ build_metrics_app,
+ main,
+ metrics_url,
+ start_metrics_server_process,
+)
+
+_STARTUP_TIMEOUT_SECONDS: Final = 60.0
+_SHUTDOWN_TIMEOUT_SECONDS: Final = 15.0
+
+
+def _write_worker_sample(pid: int, value: float) -> None:
+ """Write one counter sample into PROMETHEUS_MULTIPROC_DIR the way a proxy worker would."""
+ counter: Final = values.MultiProcessValue(process_identifier=lambda: pid)(
+ "counter",
+ "litellm_requests_metric_total",
+ "litellm_requests_metric_total",
+ ("model",),
+ ("gpt-5",),
+ "Total number of LLM calls",
+ )
+ counter.inc(value)
+
+
+def _free_port() -> int:
+ with socket.socket() as sock:
+ sock.bind(("127.0.0.1", 0))
+ return sock.getsockname()[1]
+
+
+def _wait_for_metrics(port: int, pid: int) -> httpx.Response:
+ deadline: Final = time.monotonic() + _STARTUP_TIMEOUT_SECONDS
+ while time.monotonic() < deadline:
+ try:
+ response: Final = httpx.get(f"http://127.0.0.1:{port}/metrics", follow_redirects=True, timeout=1.0)
+ if response.status_code == 200 and response.headers.get(PID_HEADER) == str(pid):
+ return response
+ except httpx.TransportError:
+ pass
+ time.sleep(0.2)
+ raise AssertionError(f"metrics server on port {port} never served metrics")
+
+
+def _wait_until_down(port: int) -> None:
+ deadline: Final = time.monotonic() + _SHUTDOWN_TIMEOUT_SECONDS
+ while time.monotonic() < deadline:
+ try:
+ httpx.get(f"http://127.0.0.1:{port}/metrics", timeout=1.0)
+ except httpx.TransportError:
+ return
+ time.sleep(0.2)
+ raise AssertionError(f"metrics server on port {port} kept running after its parent died")
+
+
+def test_metrics_app_aggregates_multiproc_dir_and_reports_pid(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
+ monkeypatch.setenv("PROMETHEUS_MULTIPROC_DIR", str(tmp_path))
+ _write_worker_sample(pid=1001, value=2)
+ _write_worker_sample(pid=1002, value=3)
+ other_dir: Final = tmp_path / "other"
+ other_dir.mkdir()
+
+ client: Final = TestClient(build_metrics_app(str(tmp_path)))
+ metrics: Final = client.get("/metrics")
+ assert metrics.status_code == 200
+ assert metrics.headers[PID_HEADER] == str(os.getpid())
+ assert 'litellm_requests_metric_total{model="gpt-5"} 5.0' in metrics.text
+
+ assert client.get("/health").status_code == 404
+
+ empty: Final = TestClient(build_metrics_app(str(other_dir))).get("/metrics")
+ assert empty.status_code == 200
+ assert "litellm_requests_metric_total" not in empty.text
+
+
+@pytest.mark.parametrize(
+ ("host", "expected"),
+ (
+ ("0.0.0.0", "http://127.0.0.1:4001/metrics"),
+ ("::", "http://[::1]:4001/metrics"),
+ ("10.1.2.3", "http://10.1.2.3:4001/metrics"),
+ ("metrics.internal", "http://metrics.internal:4001/metrics"),
+ ),
+)
+def test_metrics_url_probes_loopback_for_wildcard_binds(host: str, expected: str):
+ assert metrics_url(host, 4001) == expected
+
+
+def test_main_serves_the_app_for_the_given_dir_with_uvicorn(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
+ monkeypatch.setenv("PROMETHEUS_MULTIPROC_DIR", str(tmp_path))
+ _write_worker_sample(pid=2001, value=6)
+ with patch("uvicorn.run") as run:
+ main(["--host", "10.1.2.3", "--port", "4001", "--multiproc_dir", str(tmp_path)])
+
+ run.assert_called_once()
+ assert run.call_args.kwargs["host"] == "10.1.2.3"
+ assert run.call_args.kwargs["port"] == 4001
+ client: Final = TestClient(run.call_args.args[0])
+ metrics: Final = client.get("/metrics")
+ assert metrics.status_code == 200
+ assert metrics.headers[PID_HEADER] == str(os.getpid())
+ assert 'litellm_requests_metric_total{model="gpt-5"} 6.0' in client.get("/metrics").text
+
+
+def test_main_falls_back_to_env_multiproc_dir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
+ monkeypatch.setenv("PROMETHEUS_MULTIPROC_DIR", str(tmp_path))
+ with patch("uvicorn.run") as run:
+ main(["--port", "4001"])
+
+ (app,), served_on = run.call_args
+ assert served_on["host"] == "0.0.0.0"
+ metrics: Final = TestClient(app).get("/metrics")
+ assert metrics.status_code == 200
+ assert metrics.headers[PID_HEADER] == str(os.getpid())
+
+
+def test_main_rejects_missing_multiproc_dir(monkeypatch: pytest.MonkeyPatch):
+ monkeypatch.delenv("PROMETHEUS_MULTIPROC_DIR", raising=False)
+ with patch("uvicorn.run") as run, pytest.raises(SystemExit) as exit_info:
+ main(["--port", "4001"])
+
+ assert exit_info.value.code == 2
+ run.assert_not_called()
+
+
+def test_start_metrics_server_process_returns_only_once_child_serves(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
+ monkeypatch.setenv("PROMETHEUS_MULTIPROC_DIR", str(tmp_path))
+ _write_worker_sample(pid=3001, value=4)
+ port: Final = _free_port()
+ with patch("atexit.register") as register:
+ process: Final = start_metrics_server_process(host="127.0.0.1", port=port, multiproc_dir=str(tmp_path))
+ try:
+ register.assert_called_once_with(process.terminate)
+ assert process.poll() is None
+ startup_metrics: Final = httpx.get(f"http://127.0.0.1:{port}/metrics", follow_redirects=True, timeout=5.0)
+ assert startup_metrics.status_code == 200
+ assert startup_metrics.headers[PID_HEADER] == str(process.pid)
+ metrics: Final = httpx.get(f"http://127.0.0.1:{port}/metrics", follow_redirects=True, timeout=10.0)
+ assert 'litellm_requests_metric_total{model="gpt-5"} 4.0' in metrics.text
+ finally:
+ process.kill()
+ process.wait(timeout=10)
+
+
+def test_start_metrics_server_process_fails_when_port_is_taken(tmp_path: Path):
+ with socket.socket() as occupied:
+ occupied.bind(("127.0.0.1", 0))
+ occupied.listen()
+ port: Final = occupied.getsockname()[1]
+ with (
+ patch("atexit.register"),
+ pytest.raises(
+ MetricsServerStartupError, match=rf"exited with code [1-9]\d* before serving 127.0.0.1:{port}"
+ ),
+ ):
+ start_metrics_server_process(host="127.0.0.1", port=port, multiproc_dir=str(tmp_path))
+
+
+class _ImpostorMetrics(BaseHTTPRequestHandler):
+ """An unrelated service already on the port that answers /metrics with 200 and plausible metrics."""
+
+ def do_GET(self) -> None:
+ body: Final = b"# HELP impostor_metric A plausible metric\n# TYPE impostor_metric counter\nimpostor_metric 1\n"
+ self.send_response(200)
+ self.send_header("Content-Type", "text/plain")
+ self.end_headers()
+ self.wfile.write(body)
+
+ def log_message(self, format: str, *args: object) -> None:
+ return
+
+
+def test_start_metrics_server_process_rejects_metrics_from_another_service_on_the_port(tmp_path: Path):
+ with ThreadingHTTPServer(("127.0.0.1", 0), _ImpostorMetrics) as impostor:
+ threading.Thread(target=impostor.serve_forever, daemon=True).start()
+ port: Final = impostor.server_address[1]
+ impostor_response: Final = httpx.get(f"http://127.0.0.1:{port}/metrics")
+ assert impostor_response.status_code == 200
+ assert "# HELP impostor_metric" in impostor_response.text
+ assert PID_HEADER not in impostor_response.headers
+ with (
+ patch("atexit.register"),
+ pytest.raises(MetricsServerStartupError, match=rf"exited with code [1-9]\d* before serving 127.0.0.1:{port}"),
+ ):
+ start_metrics_server_process(host="127.0.0.1", port=port, multiproc_dir=str(tmp_path))
+ impostor.shutdown()
+
+
+def test_metrics_server_process_serves_and_exits_with_parent(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
+ monkeypatch.setenv("PROMETHEUS_MULTIPROC_DIR", str(tmp_path))
+ _write_worker_sample(pid=2001, value=7)
+ port: Final = _free_port()
+ server_argv: Final = (
+ sys.executable,
+ "-m",
+ "litellm.proxy.prometheus_metrics_server",
+ "--host",
+ "127.0.0.1",
+ "--port",
+ str(port),
+ "--multiproc_dir",
+ str(tmp_path),
+ )
+ parent: Final = subprocess.Popen(
+ (
+ sys.executable,
+ "-c",
+ "import subprocess, sys, time; p = subprocess.Popen(sys.argv[1:]); print(p.pid, flush=True); time.sleep(600)",
+ *server_argv,
+ ),
+ stdout=subprocess.PIPE,
+ text=True,
+ )
+ assert parent.stdout is not None
+ server_pid: Final = int(parent.stdout.readline())
+ try:
+ metrics: Final = _wait_for_metrics(port, server_pid)
+ assert metrics.status_code == 200
+ assert metrics.headers[PID_HEADER] == str(server_pid)
+
+ scrape: Final = httpx.get(f"http://127.0.0.1:{port}/metrics", follow_redirects=True, timeout=10.0)
+ assert scrape.status_code == 200
+ assert scrape.headers[PID_HEADER] == str(server_pid)
+ assert 'litellm_requests_metric_total{model="gpt-5"} 7.0' in scrape.text
+
+ parent.kill()
+ parent.wait(timeout=10)
+ _wait_until_down(port)
+ finally:
+ parent.kill()
+ try:
+ os.kill(server_pid, 9)
+ except ProcessLookupError:
+ pass
diff --git a/tests/test_litellm/proxy/test_proxy_cli.py b/tests/test_litellm/proxy/test_proxy_cli.py
index 9256706d340..0c20d5e0ff0 100644
--- a/tests/test_litellm/proxy/test_proxy_cli.py
+++ b/tests/test_litellm/proxy/test_proxy_cli.py
@@ -662,6 +662,124 @@ class TestProxyInitializationHelpers:
assert "Invalid value for '--limit_concurrency'" in result.output
mock_uvicorn_run.assert_not_called()
+ @patch("uvicorn.run")
+ @patch("httpx.HTTPTransport.handle_request")
+ @patch("atexit.register")
+ @patch("subprocess.Popen")
+ @patch("litellm.proxy.db.prisma_client.PrismaManager.setup_database") # test-quality-ok: run_server always wires the DB; same isolation as the sibling CLI tests above
+ @patch( # test-quality-ok: run_server always wires the DB; same isolation as the sibling CLI tests above
+ "litellm.proxy.db.prisma_client.should_update_prisma_schema", return_value=False
+ )
+ def test_prometheus_metrics_port_starts_separate_metrics_process(
+ self,
+ mock_should_update,
+ mock_setup_db,
+ mock_popen,
+ mock_atexit_register,
+ mock_handle_request,
+ mock_uvicorn_run,
+ tmp_path,
+ ):
+ """--prometheus_metrics_port must spawn `python -m litellm.proxy.prometheus_metrics_server` on --host
+ with the shared multiproc dir, wait for its /metrics response, and only then start uvicorn. It must stay off by
+ default, refuse to share --port, and abort the proxy when the child dies before serving."""
+ import httpx
+ from click.testing import CliRunner
+
+ from litellm.proxy.proxy_cli import run_server
+
+ runner = CliRunner()
+ mock_popen.return_value = MagicMock(pid=4242, **{"poll.return_value": None})
+ probed_urls: list[str] = []
+
+ def child_metrics(request: httpx.Request) -> httpx.Response:
+ probed_urls.append(str(request.url))
+ return httpx.Response(200, headers={"x-litellm-metrics-pid": "4242"}, content=b"")
+
+ mock_handle_request.side_effect = child_metrics
+ mock_proxy_module = MagicMock(
+ app=MagicMock(),
+ ProxyConfig=MagicMock(),
+ KeyManagementSettings=MagicMock(),
+ save_worker_config=MagicMock(),
+ )
+ clean_env = {
+ k: v
+ for k, v in os.environ.items()
+ if k not in ("DATABASE_URL", "DIRECT_URL", "PROMETHEUS_METRICS_PORT")
+ }
+ clean_env["PROMETHEUS_MULTIPROC_DIR"] = str(tmp_path)
+ with (
+ patch.dict(os.environ, clean_env, clear=True),
+ patch.dict(
+ "sys.modules",
+ {
+ "proxy_server": mock_proxy_module,
+ "litellm.proxy.proxy_server": mock_proxy_module,
+ },
+ ),
+ patch( # test-quality-ok: same isolation as the sibling CLI tests above
+ "litellm.proxy.proxy_cli.ProxyInitializationHelpers._get_default_unvicorn_init_args"
+ ) as mock_get_args,
+ ):
+ mock_get_args.side_effect = lambda *a, **k: {
+ "app": "litellm.proxy.proxy_server:app",
+ "host": "localhost",
+ "port": 8000,
+ }
+
+ result = runner.invoke(
+ run_server,
+ ["--local", "--host", "127.0.0.1", "--port", "4000", "--prometheus_metrics_port", "4001"],
+ )
+ assert (
+ result.exit_code == 0
+ ), f"exit_code={result.exit_code}, output={result.output}"
+ mock_popen.assert_called_once()
+ spawned = list(mock_popen.call_args.args[0])
+ assert spawned[1:3] == ["-m", "litellm.proxy.prometheus_metrics_server"]
+ assert spawned[3:] == ["--host", "127.0.0.1", "--port", "4001", "--multiproc_dir", str(tmp_path)]
+ assert probed_urls == ["http://127.0.0.1:4001/metrics"]
+ assert "Serving Prometheus metrics on 127.0.0.1:4001/metrics (pid 4242)" in result.output
+ mock_uvicorn_run.assert_called_once()
+
+ mock_popen.reset_mock()
+ mock_uvicorn_run.reset_mock()
+ mock_popen.return_value = MagicMock(pid=4243, **{"poll.return_value": 1})
+ result = runner.invoke(
+ run_server,
+ ["--local", "--port", "4000", "--prometheus_metrics_port", "4001"],
+ )
+ assert result.exit_code == 1, f"exit_code={result.exit_code}, output={result.output}"
+ assert "Prometheus metrics server exited with code 1 before serving 0.0.0.0:4001" in result.output
+ mock_uvicorn_run.assert_not_called()
+
+ mock_popen.reset_mock()
+ mock_uvicorn_run.reset_mock()
+ result = runner.invoke(run_server, ["--local"])
+ assert (
+ result.exit_code == 0
+ ), f"exit_code={result.exit_code}, output={result.output}"
+ mock_popen.assert_not_called()
+ mock_uvicorn_run.assert_called_once()
+
+ mock_uvicorn_run.reset_mock()
+ result = runner.invoke(
+ run_server,
+ ["--local", "--port", "4000", "--prometheus_metrics_port", "4000"],
+ )
+ assert result.exit_code == 2
+ assert "--prometheus_metrics_port must differ from --port" in result.output
+ mock_popen.assert_not_called()
+ mock_uvicorn_run.assert_not_called()
+
+ result = runner.invoke(
+ run_server, ["--local", "--prometheus_metrics_port", "0"]
+ )
+ assert result.exit_code == 2
+ assert "Invalid value for '--prometheus_metrics_port'" in result.output
+ mock_popen.assert_not_called()
+
@pytest.mark.parametrize(
"timeout_config,expected_timeout",
[
diff --git a/type-discipline-budget.json b/type-discipline-budget.json
index 225134b4e2b..e35e470c979 100644
--- a/type-discipline-budget.json
+++ b/type-discipline-budget.json
@@ -3,7 +3,7 @@
"limit": 22180
},
"LIT002": {
- "limit": 26745
+ "limit": 26729
},
"LIT003": {
"limit": 261
@@ -27,7 +27,7 @@
"limit": 0
},
"LIT010": {
- "limit": 16462
+ "limit": 16430
},
"LIT011": {
"limit": 5506
From 9832d6e4a6e3cc832e4425f759243f97926e6d46 Mon Sep 17 00:00:00 2001
From: Yassin Kortam
Date: Sat, 5 Sep 2026 13:51:25 -0700
Subject: [PATCH 17/35] fix(mcp): scan and mask MCP tool call arguments in
unified guardrails (#35142)
* fix(mcp): scan and mask MCP tool call arguments in unified guardrails
A guardrail configured with mode pre_mcp_call was handed only a synthetic
tool definition (name plus an empty parameters schema), so it never saw the
argument values it was configured to inspect, and any rewrite it returned was
discarded. Detection could not fire and masking could not take effect, while
the applied-guardrails metadata still reported the guardrail as having run.
Pass every string leaf of the tool call arguments as texts, and fold the
guardrail's rewritten leaves back into modified_arguments, which is the channel
the MCP call path reads to decide what to send upstream. The leaf walk reuses
the json_string_leaves / with_json_string_leaves helpers the tool result path
already uses, so both directions share one bounded traversal.
Two guardrails running concurrently under run_in_parallel scan the same payload
snapshot, so each returns a full replacement derived from the original leaf.
Rewrites of the same leaf to different values are rejected rather than silently
losing one redaction; a leaf that already holds this guardrail's own replacement
is convergent and still masks, which is what the bundled content filter does
when it rewrites the arguments itself as well as through texts.
* fix(mcp): annotate guardrail argument rewrites
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(tests): isolate MCP guardrail callback state
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* chore: ratchet LIT010 budget after merge
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(tests): remove duplicate Bedrock hook parameter
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(mcp): fail closed when guardrail rewrites cannot be mapped to MCP arguments
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(tests): patch the guardrail translation mappings cache where staging now keeps it
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---
.../guardrail_translation/handler.py | 137 ++++--
.../test_mcp_guardrail_handler.py | 429 +++++++++++++++++-
type-discipline-budget.json | 2 +-
3 files changed, 530 insertions(+), 38 deletions(-)
diff --git a/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py b/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py
index 4918229c2b8..c0235077ecd 100644
--- a/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py
+++ b/litellm/proxy/_experimental/mcp_server/guardrail_translation/handler.py
@@ -1,16 +1,19 @@
"""
MCP Guardrail Handler for Unified Guardrails.
-Converts an MCP call_tool (name + arguments) into a single OpenAI-compatible
-tool_call and passes it to apply_guardrail. Works with the synthetic payload
-from ProxyLogging._convert_mcp_to_llm_format.
+Converts an MCP call_tool (name + arguments) into the OpenAI-compatible shape
+apply_guardrail expects: the tool as a single-entry ``tools`` definition, and
+every string leaf of the call arguments as ``texts`` so text guardrails can
+detect and mask sensitive values in the payload. Works with the synthetic
+request from ProxyLogging._convert_mcp_to_llm_format.
Note: For MCP tool definitions (schema) -> OpenAI tools=[], see
litellm.experimental_mcp_client.tools.transform_mcp_tool_to_openai_tool
when you have a full MCP Tool from list_tools. Here we only have the call
-payload (name + arguments) so we just build the tool_call.
+payload (name + arguments) so we just build the tool definition.
"""
+from collections.abc import Mapping, Sequence
from typing import TYPE_CHECKING, Any, Final
from fastapi import HTTPException
@@ -20,6 +23,8 @@ from litellm._logging import verbose_proxy_logger
from litellm.experimental_mcp_client.tools import transform_mcp_tool_to_openai_tool
from litellm.llms.base_llm.guardrail_translation.base_translation import BaseTranslation
from litellm.proxy._experimental.mcp_server.utils import (
+ MAX_STRUCTURED_CONTENT_SCAN_DEPTH,
+ JSONLeafPath,
json_string_leaves,
json_unrewritable_labels,
mcp_content_item_text,
@@ -42,6 +47,72 @@ if TYPE_CHECKING:
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
+def _blocked(reason: str) -> HTTPException:
+ return HTTPException(status_code=400, detail={"error": f"Content blocked: {reason}"})
+
+
+def _too_deeply_nested() -> HTTPException:
+ return _blocked(
+ f"MCP tool call arguments exceed the maximum nesting depth of {MAX_STRUCTURED_CONTENT_SCAN_DEPTH} "
+ "and cannot be scanned by the configured guardrail"
+ )
+
+
+def _argument_replacements(
+ argument_leaves: tuple[tuple[JSONLeafPath, str], ...],
+ masked_texts: Sequence[str] | None,
+) -> Mapping[JSONLeafPath, str]:
+ """Positionally pair the guardrail's returned texts with the leaves they came from.
+
+ Only leaves the guardrail actually rewrote are returned, so a guardrail that
+ detects nothing leaves the outbound tool call byte-identical. A guardrail that
+ returns the wrong number of texts fails closed, because a positional write-back
+ would scramble the arguments rather than mask them.
+ """
+ if masked_texts is not None and len(masked_texts) != len(argument_leaves):
+ raise _blocked(
+ f"guardrail returned {len(masked_texts)} texts for {len(argument_leaves)} MCP tool call argument strings, "
+ "so the redaction cannot be mapped back to the arguments"
+ )
+ return {path: masked for (path, original), masked in zip(argument_leaves, masked_texts or ()) if masked != original}
+
+
+def _conflicting_rewrite_paths(
+ scanned_leaves: tuple[tuple[JSONLeafPath, str], ...],
+ current_leaves: tuple[tuple[JSONLeafPath, str], ...],
+ replacements: Mapping[JSONLeafPath, str],
+) -> tuple[JSONLeafPath, ...]:
+ """Paths another guardrail already rewrote differently from what this one wants.
+
+ Guardrails opted into ``run_in_parallel`` all scan the same payload snapshot, so
+ each one returns a full replacement string derived from the *original* leaf. Two
+ of them rewriting one leaf to different values cannot be merged: writing either
+ result discards the other guardrail's redaction. A leaf still holding the text
+ this guardrail was handed, or already holding this guardrail's own replacement,
+ is safe to write; the latter is how a guardrail that masks the arguments itself
+ as well as through ``texts`` gets there first. Anything else fails closed,
+ including a payload reshaped so the leaves no longer line up, because the
+ write-back is positional and would land a redaction on the wrong value.
+ """
+ if tuple(path for path, _ in scanned_leaves) != tuple(path for path, _ in current_leaves):
+ return tuple(replacements)
+ return tuple(
+ path
+ for (path, scanned), (_, current) in zip(scanned_leaves, current_leaves)
+ if path in replacements and current not in (scanned, replacements[path])
+ )
+
+
+def _conflicting_rewrite(paths: tuple[JSONLeafPath, ...]) -> HTTPException:
+ return _blocked(
+ "two guardrails running concurrently rewrote the same MCP tool call "
+ f"argument{'s' if len(paths) > 1 else ''} "
+ f"({', '.join('.'.join(str(part) for part in path) for path in paths)}); "
+ "their redactions cannot be merged. Remove run_in_parallel from one of them so they "
+ "run in sequence."
+ )
+
+
class MCPGuardrailTranslationHandler(BaseTranslation):
"""Guardrail translation handler for MCP tool calls (passes a single tool_call to guardrail)."""
@@ -52,10 +123,8 @@ class MCPGuardrailTranslationHandler(BaseTranslation):
litellm_logging_obj: "LiteLLMLoggingObj | None" = None,
) -> dict[str, Any]:
mcp_tool_name: Final = data.get("mcp_tool_name") or data.get("name")
- mcp_arguments = data.get("mcp_arguments") or data.get("arguments")
+ mcp_arguments: Final[object] = data.get("mcp_arguments") or data.get("arguments")
mcp_tool_description: Final = data.get("mcp_tool_description") or data.get("description")
- if mcp_arguments is None or not isinstance(mcp_arguments, dict):
- mcp_arguments = {}
if not mcp_tool_name:
verbose_proxy_logger.debug("MCP Guardrail: mcp_tool_name missing")
@@ -84,16 +153,37 @@ class MCPGuardrailTranslationHandler(BaseTranslation):
strict=fn.get("strict", False) or False, # Default to False if None
),
}
+ argument_leaves: Final = json_string_leaves(mcp_arguments)
+ if argument_leaves is None:
+ raise _too_deeply_nested()
inputs: Final[GenericGuardrailAPIInputs] = GenericGuardrailAPIInputs(
tools=[tool_def],
+ texts=[text for _, text in argument_leaves],
)
- await guardrail_to_apply.apply_guardrail(
+ guarded: Final = await guardrail_to_apply.apply_guardrail(
inputs=inputs,
request_data=data,
input_type="request",
logging_obj=litellm_logging_obj,
)
+ replacements: Final = _argument_replacements(
+ argument_leaves=argument_leaves,
+ masked_texts=guarded.get("texts") if guarded else None,
+ )
+ if not replacements:
+ return data
+
+ current_arguments: Final[object] = data.get("mcp_arguments") or data.get("arguments")
+ current_leaves: Final = json_string_leaves(current_arguments)
+ if current_leaves is None:
+ raise _too_deeply_nested()
+ conflicting: Final = _conflicting_rewrite_paths(argument_leaves, current_leaves, replacements)
+ if conflicting:
+ raise _conflicting_rewrite(conflicting)
+ masked_arguments: Final = with_json_string_leaves(current_arguments, replacements)
+ data["mcp_arguments"] = masked_arguments # rebind-ok: preserve the mask for the outbound MCP call
+ data["modified_arguments"] = masked_arguments # rebind-ok: expose the applied mask to the caller
return data
async def process_output_response(
@@ -131,14 +221,8 @@ class MCPGuardrailTranslationHandler(BaseTranslation):
structured_leaves: Final = json_string_leaves(structured) if structured is not None else ()
structured_labels: Final = json_unrewritable_labels(structured) if structured is not None else ()
if structured_leaves is None or structured_labels is None:
- raise HTTPException(
- status_code=400,
- detail={
- "error": (
- "Content blocked: MCP tool result structuredContent is nested too deeply to be scanned "
- "by the configured guardrail"
- )
- },
+ raise _blocked(
+ "MCP tool result structuredContent is nested too deeply to be scanned by the configured guardrail"
)
if not text_blocks and not structured_leaves and not structured_labels:
@@ -158,12 +242,10 @@ class MCPGuardrailTranslationHandler(BaseTranslation):
if masked_texts is None:
return response
if len(masked_texts) != len(originals):
- verbose_proxy_logger.warning(
- "MCP Guardrail: guardrail returned %d texts for %d tool result texts; leaving the result unmasked",
- len(masked_texts),
- len(originals),
+ raise _blocked(
+ f"guardrail returned {len(masked_texts)} texts for {len(originals)} MCP tool result texts, "
+ "so the redaction cannot be mapped back to the result"
)
- return response
split: Final = len(text_blocks)
if content is not None:
@@ -173,15 +255,10 @@ class MCPGuardrailTranslationHandler(BaseTranslation):
label_start: Final = split + len(structured_leaves)
if any(masked != original for original, masked in zip(structured_labels, masked_texts[label_start:])):
- raise HTTPException(
- status_code=400,
- detail={
- "error": (
- "Content blocked: MCP tool result matched a masking rule on a non-rewritable field "
- "(a structuredContent key or numeric value), which cannot be redacted without changing "
- "the payload contract"
- )
- },
+ raise _blocked(
+ "MCP tool result matched a masking rule on a non-rewritable field "
+ "(a structuredContent key or numeric value), which cannot be redacted without changing "
+ "the payload contract"
)
structured_replacements: Final = {
diff --git a/tests/test_litellm/proxy/_experimental/mcp_server/guardrail_translation/test_mcp_guardrail_handler.py b/tests/test_litellm/proxy/_experimental/mcp_server/guardrail_translation/test_mcp_guardrail_handler.py
index 2e286a237c4..28959054195 100644
--- a/tests/test_litellm/proxy/_experimental/mcp_server/guardrail_translation/test_mcp_guardrail_handler.py
+++ b/tests/test_litellm/proxy/_experimental/mcp_server/guardrail_translation/test_mcp_guardrail_handler.py
@@ -1,13 +1,22 @@
"""Tests for the MCP guardrail translation handler."""
+import asyncio
+
import pytest
+from fastapi import HTTPException
from mcp.types import CallToolResult, ImageContent, TextContent
+import litellm
+import litellm.llms as litellm_llms
+from litellm.caching.caching import DualCache
from litellm.exceptions import BlockedPiiEntityError
from litellm.integrations.custom_guardrail import CustomGuardrail
from litellm.proxy._experimental.mcp_server.guardrail_translation.handler import (
MCPGuardrailTranslationHandler,
)
+from litellm.proxy._experimental.mcp_server.utils import MAX_STRUCTURED_CONTENT_SCAN_DEPTH
+from litellm.proxy._types import UserAPIKeyAuth
+from litellm.proxy.utils import ProxyLogging
from litellm.types.utils import GenericGuardrailAPIInputs
@@ -24,12 +33,11 @@ class MockGuardrail(CustomGuardrail):
self.call_count += 1
self.last_inputs = inputs
self.last_request_data = request_data
- return None # Guardrail doesn't modify for MCP tools
@pytest.mark.asyncio
async def test_process_input_messages_updates_content():
- """Handler should pass tool definition to guardrail when mcp_tool_name is present."""
+ """Handler should pass the tool definition and the argument strings to the guardrail."""
handler = MCPGuardrailTranslationHandler()
guardrail = MockGuardrail()
@@ -45,7 +53,7 @@ async def test_process_input_messages_updates_content():
assert result == data
# Guardrail was called
assert guardrail.call_count == 1
- # Guardrail received tools (not texts) with tool definition
+ # Guardrail received tools with the tool definition
assert guardrail.last_inputs is not None
tools = guardrail.last_inputs.get("tools", [])
assert len(tools) == 1
@@ -85,6 +93,412 @@ async def test_process_input_messages_handles_minimal_data():
assert tools[0]["function"]["name"] == "simple_tool"
+class ArgumentMaskingGuardrail(CustomGuardrail):
+ """Unified guardrail that rewrites every text it is handed, like presidio does."""
+
+ def __init__(
+ self,
+ secret: str = "jane.doe@example.com",
+ replacement: str = "",
+ texts_override: list[str] | None = None,
+ **kwargs,
+ ):
+ kwargs.setdefault("guardrail_name", "argument-masking-mcp-guardrail")
+ super().__init__(**kwargs)
+ self.secret = secret
+ self.replacement = replacement
+ self.texts_override = texts_override
+ self.seen_texts: list[str] | None = None
+
+ def _mask(self, text: str) -> str:
+ return text.replace(self.secret, self.replacement)
+
+ async def apply_guardrail(self, inputs, request_data, input_type, **kwargs):
+ self.seen_texts = list(inputs.get("texts") or [])
+ if self.texts_override is not None:
+ inputs["texts"] = self.texts_override
+ else:
+ inputs["texts"] = [self._mask(text) for text in self.seen_texts]
+ return inputs
+
+
+@pytest.fixture
+def restore_callbacks(monkeypatch):
+ """Restore the process-wide state driving pre_call_hook through unified_guardrail.
+
+ litellm.llms memoizes the guardrail translation mappings in a module global, and
+ ProxyLogging caches callback capabilities keyed on id()s of litellm.callbacks,
+ so leaving either populated leaks into unrelated tests in the same worker.
+ """
+ monkeypatch.setattr(litellm, "callbacks", litellm.callbacks)
+ monkeypatch.setattr(
+ litellm_llms,
+ "endpoint_guardrail_translation_mappings",
+ litellm_llms.endpoint_guardrail_translation_mappings,
+ )
+ yield
+ ProxyLogging._callback_capabilities_cache.clear()
+
+
+@pytest.mark.asyncio
+async def test_argument_strings_are_handed_to_the_guardrail():
+ """A guardrail must see the argument values, not just the tool definition.
+
+ Without this the guardrail is handed a name and an empty schema, so no
+ sensitive-data detection can ever fire on an MCP tool call.
+ """
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = MockGuardrail()
+
+ data = {
+ "mcp_tool_name": "search",
+ "mcp_arguments": {"query": "contact jane.doe@example.com about the invoice"},
+ }
+
+ await handler.process_input_messages(data, guardrail)
+
+ assert guardrail.last_inputs is not None
+ assert guardrail.last_inputs.get("texts") == ["contact jane.doe@example.com about the invoice"]
+
+
+@pytest.mark.asyncio
+async def test_masked_arguments_are_written_back_for_the_call_path():
+ """A mask only takes effect once it lands in modified_arguments."""
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = ArgumentMaskingGuardrail()
+
+ data = {
+ "mcp_tool_name": "search",
+ "mcp_arguments": {"query": "contact jane.doe@example.com about the invoice"},
+ }
+
+ result = await handler.process_input_messages(data, guardrail)
+
+ masked = {"query": "contact about the invoice"}
+ assert result["modified_arguments"] == masked
+ assert result["mcp_arguments"] == masked
+
+
+@pytest.mark.asyncio
+async def test_nested_arguments_keep_their_shape_when_masked():
+ """Masking rewrites string leaves in place and preserves non-string values."""
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = ArgumentMaskingGuardrail()
+
+ arguments = {
+ "recipients": ["jane.doe@example.com", "ops@example.net"],
+ "envelope": {"reply_to": "jane.doe@example.com", "retries": 3, "urgent": True, "cc": None},
+ "count": 2,
+ }
+ data = {"mcp_tool_name": "send_email", "mcp_arguments": arguments}
+
+ result = await handler.process_input_messages(data, guardrail)
+
+ assert guardrail.seen_texts == [
+ "jane.doe@example.com",
+ "ops@example.net",
+ "jane.doe@example.com",
+ ]
+ assert result["modified_arguments"] == {
+ "recipients": ["", "ops@example.net"],
+ "envelope": {"reply_to": "", "retries": 3, "urgent": True, "cc": None},
+ "count": 2,
+ }
+
+
+@pytest.mark.asyncio
+async def test_clean_arguments_are_not_overridden():
+ """A guardrail that changes nothing must not set modified_arguments."""
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = ArgumentMaskingGuardrail()
+
+ data = {"mcp_tool_name": "search", "mcp_arguments": {"query": "quarterly revenue"}}
+
+ result = await handler.process_input_messages(data, guardrail)
+
+ assert "modified_arguments" not in result
+ assert result["mcp_arguments"] == {"query": "quarterly revenue"}
+
+
+@pytest.mark.asyncio
+async def test_guardrail_returning_wrong_text_count_blocks_the_call():
+ """Write-back is positional, so a length mismatch must block the call."""
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = ArgumentMaskingGuardrail(texts_override=["only", "two", "texts"])
+
+ arguments = {"query": "contact jane.doe@example.com about the invoice"}
+ data = {"mcp_tool_name": "search", "mcp_arguments": arguments}
+
+ with pytest.raises(HTTPException) as exc_info:
+ await handler.process_input_messages(data, guardrail)
+
+ assert exc_info.value.status_code == 400
+ assert "modified_arguments" not in data
+
+
+@pytest.mark.asyncio
+async def test_deeply_nested_arguments_are_blocked_rather_than_skipped():
+ """Arguments too deep to walk must block instead of passing unscanned."""
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = ArgumentMaskingGuardrail()
+
+ nested: dict = {"leaf": "jane.doe@example.com"}
+ for _ in range(MAX_STRUCTURED_CONTENT_SCAN_DEPTH + 1):
+ nested = {"next": nested}
+
+ data = {"mcp_tool_name": "search", "mcp_arguments": nested}
+
+ with pytest.raises(HTTPException) as exc_info:
+ await handler.process_input_messages(data, guardrail)
+
+ assert exc_info.value.status_code == 400
+
+
+class SelfWritingMaskingGuardrail(ArgumentMaskingGuardrail):
+ """Masks through ``texts`` and writes the masked arguments itself.
+
+ The shape the bundled content filter guardrail already has: it rewrites
+ ``request_data["mcp_arguments"]`` from inside ``apply_guardrail`` as well as
+ returning masked texts.
+ """
+
+ async def apply_guardrail(self, inputs, request_data, input_type, **kwargs):
+ returned = await super().apply_guardrail(inputs, request_data, input_type, **kwargs)
+ arguments = request_data.get("mcp_arguments") or {}
+ masked = {key: self._mask(value) if isinstance(value, str) else value for key, value in arguments.items()}
+ request_data["mcp_arguments"] = masked
+ request_data["modified_arguments"] = masked
+ return returned
+
+
+@pytest.mark.asyncio
+async def test_guardrail_that_masks_the_arguments_itself_is_not_treated_as_a_conflict():
+ """Converging on the same replacement is not an unmergeable rewrite.
+
+ A guardrail that both returns masked texts and rewrites the arguments in
+ request_data must still mask, not be rejected as if a second guardrail had
+ clobbered the leaf.
+ """
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = SelfWritingMaskingGuardrail()
+
+ data = {
+ "mcp_tool_name": "search",
+ "mcp_arguments": {"query": "contact jane.doe@example.com about the invoice"},
+ }
+
+ result = await handler.process_input_messages(data, guardrail)
+
+ assert result["modified_arguments"] == {"query": "contact about the invoice"}
+
+
+class ReshapingGuardrail(ArgumentMaskingGuardrail):
+ """Masks through ``texts`` while moving the secret to a different path."""
+
+ def __init__(self, reshaped: dict, **kwargs):
+ super().__init__(**kwargs)
+ self.reshaped = reshaped
+
+ async def apply_guardrail(self, inputs, request_data, input_type, **kwargs):
+ returned = await super().apply_guardrail(inputs, request_data, input_type, **kwargs)
+ request_data["mcp_arguments"] = self.reshaped
+ return returned
+
+
+@pytest.mark.asyncio
+async def test_arguments_reshaped_under_the_guardrail_fail_closed():
+ """A payload that no longer lines up leaf for leaf must block, not be written blind.
+
+ Write-back pairs masked texts to leaves positionally, so a tree another guardrail
+ reshaped would take the redaction on the wrong value.
+ """
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = ReshapingGuardrail({"query": "contact jane.doe@example.com", "note": "added"})
+
+ data = {
+ "mcp_tool_name": "search",
+ "mcp_arguments": {"query": "contact jane.doe@example.com about the invoice"},
+ }
+
+ with pytest.raises(HTTPException) as exc_info:
+ await handler.process_input_messages(data, guardrail)
+
+ assert exc_info.value.status_code == 400
+
+
+@pytest.mark.asyncio
+async def test_arguments_shortened_under_the_guardrail_fail_closed():
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = ReshapingGuardrail({"padding": "jane.doe@example.com"})
+
+ data = {
+ "mcp_tool_name": "search",
+ "mcp_arguments": {"padding": "x", "secret": "jane.doe@example.com"},
+ }
+
+ with pytest.raises(HTTPException) as exc_info:
+ await handler.process_input_messages(data, guardrail)
+
+ assert exc_info.value.status_code == 400
+ assert "jane.doe@example.com" not in str(data.get("modified_arguments"))
+
+
+@pytest.mark.asyncio
+async def test_a_renamed_argument_key_blocks_rather_than_dropping_the_mask():
+ """The leak this closes: same text, new path, so the write-back would find nothing.
+
+ Matching purely on position would see an unchanged value and write the mask to a
+ path that no longer exists, shipping the secret while reporting a clean scan.
+ """
+ handler = MCPGuardrailTranslationHandler()
+ guardrail = ReshapingGuardrail({"renamed": "jane.doe@example.com", "other": "kept"})
+
+ data = {
+ "mcp_tool_name": "search",
+ "mcp_arguments": {"query": "jane.doe@example.com", "other": "kept"},
+ }
+
+ with pytest.raises(HTTPException) as exc_info:
+ await handler.process_input_messages(data, guardrail)
+
+ assert exc_info.value.status_code == 400
+ assert "jane.doe@example.com" not in str(data.get("modified_arguments"))
+
+
+@pytest.mark.parametrize("run_in_parallel", [False, True])
+@pytest.mark.asyncio
+async def test_masked_arguments_reach_the_outbound_mcp_call(restore_callbacks, monkeypatch, run_in_parallel):
+ """End to end over the real MCP pre-call path, not just the handler.
+
+ Drives the same sequence mcp_server_manager.call_tool uses:
+ synthetic payload -> pre_call_hook -> arguments sent upstream.
+
+ Covers run_in_parallel both ways: that path shares one payload snapshot and
+ discards whatever a guardrail returns, so the mask has to land on the caller's
+ dict rather than on a copy of it.
+ """
+ guardrail = ArgumentMaskingGuardrail(
+ event_hook="pre_mcp_call",
+ default_on=True,
+ run_in_parallel=run_in_parallel,
+ )
+ monkeypatch.setattr(litellm, "callbacks", [guardrail])
+
+ proxy_logging_obj = ProxyLogging(user_api_key_cache=DualCache())
+ arguments = {"query": "contact jane.doe@example.com about the invoice"}
+ pre_hook_kwargs = {
+ "name": "search",
+ "arguments": arguments,
+ "server_name": "test-server",
+ "user_api_key_auth": UserAPIKeyAuth(api_key="sk-test", user_id="test-user"),
+ }
+
+ request_obj = proxy_logging_obj._create_mcp_request_object_from_kwargs(pre_hook_kwargs)
+ synthetic_data = proxy_logging_obj._convert_mcp_to_llm_format(request_obj, pre_hook_kwargs)
+
+ modified_data = await proxy_logging_obj.pre_call_hook(
+ user_api_key_dict=pre_hook_kwargs["user_api_key_auth"],
+ data=synthetic_data,
+ call_type="call_mcp_tool",
+ )
+ modified_kwargs = proxy_logging_obj._convert_mcp_hook_response_to_kwargs(modified_data, pre_hook_kwargs)
+
+ assert modified_kwargs["arguments"] == {"query": "contact about the invoice"}
+
+
+class SlowSubstitutionGuardrail(CustomGuardrail):
+ """Rewrites one substring, after a delay, so two instances genuinely interleave."""
+
+ def __init__(self, needle: str, replacement: str, delay: float, **kwargs):
+ super().__init__(**kwargs)
+ self.needle = needle
+ self.replacement = replacement
+ self.delay = delay
+
+ async def apply_guardrail(self, inputs, request_data, input_type, **kwargs):
+ await asyncio.sleep(self.delay)
+ inputs["texts"] = [text.replace(self.needle, self.replacement) for text in (inputs.get("texts") or [])]
+ return inputs
+
+
+def _two_interleaving_maskers(run_in_parallel: bool):
+ return [
+ SlowSubstitutionGuardrail(
+ "jane.doe@example.com",
+ "",
+ 0.02,
+ guardrail_name="mask-email",
+ event_hook="pre_mcp_call",
+ default_on=True,
+ run_in_parallel=run_in_parallel,
+ ),
+ SlowSubstitutionGuardrail(
+ "415-555-0132",
+ "",
+ 0.04,
+ guardrail_name="mask-phone",
+ event_hook="pre_mcp_call",
+ default_on=True,
+ run_in_parallel=run_in_parallel,
+ ),
+ ]
+
+
+async def _arguments_sent_upstream(arguments: dict):
+ proxy_logging_obj = ProxyLogging(user_api_key_cache=DualCache())
+ pre_hook_kwargs = {
+ "name": "search",
+ "arguments": arguments,
+ "server_name": "test-server",
+ "user_api_key_auth": UserAPIKeyAuth(api_key="sk-test", user_id="test-user"),
+ }
+ request_obj = proxy_logging_obj._create_mcp_request_object_from_kwargs(pre_hook_kwargs)
+ modified_data = await proxy_logging_obj.pre_call_hook(
+ user_api_key_dict=pre_hook_kwargs["user_api_key_auth"],
+ data=proxy_logging_obj._convert_mcp_to_llm_format(request_obj, pre_hook_kwargs),
+ call_type="call_mcp_tool",
+ )
+ return proxy_logging_obj._convert_mcp_hook_response_to_kwargs(modified_data, pre_hook_kwargs)["arguments"]
+
+
+@pytest.mark.asyncio
+async def test_two_sequential_guardrails_both_masks_survive(restore_callbacks, monkeypatch):
+ """The recommended config: each guardrail sees the previous one's output."""
+ monkeypatch.setattr(litellm, "callbacks", _two_interleaving_maskers(run_in_parallel=False))
+
+ sent = await _arguments_sent_upstream({"note": "mail jane.doe@example.com or call 415-555-0132"})
+
+ assert sent == {"note": "mail or call "}
+
+
+@pytest.mark.asyncio
+async def test_two_parallel_guardrails_on_separate_arguments_both_masks_survive(restore_callbacks, monkeypatch):
+ """Concurrent rewrites of different leaves compose; neither is lost."""
+ monkeypatch.setattr(litellm, "callbacks", _two_interleaving_maskers(run_in_parallel=True))
+
+ sent = await _arguments_sent_upstream({"email": "jane.doe@example.com", "phone": "415-555-0132"})
+
+ assert sent == {"email": "", "phone": ""}
+
+
+@pytest.mark.asyncio
+async def test_two_parallel_guardrails_on_one_argument_block_instead_of_losing_a_mask(restore_callbacks, monkeypatch):
+ """Unmergeable concurrent rewrites must fail closed, not ship one redaction.
+
+ Both guardrails derive a full replacement string from the same snapshot, so
+ writing either result would silently discard the other's redaction and leak
+ the value it was configured to mask.
+ """
+ monkeypatch.setattr(litellm, "callbacks", _two_interleaving_maskers(run_in_parallel=True))
+ original = "mail jane.doe@example.com or call 415-555-0132"
+
+ with pytest.raises(HTTPException) as exc_info:
+ await _arguments_sent_upstream({"note": original})
+
+ assert exc_info.value.status_code == 400
+ assert "note" in str(exc_info.value.detail)
+
+
class MaskingGuardrail(CustomGuardrail):
"""Guardrail that rewrites every scanned text, recording what it saw."""
@@ -190,8 +604,8 @@ async def test_process_output_response_handles_result_without_content():
@pytest.mark.asyncio
-async def test_process_output_response_leaves_result_unmasked_on_text_count_mismatch():
- """A guardrail returning the wrong number of texts must not shuffle content."""
+async def test_process_output_response_blocks_on_text_count_mismatch():
+ """A guardrail returning the wrong number of texts must block the result."""
handler = MCPGuardrailTranslationHandler()
guardrail = MaskingGuardrail(masked_texts=[""])
result = CallToolResult(
@@ -202,9 +616,10 @@ async def test_process_output_response_leaves_result_unmasked_on_text_count_mism
isError=False,
)
- returned = await handler.process_output_response(response=result, guardrail_to_apply=guardrail)
+ with pytest.raises(HTTPException) as exc_info:
+ await handler.process_output_response(response=result, guardrail_to_apply=guardrail)
- assert [item.text for item in returned.content] == ["jane@example.com", "415-555-0132"]
+ assert exc_info.value.status_code == 400
class SubstitutingGuardrail(CustomGuardrail):
diff --git a/type-discipline-budget.json b/type-discipline-budget.json
index e35e470c979..e7186dfe186 100644
--- a/type-discipline-budget.json
+++ b/type-discipline-budget.json
@@ -27,7 +27,7 @@
"limit": 0
},
"LIT010": {
- "limit": 16430
+ "limit": 16426
},
"LIT011": {
"limit": 5506
From a46a076b2abd46b88f65d6d21d7afd9c052bb826 Mon Sep 17 00:00:00 2001
From: "devin-ai-integration[bot]"
<158243242+devin-ai-integration[bot]@users.noreply.github.com>
Date: Sat, 5 Sep 2026 14:22:26 -0700
Subject: [PATCH 18/35] fix(proxy): reject ambiguous name or alias keys in
mcp_tool_permissions on write (#39947)
Co-authored-by: yassin
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---
.../organization_endpoints.py | 6 +
.../object_permission_utils.py | 71 ++++++++++-
.../test_internal_user_endpoints.py | 2 +
.../test_key_management_endpoints.py | 1 +
.../test_organization_endpoints.py | 31 +++++
.../test_team_endpoints.py | 1 +
.../test_object_permission_utils.py | 119 ++++++++++++++++++
7 files changed, 229 insertions(+), 2 deletions(-)
diff --git a/litellm/proxy/management_endpoints/organization_endpoints.py b/litellm/proxy/management_endpoints/organization_endpoints.py
index 0af9f816318..1e711b036d2 100644
--- a/litellm/proxy/management_endpoints/organization_endpoints.py
+++ b/litellm/proxy/management_endpoints/organization_endpoints.py
@@ -46,6 +46,7 @@ from litellm.proxy.management_endpoints.common_utils import (
from litellm.proxy.management_helpers.object_permission_utils import (
handle_update_object_permission_common,
prepare_object_permission_upsert,
+ reject_ambiguous_mcp_tool_permission_keys,
)
from litellm.proxy.management_helpers.utils import (
get_new_internal_user_defaults,
@@ -606,6 +607,11 @@ async def _set_object_permission(
return None
if data.object_permission is not None:
+ await reject_ambiguous_mcp_tool_permission_keys(
+ new_mcp_tool_permissions=data.object_permission.mcp_tool_permissions,
+ existing_mcp_tool_permissions=None,
+ prisma_client=prisma_client,
+ )
created_object_permission: Final = await _table(ObjectPermissionRepository(prisma_client)).create(
data=data.object_permission.model_dump(exclude_none=True),
)
diff --git a/litellm/proxy/management_helpers/object_permission_utils.py b/litellm/proxy/management_helpers/object_permission_utils.py
index a2fbf80422c..daab38d3662 100644
--- a/litellm/proxy/management_helpers/object_permission_utils.py
+++ b/litellm/proxy/management_helpers/object_permission_utils.py
@@ -5,10 +5,13 @@ organizations, teams, and keys.
import json
from collections.abc import Mapping, Sequence
+from collections.abc import Set as AbstractSet
from dataclasses import dataclass
+from types import MappingProxyType
from typing import TYPE_CHECKING, Any, Final, Optional
from fastapi import HTTPException, status
+from pydantic import TypeAdapter
from litellm._logging import verbose_proxy_logger
from litellm._uuid import uuid
@@ -103,6 +106,11 @@ async def prepare_object_permission_upsert(
if existing_object_permission is not None
else {}
)
+ await reject_ambiguous_mcp_tool_permission_keys(
+ new_mcp_tool_permissions=new_object_permission.get("mcp_tool_permissions"),
+ existing_mcp_tool_permissions=existing_fields.get("mcp_tool_permissions"),
+ prisma_client=prisma_client,
+ )
merged: Final[dict[str, object]] = {
**existing_fields,
**new_object_permission,
@@ -194,6 +202,12 @@ async def _set_object_permission(
k: v for k, v in permission_data.items() if v is not None and k != "object_permission_id"
}
+ await reject_ambiguous_mcp_tool_permission_keys(
+ new_mcp_tool_permissions=clean_data.get("mcp_tool_permissions"),
+ existing_mcp_tool_permissions=None,
+ prisma_client=prisma_client,
+ )
+
# Serialize mcp_tool_permissions to JSON string for GraphQL compatibility
if "mcp_tool_permissions" in clean_data:
clean_data["mcp_tool_permissions"] = safe_dumps(clean_data["mcp_tool_permissions"])
@@ -226,7 +240,7 @@ def _mcp_server_identifier_matches(server: Any, identifier: str) -> bool:
async def _get_db_mcp_servers_by_identifiers(
- identifiers: set[str],
+ identifiers: AbstractSet[str],
prisma_client: PrismaClient | None,
) -> "Sequence[prisma_models.LiteLLM_MCPServerTable]":
if prisma_client is None or not identifiers:
@@ -245,7 +259,7 @@ async def _get_db_mcp_servers_by_identifiers(
async def _resolve_mcp_server_identifiers_to_ids(
- identifiers: set[str],
+ identifiers: AbstractSet[str],
prisma_client: PrismaClient | None,
) -> dict[str, set[str]]:
"""
@@ -286,6 +300,59 @@ async def _resolve_mcp_server_identifiers_to_ids(
return resolved
+_MCP_TOOL_PERMISSIONS_ADAPTER: Final = TypeAdapter(dict[str, list[str] | None])
+
+
+def _mcp_tool_permission_entries(raw: object) -> Mapping[str, frozenset[str]]:
+ parsed: Final[Mapping[str, Sequence[str] | None]] = (
+ _MCP_TOOL_PERMISSIONS_ADAPTER.validate_json(raw)
+ if isinstance(raw, str)
+ else _MCP_TOOL_PERMISSIONS_ADAPTER.validate_python(raw)
+ if isinstance(raw, Mapping)
+ else MappingProxyType({})
+ )
+ return MappingProxyType({identifier: frozenset(tools or ()) for identifier, tools in parsed.items()})
+
+
+async def reject_ambiguous_mcp_tool_permission_keys(
+ new_mcp_tool_permissions: object,
+ existing_mcp_tool_permissions: object,
+ prisma_client: PrismaClient | None,
+) -> None:
+ """
+ A name or alias shared by several MCP servers cannot key ``mcp_tool_permissions``:
+ the read path unions the entry into every match, so no edit can narrow one of
+ those servers without also changing the other. An exact server_id is never
+ ambiguous, even when another server uses that string as its alias. Entries the
+ row already stores with the same tool list are left alone, so unrelated edits
+ to such an entity still succeed.
+
+ Raises HTTPException(400) naming the colliding servers.
+ """
+ requested: Final = _mcp_tool_permission_entries(new_mcp_tool_permissions)
+ stored: Final = _mcp_tool_permission_entries(existing_mcp_tool_permissions)
+ resolved: Final = await _resolve_mcp_server_identifiers_to_ids(
+ identifiers=frozenset(identifier for identifier, tools in requested.items() if stored.get(identifier) != tools),
+ prisma_client=prisma_client,
+ )
+ collisions: Final = "; ".join(
+ f"'{identifier}' matches MCP servers {sorted(server_ids)}"
+ for identifier, server_ids in sorted(resolved.items())
+ if identifier not in server_ids and len(server_ids) > 1
+ )
+ if not collisions:
+ return
+ raise HTTPException(
+ status_code=status.HTTP_400_BAD_REQUEST,
+ detail={ # mutable-ok: HTTPException.detail has no immutable form; same shape as the sibling errors here
+ "error": (
+ f"Ambiguous mcp_tool_permissions key: {collisions}. "
+ "Key tool permissions by server_id when servers share a name or alias."
+ )
+ },
+ )
+
+
def _drop_stale_object_permission_mcp_servers(
object_permission: ObjectPermissionDict,
identifier_to_server_ids: dict[str, set[str]],
diff --git a/tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py
index 0d3ea5863a2..d1d669cae38 100644
--- a/tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py
+++ b/tests/test_litellm/proxy/management_endpoints/test_internal_user_endpoints.py
@@ -3917,6 +3917,7 @@ def _object_permission_mocks(mocker, existing_object_permission_id=None):
mock_prisma_client.db.litellm_objectpermissiontable.upsert = mocker.AsyncMock(
return_value=SimpleNamespace(object_permission_id="perm-new")
)
+ mock_prisma_client.db.litellm_mcpservertable.find_many = mocker.AsyncMock(return_value=[])
mock_prisma_client.update_data = mocker.AsyncMock(
return_value={"user_id": "target-user"}
)
@@ -4146,6 +4147,7 @@ async def test_new_user_persists_the_requested_mcp_entitlement(mocker):
mock_prisma_client.db.litellm_objectpermissiontable.create = mocker.AsyncMock(
return_value=SimpleNamespace(object_permission_id="perm-created")
)
+ mock_prisma_client.db.litellm_mcpservertable.find_many = mocker.AsyncMock(return_value=[])
mock_prisma_client.db.litellm_usertable.find_first = mocker.AsyncMock(
return_value=None
)
diff --git a/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py
index 47571497f74..8766b1a1868 100644
--- a/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py
+++ b/tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py
@@ -963,6 +963,7 @@ async def test_key_generation_with_mcp_tool_permissions(monkeypatch):
mock_prisma_client.db = MagicMock()
mock_prisma_client.db.litellm_objectpermissiontable = MagicMock()
mock_prisma_client.db.litellm_objectpermissiontable.create = mock_create
+ mock_prisma_client.db.litellm_mcpservertable.find_many = AsyncMock(return_value=[])
async def _insert_data_side_effect(*args, **kwargs):
table_name = kwargs.get("table_name")
diff --git a/tests/test_litellm/proxy/management_endpoints/test_organization_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_organization_endpoints.py
index da68492e3d7..4d13e054e46 100644
--- a/tests/test_litellm/proxy/management_endpoints/test_organization_endpoints.py
+++ b/tests/test_litellm/proxy/management_endpoints/test_organization_endpoints.py
@@ -1183,6 +1183,37 @@ async def test_find_member_if_email_missing_row_raises_documented_400():
}
+@pytest.mark.asyncio
+async def test_new_organization_rejects_shared_alias_tool_permission_key():
+ """/organization/new creates its permission row through its own helper, so the
+ ambiguous mcp_tool_permissions key check (LIT-4982) has to run there too."""
+ from litellm.proxy._types import LiteLLM_ObjectPermissionBase, NewOrganizationRequest
+ from litellm.proxy.management_endpoints.organization_endpoints import (
+ _set_object_permission,
+ )
+
+ prisma_client = MagicMock()
+ prisma_client.db.litellm_mcpservertable.find_many = AsyncMock(
+ return_value=[
+ MagicMock(server_id="wiki-a-id", alias="wiki", server_name="wiki_a"),
+ MagicMock(server_id="wiki-b-id", alias="wiki", server_name="wiki_b"),
+ ]
+ )
+ prisma_client.db.litellm_objectpermissiontable.create = AsyncMock()
+ data = NewOrganizationRequest(
+ organization_alias="org",
+ object_permission=LiteLLM_ObjectPermissionBase(mcp_tool_permissions={"wiki": ["ask_question"]}),
+ )
+
+ with pytest.raises(HTTPException) as exc_info:
+ await _set_object_permission(data=data, prisma_client=prisma_client)
+
+ assert exc_info.value.status_code == 400
+ assert "wiki-a-id" in str(exc_info.value.detail)
+ assert "wiki-b-id" in str(exc_info.value.detail)
+ prisma_client.db.litellm_objectpermissiontable.create.assert_not_called()
+
+
def test_v2_update_organization_is_in_openapi_schema():
"""PATCH /v2/organization/{organization_id} is documented in the generated OpenAPI spec."""
from fastapi import FastAPI
diff --git a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py
index 46678c8ff6a..051e6bed4fd 100644
--- a/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py
+++ b/tests/test_litellm/proxy/management_endpoints/test_team_endpoints.py
@@ -651,6 +651,7 @@ async def test_new_team_with_mcp_tool_permissions(mock_db_client, mock_admin_aut
mock_db_client.db.litellm_objectpermissiontable = MagicMock()
mock_db_client.db.litellm_objectpermissiontable.create = mock_obj_perm_create
+ mock_db_client.db.litellm_mcpservertable.find_many = AsyncMock(return_value=[])
# Mock model table
mock_db_client.db.litellm_modeltable = MagicMock()
diff --git a/tests/test_litellm/proxy/management_helpers/test_object_permission_utils.py b/tests/test_litellm/proxy/management_helpers/test_object_permission_utils.py
index f2b6b799271..d7ebb1f60bf 100644
--- a/tests/test_litellm/proxy/management_helpers/test_object_permission_utils.py
+++ b/tests/test_litellm/proxy/management_helpers/test_object_permission_utils.py
@@ -17,6 +17,7 @@ from litellm.proxy.management_helpers.object_permission_utils import (
_resolve_team_allowed_mcp_servers,
_set_object_permission,
enforce_all_proxy_mcp_servers_grant_is_admin_only,
+ prepare_object_permission_upsert,
validate_key_mcp_servers_against_team,
validate_key_search_tools_against_team,
validate_key_vector_stores_against_team,
@@ -41,6 +42,7 @@ async def test_set_object_permission():
mock_prisma_client.db.litellm_objectpermissiontable.create = AsyncMock(
return_value=mock_created_permission
)
+ mock_prisma_client.db.litellm_mcpservertable.find_many = AsyncMock(return_value=[])
# Test data with object_permission
data_json = {
@@ -1349,6 +1351,123 @@ async def test_validate_key_update_sentinels_do_not_grandfather(monkeypatch):
assert exc_info.value.status_code == 403
+# ---- Tests for rejecting ambiguous mcp_tool_permissions keys on write (LIT-4982) ----
+
+
+_SHARED_ALIAS_DB_SERVERS = (
+ _make_mock_mcp_server("wiki-a-id", alias="wiki", server_name="wiki_a"),
+ _make_mock_mcp_server("wiki-b-id", alias="wiki", server_name="wiki_b"),
+ _make_mock_mcp_server("gh-a-id", alias="gh_a", server_name="github"),
+ _make_mock_mcp_server("gh-b-id", alias="gh_b", server_name="github"),
+ _make_mock_mcp_server("solo-id", alias="solo", server_name="Solo Server"),
+ _make_mock_mcp_server("shadow-id", alias="solo-id", server_name="shadow"),
+)
+
+
+def _make_ambiguity_prisma(existing_tool_permissions=None):
+ """Mock prisma client whose MCP server table holds _SHARED_ALIAS_DB_SERVERS and whose
+ object permission row (if any) stores the given mcp_tool_permissions JSON string."""
+ mock_prisma = MagicMock()
+ mock_prisma.db.litellm_mcpservertable.find_many = AsyncMock(return_value=list(_SHARED_ALIAS_DB_SERVERS))
+ mock_prisma.db.litellm_objectpermissiontable.create = AsyncMock(
+ return_value=MagicMock(object_permission_id="perm-id")
+ )
+ existing_row = None
+ if existing_tool_permissions is not None:
+ existing_row = MagicMock()
+ existing_row.model_dump.return_value = {
+ "object_permission_id": "perm-id",
+ "mcp_tool_permissions": json.dumps(existing_tool_permissions),
+ }
+ mock_prisma.db.litellm_objectpermissiontable.find_unique = AsyncMock(return_value=existing_row)
+ return mock_prisma
+
+
+@pytest.mark.asyncio
+@pytest.mark.parametrize(
+ "identifier, colliding_ids",
+ [("wiki", ("wiki-a-id", "wiki-b-id")), ("github", ("gh-a-id", "gh-b-id"))],
+)
+async def test_set_object_permission_rejects_shared_alias_or_name_tool_permission_key(identifier, colliding_ids):
+ """An alias or server_name two servers share cannot key mcp_tool_permissions on
+ create: the write is rejected with 400 naming both servers and nothing is persisted."""
+ mock_prisma = _make_ambiguity_prisma()
+ data_json = {"object_permission": {"mcp_tool_permissions": {identifier: ["read_wiki_structure"]}}}
+
+ with pytest.raises(HTTPException) as exc_info:
+ await _set_object_permission(data_json=data_json, prisma_client=mock_prisma)
+
+ assert exc_info.value.status_code == 400
+ assert all(server_id in str(exc_info.value.detail) for server_id in colliding_ids)
+ mock_prisma.db.litellm_objectpermissiontable.create.assert_not_called()
+
+
+@pytest.mark.asyncio
+async def test_prepare_object_permission_upsert_rejects_shared_alias_tool_permission_key():
+ """The update seam shared by key/team/org/user/customer/agent rejects a new
+ shared-alias key when the existing row does not already hold it."""
+ mock_prisma = _make_ambiguity_prisma(existing_tool_permissions={"solo-id": ["tool1"]})
+
+ with pytest.raises(HTTPException) as exc_info:
+ await prepare_object_permission_upsert(
+ new_object_permission={"mcp_tool_permissions": {"wiki": ["ask_question"]}},
+ existing_object_permission_id="perm-id",
+ prisma_client=mock_prisma,
+ )
+
+ assert exc_info.value.status_code == 400
+ assert "'wiki'" in str(exc_info.value.detail)
+
+
+@pytest.mark.asyncio
+async def test_unambiguous_tool_permission_keys_persist_verbatim():
+ """Exact ids (even when another server uses that id string as its alias),
+ unique aliases, and an id plus alias pointing at one server all still write."""
+ mock_prisma = _make_ambiguity_prisma()
+ tool_permissions = {
+ "wiki-a-id": ["ask_question"],
+ "wiki-b-id": ["read_wiki_structure"],
+ "solo-id": ["tool1"],
+ "solo": ["tool2"],
+ "Solo Server": ["tool3"],
+ }
+
+ upsert = await prepare_object_permission_upsert(
+ new_object_permission={"mcp_tool_permissions": dict(tool_permissions)},
+ existing_object_permission_id=None,
+ prisma_client=mock_prisma,
+ )
+
+ assert json.loads(upsert.record["mcp_tool_permissions"]) == tool_permissions
+
+
+@pytest.mark.asyncio
+async def test_stored_ambiguous_tool_permission_key_is_grandfathered_until_changed():
+ """A shared-alias entry already on the row may be re-sent unchanged so unrelated
+ edits succeed, but changing its tool list is rejected."""
+ mock_prisma = _make_ambiguity_prisma(existing_tool_permissions={"wiki": ["read_wiki_structure"]})
+
+ upsert = await prepare_object_permission_upsert(
+ new_object_permission={
+ "mcp_tool_permissions": {"wiki": ["read_wiki_structure"], "solo-id": ["tool1"]},
+ },
+ existing_object_permission_id="perm-id",
+ prisma_client=mock_prisma,
+ )
+ assert json.loads(upsert.record["mcp_tool_permissions"]) == {
+ "wiki": ["read_wiki_structure"],
+ "solo-id": ["tool1"],
+ }
+
+ with pytest.raises(HTTPException) as exc_info:
+ await prepare_object_permission_upsert(
+ new_object_permission={"mcp_tool_permissions": {"wiki": ["ask_question"]}},
+ existing_object_permission_id="perm-id",
+ prisma_client=mock_prisma,
+ )
+ assert exc_info.value.status_code == 400
+
+
def test_object_permission_dict_mirrors_pydantic_model():
"""ObjectPermissionDict must stay field-for-field aligned with
LiteLLM_ObjectPermissionBase. If a new field is added to the Pydantic
From b99d8ac38ee021b4a58b1fcfd4f4fbc1cf0c5b62 Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Sat, 5 Sep 2026 14:27:08 -0700
Subject: [PATCH 19/35] refactor(ui): keep guardrail usage code under the
inline-object-arg lint budget
The staging merge pushed local/no-large-inline-object-arg to 567 against a 554 ceiling, and 15 of those hits came from this branch. useGuardrailsUsageDetail now takes the guardrail id positionally with the date window as its second argument, the usageUnits tests build CounterMath rows through a positional helper, and the overview fixture spreads a base row inside the array instead of calling a factory
Claude-Session: https://claude.ai/code/session_01EX13mWex6RaBo9PYnkAtFW
---
.../_components/GuardrailDetail.test.tsx | 8 ++--
.../_components/GuardrailDetail.tsx | 2 +-
.../GuardrailsMonitorView.test.tsx | 3 +-
.../_components/GuardrailsOverview.test.tsx | 20 +++++----
.../guardrails/useGuardrailsUsage.test.ts | 5 +--
.../hooks/guardrails/useGuardrailsUsage.ts | 10 ++---
.../GuardrailsMonitor/usageUnits.test.ts | 43 +++++++++----------
7 files changed, 46 insertions(+), 45 deletions(-)
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
index 3d00e29245d..9f2a4c42228 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
@@ -89,9 +89,8 @@ describe("GuardrailDetail", () => {
it("should request the detail and the logs for the guardrail and date range", async () => {
renderDetail();
- expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith({
+ expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith("pii-detector", {
accessToken: "test-token",
- guardrailId: "pii-detector",
startDate: "2026-07-01",
endDate: "2026-07-24",
});
@@ -166,7 +165,10 @@ describe("GuardrailDetail", () => {
it("should not request anything without an access token", () => {
mockUseGuardrailsUsageDetail.mockReturnValue(loaded(undefined));
renderDetail({ accessToken: null });
- expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith(expect.objectContaining({ accessToken: null }));
+ expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith(
+ "pii-detector",
+ expect.objectContaining({ accessToken: null }),
+ );
expect(mockGetGuardrailsUsageLogs).not.toHaveBeenCalled();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
index 1e82f1fee85..81c39258f67 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
@@ -38,7 +38,7 @@ export function GuardrailDetail({ guardrailId, onBack, accessToken = null, start
data: detailData,
isLoading: detailLoading,
error: detailError,
- } = useGuardrailsUsageDetail({ accessToken, guardrailId, startDate, endDate });
+ } = useGuardrailsUsageDetail(guardrailId, { accessToken, startDate, endDate });
const { data: logsData, isLoading: logsLoading } = useQuery({
queryKey: ["guardrails-usage-logs", guardrailId, logsPage, logsPageSize],
queryFn: () =>
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
index e86b6fa53b6..df106fc38c3 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
@@ -107,7 +107,8 @@ describe("GuardrailsMonitorView", () => {
expect(await screen.findByRole("heading", { name: "PII Guard" })).toBeInTheDocument();
expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith(
- expect.objectContaining({ accessToken: "test-token", guardrailId: "gr-pii", startDate: expect.any(String) }),
+ "gr-pii",
+ expect.objectContaining({ accessToken: "test-token", startDate: expect.any(String) }),
);
expect(screen.queryByRole("heading", { name: /Guardrails Monitor/i })).not.toBeInTheDocument();
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
index 959ed8b172e..ead5fc9f845 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
@@ -20,7 +20,7 @@ vi.mock("./EvaluationSettingsModal", () => ({
EvaluationSettingsModal: ({ open }: { open: boolean }) => (open ? Evaluation settings modal
: null),
}));
-const row = (overrides: Partial): GuardrailUsageOverviewRow => ({
+const baseRow: GuardrailUsageOverviewRow = {
id: "guardrail",
name: "Guardrail",
type: "content_filter",
@@ -34,20 +34,21 @@ const row = (overrides: Partial): GuardrailUsageOverv
usageUnits: {},
cost: null,
untrackedUsageUnits: {},
- ...overrides,
-});
+};
const overview: GuardrailUsageOverview = {
rows: [
- row({
+ {
+ ...baseRow,
id: "guardrail-low",
name: "Low Failure Guardrail",
requestsEvaluated: 1200,
failRate: 2.5,
avgLatency: 45,
trend: "down",
- }),
- row({
+ },
+ {
+ ...baseRow,
id: "guardrail-high",
name: "High Failure Guardrail",
provider: "Bedrock",
@@ -58,8 +59,9 @@ const overview: GuardrailUsageOverview = {
usageUnits: { contentPolicyUnits: 1000, sensitiveInformationPolicyUnits: 250 },
cost: 0.15,
untrackedUsageUnits: { sensitiveInformationPolicyUnits: 250 },
- }),
- row({
+ },
+ {
+ ...baseRow,
id: "guardrail-free",
name: "Free Bedrock Guardrail",
provider: "Bedrock",
@@ -67,7 +69,7 @@ const overview: GuardrailUsageOverview = {
failRate: 0,
usageUnits: { contentPolicyUnits: 40 },
cost: 0,
- }),
+ },
],
chart: [],
totalRequests: 1510,
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
index f0b2709484d..70fc874fb50 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
+++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
@@ -50,9 +50,8 @@ describe("useGuardrailsUsageDetail", () => {
it("queries GET /guardrails/usage/detail/{guardrail_id} with the id as a path param", () => {
renderHook(() =>
- useGuardrailsUsageDetail({
+ useGuardrailsUsageDetail("bedrock-pii-mask", {
accessToken: "sk",
- guardrailId: "bedrock-pii-mask",
startDate: "2026-09-01",
endDate: "2026-09-04",
}),
@@ -73,7 +72,7 @@ describe("useGuardrailsUsageDetail", () => {
it("stays disabled without a guardrail id", () => {
renderHook(() =>
- useGuardrailsUsageDetail({ accessToken: "sk", guardrailId: "", startDate: "2026-09-01", endDate: "2026-09-04" }),
+ useGuardrailsUsageDetail("", { accessToken: "sk", startDate: "2026-09-01", endDate: "2026-09-04" }),
);
expect(lastCall()[3].enabled).toBe(false);
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
index dc7f58fbc8f..5569bdc8beb 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
+++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
@@ -24,12 +24,10 @@ export const useGuardrailsUsageOverview = ({ accessToken, startDate, endDate }:
{ enabled: Boolean(accessToken) },
);
-export const useGuardrailsUsageDetail = ({
- accessToken,
- guardrailId,
- startDate,
- endDate,
-}: GuardrailsUsageWindow & { guardrailId: string }) =>
+export const useGuardrailsUsageDetail = (
+ guardrailId: string,
+ { accessToken, startDate, endDate }: GuardrailsUsageWindow,
+) =>
$api.useQuery(
"get",
"/guardrails/usage/detail/{guardrail_id}",
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
index 8e2baaaa3c5..dd5b564b49a 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
@@ -9,8 +9,16 @@ import {
unitPrice,
unitsMathRows,
unpricedSummary,
+ type CounterMath,
} from "./usageUnits";
+const counterOf = (counter: string, units: number, unpriced: number, cost: number | null): CounterMath => ({
+ counter,
+ units,
+ unpriced,
+ cost,
+});
+
describe("formatCost", () => {
it("renders a dash when nothing was priced", () => {
expect(formatCost(null)).toBe("—");
@@ -66,15 +74,12 @@ describe("unpricedSummary", () => {
describe("unitPrice", () => {
it("backs the per-unit price out of the priced share only", () => {
- expect(unitPrice({ counter: "contentPolicyUnits", units: 1200, unpriced: 200, cost: 0.15 })).toBeCloseTo(
- 0.00015,
- 10,
- );
+ expect(unitPrice(counterOf("contentPolicyUnits", 1200, 200, 0.15))).toBeCloseTo(0.00015, 10);
});
it("is null when nothing was priced", () => {
- expect(unitPrice({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: null })).toBeNull();
- expect(unitPrice({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: 0 })).toBeNull();
+ expect(unitPrice(counterOf("someFutureCounter", 7, 7, null))).toBeNull();
+ expect(unitPrice(counterOf("someFutureCounter", 7, 7, 0))).toBeNull();
});
});
@@ -93,7 +98,7 @@ describe("formatUnitPrice", () => {
describe("counterMathRow", () => {
it("shows units × price = cost for a fully priced counter", () => {
- expect(counterMathRow({ counter: "contentPolicyUnits", units: 1000, unpriced: 0, cost: 0.15 })).toEqual({
+ expect(counterMathRow(counterOf("contentPolicyUnits", 1000, 0, 0.15))).toEqual({
label: "Content Policy",
parts: ["1,000", "× $0.00015", "= $0.1500"],
note: null,
@@ -101,20 +106,18 @@ describe("counterMathRow", () => {
});
it("prices only the priced share and calls out the rest", () => {
- expect(counterMathRow({ counter: "sensitiveInformationPolicyUnits", units: 8, unpriced: 2, cost: 0.0006 })).toEqual(
- {
- label: "Sensitive Information Policy",
- parts: ["6", "× $0.0001", "= $0.0006"],
- note: "2 unpriced units left out",
- },
+ expect(counterMathRow(counterOf("sensitiveInformationPolicyUnits", 8, 2, 0.0006))).toEqual({
+ label: "Sensitive Information Policy",
+ parts: ["6", "× $0.0001", "= $0.0006"],
+ note: "2 unpriced units left out",
+ });
+ expect(counterMathRow(counterOf("sensitiveInformationPolicyUnits", 8, 1, 0.0007)).note).toBe(
+ "1 unpriced unit left out",
);
- expect(
- counterMathRow({ counter: "sensitiveInformationPolicyUnits", units: 8, unpriced: 1, cost: 0.0007 }).note,
- ).toBe("1 unpriced unit left out");
});
it("says so when a counter has no known price at all", () => {
- expect(counterMathRow({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: null })).toEqual({
+ expect(counterMathRow(counterOf("someFutureCounter", 7, 7, null))).toEqual({
label: "Some Future Counter",
parts: ["7", "× —", "= —"],
note: "no known price, left out",
@@ -122,11 +125,7 @@ describe("counterMathRow", () => {
});
it("shows a free counter as × $0", () => {
- expect(counterMathRow({ counter: "wordPolicyUnits", units: 2, unpriced: 0, cost: 0 }).parts).toEqual([
- "2",
- "× $0",
- "= $0.0000",
- ]);
+ expect(counterMathRow(counterOf("wordPolicyUnits", 2, 0, 0)).parts).toEqual(["2", "× $0", "= $0.0000"]);
});
});
From d56affa81413ab0c04c3e3a94aae3286f3b2f8c7 Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 14:44:21 -0700
Subject: [PATCH 20/35] test(e2e): judge /v1/messages streaming on the clock,
not on the provider's delta count
The Anthropic and Together AI /v1/messages streaming tests required at
least two content_block_delta events. How many deltas a reply is split into
is the provider's choice, and Haiku answers a short count in one or two, so
the assertion failed on provider variance with no change in the proxy: four
of the day's full runs on the PR e2e gate went red on it on 2026-09-05.
The harness now stamps when each SSE event reached the client
(StreamingResponse.stream_event_arrivals, index-aligned with stream_events,
with the clock injectable so the reader has a unit test). Both tests ask for
a reply long enough to take seconds to generate and require the first
content delta to land at least STREAM_MIN_LEAD_SECONDS before message_stop.
A relayed stream shows a lead of about two seconds. A proxy that buffered
the response delivers every event in one burst and fails every time, which
a whole-response buffering relay in front of a live proxy confirmed. The
event-grammar assertions are unchanged.
Replay hands the proxy its recorded chunks back to back, so timing says
nothing there. The assertion is gated on provider_paces_stream() and replay
proves the grammar only, which tests/e2e/CLAUDE.md now says.
---
tests/e2e/CLAUDE.md | 2 +-
tests/e2e/e2e_config.py | 8 ++
tests/e2e/e2e_http.py | 99 ++++++++++++-------
.../e2e/llm_translation/test_messages_e2e.py | 38 ++++---
.../llm_translation/test_together_ai_e2e.py | 29 ++++--
tests/e2e/test_e2e_http.py | 57 ++++++++++-
6 files changed, 173 insertions(+), 60 deletions(-)
diff --git a/tests/e2e/CLAUDE.md b/tests/e2e/CLAUDE.md
index 14b2b4e3299..89c04208d65 100644
--- a/tests/e2e/CLAUDE.md
+++ b/tests/e2e/CLAUDE.md
@@ -77,7 +77,7 @@ Mark live tests with `@pytest.mark.e2e` (on the class or the module). Pure cover
The seam is `provider_edge.py`: `start_provider_edge` boots an in-process HTTP server (one shared instance per pytest process, `e2e_config.provider_edge_base` is the accessor) that mounts each supported provider under a path prefix (`EDGE_MOUNTS`: `/openai` -> `https://api.openai.com`, `/anthropic` -> `https://api.anthropic.com`). A test participates by registering its deployment with `api_base=provider_edge_base("openai")` plus the provider's path suffix; `quota_management/spend_tracking/test_provider_edge_spend_e2e.py` is the reference. In live mode the accessor returns None and the deployment defaults to the real provider, so an edge-wired test runs in all three modes unchanged. Non-wired tests hit their providers live in every mode. The edge binds `E2E_PROVIDER_EDGE_BIND_HOST` (default 127.0.0.1) and advertises `E2E_PROVIDER_EDGE_ADVERTISE_HOST` in the api_base it hands out, for proxies running in containers
-A bundle (default `tests/e2e/.fixtures`, override with `E2E_FIXTURE_DIR`) is a directory: `manifest.json` carries the record timestamp, harness git version, and format version, and each test gets a subdirectory holding one JSON file per provider call in call order (`0000-post-openai-v1-chat-completions.json`). Request headers are never stored (provider credentials never touch disk), non-JSON request bodies store a canonicalized sha256 digest instead of the bytes, `multipart/form-data` bodies store their ordinary fields plus a JSON list of the uploaded parts' `[field, filename, content-type]` triples and a digest of their content, so the per-request random boundary and the envelope never reach the key, and responses store status, filtered headers, and the verbatim body base64-encoded, which is part of why bundles are gitignored. Responses come in two shapes told apart by a `kind` tag: an ordinary one holding a single base64 body, and, for a response the provider streamed (`content-type: text/event-stream`), one holding its transfer chunks in order plus why the stream ended early if it did, so replay reproduces the split points the provider chose instead of one coalesced body. `fixture_bundle.py` owns the format, and `BUNDLE_FORMAT_VERSION` is checked on load, so a bundle recorded under older rules is refused by name rather than partially read. Record serves the proxy the same filtered stored response replay will serve later, chunk for chunk on a stream, so the two modes are byte-identical from the proxy's side of the socket
+A bundle (default `tests/e2e/.fixtures`, override with `E2E_FIXTURE_DIR`) is a directory: `manifest.json` carries the record timestamp, harness git version, and format version, and each test gets a subdirectory holding one JSON file per provider call in call order (`0000-post-openai-v1-chat-completions.json`). Request headers are never stored (provider credentials never touch disk), non-JSON request bodies store a canonicalized sha256 digest instead of the bytes, `multipart/form-data` bodies store their ordinary fields plus a JSON list of the uploaded parts' `[field, filename, content-type]` triples and a digest of their content, so the per-request random boundary and the envelope never reach the key, and responses store status, filtered headers, and the verbatim body base64-encoded, which is part of why bundles are gitignored. Responses come in two shapes told apart by a `kind` tag: an ordinary one holding a single base64 body, and, for a response the provider streamed (`content-type: text/event-stream`), one holding its transfer chunks in order plus why the stream ended early if it did, so replay reproduces the split points the provider chose instead of one coalesced body. `fixture_bundle.py` owns the format, and `BUNDLE_FORMAT_VERSION` is checked on load, so a bundle recorded under older rules is refused by name rather than partially read. Record serves the proxy the same filtered stored response replay will serve later, chunk for chunk on a stream, so the two modes are byte-identical from the proxy's side of the socket. Replay does not reproduce the provider's inter-chunk timing (chunks go out as fast as the socket takes them), so a test that judges streaming on the clock, such as the `stream_event_arrivals` lead between the first content delta and `message_stop`, gates that assertion on `provider_paces_stream()` and proves only the event grammar in replay
Multipart identity is the fiddly corner, and the rules exist because each one had a collision behind it. A part counts as an upload when it carries a filename or declares its own content type, and everything else is an ordinary field. Field names get a `name[n]` suffix on repeats, with a literal `[` doubled first, so a form that repeats `purpose` never keys the same as one that literally sends `purpose[1]`. A field whose name reads as a credential is stored as ``, which stays key-preserving because the key is recomputed from the stored request rather than saved alongside it, so the live request carrying the real value still matches its redacted fixture. A field value that is not UTF-8 is stored as a base64 sha256 digest, base64 and not hex because the canonicalizer rewrites any 64-character hex run to `` and would fold every binary value onto one key. The uploaded parts contribute a JSON list rather than a `field:filename` string, so a separator inside a filename cannot impersonate a field boundary, and their byte length is stored for a reader's benefit but deliberately left out of the key, since the canonicalizer absorbs timestamp and id drift inside a file that changes its length
diff --git a/tests/e2e/e2e_config.py b/tests/e2e/e2e_config.py
index 21c5a338dc3..09d17b9a0db 100644
--- a/tests/e2e/e2e_config.py
+++ b/tests/e2e/e2e_config.py
@@ -10,6 +10,7 @@ import os
import time
import uuid
from pathlib import Path
+from typing import Final
from dotenv import load_dotenv
@@ -192,6 +193,13 @@ def provider_edge_base(mount: str) -> str | None:
)
+STREAM_MIN_LEAD_SECONDS: Final = 1.0
+
+
+def provider_paces_stream() -> bool:
+ return parse_fixture_mode(FIXTURE_MODE_RAW) != "replay"
+
+
def unique_marker() -> str:
"""A short unique token per call/run, so concurrent runs and the shared
response cache never collide on prompts, tags, or customer ids. In record
diff --git a/tests/e2e/e2e_http.py b/tests/e2e/e2e_http.py
index bc76eb3ea7a..3a4e69cfb43 100644
--- a/tests/e2e/e2e_http.py
+++ b/tests/e2e/e2e_http.py
@@ -16,9 +16,9 @@ requests itself imports.
from __future__ import annotations
import time
-from collections.abc import Callable
+from collections.abc import Callable, Mapping
from dataclasses import dataclass
-from typing import Generator, Generic, Iterator, Literal, NewType, Protocol, TypeVar, cast
+from typing import Final, Generator, Generic, Iterator, Literal, NewType, Protocol, TypeVar, cast
import pytest
import requests
@@ -132,7 +132,12 @@ class StreamingResponse(BaseModel):
non-streaming `application/json`), the response headers (lowercased names, e.g.
the x-ratelimit-* pacing headers and retry-after on a 429), and the body.
SpendLogs.request_id is the completion body id, not call_id. Used by passthrough
- and streaming, where one validated JSON model does not fit."""
+ and streaming, where one validated JSON model does not fit.
+
+ ``stream_event_arrivals`` is index-aligned with ``stream_events`` and holds the
+ seconds after the request was sent at which each event reached the client, so a
+ test can tell a relayed stream (events spread over the provider's generation time)
+ from a buffered one (every event in one burst at the end)."""
status_code: int
call_id: str | None = None # x-litellm-call-id header
@@ -142,6 +147,7 @@ class StreamingResponse(BaseModel):
body: str
chunks: int = 0 # streamed events (0 for non-streaming)
stream_events: list[str] = []
+ stream_event_arrivals: list[float] = []
# First in-stream error event, if any. A streamed call commits its HTTP 200
# before the upstream completes, so upstream failures (e.g. insufficient
# quota) arrive as SSE error events inside an otherwise-successful response;
@@ -184,7 +190,20 @@ class BinaryStream(BaseModel):
return "chunked" in (self.transfer_encoding or "")
-def _hdr(resp: requests.Response, name: str) -> str | None:
+class SseResponse(Protocol):
+ @property
+ def status_code(self) -> int: ...
+
+ @property
+ def headers(self) -> Mapping[str, str]: ...
+
+ @property
+ def text(self) -> str: ...
+
+ def iter_lines(self) -> Iterator[bytes]: ...
+
+
+def _hdr(resp: SseResponse, name: str) -> str | None:
value = resp.headers.get(name)
return value if isinstance(value, str) else None
@@ -457,7 +476,7 @@ def probe(
return ProbeResult(status_code=resp.status_code, body=resp.text)
-def _parse_response_cost(resp: requests.Response) -> float | None:
+def _parse_response_cost(resp: SseResponse) -> float | None:
raw = _hdr(resp, "x-litellm-response-cost")
if raw is None or raw == "":
return None
@@ -467,11 +486,26 @@ def _parse_response_cost(resp: requests.Response) -> float | None:
return None
-def _streaming_outcome(resp: requests.Response, stream: bool) -> StreamingResponse:
- call_id = _hdr(resp, "x-litellm-call-id")
- response_cost = _parse_response_cost(resp)
- content_type = _hdr(resp, "content-type")
- headers = {name.lower(): value for name, value in resp.headers.items()}
+_SSE_DATA_PREFIX: Final = b"data: "
+_SSE_DONE: Final = "[DONE]"
+
+
+def _is_stream_error_line(line: bytes) -> bool:
+ return (
+ line.startswith(b"event: error")
+ or b'"type":"error"' in line
+ or b'"type": "error"' in line
+ or line.startswith(b'data: {"error"')
+ )
+
+
+def streaming_outcome(
+ resp: SseResponse, stream: bool, *, sent_at: float, clock: Callable[[], float] = time.monotonic
+) -> StreamingResponse:
+ call_id: Final = _hdr(resp, "x-litellm-call-id")
+ response_cost: Final = _parse_response_cost(resp)
+ content_type: Final = _hdr(resp, "content-type")
+ headers: Final = {name.lower(): value for name, value in resp.headers.items()}
if not stream or not (200 <= resp.status_code < 300):
return StreamingResponse(
status_code=resp.status_code,
@@ -481,29 +515,13 @@ def _streaming_outcome(resp: requests.Response, stream: bool) -> StreamingRespon
headers=headers,
body=resp.text,
)
- lines = cast("Iterator[bytes]", resp.iter_lines())
- chunks = 0
- stream_error: str | None = None
- stream_events: list[str] = []
- stream_done = False
- for line in lines:
- if not line:
- continue
- chunks += 1
- decoded_line = line.decode(errors="replace")
- if decoded_line.startswith("data: "):
- payload = decoded_line.removeprefix("data: ")
- if payload == "[DONE]":
- stream_done = True
- else:
- stream_events.append(payload)
- if stream_error is None and (
- line.startswith(b"event: error")
- or b'"type":"error"' in line
- or b'"type": "error"' in line
- or line.startswith(b'data: {"error"')
- ):
- stream_error = line.decode(errors="replace")[:300]
+ stamped: Final = tuple((line, clock() - sent_at) for line in resp.iter_lines() if line)
+ payloads: Final = tuple(
+ (line.removeprefix(_SSE_DATA_PREFIX).decode(errors="replace"), arrived)
+ for line, arrived in stamped
+ if line.startswith(_SSE_DATA_PREFIX)
+ )
+ events: Final = tuple((payload, arrived) for payload, arrived in payloads if payload != _SSE_DONE)
return StreamingResponse(
status_code=resp.status_code,
call_id=call_id,
@@ -511,10 +529,14 @@ def _streaming_outcome(resp: requests.Response, stream: bool) -> StreamingRespon
content_type=content_type,
headers=headers,
body="",
- chunks=chunks,
- stream_events=stream_events,
- stream_done=stream_done,
- stream_error=stream_error,
+ chunks=len(stamped),
+ stream_events=[payload for payload, _ in events],
+ stream_event_arrivals=[arrived for _, arrived in events],
+ stream_done=any(payload == _SSE_DONE for payload, _ in payloads),
+ stream_error=next(
+ (line.decode(errors="replace")[:300] for line, _ in stamped if _is_stream_error_line(line)),
+ None,
+ ),
)
@@ -531,6 +553,7 @@ def send(
x-litellm-call-id header. For native/passthrough bodies and for calls judged by
status rather than a typed JSON model (e.g. a budget block is a non-2xx). With
``stream=True`` the SSE body is consumed and its events counted instead."""
+ sent_at: Final = time.monotonic()
try:
resp = request_with_retry(
lambda: requests.post(
@@ -544,7 +567,7 @@ def send(
)
except requests.RequestException as exc:
return StreamingResponse(status_code=-1, body=str(exc))
- return _streaming_outcome(resp, stream)
+ return streaming_outcome(resp, stream, sent_at=sent_at)
def stream(
diff --git a/tests/e2e/llm_translation/test_messages_e2e.py b/tests/e2e/llm_translation/test_messages_e2e.py
index a5f36a8cbdd..1227b1c7119 100644
--- a/tests/e2e/llm_translation/test_messages_e2e.py
+++ b/tests/e2e/llm_translation/test_messages_e2e.py
@@ -9,7 +9,12 @@ litellm-regression-tests/tests/test_inference_endpoints.py.
from __future__ import annotations
import pytest
-from e2e_config import provider_edge_base, unique_marker
+from e2e_config import (
+ STREAM_MIN_LEAD_SECONDS,
+ provider_edge_base,
+ provider_paces_stream,
+ unique_marker,
+)
from e2e_http import assert_client_error, require_successful_call, unwrap
from endpoints_client import EndpointsClient, MessagesResult
from lifecycle import ResourceManager
@@ -159,19 +164,24 @@ class TestAnthropicMessages:
"""Edge-wired like its non-streaming siblings, so record and replay both
carry the streamed response.
- Asserts the shape of the event sequence, not just that deltas and a stop
- appeared somewhere in it: the answer arrives across several deltas, and the
- usage event sits between the last of them and ``message_stop``. A replay that
- coalesced the response into one buffered body could not satisfy either."""
+ Asserts what the proxy controls. The event grammar arrives intact: the usage
+ event sits between the last content delta and ``message_stop``. And the relay
+ is incremental, judged on the clock rather than by counting deltas: how many
+ deltas a reply is split into is the provider's choice (Haiku often sends a
+ 20-line count as one), so a count threshold flaked on provider variance. A
+ reply that takes seconds to generate must reach the client with its first
+ delta well before ``message_stop``; a proxy that buffered would deliver every
+ event in one burst. Replay hands the proxy its recorded chunks back to back,
+ so only live and record runs can judge the timing."""
model, key = self._register(endpoints_client, resources)
result = endpoints_client.proxy.messages_stream(
key,
AnthropicMessagesBody(
model=model,
- max_tokens=400,
+ max_tokens=800,
stream=True,
- messages=[ChatMessage(role="user", content="Count from 1 to 100, one number per line.")],
+ messages=[ChatMessage(role="user", content="Count from 1 to 200, one number per line.")],
),
)
require_successful_call(result)
@@ -186,10 +196,7 @@ class TestAnthropicMessages:
delta_positions = [
index for index, event in enumerate(events) if event.type == "content_block_delta"
]
- assert len(delta_positions) >= 2, (
- f"stream carried {len(delta_positions)} content deltas, so it was not "
- f"incremental: {types}"
- )
+ assert delta_positions, f"stream carried no content deltas: {types}"
text = "".join(
event.delta.text
for event in events
@@ -209,6 +216,15 @@ class TestAnthropicMessages:
f"usage did not land between the last content delta and message_stop: {types}"
)
+ first_delta_at = result.stream_event_arrivals[delta_positions[0]]
+ stop_at = result.stream_event_arrivals[stop_position]
+ if provider_paces_stream():
+ assert stop_at - first_delta_at >= STREAM_MIN_LEAD_SECONDS, (
+ f"first content delta reached the client {first_delta_at:.2f}s after the request "
+ f"and message_stop {stop_at:.2f}s after it; a relayed stream shows the first delta "
+ f"at least {STREAM_MIN_LEAD_SECONDS}s before the end, so the response was buffered"
+ )
+
@pytest.mark.covers("llm.messages.anthropic.tool_use.nonstream.works")
def test_messages_tool_use(
self, endpoints_client: EndpointsClient, resources: ResourceManager
diff --git a/tests/e2e/llm_translation/test_together_ai_e2e.py b/tests/e2e/llm_translation/test_together_ai_e2e.py
index 2c8a7a3aa20..26daf9040e0 100644
--- a/tests/e2e/llm_translation/test_together_ai_e2e.py
+++ b/tests/e2e/llm_translation/test_together_ai_e2e.py
@@ -23,7 +23,7 @@ from datetime import date
from typing import Final
import pytest
-from e2e_config import unique_marker
+from e2e_config import STREAM_MIN_LEAD_SECONDS, provider_paces_stream, unique_marker
from e2e_http import StreamingResponse, require_successful_call, unwrap
from lifecycle import ResourceManager
from models import (
@@ -81,7 +81,7 @@ PERSON_RESPONSE_FORMAT: dict[str, object] = {
}
WEATHER_PROMPT = "What is the weather in Paris? Use the tool."
WEATHER_REPORT = "Paris: 22 degrees Celsius, clear skies, wind from the northwest at 9 km/h"
-COUNTING_PROMPT = "Count from 1 to 20, one number per line."
+COUNTING_PROMPT = "Count from 1 to 200, one number per line."
WEATHER_TOOL = ChatTool(
function=ChatToolFunction(
@@ -753,7 +753,7 @@ class TestTogetherMessages:
key,
AnthropicMessagesBody(
model=model,
- max_tokens=512,
+ max_tokens=2048,
stream=True,
messages=[ChatMessage(role="user", content=COUNTING_PROMPT)],
),
@@ -763,11 +763,24 @@ class TestTogetherMessages:
assert not result.stream_error, f"stream errored: {result.stream_error}"
events = [_MessagesStreamEvent.model_validate_json(event) for event in result.stream_events]
types = [event.type for event in events]
- text_deltas = [
+ delta_positions = [
+ index for index, event in enumerate(events) if event.type == "content_block_delta"
+ ]
+ assert delta_positions, f"stream carried no content deltas: {types}"
+ text = "".join(
event.delta.text
for event in events
- if event.type == "content_block_delta" and event.delta is not None and event.delta.text
- ]
- assert len(text_deltas) >= 2, f"stream was not incremental: {types}"
- assert "20" in "".join(text_deltas), f"streamed text lost the answer: {text_deltas}"
+ if event.type == "content_block_delta" and event.delta is not None
+ )
+ assert "200" in text, f"streamed text lost the answer: {text[:300]!r}"
assert "message_stop" in types, f"stream never reached message_stop: {types}"
+
+ stop_position = types.index("message_stop")
+ first_delta_at = result.stream_event_arrivals[delta_positions[0]]
+ stop_at = result.stream_event_arrivals[stop_position]
+ if provider_paces_stream():
+ assert stop_at - first_delta_at >= STREAM_MIN_LEAD_SECONDS, (
+ f"first content delta reached the client {first_delta_at:.2f}s after the request "
+ f"and message_stop {stop_at:.2f}s after it; a relayed stream shows the first delta "
+ f"at least {STREAM_MIN_LEAD_SECONDS}s before the end, so the response was buffered"
+ )
diff --git a/tests/e2e/test_e2e_http.py b/tests/e2e/test_e2e_http.py
index 007801a797a..dc92e31fc5c 100644
--- a/tests/e2e/test_e2e_http.py
+++ b/tests/e2e/test_e2e_http.py
@@ -12,12 +12,13 @@ monkeypatches anything.
from __future__ import annotations
-from collections.abc import Callable, Sequence
+from collections.abc import Callable, Iterator, Mapping, Sequence
from dataclasses import dataclass, field
+from types import MappingProxyType
import pytest
-from e2e_http import RETRY_ATTEMPTS, TRANSIENT_STATUSES, request_with_retry
+from e2e_http import RETRY_ATTEMPTS, TRANSIENT_STATUSES, request_with_retry, streaming_outcome
@dataclass
@@ -80,3 +81,55 @@ class TestTransientRetryPolicy:
assert result is responses[RETRY_ATTEMPTS - 1]
assert sleep.delays == [0.5, 1.0]
assert [r.close_calls for r in responses] == [1, 1, 0, 0]
+
+
+@dataclass(frozen=True, slots=True)
+class FakeSseResponse:
+ lines: Sequence[bytes]
+ status_code: int = 200
+ headers: Mapping[str, str] = MappingProxyType({"content-type": "text/event-stream"})
+ text: str = ""
+
+ def iter_lines(self) -> Iterator[bytes]:
+ return iter(self.lines)
+
+
+def _ticking_clock(start: float, step: float) -> Callable[[], float]:
+ ticks = iter(range(10_000))
+ return lambda: start + step * next(ticks)
+
+
+class TestStreamEventArrivals:
+ def test_each_event_is_stamped_at_the_moment_its_line_arrives(self) -> None:
+ resp = FakeSseResponse(
+ lines=(
+ b"event: message_start",
+ b'data: {"type":"message_start"}',
+ b"",
+ b"event: ping",
+ b'data: {"type":"ping"}',
+ b"event: content_block_delta",
+ b'data: {"type":"content_block_delta"}',
+ b"data: [DONE]",
+ )
+ )
+
+ result = streaming_outcome(resp, True, sent_at=100.0, clock=_ticking_clock(start=100.0, step=0.5))
+
+ assert result.stream_events == [
+ '{"type":"message_start"}',
+ '{"type":"ping"}',
+ '{"type":"content_block_delta"}',
+ ]
+ assert result.stream_event_arrivals == [0.5, 1.5, 2.5]
+ assert result.stream_done
+ assert result.chunks == 7
+
+ def test_a_non_streaming_outcome_carries_no_arrivals(self) -> None:
+ resp = FakeSseResponse(lines=(), status_code=400, text="bad request")
+
+ result = streaming_outcome(resp, True, sent_at=0.0, clock=_ticking_clock(start=0.0, step=1.0))
+
+ assert result.stream_events == []
+ assert result.stream_event_arrivals == []
+ assert result.body == "bad request"
From 0cb759772caccee55fae6ca37dfdd05cf47c1da8 Mon Sep 17 00:00:00 2001
From: Yassin Kortam
Date: Sat, 5 Sep 2026 14:49:30 -0700
Subject: [PATCH 21/35] fix(ui): show indirectly granted and name-keyed MCP
servers in the tool matrix (#35154)
* fix(ui): show indirectly granted and name-keyed MCP servers in the tool matrix
The MCP tool permission editor was fed the direct server list only, so a server a
principal reaches through an access group or a toolset never appeared in the matrix.
That single blind spot produced two opposite bugs depending on how a save handler
filtered mcp_tool_permissions: filtering by the selected servers deletes an indirect
server's allowlist, and because a missing entry means "no restriction from this
level", the principal silently gains every tool on it; not filtering leaves a stale
entry that keeps a removed access group's server reachable, since a server named
under mcp_tool_permissions is entitled on purpose.
The editor now resolves the selected access groups and toolsets to their servers and
renders them alongside the direct ones, badged with where the grant comes from, so an
admin can see and clear an inherited server's tools like any other. Resolution reuses
the data the selector already loads: access groups resolve from each server's
mcp_access_groups, toolsets from the toolset's own tool list. When that data cannot be
loaded the editor says so instead of rendering an empty list, because an absent
inherited server reads as "there are none". Servers named only by an
mcp_tool_permissions key are listed too, which is what makes a leftover entry
visible; the opt-out sentinel still renders nothing, since it short-circuits the
backend resolver to zero servers.
Opening the editor no longer applies the delete-blocked-by-default allowlist to an
inherited server. Writing an entry for one would narrow a grant the admin never
touched just by opening the form; direct servers keep that default.
Both components also matched on server_id alone, while the backend accepts a server
id, name or alias interchangeably. A grant or allowlist written by API or config with
a name rendered as a selected server with no tools under it, which reads as "this
server has no tools". Matching now covers all three identifiers, and an edit writes
back to the key the entry already uses rather than forking a second id-keyed entry.
The same mismatch could also put one server under several keys at once, its id and
its name for instance. The backend unions every key's list, so reading one key
understated what was in force and writing one key left the others granting. The
resolver now reports, per server, the key an edit keeps, the equivalent keys it
supersedes, and the union those keys allow; the card renders the union and every
write goes through one function that writes the kept key and drops the superseded
ones. A key that also names a DIFFERENT server, which happens when two servers share
a name, is never dropped, because dropping it would strip the neighbouring server's
restriction; the card names such a key and says its tools stay allowed until the
servers no longer share the name, so an admin is told rather than left to infer it
from an edit that bounces back.
A third divergence from the backend sat in the same matching. The backend resolves an
identifier with exact-id precedence: a string that is a registry server id names that
server and stops, and only a string that is no server's id falls back to name and alias,
which can name several. Matching all three fields at once meant a server merely named
after another server's id joined the matrix as if it had been selected, and because it
landed there as a directly selected server it also received the delete-blocked default
write on open. Since an mcp_tool_permissions key is itself a grant source, saving then
handed out a server nobody granted, with no admin gesture involved. Identifier
resolution now mirrors the backend's precedence, and a key is read as this server's only
when it resolves back to it, so an entry that belongs to the id's owner is neither read
into this server's allowlist nor overwritten by an edit made against it.
A toolset grant was also invisible to the tool matrix. The backend unions a toolset's
tools with whatever mcp_tool_permissions allows, so a toolset-only grant restricts the
server to that toolset's tools; the editor read the map alone, found no entry and
rendered every tool on the server as allowed. Deselecting one from that state wrote all
the others as a permission entry, and the union turned a revocation into a grant of
every tool the toolset never included. The resolved entry now carries the toolset's
tools, so the matrix opens on what is actually in force, the delete-blocked default is
withheld from a server a toolset restricts, and a write keeps out the tools only the
toolset accounts for so a grant that ends with the toolset does not become a standing
one. Those tools cannot be revoked from this screen at all, since the backend unions
them in; they render allowed and locked and the card says which of them a toolset holds
open and where to go to revoke them.
That guard originally covered only the keys an edit supersedes, on the assumption that
the key it keeps names one server. It does not when a shared key is a server's only
entry: it then becomes the key an edit writes, and writing it moves the other server's
allowlist too, which is the widening the guard exists to prevent. The key an edit writes
is now the first one naming this server and no other, falling back to the server's own
id, so a shared key is never written through and an edit against one card cannot reach
the server behind the other. Both cards say the shared key holds tools open, since
neither can revoke them.
No owner's save handler changes here. With the full effective set now available to
the editor, the key and team handlers can filter against it instead of guessing,
which makes the internal-user surface's unfiltered save redundant
Resolves LIT-4963
Resolves LIT-4958
* chore: drop tsbuildinfo churn from merge
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): satisfy dashboard lint budgets
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): keep MCP tool allowlists for indirect grants
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): keep standing MCP grants on team save
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* style(ui): format TeamInfo and hoist inline object args
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): keep MCP tool allowlists for team servers granted indirectly (#35153)
* fix(ui): filter team MCP tool allowlists against the effective server set
Saving a team filtered mcp_tool_permissions down to the directly selected servers. A server reached
through an access group or a toolset is never in that list, so any save dropped its entry, including
a save that only changed the team alias. Because the resolver unions tool-permission keys into the
entitled server set and treats a missing entry as "no restriction from this level", the team kept
the server and lost the tool allowlist on it
Filtering on the direct list alone cannot get this right in either direction. Keeping every entry a
level did not directly select leaves a removed access group's server reachable through its own stale
entry, which breaks revocation. Dropping on deselection alone widens a server that an access group
still supplies
The save handler now resolves the effective server set with resolveEffectiveMcpServers and keeps an
entry only when something other than the entry itself still grants that server: a direct selection, a
selected access group, or a selected toolset. Unified access group ids are added when that selection
is untouched, since the loaded server list is then still accurate
When the server or toolset list cannot be resolved, every entry is kept and the admin is told the
allowlists were saved unchanged. Pruning on incomplete knowledge is the direction that silently
widens, so it only happens when the editor can show the server became unreachable. A failed lookup
and a changed access group selection are separate cases in a tagged union, so the notice names what
actually happened instead of describing the intentional one as a failure, and both hooks gate the
filter symmetrically so a save fired before toolsets settle cannot resolve against an empty toolset
list
Resolves LIT-4961
* fix(ui): resolve team MCP grants from access group metadata and refuse unsafe saves
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): resolve team access group grants from team info when the access group list is role-gated
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): match every selected access group by id instead of by count
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): reload team access group grants at save time
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): keep frontend lint budget within limit
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* test(ui): cover a standing allowlist no group grant covers at load or save
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor(ui): keep MCP grant inputs in named variables for the lint budget
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): guard MCP default write on toolset load, keep create toolsets, fix flat view
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---
.../_components/add_agent_form.test.tsx | 45 ++
.../agents/_components/add_agent_form.tsx | 3 +
.../src/components/Teams.test.tsx | 26 +
ui/litellm-dashboard/src/components/Teams.tsx | 8 +-
.../MCPToolPermissions.test.tsx | 659 +++++++++++++++++-
.../MCPToolPermissions.tsx | 204 ++++--
.../effectiveMcpServers.test.ts | 524 ++++++++++++++
.../effectiveMcpServers.ts | 216 ++++++
.../mcp_tools/McpCrudPermissionPanel.tsx | 19 +-
.../organisms/create_key_button.tsx | 9 +-
.../permissions/MCPServerPermissions.test.tsx | 75 +-
.../permissions/MCPServerPermissions.tsx | 25 +-
.../src/components/team/TeamInfo.test.tsx | 519 +++++++++++++-
.../src/components/team/TeamInfo.tsx | 179 ++++-
.../components/templates/key_edit_view.tsx | 11 +-
15 files changed, 2440 insertions(+), 82 deletions(-)
create mode 100644 ui/litellm-dashboard/src/components/mcp_server_management/effectiveMcpServers.test.ts
create mode 100644 ui/litellm-dashboard/src/components/mcp_server_management/effectiveMcpServers.ts
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.test.tsx
index 4e637344e2c..ccac244f019 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.test.tsx
@@ -24,6 +24,30 @@ vi.mock("./agent_form_fields", () => ({
default: () =>
,
}));
+vi.mock("@/components/mcp_server_management/MCPServerSelector", () => ({
+ default: ({
+ onChange,
+ }: {
+ onChange: (selection: { servers: string[]; accessGroups: string[]; toolsets: string[] }) => void;
+ }) => (
+ onChange({ servers: [], accessGroups: [], toolsets: ["ts-1"] })}
+ >
+ Select MCP toolset
+
+ ),
+}));
+
+vi.mock("@/components/mcp_server_management/MCPToolPermissions", () => ({
+ default: () => null,
+}));
+
+vi.mock("@/components/common_components/team_dropdown", () => ({
+ default: () => null,
+}));
+
const a2aInfo: AgentCreateInfo = {
agent_type: "a2a",
agent_type_display_name: "A2A Agent",
@@ -97,4 +121,25 @@ describe("AddAgentForm logos", () => {
expect(warnSpy).toHaveBeenCalledTimes(2);
warnSpy.mockRestore();
});
+
+ it("includes selected MCP toolsets in the create payload", async () => {
+ const user = userEvent.setup({ pointerEventsCheck: PointerEventsCheckLevel.Never });
+ vi.mocked(networking.createAgentCall).mockResolvedValue({
+ agent_id: "agent-1",
+ agent_name: "Test Agent",
+ } as never);
+ vi.mocked(networking.keyListCall).mockResolvedValue({ keys: [] });
+
+ renderForm();
+ await user.click(screen.getByRole("button", { name: "Next →" }));
+ await user.click(screen.getByTestId("select-mcp-toolset"));
+ await user.click(screen.getByRole("button", { name: "Next →" }));
+ await user.click(screen.getByRole("button", { name: "Next →" }));
+ await user.click(screen.getByText(/Skip for now/));
+ await user.click(screen.getByRole("button", { name: "Create Agent →" }));
+
+ await vi.waitFor(() => expect(networking.createAgentCall).toHaveBeenCalled());
+ const [, payload] = vi.mocked(networking.createAgentCall).mock.calls[0];
+ expect(payload.object_permission).toEqual({ mcp_toolsets: ["ts-1"] });
+ });
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx
index 51445ec1bdb..108bae977e1 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/agents/_components/add_agent_form.tsx
@@ -361,6 +361,7 @@ const AddAgentForm: React.FC = ({ visible, onClose, accessTok
const objectPermission: Record = {
...(mcpServersAndGroups.servers?.length ? { mcp_servers: mcpServersAndGroups.servers } : {}),
...(mcpServersAndGroups.accessGroups?.length ? { mcp_access_groups: mcpServersAndGroups.accessGroups } : {}),
+ ...(mcpServersAndGroups.toolsets?.length ? { mcp_toolsets: mcpServersAndGroups.toolsets } : {}),
...(Object.keys(toolPermissions).length ? { mcp_tool_permissions: toolPermissions } : {}),
...(entitlementModels.length ? { models: entitlementModels } : {}),
...(entitlementAgents.length ? { agents: entitlementAgents } : {}),
@@ -520,6 +521,8 @@ const AddAgentForm: React.FC = ({ visible, onClose, accessTok
) => form.setValue("mcp_tool_permissions", toolPerms)}
/>
diff --git a/ui/litellm-dashboard/src/components/Teams.test.tsx b/ui/litellm-dashboard/src/components/Teams.test.tsx
index 2bceb00aae1..c7df35197e6 100644
--- a/ui/litellm-dashboard/src/components/Teams.test.tsx
+++ b/ui/litellm-dashboard/src/components/Teams.test.tsx
@@ -17,6 +17,22 @@ import {
import Teams from "./Teams";
import { chooseSelectOption } from "../../tests/test-utils";
+vi.mock("./mcp_server_management/MCPServerSelector", () => ({
+ default: ({
+ onChange,
+ }: {
+ onChange: (selection: { servers: string[]; accessGroups: string[]; toolsets: string[] }) => void;
+ }) => (
+ onChange({ servers: [], accessGroups: [], toolsets: ["ts-1"] })}
+ >
+ Select MCP toolset
+
+ ),
+}));
+
const can = vi.fn();
vi.mock("@/app/(dashboard)/hooks/useCan", () => ({
default: (...args: unknown[]) => can(...args),
@@ -1343,6 +1359,16 @@ describe("Teams - the exact bytes the create call sends", () => {
});
});
+ it("includes selected MCP toolsets in the create object permission", async () => {
+ await openCreateModal();
+ await openSection("MCP Settings", /Allowed MCP Servers/);
+ fireEvent.click(screen.getByTestId("select-mcp-toolset"));
+
+ const payload = await submit();
+
+ expect(payload.object_permission).toStrictEqual({ mcp_toolsets: ["ts-1"] });
+ });
+
it.each([
["MCP Settings", /Allowed MCP Servers/, ["allowed_mcp_servers_and_groups", "mcp_tool_permissions"]],
["Agent Settings", /Allowed Agents/, ["allowed_agents_and_groups"]],
diff --git a/ui/litellm-dashboard/src/components/Teams.tsx b/ui/litellm-dashboard/src/components/Teams.tsx
index 4be91f22339..c4060163c78 100644
--- a/ui/litellm-dashboard/src/components/Teams.tsx
+++ b/ui/litellm-dashboard/src/components/Teams.tsx
@@ -443,6 +443,7 @@ const Teams: React.FC = ({ accessToken, userID, userRole, premiumUser
(formValues.allowed_mcp_servers_and_groups &&
(formValues.allowed_mcp_servers_and_groups.servers?.length > 0 ||
formValues.allowed_mcp_servers_and_groups.accessGroups?.length > 0 ||
+ formValues.allowed_mcp_servers_and_groups.toolsets?.length > 0 ||
formValues.allowed_mcp_servers_and_groups.toolPermissions))
) {
if (!formValues.object_permission) {
@@ -453,13 +454,16 @@ const Teams: React.FC = ({ accessToken, userID, userRole, premiumUser
delete formValues.allowed_vector_store_ids;
}
if (formValues.allowed_mcp_servers_and_groups) {
- const { servers, accessGroups } = formValues.allowed_mcp_servers_and_groups;
+ const { servers, accessGroups, toolsets } = formValues.allowed_mcp_servers_and_groups;
if (servers && servers.length > 0) {
formValues.object_permission.mcp_servers = servers;
}
if (accessGroups && accessGroups.length > 0) {
formValues.object_permission.mcp_access_groups = accessGroups;
}
+ if (toolsets && toolsets.length > 0) {
+ formValues.object_permission.mcp_toolsets = toolsets;
+ }
delete formValues.allowed_mcp_servers_and_groups;
}
@@ -1086,6 +1090,8 @@ const Teams: React.FC = ({ accessToken, userID, userRole, premiumUser
form.setValue("mcp_tool_permissions", toolPerms)}
/>
diff --git a/ui/litellm-dashboard/src/components/mcp_server_management/MCPToolPermissions.test.tsx b/ui/litellm-dashboard/src/components/mcp_server_management/MCPToolPermissions.test.tsx
index 91f1a45f858..69a761b4723 100644
--- a/ui/litellm-dashboard/src/components/mcp_server_management/MCPToolPermissions.test.tsx
+++ b/ui/litellm-dashboard/src/components/mcp_server_management/MCPToolPermissions.test.tsx
@@ -2,9 +2,11 @@ import { useState } from "react";
import { describe, it, expect, vi, beforeEach } from "vitest";
import { screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
-import { renderWithProviders } from "../../../tests/test-utils";
+import { renderWithProviders, testQueryClient } from "../../../tests/test-utils";
import MCPToolPermissions from "./MCPToolPermissions";
import * as networking from "../networking";
+import { NO_MCP_SERVERS_SENTINEL } from "../mcp_tools/constants";
+import type { MCPToolset } from "../mcp_tools/types";
vi.mock("../networking");
@@ -15,6 +17,8 @@ describe("MCPToolPermissions", () => {
beforeEach(() => {
vi.clearAllMocks();
+ testQueryClient.clear();
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
});
it("should update tool permissions when user selects a tool", async () => {
@@ -71,9 +75,10 @@ describe("MCPToolPermissions", () => {
await userEvent.click(screen.getByRole("checkbox", { name: "read_wiki_structure" }));
// Verify onChange was called with read_wiki_structure removed
- expect(mockOnChange).toHaveBeenCalledWith({
+ const expectedToolPermissions = {
[mockServerId]: ["read_wiki_contents", "ask_question"],
- });
+ };
+ expect(mockOnChange).toHaveBeenCalledWith(expectedToolPermissions);
// Verify API calls
// Note: useMCPServers uses useAuthorized() internally, which returns "123" from global mock
@@ -184,6 +189,654 @@ describe("MCPToolPermissions", () => {
});
});
+ describe("servers reached indirectly", () => {
+ const groupServer = {
+ server_id: "srv-group-1",
+ server_name: "Group Server",
+ alias: "Group Server",
+ mcp_access_groups: ["production-group"],
+ };
+ const groupTools = [
+ { name: "list_issues", description: "List issues" },
+ { name: "delete_issue", description: "Delete an issue" },
+ ];
+
+ it("renders the tool matrix for a server granted only through an access group", async () => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([groupServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("Group Server")).toBeInTheDocument();
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ expect(screen.getByText("delete_issue")).toBeInTheDocument();
+ expect(networking.listMCPTools).toHaveBeenCalledWith(mockAccessToken, groupServer.server_id);
+ });
+
+ it("shows every tool selected in flat view for an unrestricted access-group server", async () => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([groupServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ await screen.findByText("Group Server");
+ await userEvent.click(screen.getByText("Flat List"));
+
+ const [listIssues, deleteIssue] = screen.getAllByRole("checkbox");
+ expect(listIssues).toBeChecked();
+ expect(deleteIssue).toBeChecked();
+
+ await userEvent.click(listIssues);
+ expect(mockOnChange).toHaveBeenCalledWith({ [groupServer.server_id]: ["delete_issue"] });
+ });
+
+ it("marks an access-group server as inherited and leaves a directly selected one unmarked", async () => {
+ const directServer = { server_id: "srv-direct-1", server_name: "Direct Server", alias: "Direct Server" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([directServer, groupServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("Direct Server")).toBeInTheDocument();
+ expect(await screen.findByText("Group Server")).toBeInTheDocument();
+ expect(screen.getByText("Via access group: production-group")).toBeInTheDocument();
+ expect(screen.queryAllByText(/^Via /)).toHaveLength(1);
+ });
+
+ it("renders a toolset server as inherited from that toolset", async () => {
+ const toolsetServer = { server_id: "srv-toolset-1", server_name: "Toolset Server", alias: "Toolset Server" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([toolsetServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([
+ {
+ toolset_id: "ts-1",
+ toolset_name: "Support Toolset",
+ tools: [{ server_id: toolsetServer.server_id, tool_name: "list_issues" }],
+ },
+ ]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("Toolset Server")).toBeInTheDocument();
+ expect(screen.getByText("Via toolset: Support Toolset")).toBeInTheDocument();
+ });
+
+ // The backend adds a toolset's tools to whatever mcp_tool_permissions holds, so showing the
+ // server as unrestricted would invite a deselection that grants every other tool on it.
+ it("shows a toolset's own tools as the allowed set and locks them", async () => {
+ const toolsetServer = { server_id: "srv-toolset-1", server_name: "Toolset Server", alias: "Toolset Server" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([toolsetServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([
+ {
+ toolset_id: "ts-1",
+ toolset_name: "Support Toolset",
+ tools: [{ server_id: toolsetServer.server_id, tool_name: "list_issues" }],
+ },
+ ]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ expect(
+ screen.getByText(
+ "list_issues is granted by a selected toolset, so it stays allowed here; edit the toolset to revoke it",
+ ),
+ ).toBeInTheDocument();
+
+ await userEvent.click(screen.getByText("Flat List"));
+ const [listIssues, deleteIssue] = screen.getAllByRole("checkbox");
+ expect(listIssues).toBeChecked();
+ expect(listIssues).toBeDisabled();
+ expect(deleteIssue).not.toBeChecked();
+
+ await userEvent.click(listIssues);
+ expect(mockOnChange).not.toHaveBeenCalled();
+ });
+
+ it("ignores a click on a locked tool in the risk-group view", async () => {
+ const toolsetServer = { server_id: "srv-toolset-1", server_name: "Toolset Server", alias: "Toolset Server" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([toolsetServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([
+ {
+ toolset_id: "ts-1",
+ toolset_name: "Support Toolset",
+ tools: [{ server_id: toolsetServer.server_id, tool_name: "list_issues" }],
+ },
+ ]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ await userEvent.click(await screen.findByText("list_issues"));
+ expect(mockOnChange).not.toHaveBeenCalled();
+ });
+
+ // Turning a risk group off must not drop a tool the entry grants in its own right, which the
+ // toolset happens to grant too: that tool outlives the toolset and the admin did not clear it.
+ it("keeps a locked tool the entry also grants when its risk group is turned off", async () => {
+ const toolsetServer = { server_id: "srv-toolset-1", server_name: "Toolset Server", alias: "Toolset Server" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([toolsetServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([
+ {
+ toolset_id: "ts-1",
+ toolset_name: "Support Toolset",
+ tools: [{ server_id: toolsetServer.server_id, tool_name: "list_issues" }],
+ },
+ ]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ // First checkbox is the header toggle of the group holding list_issues.
+ await userEvent.click(screen.getAllByRole("checkbox")[0]);
+
+ expect(mockOnChange).toHaveBeenCalledWith({ [toolsetServer.server_id]: ["list_issues"] });
+ });
+
+ // Copying the toolset's tools into the entry would outlive the toolset, so a write keeps only
+ // what this level grants on its own.
+ it("leaves a toolset's tools out of the entry a Select All writes", async () => {
+ const toolsetServer = { server_id: "srv-toolset-1", server_name: "Toolset Server", alias: "Toolset Server" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([toolsetServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([
+ {
+ toolset_id: "ts-1",
+ toolset_name: "Support Toolset",
+ tools: [{ server_id: toolsetServer.server_id, tool_name: "list_issues" }],
+ },
+ ]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ await userEvent.click(screen.getByText("Select All"));
+
+ expect(mockOnChange).toHaveBeenCalledWith({ [toolsetServer.server_id]: ["delete_issue"] });
+ });
+
+ // The default narrows an unrestricted server; against a toolset-restricted one it would widen
+ // the grant to every non-delete tool the server exposes.
+ it("does not write the delete-blocked default for a directly selected server a toolset restricts", async () => {
+ const directServer = { server_id: "srv-direct-1", server_name: "Direct Server", alias: "Direct Server" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([directServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([
+ {
+ toolset_id: "ts-1",
+ toolset_name: "Support Toolset",
+ tools: [{ server_id: directServer.server_id, tool_name: "list_issues" }],
+ },
+ ]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ expect(mockOnChange).not.toHaveBeenCalled();
+ });
+
+ it("waits for toolsets before writing the delete-blocked default", async () => {
+ const directServer = { server_id: "srv-direct-1", server_name: "Direct Server", alias: "Direct Server" };
+ let resolveToolsets: (toolsets: MCPToolset[]) => void = () => {};
+ const pendingToolsets = new Promise((resolve) => {
+ resolveToolsets = resolve;
+ });
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([directServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockReturnValue(pendingToolsets);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ await screen.findByText("Direct Server");
+ expect(mockOnChange).not.toHaveBeenCalled();
+
+ resolveToolsets([
+ {
+ toolset_id: "ts-1",
+ toolset_name: "Support Toolset",
+ tools: [{ server_id: directServer.server_id, tool_name: "list_issues" }],
+ },
+ ]);
+
+ await screen.findByText("list_issues");
+ expect(screen.getByRole("checkbox", { name: "list_issues" })).toHaveAttribute("aria-disabled", "true");
+ expect(mockOnChange).not.toHaveBeenCalled();
+ });
+
+ // The backend resolves a selection that is a registry id to that server alone. Rendering the
+ // server merely named after it would fire the default write against a server nobody granted,
+ // and a tool-permission entry is itself a grant.
+ it.each([
+ { label: "id owner first", idOwnerFirst: true },
+ { label: "name twin first", idOwnerFirst: false },
+ ])("does not offer a server merely named after a selected id ($label)", async ({ idOwnerFirst }) => {
+ const idOwner = { server_id: "srv-collide", server_name: "Payments", alias: "Payments" };
+ const nameTwin = { server_id: "srv-twin", server_name: "srv-collide", alias: "srv-collide" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue(idOwnerFirst ? [idOwner, nameTwin] : [nameTwin, idOwner]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("Payments")).toBeInTheDocument();
+ expect(screen.queryByText("srv-collide")).not.toBeInTheDocument();
+ await waitFor(() => {
+ expect(mockOnChange).toHaveBeenCalledWith({ "srv-collide": ["list_issues"] });
+ });
+ expect(mockOnChange.mock.calls.every(([written]) => !Object.hasOwn(written, "srv-twin"))).toBe(true);
+ expect(networking.listMCPTools).not.toHaveBeenCalledWith(mockAccessToken, "srv-twin");
+ });
+
+ it("does not write a default allowlist for an inherited server", async () => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([groupServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ expect(mockOnChange).not.toHaveBeenCalled();
+ });
+
+ it("keeps blocking delete tools by default for a directly selected server", async () => {
+ const directServer = { server_id: "srv-direct-1", server_name: "Direct Server", alias: "Direct Server" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([directServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ await waitFor(() => {
+ expect(mockOnChange).toHaveBeenCalledWith({ [directServer.server_id]: ["list_issues"] });
+ });
+ });
+
+ it("shows a server that only a stale tool-permission entry still entitles", async () => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([groupServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("Group Server")).toBeInTheDocument();
+ expect(screen.getByText("Via tool permissions")).toBeInTheDocument();
+ });
+
+ it("shows nothing for a principal blocked from every MCP server", async () => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([groupServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: groupTools, error: false });
+
+ const { container } = renderWithProviders(
+ ,
+ );
+
+ expect(container).toBeEmptyDOMElement();
+ expect(networking.listMCPTools).not.toHaveBeenCalled();
+ });
+
+ it("warns instead of showing no inherited servers when the server list cannot be loaded", async () => {
+ vi.mocked(networking.fetchMCPServers).mockRejectedValue(new Error("boom"));
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("Unable to load MCP servers")).toBeInTheDocument();
+ });
+
+ it("warns when the selected toolsets cannot be resolved to servers", async () => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([]);
+ vi.mocked(networking.fetchMCPToolsets).mockRejectedValue(new Error("boom"));
+
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("Unable to load toolsets")).toBeInTheDocument();
+ });
+ });
+
+ describe("grants keyed by server name", () => {
+ const namedServer = {
+ server_id: "1f4bd6c1-0000-4000-8000-000000000001",
+ server_name: "github_mcp",
+ alias: "GitHub",
+ };
+ const namedTools = [
+ { name: "list_issues", description: "List issues" },
+ { name: "delete_issue", description: "Delete an issue" },
+ ];
+
+ it("renders the tool matrix for a grant that names the server instead of its id", async () => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([namedServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: namedTools, error: false });
+
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("github_mcp")).toBeInTheDocument();
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ expect(screen.getByText("delete_issue")).toBeInTheDocument();
+ expect(networking.listMCPTools).toHaveBeenCalledWith(mockAccessToken, namedServer.server_id);
+ });
+
+ it("writes an edit back to the name key instead of adding a second id-keyed entry", async () => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([namedServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: namedTools, error: false });
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ await userEvent.click(screen.getByRole("button", { name: "Deselect All" }));
+
+ expect(mockOnChange).toHaveBeenCalledWith({ github_mcp: [] });
+ });
+ });
+
+ describe("a server named by several equivalent keys", () => {
+ const namedServer = {
+ server_id: "1f4bd6c1-0000-4000-8000-000000000001",
+ server_name: "github_mcp",
+ alias: "GitHub",
+ mcp_access_groups: ["production-group"],
+ };
+ const namedTools = [
+ { name: "list_issues", description: "List issues" },
+ { name: "create_issue", description: "Open an issue" },
+ { name: "delete_issue", description: "Delete an issue" },
+ ];
+
+ const renderWithBothKeys = (onChange: () => void) =>
+ renderWithProviders(
+ ,
+ );
+
+ beforeEach(() => {
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([namedServer]);
+ vi.mocked(networking.fetchMCPToolsets).mockResolvedValue([]);
+ vi.mocked(networking.listMCPTools).mockResolvedValue({ tools: namedTools, error: false });
+ });
+
+ it("renders one card showing the union both keys grant", async () => {
+ renderWithBothKeys(vi.fn());
+
+ expect(await screen.findByText("github_mcp")).toBeInTheDocument();
+ expect(screen.getAllByText("github_mcp")).toHaveLength(1);
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+
+ // Flat view keeps checkbox order identical to the fetched tool order.
+ await userEvent.click(screen.getByText("Flat List"));
+ const [listIssues, createIssue, deleteIssue] = screen.getAllByRole("checkbox");
+ expect(listIssues).toBeChecked();
+ expect(createIssue).toBeChecked();
+ expect(deleteIssue).not.toBeChecked();
+ });
+
+ it("removes a deselected tool from every equivalent key, leaving one entry for the server", async () => {
+ const mockOnChange = vi.fn();
+ renderWithBothKeys(mockOnChange);
+
+ expect(await screen.findByText("list_issues")).toBeInTheDocument();
+ await userEvent.click(screen.getByText("Flat List"));
+ await userEvent.click(screen.getAllByRole("checkbox")[0]);
+
+ const written = mockOnChange.mock.calls.at(-1)?.[0] as Record;
+ expect(Object.keys(written)).toEqual([namedServer.server_id]);
+ expect(written[namedServer.server_id]).not.toContain("list_issues");
+ expect(written[namedServer.server_id]).toContain("create_issue");
+ });
+
+ // Both catalog orders, because a name resolves to two servers here and a first-match
+ // implementation is only wrong in one of them.
+ it.each([
+ { label: "edited server first", editedFirst: true },
+ { label: "twin first", editedFirst: false },
+ ])(
+ "says on the card when a key names another server too, since its tools cannot be revoked here ($label)",
+ async ({ editedFirst }) => {
+ const twin = { server_id: "1f4bd6c1-0000-4000-8000-000000000002", server_name: "github_mcp", alias: "Twin" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue(
+ editedFirst ? [namedServer, twin] : [twin, namedServer],
+ );
+
+ renderWithProviders(
+ ,
+ );
+
+ // Both cards say it: the shared key grants on either server and neither card can revoke it,
+ // so an admin looking at either one has to be told the same thing.
+ expect(
+ await screen.findAllByText(
+ 'Also granted by "github_mcp", which names another server too. Those tools stay allowed here until the servers no longer share that name',
+ ),
+ ).toHaveLength(2);
+ },
+ );
+
+ // The shared key is the twin's only entry, so it would otherwise be the key an edit writes,
+ // and writing it would move the allowlist of the server the admin is not looking at.
+ it.each([
+ { label: "edited server first", editedFirst: true },
+ { label: "twin first", editedFirst: false },
+ ])("edits the twin through its own id rather than the shared key ($label)", async ({ editedFirst }) => {
+ const twin = { server_id: "1f4bd6c1-0000-4000-8000-000000000002", server_name: "github_mcp", alias: "Twin" };
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue(editedFirst ? [namedServer, twin] : [twin, namedServer]);
+
+ const mockOnChange = vi.fn();
+ renderWithProviders(
+ ,
+ );
+
+ // The directly selected twin is the first card; both share the display name "github_mcp".
+ expect(await screen.findAllByText("list_issues")).toHaveLength(2);
+ await userEvent.click(screen.getAllByText("Select All")[0]);
+
+ const written = mockOnChange.mock.calls.at(-1)?.[0] as Record;
+ expect(written["github_mcp"]).toEqual(["list_issues"]);
+ expect(written[twin.server_id]).toEqual(["list_issues", "create_issue", "delete_issue"]);
+ });
+
+ it("says nothing about shared names when every key names one server", async () => {
+ renderWithBothKeys(vi.fn());
+
+ expect(await screen.findByText("github_mcp")).toBeInTheDocument();
+ expect(screen.queryByText(/names another server too/)).not.toBeInTheDocument();
+ });
+
+ it("badges the server once, by its strongest grant, when a key and a group both name it", async () => {
+ renderWithProviders(
+ ,
+ );
+
+ expect(await screen.findByText("github_mcp")).toBeInTheDocument();
+ expect(screen.getByText("Via access group: production-group")).toBeInTheDocument();
+ expect(screen.queryByText("Via tool permissions")).not.toBeInTheDocument();
+ expect(screen.queryAllByText(/^Via /)).toHaveLength(1);
+ });
+ });
+
describe("risk-group (CRUD) view", () => {
const crudTools = [
{ name: "list_documents", description: "List every document" },
diff --git a/ui/litellm-dashboard/src/components/mcp_server_management/MCPToolPermissions.tsx b/ui/litellm-dashboard/src/components/mcp_server_management/MCPToolPermissions.tsx
index 9d7c8cd452b..c866e9cc011 100644
--- a/ui/litellm-dashboard/src/components/mcp_server_management/MCPToolPermissions.tsx
+++ b/ui/litellm-dashboard/src/components/mcp_server_management/MCPToolPermissions.tsx
@@ -1,28 +1,62 @@
import React, { useEffect, useRef, useState, useMemo } from "react";
import { listMCPTools } from "../networking";
-import { MCPTool, MCPServer } from "../mcp_tools/types";
+import { MCPTool } from "../mcp_tools/types";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
import { useMCPServers } from "../../app/(dashboard)/hooks/mcpServers/useMCPServers";
+import { useMCPToolsets } from "../../app/(dashboard)/hooks/mcpServers/useMCPToolsets";
import McpCrudPermissionPanel from "../mcp_tools/McpCrudPermissionPanel";
import { classifyToolOp } from "../../utils/mcpToolCrudClassification";
+import { NO_MCP_SERVERS_SENTINEL } from "../mcp_tools/constants";
+import {
+ EffectiveMcpServer,
+ McpGrantSource,
+ applyToolPermissionWrite,
+ mcpAllowedToolsFor,
+ resolveEffectiveMcpServers,
+} from "./effectiveMcpServers";
interface MCPToolPermissionsProps {
accessToken: string;
- selectedServers: string[];
+ selectedServers: readonly string[];
+ selectedAccessGroups?: readonly string[];
+ selectedToolsets?: readonly string[];
toolPermissions: Record;
onChange: (toolPermissions: Record) => void;
disabled?: boolean;
}
+const NO_SELECTION: readonly string[] = [];
+
+interface InheritedBadge {
+ readonly label: string;
+ readonly className: string;
+}
+
+const inheritedBadgeFor = (source: McpGrantSource): InheritedBadge | null => {
+ switch (source.kind) {
+ case "direct":
+ return null;
+ case "accessGroup":
+ return { label: `Via access group: ${source.name}`, className: "text-green-700 bg-green-50 border-green-200" };
+ case "toolset":
+ return { label: `Via toolset: ${source.name}`, className: "text-purple-700 bg-purple-50 border-purple-200" };
+ case "toolPermission":
+ return { label: "Via tool permissions", className: "text-amber-700 bg-amber-50 border-amber-200" };
+ }
+};
+
const MCPToolPermissions: React.FC = ({
accessToken,
selectedServers,
+ selectedAccessGroups = NO_SELECTION,
+ selectedToolsets = NO_SELECTION,
toolPermissions,
onChange,
disabled = false,
}) => {
- const { data: allServers = [] } = useMCPServers();
+ const { data: allServers = [], isError: serversFailed, isLoading: serversLoading } = useMCPServers();
+ const { data: toolsets = [], isError: toolsetsFailed, isLoading: toolsetsLoading } = useMCPToolsets();
const [serverTools, setServerTools] = useState>({});
const [loadingTools, setLoadingTools] = useState>({});
const [toolErrors, setToolErrors] = useState>({});
@@ -36,15 +70,25 @@ const MCPToolPermissions: React.FC = ({
toolPermissionsRef.current = toolPermissions;
}, [toolPermissions]);
- // Filter servers based on selectedServers
- const servers = useMemo(() => {
- if (selectedServers.length === 0) return [];
- return allServers.filter((server: MCPServer) => selectedServers.includes(server.server_id));
- }, [allServers, selectedServers]);
+ // Every server this permission level reaches, not just the directly selected ones: a server
+ // reached through an access group or a toolset needs its allowlist visible and editable too.
+ const effectiveMcpInput = {
+ allServers,
+ selectedServers,
+ selectedAccessGroups,
+ selectedToolsets,
+ toolsets,
+ toolPermissions,
+ };
+ const servers = useMemo(
+ () => resolveEffectiveMcpServers(effectiveMcpInput),
+ [allServers, selectedServers, selectedAccessGroups, selectedToolsets, toolsets, toolPermissions],
+ );
// Fetch tools for a specific server; applies delete-blocked-by-default for new servers.
// `token` is passed explicitly so the closure never captures a stale accessToken.
- const fetchToolsForServer = async (serverId: string, token: string) => {
+ const fetchToolsForServer = async (entry: EffectiveMcpServer, token: string) => {
+ const serverId = entry.server.server_id;
setLoadingTools((prev) => ({ ...prev, [serverId]: true }));
setToolErrors((prev) => ({ ...prev, [serverId]: "" }));
@@ -58,14 +102,18 @@ const MCPToolPermissions: React.FC = ({
const fetchedTools: MCPTool[] = response.tools || [];
setServerTools((prev) => ({ ...prev, [serverId]: fetchedTools }));
- // For servers that have no permissions stored yet, block delete tools by default.
+ // Default only unrestricted direct servers to non-delete tools.
// Read latest permissions from the ref to avoid clobbering concurrent results.
const latestPermissions = toolPermissionsRef.current;
- if (!latestPermissions[serverId] && fetchedTools.length > 0) {
+ const isDirect = entry.source.kind === "direct";
+ const unrestricted =
+ mcpAllowedToolsFor(entry.server, latestPermissions, allServers) === undefined &&
+ entry.toolsetTools === undefined;
+ if (isDirect && unrestricted && (selectedToolsets.length === 0 || !toolsetsFailed) && fetchedTools.length > 0) {
const nonDeleteTools = fetchedTools
.filter((t) => classifyToolOp(t.name, t.description || "") !== "delete")
.map((t) => t.name);
- onChange({ ...latestPermissions, [serverId]: nonDeleteTools });
+ onChange(applyToolPermissionWrite({ toolPermissions: latestPermissions, entry, allowed: nonDeleteTools }));
}
}
} catch (err) {
@@ -79,58 +127,124 @@ const MCPToolPermissions: React.FC = ({
// Auto-fetch tools when servers or accessToken change
useEffect(() => {
- servers.forEach((server) => {
- if (!serverTools[server.server_id] && !loadingTools[server.server_id]) {
- fetchToolsForServer(server.server_id, accessToken);
+ if (toolsetsLoading) return;
+ servers.forEach((entry) => {
+ const serverId = entry.server.server_id;
+ if (!serverTools[serverId] && !loadingTools[serverId]) {
+ fetchToolsForServer(entry, accessToken);
}
});
// fetchToolsForServer is defined in this render scope but receives `accessToken`
// as an explicit argument, so it is safe to omit from deps here.
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [servers, accessToken]);
+ }, [servers, accessToken, toolsetsLoading]);
- const handleCrudPanelChange = (serverId: string, allowed: string[]) => {
- onChange({ ...toolPermissions, [serverId]: allowed });
+ // Every write goes through here so an edit is authoritative for the SERVER, not for one of the
+ // equivalent keys that may name it.
+ const writeAllowedTools = (entry: EffectiveMcpServer, allowed: string[]) => {
+ onChange(applyToolPermissionWrite({ toolPermissions, entry, allowed }));
};
- const handleSelectAll = (serverId: string) => {
- const tools = serverTools[serverId] || [];
- onChange({ ...toolPermissions, [serverId]: tools.map((t) => t.name) });
+ const handleSelectAll = (entry: EffectiveMcpServer) => {
+ const tools = serverTools[entry.server.server_id] || [];
+ writeAllowedTools(
+ entry,
+ tools.map((t) => t.name),
+ );
};
- const handleDeselectAll = (serverId: string) => {
- onChange({ ...toolPermissions, [serverId]: [] });
- };
+ // The opt-out sentinel short-circuits the backend resolver to zero servers, so nothing stored
+ // here is in force and showing a tool matrix would claim otherwise.
+ if (selectedServers.includes(NO_MCP_SERVERS_SENTINEL)) {
+ return null;
+ }
- if (selectedServers.length === 0) {
+ const selectionSizes = [
+ selectedServers.length,
+ selectedAccessGroups.length,
+ selectedToolsets.length,
+ Object.keys(toolPermissions).length,
+ ];
+ if (!selectionSizes.some((size) => size > 0)) {
return null;
}
return (
- {servers.map((server) => {
- const serverName = server.server_name || server.alias || server.server_id;
- const tools = serverTools[server.server_id] || [];
- const selectedTools = toolPermissions[server.server_id] || [];
- const isLoading = loadingTools[server.server_id];
- const error = toolErrors[server.server_id];
- const viewMode = viewModes[server.server_id] ?? "crud";
+ {serversFailed && (
+
+
Unable to load MCP servers
+
+ This list is incomplete; servers granted directly or through an access group may be missing. Reload before
+ changing tool permissions
+
+
+ )}
+
+ {toolsetsFailed && selectedToolsets.length > 0 && (
+
+
Unable to load toolsets
+
+ Servers reached through the selected toolsets are not listed below
+
+
+ )}
+
+ {serversLoading && (
+
+
+
Loading MCP servers...
+
+ )}
+
+ {servers.map((entry) => {
+ const server = entry.server;
+ const serverId = server.server_id;
+ const serverName = server.server_name || server.alias || serverId;
+ const tools = serverTools[serverId] || [];
+ const selectedTools = entry.allowedTools ?? tools.map((t) => t.name);
+ const isLoading = loadingTools[serverId];
+ const error = toolErrors[serverId];
+ const viewMode = viewModes[serverId] ?? "crud";
+ const inherited = inheritedBadgeFor(entry.source);
+ // The backend adds a toolset's tools to whatever this map allows, so these stay on however
+ // the boxes are ticked. Locking them is what keeps the matrix an honest picture of the grant.
+ const toolsetTools = entry.toolsetTools ?? [];
return (
-
+
{/* Header */}
-
{serverName}
+
+
{serverName}
+ {inherited && (
+
+ {inherited.label}
+
+ )}
+
{server.description &&
{server.description}
}
+ {entry.ambiguousKeys.length > 0 && (
+
+ {`Also granted by ${entry.ambiguousKeys.map((key) => `"${key}"`).join(", ")}, which names another server too. Those tools stay allowed here until the servers no longer share that name`}
+
+ )}
+ {toolsetTools.length > 0 && (
+
+ {toolsetTools.length === 1
+ ? `${toolsetTools[0]} is granted by a selected toolset, so it stays allowed here; edit the toolset to revoke it`
+ : `${toolsetTools.join(", ")} are granted by a selected toolset, so they stay allowed here; edit the toolset to revoke them`}
+
+ )}
{!disabled && tools.length > 0 && (
- setViewModes((prev) => ({ ...prev, [server.server_id]: next as "crud" | "flat" }))
- }
+ onValueChange={(next) => setViewModes((prev) => ({ ...prev, [serverId]: next as "crud" | "flat" }))}
className="flex w-auto items-center gap-4"
>
@@ -148,7 +262,7 @@ const MCPToolPermissions: React.FC = ({
handleSelectAll(server.server_id)}
+ onClick={() => handleSelectAll(entry)}
disabled={isLoading}
>
Select All
@@ -156,7 +270,7 @@ const MCPToolPermissions: React.FC = ({
handleDeselectAll(server.server_id)}
+ onClick={() => writeAllowedTools(entry, [])}
disabled={isLoading}
>
Deselect All
@@ -188,8 +302,9 @@ const MCPToolPermissions: React.FC = ({
{!isLoading && !error && tools.length > 0 && viewMode === "crud" && (
handleCrudPanelChange(server.server_id, allowed)}
+ value={entry.allowedTools === undefined ? undefined : [...selectedTools]}
+ lockedTools={toolsetTools}
+ onChange={(allowed) => writeAllowedTools(entry, allowed)}
readOnly={disabled}
/>
)}
@@ -199,6 +314,7 @@ const MCPToolPermissions: React.FC = ({
{tools.map((tool) => {
const isSelected = selectedTools.includes(tool.name);
+ const isLocked = toolsetTools.includes(tool.name);
return (
= ({
aria-label={tool.name}
checked={isSelected}
onChange={() => {
- if (disabled) return;
+ if (disabled || isLocked) return;
const next = isSelected
? selectedTools.filter((n) => n !== tool.name)
: [...selectedTools, tool.name];
- handleCrudPanelChange(server.server_id, next);
+ writeAllowedTools(entry, next);
}}
- disabled={disabled}
+ disabled={disabled || isLocked}
className="mt-0.5"
/>
diff --git a/ui/litellm-dashboard/src/components/mcp_server_management/effectiveMcpServers.test.ts b/ui/litellm-dashboard/src/components/mcp_server_management/effectiveMcpServers.test.ts
new file mode 100644
index 00000000000..b2ac5337245
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/mcp_server_management/effectiveMcpServers.test.ts
@@ -0,0 +1,524 @@
+import { describe, it, expect } from "vitest";
+import { MCPServer, MCPToolset } from "../mcp_tools/types";
+import {
+ applyToolPermissionWrite,
+ mcpAllowedToolsFor,
+ mcpServersForIdentifier,
+ mcpToolPermissionKeyFor,
+ resolveEffectiveMcpServers,
+} from "./effectiveMcpServers";
+
+const server = (overrides: Partial
& { server_id: string }): MCPServer =>
+ ({
+ server_name: null,
+ alias: null,
+ created_at: "2026-01-01",
+ created_by: "admin",
+ updated_at: "2026-01-01",
+ updated_by: "admin",
+ ...overrides,
+ }) as MCPServer;
+
+const toolset = (overrides: Partial & { toolset_id: string }): MCPToolset =>
+ ({ toolset_name: overrides.toolset_id, tools: [], ...overrides }) as MCPToolset;
+
+const emptyInput = {
+ allServers: [] as readonly MCPServer[],
+ selectedServers: [] as readonly string[],
+ selectedAccessGroups: [] as readonly string[],
+ selectedToolsets: [] as readonly string[],
+ toolsets: [] as readonly MCPToolset[],
+ toolPermissions: {} as Readonly>,
+};
+
+describe("mcpServersForIdentifier", () => {
+ const target = server({ server_id: "uuid-1", server_name: "github_mcp", alias: "GitHub" });
+
+ it("matches on id, server name and alias alike", () => {
+ expect(mcpServersForIdentifier([target], "uuid-1")).toEqual([target]);
+ expect(mcpServersForIdentifier([target], "github_mcp")).toEqual([target]);
+ expect(mcpServersForIdentifier([target], "GitHub")).toEqual([target]);
+ expect(mcpServersForIdentifier([target], "other")).toEqual([]);
+ });
+
+ it("names every server sharing a duplicated name, as the backend does", () => {
+ const twin = server({ server_id: "uuid-2", server_name: "github_mcp" });
+
+ expect(mcpServersForIdentifier([target, twin], "github_mcp").map((match) => match.server_id)).toEqual([
+ "uuid-1",
+ "uuid-2",
+ ]);
+ });
+
+ // The backend's expand_permission_list resolves a registry server id to that server and stops;
+ // only a string that is no server's id falls through to the name/alias pass. An identifier can
+ // name several servers, so this has to hold in either catalog order.
+ it.each([
+ { label: "id owner first", idOwnerFirst: true },
+ { label: "name twin first", idOwnerFirst: false },
+ ])("resolves an id to its own server even when another server is named after it ($label)", ({ idOwnerFirst }) => {
+ const byId = server({ server_id: "collide", server_name: "Payments" });
+ const byName = server({ server_id: "uuid-9", server_name: "collide" });
+ const catalog = idOwnerFirst ? [byId, byName] : [byName, byId];
+
+ expect(mcpServersForIdentifier(catalog, "collide").map((match) => match.server_id)).toEqual(["collide"]);
+ });
+});
+
+describe("mcpToolPermissionKeyFor", () => {
+ const target = server({ server_id: "uuid-1", server_name: "github_mcp", alias: "GitHub" });
+
+ it("returns the existing name key so an edit does not fork into a second entry", () => {
+ expect(mcpToolPermissionKeyFor(target, { github_mcp: ["list_issues"] }, [target])).toBe("github_mcp");
+ });
+
+ // The map is a second collection of non-unique identifiers for one server, and this picks a
+ // winner from it, so both write orders have to hold or a map-order winner would slip through.
+ it.each([
+ { label: "id key first", toolPermissions: { "uuid-1": ["list_prs"], github_mcp: ["list_issues"] } },
+ { label: "name key first", toolPermissions: { github_mcp: ["list_issues"], "uuid-1": ["list_prs"] } },
+ ])("prefers the id key when both an id and a name key exist ($label)", ({ toolPermissions }) => {
+ expect(mcpToolPermissionKeyFor(target, toolPermissions, [target])).toBe("uuid-1");
+ });
+
+ it("falls back to the server id when no entry exists yet", () => {
+ expect(mcpToolPermissionKeyFor(target, {}, [target])).toBe("uuid-1");
+ });
+
+ // Writing this key would hand the entry's tools to the server that owns the id, not to the one
+ // being edited, so it is not this server's key however much its name looks like it.
+ it.each([
+ { label: "id owner first", idOwnerFirst: true },
+ { label: "name twin first", idOwnerFirst: false },
+ ])("ignores a key that is another server's id ($label)", ({ idOwnerFirst }) => {
+ const byId = server({ server_id: "collide", server_name: "Payments" });
+ const byName = server({ server_id: "uuid-9", server_name: "collide" });
+ const catalog = idOwnerFirst ? [byId, byName] : [byName, byId];
+
+ expect(mcpToolPermissionKeyFor(byName, { collide: ["list_issues"] }, catalog)).toBe("uuid-9");
+ expect(mcpAllowedToolsFor(byName, { collide: ["list_issues"] }, catalog)).toBeUndefined();
+ expect(mcpAllowedToolsFor(byId, { collide: ["list_issues"] }, catalog)).toEqual(["list_issues"]);
+ });
+});
+
+describe("resolveEffectiveMcpServers", () => {
+ const direct = server({ server_id: "srv-direct", server_name: "Direct" });
+ const grouped = server({ server_id: "srv-group", server_name: "Grouped", mcp_access_groups: ["prod"] });
+ const inToolset = server({ server_id: "srv-toolset", server_name: "Toolsetted" });
+
+ it("resolves a selected access group to its member servers", () => {
+ const resolved = resolveEffectiveMcpServers({
+ ...emptyInput,
+ allServers: [direct, grouped],
+ selectedAccessGroups: ["prod"],
+ });
+
+ expect(resolved).toEqual([
+ {
+ server: grouped,
+ permissionKey: "srv-group",
+ supersededKeys: [],
+ ambiguousKeys: [],
+ keyedTools: undefined,
+ toolsetTools: undefined,
+ allowedTools: undefined,
+ source: { kind: "accessGroup", name: "prod" },
+ },
+ ]);
+ });
+
+ it("resolves access groups stored as objects rather than plain names", () => {
+ const objectGrouped = { ...grouped, mcp_access_groups: [{ name: "prod" }] } as unknown as MCPServer;
+
+ const resolved = resolveEffectiveMcpServers({
+ ...emptyInput,
+ allServers: [objectGrouped],
+ selectedAccessGroups: ["prod"],
+ });
+
+ expect(resolved.map((entry) => entry.server.server_id)).toEqual(["srv-group"]);
+ });
+
+ it("resolves a selected toolset to the servers its tools live on", () => {
+ const input = {
+ ...emptyInput,
+ allServers: [direct, inToolset],
+ selectedToolsets: ["ts-1"],
+ toolsets: [
+ toolset({
+ toolset_id: "ts-1",
+ toolset_name: "Support",
+ tools: [{ server_id: "srv-toolset", tool_name: "list_issues" }],
+ }),
+ ],
+ };
+ const resolved = resolveEffectiveMcpServers(input);
+
+ expect(resolved).toEqual([
+ {
+ server: inToolset,
+ permissionKey: "srv-toolset",
+ supersededKeys: [],
+ ambiguousKeys: [],
+ keyedTools: undefined,
+ toolsetTools: ["list_issues"],
+ allowedTools: ["list_issues"],
+ source: { kind: "toolset", name: "Support" },
+ },
+ ]);
+ });
+
+ it("yields nothing for a toolset that is not in the loaded list", () => {
+ const input = {
+ ...emptyInput,
+ allServers: [inToolset],
+ selectedToolsets: ["ts-missing"],
+ toolsets: [],
+ };
+ const resolved = resolveEffectiveMcpServers(input);
+
+ expect(resolved).toEqual([]);
+ });
+
+ it("includes a server that only a tool-permission entry names", () => {
+ const resolved = resolveEffectiveMcpServers({
+ ...emptyInput,
+ allServers: [grouped],
+ toolPermissions: { "srv-group": ["list_issues"] },
+ });
+
+ expect(resolved).toEqual([
+ {
+ server: grouped,
+ permissionKey: "srv-group",
+ supersededKeys: [],
+ ambiguousKeys: [],
+ keyedTools: ["list_issues"],
+ toolsetTools: undefined,
+ allowedTools: ["list_issues"],
+ source: { kind: "toolPermission" },
+ },
+ ]);
+ });
+
+ it("reports a server once, attributing it to the strongest grant", () => {
+ const input = {
+ ...emptyInput,
+ allServers: [grouped],
+ selectedServers: ["srv-group"],
+ selectedAccessGroups: ["prod"],
+ toolPermissions: { "srv-group": ["list_issues"] },
+ };
+ const resolved = resolveEffectiveMcpServers(input);
+
+ expect(resolved).toEqual([
+ {
+ server: grouped,
+ permissionKey: "srv-group",
+ supersededKeys: [],
+ ambiguousKeys: [],
+ keyedTools: ["list_issues"],
+ toolsetTools: undefined,
+ allowedTools: ["list_issues"],
+ source: { kind: "direct" },
+ },
+ ]);
+ });
+
+ it("resolves a server selected by name", () => {
+ const named = server({ server_id: "uuid-1", server_name: "github_mcp", alias: "GitHub" });
+
+ const input = {
+ ...emptyInput,
+ allServers: [named],
+ selectedServers: ["github_mcp"],
+ toolPermissions: { github_mcp: ["list_issues"] },
+ };
+ const resolved = resolveEffectiveMcpServers(input);
+
+ expect(resolved).toEqual([
+ {
+ server: named,
+ permissionKey: "github_mcp",
+ supersededKeys: [],
+ ambiguousKeys: [],
+ keyedTools: ["list_issues"],
+ toolsetTools: undefined,
+ allowedTools: ["list_issues"],
+ source: { kind: "direct" },
+ },
+ ]);
+ });
+
+ // The backend resolves a selection that is a registry id to that server alone, so a server that
+ // merely answers to the same string is not in the grant and must not become editable here: an
+ // edit would write its own id into mcp_tool_permissions, which is itself a grant.
+ it.each([
+ { label: "id owner first", idOwnerFirst: true },
+ { label: "name twin first", idOwnerFirst: false },
+ ])("does not resolve a selected id to a server merely named after it ($label)", ({ idOwnerFirst }) => {
+ const byId = server({ server_id: "collide", server_name: "Payments" });
+ const byName = server({ server_id: "uuid-9", server_name: "collide" });
+
+ const resolved = resolveEffectiveMcpServers({
+ ...emptyInput,
+ allServers: idOwnerFirst ? [byId, byName] : [byName, byId],
+ selectedServers: ["collide"],
+ });
+
+ expect(resolved.map((entry) => entry.server.server_id)).toEqual(["collide"]);
+ });
+
+ it("resolves every server sharing a duplicated name, as the backend does", () => {
+ const first = server({ server_id: "uuid-1", server_name: "shared" });
+ const second = server({ server_id: "uuid-2", server_name: "shared" });
+
+ const resolved = resolveEffectiveMcpServers({
+ ...emptyInput,
+ allServers: [first, second],
+ selectedServers: ["shared"],
+ });
+
+ expect(resolved.map((entry) => entry.server.server_id)).toEqual(["uuid-1", "uuid-2"]);
+ });
+});
+
+describe("equivalent permission keys for one server", () => {
+ const named = server({ server_id: "uuid-1", server_name: "github_mcp", alias: "GitHub" });
+ const other = server({ server_id: "uuid-2", server_name: "other_mcp" });
+
+ it("unions every equivalent key, which is what the backend enforces", () => {
+ expect(mcpAllowedToolsFor(named, { "uuid-1": ["list_issues"], github_mcp: ["create_issue"] }, [named])).toEqual([
+ "list_issues",
+ "create_issue",
+ ]);
+ });
+
+ it("reports the extra keys as superseded so a write can collapse them", () => {
+ const input = {
+ ...emptyInput,
+ allServers: [named],
+ selectedServers: ["uuid-1"],
+ toolPermissions: { "uuid-1": ["list_issues"], github_mcp: ["create_issue"], GitHub: ["delete_issue"] },
+ };
+ const resolved = resolveEffectiveMcpServers(input);
+
+ expect(resolved).toHaveLength(1);
+ expect(resolved[0].permissionKey).toBe("uuid-1");
+ expect(resolved[0].supersededKeys).toEqual(["github_mcp", "GitHub"]);
+ expect(resolved[0].ambiguousKeys).toEqual([]);
+ expect(resolved[0].allowedTools).toEqual(["list_issues", "create_issue", "delete_issue"]);
+ });
+
+ it("collapses a write onto the kept key and drops the equivalents", () => {
+ const toolPermissions = { "uuid-1": ["list_issues"], github_mcp: ["create_issue"], "uuid-2": ["ping"] };
+ const input = {
+ ...emptyInput,
+ allServers: [named, other],
+ selectedServers: ["uuid-1"],
+ toolPermissions,
+ };
+ const [entry] = resolveEffectiveMcpServers(input);
+
+ expect(applyToolPermissionWrite({ toolPermissions, entry, allowed: ["list_issues"] })).toEqual({
+ "uuid-1": ["list_issues"],
+ "uuid-2": ["ping"],
+ });
+ });
+
+ it("leaves a single-key server, and every other server, untouched", () => {
+ const toolPermissions = { github_mcp: ["list_issues"], "uuid-2": ["ping"] };
+ const input = {
+ ...emptyInput,
+ allServers: [named, other],
+ selectedServers: ["github_mcp"],
+ toolPermissions,
+ };
+ const [entry] = resolveEffectiveMcpServers(input);
+
+ expect(entry.supersededKeys).toEqual([]);
+ expect(entry.ambiguousKeys).toEqual([]);
+ expect(applyToolPermissionWrite({ toolPermissions, entry, allowed: [] })).toEqual({
+ github_mcp: [],
+ "uuid-2": ["ping"],
+ });
+ });
+
+ // A name resolves to several servers, so a first-match implementation is right in one catalog
+ // order and wrong in the other; both orders have to hold for this to pin anything.
+ it.each([
+ { label: "edited server first", editedFirst: true },
+ { label: "other server first", editedFirst: false },
+ ])("never drops a key that also names a different server ($label)", ({ editedFirst }) => {
+ const firstShared = server({ server_id: "uuid-1", server_name: "shared" });
+ const secondShared = server({ server_id: "uuid-2", server_name: "shared" });
+ const toolPermissions = { "uuid-1": ["list_issues"], shared: ["create_issue"] };
+
+ const input = {
+ ...emptyInput,
+ allServers: editedFirst ? [firstShared, secondShared] : [secondShared, firstShared],
+ selectedServers: ["uuid-1"],
+ toolPermissions,
+ };
+ const [entry] = resolveEffectiveMcpServers(input);
+
+ expect(entry.supersededKeys).toEqual([]);
+ expect(entry.ambiguousKeys).toEqual(["shared"]);
+ expect(applyToolPermissionWrite({ toolPermissions, entry, allowed: ["list_issues"] })).toEqual({
+ "uuid-1": ["list_issues"],
+ shared: ["create_issue"],
+ });
+ });
+
+ // The shared key is the only entry, so it would otherwise be the key an edit writes; writing it
+ // moves the other server's allowlist too, which is the same widening the secondary-key guard
+ // exists to prevent. Both catalog orders, since a shared name resolves to several servers.
+ it.each([
+ { label: "edited server first", editedFirst: true },
+ { label: "other server first", editedFirst: false },
+ ])("never writes through a shared key, even as a server's only entry ($label)", ({ editedFirst }) => {
+ const firstShared = server({ server_id: "uuid-1", server_name: "shared" });
+ const secondShared = server({ server_id: "uuid-2", server_name: "shared" });
+ const toolPermissions = { shared: ["list_issues"] };
+
+ const input = {
+ ...emptyInput,
+ allServers: editedFirst ? [firstShared, secondShared] : [secondShared, firstShared],
+ selectedServers: ["uuid-1"],
+ toolPermissions,
+ };
+ const resolved = resolveEffectiveMcpServers(input);
+
+ const edited = resolved.find((entry) => entry.server.server_id === "uuid-1")!;
+ expect(edited.permissionKey).toBe("uuid-1");
+ expect(edited.supersededKeys).toEqual([]);
+ expect(edited.ambiguousKeys).toEqual(["shared"]);
+ // What the backend enforces on this server today, which is what the card has to show.
+ expect(edited.allowedTools).toEqual(["list_issues"]);
+ expect(
+ applyToolPermissionWrite({ toolPermissions, entry: edited, allowed: ["list_issues", "create_issue"] }),
+ ).toEqual({
+ shared: ["list_issues"],
+ "uuid-1": ["list_issues", "create_issue"],
+ });
+ });
+
+ it("adds an entry for a server that had none", () => {
+ const [entry] = resolveEffectiveMcpServers({
+ ...emptyInput,
+ allServers: [named],
+ selectedServers: ["uuid-1"],
+ });
+
+ expect(applyToolPermissionWrite({ toolPermissions: {}, entry, allowed: ["list_issues"] })).toEqual({
+ "uuid-1": ["list_issues"],
+ });
+ });
+
+ // A key that is another server's id belongs to that server, so reading it here would overstate
+ // what this one allows and writing it would hand this server's tools to the other one.
+ it.each([
+ { label: "id owner first", idOwnerFirst: true },
+ { label: "name twin first", idOwnerFirst: false },
+ ])("does not treat another server's id as this server's key ($label)", ({ idOwnerFirst }) => {
+ const byId = server({ server_id: "collide", server_name: "Payments" });
+ const byName = server({ server_id: "uuid-9", server_name: "collide" });
+ const toolPermissions = { collide: ["list_issues"] };
+
+ const input = {
+ ...emptyInput,
+ allServers: idOwnerFirst ? [byId, byName] : [byName, byId],
+ selectedServers: ["uuid-9"],
+ toolPermissions,
+ };
+ const resolved = resolveEffectiveMcpServers(input);
+
+ const edited = resolved.find((entry) => entry.server.server_id === "uuid-9")!;
+ expect(edited.permissionKey).toBe("uuid-9");
+ expect(edited.supersededKeys).toEqual([]);
+ expect(edited.allowedTools).toBeUndefined();
+ expect(applyToolPermissionWrite({ toolPermissions, entry: edited, allowed: ["ping"] })).toEqual({
+ collide: ["list_issues"],
+ "uuid-9": ["ping"],
+ });
+ });
+});
+
+// The backend adds a toolset's tools to whatever mcp_tool_permissions holds, so a toolset grant is
+// part of what this level allows and none of it can be revoked by writing that map.
+describe("tools a selected toolset grants", () => {
+ const inToolset = server({ server_id: "srv-toolset", server_name: "Toolsetted" });
+ const support = toolset({
+ toolset_id: "ts-1",
+ toolset_name: "Support",
+ tools: [
+ { server_id: "srv-toolset", tool_name: "list_issues" },
+ { server_id: "srv-other", tool_name: "ignored" },
+ ],
+ });
+
+ const resolveOne = (toolPermissions: Readonly>) => {
+ const input = {
+ ...emptyInput,
+ allServers: [inToolset],
+ selectedToolsets: ["ts-1"],
+ toolsets: [support],
+ toolPermissions,
+ };
+ return resolveEffectiveMcpServers(input)[0];
+ };
+
+ it("reports them as allowed rather than leaving the server unrestricted", () => {
+ const entry = resolveOne({});
+
+ expect(entry.toolsetTools).toEqual(["list_issues"]);
+ expect(entry.allowedTools).toEqual(["list_issues"]);
+ });
+
+ it("unions them with what the permission key allows", () => {
+ const entry = resolveOne({ "srv-toolset": ["create_issue"] });
+
+ expect(entry.keyedTools).toEqual(["create_issue"]);
+ expect(entry.allowedTools).toEqual(["create_issue", "list_issues"]);
+ });
+
+ it("keeps a write from copying a toolset tool into the permission entry", () => {
+ const entry = resolveOne({});
+
+ expect(applyToolPermissionWrite({ toolPermissions: {}, entry, allowed: ["list_issues", "create_issue"] })).toEqual({
+ "srv-toolset": ["create_issue"],
+ });
+ });
+
+ it("keeps a tool the entry already holds even when the toolset grants it too", () => {
+ const toolPermissions = { "srv-toolset": ["list_issues", "create_issue"] };
+ const entry = resolveOne(toolPermissions);
+
+ expect(applyToolPermissionWrite({ toolPermissions, entry, allowed: ["list_issues", "create_issue"] })).toEqual({
+ "srv-toolset": ["list_issues", "create_issue"],
+ });
+ });
+
+ it("still narrows a tool only the permission entry grants", () => {
+ const toolPermissions = { "srv-toolset": ["create_issue", "delete_repo"] };
+ const entry = resolveOne(toolPermissions);
+
+ expect(applyToolPermissionWrite({ toolPermissions, entry, allowed: ["list_issues", "create_issue"] })).toEqual({
+ "srv-toolset": ["create_issue"],
+ });
+ });
+
+ it("leaves a server no selected toolset names unrestricted", () => {
+ const input = {
+ ...emptyInput,
+ allServers: [inToolset],
+ selectedServers: ["srv-toolset"],
+ selectedToolsets: [],
+ toolsets: [support],
+ };
+ const untouched = resolveEffectiveMcpServers(input)[0];
+
+ expect(untouched.toolsetTools).toBeUndefined();
+ expect(untouched.allowedTools).toBeUndefined();
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/mcp_server_management/effectiveMcpServers.ts b/ui/litellm-dashboard/src/components/mcp_server_management/effectiveMcpServers.ts
new file mode 100644
index 00000000000..3320dc135c9
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/mcp_server_management/effectiveMcpServers.ts
@@ -0,0 +1,216 @@
+import { z } from "zod/v4";
+import { MCPServer, MCPToolset } from "../mcp_tools/types";
+
+// Mirrors the backend resolver's union (direct + access_group + tool_perm + toolset), so the
+// editor shows exactly the servers this permission level entitles.
+export type McpGrantSource =
+ | { readonly kind: "direct" }
+ | { readonly kind: "accessGroup"; readonly name: string }
+ | { readonly kind: "toolset"; readonly name: string }
+ | { readonly kind: "toolPermission" };
+
+export interface EffectiveMcpServer {
+ readonly server: MCPServer;
+ // The mcp_tool_permissions key an edit writes to. The backend accepts a server id, name or
+ // alias interchangeably, so an API- or config-written entry may use any of them; writing the
+ // key already in the map keeps an edit from leaving the original entry behind.
+ readonly permissionKey: string;
+ // Other keys in the map that name this same server. The backend unions every key's list, so a
+ // write that touched only `permissionKey` would leave these still granting.
+ readonly supersededKeys: readonly string[];
+ // Keys naming this server that name another server too, which happens when two servers share a
+ // name or alias. They are kept rather than collapsed, so their tools cannot be revoked here; the
+ // editor has to say so rather than let an edit look like it narrowed the grant.
+ readonly ambiguousKeys: readonly string[];
+ // What the mcp_tool_permissions entries alone allow: the union across every equivalent key.
+ // `undefined` means no entry at all, so those keys impose no restriction.
+ readonly keyedTools: readonly string[] | undefined;
+ // Tools a selected toolset grants on this server. The backend unions them with the keyed tools,
+ // so they are allowed whatever this map holds and no edit here can revoke them; the editor shows
+ // them allowed and locked rather than as tools an admin is free to turn off.
+ readonly toolsetTools: readonly string[] | undefined;
+ // What this level actually allows on the server, which is what the backend enforces: the keyed
+ // union widened by the toolset grant. `undefined` means nothing restricts the server from here.
+ readonly allowedTools: readonly string[] | undefined;
+ readonly source: McpGrantSource;
+}
+
+interface ResolveInput {
+ readonly allServers: readonly MCPServer[];
+ readonly selectedServers: readonly string[];
+ readonly selectedAccessGroups: readonly string[];
+ readonly selectedToolsets: readonly string[];
+ readonly toolsets: readonly MCPToolset[];
+ readonly toolPermissions: Readonly>;
+}
+
+// Access groups come back as plain names, but older records carry `{ name }` objects.
+const accessGroupRefSchema = z.union([z.string(), z.object({ name: z.string() })]);
+
+const accessGroupNamesOf = (server: MCPServer): readonly string[] =>
+ (server.mcp_access_groups ?? []).flatMap((group) => {
+ const parsed = accessGroupRefSchema.safeParse(group);
+ if (!parsed.success) return [];
+ return [typeof parsed.data === "string" ? parsed.data : parsed.data.name];
+ });
+
+// Which servers an identifier names, with the same precedence the backend's expand_permission_list
+// applies: a string that is a registry server id names exactly that server, and only a string that
+// is not falls back to server_name/alias, which can name several. Matching all three fields at once
+// would attach a grant to a server the backend never resolves the identifier to, so an edit made
+// against that server would hand it access the original grant did not include.
+export const mcpServersForIdentifier = (allServers: readonly MCPServer[], identifier: string): readonly MCPServer[] => {
+ const byId = allServers.filter((server) => server.server_id === identifier);
+ if (byId.length > 0) return byId;
+ return allServers.filter((server) => server.server_name === identifier || server.alias === identifier);
+};
+
+// Every key in the map that names this server, id first so an id key stays the one an edit keeps.
+// A key spelled like this server's name still belongs to another server when that string is that
+// server's id, so the catalog decides membership rather than a field-by-field comparison.
+export const mcpToolPermissionKeysFor = (
+ server: MCPServer,
+ toolPermissions: Readonly>,
+ allServers: readonly MCPServer[],
+): readonly string[] =>
+ [server.server_id, server.server_name, server.alias].filter(
+ (identifier): identifier is string =>
+ typeof identifier === "string" &&
+ Object.hasOwn(toolPermissions, identifier) &&
+ mcpServersForIdentifier(allServers, identifier).some((match) => match.server_id === server.server_id),
+ );
+
+// A key naming more than one server cannot be written on any one server's behalf: the backend
+// unions it into every match, so an edit made here would move the other server's allowlist too.
+const mcpKeyNamesOneServerOnly = (allServers: readonly MCPServer[], key: string): boolean =>
+ mcpServersForIdentifier(allServers, key).length === 1;
+
+// The key an edit writes: the first one that names this server and no other, falling back to the
+// server's own id. When the only entry is a key several servers share, that fallback creates an
+// id-keyed entry rather than rewriting the shared one, which would edit the other server too.
+export const mcpToolPermissionKeyFor = (
+ server: MCPServer,
+ toolPermissions: Readonly>,
+ allServers: readonly MCPServer[],
+): string =>
+ mcpToolPermissionKeysFor(server, toolPermissions, allServers).find((key) =>
+ mcpKeyNamesOneServerOnly(allServers, key),
+ ) ?? server.server_id;
+
+// The union the backend enforces across equivalent keys, first-seen order preserved.
+export const mcpAllowedToolsFor = (
+ server: MCPServer,
+ toolPermissions: Readonly>,
+ allServers: readonly MCPServer[],
+): readonly string[] | undefined => {
+ const keys = mcpToolPermissionKeysFor(server, toolPermissions, allServers);
+ if (keys.length === 0) return undefined;
+ return [...new Set(keys.flatMap((key) => toolPermissions[key] ?? []))];
+};
+
+// Tool names the given toolsets grant on this server, `undefined` when they grant none.
+const mcpToolsetToolsFor = (
+ server: MCPServer,
+ selectedToolsets: readonly string[],
+ toolsets: readonly MCPToolset[],
+): readonly string[] | undefined => {
+ const granted = [
+ ...new Set(
+ toolsets
+ .filter((toolset) => selectedToolsets.includes(toolset.toolset_id))
+ .flatMap((toolset) =>
+ toolset.tools.filter((tool) => tool.server_id === server.server_id).map((tool) => tool.tool_name),
+ ),
+ ),
+ ];
+ return granted.length > 0 ? granted : undefined;
+};
+
+// Collapse a server's grant onto one key: the kept key gets exactly what the admin sees, and the
+// equivalent keys are dropped so nothing keeps granting under another spelling. A key that also
+// names a DIFFERENT server (duplicate server names) is never dropped, since that would silently
+// strip the other server's restriction.
+export const applyToolPermissionWrite = ({
+ toolPermissions,
+ entry,
+ allowed,
+}: {
+ readonly toolPermissions: Readonly>;
+ readonly entry: EffectiveMcpServer;
+ readonly allowed: readonly string[];
+}): Record => {
+ // A toolset grant is unioned in by the backend, so copying its tools into this entry would turn a
+ // grant that ends with the toolset into a standing one. Leaving out a tool the entry already
+ // holds would go the other way and drop a grant that survives the toolset, so only the tools the
+ // toolset alone accounts for are withheld.
+ const toolsetOnly = (entry.toolsetTools ?? []).filter((tool) => !(entry.keyedTools ?? []).includes(tool));
+ const written = allowed.filter((tool) => !toolsetOnly.includes(tool));
+ const kept: [string, string[]][] = Object.entries(toolPermissions)
+ .filter(([key]) => !entry.supersededKeys.includes(key))
+ .map(([key, tools]) => [key, key === entry.permissionKey ? [...written] : [...tools]]);
+ const withWrite: [string, string[]][] = Object.hasOwn(toolPermissions, entry.permissionKey)
+ ? kept
+ : [...kept, [entry.permissionKey, [...written]]];
+ return Object.fromEntries(withWrite);
+};
+
+export const resolveEffectiveMcpServers = ({
+ allServers,
+ selectedServers,
+ selectedAccessGroups,
+ selectedToolsets,
+ toolsets,
+ toolPermissions,
+}: ResolveInput): readonly EffectiveMcpServer[] => {
+ const entry = (server: MCPServer, source: McpGrantSource): EffectiveMcpServer => {
+ const keys = mcpToolPermissionKeysFor(server, toolPermissions, allServers);
+ const permissionKey = mcpToolPermissionKeyFor(server, toolPermissions, allServers);
+ const editable = keys.filter((key) => key !== permissionKey);
+ const keyedTools = mcpAllowedToolsFor(server, toolPermissions, allServers);
+ const toolsetTools = mcpToolsetToolsFor(server, selectedToolsets, toolsets);
+ return {
+ server,
+ permissionKey,
+ supersededKeys: editable.filter((key) => mcpKeyNamesOneServerOnly(allServers, key)),
+ ambiguousKeys: editable.filter((key) => !mcpKeyNamesOneServerOnly(allServers, key)),
+ keyedTools,
+ toolsetTools,
+ allowedTools:
+ keyedTools === undefined && toolsetTools === undefined
+ ? undefined
+ : [...new Set([...(keyedTools ?? []), ...(toolsetTools ?? [])])],
+ source,
+ };
+ };
+
+ const direct = selectedServers.flatMap((identifier) =>
+ mcpServersForIdentifier(allServers, identifier).map((server) => entry(server, { kind: "direct" })),
+ );
+
+ const viaAccessGroups = selectedAccessGroups.flatMap((group) =>
+ allServers
+ .filter((server) => accessGroupNamesOf(server).includes(group))
+ .map((server) => entry(server, { kind: "accessGroup", name: group })),
+ );
+
+ const viaToolsets = selectedToolsets.flatMap((toolsetId) => {
+ const toolset = toolsets.find((candidate) => candidate.toolset_id === toolsetId);
+ if (!toolset) return [];
+ const toolsetServerIds = new Set(toolset.tools.map((tool) => tool.server_id));
+ return allServers
+ .filter((server) => toolsetServerIds.has(server.server_id))
+ .map((server) => entry(server, { kind: "toolset", name: toolset.toolset_name }));
+ });
+
+ // A server named only under mcp_tool_permissions is entitled on purpose, so it belongs in the
+ // editor: without it, an entry left over from a removed access group is invisible and unclearable.
+ const viaToolPermissions = Object.keys(toolPermissions).flatMap((key) =>
+ mcpServersForIdentifier(allServers, key).map((server) => entry(server, { kind: "toolPermission" })),
+ );
+
+ const candidates = [...direct, ...viaAccessGroups, ...viaToolsets, ...viaToolPermissions];
+ return candidates.filter(
+ (candidate, index) =>
+ candidates.findIndex((other) => other.server.server_id === candidate.server.server_id) === index,
+ );
+};
diff --git a/ui/litellm-dashboard/src/components/mcp_tools/McpCrudPermissionPanel.tsx b/ui/litellm-dashboard/src/components/mcp_tools/McpCrudPermissionPanel.tsx
index 26101b0a509..829667af796 100644
--- a/ui/litellm-dashboard/src/components/mcp_tools/McpCrudPermissionPanel.tsx
+++ b/ui/litellm-dashboard/src/components/mcp_tools/McpCrudPermissionPanel.tsx
@@ -25,6 +25,11 @@ interface McpCrudPermissionPanelProps {
value: string[] | undefined;
/** Called whenever the allowed set changes. Always emits a concrete string[]. */
onChange: (allowed: string[]) => void;
+ /**
+ * Tools that are allowed by a grant this panel cannot edit, so they stay allowed whatever is
+ * ticked here. They render allowed and disabled, and a group toggle leaves them on.
+ */
+ lockedTools?: readonly string[];
readOnly?: boolean;
/**
* Optional search filter string. When set, only tools whose name or description
@@ -61,10 +66,13 @@ const GROUP_HEADER_BG: Record = {
// ---------------------------------------------------------------------------
+const NO_LOCKED_TOOLS: readonly string[] = [];
+
const McpCrudPermissionPanel: React.FC = ({
tools,
value,
onChange,
+ lockedTools = NO_LOCKED_TOOLS,
readOnly = false,
searchFilter = "",
}) => {
@@ -90,6 +98,8 @@ const McpCrudPermissionPanel: React.FC = ({
return new Set(value);
}, [value, tools]);
+ const locked: Set = useMemo(() => new Set(lockedTools), [lockedTools]);
+
const isToolAllowed = (name: string) => effectiveAllowed.has(name);
const isGroupFullyAllowed = (op: CrudOp) => {
@@ -105,7 +115,7 @@ const McpCrudPermissionPanel: React.FC = ({
};
const toggleTool = (toolName: string) => {
- if (readOnly) return;
+ if (readOnly || locked.has(toolName)) return;
const next = new Set(effectiveAllowed);
if (next.has(toolName)) {
next.delete(toolName);
@@ -121,7 +131,7 @@ const McpCrudPermissionPanel: React.FC = ({
for (const tool of grouped[op]) {
if (enable) {
next.add(tool.name);
- } else {
+ } else if (!locked.has(tool.name)) {
next.delete(tool.name);
}
}
@@ -220,18 +230,19 @@ const McpCrudPermissionPanel: React.FC = ({
)
.map((tool) => {
const allowed = isToolAllowed(tool.name);
+ const isLocked = locked.has(tool.name);
return (
toggleTool(tool.name)}
>
e.stopPropagation()}
/>
diff --git a/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx b/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
index 7ada45947cb..16ea99ea94c 100644
--- a/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
+++ b/ui/litellm-dashboard/src/components/organisms/create_key_button.tsx
@@ -61,7 +61,6 @@ import {
} from "../key_team_helpers/fetch_available_models_team_key";
import { Team } from "../key_team_helpers/key_list";
import MCPServerSelector from "../mcp_server_management/MCPServerSelector";
-import { NO_MCP_SERVERS_SENTINEL } from "../mcp_tools/constants";
import MCPToolPermissions from "../mcp_server_management/MCPToolPermissions";
import { toast } from "@/lib/toast";
import {
@@ -119,14 +118,18 @@ interface McpToolPermissionsFieldProps {
}
const McpToolPermissionsField: React.FC
= ({ accessToken, control, setValue }) => {
- const selection = useWatch({ control, name: "allowed_mcp_servers_and_groups" }) as { servers?: string[] } | undefined;
+ const selection = useWatch({ control, name: "allowed_mcp_servers_and_groups" }) as
+ | { servers?: string[]; accessGroups?: string[]; toolsets?: string[] }
+ | undefined;
const toolPermissions = useWatch({ control, name: "mcp_tool_permissions" }) as Record | undefined;
return (
s !== NO_MCP_SERVERS_SENTINEL)}
+ selectedServers={selection?.servers || []}
+ selectedAccessGroups={selection?.accessGroups || []}
+ selectedToolsets={selection?.toolsets || []}
toolPermissions={toolPermissions || {}}
onChange={(toolPerms) => setValue("mcp_tool_permissions", toolPerms)}
/>
diff --git a/ui/litellm-dashboard/src/components/permissions/MCPServerPermissions.test.tsx b/ui/litellm-dashboard/src/components/permissions/MCPServerPermissions.test.tsx
index 78ede9865a4..e34359687d9 100644
--- a/ui/litellm-dashboard/src/components/permissions/MCPServerPermissions.test.tsx
+++ b/ui/litellm-dashboard/src/components/permissions/MCPServerPermissions.test.tsx
@@ -106,8 +106,7 @@ describe("MCPServerPermissions", () => {
expect(screen.queryByText("ask_question")).not.toBeInTheDocument();
// Click the server row to expand
- const serverRow = screen.getByText(/DW_MCP/).closest("div");
- await userEvent.click(serverRow!);
+ await userEvent.click(screen.getByText(/DW_MCP/));
// Now tools should be visible
await waitFor(() => {
@@ -117,7 +116,7 @@ describe("MCPServerPermissions", () => {
});
// Click the server row again to collapse
- await userEvent.click(serverRow!);
+ await userEvent.click(screen.getByText(/DW_MCP/));
// Tools should be hidden again
await waitFor(() => {
@@ -297,11 +296,8 @@ describe("MCPServerPermissions", () => {
expect(toolLabels.length).toBeGreaterThan(0);
// Expand both servers by clicking their rows
- const server1Row = screen.getByText(/DW_MCP/).closest("div");
- const server2Row = screen.getByText(/Test Server/).closest("div");
-
- await userEvent.click(server1Row!); // Expand server 1
- await userEvent.click(server2Row!); // Expand server 2
+ await userEvent.click(screen.getByText(/DW_MCP/)); // Expand server 1
+ await userEvent.click(screen.getByText(/Test Server/)); // Expand server 2
// Verify server 1 tools are now visible
await waitFor(() => {
@@ -356,6 +352,69 @@ describe("MCPServerPermissions", () => {
expect(networking.fetchMCPServers).not.toHaveBeenCalled();
});
+ it("should name a server a grant references by server name rather than by id", async () => {
+ /**
+ * The backend accepts a server id, name or alias interchangeably, so a grant written by API
+ * or config can name the server. Falling through to the raw string hides which server it is.
+ */
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([
+ {
+ server_id: mockServerId1,
+ server_name: "github_mcp",
+ alias: "GitHub",
+ },
+ ]);
+
+ render(
+ ,
+ );
+
+ expect(await screen.findByText(/GitHub/)).toBeInTheDocument();
+ expect(screen.queryByText("github_mcp")).not.toBeInTheDocument();
+ });
+
+ it("should display tools for a name-keyed allowlist on an id-referenced server", async () => {
+ /**
+ * The allowlist key and the grant entry can name the same server differently; matching only on
+ * server_id renders the server as if it had no tool restrictions at all.
+ */
+ vi.mocked(networking.fetchMCPServers).mockResolvedValue([
+ {
+ server_id: mockServerId1,
+ server_name: "github_mcp",
+ alias: "GitHub",
+ },
+ ]);
+
+ render(
+ ,
+ );
+
+ await waitFor(() => {
+ expect(screen.getByText(/GitHub/)).toBeInTheDocument();
+ });
+
+ expect(screen.getByText("2")).toBeInTheDocument();
+ expect(screen.getByText("tools")).toBeInTheDocument();
+
+ await userEvent.click(screen.getByText(/GitHub/));
+
+ await waitFor(() => {
+ expect(screen.getByText("list_issues")).toBeInTheDocument();
+ expect(screen.getByText("list_prs")).toBeInTheDocument();
+ });
+ });
+
it("should display the All Proxy MCP Servers state instead of the raw sentinel string", async () => {
vi.mocked(networking.fetchMCPServers).mockResolvedValue([]);
diff --git a/ui/litellm-dashboard/src/components/permissions/MCPServerPermissions.tsx b/ui/litellm-dashboard/src/components/permissions/MCPServerPermissions.tsx
index 65f210addfa..b4546d0b4dd 100644
--- a/ui/litellm-dashboard/src/components/permissions/MCPServerPermissions.tsx
+++ b/ui/litellm-dashboard/src/components/permissions/MCPServerPermissions.tsx
@@ -5,6 +5,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip
import { fetchMCPServers, fetchMCPToolsets } from "../networking";
import { MCPServer, MCPToolset } from "../mcp_tools/types";
import { ALL_PROXY_MCP_SERVERS_SENTINEL, NO_MCP_SERVERS_SENTINEL } from "../mcp_tools/constants";
+import { mcpAllowedToolsFor, mcpServersForIdentifier } from "../mcp_server_management/effectiveMcpServers";
import { InheritedGrant, inheritedGrantTooltip } from "./inheritedGrants";
interface MCPServerPermissionsProps {
@@ -94,14 +95,26 @@ export function MCPServerPermissions({
fetchToolsets();
}, [accessToken, mcpToolsets.length]);
- // Function to get display name for MCP server
- const getMCPServerDisplayName = (serverId: string) => {
- const serverDetail = mcpServerDetails.find((server) => server.server_id === serverId);
+ // A grant may name a server by id, name or alias, resolved the way the backend resolves it.
+ const getMCPServerDisplayName = (serverIdentifier: string) => {
+ const [serverDetail] = mcpServersForIdentifier(mcpServerDetails, serverIdentifier);
if (serverDetail) {
+ const label = serverDetail.alias || serverDetail.server_name || serverDetail.server_id;
+ const serverId = serverDetail.server_id;
const truncatedId = serverId.length > 7 ? `${serverId.slice(0, 3)}...${serverId.slice(-4)}` : serverId;
- return `${serverDetail.alias || serverDetail.server_name || serverId} (${truncatedId})`;
+ return `${label} (${truncatedId})`;
}
- return serverId;
+ return serverIdentifier;
+ };
+
+ // The allowlist may be keyed by a different identifier than the grant names the server by, and
+ // several equivalent keys may each carry part of it; the backend enforces their union.
+ const getToolPermissionsFor = (serverIdentifier: string): readonly string[] | undefined => {
+ const [serverDetail] = mcpServersForIdentifier(mcpServerDetails, serverIdentifier);
+ if (!serverDetail) {
+ return mcpToolPermissions[serverIdentifier];
+ }
+ return mcpAllowedToolsFor(serverDetail, mcpToolPermissions, mcpServerDetails);
};
const blocksAllMcpServers = mcpServers.includes(NO_MCP_SERVERS_SENTINEL);
@@ -143,7 +156,7 @@ export function MCPServerPermissions({
) : totalCount > 0 ? (
{mergedItems.map((item, index) => {
- const toolsForServer = item.type === "server" ? mcpToolPermissions[item.value] : undefined;
+ const toolsForServer = item.type === "server" ? getToolPermissionsFor(item.value) : undefined;
const hasToolRestrictions = toolsForServer && toolsForServer.length > 0;
const isExpanded = expandedServers.has(item.value);
diff --git a/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx b/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx
index a993c1f6bd6..041ba4b548d 100644
--- a/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx
+++ b/ui/litellm-dashboard/src/components/team/TeamInfo.test.tsx
@@ -4,7 +4,16 @@ import { fireEvent, screen, waitFor, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { chooseSelectOption, renderWithProviders, testQueryClient } from "../../../tests/test-utils";
-import TeamInfoView, { type TeamData } from "./TeamInfo";
+import { toast } from "@/lib/toast";
+import type { EffectiveMcpServer } from "../mcp_server_management/effectiveMcpServers";
+import type { MCPServer } from "../mcp_tools/types";
+import TeamInfoView, {
+ grantedMcpServerIds,
+ type McpGrantInput,
+ retainedMcpToolPermissions,
+ standingToolPermissionServerIds,
+ type TeamData,
+} from "./TeamInfo";
const authState = vi.hoisted(() => ({ userRole: "Admin" }));
@@ -37,9 +46,11 @@ vi.mock("@/components/networking", () => ({
getTeamPermissionsCall: vi.fn(),
organizationInfoCall: vi.fn(),
getRouterSettingsCall: vi.fn().mockResolvedValue({ fields: [] }),
- getPassThroughEndpointsCall: vi.fn(),
+ getPassThroughEndpointsCall: vi.fn().mockResolvedValue({ endpoints: [] }),
fetchMCPServers: vi.fn().mockResolvedValue([]),
fetchMCPToolsets: vi.fn().mockResolvedValue([]),
+ listMCPTools: vi.fn().mockResolvedValue({ tools: [] }),
+ vectorStoreListCall: vi.fn().mockResolvedValue({ data: [] }),
getAgentsList: vi.fn().mockResolvedValue({ agents: [] }),
}));
@@ -66,6 +77,7 @@ vi.mock("@/app/(dashboard)/hooks/teams/useTeams", () => ({
}));
vi.mock("@/app/(dashboard)/hooks/organizations/useOrganizations", () => ({
+ organizationKeys: { all: ["organizations"] },
useOrganization: vi.fn(),
useOrganizations: vi.fn().mockReturnValue({ data: [], isLoading: false }),
}));
@@ -74,6 +86,38 @@ vi.mock("@/app/(dashboard)/hooks/users/useCurrentUser", () => ({
useCurrentUser: vi.fn(),
}));
+vi.mock("@/app/(dashboard)/hooks/mcpServers/useMCPServers", () => ({
+ useMCPServers: vi.fn(),
+}));
+
+vi.mock("@/app/(dashboard)/hooks/mcpServers/useMCPToolsets", () => ({
+ useMCPToolsets: vi.fn(),
+}));
+
+vi.mock("@/components/mcp_server_management/MCPServerSelector", () => ({
+ default: ({
+ value,
+ onChange,
+ }: {
+ value?: { servers: string[]; accessGroups: string[]; toolsets?: string[] };
+ onChange: (next: { servers: string[]; accessGroups: string[]; toolsets: string[] }) => void;
+ }) => (
+ <>
+
+ onChange({ servers: [], accessGroups: value?.accessGroups ?? [], toolsets: value?.toolsets ?? [] })
+ }
+ >
+ deselect all mcp servers
+
+
onChange({ servers: value?.servers ?? [], accessGroups: [], toolsets: [] })}>
+ remove all access groups
+
+ >
+ ),
+}));
+
vi.mock("@/components/team/TeamMemberTab", () => ({
default: vi.fn(({ setIsAddMemberModalVisible }) => (
@@ -127,7 +171,9 @@ vi.mock("@/components/common_components/ModelAliasManager", () => ({
default: vi.fn(({ initialModelAliases, onAliasUpdate }) => (
{JSON.stringify(initialModelAliases)}
-
onAliasUpdate({ "gpt-4o": "gpt-4" })}>Set Alias
+
onAliasUpdate({ "gpt-4o": "gpt-4" })}>
+ Set Alias
+
onAliasUpdate({})}>
Clear Aliases
@@ -138,14 +184,22 @@ vi.mock("@/components/common_components/ModelAliasManager", () => ({
vi.mock("@/app/(dashboard)/hooks/accessGroups/useAccessGroups", () => ({
useAccessGroups: vi.fn().mockReturnValue({
data: [
- { access_group_id: "ag-1", access_group_name: "Group 1" },
- { access_group_id: "ag-2", access_group_name: "Group 2" },
+ { access_group_id: "ag-1", access_group_name: "Group 1", access_mcp_server_ids: [] },
+ { access_group_id: "ag-2", access_group_name: "Group 2", access_mcp_server_ids: [] },
],
isLoading: false,
isError: false,
}),
}));
+vi.mock("@/components/common_components/AccessGroupSelector", () => ({
+ default: ({ value, onChange }: { value?: string[]; onChange?: (next: string[]) => void }) => (
+
onChange?.((value ?? []).slice(1))}>
+ remove first unified access group
+
+ ),
+}));
+
vi.mock("@/app/(dashboard)/hooks/keys/useKeys", () => ({
useKeys: vi.fn().mockReturnValue({
data: { keys: [], total_count: 0, current_page: 1, total_pages: 1 },
@@ -170,12 +224,18 @@ import { useKeys } from "@/app/(dashboard)/hooks/keys/useKeys";
import { useOrganization } from "@/app/(dashboard)/hooks/organizations/useOrganizations";
import { useTeam } from "@/app/(dashboard)/hooks/teams/useTeams";
import { useCurrentUser } from "@/app/(dashboard)/hooks/users/useCurrentUser";
+import { useMCPServers } from "@/app/(dashboard)/hooks/mcpServers/useMCPServers";
+import { useMCPToolsets } from "@/app/(dashboard)/hooks/mcpServers/useMCPToolsets";
+import { useAccessGroups } from "@/app/(dashboard)/hooks/accessGroups/useAccessGroups";
const mockUseAllProxyModels = vi.mocked(useAllProxyModels);
const mockUseKeys = vi.mocked(useKeys);
const mockUseTeam = vi.mocked(useTeam);
const mockUseOrganization = vi.mocked(useOrganization);
const mockUseCurrentUser = vi.mocked(useCurrentUser);
+const mockUseMCPServers = vi.mocked(useMCPServers);
+const mockUseMCPToolsets = vi.mocked(useMCPToolsets);
+const mockUseAccessGroups = vi.mocked(useAccessGroups);
const createMockTeamData = (overrides = {}) => ({
team_id: "123",
@@ -234,6 +294,16 @@ const seedDefaultMocks = () => {
data: { models: [] },
isLoading: false,
} as any);
+ mockUseMCPServers.mockReturnValue({ data: [], isLoading: false, isError: false } as any);
+ mockUseMCPToolsets.mockReturnValue({ data: [], isLoading: false, isError: false } as any);
+ mockUseAccessGroups.mockReturnValue({
+ data: [
+ { access_group_id: "ag-1", access_group_name: "Group 1", access_mcp_server_ids: [] },
+ { access_group_id: "ag-2", access_group_name: "Group 2", access_mcp_server_ids: [] },
+ ],
+ isLoading: false,
+ isError: false,
+ } as any);
mockUseKeys.mockReturnValue({
data: { keys: [], total_count: 0, current_page: 1, total_pages: 1 },
isPending: false,
@@ -2193,3 +2263,442 @@ describe("TeamInfoView - the exact bytes the update call sends", () => {
expect(networking.teamUpdateCall).not.toHaveBeenCalled();
});
});
+
+describe("TeamInfo MCP permission retention", () => {
+ beforeEach(seedDefaultMocks);
+
+ afterEach(() => {
+ vi.clearAllMocks();
+ });
+
+ const server = (serverId: string, serverName: string, alias?: string): MCPServer =>
+ ({
+ server_id: serverId,
+ server_name: serverName,
+ alias,
+ mcp_access_groups: [],
+ created_at: "",
+ created_by: "",
+ updated_at: "",
+ updated_by: "",
+ }) as MCPServer;
+
+ const effective = (serverId: string, kind: EffectiveMcpServer["source"]["kind"]): EffectiveMcpServer =>
+ ({
+ server: server(serverId, serverId),
+ permissionKey: serverId,
+ supersededKeys: [],
+ ambiguousKeys: [],
+ keyedTools: undefined,
+ toolsetTools: undefined,
+ allowedTools: undefined,
+ source: kind === "accessGroup" ? { kind, name: "ops_readonly" } : { kind },
+ }) as EffectiveMcpServer;
+
+ const UNIFIED_SERVER = server("unified-server", "wiki");
+ const UNIFIED_GROUPS = [
+ { access_group_id: "ag-1", access_group_name: "Group 1", access_mcp_server_ids: ["unified-server"] },
+ { access_group_id: "ag-2", access_group_name: "Group 2", access_mcp_server_ids: [] },
+ ];
+
+ const unifiedTeam = (toolPermissions: Record
, serverIds: string[] = []) => {
+ const teamData = {
+ models: ["gpt-4"],
+ access_group_ids: ["ag-1", "ag-2"],
+ access_group_mcp_server_ids: serverIds,
+ object_permission: {
+ mcp_servers: [],
+ mcp_access_groups: [],
+ mcp_toolsets: [],
+ mcp_tool_permissions: toolPermissions,
+ },
+ };
+ return createMockTeamData(teamData);
+ };
+
+ const renderMcpEditor = async (
+ user: ReturnType,
+ {
+ initialTeam = unifiedTeam({ wiki: ["read_page"] }, ["unified-server"]),
+ freshTeam = initialTeam,
+ accessGroups = [],
+ }: {
+ initialTeam?: ReturnType;
+ freshTeam?: ReturnType;
+ accessGroups?: typeof UNIFIED_GROUPS;
+ } = {},
+ ) => {
+ mockUseMCPServers.mockReturnValue({ data: [UNIFIED_SERVER], isLoading: false, isError: false } as any);
+ mockUseMCPToolsets.mockReturnValue({ data: [], isLoading: false, isError: false } as any);
+ mockUseAccessGroups.mockReturnValue({ data: accessGroups, isLoading: false, isError: false } as any);
+ vi.mocked(networking.teamInfoCall).mockResolvedValueOnce(initialTeam).mockResolvedValue(freshTeam);
+ vi.mocked(networking.teamUpdateCall).mockResolvedValue({ data: {}, team_id: "123" } as any);
+
+ renderWithProviders(
+ ,
+ );
+ await waitFor(() => expect(screen.queryAllByText("Test Team").length).toBeGreaterThan(0));
+ await user.click(screen.getByRole("tab", { name: "Settings" }));
+ await user.click(await screen.findByRole("button", { name: /edit settings/i }));
+ await screen.findByLabelText("Team Name");
+ };
+
+ const saveMcpEditor = async (user: ReturnType) => {
+ await user.click(screen.getByRole("button", { name: /save changes/i }));
+ await waitFor(() => expect(networking.teamUpdateCall).toHaveBeenCalled());
+ const calls = vi.mocked(networking.teamUpdateCall).mock.calls;
+ const [, payload] = calls[calls.length - 1];
+ return payload.object_permission.mcp_tool_permissions;
+ };
+
+ const refuseMcpSave = async (user: ReturnType, reason: RegExp) => {
+ const errorToast = vi.spyOn(toast, "fromError").mockImplementation(() => {});
+ await user.click(screen.getByRole("button", { name: /save changes/i }));
+ await waitFor(() => expect(errorToast).toHaveBeenCalledWith(expect.stringMatching(reason)));
+ expect(networking.teamUpdateCall).not.toHaveBeenCalled();
+ errorToast.mockRestore();
+ };
+
+ const resolveGrants = (overrides: Partial) => {
+ const input: McpGrantInput = {
+ effectiveServers: [effective("server-1", "direct")],
+ selectedAccessGroupIds: ["ag-1"],
+ accessGroups: [],
+ standingServerIds: new Set(),
+ loadTeamGroups: vi.fn(),
+ ...overrides,
+ };
+ return grantedMcpServerIds(input);
+ };
+
+ it("retains permissions for directly and indirectly granted servers", async () => {
+ const resolution = await resolveGrants({
+ effectiveServers: [effective("direct", "direct"), effective("inherited", "toolPermission")],
+ accessGroups: [{ access_group_id: "ag-1", access_mcp_server_ids: ["inherited"] }],
+ });
+ expect(resolution.kind).toBe("resolved");
+ if (resolution.kind !== "resolved") return;
+
+ expect(
+ retainedMcpToolPermissions(
+ { direct: ["create_issue"], inherited: ["list_issues"], removed: ["delete_repo"] },
+ resolution.serverIds,
+ [server("direct", "deploy_tracker"), server("inherited", "issue_tracker"), server("removed", "old_tracker")],
+ ),
+ ).toEqual({
+ direct: ["create_issue"],
+ inherited: ["list_issues"],
+ });
+ });
+
+ it("matches name and alias permission keys to granted server ids", () => {
+ const catalog = [server("server-1", "issue_tracker", "issues")];
+
+ expect(
+ retainedMcpToolPermissions(
+ { issue_tracker: ["list_issues"], issues: ["create_issue"] },
+ new Set(["server-1"]),
+ catalog,
+ ),
+ ).toEqual({
+ issue_tracker: ["list_issues"],
+ issues: ["create_issue"],
+ });
+ });
+
+ it("does not reload the team when the access group list covers the selection", async () => {
+ const loadTeamGroups = vi.fn();
+ await expect(
+ resolveGrants({
+ accessGroups: [{ access_group_id: "ag-1", access_mcp_server_ids: ["group-server"] }],
+ loadTeamGroups,
+ }),
+ ).resolves.toEqual({
+ kind: "resolved",
+ serverIds: new Set(["server-1", "group-server"]),
+ });
+ expect(loadTeamGroups).not.toHaveBeenCalled();
+ });
+
+ it("falls back to the team's loaded access group servers when the list is unavailable and the selection is unchanged", async () => {
+ expect(
+ await resolveGrants({
+ loadTeamGroups: vi.fn().mockResolvedValue({ ids: ["ag-1"], serverIds: ["group-server"] }),
+ }),
+ ).toEqual({
+ kind: "resolved",
+ serverIds: new Set(["server-1", "group-server"]),
+ });
+ });
+
+ it("adds standing tool-permission grants to the reloaded team grants", async () => {
+ expect(
+ await resolveGrants({
+ effectiveServers: [effective("server-1", "direct"), effective("standing", "toolPermission")],
+ standingServerIds: new Set(["standing"]),
+ loadTeamGroups: vi.fn().mockResolvedValue({ ids: ["ag-1"], serverIds: ["group-server"] }),
+ }),
+ ).toEqual({
+ kind: "resolved",
+ serverIds: new Set(["server-1", "group-server", "standing"]),
+ });
+ });
+
+ it("is unresolvable when the list is unavailable and the selection changed", async () => {
+ expect(
+ await resolveGrants({
+ loadTeamGroups: vi.fn().mockResolvedValue({ ids: ["ag-1", "ag-2"], serverIds: ["group-server"] }),
+ }),
+ ).toEqual({
+ kind: "unresolvable",
+ reason: expect.stringMatching(/access groups could not be loaded/),
+ });
+ });
+
+ it("is unresolvable when the team reload fails", async () => {
+ expect(await resolveGrants({ loadTeamGroups: vi.fn().mockRejectedValue(new Error("boom")) })).toEqual({
+ kind: "unresolvable",
+ reason: expect.stringMatching(/access groups could not be reloaded/),
+ });
+ });
+
+ it("refuses an unresolved selected access group", async () => {
+ expect(
+ await resolveGrants({
+ selectedAccessGroupIds: ["missing"],
+ loadTeamGroups: vi.fn().mockResolvedValue({ ids: [], serverIds: [] }),
+ }),
+ ).toEqual({
+ kind: "unresolvable",
+ reason: expect.stringMatching(/access groups could not be loaded/),
+ });
+ });
+
+ it("retains an unknown permission key so an inventory refresh cannot erase it", () => {
+ expect(retainedMcpToolPermissions({ "not-yet-loaded": ["read"] }, new Set(), [])).toEqual({
+ "not-yet-loaded": ["read"],
+ });
+ });
+
+ it("splits an ambiguous permission across the matching granted server", () => {
+ const catalog = [server("server-1", "shared"), server("server-2", "shared")];
+
+ expect(
+ retainedMcpToolPermissions({ shared: ["read"], "server-1": ["write"] }, new Set(["server-1"]), catalog),
+ ).toEqual({
+ "server-1": ["write", "read"],
+ });
+ });
+
+ it("keeps an ambiguous permission when all matching servers remain granted", () => {
+ const catalog = [server("server-1", "shared"), server("server-2", "shared")];
+
+ expect(retainedMcpToolPermissions({ shared: ["read"] }, new Set(["server-1", "server-2"]), catalog)).toEqual({
+ shared: ["read"],
+ });
+ });
+
+ it("keeps the group server allowlist when the access group list is unavailable and the selection is unchanged", async () => {
+ const user = userEvent.setup({ delay: null });
+ await renderMcpEditor(user);
+
+ await user.clear(screen.getByLabelText("Team Name"));
+ await user.type(screen.getByLabelText("Team Name"), "Renamed Team");
+
+ expect(await saveMcpEditor(user)).toEqual({ wiki: ["read_page"] });
+ });
+
+ it("refuses a save when the access group list is unavailable and the selection changed", async () => {
+ const user = userEvent.setup({ delay: null });
+ await renderMcpEditor(user);
+
+ await user.click(screen.getByRole("button", { name: "remove first unified access group" }));
+ await refuseMcpSave(user, /access groups could not be loaded/);
+ });
+
+ it("keeps the group server allowlist when a selected access group is missing from the list", async () => {
+ const user = userEvent.setup({ delay: null });
+ await renderMcpEditor(user, {
+ accessGroups: [UNIFIED_GROUPS[1]],
+ initialTeam: unifiedTeam({ wiki: ["read_page"] }, ["unified-server"]),
+ });
+
+ expect(await saveMcpEditor(user)).toEqual({ wiki: ["read_page"] });
+ });
+
+ it("uses current group grants when a server was revoked after the page loaded", async () => {
+ const user = userEvent.setup({ delay: null });
+ await renderMcpEditor(user, {
+ initialTeam: unifiedTeam({ wiki: ["read_page"] }, ["unified-server"]),
+ freshTeam: unifiedTeam({ wiki: ["read_page"] }),
+ });
+
+ expect(await saveMcpEditor(user)).toEqual({});
+ });
+
+ it("uses current group grants when a server was granted after the page loaded", async () => {
+ const user = userEvent.setup({ delay: null });
+ await renderMcpEditor(user, {
+ initialTeam: unifiedTeam({ wiki: ["read_page"] }),
+ freshTeam: unifiedTeam({ wiki: ["read_page"] }, ["unified-server"]),
+ });
+
+ expect(await saveMcpEditor(user)).toEqual({ wiki: ["read_page"] });
+ });
+
+ it("keeps a standing allowlist that no group grant covers at load or at save", async () => {
+ const user = userEvent.setup({ delay: null });
+ await renderMcpEditor(user, {
+ initialTeam: unifiedTeam({ wiki: ["read_page"] }),
+ freshTeam: unifiedTeam({ wiki: ["read_page"] }),
+ });
+
+ expect(await saveMcpEditor(user)).toEqual({ wiki: ["read_page"] });
+ });
+
+ it("refuses a save when the access group list is unavailable and the team reload fails", async () => {
+ const user = userEvent.setup({ delay: null });
+ await renderMcpEditor(user);
+ vi.mocked(networking.teamInfoCall).mockRejectedValueOnce(new Error("boom"));
+
+ await refuseMcpSave(user, /access groups could not be reloaded/);
+ });
+
+ it("identifies standing tool-permission grants not covered by loaded access groups", () => {
+ expect(
+ standingToolPermissionServerIds(
+ [effective("a", "toolPermission"), effective("b", "toolPermission"), effective("c", "direct")],
+ ["ag-1"],
+ [{ access_group_id: "ag-1", access_mcp_server_ids: ["b"] }],
+ [],
+ ),
+ ).toEqual(new Set(["a"]));
+ });
+
+ it("does not treat a server granted by the team's loaded access groups as standing", () => {
+ expect(
+ standingToolPermissionServerIds(
+ [effective("a", "toolPermission"), effective("b", "toolPermission")],
+ ["ag-1"],
+ [],
+ ["b"],
+ ),
+ ).toEqual(new Set(["a"]));
+ });
+
+ it("includes standing tool-permission grants in the resolved server ids", async () => {
+ const standingOnly = { effectiveServers: [effective("x", "toolPermission")], selectedAccessGroupIds: [] };
+ expect(await resolveGrants({ ...standingOnly, standingServerIds: new Set(["x"]) })).toEqual({
+ kind: "resolved",
+ serverIds: new Set(["x"]),
+ });
+ expect(await resolveGrants(standingOnly)).toEqual({
+ kind: "resolved",
+ serverIds: new Set(),
+ });
+ });
+
+ it("retains an indirectly granted server on an unrelated team save", async () => {
+ const user = userEvent.setup({ delay: null });
+ const catalog = [server("direct-server", "deploy_tracker"), server("perm-only-server", "issue_tracker")];
+ mockUseMCPServers.mockReturnValue({ data: catalog, isLoading: false, isError: false } as any);
+ mockUseMCPToolsets.mockReturnValue({ data: [], isLoading: false, isError: false } as any);
+ mockUseAccessGroups.mockReturnValue({
+ data: [],
+ isLoading: false,
+ isError: false,
+ } as any);
+ vi.mocked(networking.teamInfoCall).mockResolvedValue(
+ createMockTeamData({
+ models: ["gpt-4"],
+ access_group_ids: [],
+ object_permission: {
+ mcp_servers: ["direct-server"],
+ mcp_access_groups: [],
+ mcp_toolsets: [],
+ mcp_tool_permissions: {
+ "direct-server": ["create_issue"],
+ "perm-only-server": ["list_issues"],
+ },
+ },
+ }),
+ );
+ vi.mocked(networking.teamUpdateCall).mockResolvedValue({ data: {}, team_id: "123" } as any);
+
+ renderWithProviders(
+ ,
+ );
+ await waitFor(() => expect(screen.queryAllByText("Test Team").length).toBeGreaterThan(0));
+ await user.click(screen.getByRole("tab", { name: "Settings" }));
+ await user.click(await screen.findByRole("button", { name: /edit settings/i }));
+ await user.clear(screen.getByLabelText("Team Name"));
+ await user.type(screen.getByLabelText("Team Name"), "Renamed Team");
+ await user.click(screen.getByRole("button", { name: /save changes/i }));
+
+ await waitFor(() => expect(networking.teamUpdateCall).toHaveBeenCalled());
+ const [, payload] = vi.mocked(networking.teamUpdateCall).mock.calls[0];
+ expect(payload.object_permission.mcp_tool_permissions).toEqual({
+ "direct-server": ["create_issue"],
+ "perm-only-server": ["list_issues"],
+ });
+ });
+
+ it("refuses a save with MCP permissions while the server inventory is unavailable", async () => {
+ const user = userEvent.setup({ delay: null });
+ mockUseMCPServers.mockReturnValue({ data: [], isLoading: false, isError: true } as any);
+ vi.mocked(networking.teamInfoCall).mockResolvedValue(
+ createMockTeamData({
+ models: ["gpt-4"],
+ object_permission: {
+ mcp_servers: ["direct-server"],
+ mcp_access_groups: [],
+ mcp_toolsets: [],
+ mcp_tool_permissions: { "direct-server": ["create_issue"] },
+ },
+ }),
+ );
+ vi.mocked(networking.teamUpdateCall).mockResolvedValue({ data: {}, team_id: "123" } as any);
+ const errorToast = vi.spyOn(toast, "fromError").mockImplementation(() => {});
+
+ renderWithProviders(
+ ,
+ );
+ await waitFor(() => expect(screen.queryAllByText("Test Team").length).toBeGreaterThan(0));
+ await user.click(screen.getByRole("tab", { name: "Settings" }));
+ await user.click(await screen.findByRole("button", { name: /edit settings/i }));
+ await user.click(screen.getByRole("button", { name: /save changes/i }));
+
+ await waitFor(() =>
+ expect(errorToast).toHaveBeenCalledWith(expect.stringMatching(/server list could not be loaded/)),
+ );
+ expect(networking.teamUpdateCall).not.toHaveBeenCalled();
+ errorToast.mockRestore();
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/team/TeamInfo.tsx b/ui/litellm-dashboard/src/components/team/TeamInfo.tsx
index 23ecd19fdd7..efd69a79fc0 100644
--- a/ui/litellm-dashboard/src/components/team/TeamInfo.tsx
+++ b/ui/litellm-dashboard/src/components/team/TeamInfo.tsx
@@ -74,6 +74,15 @@ import GuardrailSettingsView from "../GuardrailSettingsView";
import LoggingSettingsView from "../logging_settings_view";
import MCPServerSelector from "../mcp_server_management/MCPServerSelector";
import MCPToolPermissions from "../mcp_server_management/MCPToolPermissions";
+import {
+ mcpServersForIdentifier,
+ resolveEffectiveMcpServers,
+ type EffectiveMcpServer,
+} from "../mcp_server_management/effectiveMcpServers";
+import type { MCPServer } from "../mcp_tools/types";
+import { useMCPServers } from "@/app/(dashboard)/hooks/mcpServers/useMCPServers";
+import { useMCPToolsets } from "@/app/(dashboard)/hooks/mcpServers/useMCPToolsets";
+import { useAccessGroups, type AccessGroupResponse } from "@/app/(dashboard)/hooks/accessGroups/useAccessGroups";
import { ModelSelect } from "../ModelSelect/ModelSelect";
import { estimateChecks, estimateTooltips } from "../templates/estimatedOutputTokens";
import ObjectPermissionsView from "../object_permissions_view";
@@ -118,6 +127,110 @@ const TEAM_MODEL_BADGE_TONES: Record = {
const teamModelBadgeHref = (badge: TeamModelBadge): string | undefined =>
badge.kind === "direct" || badge.kind === "access-group" ? modelGroupHref(badge.label) : undefined;
+export type McpGrantResolution =
+ | { readonly kind: "resolved"; readonly serverIds: ReadonlySet }
+ | { readonly kind: "unresolvable"; readonly reason: string };
+
+export type TeamAccessGroupGrants = {
+ readonly ids: readonly string[];
+ readonly serverIds: readonly string[];
+};
+
+const sameIdSelection = (a: readonly string[], b: readonly string[]): boolean => {
+ const aSet = new Set(a);
+ const bSet = new Set(b);
+ return aSet.size === bSet.size && [...aSet].every((id) => bSet.has(id));
+};
+
+export const standingToolPermissionServerIds = (
+ loadedEffectiveServers: readonly EffectiveMcpServer[],
+ loadedAccessGroupIds: readonly string[],
+ accessGroups: readonly Pick[],
+ loadedTeamGroupServerIds: readonly string[],
+): ReadonlySet => {
+ const loadedUnifiedServerIds = new Set([
+ ...accessGroups
+ .filter((group) => loadedAccessGroupIds.includes(group.access_group_id))
+ .flatMap((group) => group.access_mcp_server_ids),
+ ...loadedTeamGroupServerIds,
+ ]);
+ return new Set(
+ loadedEffectiveServers
+ .filter(({ source, server }) => source.kind === "toolPermission" && !loadedUnifiedServerIds.has(server.server_id))
+ .map(({ server }) => server.server_id),
+ );
+};
+
+export type McpGrantInput = {
+ readonly effectiveServers: readonly EffectiveMcpServer[];
+ readonly selectedAccessGroupIds: readonly string[];
+ readonly accessGroups: readonly Pick[];
+ readonly standingServerIds: ReadonlySet;
+ readonly loadTeamGroups: () => Promise;
+};
+
+export const grantedMcpServerIds = async ({
+ effectiveServers,
+ selectedAccessGroupIds,
+ accessGroups,
+ standingServerIds,
+ loadTeamGroups,
+}: McpGrantInput): Promise => {
+ const selectedGroups = accessGroups.filter((group) => selectedAccessGroupIds.includes(group.access_group_id));
+ const direct = effectiveServers
+ .filter(({ source }) => source.kind !== "toolPermission")
+ .map(({ server }) => server.server_id);
+ if (selectedAccessGroupIds.every((id) => selectedGroups.some((group) => group.access_group_id === id))) {
+ return {
+ kind: "resolved",
+ serverIds: new Set([
+ ...direct,
+ ...selectedGroups.flatMap((group) => group.access_mcp_server_ids),
+ ...standingServerIds,
+ ]),
+ };
+ }
+ const loadedTeamGroups = await loadTeamGroups().catch(() => null);
+ if (loadedTeamGroups === null) {
+ return { kind: "unresolvable", reason: "the team's access groups could not be reloaded" };
+ }
+ if (sameIdSelection(selectedAccessGroupIds, loadedTeamGroups.ids)) {
+ return {
+ kind: "resolved",
+ serverIds: new Set([...direct, ...loadedTeamGroups.serverIds, ...standingServerIds]),
+ };
+ }
+ return { kind: "unresolvable", reason: "the team's access groups could not be loaded" };
+};
+
+export const retainedMcpToolPermissions = (
+ toolPermissions: Record,
+ grantedServerIds: ReadonlySet,
+ knownServers: readonly MCPServer[],
+): Record => {
+ const entries = Object.entries(toolPermissions).flatMap(([key, tools]) => {
+ const named = mcpServersForIdentifier(knownServers, key);
+ const granted = named.filter((server) => grantedServerIds.has(server.server_id));
+ if (named.length === 0 || granted.length === named.length) {
+ return [[key, tools] as const];
+ }
+ if (granted.length === 0) {
+ return [];
+ }
+ return granted.map(({ server_id }) => [server_id, [...(toolPermissions[server_id] ?? []), ...tools]] as const);
+ });
+ return entries.reduce>(
+ (retained, [key, tools]) => ({
+ ...retained,
+ [key]: [...new Set([...(retained[key] ?? []), ...tools])],
+ }),
+ {},
+ );
+};
+
+export const mcpUnresolvableSaveError = (reason: string): string =>
+ `Cannot save MCP tool permissions because ${reason}. Retry once the page has finished loading`;
+
export interface TeamMembership {
user_id: string;
team_id: string;
@@ -442,6 +555,9 @@ const TeamInfoView: React.FC = ({
const routerSettingsRef = React.useRef(null);
const [organization, setOrganization] = useState(null);
const { userRole, userId } = useAuthorized();
+ const { data: allMcpServers = [], isError: mcpServersFailed, isLoading: mcpServersLoading } = useMCPServers();
+ const { data: allMcpToolsets = [], isError: mcpToolsetsFailed, isLoading: mcpToolsetsLoading } = useMCPToolsets();
+ const { data: allAccessGroups = [], isError: accessGroupsFailed, isLoading: accessGroupsLoading } = useAccessGroups();
const canEditTeamEstimates = isProxyAdminRole(userRole);
const teamEstimateTooltip = estimateTooltips(canEditTeamEstimates, "team");
const { data: userOrganizations = [] } = useOrganizations();
@@ -462,6 +578,15 @@ const TeamInfoView: React.FC = ({
const killSwitchOn = form.watch("disable_global_guardrails");
const watchedMcpSelection = form.watch("mcp_servers_and_groups");
const watchedToolPermissions = form.watch("mcp_tool_permissions");
+ const mcpLookupFailure =
+ (
+ [
+ [mcpServersFailed, "the MCP server list could not be loaded"],
+ [mcpToolsetsFailed, "the MCP toolset list could not be loaded"],
+ [accessGroupsFailed, "the access group list could not be loaded"],
+ [mcpServersLoading || mcpToolsetsLoading || accessGroupsLoading, "the MCP server inventory is still loading"],
+ ] as const
+ ).find(([failed]) => failed)?.[1] ?? null;
const availableRateLimitModels = useMemo(() => {
const selected = watchedModels ?? teamData?.team_info?.models ?? [];
if (selected.includes("all-proxy-models") || selected.includes("all-team-models")) {
@@ -837,10 +962,56 @@ const TeamInfoView: React.FC = ({
accessGroups: [],
toolsets: [],
};
- const serverIds = new Set(servers || []);
- const mcpToolPermissions = Object.fromEntries(
- Object.entries(values.mcp_tool_permissions || {}).filter(([serverId]) => serverIds.has(serverId)),
+ const submittedToolPermissions: Record = values.mcp_tool_permissions || {};
+ const effectiveMcpInput = {
+ allServers: allMcpServers,
+ selectedServers: servers || [],
+ selectedAccessGroups: accessGroups || [],
+ selectedToolsets: toolsets || [],
+ toolsets: allMcpToolsets,
+ toolPermissions: submittedToolPermissions,
+ };
+ const loadedObjectPermission = info.object_permission ?? {};
+ const loadedMcpInput = {
+ allServers: allMcpServers,
+ selectedServers: loadedObjectPermission.mcp_servers ?? [],
+ selectedAccessGroups: loadedObjectPermission.mcp_access_groups ?? [],
+ selectedToolsets: loadedObjectPermission.mcp_toolsets ?? [],
+ toolsets: allMcpToolsets,
+ toolPermissions: loadedObjectPermission.mcp_tool_permissions ?? {},
+ };
+ const loadedEffectiveMcpServers = resolveEffectiveMcpServers(loadedMcpInput);
+ const standingServerIds = standingToolPermissionServerIds(
+ loadedEffectiveMcpServers,
+ info.access_group_ids ?? [],
+ allAccessGroups,
+ info.access_group_mcp_server_ids ?? [],
);
+ const mcpGrantInput: McpGrantInput = {
+ effectiveServers: resolveEffectiveMcpServers(effectiveMcpInput),
+ selectedAccessGroupIds: values.access_group_ids || [],
+ accessGroups: allAccessGroups,
+ standingServerIds,
+ loadTeamGroups: async () => {
+ const teamInfo = await teamInfoCall(accessToken, teamId);
+ return {
+ ids: teamInfo.team_info.access_group_ids ?? [],
+ serverIds: teamInfo.team_info.access_group_mcp_server_ids ?? [],
+ };
+ },
+ };
+ const mcpResolution: McpGrantResolution =
+ mcpLookupFailure !== null
+ ? { kind: "unresolvable", reason: mcpLookupFailure }
+ : await grantedMcpServerIds(mcpGrantInput);
+ if (mcpResolution.kind === "unresolvable" && Object.keys(submittedToolPermissions).length > 0) {
+ toast.fromError(mcpUnresolvableSaveError(mcpResolution.reason));
+ return;
+ }
+ const mcpToolPermissions =
+ mcpResolution.kind === "resolved"
+ ? retainedMcpToolPermissions(submittedToolPermissions, mcpResolution.serverIds, allMcpServers)
+ : submittedToolPermissions;
updateData.object_permission = {};
if (servers) {
@@ -1629,6 +1800,8 @@ const TeamInfoView: React.FC = ({
form.setValue("mcp_tool_permissions", toolPerms)}
/>
diff --git a/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx b/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx
index 9edfba4b981..0f955fee895 100644
--- a/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx
+++ b/ui/litellm-dashboard/src/components/templates/key_edit_view.tsx
@@ -54,7 +54,6 @@ import {
import { excludeProxyWideSentinel, hasAllModelsSentinel } from "../key_team_helpers/fetch_available_models_team_key";
import { KeyResponse } from "../key_team_helpers/key_list";
import MCPServerSelector from "../mcp_server_management/MCPServerSelector";
-import { NO_MCP_SERVERS_SENTINEL } from "../mcp_tools/constants";
import MCPToolPermissions from "../mcp_server_management/MCPToolPermissions";
import { toast } from "@/lib/toast";
import { getPromptsList, modelAvailableCall, tagListCall } from "../networking";
@@ -138,7 +137,9 @@ export function KeyEditView({
const selectedModels = (form.watch("models") as string[] | undefined) ?? [];
const allowedRoutes = parseAllowedRoutes(allowedRoutesValue);
const isModelsDisabled = allowedRoutes.includes("management_routes") || allowedRoutes.includes("info_routes");
- const mcpServersAndGroups = form.watch("mcp_servers_and_groups");
+ const mcpSelection = form.watch("mcp_servers_and_groups") as
+ | { servers?: string[]; accessGroups?: string[]; toolsets?: string[] }
+ | undefined;
const mcpToolPermissions = form.watch("mcp_tool_permissions");
useEffect(() => {
@@ -751,9 +752,9 @@ export function KeyEditView({
s !== NO_MCP_SERVERS_SENTINEL,
- )}
+ selectedServers={mcpSelection?.servers || []}
+ selectedAccessGroups={mcpSelection?.accessGroups || []}
+ selectedToolsets={mcpSelection?.toolsets || []}
toolPermissions={(mcpToolPermissions as Record | undefined) || {}}
onChange={(toolPerms) => form.setValue("mcp_tool_permissions", toolPerms)}
/>
From b55a4317a655a1ad3e653380c328c5d66cf3d512 Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 14:49:56 -0700
Subject: [PATCH 22/35] test(e2e): annotate new stream-timing locals as Final
and trim the docstrings
---
tests/e2e/e2e_http.py | 9 +++-----
.../e2e/llm_translation/test_messages_e2e.py | 21 +++++++++----------
.../llm_translation/test_together_ai_e2e.py | 6 +++---
tests/e2e/test_e2e_http.py | 11 +++++-----
4 files changed, 22 insertions(+), 25 deletions(-)
diff --git a/tests/e2e/e2e_http.py b/tests/e2e/e2e_http.py
index 3a4e69cfb43..be5e55f8edc 100644
--- a/tests/e2e/e2e_http.py
+++ b/tests/e2e/e2e_http.py
@@ -132,12 +132,9 @@ class StreamingResponse(BaseModel):
non-streaming `application/json`), the response headers (lowercased names, e.g.
the x-ratelimit-* pacing headers and retry-after on a 429), and the body.
SpendLogs.request_id is the completion body id, not call_id. Used by passthrough
- and streaming, where one validated JSON model does not fit.
-
- ``stream_event_arrivals`` is index-aligned with ``stream_events`` and holds the
- seconds after the request was sent at which each event reached the client, so a
- test can tell a relayed stream (events spread over the provider's generation time)
- from a buffered one (every event in one burst at the end)."""
+ and streaming, where one validated JSON model does not fit. ``stream_event_arrivals``
+ is index-aligned with ``stream_events``: seconds after the request was sent at which
+ each event reached the client."""
status_code: int
call_id: str | None = None # x-litellm-call-id header
diff --git a/tests/e2e/llm_translation/test_messages_e2e.py b/tests/e2e/llm_translation/test_messages_e2e.py
index 1227b1c7119..c731b52acd8 100644
--- a/tests/e2e/llm_translation/test_messages_e2e.py
+++ b/tests/e2e/llm_translation/test_messages_e2e.py
@@ -8,6 +8,8 @@ litellm-regression-tests/tests/test_inference_endpoints.py.
from __future__ import annotations
+from typing import Final
+
import pytest
from e2e_config import (
STREAM_MIN_LEAD_SECONDS,
@@ -164,15 +166,12 @@ class TestAnthropicMessages:
"""Edge-wired like its non-streaming siblings, so record and replay both
carry the streamed response.
- Asserts what the proxy controls. The event grammar arrives intact: the usage
- event sits between the last content delta and ``message_stop``. And the relay
- is incremental, judged on the clock rather than by counting deltas: how many
- deltas a reply is split into is the provider's choice (Haiku often sends a
- 20-line count as one), so a count threshold flaked on provider variance. A
- reply that takes seconds to generate must reach the client with its first
- delta well before ``message_stop``; a proxy that buffered would deliver every
- event in one burst. Replay hands the proxy its recorded chunks back to back,
- so only live and record runs can judge the timing."""
+ Asserts what the proxy controls: the event grammar (usage between the last
+ content delta and ``message_stop``) and, on the clock, that the relay is
+ incremental. How many deltas a reply is split into is the provider's choice, so
+ the first content delta must instead reach the client well before
+ ``message_stop``, which a buffered response cannot do. Replay serves chunks back
+ to back, so only live and record runs judge the timing."""
model, key = self._register(endpoints_client, resources)
result = endpoints_client.proxy.messages_stream(
@@ -216,8 +215,8 @@ class TestAnthropicMessages:
f"usage did not land between the last content delta and message_stop: {types}"
)
- first_delta_at = result.stream_event_arrivals[delta_positions[0]]
- stop_at = result.stream_event_arrivals[stop_position]
+ first_delta_at: Final = result.stream_event_arrivals[delta_positions[0]]
+ stop_at: Final = result.stream_event_arrivals[stop_position]
if provider_paces_stream():
assert stop_at - first_delta_at >= STREAM_MIN_LEAD_SECONDS, (
f"first content delta reached the client {first_delta_at:.2f}s after the request "
diff --git a/tests/e2e/llm_translation/test_together_ai_e2e.py b/tests/e2e/llm_translation/test_together_ai_e2e.py
index 26daf9040e0..31e74c22e17 100644
--- a/tests/e2e/llm_translation/test_together_ai_e2e.py
+++ b/tests/e2e/llm_translation/test_together_ai_e2e.py
@@ -775,9 +775,9 @@ class TestTogetherMessages:
assert "200" in text, f"streamed text lost the answer: {text[:300]!r}"
assert "message_stop" in types, f"stream never reached message_stop: {types}"
- stop_position = types.index("message_stop")
- first_delta_at = result.stream_event_arrivals[delta_positions[0]]
- stop_at = result.stream_event_arrivals[stop_position]
+ stop_position: Final = types.index("message_stop")
+ first_delta_at: Final = result.stream_event_arrivals[delta_positions[0]]
+ stop_at: Final = result.stream_event_arrivals[stop_position]
if provider_paces_stream():
assert stop_at - first_delta_at >= STREAM_MIN_LEAD_SECONDS, (
f"first content delta reached the client {first_delta_at:.2f}s after the request "
diff --git a/tests/e2e/test_e2e_http.py b/tests/e2e/test_e2e_http.py
index dc92e31fc5c..66841725d1d 100644
--- a/tests/e2e/test_e2e_http.py
+++ b/tests/e2e/test_e2e_http.py
@@ -15,6 +15,7 @@ from __future__ import annotations
from collections.abc import Callable, Iterator, Mapping, Sequence
from dataclasses import dataclass, field
from types import MappingProxyType
+from typing import Final
import pytest
@@ -95,13 +96,13 @@ class FakeSseResponse:
def _ticking_clock(start: float, step: float) -> Callable[[], float]:
- ticks = iter(range(10_000))
+ ticks: Final = iter(range(10_000))
return lambda: start + step * next(ticks)
class TestStreamEventArrivals:
def test_each_event_is_stamped_at_the_moment_its_line_arrives(self) -> None:
- resp = FakeSseResponse(
+ resp: Final = FakeSseResponse(
lines=(
b"event: message_start",
b'data: {"type":"message_start"}',
@@ -114,7 +115,7 @@ class TestStreamEventArrivals:
)
)
- result = streaming_outcome(resp, True, sent_at=100.0, clock=_ticking_clock(start=100.0, step=0.5))
+ result: Final = streaming_outcome(resp, True, sent_at=100.0, clock=_ticking_clock(start=100.0, step=0.5))
assert result.stream_events == [
'{"type":"message_start"}',
@@ -126,9 +127,9 @@ class TestStreamEventArrivals:
assert result.chunks == 7
def test_a_non_streaming_outcome_carries_no_arrivals(self) -> None:
- resp = FakeSseResponse(lines=(), status_code=400, text="bad request")
+ resp: Final = FakeSseResponse(lines=(), status_code=400, text="bad request")
- result = streaming_outcome(resp, True, sent_at=0.0, clock=_ticking_clock(start=0.0, step=1.0))
+ result: Final = streaming_outcome(resp, True, sent_at=0.0, clock=_ticking_clock(start=0.0, step=1.0))
assert result.stream_events == []
assert result.stream_event_arrivals == []
From cd976624d1c7d8c220f94987cc61b6d089b241e2 Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 14:53:12 -0700
Subject: [PATCH 23/35] test(e2e): drop the explanatory sentence from the
StreamingResponse docstring
---
tests/e2e/e2e_http.py | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/tests/e2e/e2e_http.py b/tests/e2e/e2e_http.py
index be5e55f8edc..9d5f1658e91 100644
--- a/tests/e2e/e2e_http.py
+++ b/tests/e2e/e2e_http.py
@@ -132,9 +132,7 @@ class StreamingResponse(BaseModel):
non-streaming `application/json`), the response headers (lowercased names, e.g.
the x-ratelimit-* pacing headers and retry-after on a 429), and the body.
SpendLogs.request_id is the completion body id, not call_id. Used by passthrough
- and streaming, where one validated JSON model does not fit. ``stream_event_arrivals``
- is index-aligned with ``stream_events``: seconds after the request was sent at which
- each event reached the client."""
+ and streaming, where one validated JSON model does not fit."""
status_code: int
call_id: str | None = None # x-litellm-call-id header
From acddd21860468c3eb72d12fbddc330d7758076dd Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Sat, 5 Sep 2026 15:32:02 -0700
Subject: [PATCH 24/35] fix(proxy): keep guardrail cost in spend on cache hits
The proxy cost callback zeroed response_cost whenever cache_hit was true. That rule dates from Jan 2024 when it was the only place cache hits were priced. The logging layer has priced the LLM share at 0 on a cache hit since Aug 2024, and since guardrail cost joined the standard logging payload the proxy-side zeroing has thrown away a real provider charge: a pre_call guardrail runs before the cache is consulted, so a cached response still cost whatever the guardrail billed. Drop the redundant zeroing so the payload's response_cost, which is already LLM 0 + guardrail cost, reaches spend logs, daily tables and budgets untouched
Claude-Session: https://claude.ai/code/session_01EX13mWex6RaBo9PYnkAtFW
---
.../proxy/hooks/proxy_track_cost_callback.py | 6 +--
.../hooks/test_proxy_track_cost_callback.py | 47 +++++++++++++++++++
2 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/litellm/proxy/hooks/proxy_track_cost_callback.py b/litellm/proxy/hooks/proxy_track_cost_callback.py
index 7254b05db2e..d6276c03155 100644
--- a/litellm/proxy/hooks/proxy_track_cost_callback.py
+++ b/litellm/proxy/hooks/proxy_track_cost_callback.py
@@ -254,7 +254,7 @@ class _ProxyDBLogger(CustomLogger):
key_alias: Final = cast(str | None, metadata.get("user_api_key_alias", None))
end_user_max_budget: Final = metadata.get("user_api_end_user_max_budget", None)
sl_object: Final[StandardLoggingPayload | None] = kwargs.get("standard_logging_object", None)
- response_cost = (
+ response_cost: Final = (
sl_object.get("response_cost", None) if sl_object is not None else kwargs.get("response_cost", None)
)
tags: Final = _get_request_tags_for_cost_tracking(
@@ -269,10 +269,6 @@ class _ProxyDBLogger(CustomLogger):
if response_cost is not None:
user_api_key: Final = metadata.get("user_api_key", None)
- if kwargs.get("cache_hit", False) is True:
- response_cost = 0.0
- verbose_proxy_logger.debug("Cache Hit: response_cost %s, for user_id %s", response_cost, user_id)
-
verbose_proxy_logger.debug(
"user_api_key %s, user_id %s, team_id %s, end_user_id %s",
user_api_key,
diff --git a/tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py b/tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py
index 8043a1aca3f..4e6e3bb458d 100644
--- a/tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py
+++ b/tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py
@@ -1783,6 +1783,53 @@ async def test_track_cost_callback_enriches_user_id_for_mcp_style_metadata():
)
+@pytest.mark.asyncio
+async def test_track_cost_callback_keeps_guardrail_cost_on_cache_hit():
+ """A cache hit skips the LLM, not the guardrail that screened the prompt, so the
+ guardrail's provider charge must still reach spend logs and budgets. The payload
+ already prices the LLM share at 0 on a cache hit, so its response_cost is the
+ guardrail cost alone and the callback must pass it through untouched."""
+ logger = _ProxyDBLogger()
+ kwargs = {
+ "call_type": "acompletion",
+ "model": "gpt-4o",
+ "cache_hit": True,
+ "response_cost": 0.0,
+ "litellm_params": {
+ "metadata": {
+ "user_api_key": "hashed-key",
+ "user_api_key_user_id": "user-1",
+ "user_api_key_team_id": "team-1",
+ }
+ },
+ "standard_logging_object": {
+ "response_cost": 0.0003,
+ "request_tags": [],
+ "metadata": {},
+ "cost_breakdown": {"guardrail_cost": 0.0003, "total_cost": 0.0003},
+ },
+ }
+
+ with (
+ patch("litellm.proxy.proxy_server.increment_spend_counters", new_callable=AsyncMock) as mock_increment,
+ patch("litellm.proxy.proxy_server.update_cache", new_callable=AsyncMock),
+ patch("litellm.proxy.proxy_server.proxy_logging_obj") as mock_proxy_logging,
+ ):
+ mock_proxy_logging.db_spend_update_writer.update_database = AsyncMock()
+ mock_proxy_logging.slack_alerting_instance.customer_spend_alert = AsyncMock()
+
+ await logger._PROXY_track_cost_callback(
+ kwargs=kwargs,
+ completion_response={"id": "cached-call-1"},
+ start_time=datetime.now(),
+ end_time=datetime.now(),
+ )
+
+ update_kwargs = mock_proxy_logging.db_spend_update_writer.update_database.await_args.kwargs
+ assert update_kwargs["response_cost"] == pytest.approx(0.0003)
+ assert mock_increment.call_args.kwargs["response_cost"] == pytest.approx(0.0003)
+
+
@pytest.mark.parametrize(
"call_type, expected",
[
From 63156a7bd61e1a7ecd7f5b95ea2bbd9ee2a9c286 Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Sat, 5 Sep 2026 15:44:37 -0700
Subject: [PATCH 25/35] test(proxy): explain the proxy_server patches in the
cache-hit regression test
The test-quality gate counts every patch of a litellm internal against a ceiling, and the three patches this test needs pushed it over. The callback imports increment_spend_counters, update_cache and proxy_logging_obj from proxy_server inside its own body, so there is no seam to inject fakes through; every other test in this file uses the same three patches for the same reason
Claude-Session: https://claude.ai/code/session_01EX13mWex6RaBo9PYnkAtFW
---
.../proxy/hooks/test_proxy_track_cost_callback.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py b/tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py
index 4e6e3bb458d..f3fd9f41cc2 100644
--- a/tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py
+++ b/tests/test_litellm/proxy/hooks/test_proxy_track_cost_callback.py
@@ -1811,9 +1811,9 @@ async def test_track_cost_callback_keeps_guardrail_cost_on_cache_hit():
}
with (
- patch("litellm.proxy.proxy_server.increment_spend_counters", new_callable=AsyncMock) as mock_increment,
- patch("litellm.proxy.proxy_server.update_cache", new_callable=AsyncMock),
- patch("litellm.proxy.proxy_server.proxy_logging_obj") as mock_proxy_logging,
+ patch("litellm.proxy.proxy_server.increment_spend_counters", new_callable=AsyncMock) as mock_increment, # test-quality-ok: the callback imports this from proxy_server inside its body, so there is no injection seam
+ patch("litellm.proxy.proxy_server.update_cache", new_callable=AsyncMock), # test-quality-ok: same function-body import, no injection seam
+ patch("litellm.proxy.proxy_server.proxy_logging_obj") as mock_proxy_logging, # test-quality-ok: same function-body import, no injection seam
):
mock_proxy_logging.db_spend_update_writer.update_database = AsyncMock()
mock_proxy_logging.slack_alerting_instance.customer_spend_alert = AsyncMock()
From 4ec5a6761c014ab4b3316d25a469b234b5e88876 Mon Sep 17 00:00:00 2001
From: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Date: Sat, 5 Sep 2026 15:58:33 -0700
Subject: [PATCH 26/35] fix(proxy): redact provider keys from pass-through
failure tracebacks
A failed pass-through call logged the httpx traceback, whose message
quotes the upstream URL with the provider API key in its query string,
into the spend log's error information and into every failure callback.
The error information built for logging now redacts its traceback and
error message, and the traceback is redacted once before the failure
callbacks receive it.
---
litellm/litellm_core_utils/litellm_logging.py | 4 +-
litellm/proxy/utils.py | 4 +-
.../test_litellm_logging.py | 29 +++++++++++
tests/test_litellm/proxy/test_proxy_utils.py | 49 +++++++++++++++++++
4 files changed, 83 insertions(+), 3 deletions(-)
diff --git a/litellm/litellm_core_utils/litellm_logging.py b/litellm/litellm_core_utils/litellm_logging.py
index c31c4323157..989777e9412 100644
--- a/litellm/litellm_core_utils/litellm_logging.py
+++ b/litellm/litellm_core_utils/litellm_logging.py
@@ -5675,8 +5675,8 @@ class StandardLoggingPayloadSetup:
error_code=error_status,
error_class=error_class,
llm_provider=_llm_provider_in_exception,
- traceback=traceback_info,
- error_message=error_message,
+ traceback=_redact_string(traceback_info),
+ error_message=_redact_string(error_message),
error_rate_limit_category=rate_limit_category,
error_rate_limit_type=rate_limit_type,
error_budget_entity_type=budget_error.entity_type if budget_error else None,
diff --git a/litellm/proxy/utils.py b/litellm/proxy/utils.py
index accf7b720fb..b4e4dfeae67 100644
--- a/litellm/proxy/utils.py
+++ b/litellm/proxy/utils.py
@@ -2568,6 +2568,8 @@ class ProxyLogging:
# Remove before callbacks iterate — not serialisable
request_data.pop("litellm_logging_obj", None)
+ redacted_traceback_str: Final = _redact_string(traceback_str) if traceback_str is not None else None
+
# Track the first HTTPException returned or raised by any callback
transformed_exception: HTTPException | None = None
@@ -2586,7 +2588,7 @@ class ProxyLogging:
request_data=request_data,
user_api_key_dict=user_api_key_dict,
original_exception=original_exception,
- traceback_str=traceback_str,
+ traceback_str=redacted_traceback_str,
)
# If callback returned an HTTPException, use it (first one wins)
if isinstance(hook_result, HTTPException) and transformed_exception is None:
diff --git a/tests/test_litellm/litellm_core_utils/test_litellm_logging.py b/tests/test_litellm/litellm_core_utils/test_litellm_logging.py
index 16a99713a06..0f44cbbb2a7 100644
--- a/tests/test_litellm/litellm_core_utils/test_litellm_logging.py
+++ b/tests/test_litellm/litellm_core_utils/test_litellm_logging.py
@@ -6457,3 +6457,32 @@ def test_get_status_fields_ranks_guardrail_flagged_between_success_and_intervene
assert _get_status_fields(
"success", [flagged, {"guardrail_status": "guardrail_intervened"}], None
)["guardrail_status"] == "guardrail_intervened"
+
+
+def test_get_error_information_redacts_provider_key_from_upstream_url():
+ """A pass-through upstream failure logs the httpx traceback, whose message
+ quotes the upstream URL with the provider key in its query string. That
+ key must never reach spend logs or logging callbacks."""
+ import traceback
+
+ from litellm.litellm_core_utils.litellm_logging import StandardLoggingPayloadSetup
+
+ provider_key = "AIza" + "S" * 35
+ upstream_url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini:generateContent?key={provider_key}"
+ response = httpx.Response(400, request=httpx.Request("POST", upstream_url))
+ try:
+ response.raise_for_status()
+ except httpx.HTTPStatusError as caught:
+ upstream_error = caught
+ upstream_traceback = traceback.format_exc()
+ assert provider_key in upstream_traceback
+
+ result = StandardLoggingPayloadSetup.get_error_information(
+ original_exception=upstream_error, traceback_str=upstream_traceback
+ )
+
+ assert provider_key not in result["traceback"]
+ assert provider_key not in result["error_message"]
+ assert "REDACTED" in result["traceback"]
+ assert "REDACTED" in result["error_message"]
+ assert result["error_code"] == "400"
diff --git a/tests/test_litellm/proxy/test_proxy_utils.py b/tests/test_litellm/proxy/test_proxy_utils.py
index f16c6c937d0..51176c2b251 100644
--- a/tests/test_litellm/proxy/test_proxy_utils.py
+++ b/tests/test_litellm/proxy/test_proxy_utils.py
@@ -6,6 +6,7 @@ from fastapi import HTTPException
from litellm.caching.caching import DualCache
from litellm.integrations.custom_guardrail import CustomGuardrail
+from litellm.integrations.custom_logger import CustomLogger
from litellm.proxy._types import ProxyErrorTypes
from litellm.proxy.utils import ProxyLogging
from litellm.types.guardrails import GuardrailEventHooks
@@ -1919,3 +1920,51 @@ async def test_proxy_only_error_5xx_keeps_traceback_and_runs_sync_callbacks(monk
Logging.failure_handler = orig_sync_failure
assert "test_proxy_utils" in captured["async_traceback"]
+
+
+class _TracebackRecordingLogger(CustomLogger):
+ def __init__(self):
+ super().__init__()
+ self.received_traceback: str | None = None
+
+ async def async_post_call_failure_hook(self, request_data, original_exception, user_api_key_dict, traceback_str=None):
+ self.received_traceback = traceback_str
+ return None
+
+
+@pytest.mark.asyncio
+async def test_post_call_failure_hook_redacts_traceback_before_callbacks(monkeypatch):
+ """A pass-through upstream failure hands the hook the httpx traceback, whose
+ message quotes the upstream URL with the provider key in its query string.
+ Every callback, custom loggers included, must receive it redacted."""
+ import traceback
+ from unittest.mock import AsyncMock, patch
+
+ import httpx
+
+ from litellm.proxy._types import UserAPIKeyAuth
+
+ provider_key = "AIza" + "S" * 35
+ upstream_url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini:generateContent?key={provider_key}"
+ response = httpx.Response(400, request=httpx.Request("POST", upstream_url))
+ try:
+ response.raise_for_status()
+ except httpx.HTTPStatusError:
+ upstream_traceback = traceback.format_exc()
+ assert provider_key in upstream_traceback
+
+ recorder = _TracebackRecordingLogger()
+ monkeypatch.setattr(litellm, "callbacks", [recorder])
+ proxy_logging_obj = ProxyLogging(user_api_key_cache=DualCache())
+ proxy_logging_obj.alert_types = []
+ with patch.object(proxy_logging_obj, "update_request_status", new=AsyncMock()):
+ await proxy_logging_obj.post_call_failure_hook(
+ request_data={"metadata": {}},
+ original_exception=HTTPException(status_code=400, detail="Upstream passthrough request failed with status 400"),
+ user_api_key_dict=UserAPIKeyAuth(),
+ traceback_str=upstream_traceback,
+ )
+
+ assert recorder.received_traceback is not None
+ assert provider_key not in recorder.received_traceback
+ assert "REDACTED" in recorder.received_traceback
From 79a5614c185de496df4728cafee99aa2658f6afc Mon Sep 17 00:00:00 2001
From: ryan-crabbe-berri
Date: Sat, 5 Sep 2026 16:04:50 -0700
Subject: [PATCH 27/35] fix(ui): remove unreachable AI Hub dialog that put the
session key in a URL
The Public Model Hub dialog in ModelHubTable was never opened (its open setter had no callers), but its See Page button navigated to /model_hub_table?key=. Delete the dialog, its state, the handler and the unused router import so the path cannot be revived.
---
.../src/components/AIHub/ModelHubTable.tsx | 29 -------------------
1 file changed, 29 deletions(-)
diff --git a/ui/litellm-dashboard/src/components/AIHub/ModelHubTable.tsx b/ui/litellm-dashboard/src/components/AIHub/ModelHubTable.tsx
index 7f349fa29ba..634adc6fba8 100644
--- a/ui/litellm-dashboard/src/components/AIHub/ModelHubTable.tsx
+++ b/ui/litellm-dashboard/src/components/AIHub/ModelHubTable.tsx
@@ -32,7 +32,6 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/u
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from "@/components/ui/input-group";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Copy, Inbox, Search as SearchIcon, X } from "lucide-react";
-import { useRouter } from "next/navigation";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { prism } from "react-syntax-highlighter/dist/esm/styles/prism";
@@ -72,7 +71,6 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage,
const [modelHubData, setModelHubData] = useState(null);
const [loading, setLoading] = useState(true);
const [isModalVisible, setIsModalVisible] = useState(false);
- const [isPublicPageModalVisible, setIsPublicPageModalVisible] = useState(false);
const [selectedModel, setSelectedModel] = useState(null);
const [filteredData, setFilteredData] = useState([]);
const [isMakePublicModalVisible, setIsMakePublicModalVisible] = useState(false);
@@ -93,7 +91,6 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage,
const [skillHubData, setSkillHubData] = useState([]);
const [skillLoading, setSkillLoading] = useState(false);
const [isMakeSkillPublicModalVisible, setIsMakeSkillPublicModalVisible] = useState(false);
- const router = useRouter();
const { data: uiSettings, isLoading: isUISettingsLoading } = useUISettings();
// Check authentication requirement for public AI Hub
@@ -256,10 +253,6 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage,
setIsMcpModalVisible(true);
}, []);
- const goToPublicModelPage = () => {
- router.replace(`/model_hub_table?key=${accessToken}`);
- };
-
const handleMakePublicPage = () => {
if (!accessToken) {
return;
@@ -289,7 +282,6 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage,
const handleOk = () => {
setIsModalVisible(false);
- setIsPublicPageModalVisible(false);
setSelectedModel(null);
setIsAgentModalVisible(false);
setSelectedAgent(null);
@@ -299,7 +291,6 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage,
const handleCancel = () => {
setIsModalVisible(false);
- setIsPublicPageModalVisible(false);
setSelectedModel(null);
setIsAgentModalVisible(false);
setSelectedAgent(null);
@@ -639,26 +630,6 @@ const ModelHubTable: React.FC = ({ accessToken, publicPage,
)}
- {/* Public Page Modal */}
- !open && handleCancel()}>
-
-
- {"Public Model Hub"}
-
-
-
-
Shareable Link:
-
- {`${getProxyBaseUrl()}/ui/model_hub_table`}
-
-
-
- See Page
-
-
-
-
-
{/* Model Details Modal */}
!open && handleCancel()}>
From 45cf1a7ef14ed77a10bdede74191fa8d704d6b4c Mon Sep 17 00:00:00 2001
From: yuneng-jiang
Date: Sat, 5 Sep 2026 16:07:09 -0700
Subject: [PATCH 28/35] =?UTF-8?q?Revert=20"perf:=20lazy-load=20SDK=20symbo?=
=?UTF-8?q?ls=20so=20import=20litellm=20stays=20under=2060=20MB=20RSS=20(?=
=?UTF-8?q?=E2=80=A6"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit c091dd46087bc3a40f18ab0bc48dc08a2b0552a8.
---
litellm/__init__.py | 410 ++--
litellm/_lazy_imports.py | 96 +-
litellm/_lazy_imports_registry.py | 2693 -----------------------
litellm/proxy/__init__.py | 12 +-
tests/test_litellm/test_lazy_imports.py | 87 -
5 files changed, 203 insertions(+), 3095 deletions(-)
diff --git a/litellm/__init__.py b/litellm/__init__.py
index b2bf3f09152..42c0ea881fd 100644
--- a/litellm/__init__.py
+++ b/litellm/__init__.py
@@ -13,7 +13,6 @@ warnings.filterwarnings("ignore", message=".*`ReadOnly` qualifier.*")
### INIT VARIABLES #########################
import threading
import os
-import sys
# Load .env before any other litellm imports so env vars (e.g. LITELLM_UI_SESSION_DURATION) are available
import dotenv as _dotenv
@@ -46,6 +45,8 @@ from typing import (
TYPE_CHECKING,
Union,
)
+from litellm.types.integrations.datadog import DatadogInitParams
+from litellm.types.integrations.newrelic import NewRelicInitParams
from litellm._logging import (
set_verbose,
_turn_on_debug,
@@ -94,7 +95,8 @@ from litellm.constants import (
DEFAULT_SOFT_BUDGET,
DEFAULT_ALLOWED_FAILS,
)
-# httpx is lazy-loaded via __getattr__
+import httpx
+
# register_async_client_cleanup is lazy-loaded and called on first access
litellm_mode = os.getenv("LITELLM_MODE", "DEV") # "PRODUCTION", "DEV"
@@ -362,6 +364,8 @@ guardrail_name_config_map: Dict[str, GuardrailItem] = {}
include_cost_in_streaming_usage: bool = False
reasoning_auto_summary: bool = False
### PROMPTS ####
+from litellm.types.prompts.init_prompts import PromptSpec
+
prompt_name_config_map: Dict[str, PromptSpec] = {}
##################
@@ -1267,203 +1271,206 @@ openai_video_generation_models = ["sora-2"]
# get_llm_provider is lazy-loaded via __getattr__
# remove_index_from_tool_calls is lazy-loaded via __getattr__
-# SDK symbols previously imported eagerly here are lazy-loaded via __getattr__
-# (_SDK_SYMBOLS_IMPORT_MAP in _lazy_imports_registry.py); mirrored under TYPE_CHECKING
-# so static type checkers still see them
-if TYPE_CHECKING:
- _key_management_settings: KeyManagementSettings
+# Import KeyManagementSettings here (before utils import) because _key_management_settings
+# is accessed during import time in secret_managers/main.py (via dd_tracing -> datadog -> _service_logger -> utils)
+from litellm.types.secret_managers.main import KeyManagementSettings
- from .utils import client
+_key_management_settings: KeyManagementSettings = KeyManagementSettings()
- from .llms.custom_llm import CustomLLM
- from .llms.anthropic.common_utils import AnthropicModelInfo
- from .llms.ai21.chat.transformation import AI21ChatConfig, AI21ChatConfig as AI21Config
- from .llms.deprecated_providers.palm import (
- PalmConfig,
- ) # here to prevent breaking changes
- from .llms.deprecated_providers.aleph_alpha import AlephAlphaConfig
- from .llms.gemini.common_utils import GeminiModelInfo
+# client must be imported immediately as it's used as a decorator at function definition time
+from .utils import client
- from .llms.vertex_ai.vertex_embeddings.transformation import (
- VertexAITextEmbeddingConfig,
- )
+# Note: Most other utils imports are lazy-loaded via __getattr__ to avoid loading utils.py
+# (which imports tiktoken) at import time
- vertexAITextEmbeddingConfig = VertexAITextEmbeddingConfig()
+from .llms.custom_llm import CustomLLM
+from .llms.anthropic.common_utils import AnthropicModelInfo
+from .llms.ai21.chat.transformation import AI21ChatConfig, AI21ChatConfig as AI21Config
+from .llms.deprecated_providers.palm import (
+ PalmConfig,
+) # here to prevent breaking changes
+from .llms.deprecated_providers.aleph_alpha import AlephAlphaConfig
+from .llms.gemini.common_utils import GeminiModelInfo
- from .llms.bedrock.embed.amazon_titan_v2_transformation import (
- AmazonTitanV2Config,
- )
- from .llms.topaz.common_utils import TopazModelInfo
- # OpenAIOSeriesConfig is lazy loaded - openaiOSeriesConfig will be created on first access
- # OpenAIGPTConfig, OpenAIGPT5Config, etc. are lazy loaded - instances will be created on first access
- from .llms.xai.common_utils import XAIModelInfo
+from .llms.vertex_ai.vertex_embeddings.transformation import (
+ VertexAITextEmbeddingConfig,
+)
- # PublicAI now uses JSON-based configuration (see litellm/llms/openai_like/providers.json)
- # All remaining configs are now lazy loaded - see _lazy_imports_registry.py
+vertexAITextEmbeddingConfig = VertexAITextEmbeddingConfig()
- # Import LlmProviders here (before main import) because it's imported during import time
- # in multiple places including openai.py (via main import)
- ## Lazy loading this is not straightforward, will leave it here for now.
- from .main import *
- from .compression import compress
+from .llms.bedrock.embed.amazon_titan_v2_transformation import (
+ AmazonTitanV2Config,
+)
+from .llms.topaz.common_utils import TopazModelInfo
- # Skills API
- from .skills.main import (
- create_skill,
- acreate_skill,
- list_skills,
- alist_skills,
- get_skill,
- aget_skill,
- delete_skill,
- adelete_skill,
- )
- from .evals.main import (
- create_eval,
- acreate_eval,
- list_evals,
- alist_evals,
- get_eval,
- aget_eval,
- delete_eval,
- adelete_eval,
- cancel_eval,
- acancel_eval,
- create_run,
- acreate_run,
- list_runs,
- alist_runs,
- get_run,
- aget_run,
- delete_run,
- adelete_run,
- cancel_run,
- acancel_run,
- )
- from .integrations import *
- from .llms.custom_httpx.async_client_cleanup import close_litellm_async_clients
- from .exceptions import (
- AuthenticationError,
- InvalidRequestError,
- BadRequestError,
- ImageFetchError,
- NotFoundError,
- PermissionDeniedError,
- RateLimitError,
- RateLimitErrorCategory,
- RateLimitType,
- ServiceUnavailableError,
- BadGatewayError,
- OpenAIError,
- ContextWindowExceededError,
- ContentPolicyViolationError,
- BudgetExceededError,
- APIError,
- Timeout,
- APIConnectionError,
- UnsupportedParamsError,
- APIResponseValidationError,
- UnprocessableEntityError,
- InternalServerError,
- JSONSchemaValidationError,
- LITELLM_EXCEPTION_TYPES,
- MockException,
- )
- from .budget_manager import BudgetManager
- from .proxy.proxy_cli import run_server
- from .router import Router
- from .assistants.main import *
- from .batches.main import *
- from .images.main import *
- from .videos.main import *
- from .batch_completion.main import *
- from .rerank_api.main import *
- from .llms.anthropic.experimental_pass_through.messages.handler import *
- from .responses.main import *
+# OpenAIOSeriesConfig is lazy loaded - openaiOSeriesConfig will be created on first access
+# OpenAIGPTConfig, OpenAIGPT5Config, etc. are lazy loaded - instances will be created on first access
+from .llms.xai.common_utils import XAIModelInfo
- # Interactions API is available as litellm.interactions module
- # Usage: litellm.interactions.create(), litellm.interactions.get(), etc.
- from . import interactions
- from .interactions.agents.main import (
- acreate as acreate_agent,
- create as create_agent,
- alist as alist_agents,
- list as list_agents,
- aget as aget_agent,
- get as get_agent,
- adelete as adelete_agent,
- delete as delete_agent,
- alist_versions as alist_agent_versions,
- list_versions as list_agent_versions,
- )
- from .skills.main import (
- create_skill,
- acreate_skill,
- list_skills,
- alist_skills,
- get_skill,
- aget_skill,
- delete_skill,
- adelete_skill,
- )
- from .containers.main import *
- from .ocr.main import *
- from .rust_bridge import rust
- from .rag.main import *
- from .sandbox.main import *
- from .search.main import *
- from .realtime_api.main import (
- _arealtime,
- acreate_realtime_client_secret,
- acreate_realtime_transcription_session,
- arealtime_calls,
- )
- from .responses.main import _aresponses_websocket
- from .fine_tuning.main import *
- from .files.main import *
- from .vector_store_files.main import (
- acreate as avector_store_file_create,
- adelete as avector_store_file_delete,
- alist as avector_store_file_list,
- aretrieve as avector_store_file_retrieve,
- aretrieve_content as avector_store_file_content,
- aupdate as avector_store_file_update,
- create as vector_store_file_create,
- delete as vector_store_file_delete,
- list as vector_store_file_list,
- retrieve as vector_store_file_retrieve,
- retrieve_content as vector_store_file_content,
- update as vector_store_file_update,
- )
- from .scheduler import *
+# PublicAI now uses JSON-based configuration (see litellm/llms/openai_like/providers.json)
+# All remaining configs are now lazy loaded - see _lazy_imports_registry.py
- ### ADAPTERS ###
- import litellm.anthropic_interface as anthropic
+# Import LlmProviders here (before main import) because it's imported during import time
+# in multiple places including openai.py (via main import)
+from litellm.types.utils import LlmProviders
- ### Vector Store Registry ###
+## Lazy loading this is not straightforward, will leave it here for now.
+from .main import *
+from .compression import compress
- ### RAG ###
- from . import rag
+# Skills API
+from .skills.main import (
+ create_skill,
+ acreate_skill,
+ list_skills,
+ alist_skills,
+ get_skill,
+ aget_skill,
+ delete_skill,
+ adelete_skill,
+)
+from .evals.main import (
+ create_eval,
+ acreate_eval,
+ list_evals,
+ alist_evals,
+ get_eval,
+ aget_eval,
+ delete_eval,
+ adelete_eval,
+ cancel_eval,
+ acancel_eval,
+ create_run,
+ acreate_run,
+ list_runs,
+ alist_runs,
+ get_run,
+ aget_run,
+ delete_run,
+ adelete_run,
+ cancel_run,
+ acancel_run,
+)
+from .integrations import *
+from .llms.custom_httpx.async_client_cleanup import close_litellm_async_clients
+from .exceptions import (
+ AuthenticationError,
+ InvalidRequestError,
+ BadRequestError,
+ ImageFetchError,
+ NotFoundError,
+ PermissionDeniedError,
+ RateLimitError,
+ RateLimitErrorCategory,
+ RateLimitType,
+ ServiceUnavailableError,
+ BadGatewayError,
+ OpenAIError,
+ ContextWindowExceededError,
+ ContentPolicyViolationError,
+ BudgetExceededError,
+ APIError,
+ Timeout,
+ APIConnectionError,
+ UnsupportedParamsError,
+ APIResponseValidationError,
+ UnprocessableEntityError,
+ InternalServerError,
+ JSONSchemaValidationError,
+ LITELLM_EXCEPTION_TYPES,
+ MockException,
+)
+from .budget_manager import BudgetManager
+from .proxy.proxy_cli import run_server
+from .router import Router
+from .assistants.main import *
+from .batches.main import *
+from .images.main import *
+from .videos.main import *
+from .batch_completion.main import *
+from .rerank_api.main import *
+from .llms.anthropic.experimental_pass_through.messages.handler import *
+from .responses.main import *
- ### CUSTOM LLMs ###
-
- ### CLI UTILITIES ###
- from litellm.litellm_core_utils.cli_token_utils import get_litellm_gateway_api_key
-
- ### PASSTHROUGH ###
- from .passthrough import allm_passthrough_route, llm_passthrough_route
- from .google_genai import agenerate_content
+# Interactions API is available as litellm.interactions module
+# Usage: litellm.interactions.create(), litellm.interactions.get(), etc.
+from . import interactions
+from .interactions.agents.main import (
+ acreate as acreate_agent,
+ create as create_agent,
+ alist as alist_agents,
+ list as list_agents,
+ aget as aget_agent,
+ get as get_agent,
+ adelete as adelete_agent,
+ delete as delete_agent,
+ alist_versions as alist_agent_versions,
+ list_versions as list_agent_versions,
+)
+from .skills.main import (
+ create_skill,
+ acreate_skill,
+ list_skills,
+ alist_skills,
+ get_skill,
+ aget_skill,
+ delete_skill,
+ adelete_skill,
+)
+from .containers.main import *
+from .ocr.main import *
+from .rust_bridge import rust
+from .rag.main import *
+from .sandbox.main import *
+from .search.main import *
+from .realtime_api.main import (
+ _arealtime,
+ acreate_realtime_client_secret,
+ acreate_realtime_transcription_session,
+ arealtime_calls,
+)
+from .responses.main import _aresponses_websocket
+from .fine_tuning.main import *
+from .files.main import *
+from .vector_store_files.main import (
+ acreate as avector_store_file_create,
+ adelete as avector_store_file_delete,
+ alist as avector_store_file_list,
+ aretrieve as avector_store_file_retrieve,
+ aretrieve_content as avector_store_file_content,
+ aupdate as avector_store_file_update,
+ create as vector_store_file_create,
+ delete as vector_store_file_delete,
+ list as vector_store_file_list,
+ retrieve as vector_store_file_retrieve,
+ retrieve_content as vector_store_file_content,
+ update as vector_store_file_update,
+)
+from .scheduler import *
### ADAPTERS ###
+from .types.adapter import AdapterItem
+import litellm.anthropic_interface as anthropic
+
adapters: List[AdapterItem] = []
### Vector Store Registry ###
+from .vector_stores.vector_store_registry import (
+ VectorStoreRegistry,
+ VectorStoreIndexRegistry,
+)
+
vector_store_registry: Optional[VectorStoreRegistry] = None
vector_store_index_registry: Optional[VectorStoreIndexRegistry] = None
+### RAG ###
+from . import rag
+
### CUSTOM LLMs ###
+from .types.llms.custom_llm import CustomLLMItem
+
custom_provider_map: List[CustomLLMItem] = []
_custom_providers: List[str] = [] # internal helper util, used to track names of custom providers
disable_hf_tokenizer_download: Optional[bool] = (
@@ -1471,6 +1478,13 @@ disable_hf_tokenizer_download: Optional[bool] = (
)
global_disable_no_log_param: bool = False
+### CLI UTILITIES ###
+from litellm.litellm_core_utils.cli_token_utils import get_litellm_gateway_api_key
+
+### PASSTHROUGH ###
+from .passthrough import allm_passthrough_route, llm_passthrough_route
+from .google_genai import agenerate_content
+
### GLOBAL CONFIG ###
global_bitbucket_config: Optional[Dict[str, Any]] = None
@@ -1494,21 +1508,10 @@ def set_global_gitlab_config(config: Dict[str, Any]) -> None:
# Lazy loading system for heavy modules to reduce initial import time and memory usage
if TYPE_CHECKING:
- import httpx
-
from litellm.types.utils import ModelInfo as _ModelInfoType
from litellm.types.utils import PriorityReservationSettings
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler, HTTPHandler
from litellm.caching.caching import Cache
- from litellm.types.adapter import AdapterItem
- from litellm.types.integrations.datadog import DatadogInitParams
- from litellm.types.integrations.newrelic import NewRelicInitParams
- from litellm.types.llms.custom_llm import CustomLLMItem
- from litellm.types.prompts.init_prompts import PromptSpec
- from litellm.vector_stores.vector_store_registry import (
- VectorStoreIndexRegistry,
- VectorStoreRegistry,
- )
# Type stubs for lazy-loaded configs to help mypy
from .llms.bedrock.chat.converse_transformation import (
@@ -2184,6 +2187,16 @@ if TYPE_CHECKING:
# Track if async client cleanup has been registered (for lazy loading)
_async_client_cleanup_registered = False
+# Eager loading for backwards compatibility with VCR and other HTTP recording tools
+# When LITELLM_DISABLE_LAZY_LOADING is set, lazy-loaded attributes are loaded at import time
+# For now, this only affects encoding (tiktoken) as it was the only reported issue
+# See: https://github.com/BerriAI/litellm/issues/18659
+# This ensures encoding is initialized before VCR starts recording HTTP requests
+if os.getenv("LITELLM_DISABLE_LAZY_LOADING", "").lower() in ("1", "true", "yes", "on"):
+ # Load encoding at import time (pre-#18070 behavior)
+ # This ensures encoding is initialized before VCR starts recording
+ from .main import encoding
+
def __getattr__(name: str) -> Any:
"""Lazy import handler with cached registry for improved performance."""
@@ -2263,8 +2276,6 @@ def __getattr__(name: str) -> Any:
"openAIGPT5Config": "OpenAIGPT5Config",
"nvidiaNimConfig": "NvidiaNimConfig",
"nvidiaNimEmbeddingConfig": "NvidiaNimEmbeddingConfig",
- "vertexAITextEmbeddingConfig": "VertexAITextEmbeddingConfig",
- "_key_management_settings": "KeyManagementSettings",
}
if name in _config_instances:
from ._lazy_imports import get_litellm_globals
@@ -2382,30 +2393,7 @@ def __getattr__(name: str) -> Any:
return locals()[name]
- from ._lazy_imports import lazy_import_litellm_submodule
-
- submodule: Final = lazy_import_litellm_submodule(name)
- if submodule is not None:
- return submodule
-
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
-from ._lazy_imports import LiteLLMModule
-from ._lazy_imports_registry import STAR_IMPORT_PUBLIC_NAMES
-
-sys.modules[__name__].__class__ = LiteLLMModule
-
-__all__ = list(STAR_IMPORT_PUBLIC_NAMES) # mutable-ok: star imports require __all__ to be a list of str
-
-
# ALL_LITELLM_RESPONSE_TYPES is lazy-loaded via __getattr__ to avoid loading utils at import time
-
-# Eager loading for backwards compatibility with VCR and other HTTP recording tools
-# When LITELLM_DISABLE_LAZY_LOADING is set, lazy-loaded attributes are loaded at import time
-# For now, this only affects encoding (tiktoken) as it was the only reported issue
-# See: https://github.com/BerriAI/litellm/issues/18659
-# This ensures encoding is initialized before VCR starts recording HTTP requests
-# This block stays at the bottom so __getattr__ can resolve attributes main.py needs during its import
-if os.getenv("LITELLM_DISABLE_LAZY_LOADING", "").lower() in ("1", "true", "yes", "on"):
- from .main import encoding
diff --git a/litellm/_lazy_imports.py b/litellm/_lazy_imports.py
index 004297a559e..553aeb6680d 100644
--- a/litellm/_lazy_imports.py
+++ b/litellm/_lazy_imports.py
@@ -16,10 +16,9 @@ until they're actually needed.
"""
import importlib
-import importlib.util
import sys
from collections.abc import Callable, Mapping
-from types import MappingProxyType, ModuleType
+from types import ModuleType
from typing import TYPE_CHECKING, Any, Final, cast
from typing_extensions import ReadOnly, TypedDict
@@ -35,8 +34,6 @@ from ._lazy_imports_registry import (
_LITELLM_LOGGING_IMPORT_MAP,
_LLM_CONFIGS_IMPORT_MAP,
_LLM_PROVIDER_LOGIC_IMPORT_MAP,
- _SDK_MODULE_ALIASES,
- _SDK_SYMBOLS_IMPORT_MAP,
_TOKEN_COUNTER_IMPORT_MAP,
_TYPES_IMPORT_MAP,
_TYPES_UTILS_IMPORT_MAP,
@@ -81,10 +78,7 @@ def _get_utils_globals() -> dict[str, object]:
This is where we cache imported attributes so we don't import them twice.
When you do `litellm.utils.some_function`, it gets stored in this dictionary.
"""
- cached: Final = sys.modules.get("litellm.utils")
- if cached is not None:
- return cached.__dict__
- return importlib.import_module("litellm.utils").__dict__
+ return sys.modules["litellm.utils"].__dict__
def _get_module_level_client_timeout(litellm_globals: Mapping[str, Any]) -> "float | httpx.Timeout | None":
@@ -220,10 +214,6 @@ def _get_lazy_import_registry() -> dict[str, Callable[[str], object]]:
_LAZY_IMPORT_REGISTRY[name] = _lazy_import_llm_provider_logic
for name in UTILS_MODULE_NAMES:
_LAZY_IMPORT_REGISTRY[name] = _lazy_import_utils_module
- for name in _SDK_SYMBOLS_IMPORT_MAP:
- _LAZY_IMPORT_REGISTRY.setdefault(name, _lazy_import_sdk_symbols)
- for name in _SDK_MODULE_ALIASES:
- _LAZY_IMPORT_REGISTRY.setdefault(name, _lazy_import_sdk_module_alias)
return _LAZY_IMPORT_REGISTRY
@@ -239,7 +229,7 @@ def _module_attribute(module: ModuleType, attr_name: str) -> object:
return attribute["value"]
-def _generic_lazy_import(name: str, import_map: Mapping[str, tuple[str, str]], category: str) -> object:
+def _generic_lazy_import(name: str, import_map: dict[str, tuple[str, str]], category: str) -> object:
"""
Generic function that handles lazy importing for most attributes.
@@ -360,86 +350,6 @@ def _lazy_import_llm_provider_logic(name: str) -> object:
return _generic_lazy_import(name, _LLM_PROVIDER_LOGIC_IMPORT_MAP, "LLM provider logic")
-def _lazy_import_sdk_symbols(name: str) -> object:
- """Handler for SDK symbols previously imported eagerly at the bottom of litellm/__init__.py"""
- return _generic_lazy_import(name, _SDK_SYMBOLS_IMPORT_MAP, "SDK symbols")
-
-
-def _lazy_import_sdk_module_alias(name: str) -> object:
- """Handler for litellm attributes that bind a module (e.g. litellm.anthropic)"""
- _globals: Final = get_litellm_globals()
- if name in _globals:
- return _globals[name]
- module: Final = importlib.import_module(_SDK_MODULE_ALIASES[name])
- _globals[name] = module # rebind-ok: caches the resolved module alias on the package
- return module
-
-
-_SHADOWABLE_SDK_FUNCTIONS: Final = MappingProxyType(
- {
- "batch_completion": ("litellm.batch_completion.main", "batch_completion"),
- "ocr": ("litellm.ocr.main", "ocr"),
- "responses": ("litellm.responses.main", "responses"),
- "search": ("litellm.search.main", "search"),
- }
-)
-
-
-def _shadowable_function_property(name: str) -> property:
- """Property keeping litellm. bound to the SDK function even after the import
- machinery binds the identically named litellm. subpackage onto the litellm module."""
- module_path, attr_name = _SHADOWABLE_SDK_FUNCTIONS[name]
-
- def _get(module: ModuleType) -> object:
- stored: Final = module.__dict__.get(name)
- if stored is not None and not (isinstance(stored, ModuleType) and stored.__name__ == f"litellm.{name}"):
- return stored
- value: Final = _module_attribute(importlib.import_module(module_path), attr_name)
- module.__dict__[name] = value # rebind-ok: caches the resolved function on the litellm module
- return value
-
- def _set(module: ModuleType, value: object) -> None:
- module.__dict__[name] = value # rebind-ok: property setter must store assignments on the module
-
- return property(_get, _set)
-
-
-class LiteLLMModule(ModuleType):
- """Module type installed on the litellm package so function names shadowed by
- same-named subpackages (litellm.responses, ...) keep resolving to the functions."""
-
- batch_completion = _shadowable_function_property("batch_completion")
- ocr = _shadowable_function_property("ocr")
- responses = _shadowable_function_property("responses")
- search = _shadowable_function_property("search")
-
-
-def lazy_import_submodule(package: str, name: str) -> "ModuleType | None":
- """Resolve . as a submodule (e.g. litellm.utils) when no other handler matches"""
- if name.startswith("__") or not name.isidentifier():
- return None
- qualified_name: Final = f"{package}.{name}"
- try:
- spec: Final = importlib.util.find_spec(qualified_name)
- except ModuleNotFoundError:
- return None
- if spec is None:
- return None
- try:
- module: Final = importlib.import_module(qualified_name)
- except ModuleNotFoundError as exc:
- if exc.name == qualified_name:
- return None
- raise
- sys.modules[package].__dict__[name] = module # rebind-ok: caches the resolved submodule on the package
- return module
-
-
-def lazy_import_litellm_submodule(name: str) -> "ModuleType | None":
- """Resolve litellm. as a submodule (e.g. litellm.utils) when no other handler matches"""
- return lazy_import_submodule("litellm", name)
-
-
def _lazy_import_utils_module(name: str) -> object:
"""
Handler for utils module lazy imports.
diff --git a/litellm/_lazy_imports_registry.py b/litellm/_lazy_imports_registry.py
index b0e2fb1398c..e9199e1ec80 100644
--- a/litellm/_lazy_imports_registry.py
+++ b/litellm/_lazy_imports_registry.py
@@ -5,8 +5,6 @@ This module contains all the name tuples and import maps used by the lazy import
Separated from the handler functions for better organization.
"""
-from collections.abc import Mapping
-from types import MappingProxyType
from typing import Final
# Cost calculator names that support lazy loading via _lazy_import_cost_calculator
@@ -1481,1171 +1479,6 @@ _UTILS_MODULE_IMPORT_MAP: Final = {
"LiteLLM_Params": ("litellm.types.router", "LiteLLM_Params"),
}
-_SDK_SYMBOLS_IMPORT_MAP: Final[Mapping[str, tuple[str, str]]] = MappingProxyType(
- {
- "AI21Config": ("litellm.llms.ai21.chat.transformation", "AI21ChatConfig"),
- "ALL_RESPONSES_API_TOOL_PARAMS": ("litellm.assistants.main", "ALL_RESPONSES_API_TOOL_PARAMS"),
- "APIConnectionError": ("litellm.exceptions", "APIConnectionError"),
- "APIError": ("litellm.exceptions", "APIError"),
- "APIResponseValidationError": ("litellm.exceptions", "APIResponseValidationError"),
- "AZURE_OPENAI_AUDIO_PROVIDERS": ("litellm.main", "AZURE_OPENAI_AUDIO_PROVIDERS"),
- "AdapterCompletionStreamWrapper": ("litellm.types.utils", "AdapterCompletionStreamWrapper"),
- "AdapterItem": ("litellm.types.adapter", "AdapterItem"),
- "AdaptiveRouterConfig": ("litellm.types.router", "AdaptiveRouterConfig"),
- "AdaptiveRouterPreferences": ("litellm.types.router", "AdaptiveRouterPreferences"),
- "AdaptiveRouterWeights": ("litellm.types.router", "AdaptiveRouterWeights"),
- "AlephAlphaConfig": ("litellm.llms.deprecated_providers.aleph_alpha", "AlephAlphaConfig"),
- "AlertingConfig": ("litellm.types.router", "AlertingConfig"),
- "AllEmbeddingInputValues": ("litellm.assistants.main", "AllEmbeddingInputValues"),
- "AllMessageValues": ("litellm.assistants.main", "AllMessageValues"),
- "AllPromptValues": ("litellm.assistants.main", "AllPromptValues"),
- "AllowedFailsPolicy": ("litellm.types.router", "AllowedFailsPolicy"),
- "AmazonTitanV2Config": ("litellm.llms.bedrock.embed.amazon_titan_v2_transformation", "AmazonTitanV2Config"),
- "Annotated": ("litellm.assistants.main", "Annotated"),
- "AnthropicBatchesHandler": ("litellm.llms.anthropic.batches.handler", "AnthropicBatchesHandler"),
- "AnthropicChatCompletion": ("litellm.llms.anthropic.chat.handler", "AnthropicChatCompletion"),
- "AnthropicMessagesRequestUtils": (
- "litellm.llms.anthropic.experimental_pass_through.messages.utils",
- "AnthropicMessagesRequestUtils",
- ),
- "AnthropicMessagesResponse": (
- "litellm.types.llms.anthropic_messages.anthropic_response",
- "AnthropicMessagesResponse",
- ),
- "AnthropicMetadata": ("litellm.types.llms.anthropic_messages.anthropic_request", "AnthropicMetadata"),
- "AnthropicModelInfo": ("litellm.llms.anthropic.common_utils", "AnthropicModelInfo"),
- "Assistant": ("litellm.assistants.main", "Assistant"),
- "AssistantDeleted": ("litellm.assistants.main", "AssistantDeleted"),
- "AssistantEventHandler": ("litellm.assistants.main", "AssistantEventHandler"),
- "AssistantStreamManager": ("litellm.assistants.main", "AssistantStreamManager"),
- "AssistantToolParam": ("litellm.assistants.main", "AssistantToolParam"),
- "AssistantsTypedDict": ("litellm.types.router", "AssistantsTypedDict"),
- "AsyncAssistantEventHandler": ("litellm.assistants.main", "AsyncAssistantEventHandler"),
- "AsyncAssistantStreamManager": ("litellm.assistants.main", "AsyncAssistantStreamManager"),
- "AsyncCompletions": ("litellm.main", "AsyncCompletions"),
- "AsyncCursorPage": ("litellm.assistants.main", "AsyncCursorPage"),
- "AsyncIterator": ("litellm.llms.anthropic.experimental_pass_through.messages.handler", "AsyncIterator"),
- "AsyncOpenAI": ("litellm.assistants.main", "AsyncOpenAI"),
- "Attachment": ("litellm.types.llms.openai", "Attachment"),
- "AttachmentTool": ("litellm.assistants.main", "AttachmentTool"),
- "AuthenticationError": ("litellm.exceptions", "AuthenticationError"),
- "AutoRouterCapabilityLimit": ("litellm.types.router", "AutoRouterCapabilityLimit"),
- "AzureAIEmbedding": ("litellm.llms.azure_ai.embed.handler", "AzureAIEmbedding"),
- "AzureAnthropicChatCompletion": ("litellm.llms.azure_ai.anthropic.handler", "AzureAnthropicChatCompletion"),
- "AzureAssistantsAPI": ("litellm.llms.azure.assistants", "AzureAssistantsAPI"),
- "AzureAudioTranscription": ("litellm.llms.azure.audio_transcriptions", "AzureAudioTranscription"),
- "AzureBatchesAPI": ("litellm.llms.azure.batches.handler", "AzureBatchesAPI"),
- "AzureChatCompletion": ("litellm.llms.azure.azure", "AzureChatCompletion"),
- "AzureOpenAIFilesAPI": ("litellm.llms.azure.files.handler", "AzureOpenAIFilesAPI"),
- "AzureOpenAIFineTuningAPI": ("litellm.llms.azure.fine_tuning.handler", "AzureOpenAIFineTuningAPI"),
- "AzureOpenAIO1ChatCompletion": ("litellm.llms.azure.chat.o_series_handler", "AzureOpenAIO1ChatCompletion"),
- "AzureTextCompletion": ("litellm.llms.azure.completion.handler", "AzureTextCompletion"),
- "BATCH_GUARDRAIL_RESPONSE_FIELD": ("litellm.assistants.main", "BATCH_GUARDRAIL_RESPONSE_FIELD"),
- "BadGatewayError": ("litellm.exceptions", "BadGatewayError"),
- "BadRequestError": ("litellm.exceptions", "BadRequestError"),
- "BaseConfig": ("litellm.llms.base_llm.chat.transformation", "BaseConfig"),
- "BaseLLMAIOHTTPHandler": ("litellm.llms.custom_httpx.aiohttp_handler", "BaseLLMAIOHTTPHandler"),
- "BaseLLMException": ("litellm.llms.base_llm.chat.transformation", "BaseLLMException"),
- "BaseLLMHTTPHandler": ("litellm.llms.custom_httpx.llm_http_handler", "BaseLLMHTTPHandler"),
- "BaseLiteLLMOpenAIResponseObject": ("litellm.types.llms.base", "BaseLiteLLMOpenAIResponseObject"),
- "BaseModel": ("litellm.scheduler", "BaseModel"),
- "BaseResponsesAPIConfig": ("litellm.llms.base_llm.responses.transformation", "BaseResponsesAPIConfig"),
- "BaseResponsesAPIStreamingIterator": (
- "litellm.responses.streaming_iterator",
- "BaseResponsesAPIStreamingIterator",
- ),
- "Batch": ("litellm.assistants.main", "Batch"),
- "BatchGuardrailRecord": ("litellm.types.llms.openai", "BatchGuardrailRecord"),
- "BatchGuardrailReport": ("litellm.types.llms.openai", "BatchGuardrailReport"),
- "BatchJobStatus": ("litellm.assistants.main", "BatchJobStatus"),
- "BatchRequestCounts": ("litellm.batches.main", "BatchRequestCounts"),
- "BedrockBatchesHandler": ("litellm.llms.bedrock.batches.handler", "BedrockBatchesHandler"),
- "BedrockConverseLLM": ("litellm.llms.bedrock.chat.converse_handler", "BedrockConverseLLM"),
- "BedrockEmbedding": ("litellm.llms.bedrock.embed.embedding", "BedrockEmbedding"),
- "BedrockFilesHandler": ("litellm.llms.bedrock.files.handler", "BedrockFilesHandler"),
- "BedrockImageEdit": ("litellm.llms.bedrock.image_edit.handler", "BedrockImageEdit"),
- "BedrockImageGeneration": ("litellm.llms.bedrock.image_generation.image_handler", "BedrockImageGeneration"),
- "BedrockRerankHandler": ("litellm.llms.bedrock.rerank.handler", "BedrockRerankHandler"),
- "BudgetExceededError": ("litellm.exceptions", "BudgetExceededError"),
- "BudgetManager": ("litellm.budget_manager", "BudgetManager"),
- "CARRY_UNMATCHED_MESSAGE_POINTS": ("litellm.responses.main", "CARRY_UNMATCHED_MESSAGE_POINTS"),
- "CONFIGURABLE_CLIENTSIDE_AUTH_PARAMS": ("litellm.files.main", "CONFIGURABLE_CLIENTSIDE_AUTH_PARAMS"),
- "CREATE_FILE_REQUESTS_PURPOSE": ("litellm.assistants.main", "CREATE_FILE_REQUESTS_PURPOSE"),
- "CallTypes": ("litellm.types.utils", "CallTypes"),
- "CancelBatchRequest": ("litellm.types.llms.openai", "CancelBatchRequest"),
- "CharacterObject": ("litellm.types.videos.main", "CharacterObject"),
- "Chat": ("litellm.main", "Chat"),
- "ChatCompletionAnnotation": ("litellm.types.llms.openai", "ChatCompletionAnnotation"),
- "ChatCompletionAnnotationURLCitation": ("litellm.types.llms.openai", "ChatCompletionAnnotationURLCitation"),
- "ChatCompletionAssistantContentValue": ("litellm.assistants.main", "ChatCompletionAssistantContentValue"),
- "ChatCompletionAssistantMessage": ("litellm.types.llms.openai", "ChatCompletionAssistantMessage"),
- "ChatCompletionAssistantToolCall": ("litellm.types.llms.openai", "ChatCompletionAssistantToolCall"),
- "ChatCompletionAudioDelta": ("litellm.types.llms.openai", "ChatCompletionAudioDelta"),
- "ChatCompletionAudioObject": ("litellm.types.llms.openai", "ChatCompletionAudioObject"),
- "ChatCompletionAudioParam": ("litellm.assistants.main", "ChatCompletionAudioParam"),
- "ChatCompletionCachedContent": ("litellm.types.llms.openai", "ChatCompletionCachedContent"),
- "ChatCompletionChunk": ("litellm.assistants.main", "ChatCompletionChunk"),
- "ChatCompletionContentPartInputAudioParam": (
- "litellm.assistants.main",
- "ChatCompletionContentPartInputAudioParam",
- ),
- "ChatCompletionDeltaChunk": ("litellm.types.llms.openai", "ChatCompletionDeltaChunk"),
- "ChatCompletionDeveloperMessage": ("litellm.types.llms.openai", "ChatCompletionDeveloperMessage"),
- "ChatCompletionDocumentObject": ("litellm.types.llms.openai", "ChatCompletionDocumentObject"),
- "ChatCompletionFileObject": ("litellm.types.llms.openai", "ChatCompletionFileObject"),
- "ChatCompletionFileObjectFile": ("litellm.types.llms.openai", "ChatCompletionFileObjectFile"),
- "ChatCompletionFunctionMessage": ("litellm.types.llms.openai", "ChatCompletionFunctionMessage"),
- "ChatCompletionImageObject": ("litellm.types.llms.openai", "ChatCompletionImageObject"),
- "ChatCompletionImageUrlObject": ("litellm.types.llms.openai", "ChatCompletionImageUrlObject"),
- "ChatCompletionMessageToolCall": ("litellm.types.utils", "ChatCompletionMessageToolCall"),
- "ChatCompletionModality": ("litellm.assistants.main", "ChatCompletionModality"),
- "ChatCompletionNamedToolChoiceParam": ("litellm.types.llms.openai", "ChatCompletionNamedToolChoiceParam"),
- "ChatCompletionPredictionContentParam": ("litellm.assistants.main", "ChatCompletionPredictionContentParam"),
- "ChatCompletionReasoningItem": ("litellm.types.llms.openai", "ChatCompletionReasoningItem"),
- "ChatCompletionReasoningSummaryTextBlock": (
- "litellm.types.llms.openai",
- "ChatCompletionReasoningSummaryTextBlock",
- ),
- "ChatCompletionRedactedThinkingBlock": ("litellm.types.llms.openai", "ChatCompletionRedactedThinkingBlock"),
- "ChatCompletionRequest": ("litellm.types.llms.openai", "ChatCompletionRequest"),
- "ChatCompletionResponseMessage": ("litellm.types.llms.openai", "ChatCompletionResponseMessage"),
- "ChatCompletionSystemMessage": ("litellm.types.llms.openai", "ChatCompletionSystemMessage"),
- "ChatCompletionTextObject": ("litellm.types.llms.openai", "ChatCompletionTextObject"),
- "ChatCompletionThinkingBlock": ("litellm.types.llms.openai", "ChatCompletionThinkingBlock"),
- "ChatCompletionToolChoiceFunctionParam": ("litellm.types.llms.openai", "ChatCompletionToolChoiceFunctionParam"),
- "ChatCompletionToolChoiceObjectParam": ("litellm.types.llms.openai", "ChatCompletionToolChoiceObjectParam"),
- "ChatCompletionToolChoiceStringValues": ("litellm.assistants.main", "ChatCompletionToolChoiceStringValues"),
- "ChatCompletionToolChoiceValues": ("litellm.assistants.main", "ChatCompletionToolChoiceValues"),
- "ChatCompletionToolMessage": ("litellm.types.llms.openai", "ChatCompletionToolMessage"),
- "ChatCompletionToolParam": ("litellm.types.llms.openai", "ChatCompletionToolParam"),
- "ChatCompletionToolParamFunctionChunk": ("litellm.types.llms.openai", "ChatCompletionToolParamFunctionChunk"),
- "ChatCompletionToolReferenceObject": ("litellm.types.llms.openai", "ChatCompletionToolReferenceObject"),
- "ChatCompletionUsageBlock": ("litellm.types.llms.openai", "ChatCompletionUsageBlock"),
- "ChatCompletionUserMessage": ("litellm.types.llms.openai", "ChatCompletionUserMessage"),
- "ChatCompletionVideoObject": ("litellm.types.llms.openai", "ChatCompletionVideoObject"),
- "ChatCompletionVideoUrlObject": ("litellm.types.llms.openai", "ChatCompletionVideoUrlObject"),
- "Choices": ("litellm.types.utils", "Choices"),
- "ChunkProcessor": ("litellm.litellm_core_utils.streaming_chunk_builder_utils", "ChunkProcessor"),
- "CitationsObject": ("litellm.types.llms.openai", "CitationsObject"),
- "ClassVar": ("litellm.files.main", "ClassVar"),
- "ClassifierPlugin": ("litellm.types.router", "ClassifierPlugin"),
- "CodeInterpreterToolParam": ("litellm.types.llms.openai", "CodeInterpreterToolParam"),
- "CodestralTextCompletion": ("litellm.llms.codestral.completion.handler", "CodestralTextCompletion"),
- "CompletionRequest": ("litellm.types.completion", "CompletionRequest"),
- "CompletionTimeout": ("litellm.litellm_core_utils.completion_timeout", "CompletionTimeout"),
- "CompletionTokensDetails": ("litellm.main", "CompletionTokensDetails"),
- "Completions": ("litellm.main", "Completions"),
- "ComputerToolParam": ("litellm.types.llms.openai", "ComputerToolParam"),
- "ConfigDict": ("litellm.files.main", "ConfigDict"),
- "ConfigurableClientsideParamsCustomAuth": ("litellm.types.router", "ConfigurableClientsideParamsCustomAuth"),
- "ConsumedRequestTagsStamp": ("litellm.types.router", "ConsumedRequestTagsStamp"),
- "ContentPartAddedEvent": ("litellm.types.llms.openai", "ContentPartAddedEvent"),
- "ContentPartDoneEvent": ("litellm.types.llms.openai", "ContentPartDoneEvent"),
- "ContentPartDonePartOutputText": ("litellm.types.llms.openai", "ContentPartDonePartOutputText"),
- "ContentPartDonePartReasoningText": ("litellm.types.llms.openai", "ContentPartDonePartReasoningText"),
- "ContentPartDonePartRefusal": ("litellm.types.llms.openai", "ContentPartDonePartRefusal"),
- "ContentPolicyViolationError": ("litellm.exceptions", "ContentPolicyViolationError"),
- "ContextManagementEntry": ("litellm.types.llms.openai", "ContextManagementEntry"),
- "ContextWindowExceededError": ("litellm.exceptions", "ContextWindowExceededError"),
- "Coroutine": ("litellm.files.main", "Coroutine"),
- "CreateBatchRequest": ("litellm.types.llms.openai", "CreateBatchRequest"),
- "CreateFileRequest": ("litellm.types.llms.openai", "CreateFileRequest"),
- "CreateVideoRequest": ("litellm.types.llms.openai", "CreateVideoRequest"),
- "CredentialLiteLLMParams": ("litellm.types.router", "CredentialLiteLLMParams"),
- "CustomLLM": ("litellm.llms.custom_llm", "CustomLLM"),
- "CustomLLMItem": ("litellm.types.llms.custom_llm", "CustomLLMItem"),
- "CustomPricingLiteLLMParams": ("litellm.types.utils", "CustomPricingLiteLLMParams"),
- "CustomRoutingStrategyBase": ("litellm.types.router", "CustomRoutingStrategyBase"),
- "CustomToolCallOutputItem": ("litellm.types.responses.main", "CustomToolCallOutputItem"),
- "DEFAULT_IMAGE_ENDPOINT_MODEL": ("litellm.images.main", "DEFAULT_IMAGE_ENDPOINT_MODEL"),
- "DEFAULT_IN_MEMORY_TTL": ("litellm.scheduler", "DEFAULT_IN_MEMORY_TTL"),
- "DEFAULT_MOCK_RESPONSE_COMPLETION_TOKEN_COUNT": (
- "litellm.main",
- "DEFAULT_MOCK_RESPONSE_COMPLETION_TOKEN_COUNT",
- ),
- "DEFAULT_MOCK_RESPONSE_PROMPT_TOKEN_COUNT": ("litellm.main", "DEFAULT_MOCK_RESPONSE_PROMPT_TOKEN_COUNT"),
- "DEFAULT_POLLING_INTERVAL": ("litellm.scheduler", "DEFAULT_POLLING_INTERVAL"),
- "DEFAULT_REQUEST_TIMEOUT": ("litellm.videos.main", "DEFAULT_REQUEST_TIMEOUT"),
- "DEFAULT_VIDEO_ENDPOINT_MODEL": ("litellm.videos.main", "DEFAULT_VIDEO_ENDPOINT_MODEL"),
- "DatabricksEmbeddingHandler": ("litellm.llms.databricks.embed.handler", "DatabricksEmbeddingHandler"),
- "DatadogInitParams": ("litellm.types.integrations.datadog", "DatadogInitParams"),
- "DecodedResponseId": ("litellm.types.responses.main", "DecodedResponseId"),
- "DeleteResponseResult": ("litellm.types.responses.main", "DeleteResponseResult"),
- "Deployment": ("litellm.types.router", "Deployment"),
- "DeploymentTypedDict": ("litellm.types.router", "DeploymentTypedDict"),
- "Discriminator": ("litellm.assistants.main", "Discriminator"),
- "DocumentObject": ("litellm.types.llms.openai", "DocumentObject"),
- "EmbeddingCreateParams": ("litellm.assistants.main", "EmbeddingCreateParams"),
- "EmbeddingInput": ("litellm.assistants.main", "EmbeddingInput"),
- "EmbeddingRequest": ("litellm.types.embedding", "EmbeddingRequest"),
- "Enum": ("litellm.assistants.main", "Enum"),
- "ErrorEvent": ("litellm.types.llms.openai", "ErrorEvent"),
- "ErrorEventError": ("litellm.types.llms.openai", "ErrorEventError"),
- "FIRST_COMPLETED": ("litellm.batch_completion.main", "FIRST_COMPLETED"),
- "FORWARDED_KWARGS_KEYS": ("litellm.main", "FORWARDED_KWARGS_KEYS"),
- "FallbackAccessCheck": ("litellm.types.router", "FallbackAccessCheck"),
- "Field": ("litellm.files.main", "Field"),
- "FileContent": ("litellm.videos.main", "FileContent"),
- "FileContentProvider": ("litellm.files.main", "FileContentProvider"),
- "FileContentRequest": ("litellm.types.llms.openai", "FileContentRequest"),
- "FileContentStreamingResponse": ("litellm.files.streaming", "FileContentStreamingResponse"),
- "FileContentStreamingResult": ("litellm.files.types", "FileContentStreamingResult"),
- "FileCreateProvider": ("litellm.files.main", "FileCreateProvider"),
- "FileDeleteProvider": ("litellm.files.main", "FileDeleteProvider"),
- "FileDeleted": ("litellm.files.main", "FileDeleted"),
- "FileExpiresAfter": ("litellm.types.llms.openai", "FileExpiresAfter"),
- "FileListPage": ("litellm.types.llms.openai", "FileListPage"),
- "FileListProvider": ("litellm.files.main", "FileListProvider"),
- "FileObject": ("litellm.files.main", "FileObject"),
- "FileRetrieveProvider": ("litellm.files.main", "FileRetrieveProvider"),
- "FileSearchCallCompletedEvent": ("litellm.types.llms.openai", "FileSearchCallCompletedEvent"),
- "FileSearchCallInProgressEvent": ("litellm.types.llms.openai", "FileSearchCallInProgressEvent"),
- "FileSearchCallSearchingEvent": ("litellm.types.llms.openai", "FileSearchCallSearchingEvent"),
- "FileSearchTool": ("litellm.types.llms.openai", "FileSearchTool"),
- "FileSearchToolParam": ("litellm.types.llms.openai", "FileSearchToolParam"),
- "FileTypes": ("litellm.files.main", "FileTypes"),
- "FineTuningConfig": ("litellm.types.router", "FineTuningConfig"),
- "FineTuningJob": ("litellm.assistants.main", "FineTuningJob"),
- "FineTuningJobCreate": ("litellm.types.llms.openai", "FineTuningJobCreate"),
- "FlowItem": ("litellm.scheduler", "FlowItem"),
- "Function": ("litellm.types.llms.openai", "Function"),
- "FunctionCallArgumentsDeltaEvent": ("litellm.types.llms.openai", "FunctionCallArgumentsDeltaEvent"),
- "FunctionCallArgumentsDoneEvent": ("litellm.types.llms.openai", "FunctionCallArgumentsDoneEvent"),
- "GeminiModelInfo": ("litellm.llms.gemini.common_utils", "GeminiModelInfo"),
- "GenAIHubOrchestration": ("litellm.llms.sap.chat.handler", "GenAIHubOrchestration"),
- "Generator": ("litellm.responses.main", "Generator"),
- "Generic": ("litellm.files.main", "Generic"),
- "GenericBudgetWindowDetails": ("litellm.types.router", "GenericBudgetWindowDetails"),
- "GenericChatCompletionMessage": ("litellm.types.llms.openai", "GenericChatCompletionMessage"),
- "GenericEvent": ("litellm.types.llms.openai", "GenericEvent"),
- "GenericLiteLLMParams": ("litellm.types.router", "GenericLiteLLMParams"),
- "GenericResponseOutputItem": ("litellm.types.responses.main", "GenericResponseOutputItem"),
- "GenericResponseOutputItemContentAnnotation": (
- "litellm.types.responses.main",
- "GenericResponseOutputItemContentAnnotation",
- ),
- "GoogleBatchEmbeddings": (
- "litellm.llms.vertex_ai.gemini_embeddings.batch_embed_content_handler",
- "GoogleBatchEmbeddings",
- ),
- "GroqChatCompletion": ("litellm.llms.groq.chat.handler", "GroqChatCompletion"),
- "GuardrailLiteLLMParams": ("litellm.types.router", "GuardrailLiteLLMParams"),
- "GuardrailTypedDict": ("litellm.types.router", "GuardrailTypedDict"),
- "HiddenParams": ("litellm.types.llms.base", "HiddenParams"),
- "HttpxBinaryResponseContent": ("litellm.types.llms.openai", "HttpxBinaryResponseContent"),
- "HuggingFaceEmbedding": ("litellm.llms.huggingface.embedding.handler", "HuggingFaceEmbedding"),
- "Hyperparameters": ("litellm.types.llms.openai", "Hyperparameters"),
- "IBMWatsonXMixin": ("litellm.llms.watsonx.common_utils", "IBMWatsonXMixin"),
- "IO": ("litellm.assistants.main", "IO"),
- "IOBase": ("litellm.ocr.main", "IOBase"),
- "ImageEditOptionalRequestParams": ("litellm.types.images.main", "ImageEditOptionalRequestParams"),
- "ImageFetchError": ("litellm.exceptions", "ImageFetchError"),
- "ImageFileObject": ("litellm.types.llms.openai", "ImageFileObject"),
- "ImageGenerationPartialImageEvent": ("litellm.types.llms.openai", "ImageGenerationPartialImageEvent"),
- "ImageGenerationRequestQuality": ("litellm.types.llms.openai", "ImageGenerationRequestQuality"),
- "ImageURLListItem": ("litellm.types.llms.openai", "ImageURLListItem"),
- "ImageURLObject": ("litellm.types.llms.openai", "ImageURLObject"),
- "IncompleteDetails": ("litellm.assistants.main", "IncompleteDetails"),
- "InputTokensDetails": ("litellm.types.llms.openai", "InputTokensDetails"),
- "InternalServerError": ("litellm.exceptions", "InternalServerError"),
- "InvalidRequestError": ("litellm.exceptions", "InvalidRequestError"),
- "Iterable": ("litellm.responses.main", "Iterable"),
- "Iterator": ("litellm.llms.anthropic.experimental_pass_through.messages.handler", "Iterator"),
- "JSONProviderRegistry": ("litellm.llms.openai_like.json_loader", "JSONProviderRegistry"),
- "JSONSchemaValidationError": ("litellm.exceptions", "JSONSchemaValidationError"),
- "KeyManagementSettings": ("litellm.types.secret_managers.main", "KeyManagementSettings"),
- "LIST_BATCHES_SUPPORTED_PROVIDERS": ("litellm.batches.main", "LIST_BATCHES_SUPPORTED_PROVIDERS"),
- "LITELLM_EXCEPTION_TYPES": ("litellm.exceptions", "LITELLM_EXCEPTION_TYPES"),
- "LITELLM_IMAGE_VARIATION_PROVIDERS": ("litellm.types.utils", "LITELLM_IMAGE_VARIATION_PROVIDERS"),
- "ListBatchRequest": ("litellm.types.llms.openai", "ListBatchRequest"),
- "ListBatchesSupportedProvider": ("litellm.batches.main", "ListBatchesSupportedProvider"),
- "LiteLLM": ("litellm.main", "LiteLLM"),
- "LiteLLMBatch": ("litellm.types.utils", "LiteLLMBatch"),
- "LiteLLMBatchCreateRequest": ("litellm.types.llms.openai", "LiteLLMBatchCreateRequest"),
- "LiteLLMCompletionTransformationHandler": (
- "litellm.responses.litellm_completion_transformation.handler",
- "LiteLLMCompletionTransformationHandler",
- ),
- "LiteLLMFineTuningJob": ("litellm.types.utils", "LiteLLMFineTuningJob"),
- "LiteLLMFineTuningJobCreate": ("litellm.types.llms.openai", "LiteLLMFineTuningJobCreate"),
- "LiteLLMLoggingObj": ("litellm.files.main", "LiteLLMLoggingObj"),
- "LiteLLMMessagesToCompletionTransformationHandler": (
- "litellm.llms.anthropic.experimental_pass_through.adapters.handler",
- "LiteLLMMessagesToCompletionTransformationHandler",
- ),
- "LiteLLMMessagesToResponsesAPIHandler": (
- "litellm.llms.anthropic.experimental_pass_through.responses_adapters.handler",
- "LiteLLMMessagesToResponsesAPIHandler",
- ),
- "LiteLLMParamsTypedDict": ("litellm.types.router", "LiteLLMParamsTypedDict"),
- "LiteLLMResponsesTransformationHandler": (
- "litellm.completion_extras.litellm_responses_transformation.transformation",
- "LiteLLMResponsesTransformationHandler",
- ),
- "LiteLLMUnknownProvider": ("litellm.exceptions", "LiteLLMUnknownProvider"),
- "LiteLLM_RouterFileObject": ("litellm.types.router", "LiteLLM_RouterFileObject"),
- "LlmProviders": ("litellm.types.utils", "LlmProviders"),
- "MCPCallArgumentsDeltaEvent": ("litellm.types.llms.openai", "MCPCallArgumentsDeltaEvent"),
- "MCPCallArgumentsDoneEvent": ("litellm.types.llms.openai", "MCPCallArgumentsDoneEvent"),
- "MCPCallCompletedEvent": ("litellm.types.llms.openai", "MCPCallCompletedEvent"),
- "MCPCallFailedEvent": ("litellm.types.llms.openai", "MCPCallFailedEvent"),
- "MCPCallInProgressEvent": ("litellm.types.llms.openai", "MCPCallInProgressEvent"),
- "MCPListToolsCompletedEvent": ("litellm.types.llms.openai", "MCPListToolsCompletedEvent"),
- "MCPListToolsFailedEvent": ("litellm.types.llms.openai", "MCPListToolsFailedEvent"),
- "MCPListToolsInProgressEvent": ("litellm.types.llms.openai", "MCPListToolsInProgressEvent"),
- "MCPTool": ("litellm.responses.main", "MCPTool"),
- "MOCK_RESPONSE_TYPE": ("litellm.main", "MOCK_RESPONSE_TYPE"),
- "Mapping": ("litellm.files.main", "Mapping"),
- "MappingProxyType": ("litellm.main", "MappingProxyType"),
- "Message": ("litellm.types.utils", "Message"),
- "MessageContent": ("litellm.assistants.main", "MessageContent"),
- "MessageContentImageFileObject": ("litellm.types.llms.openai", "MessageContentImageFileObject"),
- "MessageContentImageURLObject": ("litellm.types.llms.openai", "MessageContentImageURLObject"),
- "MessageContentTextObject": ("litellm.types.llms.openai", "MessageContentTextObject"),
- "MessageData": ("litellm.types.llms.openai", "MessageData"),
- "MirroredPricingParams": ("litellm.types.utils", "MirroredPricingParams"),
- "MockException": ("litellm.exceptions", "MockException"),
- "MockRouterTestingParams": ("litellm.types.router", "MockRouterTestingParams"),
- "ModelConfig": ("litellm.types.router", "ModelConfig"),
- "ModelGroupInfo": ("litellm.types.router", "ModelGroupInfo"),
- "ModelGroupSettings": ("litellm.types.router", "ModelGroupSettings"),
- "ModelInfo": ("litellm.types.router", "ModelInfo"),
- "NOT_GIVEN": ("litellm.types.llms.openai", "NOT_GIVEN"),
- "NewRelicInitParams": ("litellm.types.integrations.newrelic", "NewRelicInitParams"),
- "NonNegativeInt": ("litellm.assistants.main", "NonNegativeInt"),
- "NotFoundError": ("litellm.exceptions", "NotFoundError"),
- "NotGiven": ("litellm.types.llms.openai", "NotGiven"),
- "NotRequired": ("litellm.assistants.main", "NotRequired"),
- "NvidiaRivaAudioTranscription": (
- "litellm.llms.nvidia_riva.audio_transcription.handler",
- "NvidiaRivaAudioTranscription",
- ),
- "NvidiaRivaAudioTranscriptionConfig": (
- "litellm.llms.nvidia_riva.audio_transcription.transformation",
- "NvidiaRivaAudioTranscriptionConfig",
- ),
- "OCRResponse": ("litellm.llms.base_llm.ocr.transformation", "OCRResponse"),
- "OCR_REQUEST_FORMAT_PARAM": ("litellm.ocr.main", "OCR_REQUEST_FORMAT_PARAM"),
- "OPENAI_COMPATIBLE_BATCH_AND_FILES_PROVIDERS": (
- "litellm.files.main",
- "OPENAI_COMPATIBLE_BATCH_AND_FILES_PROVIDERS",
- ),
- "OPTIONAL_KWARGS_KEYS": ("litellm.main", "OPTIONAL_KWARGS_KEYS"),
- "Omit": ("litellm.assistants.main", "Omit"),
- "OpenAI": ("litellm.assistants.main", "OpenAI"),
- "OpenAIAssistantsAPI": ("litellm.llms.openai.openai", "OpenAIAssistantsAPI"),
- "OpenAIAudioTranscription": ("litellm.llms.openai.transcriptions.handler", "OpenAIAudioTranscription"),
- "OpenAIAudioTranscriptionOptionalParams": ("litellm.assistants.main", "OpenAIAudioTranscriptionOptionalParams"),
- "OpenAIBatchResponse": ("litellm.types.llms.openai", "OpenAIBatchResponse"),
- "OpenAIBatchResult": ("litellm.types.llms.openai", "OpenAIBatchResult"),
- "OpenAIBatchesAPI": ("litellm.llms.openai.openai", "OpenAIBatchesAPI"),
- "OpenAIChatCompletion": ("litellm.llms.openai.openai", "OpenAIChatCompletion"),
- "OpenAIChatCompletionAssistantMessage": ("litellm.types.llms.openai", "OpenAIChatCompletionAssistantMessage"),
- "OpenAIChatCompletionChoices": ("litellm.types.llms.openai", "OpenAIChatCompletionChoices"),
- "OpenAIChatCompletionChunk": ("litellm.types.llms.openai", "OpenAIChatCompletionChunk"),
- "OpenAIChatCompletionDeveloperMessage": ("litellm.types.llms.openai", "OpenAIChatCompletionDeveloperMessage"),
- "OpenAIChatCompletionFinishReason": ("litellm.assistants.main", "OpenAIChatCompletionFinishReason"),
- "OpenAIChatCompletionLogprobs": ("litellm.types.llms.openai", "OpenAIChatCompletionLogprobs"),
- "OpenAIChatCompletionLogprobsContent": ("litellm.types.llms.openai", "OpenAIChatCompletionLogprobsContent"),
- "OpenAIChatCompletionLogprobsContentTopLogprobs": (
- "litellm.types.llms.openai",
- "OpenAIChatCompletionLogprobsContentTopLogprobs",
- ),
- "OpenAIChatCompletionResponse": ("litellm.types.llms.openai", "OpenAIChatCompletionResponse"),
- "OpenAIChatCompletionSystemMessage": ("litellm.types.llms.openai", "OpenAIChatCompletionSystemMessage"),
- "OpenAIChatCompletionTextObject": ("litellm.types.llms.openai", "OpenAIChatCompletionTextObject"),
- "OpenAIChatCompletionToolParam": ("litellm.types.llms.openai", "OpenAIChatCompletionToolParam"),
- "OpenAIChatCompletionUserMessage": ("litellm.types.llms.openai", "OpenAIChatCompletionUserMessage"),
- "OpenAICreateFileRequestOptionalParams": ("litellm.assistants.main", "OpenAICreateFileRequestOptionalParams"),
- "OpenAICreateThreadParamsMessage": ("litellm.assistants.main", "OpenAICreateThreadParamsMessage"),
- "OpenAICreateThreadParamsToolResources": ("litellm.types.llms.openai", "OpenAICreateThreadParamsToolResources"),
- "OpenAIEmbedding": ("litellm.assistants.main", "OpenAIEmbedding"),
- "OpenAIError": ("litellm.exceptions", "OpenAIError"),
- "OpenAIErrorBody": ("litellm.types.llms.openai", "OpenAIErrorBody"),
- "OpenAIFileObject": ("litellm.types.llms.openai", "OpenAIFileObject"),
- "OpenAIFilesAPI": ("litellm.llms.openai.openai", "OpenAIFilesAPI"),
- "OpenAIFilesPurpose": ("litellm.assistants.main", "OpenAIFilesPurpose"),
- "OpenAIFineTuningAPI": ("litellm.llms.openai.fine_tuning.handler", "OpenAIFineTuningAPI"),
- "OpenAIImageEditOptionalParams": ("litellm.assistants.main", "OpenAIImageEditOptionalParams"),
- "OpenAIImageGenerationOptionalParams": ("litellm.assistants.main", "OpenAIImageGenerationOptionalParams"),
- "OpenAIImageVariationOptionalParams": ("litellm.assistants.main", "OpenAIImageVariationOptionalParams"),
- "OpenAIImageVariationsHandler": (
- "litellm.llms.openai.image_variations.handler",
- "OpenAIImageVariationsHandler",
- ),
- "OpenAILikeChatHandler": ("litellm.llms.openai_like.chat.handler", "OpenAILikeChatHandler"),
- "OpenAILikeEmbeddingHandler": ("litellm.llms.openai_like.embedding.handler", "OpenAILikeEmbeddingHandler"),
- "OpenAILikeResponsesConfig": (
- "litellm.llms.openai_like.responses.transformation",
- "OpenAILikeResponsesConfig",
- ),
- "OpenAIMcpServerTool": ("litellm.types.llms.openai", "OpenAIMcpServerTool"),
- "OpenAIMessage": ("litellm.assistants.main", "OpenAIMessage"),
- "OpenAIMessageContent": ("litellm.assistants.main", "OpenAIMessageContent"),
- "OpenAIMessageContentListBlock": ("litellm.assistants.main", "OpenAIMessageContentListBlock"),
- "OpenAIModerationResponse": ("litellm.types.llms.openai", "OpenAIModerationResponse"),
- "OpenAIModerationResult": ("litellm.types.llms.openai", "OpenAIModerationResult"),
- "OpenAIRealtimeContentPartDone": ("litellm.types.llms.openai", "OpenAIRealtimeContentPartDone"),
- "OpenAIRealtimeConversationCreated": ("litellm.types.llms.openai", "OpenAIRealtimeConversationCreated"),
- "OpenAIRealtimeConversationItemAdded": ("litellm.types.llms.openai", "OpenAIRealtimeConversationItemAdded"),
- "OpenAIRealtimeConversationItemCreated": ("litellm.types.llms.openai", "OpenAIRealtimeConversationItemCreated"),
- "OpenAIRealtimeConversationItemDone": ("litellm.types.llms.openai", "OpenAIRealtimeConversationItemDone"),
- "OpenAIRealtimeConversationObject": ("litellm.types.llms.openai", "OpenAIRealtimeConversationObject"),
- "OpenAIRealtimeDoneEvent": ("litellm.types.llms.openai", "OpenAIRealtimeDoneEvent"),
- "OpenAIRealtimeEventTypes": ("litellm.types.llms.openai", "OpenAIRealtimeEventTypes"),
- "OpenAIRealtimeEvents": ("litellm.assistants.main", "OpenAIRealtimeEvents"),
- "OpenAIRealtimeFunctionCallArgumentsDone": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeFunctionCallArgumentsDone",
- ),
- "OpenAIRealtimeInputAudioBufferSpeechEvent": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeInputAudioBufferSpeechEvent",
- ),
- "OpenAIRealtimeInputAudioTranscriptionCompleted": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeInputAudioTranscriptionCompleted",
- ),
- "OpenAIRealtimeInputAudioTranscriptionDelta": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeInputAudioTranscriptionDelta",
- ),
- "OpenAIRealtimeOutputItemDone": ("litellm.types.llms.openai", "OpenAIRealtimeOutputItemDone"),
- "OpenAIRealtimeResponseAudioDone": ("litellm.types.llms.openai", "OpenAIRealtimeResponseAudioDone"),
- "OpenAIRealtimeResponseContentPart": ("litellm.types.llms.openai", "OpenAIRealtimeResponseContentPart"),
- "OpenAIRealtimeResponseContentPartAdded": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeResponseContentPartAdded",
- ),
- "OpenAIRealtimeResponseDelta": ("litellm.types.llms.openai", "OpenAIRealtimeResponseDelta"),
- "OpenAIRealtimeResponseDoneObject": ("litellm.types.llms.openai", "OpenAIRealtimeResponseDoneObject"),
- "OpenAIRealtimeResponseTextDone": ("litellm.types.llms.openai", "OpenAIRealtimeResponseTextDone"),
- "OpenAIRealtimeResponseUsage": ("litellm.types.llms.openai", "OpenAIRealtimeResponseUsage"),
- "OpenAIRealtimeStreamList": ("litellm.assistants.main", "OpenAIRealtimeStreamList"),
- "OpenAIRealtimeStreamResponseBaseObject": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeStreamResponseBaseObject",
- ),
- "OpenAIRealtimeStreamResponseOutputItem": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeStreamResponseOutputItem",
- ),
- "OpenAIRealtimeStreamResponseOutputItemAdded": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeStreamResponseOutputItemAdded",
- ),
- "OpenAIRealtimeStreamResponseOutputItemContent": (
- "litellm.types.llms.openai",
- "OpenAIRealtimeStreamResponseOutputItemContent",
- ),
- "OpenAIRealtimeStreamSession": ("litellm.types.llms.openai", "OpenAIRealtimeStreamSession"),
- "OpenAIRealtimeStreamSessionEvents": ("litellm.types.llms.openai", "OpenAIRealtimeStreamSessionEvents"),
- "OpenAIRealtimeTurnDetection": ("litellm.types.llms.openai", "OpenAIRealtimeTurnDetection"),
- "OpenAIRealtimeUsageTokenDetails": ("litellm.types.llms.openai", "OpenAIRealtimeUsageTokenDetails"),
- "OpenAITextCompletion": ("litellm.llms.openai.completion.handler", "OpenAITextCompletion"),
- "OpenAITextCompletionUserMessage": ("litellm.types.llms.openai", "OpenAITextCompletionUserMessage"),
- "OpenAIVideoObject": ("litellm.types.llms.openai", "OpenAIVideoObject"),
- "OpenAIWebSearchOptions": ("litellm.types.llms.openai", "OpenAIWebSearchOptions"),
- "OpenAIWebSearchUserLocation": ("litellm.types.llms.openai", "OpenAIWebSearchUserLocation"),
- "OpenAIWebSearchUserLocationApproximate": (
- "litellm.types.llms.openai",
- "OpenAIWebSearchUserLocationApproximate",
- ),
- "OptionalPreCallChecks": ("litellm.files.main", "OptionalPreCallChecks"),
- "OutputCodeInterpreterCall": ("litellm.types.responses.main", "OutputCodeInterpreterCall"),
- "OutputCodeInterpreterCallLog": ("litellm.types.responses.main", "OutputCodeInterpreterCallLog"),
- "OutputFunctionToolCall": ("litellm.types.responses.main", "OutputFunctionToolCall"),
- "OutputImageGenerationCall": ("litellm.types.responses.main", "OutputImageGenerationCall"),
- "OutputItemAddedEvent": ("litellm.types.llms.openai", "OutputItemAddedEvent"),
- "OutputItemDoneEvent": ("litellm.types.llms.openai", "OutputItemDoneEvent"),
- "OutputText": ("litellm.types.responses.main", "OutputText"),
- "OutputTextAnnotationAddedEvent": ("litellm.types.llms.openai", "OutputTextAnnotationAddedEvent"),
- "OutputTextDeltaEvent": ("litellm.types.llms.openai", "OutputTextDeltaEvent"),
- "OutputTextDoneEvent": ("litellm.types.llms.openai", "OutputTextDoneEvent"),
- "OutputTokensDetails": ("litellm.types.llms.openai", "OutputTokensDetails"),
- "PART_UNION_TYPES": ("litellm.assistants.main", "PART_UNION_TYPES"),
- "PalmConfig": ("litellm.llms.deprecated_providers.palm", "PalmConfig"),
- "PathLike": ("litellm.assistants.main", "PathLike"),
- "PermissionDeniedError": ("litellm.exceptions", "PermissionDeniedError"),
- "Phase": ("litellm.responses.main", "Phase"),
- "PreRoutingHookResponse": ("litellm.types.router", "PreRoutingHookResponse"),
- "PreRoutingStrategy": ("litellm.types.router", "PreRoutingStrategy"),
- "PredibaseChatCompletion": ("litellm.llms.predibase.chat.handler", "PredibaseChatCompletion"),
- "PrivateAttr": ("litellm.responses.main", "PrivateAttr"),
- "PromptCacheBreakpoint": ("litellm.types.llms.openai", "PromptCacheBreakpoint"),
- "PromptCacheOptions": ("litellm.types.llms.openai", "PromptCacheOptions"),
- "PromptObject": ("litellm.types.llms.openai", "PromptObject"),
- "PromptSpec": ("litellm.types.prompts.init_prompts", "PromptSpec"),
- "PromptTokensDetails": ("litellm.main", "PromptTokensDetails"),
- "Protocol": ("litellm.files.main", "Protocol"),
- "ProviderConfigManager": ("litellm.utils", "ProviderConfigManager"),
- "ProviderSpecificHeader": ("litellm.types.utils", "ProviderSpecificHeader"),
- "ProviderSpecificHeaderUtils": (
- "litellm.litellm_core_utils.get_provider_specific_headers",
- "ProviderSpecificHeaderUtils",
- ),
- "REASONING_EFFORT": ("litellm.assistants.main", "REASONING_EFFORT"),
- "RateLimitError": ("litellm.exceptions", "RateLimitError"),
- "RateLimitErrorCategory": ("litellm.exceptions", "RateLimitErrorCategory"),
- "RateLimitType": ("litellm.exceptions", "RateLimitType"),
- "RawRequestTypedDict": ("litellm.types.utils", "RawRequestTypedDict"),
- "ReadOnly": ("litellm.files.main", "ReadOnly"),
- "Reasoning": ("litellm.responses.main", "Reasoning"),
- "ReasoningSummaryPartDoneEvent": ("litellm.types.llms.openai", "ReasoningSummaryPartDoneEvent"),
- "ReasoningSummaryTextDeltaEvent": ("litellm.types.llms.openai", "ReasoningSummaryTextDeltaEvent"),
- "ReasoningSummaryTextDoneEvent": ("litellm.types.llms.openai", "ReasoningSummaryTextDoneEvent"),
- "RefusalDeltaEvent": ("litellm.types.llms.openai", "RefusalDeltaEvent"),
- "RefusalDoneEvent": ("litellm.types.llms.openai", "RefusalDoneEvent"),
- "RequestType": ("litellm.types.router", "RequestType"),
- "Required": ("litellm.files.main", "Required"),
- "Response": ("litellm.assistants.main", "Response"),
- "ResponseAPIUsage": ("litellm.types.llms.openai", "ResponseAPIUsage"),
- "ResponseCompletedEvent": ("litellm.types.llms.openai", "ResponseCompletedEvent"),
- "ResponseCreatedEvent": ("litellm.types.llms.openai", "ResponseCreatedEvent"),
- "ResponseFailedEvent": ("litellm.types.llms.openai", "ResponseFailedEvent"),
- "ResponseFunctionToolCall": ("litellm.responses.main", "ResponseFunctionToolCall"),
- "ResponseInProgressEvent": ("litellm.types.llms.openai", "ResponseInProgressEvent"),
- "ResponseIncludable": ("litellm.responses.main", "ResponseIncludable"),
- "ResponseIncompleteEvent": ("litellm.types.llms.openai", "ResponseIncompleteEvent"),
- "ResponseInputParam": ("litellm.responses.main", "ResponseInputParam"),
- "ResponseOutputItem": ("litellm.assistants.main", "ResponseOutputItem"),
- "ResponsePartAddedEvent": ("litellm.types.llms.openai", "ResponsePartAddedEvent"),
- "ResponseText": ("litellm.responses.main", "ResponseText"),
- "ResponsesAPIOptionalRequestParams": ("litellm.types.llms.openai", "ResponsesAPIOptionalRequestParams"),
- "ResponsesAPIRequestParams": ("litellm.types.llms.openai", "ResponsesAPIRequestParams"),
- "ResponsesAPIRequestUtils": ("litellm.responses.utils", "ResponsesAPIRequestUtils"),
- "ResponsesAPIResponse": ("litellm.types.llms.openai", "ResponsesAPIResponse"),
- "ResponsesAPIStatus": ("litellm.assistants.main", "ResponsesAPIStatus"),
- "ResponsesAPIStreamEvents": ("litellm.types.llms.openai", "ResponsesAPIStreamEvents"),
- "ResponsesAPIStreamOptions": ("litellm.types.llms.openai", "ResponsesAPIStreamOptions"),
- "ResponsesAPIStreamingResponse": ("litellm.assistants.main", "ResponsesAPIStreamingResponse"),
- "ResponsesToolUsage": ("litellm.types.llms.openai", "ResponsesToolUsage"),
- "RetrieveBatchRequest": ("litellm.types.llms.openai", "RetrieveBatchRequest"),
- "RetryPolicy": ("litellm.types.router", "RetryPolicy"),
- "Router": ("litellm.router", "Router"),
- "RouterCacheEnum": ("litellm.types.router", "RouterCacheEnum"),
- "RouterConfig": ("litellm.types.router", "RouterConfig"),
- "RouterErrors": ("litellm.types.router", "RouterErrors"),
- "RouterGeneralSettings": ("litellm.types.router", "RouterGeneralSettings"),
- "RouterModelGroupAliasItem": ("litellm.types.router", "RouterModelGroupAliasItem"),
- "RouterRateLimitError": ("litellm.types.router", "RouterRateLimitError"),
- "RouterRateLimitErrorBasic": ("litellm.types.router", "RouterRateLimitErrorBasic"),
- "RoutingContext": ("litellm.types.router", "RoutingContext"),
- "RoutingGroup": ("litellm.types.router", "RoutingGroup"),
- "RoutingPlugin": ("litellm.types.router", "RoutingPlugin"),
- "RoutingStrategy": ("litellm.types.router", "RoutingStrategy"),
- "Run": ("litellm.assistants.main", "Run"),
- "SPECIAL_MODEL_INFO_PARAMS": ("litellm.files.main", "SPECIAL_MODEL_INFO_PARAMS"),
- "SagemakerChatHandler": ("litellm.llms.sagemaker.chat.handler", "SagemakerChatHandler"),
- "SagemakerLLM": ("litellm.llms.sagemaker.completion.handler", "SagemakerLLM"),
- "Scheduler": ("litellm.scheduler", "Scheduler"),
- "SchedulerCacheKeys": ("litellm.scheduler", "SchedulerCacheKeys"),
- "SearchProvider": ("litellm.files.main", "SearchProvider"),
- "SearchResponse": ("litellm.llms.base_llm.search.transformation", "SearchResponse"),
- "SearchToolInfoTypedDict": ("litellm.types.router", "SearchToolInfoTypedDict"),
- "SearchToolLiteLLMParams": ("litellm.types.router", "SearchToolLiteLLMParams"),
- "SearchToolTypedDict": ("litellm.types.router", "SearchToolTypedDict"),
- "SerializerFunctionWrapHandler": ("litellm.assistants.main", "SerializerFunctionWrapHandler"),
- "ServiceUnavailableError": ("litellm.exceptions", "ServiceUnavailableError"),
- "ShellToolParam": ("litellm.types.llms.openai", "ShellToolParam"),
- "SlackAlerting": ("litellm.integrations.SlackAlerting.slack_alerting", "SlackAlerting"),
- "StandardLoggingRoutingDecision": ("litellm.types.utils", "StandardLoggingRoutingDecision"),
- "StreamingChoices": ("litellm.types.utils", "StreamingChoices"),
- "SyncCursorPage": ("litellm.assistants.main", "SyncCursorPage"),
- "TaggedPreRoutingStrategy": ("litellm.types.router", "TaggedPreRoutingStrategy"),
- "TextChoices": ("litellm.types.utils", "TextChoices"),
- "TextCompletionStreamWrapper": ("litellm.utils", "TextCompletionStreamWrapper"),
- "Thread": ("litellm.types.llms.openai", "Thread"),
- "ThreadPoolExecutor": ("litellm.batch_completion.main", "ThreadPoolExecutor"),
- "Timeout": ("litellm.exceptions", "Timeout"),
- "TogetherAIRerank": ("litellm.llms.together_ai.rerank.handler", "TogetherAIRerank"),
- "Tool": ("litellm.assistants.main", "Tool"),
- "ToolChoice": ("litellm.responses.main", "ToolChoice"),
- "ToolMessageContentPart": ("litellm.assistants.main", "ToolMessageContentPart"),
- "ToolParam": ("litellm.responses.main", "ToolParam"),
- "ToolResourcesCodeInterpreter": ("litellm.types.llms.openai", "ToolResourcesCodeInterpreter"),
- "ToolResourcesFileSearch": ("litellm.types.llms.openai", "ToolResourcesFileSearch"),
- "ToolResourcesFileSearchVectorStore": ("litellm.types.llms.openai", "ToolResourcesFileSearchVectorStore"),
- "TopazModelInfo": ("litellm.llms.topaz.common_utils", "TopazModelInfo"),
- "TypeAlias": ("litellm.assistants.main", "TypeAlias"),
- "TypeVar": ("litellm.files.main", "TypeVar"),
- "TypedDict": ("litellm.files.main", "TypedDict"),
- "UnprocessableEntityError": ("litellm.exceptions", "UnprocessableEntityError"),
- "UnsupportedParamsError": ("litellm.exceptions", "UnsupportedParamsError"),
- "UpdateRouterConfig": ("litellm.types.router", "UpdateRouterConfig"),
- "Usage": ("litellm.types.utils", "Usage"),
- "VALID_LITELLM_ENVIRONMENTS": ("litellm.files.main", "VALID_LITELLM_ENVIRONMENTS"),
- "ValidAssistantMessageContentTypes": ("litellm.assistants.main", "ValidAssistantMessageContentTypes"),
- "ValidAssistantMessageContentTypesLiteral": (
- "litellm.assistants.main",
- "ValidAssistantMessageContentTypesLiteral",
- ),
- "ValidChatCompletionMessageContentTypes": ("litellm.assistants.main", "ValidChatCompletionMessageContentTypes"),
- "ValidChatCompletionMessageContentTypesLiteral": (
- "litellm.assistants.main",
- "ValidChatCompletionMessageContentTypesLiteral",
- ),
- "ValidUserMessageContentTypes": ("litellm.assistants.main", "ValidUserMessageContentTypes"),
- "ValidUserMessageContentTypesLiteral": ("litellm.assistants.main", "ValidUserMessageContentTypesLiteral"),
- "VectorStoreIndexRegistry": ("litellm.vector_stores.vector_store_registry", "VectorStoreIndexRegistry"),
- "VectorStoreRegistry": ("litellm.vector_stores.vector_store_registry", "VectorStoreRegistry"),
- "VertexAIBatchPrediction": ("litellm.llms.vertex_ai.batches.handler", "VertexAIBatchPrediction"),
- "VertexAIFilesHandler": ("litellm.llms.vertex_ai.files.handler", "VertexAIFilesHandler"),
- "VertexAIGemmaModels": ("litellm.llms.vertex_ai.vertex_gemma_models.main", "VertexAIGemmaModels"),
- "VertexAIModelGardenModels": ("litellm.llms.vertex_ai.vertex_model_garden.main", "VertexAIModelGardenModels"),
- "VertexAIModelRoute": ("litellm.llms.vertex_ai.common_utils", "VertexAIModelRoute"),
- "VertexAIPartnerModels": ("litellm.llms.vertex_ai.vertex_ai_partner_models.main", "VertexAIPartnerModels"),
- "VertexAITextEmbeddingConfig": (
- "litellm.llms.vertex_ai.vertex_embeddings.transformation",
- "VertexAITextEmbeddingConfig",
- ),
- "VertexEmbedding": ("litellm.llms.vertex_ai.vertex_embeddings.embedding_handler", "VertexEmbedding"),
- "VertexFineTuningAPI": ("litellm.llms.vertex_ai.fine_tuning.handler", "VertexFineTuningAPI"),
- "VertexImageGeneration": (
- "litellm.llms.vertex_ai.image_generation.image_generation_handler",
- "VertexImageGeneration",
- ),
- "VertexLLM": ("litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_gemini", "VertexLLM"),
- "VertexMultimodalEmbedding": (
- "litellm.llms.vertex_ai.multimodal_embeddings.embedding_handler",
- "VertexMultimodalEmbedding",
- ),
- "VideoCreateOptionalRequestParams": ("litellm.types.videos.main", "VideoCreateOptionalRequestParams"),
- "VideoGenerationRequestUtils": ("litellm.videos.utils", "VideoGenerationRequestUtils"),
- "VideoObject": ("litellm.types.videos.main", "VideoObject"),
- "WatsonXChatHandler": ("litellm.llms.watsonx.chat.handler", "WatsonXChatHandler"),
- "WebSearchCallCompletedEvent": ("litellm.types.llms.openai", "WebSearchCallCompletedEvent"),
- "WebSearchCallInProgressEvent": ("litellm.types.llms.openai", "WebSearchCallInProgressEvent"),
- "WebSearchCallSearchingEvent": ("litellm.types.llms.openai", "WebSearchCallSearchingEvent"),
- "WebSearchOptions": ("litellm.types.llms.openai", "WebSearchOptions"),
- "WebSearchOptionsUserLocation": ("litellm.types.llms.openai", "WebSearchOptionsUserLocation"),
- "WebSearchOptionsUserLocationApproximate": (
- "litellm.types.llms.openai",
- "WebSearchOptionsUserLocationApproximate",
- ),
- "WebSearchToolUsage": ("litellm.types.llms.openai", "WebSearchToolUsage"),
- "XAIModelInfo": ("litellm.llms.xai.common_utils", "XAIModelInfo"),
- "_arealtime": ("litellm.realtime_api.main", "_arealtime"),
- "_aresponses_websocket": ("litellm.responses.main", "_aresponses_websocket"),
- "a_add_message": ("litellm.assistants.main", "a_add_message"),
- "aadapter_completion": ("litellm.main", "aadapter_completion"),
- "aadapter_generate_content": ("litellm.main", "aadapter_generate_content"),
- "acancel_batch": ("litellm.batches.main", "acancel_batch"),
- "acancel_fine_tuning_job": ("litellm.fine_tuning.main", "acancel_fine_tuning_job"),
- "acancel_responses": ("litellm.responses.main", "acancel_responses"),
- "acode_interpreter_tool": ("litellm.sandbox.main", "acode_interpreter_tool"),
- "acompact_responses": ("litellm.responses.main", "acompact_responses"),
- "acompletion": ("litellm.main", "acompletion"),
- "acompletion_with_retries": ("litellm.main", "acompletion_with_retries"),
- "acount_tokens": ("litellm.main", "acount_tokens"),
- "acreate_agent": ("litellm.interactions.agents.main", "acreate"),
- "acreate_assistants": ("litellm.assistants.main", "acreate_assistants"),
- "acreate_batch": ("litellm.batches.main", "acreate_batch"),
- "acreate_container": ("litellm.containers.main", "acreate_container"),
- "acreate_file": ("litellm.files.main", "acreate_file"),
- "acreate_fine_tuning_job": ("litellm.fine_tuning.main", "acreate_fine_tuning_job"),
- "acreate_realtime_client_secret": ("litellm.realtime_api.main", "acreate_realtime_client_secret"),
- "acreate_realtime_transcription_session": (
- "litellm.realtime_api.main",
- "acreate_realtime_transcription_session",
- ),
- "acreate_sandbox": ("litellm.sandbox.main", "acreate_sandbox"),
- "acreate_skill": ("litellm.skills.main", "acreate_skill"),
- "acreate_thread": ("litellm.assistants.main", "acreate_thread"),
- "adapter_completion": ("litellm.main", "adapter_completion"),
- "add_message": ("litellm.assistants.main", "add_message"),
- "add_provider_specific_params_to_optional_params": (
- "litellm.utils",
- "add_provider_specific_params_to_optional_params",
- ),
- "add_system_prompt_to_messages": (
- "litellm.litellm_core_utils.prompt_templates.common_utils",
- "add_system_prompt_to_messages",
- ),
- "add_trusted_model_credentials_to_litellm_params": (
- "litellm.litellm_core_utils.get_litellm_params",
- "add_trusted_model_credentials_to_litellm_params",
- ),
- "adelete_agent": ("litellm.interactions.agents.main", "adelete"),
- "adelete_assistant": ("litellm.assistants.main", "adelete_assistant"),
- "adelete_container": ("litellm.containers.main", "adelete_container"),
- "adelete_responses": ("litellm.responses.main", "adelete_responses"),
- "adelete_sandbox": ("litellm.sandbox.main", "adelete_sandbox"),
- "adelete_skill": ("litellm.skills.main", "adelete_skill"),
- "aembedding": ("litellm.main", "aembedding"),
- "afile_content": ("litellm.files.main", "afile_content"),
- "afile_delete": ("litellm.files.main", "afile_delete"),
- "afile_list": ("litellm.files.main", "afile_list"),
- "afile_retrieve": ("litellm.files.main", "afile_retrieve"),
- "agenerate_content": ("litellm.google_genai.main", "agenerate_content"),
- "aget_agent": ("litellm.interactions.agents.main", "aget"),
- "aget_assistants": ("litellm.assistants.main", "aget_assistants"),
- "aget_messages": ("litellm.assistants.main", "aget_messages"),
- "aget_responses": ("litellm.responses.main", "aget_responses"),
- "aget_skill": ("litellm.skills.main", "aget_skill"),
- "aget_thread": ("litellm.assistants.main", "aget_thread"),
- "ahealth_check": ("litellm.main", "ahealth_check"),
- "aimage_edit": ("litellm.images.main", "aimage_edit"),
- "aimage_generation": ("litellm.images.main", "aimage_generation"),
- "aimage_variation": ("litellm.images.main", "aimage_variation"),
- "aingest": ("litellm.rag.main", "aingest"),
- "alist_agent_versions": ("litellm.interactions.agents.main", "alist_versions"),
- "alist_agents": ("litellm.interactions.agents.main", "alist"),
- "alist_batches": ("litellm.batches.main", "alist_batches"),
- "alist_container_files": ("litellm.containers.main", "alist_container_files"),
- "alist_containers": ("litellm.containers.main", "alist_containers"),
- "alist_fine_tuning_jobs": ("litellm.fine_tuning.main", "alist_fine_tuning_jobs"),
- "alist_input_items": ("litellm.responses.main", "alist_input_items"),
- "alist_skills": ("litellm.skills.main", "alist_skills"),
- "allm_passthrough_route": ("litellm.passthrough.main", "allm_passthrough_route"),
- "amoderation": ("litellm.main", "amoderation"),
- "anthropic_batches_instance": ("litellm.batches.main", "anthropic_batches_instance"),
- "anthropic_chat_completions": ("litellm.main", "anthropic_chat_completions"),
- "anthropic_messages": (
- "litellm.llms.anthropic.experimental_pass_through.messages.handler",
- "anthropic_messages",
- ),
- "anthropic_messages_handler": (
- "litellm.llms.anthropic.experimental_pass_through.messages.handler",
- "anthropic_messages_handler",
- ),
- "aocr": ("litellm.ocr.main", "aocr"),
- "aquery": ("litellm.rag.main", "aquery"),
- "arealtime_calls": ("litellm.realtime_api.main", "arealtime_calls"),
- "arerank": ("litellm.rerank_api.main", "arerank"),
- "aresponses": ("litellm.responses.main", "aresponses"),
- "aresponses_api_with_mcp": ("litellm.responses.main", "aresponses_api_with_mcp"),
- "aresponses_with_retries": ("litellm.main", "aresponses_with_retries"),
- "aretrieve_batch": ("litellm.batches.main", "aretrieve_batch"),
- "aretrieve_container": ("litellm.containers.main", "aretrieve_container"),
- "aretrieve_fine_tuning_job": ("litellm.fine_tuning.main", "aretrieve_fine_tuning_job"),
- "arun_code": ("litellm.sandbox.main", "arun_code"),
- "arun_thread": ("litellm.assistants.main", "arun_thread"),
- "arun_thread_stream": ("litellm.assistants.main", "arun_thread_stream"),
- "asearch": ("litellm.search.main", "asearch"),
- "aspeech": ("litellm.main", "aspeech"),
- "async_completion_with_fallbacks": (
- "litellm.litellm_core_utils.fallback_utils",
- "async_completion_with_fallbacks",
- ),
- "async_mock_completion_streaming_obj": ("litellm.utils", "async_mock_completion_streaming_obj"),
- "atext_completion": ("litellm.main", "atext_completion"),
- "atranscription": ("litellm.main", "atranscription"),
- "aupload_container_file": ("litellm.containers.main", "aupload_container_file"),
- "avector_store_file_content": ("litellm.vector_store_files.main", "aretrieve_content"),
- "avector_store_file_create": ("litellm.vector_store_files.main", "acreate"),
- "avector_store_file_delete": ("litellm.vector_store_files.main", "adelete"),
- "avector_store_file_list": ("litellm.vector_store_files.main", "alist"),
- "avector_store_file_retrieve": ("litellm.vector_store_files.main", "aretrieve"),
- "avector_store_file_update": ("litellm.vector_store_files.main", "aupdate"),
- "avideo_content": ("litellm.videos.main", "avideo_content"),
- "avideo_create_character": ("litellm.videos.main", "avideo_create_character"),
- "avideo_edit": ("litellm.videos.main", "avideo_edit"),
- "avideo_extension": ("litellm.videos.main", "avideo_extension"),
- "avideo_generation": ("litellm.videos.main", "avideo_generation"),
- "avideo_get_character": ("litellm.videos.main", "avideo_get_character"),
- "avideo_list": ("litellm.videos.main", "avideo_list"),
- "avideo_remix": ("litellm.videos.main", "avideo_remix"),
- "avideo_status": ("litellm.videos.main", "avideo_status"),
- "azure_ai_embedding": ("litellm.main", "azure_ai_embedding"),
- "azure_anthropic_chat_completions": ("litellm.main", "azure_anthropic_chat_completions"),
- "azure_assistants_api": ("litellm.assistants.main", "azure_assistants_api"),
- "azure_audio_transcriptions": ("litellm.main", "azure_audio_transcriptions"),
- "azure_batches_instance": ("litellm.batches.main", "azure_batches_instance"),
- "azure_chat_completions": ("litellm.images.main", "azure_chat_completions"),
- "azure_files_instance": ("litellm.files.main", "azure_files_instance"),
- "azure_fine_tuning_apis_instance": ("litellm.fine_tuning.main", "azure_fine_tuning_apis_instance"),
- "azure_o1_chat_completions": ("litellm.main", "azure_o1_chat_completions"),
- "azure_text_completions": ("litellm.main", "azure_text_completions"),
- "base_llm_aiohttp_handler": ("litellm.images.main", "base_llm_aiohttp_handler"),
- "base_llm_http_handler": ("litellm.files.main", "base_llm_http_handler"),
- "batch_completion": ("litellm.batch_completion.main", "batch_completion"),
- "batch_completion_models": ("litellm.batch_completion.main", "batch_completion_models"),
- "batch_completion_models_all_responses": (
- "litellm.batch_completion.main",
- "batch_completion_models_all_responses",
- ),
- "bedrock_converse_chat_completion": ("litellm.main", "bedrock_converse_chat_completion"),
- "bedrock_embedding": ("litellm.main", "bedrock_embedding"),
- "bedrock_files_instance": ("litellm.files.main", "bedrock_files_instance"),
- "bedrock_image_edit": ("litellm.images.main", "bedrock_image_edit"),
- "bedrock_image_generation": ("litellm.images.main", "bedrock_image_generation"),
- "bedrock_rerank": ("litellm.rerank_api.main", "bedrock_rerank"),
- "bfl_image_edit": ("litellm.llms.black_forest_labs.image_edit.handler", "bfl_image_edit"),
- "bfl_image_generation": ("litellm.llms.black_forest_labs.image_generation.handler", "bfl_image_generation"),
- "build_code_interpreter_log_outputs": ("litellm.types.responses.main", "build_code_interpreter_log_outputs"),
- "bytez_transformation": ("litellm.main", "bytez_transformation"),
- "calculate_request_duration": ("litellm.litellm_core_utils.audio_utils.utils", "calculate_request_duration"),
- "cancel_batch": ("litellm.batches.main", "cancel_batch"),
- "cancel_fine_tuning_job": ("litellm.fine_tuning.main", "cancel_fine_tuning_job"),
- "cancel_responses": ("litellm.responses.main", "cancel_responses"),
- "cast": ("litellm.files.main", "cast"),
- "client": ("litellm.utils", "client"),
- "close_litellm_async_clients": (
- "litellm.llms.custom_httpx.async_client_cleanup",
- "close_litellm_async_clients",
- ),
- "codestral_text_completions": ("litellm.main", "codestral_text_completions"),
- "compact_responses": ("litellm.responses.main", "compact_responses"),
- "completion": ("litellm.main", "completion"),
- "completion_with_fallbacks": ("litellm.litellm_core_utils.fallback_utils", "completion_with_fallbacks"),
- "completion_with_retries": ("litellm.main", "completion_with_retries"),
- "compress": ("litellm.compression.compress", "compress"),
- "config_completion": ("litellm.main", "config_completion"),
- "contextmanager": ("litellm.responses.main", "contextmanager"),
- "convert_file_document_to_url_document": ("litellm.ocr.main", "convert_file_document_to_url_document"),
- "convert_model_response_to_streaming": (
- "litellm.llms.base_llm.base_model_iterator",
- "convert_model_response_to_streaming",
- ),
- "create_agent": ("litellm.interactions.agents.main", "create"),
- "create_assistants": ("litellm.assistants.main", "create_assistants"),
- "create_batch": ("litellm.batches.main", "create_batch"),
- "create_container": ("litellm.containers.main", "create_container"),
- "create_file": ("litellm.files.main", "create_file"),
- "create_fine_tuning_job": ("litellm.fine_tuning.main", "create_fine_tuning_job"),
- "create_skill": ("litellm.skills.main", "create_skill"),
- "create_thread": ("litellm.assistants.main", "create_thread"),
- "custom_chat_llm_router": ("litellm.llms.custom_llm", "custom_chat_llm_router"),
- "custom_prompt": ("litellm.litellm_core_utils.prompt_templates.factory", "custom_prompt"),
- "databricks_embedding": ("litellm.main", "databricks_embedding"),
- "dataclass": ("litellm.files.main", "dataclass"),
- "decode_video_id_with_provider": ("litellm.types.videos.utils", "decode_video_id_with_provider"),
- "declared_authenticating_provider": (
- "litellm.litellm_core_utils.get_llm_provider_logic",
- "declared_authenticating_provider",
- ),
- "deepcopy": ("litellm.main", "deepcopy"),
- "delete_agent": ("litellm.interactions.agents.main", "delete"),
- "delete_assistant": ("litellm.assistants.main", "delete_assistant"),
- "delete_container": ("litellm.containers.main", "delete_container"),
- "delete_responses": ("litellm.responses.main", "delete_responses"),
- "delete_skill": ("litellm.skills.main", "delete_skill"),
- "disable_cache": ("litellm.caching.caching", "disable_cache"),
- "embedding": ("litellm.main", "embedding"),
- "enable_cache": ("litellm.caching.caching", "enable_cache"),
- "field_serializer": ("litellm.assistants.main", "field_serializer"),
- "field_validator": ("litellm.files.main", "field_validator"),
- "file_content": ("litellm.files.main", "file_content"),
- "file_content_streaming": ("litellm.files.main", "file_content_streaming"),
- "file_delete": ("litellm.files.main", "file_delete"),
- "file_list": ("litellm.files.main", "file_list"),
- "file_retrieve": ("litellm.files.main", "file_retrieve"),
- "filter_out_litellm_params": ("litellm.utils", "filter_out_litellm_params"),
- "flatten_form_field_values": ("litellm.litellm_core_utils.llm_request_utils", "flatten_form_field_values"),
- "flatten_unencrypted_web_search_results_in_anthropic_messages": (
- "litellm.llms.anthropic.common_utils",
- "flatten_unencrypted_web_search_results_in_anthropic_messages",
- ),
- "function_call_prompt": ("litellm.litellm_core_utils.prompt_templates.factory", "function_call_prompt"),
- "gdc_transformation": ("litellm.main", "gdc_transformation"),
- "get_agent": ("litellm.interactions.agents.main", "get"),
- "get_api_key_from_env": ("litellm.llms.gemini.common_utils", "get_api_key_from_env"),
- "get_assistants": ("litellm.assistants.main", "get_assistants"),
- "get_audio_file_for_health_check": (
- "litellm.litellm_core_utils.audio_utils.utils",
- "get_audio_file_for_health_check",
- ),
- "get_azure_credentials": ("litellm.llms.azure.common_utils", "get_azure_credentials"),
- "get_completion_messages": (
- "litellm.litellm_core_utils.prompt_templates.common_utils",
- "get_completion_messages",
- ),
- "get_configured_request_timeout": (
- "litellm.litellm_core_utils.request_timeout_resolver",
- "get_configured_request_timeout",
- ),
- "get_content_from_model_response": (
- "litellm.litellm_core_utils.prompt_templates.common_utils",
- "get_content_from_model_response",
- ),
- "get_litellm_gateway_api_key": ("litellm.litellm_core_utils.cli_token_utils", "get_litellm_gateway_api_key"),
- "get_messages": ("litellm.assistants.main", "get_messages"),
- "get_messages_interceptors": (
- "litellm.llms.anthropic.experimental_pass_through.messages.interceptors",
- "get_messages_interceptors",
- ),
- "get_mime_type": ("litellm.ocr.main", "get_mime_type"),
- "get_non_default_completion_params": ("litellm.utils", "get_non_default_completion_params"),
- "get_non_default_transcription_params": ("litellm.utils", "get_non_default_transcription_params"),
- "get_openai_credentials": ("litellm.llms.openai.common_utils", "get_openai_credentials"),
- "get_optional_params_add_message": ("litellm.assistants.utils", "get_optional_params_add_message"),
- "get_optional_params_embeddings": ("litellm.utils", "get_optional_params_embeddings"),
- "get_optional_params_image_gen": ("litellm.utils", "get_optional_params_image_gen"),
- "get_optional_params_transcription": ("litellm.utils", "get_optional_params_transcription"),
- "get_optional_rerank_params": ("litellm.rerank_api.rerank_utils", "get_optional_rerank_params"),
- "get_requester_metadata": ("litellm.utils", "get_requester_metadata"),
- "get_responses": ("litellm.responses.main", "get_responses"),
- "get_secret": ("litellm.secret_managers.main", "get_secret"),
- "get_secret_bool": ("litellm.secret_managers.main", "get_secret_bool"),
- "get_secret_str": ("litellm.secret_managers.main", "get_secret_str"),
- "get_skill": ("litellm.skills.main", "get_skill"),
- "get_standard_openai_params": ("litellm.utils", "get_standard_openai_params"),
- "get_thread": ("litellm.assistants.main", "get_thread"),
- "get_type_hints": ("litellm.files.main", "get_type_hints"),
- "get_vertex_ai_model_route": ("litellm.llms.vertex_ai.common_utils", "get_vertex_ai_model_route"),
- "google_batch_embeddings": ("litellm.main", "google_batch_embeddings"),
- "groq_chat_completions": ("litellm.main", "groq_chat_completions"),
- "heroku_transformation": ("litellm.main", "heroku_transformation"),
- "huggingface_embed": ("litellm.main", "huggingface_embed"),
- "image_edit": ("litellm.images.main", "image_edit"),
- "image_generation": ("litellm.images.main", "image_generation"),
- "image_variation": ("litellm.images.main", "image_variation"),
- "infer_openai_data_residency": ("litellm.llms.openai.data_residency", "infer_openai_data_residency"),
- "ingest": ("litellm.rag.main", "ingest"),
- "is_azure_document_intelligence_model": (
- "litellm.llms.azure_ai.ocr.common_utils",
- "is_azure_document_intelligence_model",
- ),
- "is_reasoning_auto_summary_enabled": (
- "litellm.llms.anthropic.experimental_pass_through.utils",
- "is_reasoning_auto_summary_enabled",
- ),
- "lemonade_transformation": ("litellm.main", "lemonade_transformation"),
- "list_agent_versions": ("litellm.interactions.agents.main", "list_versions"),
- "list_agents": ("litellm.interactions.agents.main", "list"),
- "list_batches": ("litellm.batches.main", "list_batches"),
- "list_container_files": ("litellm.containers.main", "list_container_files"),
- "list_containers": ("litellm.containers.main", "list_containers"),
- "list_fine_tuning_jobs": ("litellm.fine_tuning.main", "list_fine_tuning_jobs"),
- "list_input_items": ("litellm.responses.main", "list_input_items"),
- "list_skills": ("litellm.skills.main", "list_skills"),
- "litellm_completion_transformation_handler": (
- "litellm.responses.main",
- "litellm_completion_transformation_handler",
- ),
- "llm_http_handler": ("litellm.videos.main", "llm_http_handler"),
- "llm_passthrough_route": ("litellm.passthrough.main", "llm_passthrough_route"),
- "map_system_message_pt": ("litellm.litellm_core_utils.prompt_templates.factory", "map_system_message_pt"),
- "maybe_run_chat_completion_agentic_loop": (
- "litellm.litellm_core_utils.chat_completion_agentic_loop",
- "maybe_run_chat_completion_agentic_loop",
- ),
- "mock_completion": ("litellm.main", "mock_completion"),
- "mock_completion_streaming_obj": ("litellm.utils", "mock_completion_streaming_obj"),
- "mock_embedding": ("litellm.litellm_core_utils.mock_functions", "mock_embedding"),
- "mock_image_generation": ("litellm.litellm_core_utils.mock_functions", "mock_image_generation"),
- "mock_response": ("litellm.llms.anthropic.experimental_pass_through.messages.utils", "mock_response"),
- "mock_responses_api_response": ("litellm.responses.main", "mock_responses_api_response"),
- "model_serializer": ("litellm.assistants.main", "model_serializer"),
- "model_validator": ("litellm.files.main", "model_validator"),
- "moderation": ("litellm.main", "moderation"),
- "nlp_cloud_chat_completion": ("litellm.main", "nlp_cloud_chat_completion"),
- "nvidia_riva_audio_transcriptions": ("litellm.main", "nvidia_riva_audio_transcriptions"),
- "oci_transformation": ("litellm.main", "oci_transformation"),
- "ocr": ("litellm.ocr.main", "ocr"),
- "ollama_pt": ("litellm.litellm_core_utils.prompt_templates.factory", "ollama_pt"),
- "openai_assistants_api": ("litellm.assistants.main", "openai_assistants_api"),
- "openai_audio_transcriptions": ("litellm.main", "openai_audio_transcriptions"),
- "openai_batches_instance": ("litellm.batches.main", "openai_batches_instance"),
- "openai_chat_completions": ("litellm.images.main", "openai_chat_completions"),
- "openai_files_instance": ("litellm.files.main", "openai_files_instance"),
- "openai_fine_tuning_apis_instance": ("litellm.fine_tuning.main", "openai_fine_tuning_apis_instance"),
- "openai_image_variations": ("litellm.images.main", "openai_image_variations"),
- "openai_like_chat_completion": ("litellm.main", "openai_like_chat_completion"),
- "openai_like_embedding": ("litellm.main", "openai_like_embedding"),
- "openai_text_completions": ("litellm.main", "openai_text_completions"),
- "override": ("litellm.assistants.main", "override"),
- "ovhcloud_transformation": ("litellm.main", "ovhcloud_transformation"),
- "parse_ocr_request_format": ("litellm.llms.base_llm.ocr.transformation", "parse_ocr_request_format"),
- "partial": ("litellm.files.main", "partial"),
- "peek_reasoning_summary_aliases": ("litellm.utils", "peek_reasoning_summary_aliases"),
- "pre_process_non_default_params": ("litellm.utils", "pre_process_non_default_params"),
- "predibase_chat_completions": ("litellm.main", "predibase_chat_completions"),
- "print_verbose": ("litellm.main", "print_verbose"),
- "prompt_factory": ("litellm.litellm_core_utils.prompt_templates.factory", "prompt_factory"),
- "query": ("litellm.rag.main", "query"),
- "read_config_args": ("litellm.utils", "read_config_args"),
- "replicate_chat_completion": ("litellm.main", "replicate_chat_completion"),
- "rerank": ("litellm.rerank_api.main", "rerank"),
- "responses": ("litellm.responses.main", "responses"),
- "responses_api_bridge_check": ("litellm.main", "responses_api_bridge_check"),
- "responses_with_retries": ("litellm.main", "responses_with_retries"),
- "retrieve_batch": ("litellm.batches.main", "retrieve_batch"),
- "retrieve_container": ("litellm.containers.main", "retrieve_container"),
- "retrieve_fine_tuning_job": ("litellm.fine_tuning.main", "retrieve_fine_tuning_job"),
- "run_async_function": ("litellm.litellm_core_utils.asyncify", "run_async_function"),
- "run_server": ("litellm.proxy.proxy_cli", "run_server"),
- "run_thread": ("litellm.assistants.main", "run_thread"),
- "run_thread_stream": ("litellm.assistants.main", "run_thread_stream"),
- "runtime_checkable": ("litellm.files.main", "runtime_checkable"),
- "rust": ("litellm.rust_bridge", "rust"),
- "safe_deep_copy": ("litellm.litellm_core_utils.core_helpers", "safe_deep_copy"),
- "sagemaker_chat_completion": ("litellm.main", "sagemaker_chat_completion"),
- "sagemaker_llm": ("litellm.main", "sagemaker_llm"),
- "sanitize_tool_use_ids_in_anthropic_messages": (
- "litellm.llms.anthropic.common_utils",
- "sanitize_tool_use_ids_in_anthropic_messages",
- ),
- "sap_gen_ai_hub_chat_completions": ("litellm.main", "sap_gen_ai_hub_chat_completions"),
- "sap_gen_ai_hub_emb": ("litellm.main", "sap_gen_ai_hub_emb"),
- "search": ("litellm.search.main", "search"),
- "should_run_mock_completion": ("litellm.utils", "should_run_mock_completion"),
- "speech": ("litellm.main", "speech"),
- "stream_chunk_builder": ("litellm.main", "stream_chunk_builder"),
- "stream_chunk_builder_text_completion": ("litellm.main", "stream_chunk_builder_text_completion"),
- "stringify_json_tool_call_content": (
- "litellm.litellm_core_utils.prompt_templates.factory",
- "stringify_json_tool_call_content",
- ),
- "strip_empty_content_blocks_from_anthropic_messages": (
- "litellm.llms.anthropic.common_utils",
- "strip_empty_content_blocks_from_anthropic_messages",
- ),
- "strip_reasoning_summary_aliases_from_optional_params": (
- "litellm.utils",
- "strip_reasoning_summary_aliases_from_optional_params",
- ),
- "supports_httpx_timeout": ("litellm.utils", "supports_httpx_timeout"),
- "text_completion": ("litellm.main", "text_completion"),
- "together_rerank": ("litellm.rerank_api.main", "together_rerank"),
- "tracer": ("litellm.litellm_core_utils.dd_tracing", "tracer"),
- "transcription": ("litellm.main", "transcription"),
- "updateDeployment": ("litellm.types.router", "updateDeployment"),
- "updateLiteLLMParams": ("litellm.types.router", "updateLiteLLMParams"),
- "update_cache": ("litellm.caching.caching", "update_cache"),
- "update_messages_with_model_file_ids": (
- "litellm.litellm_core_utils.prompt_templates.common_utils",
- "update_messages_with_model_file_ids",
- ),
- "update_responses_input_with_model_file_ids": (
- "litellm.litellm_core_utils.prompt_templates.common_utils",
- "update_responses_input_with_model_file_ids",
- ),
- "update_responses_tools_with_model_file_ids": (
- "litellm.litellm_core_utils.prompt_templates.common_utils",
- "update_responses_tools_with_model_file_ids",
- ),
- "upload_container_file": ("litellm.containers.main", "upload_container_file"),
- "urlsplit": ("litellm.main", "urlsplit"),
- "validate_and_fix_openai_messages": ("litellm.utils", "validate_and_fix_openai_messages"),
- "validate_and_fix_openai_tools": ("litellm.utils", "validate_and_fix_openai_tools"),
- "validate_and_fix_thinking_param": ("litellm.utils", "validate_and_fix_thinking_param"),
- "validate_anthropic_api_metadata": (
- "litellm.llms.anthropic.experimental_pass_through.messages.handler",
- "validate_anthropic_api_metadata",
- ),
- "validate_chat_completion_tool_choice": ("litellm.utils", "validate_chat_completion_tool_choice"),
- "validate_openai_optional_params": ("litellm.utils", "validate_openai_optional_params"),
- "vector_store_file_content": ("litellm.vector_store_files.main", "retrieve_content"),
- "vector_store_file_create": ("litellm.vector_store_files.main", "create"),
- "vector_store_file_delete": ("litellm.vector_store_files.main", "delete"),
- "vector_store_file_list": ("litellm.vector_store_files.main", "list"),
- "vector_store_file_retrieve": ("litellm.vector_store_files.main", "retrieve"),
- "vector_store_file_update": ("litellm.vector_store_files.main", "update"),
- "vertex_ai_batches_instance": ("litellm.batches.main", "vertex_ai_batches_instance"),
- "vertex_ai_files_instance": ("litellm.files.main", "vertex_ai_files_instance"),
- "vertex_chat_completion": ("litellm.main", "vertex_chat_completion"),
- "vertex_embedding": ("litellm.main", "vertex_embedding"),
- "vertex_fine_tuning_apis_instance": ("litellm.fine_tuning.main", "vertex_fine_tuning_apis_instance"),
- "vertex_gemma_chat_completion": ("litellm.main", "vertex_gemma_chat_completion"),
- "vertex_image_generation": ("litellm.main", "vertex_image_generation"),
- "vertex_model_garden_chat_completion": ("litellm.main", "vertex_model_garden_chat_completion"),
- "vertex_multimodal_embedding": ("litellm.main", "vertex_multimodal_embedding"),
- "vertex_partner_models_chat_completion": ("litellm.main", "vertex_partner_models_chat_completion"),
- "video_content": ("litellm.videos.main", "video_content"),
- "video_create_character": ("litellm.videos.main", "video_create_character"),
- "video_edit": ("litellm.videos.main", "video_edit"),
- "video_extension": ("litellm.videos.main", "video_extension"),
- "video_generation": ("litellm.videos.main", "video_generation"),
- "video_get_character": ("litellm.videos.main", "video_get_character"),
- "video_list": ("litellm.videos.main", "video_list"),
- "video_remix": ("litellm.videos.main", "video_remix"),
- "video_status": ("litellm.videos.main", "video_status"),
- "wait": ("litellm.batch_completion.main", "wait"),
- "watsonx_chat_completion": ("litellm.main", "watsonx_chat_completion"),
- }
-)
-
-_SDK_MODULE_ALIASES: Final[Mapping[str, str]] = MappingProxyType(
- {
- "additional_logging_utils": "litellm.integrations.additional_logging_utils",
- "agentops": "litellm.integrations.agentops",
- "aleph_alpha": "litellm.llms.deprecated_providers.aleph_alpha",
- "anthropic_cache_control_hook": "litellm.integrations.anthropic_cache_control_hook",
- "argilla": "litellm.integrations.argilla",
- "arize": "litellm.integrations.arize",
- "asyncio": "asyncio",
- "athina": "litellm.integrations.athina",
- "azure_sentinel": "litellm.integrations.azure_sentinel",
- "azure_storage": "litellm.integrations.azure_storage",
- "base64": "base64",
- "cohere_embed": "litellm.llms.cohere.embed.handler",
- "contextvars": "contextvars",
- "custom_batch_logger": "litellm.integrations.custom_batch_logger",
- "custom_guardrail": "litellm.integrations.custom_guardrail",
- "custom_logger": "litellm.integrations.custom_logger",
- "custom_prompt_management": "litellm.integrations.custom_prompt_management",
- "datadog": "litellm.integrations.datadog",
- "datetime": "datetime",
- "deepeval": "litellm.integrations.deepeval",
- "dotenv": "dotenv",
- "dotprompt": "litellm.integrations.dotprompt",
- "dynamodb": "litellm.integrations.dynamodb",
- "email_templates": "litellm.integrations.email_templates",
- "enum": "enum",
- "futures": "concurrent.futures",
- "galileo": "litellm.integrations.galileo",
- "gcs_bucket": "litellm.integrations.gcs_bucket",
- "gcs_pubsub": "litellm.integrations.gcs_pubsub",
- "generic_api": "litellm.integrations.generic_api",
- "greenscale": "litellm.integrations.greenscale",
- "heapq": "heapq",
- "helicone": "litellm.integrations.helicone",
- "helicone_mock_client": "litellm.integrations.helicone_mock_client",
- "humanloop": "litellm.integrations.humanloop",
- "importlib": "importlib",
- "inspect": "inspect",
- "json": "json",
- "lago": "litellm.integrations.lago",
- "langfuse": "litellm.integrations.langfuse",
- "langsmith": "litellm.integrations.langsmith",
- "langsmith_mock_client": "litellm.integrations.langsmith_mock_client",
- "litellm": "litellm",
- "litellm_agent": "litellm.integrations.litellm_agent",
- "literal_ai": "litellm.integrations.literal_ai",
- "logfire_logger": "litellm.integrations.logfire_logger",
- "lunary": "litellm.integrations.lunary",
- "mimetypes": "mimetypes",
- "mlflow": "litellm.integrations.mlflow",
- "mock_client_factory": "litellm.integrations.mock_client_factory",
- "newrelic": "litellm.integrations.newrelic",
- "ollama": "litellm.llms.ollama.completion.handler",
- "oobabooga": "litellm.llms.oobabooga.chat.oobabooga",
- "openai": "openai",
- "openmeter": "litellm.integrations.openmeter",
- "opentelemetry": "litellm.integrations.opentelemetry",
- "opentelemetry_utils": "litellm.integrations.opentelemetry_utils",
- "opik": "litellm.integrations.opik",
- "otel": "litellm.integrations.otel",
- "palm": "litellm.llms.deprecated_providers.palm",
- "petals_handler": "litellm.llms.petals.completion.handler",
- "posthog": "litellm.integrations.posthog",
- "posthog_mock_client": "litellm.integrations.posthog_mock_client",
- "prompt_layer": "litellm.integrations.prompt_layer",
- "prompt_management_base": "litellm.integrations.prompt_management_base",
- "random": "random",
- "rust_ocr_bridge": "litellm.rust_bridge.ocr",
- "s3": "litellm.integrations.s3",
- "s3_v2": "litellm.integrations.s3_v2",
- "sqs": "litellm.integrations.sqs",
- "supabase": "litellm.integrations.supabase",
- "sys": "sys",
- "tiktoken": "tiktoken",
- "time": "time",
- "traceback": "traceback",
- "traceloop": "litellm.integrations.traceloop",
- "uuid": "fastuuid",
- "uuid_module": "uuid",
- "vertex_ai_non_gemini": "litellm.llms.vertex_ai.vertex_ai_non_gemini",
- "vllm_handler": "litellm.llms.vllm.completion.handler",
- "anthropic": "litellm.anthropic_interface",
- "httpx": "httpx",
- "interactions": "litellm.interactions",
- "rag": "litellm.rag",
- }
-)
-
# Export all name tuples and import maps for use in _lazy_imports.py
__all__ = [
"BEDROCK_TYPES_NAMES",
@@ -2657,7 +1490,6 @@ __all__ = [
"LLM_CLIENT_CACHE_NAMES",
"LLM_CONFIG_NAMES",
"LLM_PROVIDER_LOGIC_NAMES",
- "STAR_IMPORT_PUBLIC_NAMES",
"TOKEN_COUNTER_NAMES",
"TYPES_NAMES",
"TYPES_UTILS_NAMES",
@@ -2670,1534 +1502,9 @@ __all__ = [
"_LITELLM_LOGGING_IMPORT_MAP",
"_LLM_CONFIGS_IMPORT_MAP",
"_LLM_PROVIDER_LOGIC_IMPORT_MAP",
- "_SDK_MODULE_ALIASES",
- "_SDK_SYMBOLS_IMPORT_MAP",
"_TOKEN_COUNTER_IMPORT_MAP",
"_TYPES_IMPORT_MAP",
"_TYPES_UTILS_IMPORT_MAP",
"_UTILS_IMPORT_MAP",
"_UTILS_MODULE_IMPORT_MAP",
]
-
-
-STAR_IMPORT_PUBLIC_NAMES: Final = (
- "AI21ChatConfig",
- "AI21Config",
- "ALL_RESPONSES_API_TOOL_PARAMS",
- "APIConnectionError",
- "APIError",
- "APIResponseValidationError",
- "AZURE_DEFAULT_API_VERSION",
- "AZURE_OPENAI_AUDIO_PROVIDERS",
- "AdapterCompletionStreamWrapper",
- "AdapterItem",
- "AdaptiveRouterConfig",
- "AdaptiveRouterPreferences",
- "AdaptiveRouterWeights",
- "AlephAlphaConfig",
- "AlertingConfig",
- "AllEmbeddingInputValues",
- "AllMessageValues",
- "AllPromptValues",
- "AllowedFailsPolicy",
- "AmazonTitanV2Config",
- "Annotated",
- "AnthropicBatchesHandler",
- "AnthropicChatCompletion",
- "AnthropicMessagesRequestUtils",
- "AnthropicMessagesResponse",
- "AnthropicMetadata",
- "AnthropicModelInfo",
- "AnthropicThinkingParam",
- "Any",
- "Assistant",
- "AssistantDeleted",
- "AssistantEventHandler",
- "AssistantStreamManager",
- "AssistantToolParam",
- "AssistantsTypedDict",
- "AsyncAssistantEventHandler",
- "AsyncAssistantStreamManager",
- "AsyncCompletions",
- "AsyncCursorPage",
- "AsyncHTTPHandler",
- "AsyncIterator",
- "AsyncOpenAI",
- "Attachment",
- "AttachmentTool",
- "AuthenticationError",
- "AutoRouterCapabilityLimit",
- "AzureAIEmbedding",
- "AzureAnthropicChatCompletion",
- "AzureAssistantsAPI",
- "AzureAudioTranscription",
- "AzureBatchesAPI",
- "AzureChatCompletion",
- "AzureOpenAIFilesAPI",
- "AzureOpenAIFineTuningAPI",
- "AzureOpenAIO1ChatCompletion",
- "AzureTextCompletion",
- "BATCH_GUARDRAIL_RESPONSE_FIELD",
- "BEDROCK_CONVERSE_MODELS",
- "BEDROCK_EMBEDDING_PROVIDERS_LITERAL",
- "BEDROCK_INVOKE_PROVIDERS_LITERAL",
- "BadGatewayError",
- "BadRequestError",
- "BaseAnthropicMessagesConfig",
- "BaseConfig",
- "BaseImageEditConfig",
- "BaseImageGenerationConfig",
- "BaseLLMAIOHTTPHandler",
- "BaseLLMException",
- "BaseLLMHTTPHandler",
- "BaseLiteLLMOpenAIResponseObject",
- "BaseModel",
- "BaseOCRConfig",
- "BaseRerankConfig",
- "BaseResponsesAPIConfig",
- "BaseResponsesAPIStreamingIterator",
- "BaseSearchConfig",
- "BaseVideoConfig",
- "Batch",
- "BatchGuardrailRecord",
- "BatchGuardrailReport",
- "BatchJobStatus",
- "BatchRequestCounts",
- "BedrockBatchesHandler",
- "BedrockConverseLLM",
- "BedrockEmbedding",
- "BedrockFilesHandler",
- "BedrockImageEdit",
- "BedrockImageGeneration",
- "BedrockModelInfo",
- "BedrockRerankHandler",
- "BudgetExceededError",
- "BudgetManager",
- "BytezChatConfig",
- "CALLBACK_TYPES",
- "CARRY_UNMATCHED_MESSAGE_POINTS",
- "COHERE_DEFAULT_EMBEDDING_INPUT_TYPE",
- "CONFIGURABLE_CLIENTSIDE_AUTH_PARAMS",
- "CREATE_FILE_REQUESTS_PURPOSE",
- "CallTypes",
- "Callable",
- "CancelBatchRequest",
- "CharacterObject",
- "Chat",
- "ChatCompletionAnnotation",
- "ChatCompletionAnnotationURLCitation",
- "ChatCompletionAssistantContentValue",
- "ChatCompletionAssistantMessage",
- "ChatCompletionAssistantToolCall",
- "ChatCompletionAudioDelta",
- "ChatCompletionAudioObject",
- "ChatCompletionAudioParam",
- "ChatCompletionCachedContent",
- "ChatCompletionChunk",
- "ChatCompletionContentPartInputAudioParam",
- "ChatCompletionDeltaChunk",
- "ChatCompletionDeltaToolCallChunk",
- "ChatCompletionDeveloperMessage",
- "ChatCompletionDocumentObject",
- "ChatCompletionFileObject",
- "ChatCompletionFileObjectFile",
- "ChatCompletionFunctionMessage",
- "ChatCompletionImageObject",
- "ChatCompletionImageUrlObject",
- "ChatCompletionMessageToolCall",
- "ChatCompletionModality",
- "ChatCompletionNamedToolChoiceParam",
- "ChatCompletionPredictionContentParam",
- "ChatCompletionReasoningItem",
- "ChatCompletionReasoningSummaryTextBlock",
- "ChatCompletionRedactedThinkingBlock",
- "ChatCompletionRequest",
- "ChatCompletionResponseMessage",
- "ChatCompletionSystemMessage",
- "ChatCompletionTextObject",
- "ChatCompletionThinkingBlock",
- "ChatCompletionToolCallChunk",
- "ChatCompletionToolCallFunctionChunk",
- "ChatCompletionToolChoiceFunctionParam",
- "ChatCompletionToolChoiceObjectParam",
- "ChatCompletionToolChoiceStringValues",
- "ChatCompletionToolChoiceValues",
- "ChatCompletionToolMessage",
- "ChatCompletionToolParam",
- "ChatCompletionToolParamFunctionChunk",
- "ChatCompletionToolReferenceObject",
- "ChatCompletionUsageBlock",
- "ChatCompletionUserMessage",
- "ChatCompletionVideoObject",
- "ChatCompletionVideoUrlObject",
- "Choices",
- "ChunkProcessor",
- "CitationsObject",
- "ClarifaiConfig",
- "ClassVar",
- "ClassifierPlugin",
- "CodeInterpreterToolParam",
- "CodestralTextCompletion",
- "CohereModelInfo",
- "CompletionRequest",
- "CompletionTimeout",
- "CompletionTokensDetails",
- "Completions",
- "ComputerToolParam",
- "ConfigDict",
- "ConfigurableClientsideParamsCustomAuth",
- "ConsumedRequestTagsStamp",
- "ContentPartAddedEvent",
- "ContentPartDoneEvent",
- "ContentPartDonePartOutputText",
- "ContentPartDonePartReasoningText",
- "ContentPartDonePartRefusal",
- "ContentPolicyViolationError",
- "ContextManagementEntry",
- "ContextWindowExceededError",
- "Coroutine",
- "CreateBatchRequest",
- "CreateFileRequest",
- "CreateVideoRequest",
- "CredentialLiteLLMParams",
- "CustomLLM",
- "CustomLLMItem",
- "CustomLogger",
- "CustomPricingLiteLLMParams",
- "CustomRoutingStrategyBase",
- "CustomStreamWrapper",
- "CustomToolCallOutputItem",
- "DEFAULT_ALLOWED_FAILS",
- "DEFAULT_BATCH_SIZE",
- "DEFAULT_FLUSH_INTERVAL_SECONDS",
- "DEFAULT_IMAGE_ENDPOINT_MODEL",
- "DEFAULT_IN_MEMORY_TTL",
- "DEFAULT_MAX_RETRIES",
- "DEFAULT_MAX_TOKENS",
- "DEFAULT_MOCK_RESPONSE_COMPLETION_TOKEN_COUNT",
- "DEFAULT_MOCK_RESPONSE_PROMPT_TOKEN_COUNT",
- "DEFAULT_POLLING_INTERVAL",
- "DEFAULT_REPLICATE_POLLING_DELAY_SECONDS",
- "DEFAULT_REPLICATE_POLLING_RETRIES",
- "DEFAULT_REQUEST_TIMEOUT",
- "DEFAULT_SOFT_BUDGET",
- "DEFAULT_VIDEO_ENDPOINT_MODEL",
- "DatabricksEmbeddingHandler",
- "DatadogInitParams",
- "DecodedResponseId",
- "DeleteResponseResult",
- "Deployment",
- "DeploymentTypedDict",
- "Dict",
- "Discriminator",
- "DocumentObject",
- "DualCache",
- "EmbeddingCreateParams",
- "EmbeddingInput",
- "EmbeddingRequest",
- "EmbeddingResponse",
- "Enum",
- "ErrorEvent",
- "ErrorEventError",
- "FIRST_COMPLETED",
- "FORWARDED_KWARGS_KEYS",
- "FallbackAccessCheck",
- "Field",
- "FileContent",
- "FileContentProvider",
- "FileContentRequest",
- "FileContentStreamingResponse",
- "FileContentStreamingResult",
- "FileCreateProvider",
- "FileDeleteProvider",
- "FileDeleted",
- "FileExpiresAfter",
- "FileListPage",
- "FileListProvider",
- "FileObject",
- "FileRetrieveProvider",
- "FileSearchCallCompletedEvent",
- "FileSearchCallInProgressEvent",
- "FileSearchCallSearchingEvent",
- "FileSearchTool",
- "FileSearchToolParam",
- "FileTypes",
- "Final",
- "FineTuningConfig",
- "FineTuningJob",
- "FineTuningJobCreate",
- "FlowItem",
- "Function",
- "FunctionCallArgumentsDeltaEvent",
- "FunctionCallArgumentsDoneEvent",
- "GDCGeminiConfig",
- "GeminiModelInfo",
- "GenAIHubOrchestration",
- "Generator",
- "Generic",
- "GenericBudgetWindowDetails",
- "GenericChatCompletionMessage",
- "GenericEvent",
- "GenericLiteLLMParams",
- "GenericResponseOutputItem",
- "GenericResponseOutputItemContentAnnotation",
- "GoogleBatchEmbeddings",
- "GroqChatCompletion",
- "GuardrailLiteLLMParams",
- "GuardrailTypedDict",
- "HTTPHandler",
- "HUMANLOOP_PROMPT_CACHE_TTL_SECONDS",
- "HerokuChatConfig",
- "HiddenParams",
- "HttpxBinaryResponseContent",
- "HuggingFaceEmbedding",
- "Hyperparameters",
- "IBMWatsonXMixin",
- "IO",
- "IOBase",
- "ImageEditOptionalRequestParams",
- "ImageFetchError",
- "ImageFileObject",
- "ImageGenerationPartialImageEvent",
- "ImageGenerationRequestQuality",
- "ImageResponse",
- "ImageURLListItem",
- "ImageURLObject",
- "IncompleteDetails",
- "InputTokensDetails",
- "InternalServerError",
- "InvalidRequestError",
- "Iterable",
- "Iterator",
- "JSONProviderRegistry",
- "JSONSchemaValidationError",
- "KeyManagementSettings",
- "LIST_BATCHES_SUPPORTED_PROVIDERS",
- "LITELLM_CHAT_PROVIDERS",
- "LITELLM_EXCEPTION_TYPES",
- "LITELLM_IMAGE_VARIATION_PROVIDERS",
- "LemonadeChatConfig",
- "List",
- "ListBatchRequest",
- "ListBatchesSupportedProvider",
- "LiteLLM",
- "LiteLLMBatch",
- "LiteLLMBatchCreateRequest",
- "LiteLLMCompletionTransformationHandler",
- "LiteLLMFineTuningJob",
- "LiteLLMFineTuningJobCreate",
- "LiteLLMLoggingObj",
- "LiteLLMMessagesToCompletionTransformationHandler",
- "LiteLLMMessagesToResponsesAPIHandler",
- "LiteLLMParamsTypedDict",
- "LiteLLMResponsesTransformationHandler",
- "LiteLLMUnknownProvider",
- "LiteLLM_Params",
- "LiteLLM_RouterFileObject",
- "Literal",
- "LlmProviders",
- "Logging",
- "MCPCallArgumentsDeltaEvent",
- "MCPCallArgumentsDoneEvent",
- "MCPCallCompletedEvent",
- "MCPCallFailedEvent",
- "MCPCallInProgressEvent",
- "MCPListToolsCompletedEvent",
- "MCPListToolsFailedEvent",
- "MCPListToolsInProgressEvent",
- "MCPTool",
- "MOCK_RESPONSE_TYPE",
- "Mapping",
- "MappingProxyType",
- "Message",
- "MessageContent",
- "MessageContentImageFileObject",
- "MessageContentImageURLObject",
- "MessageContentTextObject",
- "MessageData",
- "MirroredPricingParams",
- "MockException",
- "MockRouterTestingParams",
- "ModelConfig",
- "ModelGroupInfo",
- "ModelGroupSettings",
- "ModelInfo",
- "ModelResponse",
- "ModelResponseStream",
- "MyLocal",
- "NOT_GIVEN",
- "NewRelicInitParams",
- "NonNegativeInt",
- "NotFoundError",
- "NotGiven",
- "NotRequired",
- "NvidiaRivaAudioTranscription",
- "NvidiaRivaAudioTranscriptionConfig",
- "OCIChatConfig",
- "OCRResponse",
- "OCR_REQUEST_FORMAT_PARAM",
- "OPENAI_CHAT_COMPLETION_PARAMS",
- "OPENAI_COMPATIBLE_BATCH_AND_FILES_PROVIDERS",
- "OPENAI_FINISH_REASONS",
- "OPTIONAL_KWARGS_KEYS",
- "OVHCloudChatConfig",
- "Omit",
- "OpenAI",
- "OpenAIAssistantsAPI",
- "OpenAIAudioTranscription",
- "OpenAIAudioTranscriptionOptionalParams",
- "OpenAIBatchResponse",
- "OpenAIBatchResult",
- "OpenAIBatchesAPI",
- "OpenAIChatCompletion",
- "OpenAIChatCompletionAssistantMessage",
- "OpenAIChatCompletionChoices",
- "OpenAIChatCompletionChunk",
- "OpenAIChatCompletionDeveloperMessage",
- "OpenAIChatCompletionFinishReason",
- "OpenAIChatCompletionLogprobs",
- "OpenAIChatCompletionLogprobsContent",
- "OpenAIChatCompletionLogprobsContentTopLogprobs",
- "OpenAIChatCompletionResponse",
- "OpenAIChatCompletionSystemMessage",
- "OpenAIChatCompletionTextObject",
- "OpenAIChatCompletionToolParam",
- "OpenAIChatCompletionUserMessage",
- "OpenAICreateFileRequestOptionalParams",
- "OpenAICreateThreadParamsMessage",
- "OpenAICreateThreadParamsToolResources",
- "OpenAIEmbedding",
- "OpenAIError",
- "OpenAIErrorBody",
- "OpenAIFileObject",
- "OpenAIFilesAPI",
- "OpenAIFilesPurpose",
- "OpenAIFineTuningAPI",
- "OpenAIGPT5Config",
- "OpenAIImageEditOptionalParams",
- "OpenAIImageGenerationOptionalParams",
- "OpenAIImageVariationOptionalParams",
- "OpenAIImageVariationsHandler",
- "OpenAILikeChatHandler",
- "OpenAILikeEmbeddingHandler",
- "OpenAILikeResponsesConfig",
- "OpenAIMcpServerTool",
- "OpenAIMessage",
- "OpenAIMessageContent",
- "OpenAIMessageContentListBlock",
- "OpenAIModerationResponse",
- "OpenAIModerationResult",
- "OpenAIRealtimeContentPartDone",
- "OpenAIRealtimeConversationCreated",
- "OpenAIRealtimeConversationItemAdded",
- "OpenAIRealtimeConversationItemCreated",
- "OpenAIRealtimeConversationItemDone",
- "OpenAIRealtimeConversationObject",
- "OpenAIRealtimeDoneEvent",
- "OpenAIRealtimeEventTypes",
- "OpenAIRealtimeEvents",
- "OpenAIRealtimeFunctionCallArgumentsDone",
- "OpenAIRealtimeInputAudioBufferSpeechEvent",
- "OpenAIRealtimeInputAudioTranscriptionCompleted",
- "OpenAIRealtimeInputAudioTranscriptionDelta",
- "OpenAIRealtimeOutputItemDone",
- "OpenAIRealtimeResponseAudioDone",
- "OpenAIRealtimeResponseContentPart",
- "OpenAIRealtimeResponseContentPartAdded",
- "OpenAIRealtimeResponseDelta",
- "OpenAIRealtimeResponseDoneObject",
- "OpenAIRealtimeResponseTextDone",
- "OpenAIRealtimeResponseUsage",
- "OpenAIRealtimeStreamList",
- "OpenAIRealtimeStreamResponseBaseObject",
- "OpenAIRealtimeStreamResponseOutputItem",
- "OpenAIRealtimeStreamResponseOutputItemAdded",
- "OpenAIRealtimeStreamResponseOutputItemContent",
- "OpenAIRealtimeStreamSession",
- "OpenAIRealtimeStreamSessionEvents",
- "OpenAIRealtimeTurnDetection",
- "OpenAIRealtimeUsageTokenDetails",
- "OpenAITextCompletion",
- "OpenAITextCompletionUserMessage",
- "OpenAIVideoObject",
- "OpenAIWebSearchOptions",
- "OpenAIWebSearchUserLocation",
- "OpenAIWebSearchUserLocationApproximate",
- "Optional",
- "OptionalPreCallChecks",
- "OutputCodeInterpreterCall",
- "OutputCodeInterpreterCallLog",
- "OutputFunctionToolCall",
- "OutputImageGenerationCall",
- "OutputItemAddedEvent",
- "OutputItemDoneEvent",
- "OutputText",
- "OutputTextAnnotationAddedEvent",
- "OutputTextDeltaEvent",
- "OutputTextDoneEvent",
- "OutputTokensDetails",
- "PART_UNION_TYPES",
- "PalmConfig",
- "PathLike",
- "PermissionDeniedError",
- "Phase",
- "PreRoutingHookResponse",
- "PreRoutingStrategy",
- "PredibaseChatCompletion",
- "PrivateAttr",
- "PromptCacheBreakpoint",
- "PromptCacheOptions",
- "PromptObject",
- "PromptSpec",
- "PromptTokensDetails",
- "Protocol",
- "ProviderConfigManager",
- "ProviderSpecificHeader",
- "ProviderSpecificHeaderUtils",
- "REASONING_EFFORT",
- "REPEATED_STREAMING_CHUNK_LIMIT",
- "ROUTER_MAX_FALLBACKS",
- "RateLimitError",
- "RateLimitErrorCategory",
- "RateLimitType",
- "RawRequestTypedDict",
- "ReadOnly",
- "Reasoning",
- "ReasoningSummaryPartDoneEvent",
- "ReasoningSummaryTextDeltaEvent",
- "ReasoningSummaryTextDoneEvent",
- "RedisCache",
- "RefusalDeltaEvent",
- "RefusalDoneEvent",
- "RequestType",
- "Required",
- "RerankResponse",
- "Response",
- "ResponseAPIUsage",
- "ResponseCompletedEvent",
- "ResponseCreatedEvent",
- "ResponseFailedEvent",
- "ResponseFunctionToolCall",
- "ResponseInProgressEvent",
- "ResponseIncludable",
- "ResponseIncompleteEvent",
- "ResponseInputParam",
- "ResponseOutputItem",
- "ResponsePartAddedEvent",
- "ResponseText",
- "ResponsesAPIOptionalRequestParams",
- "ResponsesAPIRequestParams",
- "ResponsesAPIRequestUtils",
- "ResponsesAPIResponse",
- "ResponsesAPIStatus",
- "ResponsesAPIStreamEvents",
- "ResponsesAPIStreamOptions",
- "ResponsesAPIStreamingResponse",
- "ResponsesToolUsage",
- "RetrieveBatchRequest",
- "RetryPolicy",
- "Router",
- "RouterCacheEnum",
- "RouterConfig",
- "RouterErrors",
- "RouterGeneralSettings",
- "RouterModelGroupAliasItem",
- "RouterRateLimitError",
- "RouterRateLimitErrorBasic",
- "RoutingContext",
- "RoutingGroup",
- "RoutingPlugin",
- "RoutingStrategy",
- "Run",
- "SPECIAL_MODEL_INFO_PARAMS",
- "SagemakerChatHandler",
- "SagemakerLLM",
- "Scheduler",
- "SchedulerCacheKeys",
- "SearchProvider",
- "SearchProviders",
- "SearchResponse",
- "SearchToolInfoTypedDict",
- "SearchToolLiteLLMParams",
- "SearchToolTypedDict",
- "Sequence",
- "SerializerFunctionWrapHandler",
- "ServiceUnavailableError",
- "Set",
- "ShellToolParam",
- "SlackAlerting",
- "StandardLoggingRoutingDecision",
- "StreamingChoices",
- "SyncCursorPage",
- "TYPE_CHECKING",
- "TaggedPreRoutingStrategy",
- "TextChoices",
- "TextCompletionResponse",
- "TextCompletionStreamWrapper",
- "Thread",
- "ThreadPoolExecutor",
- "Timeout",
- "TogetherAIRerank",
- "Tool",
- "ToolChoice",
- "ToolMessageContentPart",
- "ToolParam",
- "ToolResourcesCodeInterpreter",
- "ToolResourcesFileSearch",
- "ToolResourcesFileSearchVectorStore",
- "TopazModelInfo",
- "TranscriptionResponse",
- "Tuple",
- "Type",
- "TypeAlias",
- "TypeVar",
- "TypedDict",
- "Union",
- "UnprocessableEntityError",
- "UnsupportedParamsError",
- "UpdateRouterConfig",
- "Usage",
- "VALID_LITELLM_ENVIRONMENTS",
- "ValidAssistantMessageContentTypes",
- "ValidAssistantMessageContentTypesLiteral",
- "ValidChatCompletionMessageContentTypes",
- "ValidChatCompletionMessageContentTypesLiteral",
- "ValidUserMessageContentTypes",
- "ValidUserMessageContentTypesLiteral",
- "VectorStoreIndexRegistry",
- "VectorStoreRegistry",
- "VertexAIBatchPrediction",
- "VertexAIFilesHandler",
- "VertexAIGemmaModels",
- "VertexAIModelGardenModels",
- "VertexAIModelRoute",
- "VertexAIPartnerModels",
- "VertexAITextEmbeddingConfig",
- "VertexEmbedding",
- "VertexFineTuningAPI",
- "VertexImageGeneration",
- "VertexLLM",
- "VertexMultimodalEmbedding",
- "VideoCreateOptionalRequestParams",
- "VideoGenerationRequestUtils",
- "VideoObject",
- "WANDB_MODELS",
- "WATSONX_DEFAULT_API_VERSION",
- "WatsonXChatHandler",
- "WebSearchCallCompletedEvent",
- "WebSearchCallInProgressEvent",
- "WebSearchCallSearchingEvent",
- "WebSearchOptions",
- "WebSearchOptionsUserLocation",
- "WebSearchOptionsUserLocationApproximate",
- "WebSearchToolUsage",
- "XAIModelInfo",
- "a_add_message",
- "aadapter_completion",
- "aadapter_generate_content",
- "acancel_batch",
- "acancel_eval",
- "acancel_fine_tuning_job",
- "acancel_responses",
- "acancel_run",
- "aclient_session",
- "acode_interpreter_tool",
- "acompact_responses",
- "acompletion",
- "acompletion_with_retries",
- "acount_tokens",
- "acreate_agent",
- "acreate_assistants",
- "acreate_batch",
- "acreate_container",
- "acreate_eval",
- "acreate_file",
- "acreate_fine_tuning_job",
- "acreate_realtime_client_secret",
- "acreate_realtime_transcription_session",
- "acreate_run",
- "acreate_sandbox",
- "acreate_skill",
- "acreate_thread",
- "adapter_completion",
- "adapters",
- "add_function_to_prompt",
- "add_known_models",
- "add_message",
- "add_provider_specific_params_to_optional_params",
- "add_system_prompt_to_messages",
- "add_trusted_model_credentials_to_litellm_params",
- "add_user_information_to_llm_headers",
- "additional_logging_utils",
- "adelete_agent",
- "adelete_assistant",
- "adelete_container",
- "adelete_eval",
- "adelete_responses",
- "adelete_run",
- "adelete_sandbox",
- "adelete_skill",
- "aembedding",
- "afile_content",
- "afile_delete",
- "afile_list",
- "afile_retrieve",
- "agenerate_content",
- "agent_search_embedding_model",
- "agentops",
- "aget_agent",
- "aget_assistants",
- "aget_eval",
- "aget_messages",
- "aget_responses",
- "aget_run",
- "aget_skill",
- "aget_thread",
- "ahealth_check",
- "ai21_chat_models",
- "ai21_key",
- "ai21_models",
- "aimage_edit",
- "aimage_generation",
- "aimage_variation",
- "aiml_models",
- "aingest",
- "aiohttp_trust_env",
- "aleph_alpha",
- "aleph_alpha_key",
- "aleph_alpha_models",
- "alist_agent_versions",
- "alist_agents",
- "alist_batches",
- "alist_container_files",
- "alist_containers",
- "alist_evals",
- "alist_fine_tuning_jobs",
- "alist_input_items",
- "alist_runs",
- "alist_skills",
- "all_embedding_models",
- "all_litellm_params",
- "allm_passthrough_route",
- "allow_dynamic_callback_disabling",
- "allowed_fails",
- "amazon_nova_api_key",
- "amazon_nova_models",
- "amoderation",
- "annotations",
- "anthropic",
- "anthropic_batches_instance",
- "anthropic_beta_headers_manager",
- "anthropic_beta_headers_url",
- "anthropic_cache_control_hook",
- "anthropic_chat_completions",
- "anthropic_interface",
- "anthropic_key",
- "anthropic_messages",
- "anthropic_messages_handler",
- "anthropic_models",
- "anthropic_prompt_caching_ttl",
- "anthropic_sse_ping_interval_seconds",
- "anyscale_models",
- "aocr",
- "api_base",
- "api_key",
- "api_version",
- "aquery",
- "arealtime_calls",
- "arerank",
- "aresponses",
- "aresponses_api_with_mcp",
- "aresponses_with_retries",
- "aretrieve_batch",
- "aretrieve_container",
- "aretrieve_fine_tuning_job",
- "argilla",
- "argilla_batch_size",
- "argilla_transformation_object",
- "arize",
- "arun_code",
- "arun_thread",
- "arun_thread_stream",
- "asearch",
- "aspeech",
- "assemblyai_models",
- "assistants",
- "async_completion_with_fallbacks",
- "async_mock_completion_streaming_obj",
- "asyncio",
- "atext_completion",
- "athina",
- "atranscription",
- "audit_log_callbacks",
- "aupload_container_file",
- "autorouter_presets_url",
- "avector_store_file_content",
- "avector_store_file_create",
- "avector_store_file_delete",
- "avector_store_file_list",
- "avector_store_file_retrieve",
- "avector_store_file_update",
- "avideo_content",
- "avideo_create_character",
- "avideo_edit",
- "avideo_extension",
- "avideo_generation",
- "avideo_get_character",
- "avideo_list",
- "avideo_remix",
- "avideo_status",
- "aws_polly_models",
- "aws_sqs_callback_params",
- "azure_ai_embedding",
- "azure_ai_models",
- "azure_anthropic_chat_completions",
- "azure_anthropic_models",
- "azure_assistants_api",
- "azure_audio_transcriptions",
- "azure_batches_instance",
- "azure_chat_completions",
- "azure_embedding_models",
- "azure_files_instance",
- "azure_fine_tuning_apis_instance",
- "azure_key",
- "azure_llms",
- "azure_models",
- "azure_o1_chat_completions",
- "azure_sentinel",
- "azure_storage",
- "azure_text_completions",
- "azure_text_models",
- "banned_keywords_list",
- "base64",
- "base_llm_aiohttp_handler",
- "base_llm_http_handler",
- "baseten_key",
- "baseten_models",
- "batch_completion",
- "batch_completion_models",
- "batch_completion_models_all_responses",
- "batches",
- "bedrock_converse_chat_completion",
- "bedrock_converse_models",
- "bedrock_embedding",
- "bedrock_embedding_models",
- "bedrock_files_instance",
- "bedrock_image_edit",
- "bedrock_image_generation",
- "bedrock_mantle_models",
- "bedrock_models",
- "bedrock_request_metadata_fields",
- "bedrock_rerank",
- "bfl_image_edit",
- "bfl_image_generation",
- "black_forest_labs_models",
- "block_requests_for_models_without_pricing",
- "blocked_user_list",
- "blog_posts_url",
- "budget_duration",
- "budget_exceeded_throttle_percentage",
- "budget_manager",
- "budget_rollover",
- "build_code_interpreter_log_outputs",
- "bytez_key",
- "bytez_transformation",
- "cache",
- "caching",
- "caching_with_models",
- "calculate_request_duration",
- "callback_settings",
- "callbacks",
- "cancel_batch",
- "cancel_eval",
- "cancel_fine_tuning_job",
- "cancel_responses",
- "cancel_run",
- "cast",
- "cerebras_models",
- "chatgpt_models",
- "check_provider_endpoint",
- "clarifai_key",
- "clarifai_models",
- "client",
- "client_session",
- "close_litellm_async_clients",
- "cloudflare_api_key",
- "cloudflare_models",
- "codestral_models",
- "codestral_text_completions",
- "cohere_chat_models",
- "cohere_embed",
- "cohere_embedding_models",
- "cohere_key",
- "cohere_models",
- "cold_storage_custom_logger",
- "cometapi_key",
- "cometapi_models",
- "common_cloud_provider_auth_params",
- "compact_responses",
- "completion",
- "completion_extras",
- "completion_with_fallbacks",
- "completion_with_retries",
- "compress",
- "compression",
- "config_completion",
- "config_path",
- "constants",
- "containers",
- "content_policy_fallbacks",
- "context_window_fallbacks",
- "contextmanager",
- "contextvars",
- "convert_file_document_to_url_document",
- "convert_model_response_to_streaming",
- "convert_to_model_response_object",
- "cost_calculator",
- "cost_discount_config",
- "cost_margin_config",
- "create_agent",
- "create_assistants",
- "create_batch",
- "create_container",
- "create_eval",
- "create_file",
- "create_fine_tuning_job",
- "create_pretrained_tokenizer",
- "create_run",
- "create_skill",
- "create_thread",
- "create_tokenizer",
- "credential_list",
- "custom_batch_logger",
- "custom_chat_llm_router",
- "custom_guardrail",
- "custom_logger",
- "custom_prometheus_metadata_labels",
- "custom_prometheus_tags",
- "custom_prompt",
- "custom_prompt_dict",
- "custom_prompt_management",
- "custom_provider_map",
- "darkbloom_models",
- "dashscope_models",
- "databricks_embedding",
- "databricks_key",
- "databricks_models",
- "dataclass",
- "datadog",
- "datadog_llm_observability_params",
- "datadog_params",
- "datadog_use_v1",
- "datarobot_key",
- "datarobot_models",
- "datetime",
- "decode_video_id_with_provider",
- "declared_authenticating_provider",
- "deepcopy",
- "deepeval",
- "deepgram_models",
- "deepinfra_models",
- "deepseek_models",
- "default_fallbacks",
- "default_in_memory_ttl",
- "default_internal_user_params",
- "default_key_generate_params",
- "default_key_max_budget_alert_emails",
- "default_max_internal_user_budget",
- "default_redis_batch_cache_expiry",
- "default_redis_ttl",
- "default_soft_budget",
- "default_team_params",
- "default_team_settings",
- "delete_agent",
- "delete_assistant",
- "delete_container",
- "delete_eval",
- "delete_responses",
- "delete_run",
- "delete_skill",
- "disable_add_prefix_to_prompt",
- "disable_add_transform_inline_image_block",
- "disable_add_user_agent_to_request_tags",
- "disable_aiohttp_transport",
- "disable_aiohttp_trust_env",
- "disable_anthropic_gemini_context_caching_transform",
- "disable_cache",
- "disable_copilot_system_to_assistant",
- "disable_end_user_cost_tracking",
- "disable_end_user_cost_tracking_prometheus_only",
- "disable_hf_tokenizer_download",
- "disable_stop_sequence_limit",
- "disable_streaming_logging",
- "disable_token_counter",
- "disable_vertex_batch_output_transformation",
- "docker_model_runner_models",
- "dotenv",
- "dotprompt",
- "drop_params",
- "dynamodb",
- "dynamodb_table_name",
- "elevenlabs_models",
- "email",
- "email_templates",
- "embedding",
- "empower_models",
- "enable_anthropic_prompt_caching",
- "enable_azure_ad_token_refresh",
- "enable_cache",
- "enable_caching_on_provider_specific_optional_params",
- "enable_end_user_cost_tracking_prometheus_only",
- "enable_gemini_default_thinking_level_low",
- "enable_json_schema_validation",
- "enable_key_alias_format_validation",
- "enable_loadbalancing_on_batch_endpoints",
- "enable_model_config_credential_overrides",
- "enable_preview_features",
- "enum",
- "error_logs",
- "evals",
- "exception_type",
- "exceptions",
- "expose_router_debug_in_errors",
- "extra_spend_tag_headers",
- "failure_callback",
- "fal_ai_models",
- "fallbacks",
- "featherless_ai_models",
- "field_serializer",
- "field_validator",
- "file_content",
- "file_content_streaming",
- "file_delete",
- "file_list",
- "file_retrieve",
- "files",
- "filter_invalid_headers",
- "filter_out_litellm_params",
- "fine_tuning",
- "fireworks_ai_embedding_models",
- "fireworks_ai_models",
- "flatten_form_field_values",
- "flatten_unencrypted_web_search_results_in_anthropic_messages",
- "force_ipv4",
- "forward_traceparent_to_llm_provider",
- "friendliai_models",
- "function_call_prompt",
- "futures",
- "galadriel_models",
- "galileo",
- "gcs_bucket",
- "gcs_pub_sub_use_v1",
- "gcs_pubsub",
- "gdc_api_base",
- "gdc_key",
- "gdc_transformation",
- "gemini_live_defer_setup",
- "gemini_models",
- "generic_api",
- "generic_api_use_v1",
- "generic_logger_headers",
- "get_agent",
- "get_api_key_from_env",
- "get_args",
- "get_assistants",
- "get_audio_file_for_health_check",
- "get_azure_credentials",
- "get_completion_messages",
- "get_configured_request_timeout",
- "get_content_from_model_response",
- "get_eval",
- "get_litellm_gateway_api_key",
- "get_litellm_params",
- "get_llm_provider",
- "get_messages",
- "get_messages_interceptors",
- "get_mime_type",
- "get_model_cost_map",
- "get_model_info",
- "get_non_default_completion_params",
- "get_non_default_transcription_params",
- "get_openai_credentials",
- "get_optional_params",
- "get_optional_params_add_message",
- "get_optional_params_embeddings",
- "get_optional_params_image_gen",
- "get_optional_params_transcription",
- "get_optional_rerank_params",
- "get_requester_metadata",
- "get_responses",
- "get_run",
- "get_secret",
- "get_secret_bool",
- "get_secret_str",
- "get_skill",
- "get_standard_openai_params",
- "get_thread",
- "get_type_hints",
- "get_vertex_ai_model_route",
- "gigachat_key",
- "gigachat_models",
- "github_copilot_models",
- "global_bitbucket_config",
- "global_disable_no_log_param",
- "global_gitlab_config",
- "google_batch_embeddings",
- "google_genai",
- "google_moderation_confidence_threshold",
- "gradient_ai_api_key",
- "gradient_ai_models",
- "greenscale",
- "groq_chat_completions",
- "groq_key",
- "groq_models",
- "guardrail_name_config_map",
- "headers",
- "heapq",
- "helicone",
- "helicone_mock_client",
- "heroku_key",
- "heroku_models",
- "heroku_transformation",
- "httpx",
- "huggingface_embed",
- "huggingface_key",
- "huggingface_models",
- "humanloop",
- "hyperbolic_models",
- "identify",
- "image_edit",
- "image_generation",
- "image_variation",
- "images",
- "importlib",
- "in_memory_llm_clients_cache",
- "inception_key",
- "inception_models",
- "include_cost_in_streaming_usage",
- "infer_openai_data_residency",
- "infinity_key",
- "infinity_models",
- "ingest",
- "initialized_langfuse_clients",
- "input_callback",
- "inspect",
- "integrations",
- "interactions",
- "internal_user_budget_duration",
- "is_azure_document_intelligence_model",
- "is_bedrock_pricing_only_model",
- "is_openai_finetune_model",
- "is_reasoning_auto_summary_enabled",
- "jina_ai_models",
- "json",
- "json_logs",
- "key_generation_settings",
- "known_tokenizer_config",
- "lago",
- "lambda_ai_models",
- "langfuse",
- "langfuse_default_tags",
- "langfuse_enable_update_trace_keys",
- "langsmith",
- "langsmith_batch_size",
- "langsmith_mock_client",
- "lemonade_key",
- "lemonade_models",
- "lemonade_transformation",
- "list_agent_versions",
- "list_agents",
- "list_batches",
- "list_container_files",
- "list_containers",
- "list_evals",
- "list_fine_tuning_jobs",
- "list_input_items",
- "list_runs",
- "list_skills",
- "litellm",
- "litellm_agent",
- "litellm_completion_transformation_handler",
- "litellm_core_utils",
- "litellm_mode",
- "literal_ai",
- "llama_api_key",
- "llama_models",
- "llamagate_models",
- "llamaguard_model_name",
- "llamaguard_unsafe_content_categories",
- "llm_guard_mode",
- "llm_http_handler",
- "llm_passthrough_route",
- "llms",
- "log_client_error_tracebacks",
- "log_level",
- "log_raw_request_response",
- "logfire_logger",
- "logged_real_time_event_types",
- "logging",
- "longer_context_model_fallback_dict",
- "lunary",
- "main",
- "map_system_message_pt",
- "maritalk_key",
- "maritalk_models",
- "max_budget",
- "max_end_user_budget",
- "max_end_user_budget_id",
- "max_fallbacks",
- "max_internal_user_budget",
- "max_tokens",
- "max_ui_session_budget",
- "max_user_budget",
- "maybe_run_chat_completion_agentic_loop",
- "mcp_tool_search",
- "mimetypes",
- "minimax_models",
- "mistral_chat_models",
- "mlflow",
- "mock_client_factory",
- "mock_completion",
- "mock_completion_streaming_obj",
- "mock_embedding",
- "mock_image_generation",
- "mock_response",
- "mock_responses_api_response",
- "model_alias_map",
- "model_cost",
- "model_cost_map_url",
- "model_fallbacks",
- "model_group_settings",
- "model_list",
- "model_list_set",
- "model_serializer",
- "model_validator",
- "models",
- "models_by_provider",
- "modelscope_models",
- "moderation",
- "modify_params",
- "moonshot_models",
- "morph_models",
- "nebius_embedding_models",
- "nebius_key",
- "nebius_models",
- "network_mock",
- "newrelic",
- "newrelic_params",
- "nlp_cloud_chat_completion",
- "nlp_cloud_key",
- "nlp_cloud_models",
- "novita_api_key",
- "novita_models",
- "nscale_models",
- "num_retries",
- "num_retries_per_request",
- "nvidia_nim_models",
- "nvidia_riva_audio_transcriptions",
- "nvidia_riva_models",
- "oci_models",
- "oci_transformation",
- "ocr",
- "ollama",
- "ollama_key",
- "ollama_models",
- "ollama_pt",
- "oobabooga",
- "open_ai_chat_completion_models",
- "open_ai_embedding_models",
- "open_ai_text_completion_models",
- "openai",
- "openai_assistants_api",
- "openai_audio_transcriptions",
- "openai_batches_instance",
- "openai_chat_completions",
- "openai_compatible_endpoints",
- "openai_compatible_providers",
- "openai_files_instance",
- "openai_fine_tuning_apis_instance",
- "openai_image_generation_models",
- "openai_image_variations",
- "openai_key",
- "openai_like_chat_completion",
- "openai_like_embedding",
- "openai_like_key",
- "openai_moderations_model_name",
- "openai_text_completion_compatible_providers",
- "openai_text_completions",
- "openai_video_generation_models",
- "openmeter",
- "openrouter_key",
- "openrouter_models",
- "opentelemetry",
- "opentelemetry_utils",
- "opik",
- "organization",
- "os",
- "otel",
- "output_parse_pii",
- "overload",
- "override",
- "overwrite_user_with_key_hash",
- "ovhcloud_embedding_models",
- "ovhcloud_key",
- "ovhcloud_models",
- "ovhcloud_transformation",
- "palm",
- "palm_models",
- "parse_ocr_request_format",
- "partial",
- "passthrough",
- "peek_reasoning_summary_aliases",
- "perplexity_models",
- "petals_handler",
- "petals_models",
- "post_call_rules",
- "posthog",
- "posthog_mock_client",
- "pre_call_rules",
- "pre_process_non_default_params",
- "predibase_chat_completions",
- "predibase_key",
- "predibase_tenant_id",
- "presidio_ad_hoc_recognizers",
- "print_verbose",
- "priority_reservation",
- "project",
- "prometheus_deployment_and_latency_caller_identity",
- "prometheus_emit_rate_limit_labels",
- "prometheus_emit_stream_label",
- "prometheus_end_user_metrics_cleanup_interval_seconds",
- "prometheus_end_user_metrics_max_series_per_metric",
- "prometheus_end_user_metrics_ttl_seconds",
- "prometheus_exclude_labels",
- "prometheus_exclude_metrics",
- "prometheus_initialize_budget_metrics",
- "prometheus_latency_buckets",
- "prometheus_metrics_config",
- "prometheus_user_budget_label_include_email_alias",
- "prompt_factory",
- "prompt_layer",
- "prompt_management_base",
- "prompt_name_config_map",
- "provider_url_destination_allowed_hosts",
- "proxy",
- "proxy_auth",
- "public_agent_groups",
- "public_mcp_hub_strict_whitelist",
- "public_mcp_servers",
- "public_model_groups",
- "public_model_groups_links",
- "publicai_models",
- "query",
- "qwen_ai_platform_models",
- "qwencloud_models",
- "rag",
- "random",
- "re",
- "read_config_args",
- "realtime_api",
- "reasoning_auto_summary",
- "recraft_models",
- "redact_messages_in_exceptions",
- "redact_user_api_key_info",
- "reducto_models",
- "replicate_chat_completion",
- "replicate_key",
- "replicate_models",
- "repositories",
- "request_correlation_in_logs",
- "request_timeout",
- "request_timeout_explicitly_set",
- "require_auth_for_metrics_endpoint",
- "require_managed_files",
- "rerank",
- "rerank_api",
- "responses",
- "responses_api_bridge_check",
- "responses_with_retries",
- "retrieve_batch",
- "retrieve_container",
- "retrieve_fine_tuning_job",
- "retry",
- "return_response_headers",
- "route_all_chat_openai_to_responses",
- "router",
- "router_strategy",
- "router_utils",
- "run_async_function",
- "run_server",
- "run_thread",
- "run_thread_stream",
- "runtime_checkable",
- "runwayml_models",
- "rust",
- "rust_bridge",
- "rust_ocr_bridge",
- "s3",
- "s3_audit_callback_params",
- "s3_callback_params",
- "s3_v2",
- "safe_deep_copy",
- "safe_memory_mode",
- "sagemaker_chat_completion",
- "sagemaker_llm",
- "sambanova_embedding_models",
- "sambanova_models",
- "sandbox",
- "sanitize_tool_use_ids_in_anthropic_messages",
- "sap_gen_ai_hub_chat_completions",
- "sap_gen_ai_hub_emb",
- "sap_service_key",
- "scheduler",
- "search",
- "secret_manager_client",
- "secret_managers",
- "service_callback",
- "set_global_bitbucket_config",
- "set_global_gitlab_config",
- "set_verbose",
- "should_run_mock_completion",
- "skills",
- "skip_system_message_in_guardrail",
- "skip_tool_message_in_guardrail",
- "snowflake_key",
- "snowflake_models",
- "soniox_models",
- "speech",
- "sqs",
- "sse_keepalive_ping_interval_seconds",
- "ssl_certificate",
- "ssl_ecdh_curve",
- "ssl_security_level",
- "ssl_verify",
- "stability_models",
- "standard_logging_payload_excluded_fields",
- "store_audit_logs",
- "stream_chunk_builder",
- "stream_chunk_builder_text_completion",
- "stringify_json_tool_call_content",
- "strip_anthropic_total_tokens",
- "strip_empty_content_blocks_from_anthropic_messages",
- "strip_reasoning_summary_aliases_from_optional_params",
- "success_callback",
- "supabase",
- "supports_httpx_timeout",
- "suppress_debug_info",
- "sys",
- "tag_budget_config",
- "telemetry",
- "tencent_models",
- "text_completion",
- "text_completion_codestral_models",
- "text_completion_inception_models",
- "threading",
- "tiktoken",
- "time",
- "together_ai_models",
- "together_rerank",
- "togetherai_api_key",
- "token",
- "token_counter",
- "traceback",
- "traceloop",
- "tracer",
- "transcription",
- "turn_off_message_logging",
- "types",
- "updateDeployment",
- "updateLiteLLMParams",
- "update_cache",
- "update_messages_with_model_file_ids",
- "update_responses_input_with_model_file_ids",
- "update_responses_tools_with_model_file_ids",
- "upload_container_file",
- "upperbound_key_generate_params",
- "urlsplit",
- "use_aiohttp_transport",
- "use_chat_completions_url_for_anthropic_messages",
- "use_client",
- "use_legacy_interactions_schema",
- "use_litellm_proxy",
- "user_url_allowed_hosts",
- "user_url_validation",
- "utils",
- "uuid",
- "uuid_module",
- "v0_models",
- "validate_and_fix_openai_messages",
- "validate_and_fix_openai_tools",
- "validate_and_fix_thinking_param",
- "validate_anthropic_api_metadata",
- "validate_chat_completion_tool_choice",
- "validate_end_user_id_in_db",
- "validate_openai_optional_params",
- "vector_store_file_content",
- "vector_store_file_create",
- "vector_store_file_delete",
- "vector_store_file_list",
- "vector_store_file_retrieve",
- "vector_store_file_update",
- "vector_store_files",
- "vector_store_index_registry",
- "vector_store_registry",
- "vector_stores",
- "verbose_logger",
- "vercel_ai_gateway_key",
- "vercel_ai_gateway_models",
- "vertexAITextEmbeddingConfig",
- "vertex_ai_ai21_models",
- "vertex_ai_batches_instance",
- "vertex_ai_files_instance",
- "vertex_ai_image_models",
- "vertex_ai_non_gemini",
- "vertex_ai_safety_settings",
- "vertex_ai_video_models",
- "vertex_anthropic_models",
- "vertex_chat_completion",
- "vertex_chat_models",
- "vertex_code_chat_models",
- "vertex_code_text_models",
- "vertex_deepseek_models",
- "vertex_embedding",
- "vertex_embedding_models",
- "vertex_fine_tuning_apis_instance",
- "vertex_gemma_chat_completion",
- "vertex_image_generation",
- "vertex_language_models",
- "vertex_llama3_models",
- "vertex_location",
- "vertex_minimax_models",
- "vertex_mistral_models",
- "vertex_model_garden_chat_completion",
- "vertex_moonshot_models",
- "vertex_multimodal_embedding",
- "vertex_openai_models",
- "vertex_partner_models_chat_completion",
- "vertex_project",
- "vertex_text_models",
- "vertex_vision_models",
- "vertex_zai_models",
- "video_content",
- "video_create_character",
- "video_edit",
- "video_extension",
- "video_generation",
- "video_get_character",
- "video_list",
- "video_remix",
- "video_status",
- "videos",
- "vllm_handler",
- "volcengine_models",
- "voyage_models",
- "wait",
- "wandb_key",
- "wandb_models",
- "warnings",
- "watsonx_chat_completion",
- "watsonx_models",
- "xai_key",
- "xai_models",
- "zai_models",
-)
diff --git a/litellm/proxy/__init__.py b/litellm/proxy/__init__.py
index dc819fbc85c..b6e690fd591 100644
--- a/litellm/proxy/__init__.py
+++ b/litellm/proxy/__init__.py
@@ -1,11 +1 @@
-from types import ModuleType
-from typing import Final
-
-
-def __getattr__(name: str) -> ModuleType:
- from litellm._lazy_imports import lazy_import_submodule
-
- submodule: Final = lazy_import_submodule(__name__, name)
- if submodule is not None:
- return submodule
- raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
+from . import *
diff --git a/tests/test_litellm/test_lazy_imports.py b/tests/test_litellm/test_lazy_imports.py
index 09d5e23e2e6..2b16a812611 100644
--- a/tests/test_litellm/test_lazy_imports.py
+++ b/tests/test_litellm/test_lazy_imports.py
@@ -1,8 +1,5 @@
"""Simple tests for lazy import functionality."""
-import importlib
-import json
-import subprocess
import sys
import pytest
@@ -10,10 +7,6 @@ import pytest
import litellm
from litellm._lazy_imports import (
- _SDK_MODULE_ALIASES,
- _SDK_SYMBOLS_IMPORT_MAP,
- lazy_import_litellm_submodule,
- _lazy_import_sdk_symbols,
COST_CALCULATOR_NAMES,
LITELLM_LOGGING_NAMES,
UTILS_NAMES,
@@ -353,83 +346,3 @@ def test_utils_module_lazy_imports():
assert name in utils_globals
_verify_only_requested_name_imported_in_utils(name, UTILS_MODULE_NAMES)
-
-
-def test_sdk_symbols_lazy_imports():
- """Every symbol previously imported eagerly in litellm/__init__.py resolves to the source module attribute."""
- for name, (module_path, attr_name) in _SDK_SYMBOLS_IMPORT_MAP.items():
- resolved = getattr(litellm, name)
- expected = getattr(importlib.import_module(module_path), attr_name)
- assert resolved is expected, f"litellm.{name} is not {module_path}.{attr_name}"
-
-
-def test_sdk_module_aliases():
- """Module-valued attributes (litellm.anthropic, litellm.httpx, ...) resolve to the aliased modules."""
- for name, module_path in _SDK_MODULE_ALIASES.items():
- assert getattr(litellm, name) is importlib.import_module(module_path)
-
-
-def test_litellm_submodule_fallback():
- """litellm. attribute access resolves real submodules and returns None for unknown names."""
- assert lazy_import_litellm_submodule("budget_manager") is importlib.import_module("litellm.budget_manager")
- assert litellm.utils is importlib.import_module("litellm.utils")
- assert lazy_import_litellm_submodule("not_a_real_submodule") is None
- with pytest.raises(AttributeError):
- _ = litellm.not_a_real_attribute
-
-
-def test_missing_attribute_stays_attribute_error_when_find_spec_lies(monkeypatch):
- """getattr(litellm, name, default) must not leak ModuleNotFoundError when find_spec is patched to always succeed."""
- monkeypatch.setattr(importlib.util, "find_spec", lambda name: object())
- assert getattr(litellm, "not_a_real_submodule", None) is None
- with pytest.raises(AttributeError):
- _ = litellm.not_a_real_attribute
-
-
-def test_proxy_private_submodule_resolves_in_fresh_process():
- """litellm.proxy._types resolves without an eager proxy import (used by documentation checks)."""
- code = "import litellm\nprint(litellm.proxy._types.__name__)\n"
- result = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True)
- assert result.returncode == 0, result.stderr
- assert result.stdout.strip() == "litellm.proxy._types"
-
-
-def test_lazy_instances_are_singletons():
- """Lazily created instances are cached, so repeated access returns the same object."""
- assert litellm._key_management_settings is litellm._key_management_settings
- assert litellm.vertexAITextEmbeddingConfig is litellm.vertexAITextEmbeddingConfig
- from litellm.types.secret_managers.main import KeyManagementSettings
-
- assert isinstance(litellm._key_management_settings, KeyManagementSettings)
-
-
-def test_star_import_exports_public_api():
- """`from litellm import *` keeps exporting the full public surface despite lazy loading."""
- code = (
- "from litellm import *\n"
- "import litellm\n"
- "missing = [n for n in litellm.__all__ if n not in dir()]\n"
- "assert not missing, missing[:20]\n"
- "assert callable(completion) and callable(Router)\n"
- )
- result = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True)
- assert result.returncode == 0, result.stderr
-
-
-@pytest.mark.skipif(sys.platform != "linux", reason="reads /proc for RSS")
-def test_import_litellm_stays_lightweight():
- """`import litellm` must not pull in the SDK/proxy heavyweights or blow up RSS (LIT-6607)."""
- code = (
- "import json, re, sys\n"
- "import litellm\n"
- "heavy = [m for m in ('litellm.main', 'litellm.utils', 'litellm.router', 'litellm.proxy.proxy_cli',\n"
- " 'tiktoken', 'fastapi', 'grpc', 'boto3') if m in sys.modules]\n"
- "with open('/proc/self/status') as f:\n"
- " rss_kb = int(re.search(r'VmRSS:\\s+(\\d+) kB', f.read()).group(1))\n"
- "print(json.dumps({'total': len(sys.modules), 'heavy': heavy, 'rss_mb': rss_kb / 1024}))\n"
- )
- result = subprocess.run([sys.executable, "-c", code], capture_output=True, text=True, check=True)
- stats = json.loads(result.stdout)
- assert stats["heavy"] == [], f"heavy modules imported eagerly: {stats['heavy']}"
- assert stats["total"] < 800, f"import litellm loaded {stats['total']} modules"
- assert stats["rss_mb"] < 75, f"import litellm used {stats['rss_mb']:.1f} MB RSS"
From 942e6cb3cd4c1e3a3cbb4ab1571e122a2230a593 Mon Sep 17 00:00:00 2001
From: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Date: Sat, 5 Sep 2026 16:12:43 -0700
Subject: [PATCH 29/35] fix(file_search): scope emulated file_search to the
request's vector stores
The emulated file_search handler searched whatever vector_store_id the
model returned, so a model steered to an id outside the request's
file_search tool reached a store the per-key vector store permission
check never saw. An id outside the request's stores now falls back to
those stores; an id that is one of them still narrows the search to it.
---
.../responses/file_search/emulated_handler.py | 2 +-
.../llms/test_file_search_responses.py | 110 +++++++++++++++++-
2 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/litellm/responses/file_search/emulated_handler.py b/litellm/responses/file_search/emulated_handler.py
index 0418f0c5e14..686d5c37fd0 100644
--- a/litellm/responses/file_search/emulated_handler.py
+++ b/litellm/responses/file_search/emulated_handler.py
@@ -459,7 +459,7 @@ async def _execute_file_search_tool_calls(
queries_from_call = _resolve_queries_from_args(args, input)
vs_id_arg = args.get("vector_store_id")
- vs_ids_for_call = [cast(str, vs_id_arg)] if vs_id_arg else all_vs_ids # cast-ok: model-supplied, as today
+ vs_ids_for_call = [cast(str, vs_id_arg)] if vs_id_arg in all_vs_ids else all_vs_ids # cast-ok: request id
queries, results = await _run_vector_searches(
queries=queries_from_call,
diff --git a/tests/test_litellm/llms/test_file_search_responses.py b/tests/test_litellm/llms/test_file_search_responses.py
index 887f14ce80e..5ecca664379 100644
--- a/tests/test_litellm/llms/test_file_search_responses.py
+++ b/tests/test_litellm/llms/test_file_search_responses.py
@@ -8,7 +8,7 @@ Coverage:
E1-E4 file_search guard in responses/main.py
F1-F6 ManagedFiles hook access control
G1-G3 get_vector_store_ids_from_file_search_tools()
- H1-H14 emulated_handler unit tests
+ H1-H17 emulated_handler unit tests
"""
import base64
@@ -936,3 +936,111 @@ class TestEmulatedFileSearchHandler:
f"Sub-call {i} must run with is_internal_call=True to suppress "
"billing callbacks in wrapper_async"
)
+
+ @pytest.mark.asyncio
+ async def test_H16_model_chosen_id_outside_request_is_not_searched(self):
+ """Security regression: a vector_store_id the model returns that was not in the
+ request's file_search tool must never be searched. Per-key authorization only sees
+ request ids, so honoring an off-schema id leaks stores the key cannot access.
+ The handler must fall back to the request's own stores instead."""
+ from litellm.responses.file_search.emulated_handler import (
+ aresponses_with_emulated_file_search,
+ )
+
+ first_resp = MagicMock()
+ first_resp.output = [
+ {
+ "type": "function_call",
+ "name": "litellm_file_search",
+ "call_id": "call_leak",
+ "arguments": '{"queries": ["launch codeword"], "vector_store_id": "vs_unauthorized"}',
+ }
+ ]
+ first_resp.id = "resp_leak"
+ first_resp.created_at = 1700000000
+ first_resp.model = "claude-3-5-sonnet"
+ first_resp.usage = None
+
+ final_resp = self._make_mock_responses_api_response(text="done")
+
+ search_result = MagicMock()
+ search_result.file_id = "file-allowed"
+ search_result.filename = "allowed.txt"
+ search_result.score = 0.9
+ search_result.content = [{"type": "text", "text": "allowed context"}]
+ mock_search_response = MagicMock()
+ mock_search_response.data = [search_result]
+
+ mock_asearch = AsyncMock(return_value=mock_search_response)
+ with (
+ patch.object(
+ import_module("litellm.responses.file_search.emulated_handler"),
+ "_call_aresponses",
+ new=AsyncMock(side_effect=[first_resp, final_resp]),
+ ),
+ patch("litellm.vector_stores.main.asearch", new=mock_asearch), # test-quality-ok: asserts store searched
+ ):
+ await aresponses_with_emulated_file_search(
+ input="What is the launch codeword?",
+ model="anthropic/claude-3-5-sonnet",
+ tools=[{"type": "file_search", "vector_store_ids": ["vs_allowed"]}],
+ )
+
+ searched_ids = [c.kwargs["vector_store_id"] for c in mock_asearch.call_args_list]
+ assert searched_ids, "Expected the vector store to be searched at least once"
+ assert "vs_unauthorized" not in searched_ids, (
+ "Handler searched the off-schema store the model picked; per-key auth never saw it"
+ )
+ assert set(searched_ids) == {"vs_allowed"}
+
+ @pytest.mark.asyncio
+ async def test_H17_model_chosen_id_within_request_narrows_search(self):
+ """A vector_store_id the model returns that IS one of the request's stores is honored:
+ only that store is searched, not every store in the request."""
+ from litellm.responses.file_search.emulated_handler import (
+ aresponses_with_emulated_file_search,
+ )
+
+ first_resp = MagicMock()
+ first_resp.output = [
+ {
+ "type": "function_call",
+ "name": "litellm_file_search",
+ "call_id": "call_narrow",
+ "arguments": '{"queries": ["q"], "vector_store_id": "vs_two"}',
+ }
+ ]
+ first_resp.id = "resp_narrow"
+ first_resp.created_at = 1700000000
+ first_resp.model = "claude-3-5-sonnet"
+ first_resp.usage = None
+
+ final_resp = self._make_mock_responses_api_response(text="done")
+
+ search_result = MagicMock()
+ search_result.file_id = "file-two"
+ search_result.filename = "two.txt"
+ search_result.score = 0.9
+ search_result.content = [{"type": "text", "text": "context"}]
+ mock_search_response = MagicMock()
+ mock_search_response.data = [search_result]
+
+ mock_asearch = AsyncMock(return_value=mock_search_response)
+ with (
+ patch.object(
+ import_module("litellm.responses.file_search.emulated_handler"),
+ "_call_aresponses",
+ new=AsyncMock(side_effect=[first_resp, final_resp]),
+ ),
+ patch("litellm.vector_stores.main.asearch", new=mock_asearch), # test-quality-ok: asserts store searched
+ ):
+ await aresponses_with_emulated_file_search(
+ input="q",
+ model="anthropic/claude-3-5-sonnet",
+ tools=[{"type": "file_search", "vector_store_ids": ["vs_one", "vs_two"]}],
+ )
+
+ searched_ids = [c.kwargs["vector_store_id"] for c in mock_asearch.call_args_list]
+ assert set(searched_ids) == {"vs_two"}, (
+ "A request-listed id the model picks should narrow the search to that store only"
+ )
From eee162b3178e80e91ab7b11b7504236507f9074b Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 16:12:45 -0700
Subject: [PATCH 30/35] fix(lazy_imports): type import_map as Mapping to stay
under the LIT001 budget
The revert restored the dict annotation that #39121 had loosened to Mapping,
and the LIT001 ceiling has been ratcheted down since, so the gate rejected the
one reintroduced hit. Annotation only, no behavior change.
---
litellm/_lazy_imports.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/litellm/_lazy_imports.py b/litellm/_lazy_imports.py
index 553aeb6680d..fe3c7c264ee 100644
--- a/litellm/_lazy_imports.py
+++ b/litellm/_lazy_imports.py
@@ -229,7 +229,7 @@ def _module_attribute(module: ModuleType, attr_name: str) -> object:
return attribute["value"]
-def _generic_lazy_import(name: str, import_map: dict[str, tuple[str, str]], category: str) -> object:
+def _generic_lazy_import(name: str, import_map: Mapping[str, tuple[str, str]], category: str) -> object:
"""
Generic function that handles lazy importing for most attributes.
From 27c55a21d98627661703de9683a64d6718841824 Mon Sep 17 00:00:00 2001
From: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
Date: Sat, 5 Sep 2026 16:19:29 -0700
Subject: [PATCH 31/35] test(proxy): type the traceback-recording hook to match
CustomLogger
The regression test's recording logger overrode async_post_call_failure_hook
with untyped parameters. It now mirrors the base signature, and the
UserAPIKeyAuth import moves to module level so the annotation resolves.
---
tests/test_litellm/proxy/test_proxy_utils.py | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/tests/test_litellm/proxy/test_proxy_utils.py b/tests/test_litellm/proxy/test_proxy_utils.py
index 51176c2b251..dcf18e773e8 100644
--- a/tests/test_litellm/proxy/test_proxy_utils.py
+++ b/tests/test_litellm/proxy/test_proxy_utils.py
@@ -7,7 +7,7 @@ from fastapi import HTTPException
from litellm.caching.caching import DualCache
from litellm.integrations.custom_guardrail import CustomGuardrail
from litellm.integrations.custom_logger import CustomLogger
-from litellm.proxy._types import ProxyErrorTypes
+from litellm.proxy._types import ProxyErrorTypes, UserAPIKeyAuth
from litellm.proxy.utils import ProxyLogging
from litellm.types.guardrails import GuardrailEventHooks
@@ -1923,11 +1923,17 @@ async def test_proxy_only_error_5xx_keeps_traceback_and_runs_sync_callbacks(monk
class _TracebackRecordingLogger(CustomLogger):
- def __init__(self):
+ def __init__(self) -> None:
super().__init__()
self.received_traceback: str | None = None
- async def async_post_call_failure_hook(self, request_data, original_exception, user_api_key_dict, traceback_str=None):
+ async def async_post_call_failure_hook(
+ self,
+ request_data: dict,
+ original_exception: Exception,
+ user_api_key_dict: UserAPIKeyAuth,
+ traceback_str: str | None = None,
+ ) -> HTTPException | None:
self.received_traceback = traceback_str
return None
@@ -1942,8 +1948,6 @@ async def test_post_call_failure_hook_redacts_traceback_before_callbacks(monkeyp
import httpx
- from litellm.proxy._types import UserAPIKeyAuth
-
provider_key = "AIza" + "S" * 35
upstream_url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini:generateContent?key={provider_key}"
response = httpx.Response(400, request=httpx.Request("POST", upstream_url))
From 9a5564f00e1522bbaba246221e1b1dc26bb92752 Mon Sep 17 00:00:00 2001
From: "devin-ai-integration[bot]"
<158243242+devin-ai-integration[bot]@users.noreply.github.com>
Date: Sat, 5 Sep 2026 16:20:56 -0700
Subject: [PATCH 32/35] fix(ui): read Usage Total Requests tile from gateway
request counts (#39963)
---
.../components/UsagePageView.test.tsx | 24 +++++++++----------
.../_components/components/UsagePageView.tsx | 5 +++-
2 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.test.tsx
index 26d595f4d74..7702488f5bf 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.test.tsx
@@ -424,17 +424,14 @@ describe("UsagePage", () => {
// Check that key metrics are displayed
const totalRequestElements = screen.getAllByText("Total Requests");
expect(totalRequestElements.length).toBeGreaterThan(0);
- expect(screen.getByText("1,500")).toBeInTheDocument();
const successfulRequestLabelElements = screen.getAllByText("Successful Requests");
expect(successfulRequestLabelElements.length).toBeGreaterThan(0);
- // Successful and Failed Requests both read the gateway counter, not the
- // spend-derived 1,450 / 50 that the same payload carries for the per-key and
- // per-model breakdowns. They must share a source, or the tiles contradict the
- // endpoint breakdown chart below them.
await waitFor(() => {
expect(screen.getAllByText("424,242").length).toBeGreaterThan(0);
});
expect(screen.getAllByText("909").length).toBeGreaterThan(0);
+ expect(screen.getByText("425,151")).toBeInTheDocument();
+ expect(screen.queryByText("1,500")).not.toBeInTheDocument();
expect(screen.queryByText("1,450")).not.toBeInTheDocument();
});
@@ -454,7 +451,7 @@ describe("UsagePage", () => {
renderWithProviders( );
await waitFor(() => {
- expect(screen.getAllByText("1,500").length).toBeGreaterThan(0);
+ expect(screen.getAllByText("75,000").length).toBeGreaterThan(0);
});
await act(async () => {
@@ -464,13 +461,13 @@ describe("UsagePage", () => {
await waitFor(() => {
expect(mockUserDailyActivityAggregatedCall).toHaveBeenCalledTimes(2);
});
- expect(screen.queryByText("1,500")).not.toBeInTheDocument();
+ expect(screen.queryByText("75,000")).not.toBeInTheDocument();
await act(async () => {
releaseSecondFetch();
});
await waitFor(() => {
- expect(screen.getAllByText("1,500").length).toBeGreaterThan(0);
+ expect(screen.getAllByText("75,000").length).toBeGreaterThan(0);
});
});
@@ -485,8 +482,10 @@ describe("UsagePage", () => {
await waitFor(() => {
expect(screen.getAllByText("1,450").length).toBeGreaterThan(0);
});
+ expect(screen.getByText("1,500")).toBeInTheDocument();
expect(screen.queryByText("424,242")).not.toBeInTheDocument();
expect(screen.queryByText("909")).not.toBeInTheDocument();
+ expect(screen.queryByText("425,151")).not.toBeInTheDocument();
expect(screen.queryByTestId("gateway-requests-by-endpoint")).not.toBeInTheDocument();
});
@@ -499,6 +498,7 @@ describe("UsagePage", () => {
expect(mockUserDailyActivityAggregatedCall).toHaveBeenCalled();
});
expect(mockGatewayDailyActivityCall).not.toHaveBeenCalled();
+ expect(screen.getByText("1,500")).toBeInTheDocument();
expect(screen.queryByText("424,242")).not.toBeInTheDocument();
expect(screen.queryByTestId("gateway-requests-by-endpoint")).not.toBeInTheDocument();
});
@@ -1045,7 +1045,7 @@ describe("UsagePage", () => {
});
// Should still render the data from the paginated fallback, which lands a render after the call
- expect(await screen.findByText("1,500")).toBeInTheDocument();
+ expect(await screen.findByText("75,000")).toBeInTheDocument();
});
it("should stop showing the previous range's paginated pages while a new range is in flight", async () => {
@@ -1069,7 +1069,7 @@ describe("UsagePage", () => {
renderWithProviders( );
await waitFor(() => {
- expect(screen.getAllByText("1,500").length).toBeGreaterThan(0);
+ expect(screen.getAllByText("75,000").length).toBeGreaterThan(0);
});
await act(async () => {
@@ -1079,13 +1079,13 @@ describe("UsagePage", () => {
await waitFor(() => {
expect(mockUserDailyActivityAggregatedCall).toHaveBeenCalledTimes(2);
});
- expect(screen.queryByText("1,500")).not.toBeInTheDocument();
+ expect(screen.queryByText("75,000")).not.toBeInTheDocument();
await act(async () => {
releaseSecondAggregated();
});
await waitFor(() => {
- expect(screen.getAllByText("1,500").length).toBeGreaterThan(0);
+ expect(screen.getAllByText("75,000").length).toBeGreaterThan(0);
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.tsx b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.tsx
index 29a81e1ae3f..a92d1209567 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/usage/_components/components/UsagePageView.tsx
@@ -573,7 +573,10 @@ const UsagePage: React.FC = ({ teams, organizations }) => {
Total Requests
- {userSpendData.metadata?.total_api_requests?.toLocaleString() || 0}
+ {(gatewayActivity
+ ? gatewayActivity.total_successful_requests + gatewayActivity.total_failed_requests
+ : userSpendData.metadata?.total_api_requests
+ )?.toLocaleString() || 0}
From 0e118342ac2294cce33230a8632e6901a5d4d2dd Mon Sep 17 00:00:00 2001
From: Yuneng Jiang
Date: Sat, 5 Sep 2026 16:25:57 -0700
Subject: [PATCH 33/35] chore: update Next.js build artifacts (2026-09-05 23:25
UTC, node v24.19.0)
---
litellm/proxy/_experimental/out/404.html | 2 +-
.../proxy/_experimental/out/404/index.html | 2 +-
.../out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt | 8 +-
.../out/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../proxy/_experimental/out/__next._full.txt | 40 +-
.../proxy/_experimental/out/__next._head.txt | 8 +-
.../proxy/_experimental/out/__next._index.txt | 18 +-
.../proxy/_experimental/out/__next._tree.txt | 4 +-
.../_buildManifest.js | 0
.../_clientMiddlewareManifest.js | 0
.../_ssgManifest.js | 0
.../out/_next/static/chunks/0-dst_pi7co_a.js | 1 -
.../out/_next/static/chunks/0002gr7w0f3nn.js | 1 -
.../out/_next/static/chunks/00dvxqp6f0f6s.js | 1 -
.../out/_next/static/chunks/01benr9g1pe74.js | 1 -
.../out/_next/static/chunks/01oqh-5b0ytmu.js | 420 ++++++++++++++++++
.../out/_next/static/chunks/027qywrv12iu8.js | 1 -
.../out/_next/static/chunks/028hvx-avwx8g.js | 1 +
.../out/_next/static/chunks/02ic1ccwq2p02.js | 1 +
.../out/_next/static/chunks/03_s-zve24zyk.js | 1 +
.../out/_next/static/chunks/03k5rtnvgsg9q.js | 1 -
.../out/_next/static/chunks/03pu_dx0gqja9.js | 2 +
.../out/_next/static/chunks/04fw18d3dx40b.js | 1 +
.../out/_next/static/chunks/04oxg_atba30d.js | 1 +
.../out/_next/static/chunks/059psjgsicqvu.js | 1 +
.../out/_next/static/chunks/05jtp8xqp3j0x.js | 1 -
.../{1v3m908ycsmt4.js => 07cqsb7poupf9.js} | 2 +-
.../out/_next/static/chunks/08lua1iopk_79.js | 1 -
.../out/_next/static/chunks/0a3n_ovfo3c5s.js | 1 -
.../out/_next/static/chunks/0b8dlr4_m6177.js | 1 +
.../out/_next/static/chunks/0cotqb-2hzyvs.js | 1 -
.../out/_next/static/chunks/0d4xeknobwogp.js | 1 -
.../out/_next/static/chunks/0dnt68i2qq-dg.js | 1 -
.../out/_next/static/chunks/0dypptaj7tfcw.js | 1 +
.../out/_next/static/chunks/0esaql-j_8-p2.js | 1 +
.../out/_next/static/chunks/0ikamdtw78iln.js | 1 -
.../out/_next/static/chunks/0k6ku5hw0lxbs.js | 161 +++++++
.../out/_next/static/chunks/0k88woxbttvcj.js | 179 ++++++++
.../out/_next/static/chunks/0lgjier0jo0da.js | 1 -
.../out/_next/static/chunks/0limvbttcca8i.js | 1 +
.../out/_next/static/chunks/0n_d-fecc6ing.js | 50 ---
.../out/_next/static/chunks/0nv-vje-mizhj.js | 1 -
.../out/_next/static/chunks/0ob_vs6vpubam.js | 1 -
.../out/_next/static/chunks/0p2ty6d6s6ikf.js | 1 -
.../out/_next/static/chunks/0syzzpo5y8_r6.js | 1 -
.../out/_next/static/chunks/0t8t3-_8y1jh9.js | 1 +
.../out/_next/static/chunks/0tzf0u6ba54sb.js | 1 +
.../out/_next/static/chunks/0u-hvuc1nke0t.js | 16 -
.../out/_next/static/chunks/0ukqyn87nhmzd.js | 1 +
.../out/_next/static/chunks/0v_v1lhy48ega.js | 1 -
.../out/_next/static/chunks/0wh5uu7sl34-i.js | 1 -
.../out/_next/static/chunks/0xau2pz4q9eoy.js | 1 +
.../out/_next/static/chunks/0xrc-9_hkt1-y.js | 1 -
.../out/_next/static/chunks/0xvwtyit6foq4.js | 7 +
.../out/_next/static/chunks/0ymd13yj7v7rj.js | 1 -
.../out/_next/static/chunks/0yx8e9275ph17.js | 1 -
.../{0xcu3s37s9axz.js => 0z6yavb6ipml_.js} | 2 +-
.../out/_next/static/chunks/0z7zg9587od6_.js | 1 -
.../out/_next/static/chunks/108z0ff937g6x.js | 1 +
.../out/_next/static/chunks/10ncv_5h3izdc.js | 1 -
.../out/_next/static/chunks/1197jfkq-iw2n.js | 1 -
.../out/_next/static/chunks/119w1gziyp548.js | 1 +
.../out/_next/static/chunks/11r2ma61byh99.js | 1 -
.../out/_next/static/chunks/1237ige31qaii.js | 1 +
.../out/_next/static/chunks/12_i2u3reazjh.js | 1 +
.../out/_next/static/chunks/12chby2_3oupv.js | 1 -
.../out/_next/static/chunks/12ws1ltetp8yp.js | 1 -
.../out/_next/static/chunks/1317afg16-lx1.js | 1 -
.../out/_next/static/chunks/13rzpi4q1z_e8.js | 1 -
.../out/_next/static/chunks/13sw7w_3mi213.js | 1 +
.../out/_next/static/chunks/14394ef4y9l3a.js | 1 +
.../out/_next/static/chunks/146bhdjwt88wp.js | 1 +
.../out/_next/static/chunks/14bbxzqzpwr4d.js | 1 -
.../{1caa4vd721cvu.js => 14h76g_paiizi.js} | 2 +-
.../out/_next/static/chunks/154ouf9jccp1g.js | 1 +
.../out/_next/static/chunks/16xdxq7qvv37h.js | 1 -
.../out/_next/static/chunks/16zk64em3o_xr.js | 1 -
.../out/_next/static/chunks/19d70ks0akyja.js | 1 +
.../{3gmtm1iixkmgr.js => 19h10tzn4xbhq.js} | 2 +-
.../out/_next/static/chunks/1a3mamulxkyhw.js | 1 -
.../out/_next/static/chunks/1ahp6rse2_f9c.js | 1 -
.../out/_next/static/chunks/1cawzcg3f9m_b.js | 1 +
.../out/_next/static/chunks/1dpuw-kkts-4z.js | 1 +
.../out/_next/static/chunks/1dx34ygzjt19e.js | 1 +
.../out/_next/static/chunks/1e7t2-ca-xsv3.js | 1 +
.../out/_next/static/chunks/1e94pphgfbmhc.js | 1 +
.../out/_next/static/chunks/1ffshjz5d4_3s.js | 7 -
.../out/_next/static/chunks/1fxpl6mmobvuv.js | 1 +
.../out/_next/static/chunks/1ghmzc3sotzoy.js | 1 +
.../out/_next/static/chunks/1ib-wrl-rx9mb.js | 1 -
.../out/_next/static/chunks/1ipimnkawqmc0.js | 1 +
.../out/_next/static/chunks/1j-81t3ummx7f.js | 1 +
.../out/_next/static/chunks/1j0tzdbu2gh-d.js | 1 +
.../out/_next/static/chunks/1j44zjath-uo2.js | 5 -
.../out/_next/static/chunks/1l61r88q65pjd.js | 1 -
.../out/_next/static/chunks/1l7aqyj-639ip.js | 1 -
.../out/_next/static/chunks/1l8v98u-man65.js | 1 -
.../out/_next/static/chunks/1oixgwji948fa.js | 1 +
.../out/_next/static/chunks/1p9jm-g7u52aq.js | 179 --------
.../out/_next/static/chunks/1q0dpasyg7o3d.js | 1 -
.../out/_next/static/chunks/1qn5rcv_00n67.js | 420 ++++++++++++++++++
.../out/_next/static/chunks/1r-uf54j7w03c.js | 38 ++
.../out/_next/static/chunks/1ril0nieln4ln.js | 3 -
.../out/_next/static/chunks/1t2fg_goa98_p.js | 1 +
.../out/_next/static/chunks/1tls-8aiib7f5.js | 1 +
.../out/_next/static/chunks/1tvsqn7ove-oj.js | 1 +
.../out/_next/static/chunks/1vlm1-btu0fbz.js | 1 -
.../out/_next/static/chunks/1vrr5gef27wsb.js | 1 -
.../out/_next/static/chunks/1vw9cmijff2mj.js | 1 -
.../out/_next/static/chunks/1vzcuk-15dfr2.js | 1 -
.../out/_next/static/chunks/1vzhjykovw9ji.js | 1 -
.../out/_next/static/chunks/1wuxy9_mvw4yx.js | 1 +
.../out/_next/static/chunks/1xhchm7onfol4.js | 1 -
.../out/_next/static/chunks/1z-pueirfgle5.js | 1 +
.../out/_next/static/chunks/1zzr0tgfl-g4s.js | 179 --------
.../out/_next/static/chunks/2-jkx2__3xy9q.js | 179 ++++++++
.../out/_next/static/chunks/2-z2qnhuwaoz-.js | 1 -
.../out/_next/static/chunks/20z5qtar5xis1.js | 1 -
.../out/_next/static/chunks/212bxxmv8g2o8.js | 1 +
.../out/_next/static/chunks/2165p8kcyq28a.js | 1 +
.../out/_next/static/chunks/217any77nuolr.js | 1 +
.../out/_next/static/chunks/22t32wpbub0ay.js | 1 +
.../{33s1cd7i7uenu.js => 24-0ciobj3ggc.js} | 2 +-
.../{34_wtpkkvqa3n.js => 257-u3v7vdxzj.js} | 2 +-
.../out/_next/static/chunks/26wdbcc5z9ot9.js | 1 -
.../out/_next/static/chunks/27gtmvuu3uwb-.js | 1 -
.../out/_next/static/chunks/27ztlw0u47b4v.js | 1 +
.../out/_next/static/chunks/28z7xz3dmb5mt.js | 1 +
.../{2e2guakawc2hv.js => 293hy1wyw_zum.js} | 2 +-
.../out/_next/static/chunks/29xhz9f3b5uh_.js | 1 -
.../out/_next/static/chunks/2_e0pm0jc-yil.js | 420 ------------------
.../out/_next/static/chunks/2b1up8z26ai59.js | 1 -
.../out/_next/static/chunks/2bij6nxiu6v1x.js | 1 -
.../out/_next/static/chunks/2bl93j-9lt0zm.js | 1 +
.../out/_next/static/chunks/2cl8_u3nwv5pp.js | 1 +
.../out/_next/static/chunks/2ctmb5tt7j_un.js | 1 +
.../out/_next/static/chunks/2d32l5hjlui28.js | 1 +
.../out/_next/static/chunks/2dvjnwfxzyldc.js | 1 +
.../out/_next/static/chunks/2eq3u5hwabrai.js | 1 -
.../out/_next/static/chunks/2gdhedfht2i80.js | 1 +
.../out/_next/static/chunks/2hl_9t55v67qt.js | 1 -
.../{34t9vb_mm_wki.js => 2hz92aqj77zlw.js} | 2 +-
.../out/_next/static/chunks/2k6lzy5s7rafp.js | 1 +
.../out/_next/static/chunks/2kjmosw5g-gsc.js | 1 -
.../out/_next/static/chunks/2kph8rgszljlv.js | 1 +
.../out/_next/static/chunks/2kuymb9f8gjqm.js | 49 --
.../out/_next/static/chunks/2kxwsvv2wqqd_.js | 1 -
.../out/_next/static/chunks/2lpmjdx2jlx34.js | 1 -
.../{3hpxr2v3x-0xz.js => 2lwlr41sgghqp.js} | 2 +-
.../{2veyvbaagt-60.js => 2lx_pto6xfsa7.js} | 2 +-
.../{27gjrlkmq245y.js => 2mo45qar55a-z.js} | 2 +-
.../out/_next/static/chunks/2n9vhssm1ke4u.js | 1 -
.../out/_next/static/chunks/2nfd8afirv_hx.js | 1 -
.../out/_next/static/chunks/2o6ajjzms3r2n.js | 1 +
.../out/_next/static/chunks/2orlhe31dolig.js | 1 +
.../out/_next/static/chunks/2pmm79g5r_ebn.js | 1 +
.../out/_next/static/chunks/2qr0-fzlxoy7o.js | 5 -
.../out/_next/static/chunks/2ryp4-cmeq_d2.js | 1 +
.../out/_next/static/chunks/2tckjhqtu3wii.js | 1 +
.../out/_next/static/chunks/2tco7hl92nf5g.js | 5 +
.../out/_next/static/chunks/2tj1x2xl0npv1.js | 1 -
.../out/_next/static/chunks/2ty4asibief-4.js | 1 +
.../out/_next/static/chunks/2u59vywexbybu.js | 1 -
.../out/_next/static/chunks/2u89qrvzp-8bp.js | 1 +
.../out/_next/static/chunks/2vj1gwc3np8ir.js | 1 -
.../out/_next/static/chunks/2wa5a5dysfrb3.js | 1 -
.../out/_next/static/chunks/2wjkotbxoelv_.js | 1 -
.../out/_next/static/chunks/2wmgu52j_4-e-.js | 1 +
.../out/_next/static/chunks/2yik4fkekmght.js | 1 -
.../out/_next/static/chunks/2yrtzeoze9bgu.js | 1 +
.../out/_next/static/chunks/2yypakvxqodzf.js | 1 +
.../out/_next/static/chunks/2zew1vg3hql9m.js | 158 -------
.../out/_next/static/chunks/2zk7h7_6p0cx3.js | 1 +
.../out/_next/static/chunks/3155srena77mb.js | 1 +
.../out/_next/static/chunks/318d0grxaivtg.js | 1 +
.../out/_next/static/chunks/31hmjujca2pu3.js | 1 +
.../{1_2vrjj-7-crg.js => 31u0v5nu0m22x.js} | 23 +-
.../out/_next/static/chunks/32obiws158hw0.js | 1 +
.../out/_next/static/chunks/32z61pa-uiw17.js | 1 -
.../out/_next/static/chunks/33t6_jpdse1_6.js | 1 +
.../out/_next/static/chunks/34hhnp87pqxic.js | 1 +
.../{16hwhhfys5l7o.js => 35pk5e14z92ti.js} | 2 +-
.../out/_next/static/chunks/35xohwm38b-8-.js | 1 +
.../out/_next/static/chunks/367h6aovv92ya.js | 420 ------------------
.../out/_next/static/chunks/381upin2heiqu.js | 1 +
.../out/_next/static/chunks/38pukqn2wwot2.js | 1 +
.../out/_next/static/chunks/390d3ojugt32e.js | 1 -
.../out/_next/static/chunks/3a20afvsnrq33.js | 1 +
.../out/_next/static/chunks/3agwsexylijeu.js | 1 -
.../out/_next/static/chunks/3alik9wjwtjek.js | 1 +
.../out/_next/static/chunks/3c8-k_-5ap8co.js | 1 +
.../out/_next/static/chunks/3cf10ailmi24x.js | 1 +
.../out/_next/static/chunks/3d2_6alyra4xu.js | 1 +
.../out/_next/static/chunks/3efeazyh44a5c.js | 1 -
.../out/_next/static/chunks/3f4pzky9ekcep.js | 1 +
.../out/_next/static/chunks/3f9q88-lg6z6a.js | 1 +
.../{0gb6pr-exq8__.js => 3f_0s7g6r4mmt.js} | 2 +-
.../{3kest3gurc9op.js => 3fn8zqlfrwowr.js} | 4 +-
.../out/_next/static/chunks/3goocbdtj1s73.js | 1 -
.../out/_next/static/chunks/3hzsy6hidjrrf.js | 1 -
.../out/_next/static/chunks/3idmblk6vi8i5.css | 1 -
.../out/_next/static/chunks/3it786tjaipxf.js | 1 +
.../out/_next/static/chunks/3iw7hxslaupar.js | 420 ------------------
.../out/_next/static/chunks/3jjcizfocnz_x.js | 1 +
.../out/_next/static/chunks/3jyuhlymn08un.js | 1 +
.../out/_next/static/chunks/3khb7fu59rrn0.js | 1 +
.../out/_next/static/chunks/3kjqcg08ybop4.js | 1 +
.../out/_next/static/chunks/3kmz9wrzxsgny.js | 1 -
.../out/_next/static/chunks/3lsrgjh8c8ahy.js | 1 -
.../out/_next/static/chunks/3lvwyc5xjv11f.css | 1 +
.../out/_next/static/chunks/3mf-i5vpaobpt.js | 16 +
.../out/_next/static/chunks/3mku0qt8uky_s.js | 420 ++++++++++++++++++
.../out/_next/static/chunks/3myqkomz-f4hl.js | 1 -
.../out/_next/static/chunks/3n9bn2grdu_k9.js | 1 -
.../out/_next/static/chunks/3psz25p__3u7s.js | 3 +
.../out/_next/static/chunks/3ptzupbbzlu4r.js | 1 -
.../out/_next/static/chunks/3qakmp848wcl5.js | 1 +
.../out/_next/static/chunks/3qc0ck7jhqdwb.js | 1 +
.../out/_next/static/chunks/3qcv7jqxtoq4c.js | 49 ++
.../out/_next/static/chunks/3rfer25uusl4w.js | 420 ------------------
.../out/_next/static/chunks/3rswcsdlv_3x3.js | 1 -
.../out/_next/static/chunks/3rtva9i63bdtr.js | 420 ++++++++++++++++++
.../out/_next/static/chunks/3rvs_drt9t99-.js | 1 +
.../out/_next/static/chunks/3s39b43k2vde7.js | 2 -
.../out/_next/static/chunks/3s8bc2986w4ao.js | 1 +
.../out/_next/static/chunks/3sd6_fqjvvk5h.js | 38 --
.../out/_next/static/chunks/3trm3pab_56a6.js | 1 +
.../{2c2i88pd_wixs.js => 3u5j9_7z0dl5w.js} | 4 +-
.../out/_next/static/chunks/3usevqfo8l66i.js | 1 -
.../out/_next/static/chunks/3vomzav3318x2.js | 1 +
.../out/_next/static/chunks/3wdy9040h4b13.js | 1 -
.../out/_next/static/chunks/3wo_4cg1wa3hg.js | 5 +
.../out/_next/static/chunks/3x37-3yc_2870.js | 1 +
.../out/_next/static/chunks/3xa3ywp_ixe85.js | 1 -
.../out/_next/static/chunks/3xxkselkexvi9.js | 1 +
.../out/_next/static/chunks/3yegoaduwt53n.js | 50 +++
.../out/_next/static/chunks/3zttc3p8so4fm.js | 1 -
.../out/_next/static/chunks/400vd436tmxp-.js | 1 -
.../out/_next/static/chunks/406voqt1wl0st.js | 1 +
.../out/_next/static/chunks/4221gwk3c-ett.js | 1 +
.../out/_next/static/chunks/44ycc-s2cvnts.js | 1 -
.../static/media/alice.13frxbgffyihr.svg | 4 +
.../static/media/gigachat.37uico956hu-u.svg | 27 ++
.../static/media/mongodb.1l7egqakv5sij.svg | 6 +
.../out/_not-found/__next._full.txt | 28 +-
.../out/_not-found/__next._head.txt | 8 +-
.../out/_not-found/__next._index.txt | 18 +-
.../_not-found/__next._not-found.__PAGE__.txt | 4 +-
.../out/_not-found/__next._not-found.txt | 6 +-
.../out/_not-found/__next._tree.txt | 4 +-
.../_experimental/out/_not-found/index.html | 2 +-
.../_experimental/out/_not-found/index.txt | 28 +-
...KGRhc2hib2FyZCk.access-groups.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.access-groups.txt | 6 +-
.../access-groups/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/access-groups/__next._full.txt | 40 +-
.../out/access-groups/__next._head.txt | 8 +-
.../out/access-groups/__next._index.txt | 18 +-
.../out/access-groups/__next._tree.txt | 4 +-
.../out/access-groups/index.html | 2 +-
.../_experimental/out/access-groups/index.txt | 40 +-
....!KGRhc2hib2FyZCk.admin-panel.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.admin-panel.txt | 6 +-
.../admin-panel/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/admin-panel/__next._full.txt | 40 +-
.../out/admin-panel/__next._head.txt | 8 +-
.../out/admin-panel/__next._index.txt | 18 +-
.../out/admin-panel/__next._tree.txt | 4 +-
.../_experimental/out/admin-panel/index.html | 2 +-
.../_experimental/out/admin-panel/index.txt | 40 +-
..._next.!KGRhc2hib2FyZCk.agents.__PAGE__.txt | 8 +-
.../agents/__next.!KGRhc2hib2FyZCk.agents.txt | 6 +-
.../out/agents/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../_experimental/out/agents/__next._full.txt | 40 +-
.../_experimental/out/agents/__next._head.txt | 8 +-
.../out/agents/__next._index.txt | 18 +-
.../_experimental/out/agents/__next._tree.txt | 4 +-
.../proxy/_experimental/out/agents/index.html | 2 +-
.../proxy/_experimental/out/agents/index.txt | 40 +-
...ext.!KGRhc2hib2FyZCk.api-keys.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.api-keys.txt | 6 +-
.../out/api-keys/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/api-keys/__next._full.txt | 40 +-
.../out/api-keys/__next._head.txt | 8 +-
.../out/api-keys/__next._index.txt | 18 +-
.../out/api-keys/__next._tree.txt | 4 +-
.../_experimental/out/api-keys/index.html | 2 +-
.../_experimental/out/api-keys/index.txt | 40 +-
...KGRhc2hib2FyZCk.api-reference.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.api-reference.txt | 6 +-
.../api-reference/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/api-reference/__next._full.txt | 38 +-
.../out/api-reference/__next._head.txt | 8 +-
.../out/api-reference/__next._index.txt | 18 +-
.../out/api-reference/__next._tree.txt | 4 +-
.../out/api-reference/index.html | 2 +-
.../_experimental/out/api-reference/index.txt | 38 +-
.../_experimental/out/assets/logos/alice.svg | 4 +
.../out/assets/logos/gigachat.svg | 27 ++
.../out/assets/logos/mongodb.svg | 6 +
...next.!KGRhc2hib2FyZCk.budgets.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.budgets.txt | 6 +-
.../out/budgets/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/budgets/__next._full.txt | 40 +-
.../out/budgets/__next._head.txt | 8 +-
.../out/budgets/__next._index.txt | 18 +-
.../out/budgets/__next._tree.txt | 4 +-
.../_experimental/out/budgets/index.html | 2 +-
.../proxy/_experimental/out/budgets/index.txt | 40 +-
...next.!KGRhc2hib2FyZCk.caching.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.caching.txt | 6 +-
.../out/caching/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/caching/__next._full.txt | 40 +-
.../out/caching/__next._head.txt | 8 +-
.../out/caching/__next._index.txt | 18 +-
.../out/caching/__next._tree.txt | 4 +-
.../_experimental/out/caching/index.html | 2 +-
.../proxy/_experimental/out/caching/index.txt | 40 +-
.../_experimental/out/chat/__next._full.txt | 38 +-
.../_experimental/out/chat/__next._head.txt | 8 +-
.../_experimental/out/chat/__next._index.txt | 18 +-
.../_experimental/out/chat/__next._tree.txt | 4 +-
.../out/chat/__next.chat.__PAGE__.txt | 8 +-
.../_experimental/out/chat/__next.chat.txt | 10 +-
.../out/chat/api-keys/__next._full.txt | 36 +-
.../out/chat/api-keys/__next._head.txt | 8 +-
.../out/chat/api-keys/__next._index.txt | 18 +-
.../out/chat/api-keys/__next._tree.txt | 4 +-
.../__next.chat.api-keys.__PAGE__.txt | 8 +-
.../chat/api-keys/__next.chat.api-keys.txt | 6 +-
.../out/chat/api-keys/__next.chat.txt | 10 +-
.../out/chat/api-keys/index.html | 2 +-
.../_experimental/out/chat/api-keys/index.txt | 36 +-
.../out/chat/credentials/__next._full.txt | 36 +-
.../out/chat/credentials/__next._head.txt | 8 +-
.../out/chat/credentials/__next._index.txt | 18 +-
.../out/chat/credentials/__next._tree.txt | 4 +-
.../__next.chat.credentials.__PAGE__.txt | 8 +-
.../credentials/__next.chat.credentials.txt | 6 +-
.../out/chat/credentials/__next.chat.txt | 10 +-
.../out/chat/credentials/index.html | 2 +-
.../out/chat/credentials/index.txt | 36 +-
.../proxy/_experimental/out/chat/index.html | 2 +-
.../proxy/_experimental/out/chat/index.txt | 38 +-
.../out/chat/integrations/__next._full.txt | 38 +-
.../out/chat/integrations/__next._head.txt | 8 +-
.../out/chat/integrations/__next._index.txt | 18 +-
.../out/chat/integrations/__next._tree.txt | 4 +-
.../__next.chat.integrations.__PAGE__.txt | 8 +-
.../integrations/__next.chat.integrations.txt | 6 +-
.../out/chat/integrations/__next.chat.txt | 10 +-
.../out/chat/integrations/index.html | 2 +-
.../out/chat/integrations/index.txt | 38 +-
.../out/chat/logs/__next._full.txt | 38 +-
.../out/chat/logs/__next._head.txt | 8 +-
.../out/chat/logs/__next._index.txt | 18 +-
.../out/chat/logs/__next._tree.txt | 4 +-
.../chat/logs/__next.chat.logs.__PAGE__.txt | 8 +-
.../out/chat/logs/__next.chat.logs.txt | 6 +-
.../out/chat/logs/__next.chat.txt | 10 +-
.../_experimental/out/chat/logs/index.html | 2 +-
.../_experimental/out/chat/logs/index.txt | 38 +-
.../out/chat/usage/__next._full.txt | 36 +-
.../out/chat/usage/__next._head.txt | 8 +-
.../out/chat/usage/__next._index.txt | 18 +-
.../out/chat/usage/__next._tree.txt | 4 +-
.../out/chat/usage/__next.chat.txt | 10 +-
.../chat/usage/__next.chat.usage.__PAGE__.txt | 8 +-
.../out/chat/usage/__next.chat.usage.txt | 6 +-
.../_experimental/out/chat/usage/index.html | 2 +-
.../_experimental/out/chat/usage/index.txt | 36 +-
.../out/connect/__next._full.txt | 36 +-
.../out/connect/__next._head.txt | 8 +-
.../out/connect/__next._index.txt | 18 +-
.../out/connect/__next._tree.txt | 4 +-
.../out/connect/__next.connect.__PAGE__.txt | 8 +-
.../out/connect/__next.connect.txt | 10 +-
.../_experimental/out/connect/index.html | 2 +-
.../proxy/_experimental/out/connect/index.txt | 36 +-
...c2hib2FyZCk.cost-optimization.__PAGE__.txt | 8 +-
...ext.!KGRhc2hib2FyZCk.cost-optimization.txt | 6 +-
.../__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/cost-optimization/__next._full.txt | 40 +-
.../out/cost-optimization/__next._head.txt | 8 +-
.../out/cost-optimization/__next._index.txt | 18 +-
.../out/cost-optimization/__next._tree.txt | 4 +-
.../out/cost-optimization/index.html | 2 +-
.../out/cost-optimization/index.txt | 40 +-
...KGRhc2hib2FyZCk.cost-tracking.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.cost-tracking.txt | 6 +-
.../cost-tracking/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/cost-tracking/__next._full.txt | 40 +-
.../out/cost-tracking/__next._head.txt | 8 +-
.../out/cost-tracking/__next._index.txt | 18 +-
.../out/cost-tracking/__next._tree.txt | 4 +-
.../out/cost-tracking/index.html | 2 +-
.../_experimental/out/cost-tracking/index.txt | 40 +-
...2hib2FyZCk.guardrails-monitor.__PAGE__.txt | 8 +-
...xt.!KGRhc2hib2FyZCk.guardrails-monitor.txt | 6 +-
.../__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/guardrails-monitor/__next._full.txt | 40 +-
.../out/guardrails-monitor/__next._head.txt | 8 +-
.../out/guardrails-monitor/__next._index.txt | 18 +-
.../out/guardrails-monitor/__next._tree.txt | 4 +-
.../out/guardrails-monitor/index.html | 2 +-
.../out/guardrails-monitor/index.txt | 40 +-
...t.!KGRhc2hib2FyZCk.guardrails.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.guardrails.txt | 6 +-
.../guardrails/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/guardrails/__next._full.txt | 40 +-
.../out/guardrails/__next._head.txt | 8 +-
.../out/guardrails/__next._index.txt | 18 +-
.../out/guardrails/__next._tree.txt | 4 +-
.../_experimental/out/guardrails/index.html | 2 +-
.../_experimental/out/guardrails/index.txt | 40 +-
litellm/proxy/_experimental/out/index.html | 2 +-
litellm/proxy/_experimental/out/index.txt | 40 +-
...2hib2FyZCk.logging-and-alerts.__PAGE__.txt | 8 +-
...xt.!KGRhc2hib2FyZCk.logging-and-alerts.txt | 6 +-
.../__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/logging-and-alerts/__next._full.txt | 40 +-
.../out/logging-and-alerts/__next._head.txt | 8 +-
.../out/logging-and-alerts/__next._index.txt | 18 +-
.../out/logging-and-alerts/__next._tree.txt | 4 +-
.../out/logging-and-alerts/index.html | 2 +-
.../out/logging-and-alerts/index.txt | 40 +-
.../_experimental/out/login/__next._full.txt | 32 +-
.../_experimental/out/login/__next._head.txt | 8 +-
.../_experimental/out/login/__next._index.txt | 18 +-
.../_experimental/out/login/__next._tree.txt | 4 +-
.../out/login/__next.login.__PAGE__.txt | 8 +-
.../_experimental/out/login/__next.login.txt | 6 +-
.../proxy/_experimental/out/login/index.html | 2 +-
.../proxy/_experimental/out/login/index.txt | 32 +-
.../__next.!KGRhc2hib2FyZCk.logs.__PAGE__.txt | 8 +-
.../out/logs/__next.!KGRhc2hib2FyZCk.logs.txt | 6 +-
.../out/logs/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../_experimental/out/logs/__next._full.txt | 40 +-
.../_experimental/out/logs/__next._head.txt | 8 +-
.../_experimental/out/logs/__next._index.txt | 18 +-
.../_experimental/out/logs/__next._tree.txt | 4 +-
.../proxy/_experimental/out/logs/index.html | 2 +-
.../proxy/_experimental/out/logs/index.txt | 40 +-
....!KGRhc2hib2FyZCk.mcp-servers.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.mcp-servers.txt | 6 +-
.../mcp-servers/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/mcp-servers/__next._full.txt | 40 +-
.../out/mcp-servers/__next._head.txt | 8 +-
.../out/mcp-servers/__next._index.txt | 18 +-
.../out/mcp-servers/__next._tree.txt | 4 +-
.../_experimental/out/mcp-servers/index.html | 2 +-
.../_experimental/out/mcp-servers/index.txt | 40 +-
.../out/mcp/oauth/callback/__next._full.txt | 32 +-
.../out/mcp/oauth/callback/__next._head.txt | 8 +-
.../out/mcp/oauth/callback/__next._index.txt | 18 +-
.../out/mcp/oauth/callback/__next._tree.txt | 4 +-
.../__next.mcp.oauth.callback.__PAGE__.txt | 8 +-
.../callback/__next.mcp.oauth.callback.txt | 6 +-
.../mcp/oauth/callback/__next.mcp.oauth.txt | 6 +-
.../out/mcp/oauth/callback/__next.mcp.txt | 6 +-
.../out/mcp/oauth/callback/index.html | 2 +-
.../out/mcp/oauth/callback/index.txt | 32 +-
..._next.!KGRhc2hib2FyZCk.memory.__PAGE__.txt | 8 +-
.../memory/__next.!KGRhc2hib2FyZCk.memory.txt | 6 +-
.../out/memory/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../_experimental/out/memory/__next._full.txt | 40 +-
.../_experimental/out/memory/__next._head.txt | 8 +-
.../out/memory/__next._index.txt | 18 +-
.../_experimental/out/memory/__next._tree.txt | 4 +-
.../proxy/_experimental/out/memory/index.html | 2 +-
.../proxy/_experimental/out/memory/index.txt | 40 +-
...Rhc2hib2FyZCk.model-hub-table.__PAGE__.txt | 8 +-
..._next.!KGRhc2hib2FyZCk.model-hub-table.txt | 6 +-
.../__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/model-hub-table/__next._full.txt | 40 +-
.../out/model-hub-table/__next._head.txt | 8 +-
.../out/model-hub-table/__next._index.txt | 18 +-
.../out/model-hub-table/__next._tree.txt | 4 +-
.../out/model-hub-table/index.html | 2 +-
.../out/model-hub-table/index.txt | 40 +-
.../out/model_hub/__next._full.txt | 42 +-
.../out/model_hub/__next._head.txt | 8 +-
.../out/model_hub/__next._index.txt | 18 +-
.../out/model_hub/__next._tree.txt | 4 +-
.../model_hub/__next.model_hub.__PAGE__.txt | 8 +-
.../out/model_hub/__next.model_hub.txt | 6 +-
.../_experimental/out/model_hub/index.html | 2 +-
.../_experimental/out/model_hub/index.txt | 42 +-
.../out/model_hub_table/__next._full.txt | 34 +-
.../out/model_hub_table/__next._head.txt | 8 +-
.../out/model_hub_table/__next._index.txt | 18 +-
.../out/model_hub_table/__next._tree.txt | 4 +-
.../__next.model_hub_table.__PAGE__.txt | 8 +-
.../__next.model_hub_table.txt | 6 +-
.../out/model_hub_table/index.html | 2 +-
.../out/model_hub_table/index.txt | 34 +-
...ib2FyZCk.models-and-endpoints.__PAGE__.txt | 8 +-
....!KGRhc2hib2FyZCk.models-and-endpoints.txt | 6 +-
.../__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/models-and-endpoints/__next._full.txt | 40 +-
.../out/models-and-endpoints/__next._head.txt | 8 +-
.../models-and-endpoints/__next._index.txt | 18 +-
.../out/models-and-endpoints/__next._tree.txt | 4 +-
.../out/models-and-endpoints/index.html | 2 +-
.../out/models-and-endpoints/index.txt | 40 +-
...xt.!KGRhc2hib2FyZCk.old-usage.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.old-usage.txt | 6 +-
.../out/old-usage/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/old-usage/__next._full.txt | 40 +-
.../out/old-usage/__next._head.txt | 8 +-
.../out/old-usage/__next._index.txt | 18 +-
.../out/old-usage/__next._tree.txt | 4 +-
.../_experimental/out/old-usage/index.html | 2 +-
.../_experimental/out/old-usage/index.txt | 40 +-
.../out/onboarding/__next._full.txt | 32 +-
.../out/onboarding/__next._head.txt | 8 +-
.../out/onboarding/__next._index.txt | 18 +-
.../out/onboarding/__next._tree.txt | 4 +-
.../onboarding/__next.onboarding.__PAGE__.txt | 8 +-
.../out/onboarding/__next.onboarding.txt | 6 +-
.../_experimental/out/onboarding/index.html | 2 +-
.../_experimental/out/onboarding/index.txt | 32 +-
...KGRhc2hib2FyZCk.organizations.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.organizations.txt | 6 +-
.../organizations/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/organizations/__next._full.txt | 40 +-
.../out/organizations/__next._head.txt | 8 +-
.../out/organizations/__next._index.txt | 18 +-
.../out/organizations/__next._tree.txt | 4 +-
.../out/organizations/index.html | 2 +-
.../_experimental/out/organizations/index.txt | 40 +-
...t.!KGRhc2hib2FyZCk.playground.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.playground.txt | 6 +-
.../playground/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/playground/__next._full.txt | 40 +-
.../out/playground/__next._head.txt | 8 +-
.../out/playground/__next._index.txt | 18 +-
.../out/playground/__next._tree.txt | 4 +-
.../_experimental/out/playground/index.html | 2 +-
.../_experimental/out/playground/index.txt | 40 +-
...ext.!KGRhc2hib2FyZCk.policies.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.policies.txt | 6 +-
.../out/policies/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/policies/__next._full.txt | 40 +-
.../out/policies/__next._head.txt | 8 +-
.../out/policies/__next._index.txt | 18 +-
.../out/policies/__next._tree.txt | 4 +-
.../_experimental/out/policies/index.html | 2 +-
.../_experimental/out/policies/index.txt | 40 +-
...ext.!KGRhc2hib2FyZCk.projects.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.projects.txt | 6 +-
.../out/projects/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/projects/__next._full.txt | 40 +-
.../out/projects/__next._head.txt | 8 +-
.../out/projects/__next._index.txt | 18 +-
.../out/projects/__next._tree.txt | 4 +-
.../_experimental/out/projects/index.html | 2 +-
.../_experimental/out/projects/index.txt | 40 +-
...next.!KGRhc2hib2FyZCk.prompts.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.prompts.txt | 6 +-
.../out/prompts/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/prompts/__next._full.txt | 40 +-
.../out/prompts/__next._head.txt | 8 +-
.../out/prompts/__next._index.txt | 18 +-
.../out/prompts/__next._tree.txt | 4 +-
.../_experimental/out/prompts/index.html | 2 +-
.../proxy/_experimental/out/prompts/index.txt | 40 +-
...Rhc2hib2FyZCk.router-settings.__PAGE__.txt | 8 +-
..._next.!KGRhc2hib2FyZCk.router-settings.txt | 6 +-
.../__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/router-settings/__next._full.txt | 40 +-
.../out/router-settings/__next._head.txt | 8 +-
.../out/router-settings/__next._index.txt | 18 +-
.../out/router-settings/__next._tree.txt | 4 +-
.../out/router-settings/index.html | 2 +-
.../out/router-settings/index.txt | 40 +-
...!KGRhc2hib2FyZCk.search-tools.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.search-tools.txt | 6 +-
.../search-tools/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/search-tools/__next._full.txt | 40 +-
.../out/search-tools/__next._head.txt | 8 +-
.../out/search-tools/__next._index.txt | 18 +-
.../out/search-tools/__next._tree.txt | 4 +-
.../_experimental/out/search-tools/index.html | 2 +-
.../_experimental/out/search-tools/index.txt | 40 +-
..._next.!KGRhc2hib2FyZCk.skills.__PAGE__.txt | 8 +-
.../skills/__next.!KGRhc2hib2FyZCk.skills.txt | 6 +-
.../out/skills/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../_experimental/out/skills/__next._full.txt | 40 +-
.../_experimental/out/skills/__next._head.txt | 8 +-
.../out/skills/__next._index.txt | 18 +-
.../_experimental/out/skills/__next._tree.txt | 4 +-
.../proxy/_experimental/out/skills/index.html | 2 +-
.../proxy/_experimental/out/skills/index.txt | 40 +-
...GRhc2hib2FyZCk.tag-management.__PAGE__.txt | 8 +-
...__next.!KGRhc2hib2FyZCk.tag-management.txt | 6 +-
.../__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/tag-management/__next._full.txt | 40 +-
.../out/tag-management/__next._head.txt | 8 +-
.../out/tag-management/__next._index.txt | 18 +-
.../out/tag-management/__next._tree.txt | 4 +-
.../out/tag-management/index.html | 2 +-
.../out/tag-management/index.txt | 40 +-
...__next.!KGRhc2hib2FyZCk.teams.__PAGE__.txt | 8 +-
.../teams/__next.!KGRhc2hib2FyZCk.teams.txt | 6 +-
.../out/teams/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../_experimental/out/teams/__next._full.txt | 40 +-
.../_experimental/out/teams/__next._head.txt | 8 +-
.../_experimental/out/teams/__next._index.txt | 18 +-
.../_experimental/out/teams/__next._tree.txt | 4 +-
.../proxy/_experimental/out/teams/index.html | 2 +-
.../proxy/_experimental/out/teams/index.txt | 40 +-
...KGRhc2hib2FyZCk.tool-policies.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.tool-policies.txt | 6 +-
.../tool-policies/__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/tool-policies/__next._full.txt | 40 +-
.../out/tool-policies/__next._head.txt | 8 +-
.../out/tool-policies/__next._index.txt | 18 +-
.../out/tool-policies/__next._tree.txt | 4 +-
.../out/tool-policies/index.html | 2 +-
.../_experimental/out/tool-policies/index.txt | 40 +-
...c2hib2FyZCk.transform-request.__PAGE__.txt | 8 +-
...ext.!KGRhc2hib2FyZCk.transform-request.txt | 6 +-
.../__next.!KGRhc2hib2FyZCk.txt | 10 +-
.../out/transform-request/__next._full.txt | 38 +-
.../out/transform-request/__next._head.txt | 8 +-
.../out/transform-request/__next._index.txt | 18 +-
.../out/transform-request/__next._tree.txt | 4 +-
.../out/transform-request/index.html | 2 +-
.../out/transform-request/index.txt | 38 +-
.../out/ui-theme/__next.!KGRhc2hib2FyZCk.txt | 10 +-
...ext.!KGRhc2hib2FyZCk.ui-theme.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.ui-theme.txt | 6 +-
.../out/ui-theme/__next._full.txt | 38 +-
.../out/ui-theme/__next._head.txt | 8 +-
.../out/ui-theme/__next._index.txt | 18 +-
.../out/ui-theme/__next._tree.txt | 4 +-
.../_experimental/out/ui-theme/index.html | 2 +-
.../_experimental/out/ui-theme/index.txt | 38 +-
.../out/usage/__next.!KGRhc2hib2FyZCk.txt | 10 +-
...__next.!KGRhc2hib2FyZCk.usage.__PAGE__.txt | 8 +-
.../usage/__next.!KGRhc2hib2FyZCk.usage.txt | 6 +-
.../_experimental/out/usage/__next._full.txt | 40 +-
.../_experimental/out/usage/__next._head.txt | 8 +-
.../_experimental/out/usage/__next._index.txt | 18 +-
.../_experimental/out/usage/__next._tree.txt | 4 +-
.../proxy/_experimental/out/usage/index.html | 2 +-
.../proxy/_experimental/out/usage/index.txt | 40 +-
.../out/users/__next.!KGRhc2hib2FyZCk.txt | 10 +-
...__next.!KGRhc2hib2FyZCk.users.__PAGE__.txt | 8 +-
.../users/__next.!KGRhc2hib2FyZCk.users.txt | 6 +-
.../_experimental/out/users/__next._full.txt | 40 +-
.../_experimental/out/users/__next._head.txt | 8 +-
.../_experimental/out/users/__next._index.txt | 18 +-
.../_experimental/out/users/__next._tree.txt | 4 +-
.../proxy/_experimental/out/users/index.html | 2 +-
.../proxy/_experimental/out/users/index.txt | 40 +-
.../vector-stores/__next.!KGRhc2hib2FyZCk.txt | 10 +-
...KGRhc2hib2FyZCk.vector-stores.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.vector-stores.txt | 6 +-
.../out/vector-stores/__next._full.txt | 40 +-
.../out/vector-stores/__next._head.txt | 8 +-
.../out/vector-stores/__next._index.txt | 18 +-
.../out/vector-stores/__next._tree.txt | 4 +-
.../out/vector-stores/index.html | 2 +-
.../_experimental/out/vector-stores/index.txt | 40 +-
.../out/workflows/__next.!KGRhc2hib2FyZCk.txt | 10 +-
...xt.!KGRhc2hib2FyZCk.workflows.__PAGE__.txt | 8 +-
.../__next.!KGRhc2hib2FyZCk.workflows.txt | 6 +-
.../out/workflows/__next._full.txt | 40 +-
.../out/workflows/__next._head.txt | 8 +-
.../out/workflows/__next._index.txt | 18 +-
.../out/workflows/__next._tree.txt | 4 +-
.../_experimental/out/workflows/index.html | 2 +-
.../_experimental/out/workflows/index.txt | 40 +-
675 files changed, 5809 insertions(+), 5711 deletions(-)
rename litellm/proxy/_experimental/out/_next/static/{YAsRgSxdV-OcBfib_67Dt => 912qRXFjlEYHK3EAPXXTc}/_buildManifest.js (100%)
rename litellm/proxy/_experimental/out/_next/static/{YAsRgSxdV-OcBfib_67Dt => 912qRXFjlEYHK3EAPXXTc}/_clientMiddlewareManifest.js (100%)
rename litellm/proxy/_experimental/out/_next/static/{YAsRgSxdV-OcBfib_67Dt => 912qRXFjlEYHK3EAPXXTc}/_ssgManifest.js (100%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0-dst_pi7co_a.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0002gr7w0f3nn.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/00dvxqp6f0f6s.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/01benr9g1pe74.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/01oqh-5b0ytmu.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/027qywrv12iu8.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/028hvx-avwx8g.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/02ic1ccwq2p02.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/03_s-zve24zyk.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/03k5rtnvgsg9q.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/03pu_dx0gqja9.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/04fw18d3dx40b.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/04oxg_atba30d.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/059psjgsicqvu.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/05jtp8xqp3j0x.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{1v3m908ycsmt4.js => 07cqsb7poupf9.js} (59%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/08lua1iopk_79.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0a3n_ovfo3c5s.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0b8dlr4_m6177.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0cotqb-2hzyvs.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0d4xeknobwogp.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0dnt68i2qq-dg.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0dypptaj7tfcw.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0esaql-j_8-p2.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0ikamdtw78iln.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0k6ku5hw0lxbs.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0k88woxbttvcj.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0lgjier0jo0da.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0limvbttcca8i.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0n_d-fecc6ing.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0nv-vje-mizhj.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0ob_vs6vpubam.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0p2ty6d6s6ikf.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0syzzpo5y8_r6.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0t8t3-_8y1jh9.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0tzf0u6ba54sb.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0u-hvuc1nke0t.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0ukqyn87nhmzd.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0v_v1lhy48ega.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0wh5uu7sl34-i.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0xau2pz4q9eoy.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0xrc-9_hkt1-y.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0xvwtyit6foq4.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0ymd13yj7v7rj.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0yx8e9275ph17.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{0xcu3s37s9axz.js => 0z6yavb6ipml_.js} (72%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/0z7zg9587od6_.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/108z0ff937g6x.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/10ncv_5h3izdc.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1197jfkq-iw2n.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/119w1gziyp548.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/11r2ma61byh99.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1237ige31qaii.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/12_i2u3reazjh.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/12chby2_3oupv.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/12ws1ltetp8yp.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1317afg16-lx1.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/13rzpi4q1z_e8.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/13sw7w_3mi213.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/14394ef4y9l3a.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/146bhdjwt88wp.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/14bbxzqzpwr4d.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{1caa4vd721cvu.js => 14h76g_paiizi.js} (67%)
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/154ouf9jccp1g.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/16xdxq7qvv37h.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/16zk64em3o_xr.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/19d70ks0akyja.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{3gmtm1iixkmgr.js => 19h10tzn4xbhq.js} (89%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1a3mamulxkyhw.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1ahp6rse2_f9c.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1cawzcg3f9m_b.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1dpuw-kkts-4z.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1dx34ygzjt19e.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1e7t2-ca-xsv3.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1e94pphgfbmhc.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1ffshjz5d4_3s.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1fxpl6mmobvuv.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1ghmzc3sotzoy.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1ib-wrl-rx9mb.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1ipimnkawqmc0.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1j-81t3ummx7f.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1j0tzdbu2gh-d.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1j44zjath-uo2.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1l61r88q65pjd.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1l7aqyj-639ip.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1l8v98u-man65.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1oixgwji948fa.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1p9jm-g7u52aq.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1q0dpasyg7o3d.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1qn5rcv_00n67.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1r-uf54j7w03c.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1ril0nieln4ln.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1t2fg_goa98_p.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1tls-8aiib7f5.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1tvsqn7ove-oj.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1vlm1-btu0fbz.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1vrr5gef27wsb.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1vw9cmijff2mj.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1vzcuk-15dfr2.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1vzhjykovw9ji.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1wuxy9_mvw4yx.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1xhchm7onfol4.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1z-pueirfgle5.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/1zzr0tgfl-g4s.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2-jkx2__3xy9q.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2-z2qnhuwaoz-.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/20z5qtar5xis1.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/212bxxmv8g2o8.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2165p8kcyq28a.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/217any77nuolr.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/22t32wpbub0ay.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{33s1cd7i7uenu.js => 24-0ciobj3ggc.js} (90%)
rename litellm/proxy/_experimental/out/_next/static/chunks/{34_wtpkkvqa3n.js => 257-u3v7vdxzj.js} (91%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/26wdbcc5z9ot9.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/27gtmvuu3uwb-.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/27ztlw0u47b4v.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/28z7xz3dmb5mt.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{2e2guakawc2hv.js => 293hy1wyw_zum.js} (63%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/29xhz9f3b5uh_.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2_e0pm0jc-yil.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2b1up8z26ai59.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2bij6nxiu6v1x.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2bl93j-9lt0zm.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2cl8_u3nwv5pp.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2ctmb5tt7j_un.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2d32l5hjlui28.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2dvjnwfxzyldc.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2eq3u5hwabrai.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2gdhedfht2i80.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2hl_9t55v67qt.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{34t9vb_mm_wki.js => 2hz92aqj77zlw.js} (97%)
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2k6lzy5s7rafp.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2kjmosw5g-gsc.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2kph8rgszljlv.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2kuymb9f8gjqm.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2kxwsvv2wqqd_.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2lpmjdx2jlx34.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{3hpxr2v3x-0xz.js => 2lwlr41sgghqp.js} (63%)
rename litellm/proxy/_experimental/out/_next/static/chunks/{2veyvbaagt-60.js => 2lx_pto6xfsa7.js} (56%)
rename litellm/proxy/_experimental/out/_next/static/chunks/{27gjrlkmq245y.js => 2mo45qar55a-z.js} (90%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2n9vhssm1ke4u.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2nfd8afirv_hx.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2o6ajjzms3r2n.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2orlhe31dolig.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2pmm79g5r_ebn.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2qr0-fzlxoy7o.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2ryp4-cmeq_d2.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2tckjhqtu3wii.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2tco7hl92nf5g.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2tj1x2xl0npv1.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2ty4asibief-4.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2u59vywexbybu.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2u89qrvzp-8bp.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2vj1gwc3np8ir.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2wa5a5dysfrb3.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2wjkotbxoelv_.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2wmgu52j_4-e-.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2yik4fkekmght.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2yrtzeoze9bgu.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2yypakvxqodzf.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2zew1vg3hql9m.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/2zk7h7_6p0cx3.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3155srena77mb.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/318d0grxaivtg.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/31hmjujca2pu3.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{1_2vrjj-7-crg.js => 31u0v5nu0m22x.js} (59%)
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/32obiws158hw0.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/32z61pa-uiw17.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/33t6_jpdse1_6.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/34hhnp87pqxic.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{16hwhhfys5l7o.js => 35pk5e14z92ti.js} (55%)
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/35xohwm38b-8-.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/367h6aovv92ya.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/381upin2heiqu.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/38pukqn2wwot2.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/390d3ojugt32e.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3a20afvsnrq33.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3agwsexylijeu.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3alik9wjwtjek.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3c8-k_-5ap8co.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3cf10ailmi24x.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3d2_6alyra4xu.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3efeazyh44a5c.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3f4pzky9ekcep.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3f9q88-lg6z6a.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{0gb6pr-exq8__.js => 3f_0s7g6r4mmt.js} (60%)
rename litellm/proxy/_experimental/out/_next/static/chunks/{3kest3gurc9op.js => 3fn8zqlfrwowr.js} (63%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3goocbdtj1s73.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3hzsy6hidjrrf.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3idmblk6vi8i5.css
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3it786tjaipxf.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3iw7hxslaupar.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3jjcizfocnz_x.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3jyuhlymn08un.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3khb7fu59rrn0.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3kjqcg08ybop4.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3kmz9wrzxsgny.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3lsrgjh8c8ahy.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3lvwyc5xjv11f.css
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3mf-i5vpaobpt.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3mku0qt8uky_s.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3myqkomz-f4hl.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3n9bn2grdu_k9.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3psz25p__3u7s.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3ptzupbbzlu4r.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3qakmp848wcl5.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3qc0ck7jhqdwb.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3qcv7jqxtoq4c.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3rfer25uusl4w.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3rswcsdlv_3x3.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3rtva9i63bdtr.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3rvs_drt9t99-.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3s39b43k2vde7.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3s8bc2986w4ao.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3sd6_fqjvvk5h.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3trm3pab_56a6.js
rename litellm/proxy/_experimental/out/_next/static/chunks/{2c2i88pd_wixs.js => 3u5j9_7z0dl5w.js} (55%)
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3usevqfo8l66i.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3vomzav3318x2.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3wdy9040h4b13.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3wo_4cg1wa3hg.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3x37-3yc_2870.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3xa3ywp_ixe85.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3xxkselkexvi9.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3yegoaduwt53n.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/3zttc3p8so4fm.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/400vd436tmxp-.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/406voqt1wl0st.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/4221gwk3c-ett.js
delete mode 100644 litellm/proxy/_experimental/out/_next/static/chunks/44ycc-s2cvnts.js
create mode 100644 litellm/proxy/_experimental/out/_next/static/media/alice.13frxbgffyihr.svg
create mode 100644 litellm/proxy/_experimental/out/_next/static/media/gigachat.37uico956hu-u.svg
create mode 100644 litellm/proxy/_experimental/out/_next/static/media/mongodb.1l7egqakv5sij.svg
create mode 100644 litellm/proxy/_experimental/out/assets/logos/alice.svg
create mode 100644 litellm/proxy/_experimental/out/assets/logos/gigachat.svg
create mode 100644 litellm/proxy/_experimental/out/assets/logos/mongodb.svg
diff --git a/litellm/proxy/_experimental/out/404.html b/litellm/proxy/_experimental/out/404.html
index 72dc4764ce4..d3fe1f37cd9 100644
--- a/litellm/proxy/_experimental/out/404.html
+++ b/litellm/proxy/_experimental/out/404.html
@@ -1 +1 @@
-404: This page could not be found. LiteLLM Dashboard
404
This page could not be found.
\ No newline at end of file
+404: This page could not be found. LiteLLM Dashboard
404
This page could not be found.
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/404/index.html b/litellm/proxy/_experimental/out/404/index.html
index 72dc4764ce4..d3fe1f37cd9 100644
--- a/litellm/proxy/_experimental/out/404/index.html
+++ b/litellm/proxy/_experimental/out/404/index.html
@@ -1 +1 @@
-404: This page could not be found. LiteLLM Dashboard
404
This page could not be found.
\ No newline at end of file
+404: This page could not be found. LiteLLM Dashboard
404
This page could not be found.
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt
index 6d9004683c3..38242abe1b0 100644
--- a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt
+++ b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.__PAGE__.txt
@@ -1,9 +1,9 @@
1:"$Sreact.fragment"
-2:I[347257,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ClientPageRoot"]
-3:I[871135,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","/litellm-asset-prefix/_next/static/chunks/1a3mamulxkyhw.js","/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","/litellm-asset-prefix/_next/static/chunks/27gjrlkmq245y.js","/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","/litellm-asset-prefix/_next/static/chunks/34_wtpkkvqa3n.js","/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","/litellm-asset-prefix/_next/static/chunks/1l61r88q65pjd.js","/litellm-asset-prefix/_next/static/chunks/0di-9qm-8ex8r.js","/litellm-asset-prefix/_next/static/chunks/3dy-3uqjux30s.js","/litellm-asset-prefix/_next/static/chunks/3wdy9040h4b13.js","/litellm-asset-prefix/_next/static/chunks/13rzpi4q1z_e8.js","/litellm-asset-prefix/_next/static/chunks/0wh5uu7sl34-i.js","/litellm-asset-prefix/_next/static/chunks/0cotqb-2hzyvs.js","/litellm-asset-prefix/_next/static/chunks/16xdxq7qvv37h.js","/litellm-asset-prefix/_next/static/chunks/0dylouuq8ak8p.js","/litellm-asset-prefix/_next/static/chunks/2tj1x2xl0npv1.js","/litellm-asset-prefix/_next/static/chunks/2eonl4rcemkdj.js","/litellm-asset-prefix/_next/static/chunks/0z7zg9587od6_.js","/litellm-asset-prefix/_next/static/chunks/0ab_ntohf1wik.js","/litellm-asset-prefix/_next/static/chunks/1v3m908ycsmt4.js"],"default"]
-6:I[897367,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"OutletBoundary"]
+2:I[347257,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ClientPageRoot"]
+3:I[871135,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","/litellm-asset-prefix/_next/static/chunks/2k6lzy5s7rafp.js","/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","/litellm-asset-prefix/_next/static/chunks/2mo45qar55a-z.js","/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","/litellm-asset-prefix/_next/static/chunks/257-u3v7vdxzj.js","/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","/litellm-asset-prefix/_next/static/chunks/0t8t3-_8y1jh9.js","/litellm-asset-prefix/_next/static/chunks/0di-9qm-8ex8r.js","/litellm-asset-prefix/_next/static/chunks/3dy-3uqjux30s.js","/litellm-asset-prefix/_next/static/chunks/3155srena77mb.js","/litellm-asset-prefix/_next/static/chunks/0limvbttcca8i.js","/litellm-asset-prefix/_next/static/chunks/2ty4asibief-4.js","/litellm-asset-prefix/_next/static/chunks/07cqsb7poupf9.js","/litellm-asset-prefix/_next/static/chunks/2dvjnwfxzyldc.js","/litellm-asset-prefix/_next/static/chunks/0ab_ntohf1wik.js","/litellm-asset-prefix/_next/static/chunks/0esaql-j_8-p2.js","/litellm-asset-prefix/_next/static/chunks/0dylouuq8ak8p.js","/litellm-asset-prefix/_next/static/chunks/2bl93j-9lt0zm.js","/litellm-asset-prefix/_next/static/chunks/2eonl4rcemkdj.js","/litellm-asset-prefix/_next/static/chunks/2yrtzeoze9bgu.js"],"default"]
+6:I[897367,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"OutletBoundary"]
7:"$Sreact.suspense"
-0:{"rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0di-9qm-8ex8r.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3dy-3uqjux30s.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/3wdy9040h4b13.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/13rzpi4q1z_e8.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/0wh5uu7sl34-i.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0cotqb-2hzyvs.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/16xdxq7qvv37h.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0dylouuq8ak8p.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/2tj1x2xl0npv1.js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/2eonl4rcemkdj.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0z7zg9587od6_.js","async":true}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/0ab_ntohf1wik.js","async":true}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/1v3m908ycsmt4.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"YAsRgSxdV-OcBfib_67Dt"}
+0:{"rsc":["$","$1","c",{"children":[["$","$L2",null,{"Component":"$3","serverProvidedParams":{"searchParams":{},"params":{},"promises":["$@4","$@5"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0di-9qm-8ex8r.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3dy-3uqjux30s.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/3155srena77mb.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0limvbttcca8i.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/2ty4asibief-4.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/07cqsb7poupf9.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/2dvjnwfxzyldc.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0ab_ntohf1wik.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/0esaql-j_8-p2.js","async":true}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/0dylouuq8ak8p.js","async":true}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/2bl93j-9lt0zm.js","async":true}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/2eonl4rcemkdj.js","async":true}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/2yrtzeoze9bgu.js","async":true}]],["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"912qRXFjlEYHK3EAPXXTc"}
4:{}
5:"$0:rsc:props:children:0:props:serverProvidedParams:params"
8:null
diff --git a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt
index e4a91130467..c95e3e0fa33 100644
--- a/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt
+++ b/litellm/proxy/_experimental/out/__next.!KGRhc2hib2FyZCk.txt
@@ -1,7 +1,7 @@
1:"$Sreact.fragment"
-2:I[92825,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ClientSegmentRoot"]
-3:I[216370,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","/litellm-asset-prefix/_next/static/chunks/1a3mamulxkyhw.js","/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","/litellm-asset-prefix/_next/static/chunks/27gjrlkmq245y.js","/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","/litellm-asset-prefix/_next/static/chunks/34_wtpkkvqa3n.js","/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","/litellm-asset-prefix/_next/static/chunks/1l61r88q65pjd.js"],"default"]
-4:I[339756,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
-5:I[837457,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
-0:{"rsc":["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/1a3mamulxkyhw.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/27gjrlkmq245y.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/34_wtpkkvqa3n.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/1l61r88q65pjd.js","async":true}]],["$","$L2",null,{"Component":"$3","slots":{"children":["$","$L4",null,{"parallelRouterKey":"children","template":["$","$L5",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]},"serverProvidedParams":{"params":{},"promises":["$@6"]}}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"YAsRgSxdV-OcBfib_67Dt"}
+2:I[92825,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ClientSegmentRoot"]
+3:I[216370,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","/litellm-asset-prefix/_next/static/chunks/2k6lzy5s7rafp.js","/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","/litellm-asset-prefix/_next/static/chunks/2mo45qar55a-z.js","/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","/litellm-asset-prefix/_next/static/chunks/257-u3v7vdxzj.js","/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","/litellm-asset-prefix/_next/static/chunks/0t8t3-_8y1jh9.js"],"default"]
+4:I[339756,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
+5:I[837457,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
+0:{"rsc":["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/2k6lzy5s7rafp.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/2mo45qar55a-z.js","async":true}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","async":true}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","async":true}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","async":true}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/257-u3v7vdxzj.js","async":true}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","async":true}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/0t8t3-_8y1jh9.js","async":true}]],["$","$L2",null,{"Component":"$3","slots":{"children":["$","$L4",null,{"parallelRouterKey":"children","template":["$","$L5",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]},"serverProvidedParams":{"params":{},"promises":["$@6"]}}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"912qRXFjlEYHK3EAPXXTc"}
6:"$0:rsc:props:children:1:props:serverProvidedParams:params"
diff --git a/litellm/proxy/_experimental/out/__next._full.txt b/litellm/proxy/_experimental/out/__next._full.txt
index 0f9ae0d455f..67c50407506 100644
--- a/litellm/proxy/_experimental/out/__next._full.txt
+++ b/litellm/proxy/_experimental/out/__next._full.txt
@@ -1,32 +1,32 @@
1:"$Sreact.fragment"
-2:I[363178,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ThemeProvider"]
-3:I[12985,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"NuqsAdapter"]
-4:I[867271,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
-5:I[557951,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"AuthProvider"]
-6:I[339756,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
-7:I[837457,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
-8:I[713354,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"Toaster"]
-9:I[92825,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ClientSegmentRoot"]
-a:I[216370,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","/litellm-asset-prefix/_next/static/chunks/1a3mamulxkyhw.js","/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","/litellm-asset-prefix/_next/static/chunks/27gjrlkmq245y.js","/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","/litellm-asset-prefix/_next/static/chunks/34_wtpkkvqa3n.js","/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","/litellm-asset-prefix/_next/static/chunks/1l61r88q65pjd.js"],"default"]
-e:I[168027,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default",1]
+2:I[363178,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ThemeProvider"]
+3:I[12985,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"NuqsAdapter"]
+4:I[867271,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
+5:I[557951,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"AuthProvider"]
+6:I[339756,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
+7:I[837457,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
+8:I[713354,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"Toaster"]
+9:I[92825,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ClientSegmentRoot"]
+a:I[216370,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","/litellm-asset-prefix/_next/static/chunks/2k6lzy5s7rafp.js","/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","/litellm-asset-prefix/_next/static/chunks/2mo45qar55a-z.js","/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","/litellm-asset-prefix/_next/static/chunks/257-u3v7vdxzj.js","/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","/litellm-asset-prefix/_next/static/chunks/0t8t3-_8y1jh9.js"],"default"]
+e:I[168027,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default",1]
:HL["/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","style"]
-:HL["/litellm-asset-prefix/_next/static/chunks/3idmblk6vi8i5.css","style"]
+:HL["/litellm-asset-prefix/_next/static/chunks/3lvwyc5xjv11f.css","style"]
:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.2bn3s6zvc0dyp.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
-0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["(dashboard)",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3idmblk6vi8i5.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","suppressHydrationWarning":true,"children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":true,"children":["$","$L3",null,{"children":["$","$L4",null,{"children":[["$","$L5",null,{"children":["$","$L6",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}],["$","$L8",null,{}]]}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/1a3mamulxkyhw.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/27gjrlkmq245y.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/34_wtpkkvqa3n.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/1l61r88q65pjd.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"Component":"$a","slots":{"children":["$","$L6",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:0:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:0:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:0:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:0:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]},"serverProvidedParams":{"params":{},"promises":["$@b"]}}]]}],{"children":["$Lc",{},null,false,null]},null,false,null]},null,false,null],"$Ld",false]],"m":"$undefined","G":["$e",["$Lf","$L10"]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"YAsRgSxdV-OcBfib_67Dt"}
-11:I[347257,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ClientPageRoot"]
-12:I[871135,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","/litellm-asset-prefix/_next/static/chunks/1a3mamulxkyhw.js","/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","/litellm-asset-prefix/_next/static/chunks/27gjrlkmq245y.js","/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","/litellm-asset-prefix/_next/static/chunks/34_wtpkkvqa3n.js","/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","/litellm-asset-prefix/_next/static/chunks/1l61r88q65pjd.js","/litellm-asset-prefix/_next/static/chunks/0di-9qm-8ex8r.js","/litellm-asset-prefix/_next/static/chunks/3dy-3uqjux30s.js","/litellm-asset-prefix/_next/static/chunks/3wdy9040h4b13.js","/litellm-asset-prefix/_next/static/chunks/13rzpi4q1z_e8.js","/litellm-asset-prefix/_next/static/chunks/0wh5uu7sl34-i.js","/litellm-asset-prefix/_next/static/chunks/0cotqb-2hzyvs.js","/litellm-asset-prefix/_next/static/chunks/16xdxq7qvv37h.js","/litellm-asset-prefix/_next/static/chunks/0dylouuq8ak8p.js","/litellm-asset-prefix/_next/static/chunks/2tj1x2xl0npv1.js","/litellm-asset-prefix/_next/static/chunks/2eonl4rcemkdj.js","/litellm-asset-prefix/_next/static/chunks/0z7zg9587od6_.js","/litellm-asset-prefix/_next/static/chunks/0ab_ntohf1wik.js","/litellm-asset-prefix/_next/static/chunks/1v3m908ycsmt4.js"],"default"]
-15:I[897367,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"OutletBoundary"]
+0:{"P":null,"c":["",""],"q":"","i":false,"f":[[["",{"children":["(dashboard)",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3lvwyc5xjv11f.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","async":true,"nonce":"$undefined"}]],["$","html",null,{"lang":"en","suppressHydrationWarning":true,"children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":true,"children":["$","$L3",null,{"children":["$","$L4",null,{"children":[["$","$L5",null,{"children":["$","$L6",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}],["$","$L8",null,{}]]}]}]}]}]}]]}],{"children":[["$","$1","c",{"children":[[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/2k6lzy5s7rafp.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/2mo45qar55a-z.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/257-u3v7vdxzj.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/0t8t3-_8y1jh9.js","async":true,"nonce":"$undefined"}]],["$","$L9",null,{"Component":"$a","slots":{"children":["$","$L6",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:0:props:children:props:notFound:0:1:props:style","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:0:props:children:props:notFound:0:1:props:children:props:children:1:props:style","children":404}],["$","div",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:0:props:children:props:notFound:0:1:props:children:props:children:2:props:style","children":["$","h2",null,{"style":"$0:f:0:1:0:props:children:1:props:children:props:children:props:children:props:children:props:children:0:props:children:props:notFound:0:1:props:children:props:children:2:props:children:props:style","children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]},"serverProvidedParams":{"params":{},"promises":["$@b"]}}]]}],{"children":["$Lc",{},null,false,null]},null,false,null]},null,false,null],"$Ld",false]],"m":"$undefined","G":["$e",["$Lf","$L10"]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"912qRXFjlEYHK3EAPXXTc"}
+11:I[347257,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ClientPageRoot"]
+12:I[871135,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","/litellm-asset-prefix/_next/static/chunks/2k6lzy5s7rafp.js","/litellm-asset-prefix/_next/static/chunks/2yqxc2yxa1-go.js","/litellm-asset-prefix/_next/static/chunks/2mo45qar55a-z.js","/litellm-asset-prefix/_next/static/chunks/0aoel7yrv88fp.js","/litellm-asset-prefix/_next/static/chunks/3ytz29phknzsy.js","/litellm-asset-prefix/_next/static/chunks/2i0218zvrsasm.js","/litellm-asset-prefix/_next/static/chunks/257-u3v7vdxzj.js","/litellm-asset-prefix/_next/static/chunks/1nfnjvxf_0-3n.js","/litellm-asset-prefix/_next/static/chunks/0t8t3-_8y1jh9.js","/litellm-asset-prefix/_next/static/chunks/0di-9qm-8ex8r.js","/litellm-asset-prefix/_next/static/chunks/3dy-3uqjux30s.js","/litellm-asset-prefix/_next/static/chunks/3155srena77mb.js","/litellm-asset-prefix/_next/static/chunks/0limvbttcca8i.js","/litellm-asset-prefix/_next/static/chunks/2ty4asibief-4.js","/litellm-asset-prefix/_next/static/chunks/07cqsb7poupf9.js","/litellm-asset-prefix/_next/static/chunks/2dvjnwfxzyldc.js","/litellm-asset-prefix/_next/static/chunks/0ab_ntohf1wik.js","/litellm-asset-prefix/_next/static/chunks/0esaql-j_8-p2.js","/litellm-asset-prefix/_next/static/chunks/0dylouuq8ak8p.js","/litellm-asset-prefix/_next/static/chunks/2bl93j-9lt0zm.js","/litellm-asset-prefix/_next/static/chunks/2eonl4rcemkdj.js","/litellm-asset-prefix/_next/static/chunks/2yrtzeoze9bgu.js"],"default"]
+15:I[897367,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"OutletBoundary"]
16:"$Sreact.suspense"
-18:I[897367,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ViewportBoundary"]
-1a:I[897367,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"MetadataBoundary"]
-c:["$","$1","c",{"children":[["$","$L11",null,{"Component":"$12","serverProvidedParams":{"searchParams":{},"params":"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params","promises":["$@13","$@14"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0di-9qm-8ex8r.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3dy-3uqjux30s.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/3wdy9040h4b13.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/13rzpi4q1z_e8.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/0wh5uu7sl34-i.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/0cotqb-2hzyvs.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/16xdxq7qvv37h.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0dylouuq8ak8p.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/2tj1x2xl0npv1.js","async":true,"nonce":"$undefined"}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/2eonl4rcemkdj.js","async":true,"nonce":"$undefined"}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/0z7zg9587od6_.js","async":true,"nonce":"$undefined"}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/0ab_ntohf1wik.js","async":true,"nonce":"$undefined"}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/1v3m908ycsmt4.js","async":true,"nonce":"$undefined"}]],["$","$L15",null,{"children":["$","$16",null,{"name":"Next.MetadataOutlet","children":"$@17"}]}]]}]
+18:I[897367,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ViewportBoundary"]
+1a:I[897367,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"MetadataBoundary"]
+c:["$","$1","c",{"children":[["$","$L11",null,{"Component":"$12","serverProvidedParams":{"searchParams":{},"params":"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params","promises":["$@13","$@14"]}}],[["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/0di-9qm-8ex8r.js","async":true,"nonce":"$undefined"}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3dy-3uqjux30s.js","async":true,"nonce":"$undefined"}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/3155srena77mb.js","async":true,"nonce":"$undefined"}],["$","script","script-3",{"src":"/litellm-asset-prefix/_next/static/chunks/0limvbttcca8i.js","async":true,"nonce":"$undefined"}],["$","script","script-4",{"src":"/litellm-asset-prefix/_next/static/chunks/2ty4asibief-4.js","async":true,"nonce":"$undefined"}],["$","script","script-5",{"src":"/litellm-asset-prefix/_next/static/chunks/07cqsb7poupf9.js","async":true,"nonce":"$undefined"}],["$","script","script-6",{"src":"/litellm-asset-prefix/_next/static/chunks/2dvjnwfxzyldc.js","async":true,"nonce":"$undefined"}],["$","script","script-7",{"src":"/litellm-asset-prefix/_next/static/chunks/0ab_ntohf1wik.js","async":true,"nonce":"$undefined"}],["$","script","script-8",{"src":"/litellm-asset-prefix/_next/static/chunks/0esaql-j_8-p2.js","async":true,"nonce":"$undefined"}],["$","script","script-9",{"src":"/litellm-asset-prefix/_next/static/chunks/0dylouuq8ak8p.js","async":true,"nonce":"$undefined"}],["$","script","script-10",{"src":"/litellm-asset-prefix/_next/static/chunks/2bl93j-9lt0zm.js","async":true,"nonce":"$undefined"}],["$","script","script-11",{"src":"/litellm-asset-prefix/_next/static/chunks/2eonl4rcemkdj.js","async":true,"nonce":"$undefined"}],["$","script","script-12",{"src":"/litellm-asset-prefix/_next/static/chunks/2yrtzeoze9bgu.js","async":true,"nonce":"$undefined"}]],["$","$L15",null,{"children":["$","$16",null,{"name":"Next.MetadataOutlet","children":"$@17"}]}]]}]
d:["$","$1","h",{"children":[null,["$","$L18",null,{"children":"$L19"}],["$","div",null,{"hidden":true,"children":["$","$L1a",null,{"children":["$","$16",null,{"name":"Next.Metadata","children":"$L1b"}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}]
f:["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]
-10:["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3idmblk6vi8i5.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]
+10:["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3lvwyc5xjv11f.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]
b:"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params"
13:{}
14:"$0:f:0:1:1:children:0:props:children:1:props:serverProvidedParams:params"
19:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
-1c:I[27201,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"IconMark"]
+1c:I[27201,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"IconMark"]
17:null
1b:[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.3arlap5n8tyzg.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L1c","4",{}]]
diff --git a/litellm/proxy/_experimental/out/__next._head.txt b/litellm/proxy/_experimental/out/__next._head.txt
index 32c654498b4..91c285591a3 100644
--- a/litellm/proxy/_experimental/out/__next._head.txt
+++ b/litellm/proxy/_experimental/out/__next._head.txt
@@ -1,6 +1,6 @@
1:"$Sreact.fragment"
-2:I[897367,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ViewportBoundary"]
-3:I[897367,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"MetadataBoundary"]
+2:I[897367,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ViewportBoundary"]
+3:I[897367,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"MetadataBoundary"]
4:"$Sreact.suspense"
-5:I[27201,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"IconMark"]
-0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.3arlap5n8tyzg.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"YAsRgSxdV-OcBfib_67Dt"}
+5:I[27201,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"IconMark"]
+0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"LiteLLM Dashboard"}],["$","meta","1",{"name":"description","content":"LiteLLM Proxy Admin UI"}],["$","link","2",{"rel":"icon","href":"/favicon.ico?favicon.3arlap5n8tyzg.ico","sizes":"48x48","type":"image/x-icon"}],["$","link","3",{"rel":"icon","href":"/get_favicon"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"912qRXFjlEYHK3EAPXXTc"}
diff --git a/litellm/proxy/_experimental/out/__next._index.txt b/litellm/proxy/_experimental/out/__next._index.txt
index 1f6e1f8ba43..48a148f0a6d 100644
--- a/litellm/proxy/_experimental/out/__next._index.txt
+++ b/litellm/proxy/_experimental/out/__next._index.txt
@@ -1,11 +1,11 @@
1:"$Sreact.fragment"
-2:I[363178,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ThemeProvider"]
-3:I[12985,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"NuqsAdapter"]
-4:I[867271,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
-5:I[557951,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"AuthProvider"]
-6:I[339756,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
-7:I[837457,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
-8:I[713354,["/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"Toaster"]
+2:I[363178,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"ThemeProvider"]
+3:I[12985,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"NuqsAdapter"]
+4:I[867271,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
+5:I[557951,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"AuthProvider"]
+6:I[339756,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
+7:I[837457,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"default"]
+8:I[713354,["/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js"],"Toaster"]
:HL["/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","style"]
-:HL["/litellm-asset-prefix/_next/static/chunks/3idmblk6vi8i5.css","style"]
-0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3idmblk6vi8i5.css","precedence":"next"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/3s39b43k2vde7.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3kest3gurc9op.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","async":true}]],["$","html",null,{"lang":"en","suppressHydrationWarning":true,"children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":true,"children":["$","$L3",null,{"children":["$","$L4",null,{"children":[["$","$L5",null,{"children":["$","$L6",null,{"parallelRouterKey":"children","template":["$","$L7",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}],["$","$L8",null,{}]]}]}]}]}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"YAsRgSxdV-OcBfib_67Dt"}
+:HL["/litellm-asset-prefix/_next/static/chunks/3lvwyc5xjv11f.css","style"]
+0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/litellm-asset-prefix/_next/static/chunks/3lvwyc5xjv11f.css","precedence":"next"}],["$","script","script-0",{"src":"/litellm-asset-prefix/_next/static/chunks/03pu_dx0gqja9.js","async":true}],["$","script","script-1",{"src":"/litellm-asset-prefix/_next/static/chunks/3fn8zqlfrwowr.js","async":true}],["$","script","script-2",{"src":"/litellm-asset-prefix/_next/static/chunks/1ntn7efqc-iiw.js","async":true}]],["$","html",null,{"lang":"en","suppressHydrationWarning":true,"children":["$","body",null,{"className":"inter_5972bc34-module__OU16Qa__className","children":["$","$L2",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":true,"children":["$","$L3",null,{"children":["$","$L4",null,{"children":[["$","$L5",null,{"children":["$","$L6",null,{"parallelRouterKey":"children","template":["$","$L7",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}],["$","$L8",null,{}]]}]}]}]}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"912qRXFjlEYHK3EAPXXTc"}
diff --git a/litellm/proxy/_experimental/out/__next._tree.txt b/litellm/proxy/_experimental/out/__next._tree.txt
index f8caf5c831f..77147ece1c9 100644
--- a/litellm/proxy/_experimental/out/__next._tree.txt
+++ b/litellm/proxy/_experimental/out/__next._tree.txt
@@ -1,4 +1,4 @@
:HL["/litellm-asset-prefix/_next/static/chunks/1kid9zr1--h6y.css","style"]
-:HL["/litellm-asset-prefix/_next/static/chunks/3idmblk6vi8i5.css","style"]
+:HL["/litellm-asset-prefix/_next/static/chunks/3lvwyc5xjv11f.css","style"]
:HL["/litellm-asset-prefix/_next/static/media/83afe278b6a6bb3c-s.p.2bn3s6zvc0dyp.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
-0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"(dashboard)","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}}}},"staleTime":300,"buildId":"YAsRgSxdV-OcBfib_67Dt"}
+0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"(dashboard)","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}}}},"staleTime":300,"buildId":"912qRXFjlEYHK3EAPXXTc"}
diff --git a/litellm/proxy/_experimental/out/_next/static/YAsRgSxdV-OcBfib_67Dt/_buildManifest.js b/litellm/proxy/_experimental/out/_next/static/912qRXFjlEYHK3EAPXXTc/_buildManifest.js
similarity index 100%
rename from litellm/proxy/_experimental/out/_next/static/YAsRgSxdV-OcBfib_67Dt/_buildManifest.js
rename to litellm/proxy/_experimental/out/_next/static/912qRXFjlEYHK3EAPXXTc/_buildManifest.js
diff --git a/litellm/proxy/_experimental/out/_next/static/YAsRgSxdV-OcBfib_67Dt/_clientMiddlewareManifest.js b/litellm/proxy/_experimental/out/_next/static/912qRXFjlEYHK3EAPXXTc/_clientMiddlewareManifest.js
similarity index 100%
rename from litellm/proxy/_experimental/out/_next/static/YAsRgSxdV-OcBfib_67Dt/_clientMiddlewareManifest.js
rename to litellm/proxy/_experimental/out/_next/static/912qRXFjlEYHK3EAPXXTc/_clientMiddlewareManifest.js
diff --git a/litellm/proxy/_experimental/out/_next/static/YAsRgSxdV-OcBfib_67Dt/_ssgManifest.js b/litellm/proxy/_experimental/out/_next/static/912qRXFjlEYHK3EAPXXTc/_ssgManifest.js
similarity index 100%
rename from litellm/proxy/_experimental/out/_next/static/YAsRgSxdV-OcBfib_67Dt/_ssgManifest.js
rename to litellm/proxy/_experimental/out/_next/static/912qRXFjlEYHK3EAPXXTc/_ssgManifest.js
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0-dst_pi7co_a.js b/litellm/proxy/_experimental/out/_next/static/chunks/0-dst_pi7co_a.js
deleted file mode 100644
index 36f606ebc40..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/0-dst_pi7co_a.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,486794,(e,t,n)=>{t.exports=function(){var e=document.getSelection();if(!e.rangeCount)return function(){};for(var t=document.activeElement,n=[],i=0;i{"use strict";var i=e.r(486794),s={"text/plain":"Text","text/html":"Url",default:"Text"};t.exports=function(e,t){var n,r,l,o,a,d,u,c,h=!1;t||(t={}),l=t.debug||!1;try{if(a=i(),d=document.createRange(),u=document.getSelection(),(c=document.createElement("span")).textContent=e,c.ariaHidden="true",c.style.all="unset",c.style.position="fixed",c.style.top=0,c.style.clip="rect(0, 0, 0, 0)",c.style.whiteSpace="pre",c.style.webkitUserSelect="text",c.style.MozUserSelect="text",c.style.msUserSelect="text",c.style.userSelect="text",c.addEventListener("copy",function(n){if(n.stopPropagation(),t.format)if(n.preventDefault(),void 0===n.clipboardData){l&&console.warn("unable to use e.clipboardData"),l&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();var i=s[t.format]||s.default;window.clipboardData.setData(i,e)}else n.clipboardData.clearData(),n.clipboardData.setData(t.format,e);t.onCopy&&(n.preventDefault(),t.onCopy(n.clipboardData))}),document.body.appendChild(c),d.selectNodeContents(c),u.addRange(d),!document.execCommand("copy"))throw Error("copy command was unsuccessful");h=!0}catch(i){l&&console.error("unable to copy using execCommand: ",i),l&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(t.format||"text",e),t.onCopy&&t.onCopy(window.clipboardData),h=!0}catch(i){l&&console.error("unable to copy using clipboardData: ",i),l&&console.error("falling back to prompt"),n="message"in t?t.message:"Copy to clipboard: #{key}, Enter",r=(/mac os x/i.test(navigator.userAgent)?"⌘":"Ctrl")+"+C",o=n.replace(/#{\s*key\s*}/g,r),window.prompt(o,e)}}finally{u&&("function"==typeof u.removeRange?u.removeRange(d):u.removeAllRanges()),c&&document.body.removeChild(c),a()}return h}},743151,(e,t,n)=>{"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.CopyToClipboard=void 0;var i=l(e.r(844343)),s=l(e.r(271645)),r=["text","onCopy","options","children"];function l(e){return e&&e.__esModule?e:{default:e}}function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,i)}return n}function d(e){for(var t=1;t{"use strict";var i=e.r(743151).CopyToClipboard;i.CopyToClipboard=i,t.exports=i},343488,e=>{"use strict";var t=e.i(540626),n=e.i(271645);e.s(["useDebouncedCallback",0,function(e,i){let s=(0,t.useDebouncer)(e,i).maybeExecute;return(0,n.useCallback)((...e)=>s(...e),[s])}])},540626,e=>{"use strict";let t;var n=e.i(271645);let i=(0,n.createContext)(null);function s(e,t){if(Object.is(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[n,i]of e)if(!t.has(n)||!Object.is(i,t.get(n)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let n of e)if(!t.has(n))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();let n=r(e);if(n.length!==r(t).length)return!1;for(let i=0;ie,i){let s=i?.compare??o,r=(0,n.useCallback)(t=>{let{unsubscribe:n}=e.subscribe(t);return n},[e]),d=(0,n.useCallback)(()=>e.get(),[e]);return(0,l.useSyncExternalStoreWithSelector)(r,d,d,t,s)}function d(e,...t){return"function"==typeof e?e(...t):e}var u=class{#e=!0;#t;#n;#i;#s;#r;#l;#o;#a=0;#d=5;#u=!1;#c=!1;#h=null;#p=()=>{this.debugLog("Connected to event bus"),this.#r=!0,this.#u=!1,this.debugLog("Emitting queued events",this.#s),this.#s.forEach(e=>this.emitEventToBus(e)),this.#s=[],this.stopConnectLoop(),this.#n().removeEventListener("tanstack-connect-success",this.#p)};#m=()=>{if(this.#a{this.#u||(this.#u=!0,this.#n().addEventListener("tanstack-connect-success",this.#p),this.#m())};constructor({pluginId:e,debug:t=!1,enabled:n=!0,reconnectEveryMs:i=300}){this.#t=e,this.#e=n,this.#n=this.getGlobalTarget,this.#i=t,this.debugLog(" Initializing event subscription for plugin",this.#t),this.#s=[],this.#r=!1,this.#c=!1,this.#l=null,this.#o=i}startConnectLoop(){null!==this.#l||this.#r||(this.debugLog(`Starting connect loop (every ${this.#o}ms)`),this.#l=setInterval(this.#m,this.#o))}stopConnectLoop(){this.#u=!1,null!==this.#l&&(clearInterval(this.#l),this.#l=null,this.#s=[],this.debugLog("Stopped connect loop"))}debugLog(...e){this.#i&&console.log(`🌴 [tanstack-devtools:${this.#t}-plugin]`,...e)}getGlobalTarget(){if("u">typeof globalThis&&globalThis.__TANSTACK_EVENT_TARGET__)return this.debugLog("Using global event target"),globalThis.__TANSTACK_EVENT_TARGET__;if("u">typeof window&&void 0!==window.addEventListener)return this.debugLog("Using window as event target"),window;let e="u">typeof EventTarget?new EventTarget:void 0;return void 0===e||void 0===e.addEventListener?(this.debugLog("No event mechanism available, running in non-web environment"),{addEventListener:()=>{},removeEventListener:()=>{},dispatchEvent:()=>!1}):(this.debugLog("Using new EventTarget as fallback"),e)}getPluginId(){return this.#t}dispatchCustomEventShim(e,t){try{let n=new Event(e,{detail:t});this.#n().dispatchEvent(n)}catch(e){this.debugLog("Failed to dispatch shim event")}}dispatchCustomEvent(e,t){try{this.#n().dispatchEvent(new CustomEvent(e,{detail:t}))}catch(n){this.dispatchCustomEventShim(e,t)}}emitEventToBus(e){this.debugLog("Emitting event to client bus",e),this.dispatchCustomEvent("tanstack-dispatch-event",e)}createEventPayload(e,t){return{type:`${this.#t}:${e}`,payload:t,pluginId:this.#t}}emit(e,t){if(!this.#e)return void this.debugLog("Event bus client is disabled, not emitting event",e,t);if(this.#h&&(this.debugLog("Emitting event to internal event target",e,t),this.#h.dispatchEvent(new CustomEvent(`${this.#t}:${e}`,{detail:this.createEventPayload(e,t)}))),this.#c)return void this.debugLog("Previously failed to connect, not emitting to bus");if(!this.#r){this.debugLog("Bus not available, will be pushed as soon as connected"),this.#s.push(this.createEventPayload(e,t)),"u">typeof CustomEvent&&!this.#u&&(this.#v(),this.startConnectLoop());return}return this.emitEventToBus(this.createEventPayload(e,t))}on(e,t,n){let i=n?.withEventTarget??!1,s=`${this.#t}:${e}`;if(i&&(this.#h||(this.#h=new EventTarget),this.#h.addEventListener(s,e=>{t(e.detail)})),!this.#e)return this.debugLog("Event bus client is disabled, not registering event",s),()=>{};let r=e=>{this.debugLog("Received event from bus",e.detail),t(e.detail)};return this.#n().addEventListener(s,r),this.debugLog("Registered event to bus",s),()=>{i&&this.#h?.removeEventListener(s,r),this.#n().removeEventListener(s,r)}}onAll(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{e(t.detail)};return this.#n().addEventListener("tanstack-devtools-global",t),()=>this.#n().removeEventListener("tanstack-devtools-global",t)}onAllPluginEvents(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{let n=t.detail;this.#t&&n.pluginId!==this.#t||e(n)};return this.#n().addEventListener("tanstack-devtools-global",t),()=>this.#n().removeEventListener("tanstack-devtools-global",t)}};let c=new Map;function h(e){if(void 0!==e)try{return JSON.parse(JSON.stringify(e))}catch{return null}}let p=new class extends u{constructor(e){super({pluginId:"pacer",debug:e?.debug,reconnectEveryMs:1e3})}};function m(e,t,n){let i="object"==typeof e,s=i?e:void 0;return{next:(i?e.next:e)?.bind(s),error:(i?e.error:t)?.bind(s),complete:(i?e.complete:n)?.bind(s)}}let v=[],f=0,{link:g,unlink:b,propagate:x,checkDirty:y,shallowPropagate:j}=function({update:e,notify:t,unwatched:n}){return{link:function(e,t,n){let i=t.depsTail;if(void 0!==i&&i.dep===e)return;let s=void 0!==i?i.nextDep:t.deps;if(void 0!==s&&s.dep===e){s.version=n,t.depsTail=s;return}let r=e.subsTail;if(void 0!==r&&r.version===n&&r.sub===t)return;let l=t.depsTail=e.subsTail={version:n,dep:e,sub:t,prevDep:i,nextDep:s,prevSub:r,nextSub:void 0};void 0!==s&&(s.prevDep=l),void 0!==i?i.nextDep=l:t.deps=l,void 0!==r?r.nextSub=l:e.subs=l},unlink:function(e,t=e.sub){let i=e.dep,s=e.prevDep,r=e.nextDep,l=e.nextSub,o=e.prevSub;return void 0!==r?r.prevDep=s:t.depsTail=s,void 0!==s?s.nextDep=r:t.deps=r,void 0!==l?l.prevSub=o:i.subsTail=o,void 0!==o?o.nextSub=l:void 0===(i.subs=l)&&n(i),r},propagate:function(e){let n,i=e.nextSub;e:for(;;){let s=e.sub,r=s.flags;if(60&r?12&r?4&r?!(48&r)&&function(e,t){let n=t.depsTail;for(;void 0!==n;){if(n===e)return!0;n=n.prevDep}return!1}(e,s)?(s.flags=40|r,r&=1):r=0:s.flags=-9&r|32:r=0:s.flags=32|r,2&r&&t(s),1&r){let t=s.subs;if(void 0!==t){let s=(e=t).nextSub;void 0!==s&&(n={value:i,prev:n},i=s);continue}}if(void 0!==(e=i)){i=e.nextSub;continue}for(;void 0!==n;)if(e=n.value,n=n.prev,void 0!==e){i=e.nextSub;continue e}break}},checkDirty:function(t,n){let s,r=0,l=!1;e:for(;;){let o=t.dep,a=o.flags;if(16&n.flags)l=!0;else if((17&a)==17){if(e(o)){let e=o.subs;void 0!==e.nextSub&&i(e),l=!0}}else if((33&a)==33){(void 0!==t.nextSub||void 0!==t.prevSub)&&(s={value:t,prev:s}),t=o.deps,n=o,++r;continue}if(!l){let e=t.nextDep;if(void 0!==e){t=e;continue}}for(;r--;){let r=n.subs,o=void 0!==r.nextSub;if(o?(t=s.value,s=s.prev):t=r,l){if(e(n)){o&&i(r),n=t.sub;continue}l=!1}else n.flags&=-33;n=t.sub;let a=t.nextDep;if(void 0!==a){t=a;continue e}}return l}},shallowPropagate:i};function i(e){do{let n=e.sub,i=n.flags;(48&i)==32&&(n.flags=16|i,(6&i)==2&&t(n))}while(void 0!==(e=e.nextSub))}}({update:e=>e._update(),notify(e){v[S++]=e,e.flags&=-3},unwatched(e){void 0!==e.depsTail&&(e.depsTail=void 0,e.flags=17,E(e))}}),C=0,S=0;function E(e){let t=e.depsTail,n=void 0!==t?t.nextDep:e.deps;for(;void 0!==n;)n=b(n,e)}var w=class{constructor(e,n){this.atom=function(e){let n="function"==typeof e,i={_snapshot:n?void 0:e,subs:void 0,subsTail:void 0,deps:void 0,depsTail:void 0,flags:+!n,get:()=>(void 0!==t&&g(i,t,f),i._snapshot),subscribe(e){var n;let s,r,l=m(e),o={current:!1},a=(n=()=>{i.get(),o.current?l.next?.(i._snapshot):o.current=!0},s=()=>{let e=t;t=r,++f,r.depsTail=void 0,r.flags=6;try{return n()}finally{t=e,r.flags&=-5,E(r)}},r={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:6,notify(){let e=this.flags;16&e||32&e&&y(this.deps,this)?s():this.flags=2},stop(){this.flags=0,this.depsTail=void 0,E(this)}},s(),r);return{unsubscribe:()=>{a.stop()}}},_update(s){let r=t,l=(void 0)??Object.is;if(n)t=i,++f,i.depsTail=void 0;else if(void 0===s)return!1;n&&(i.flags=5);try{let t=i._snapshot,r="function"==typeof s?s(t):void 0===s&&n?e(t):s;if(void 0===t||!l(t,r))return i._snapshot=r,!0;return!1}finally{t=r,n&&(i.flags&=-5),E(i)}}};return n?(i.flags=17,i.get=function(){let e=i.flags;if(16&e||32&e&&y(i.deps,i)){if(i._update()){let e=i.subs;void 0!==e&&j(e)}}else 32&e&&(i.flags=-33&e);return void 0!==t&&g(i,t,f),i._snapshot}):i.set=function(e){if(i._update(e)){let e=i.subs;if(void 0!==e&&(x(e),j(e),1)){for(;C{this.options={...this.options,...e},this.#g()||this.cancel()},this.#b=e=>{this.store.setState(t=>{let n={...t,...e},{isPending:i}=n;return{...n,status:this.#g()?i?"pending":"idle":"disabled"}}),((e,t)=>{let n=t.key;if(n){var i,s;c.set(n,t),p.emit(e,{key:(i={...t,key:n}).key,store:{state:h("function"==typeof(s=i.store).get?s.get():s.state)},options:h(i.options)})}})("Debouncer",this)},this.#g=()=>!!d(this.options.enabled,this),this.#x=()=>d(this.options.wait,this),this.maybeExecute=(...e)=>{if(!this.#g())return;this.#b({maybeExecuteCount:this.store.state.maybeExecuteCount+1});let t=!1;this.options.leading&&this.store.state.canLeadingExecute&&(this.#b({canLeadingExecute:!1}),t=!0,this.#y(...e)),this.options.trailing&&this.#b({isPending:!0,lastArgs:e}),this.#f&&clearTimeout(this.#f),this.#f=setTimeout(()=>{this.#b({canLeadingExecute:!0}),this.options.trailing&&!t&&this.#y(...e)},this.#x())},this.#y=(...e)=>{this.#g()&&(this.fn(...e),this.#b({executionCount:this.store.state.executionCount+1,isPending:!1,lastArgs:void 0}),this.options.onExecute?.(e,this))},this.flush=()=>{this.store.state.isPending&&this.store.state.lastArgs&&(this.#j(),this.#y(...this.store.state.lastArgs))},this.#j=()=>{this.#f&&(clearTimeout(this.#f),this.#f=void 0)},this.cancel=()=>{this.#j(),this.#b({canLeadingExecute:!0,isPending:!1})},this.reset=()=>{this.#b(_())},this.key=t.key,this.options={...N,...t},this.#b(this.options.initialState??{}),this.key&&p.on("d-Debouncer",e=>{e.payload.key===this.key&&(this.#b(e.payload.store.state),this.setOptions(e.payload.options))})}#b;#g;#x;#y;#j};e.s(["useDebouncer",0,function(e,t,r=()=>({})){let l={...((0,n.useContext)(i)?.defaultOptions??{}).debouncer,...t},[o]=(0,n.useState)(()=>{let t=new T(e,l);return t.Subscribe=function(e){let n=a(t.store,e.selector,{compare:s});return"function"==typeof e.children?e.children(n):e.children},t});o.fn=e,o.setOptions(l),(0,n.useEffect)(()=>()=>{l.onUnmount?l.onUnmount(o):o.cancel()},[]);let d=a(o.store,r,{compare:s});return(0,n.useMemo)(()=>({...o,state:d}),[o,d])}],540626)},741466,e=>{"use strict";e.s(["DEBOUNCE_WAIT_MS",0,300])},186248,e=>{"use strict";var t=e.i(343488),n=e.i(271645),i=e.i(741466);let s=new Set(["input-change","input-clear","clear-press"]);e.s(["usePaginatedCombobox",0,function({onSearchChange:e,onLoadMore:r,hasNextPage:l,isFetchingNextPage:o}){let a=(0,t.useDebouncedCallback)(e,{wait:i.DEBOUNCE_WAIT_MS}),[d,u]=(0,n.useState)(null);return{typedQuery:d,handleInputValueChange:(e,t)=>{s.has(t)?(u(e),a(e)):u(null)},handleOpenChange:(e,t)=>{if(!e){d&&a(""),u(null);return}s.has(t)||u("")},handleScroll:e=>{let t=e.currentTarget;0===t.scrollHeight||(t.scrollTop+t.clientHeight)/t.scrollHeight>=.8&&l&&!o&&r?.()}}}])},744582,e=>{"use strict";var t=e.i(843476),n=e.i(531278),i=e.i(271645),s=e.i(131792),r=e.i(186248);e.s(["PaginatedSearchSelect",0,function({options:e,value:l,onValueChange:o,onSearchChange:a,onLoadMore:d,hasNextPage:u=!1,isLoading:c=!1,isFetchingNextPage:h=!1,placeholder:p="Search…",emptyText:m="No results",errorText:v,loadingText:f="Loading…",autoHighlight:g=!1,disabled:b=!1,className:x,inputId:y,"aria-required":j,"aria-invalid":C,"aria-describedby":S}){let[E,w]=(0,i.useState)(null),_=(0,i.useRef)(!1),N=e=>{let t=e.currentTarget;_.current=t.value.length>0&&0===t.selectionStart&&t.selectionEnd===t.value.length},T=(0,i.useMemo)(()=>void 0===l||""===l?null:e.find(e=>e.value===l)??(E?.value===l?E:{label:l,value:l}),[e,l,E]),k=(0,i.useMemo)(()=>null===T||e.some(e=>e.value===T.value)?e:[T,...e],[e,T]),{typedQuery:L,handleInputValueChange:P,handleOpenChange:I,handleScroll:O}=(0,r.usePaginatedCombobox)({onSearchChange:a,onLoadMore:d,hasNextPage:u,isFetchingNextPage:h});return(0,t.jsxs)(s.Combobox,{items:k,value:T,inputValue:L??T?.label??"",onValueChange:e=>{w(e),o(e?.value??"")},onInputValueChange:(e,t)=>{var n,i;let s,r;return n=t.reason,s=_.current,_.current=!1,void P(null!==L||s||""===(r=((e,t)=>{let n=0;for(;nI(e,t.reason),isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,autoHighlight:g,filter:null,disabled:b,children:[(0,t.jsx)(s.ComboboxInput,{id:y,"aria-required":j,"aria-invalid":C,"aria-describedby":S,onFocus:e=>e.currentTarget.select(),onKeyDown:N,onPaste:N,placeholder:p,showClear:void 0!==l&&""!==l,className:`w-full ${x??""}`}),(0,t.jsxs)(s.ComboboxContent,{children:[(0,t.jsx)(s.ComboboxEmpty,{className:null==v?void 0:"text-destructive",children:v??(c?f:m)}),(0,t.jsx)(s.ComboboxList,{onScroll:O,"data-testid":"paginated-search-select-list",children:e=>(0,t.jsx)(s.ComboboxItem,{value:e,children:(0,t.jsxs)("span",{className:"flex min-w-0 flex-col",children:[(0,t.jsx)("span",{className:"truncate",children:e.label}),null!=e.sublabel&&""!==e.sublabel&&(0,t.jsx)("span",{className:"truncate text-xs text-muted-foreground",children:e.sublabel})]})},e.value)}),h&&(0,t.jsx)("div",{className:"flex justify-center py-2","data-testid":"paginated-search-select-loading-more",children:(0,t.jsx)(n.Loader2,{className:"size-4 animate-spin text-muted-foreground"})})]})]})}])},435451,e=>{"use strict";var t=e.i(843476),n=e.i(271645),i=e.i(793479);let s=n.default.forwardRef(({step:e=.01,style:n={width:"100%"},placeholder:s="Enter a numerical value",min:r,max:l,onChange:o,...a},d)=>(0,t.jsx)(i.Input,{ref:d,type:"number",onWheel:e=>e.currentTarget.blur(),step:e,style:n,placeholder:s,min:r,max:l,onChange:o,...a}));s.displayName="NumericalInput",e.s(["default",0,s])},860585,e=>{"use strict";var t=e.i(843476),n=e.i(967489);let i="none",s={[i]:"Never resets","1h":"hourly","24h":"daily","7d":"weekly","30d":"monthly"};e.s(["NEVER_RESETS_BUDGET_DURATION",0,i,"default",0,({id:e,value:r,onChange:l,className:o="",style:a={},placeholder:d="n/a",showNeverResets:u=!1})=>(0,t.jsxs)(n.Select,{items:s,value:r||null,onValueChange:e=>l?.(e??void 0),children:[(0,t.jsx)(n.SelectTrigger,{id:e,className:`w-full ${o}`,style:a,children:(0,t.jsx)(n.SelectValue,{placeholder:d})}),(0,t.jsxs)(n.SelectContent,{children:[(0,t.jsx)(n.SelectItem,{value:null,children:d}),u?(0,t.jsx)(n.SelectItem,{value:i,children:"Never resets"}):null,(0,t.jsx)(n.SelectItem,{value:"1h",children:"hourly"}),(0,t.jsx)(n.SelectItem,{value:"24h",children:"daily"}),(0,t.jsx)(n.SelectItem,{value:"7d",children:"weekly"}),(0,t.jsx)(n.SelectItem,{value:"30d",children:"monthly"})]})]}),"getBudgetDurationLabel",0,e=>e?({"1h":"hourly","24h":"daily","7d":"weekly","30d":"monthly"})[e]||e:"Not set"])},500727,e=>{"use strict";var t=e.i(266027),n=e.i(243652),i=e.i(602869),s=e.i(135214);let r=(0,n.createQueryKeys)("mcpServers");e.s(["useMCPServers",0,e=>{let{accessToken:n}=(0,s.default)();return(0,t.useQuery)({queryKey:r.list(e?{filters:{teamId:e}}:void 0),queryFn:async()=>await (0,i.fetchMCPServers)(n,e),enabled:!!n})}])},699857,e=>{"use strict";var t=e.i(266027),n=e.i(243652),i=e.i(602869),s=e.i(135214);let r=(0,n.createQueryKeys)("mcpToolsets");e.s(["useMCPToolsets",0,()=>{let{accessToken:e}=(0,s.default)();return(0,t.useQuery)({queryKey:r.list(),queryFn:async()=>await (0,i.fetchMCPToolsets)(e),enabled:!!e})}])},75921,e=>{"use strict";var t=e.i(843476),n=e.i(266027),i=e.i(243652),s=e.i(602869),r=e.i(135214);let l=(0,i.createQueryKeys)("mcpAccessGroups");var o=e.i(500727),a=e.i(699857),d=e.i(845150),u=e.i(234713);let c="toolset:";e.s(["default",0,({onChange:e,value:i,className:h,accessToken:p,placeholder:m="Select MCP servers",disabled:v=!1,teamId:f,allowNoMcpServers:g=!1,allowAllProxyMcpServers:b=!1})=>{let{data:x=[],isLoading:y}=(0,o.useMCPServers)(f),{data:j=[],isLoading:C}=(()=>{let{accessToken:e}=(0,r.default)();return(0,n.useQuery)({queryKey:l.list({}),queryFn:async()=>await (0,s.fetchMCPAccessGroups)(e),enabled:!!e})})(),{data:S=[],isLoading:E}=(0,a.useMCPToolsets)(),w=new Set(j),_=[...j.map(e=>({label:e,value:e,description:"Access Group"})),...x.map(e=>({label:`${e.server_name||e.server_id} (${e.server_id})`,value:e.server_id,description:"MCP Server"})),...S.map(e=>({label:e.toolset_name,value:`${c}${e.toolset_id}`,description:"Toolset"}))],N=[...i?.servers||[],...i?.accessGroups||[],...(i?.toolsets||[]).map(e=>`${c}${e}`)],T=g&&N.includes(u.NO_MCP_SERVERS_SENTINEL),k=N.includes(u.ALL_PROXY_MCP_SERVERS_SENTINEL),L=[...b||k?[{label:"All Proxy MCP Servers",value:u.ALL_PROXY_MCP_SERVERS_SENTINEL}]:[],...g?[{label:"No MCP Servers",value:u.NO_MCP_SERVERS_SENTINEL,description:"Block all"}]:[],..._.map(e=>({...e,disabled:T||k}))];return(0,t.jsx)("div",{children:(0,t.jsx)(d.MultiSelect,{options:L,value:N,onValueChange:t=>{if(b&&t.includes(u.ALL_PROXY_MCP_SERVERS_SENTINEL))return void e({servers:[u.ALL_PROXY_MCP_SERVERS_SENTINEL],accessGroups:[],toolsets:[]});if(g&&t.includes(u.NO_MCP_SERVERS_SENTINEL))return void e({servers:[u.NO_MCP_SERVERS_SENTINEL],accessGroups:[],toolsets:[]});let n=t.filter(e=>e.startsWith(c)).map(e=>e.slice(c.length)),i=t.filter(e=>!e.startsWith(c));e({servers:i.filter(e=>!w.has(e)),accessGroups:i.filter(e=>w.has(e)),toolsets:n})},placeholder:m,emptyText:"No MCP servers found",loading:y||C||E,disabled:v,className:`w-full ${h??""}`})})}],75921)},879002,e=>{"use strict";let t=(0,e.i(475254).default)("user-plus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]);e.s(["UserPlus",0,t],879002)},531516,696609,e=>{"use strict";var t=e.i(843476),n=e.i(271645),i=e.i(257428),s=e.i(409797),r=e.i(233565);let l=/\b(delete|remove|destroy|purge|drop|erase|unlink)\b/i,o=/\b(create|add|insert|new|post|submit|register|make|generate|write|upload)\b/i,a=/\b(update|edit|modify|change|patch|put|set|rename|move|transform)\b/i,d=/\b(get|read|list|fetch|search|find|query|retrieve|show|view|check|describe|info)\b/i;function u(e,t=""){let n=e.toLowerCase();if(d.test(n))return"read";if(l.test(n))return"delete";if(a.test(n))return"update";if(o.test(n))return"create";if(t){let e=t.toLowerCase();if(d.test(e))return"read";if(l.test(e))return"delete";if(a.test(e))return"update";if(o.test(e))return"create"}return"unknown"}function c(e){let t={read:[],create:[],update:[],delete:[],unknown:[]};for(let n of e)t[u(n.name,n.description)].push(n);return t}let h={read:{label:"Read",description:"Safe operations — fetch, list, search. No side effects.",risk:"low"},create:{label:"Create",description:"Add new resources — insert, upload, register.",risk:"medium"},update:{label:"Update",description:"Modify existing resources — edit, patch, rename.",risk:"medium"},delete:{label:"Delete",description:"Destructive operations — remove, purge, destroy.",risk:"high"},unknown:{label:"Other",description:"Operations that could not be automatically classified.",risk:"unknown"}};e.s(["CRUD_GROUP_META",0,h,"classifyToolOp",0,u,"groupToolsByCrud",0,c],696609);let p=["read","create","update","delete","unknown"],m={low:"bg-success/15 text-success",medium:"bg-warning/15 text-warning",high:"bg-destructive/15 text-destructive font-semibold",unknown:"bg-muted text-foreground"},v={read:"border-success/20",create:"border-info/20",update:"border-warning/20",delete:"border-destructive/30",unknown:"border-border"},f={read:"bg-success/10",create:"bg-info/10",update:"bg-warning/10",delete:"bg-destructive/10",unknown:"bg-muted"};e.s(["default",0,({tools:e,value:l,onChange:o,readOnly:a=!1,searchFilter:d=""})=>{let[u,g]=(0,n.useState)({read:!1,create:!1,update:!1,delete:!1,unknown:!0}),b=(0,n.useMemo)(()=>c(e),[e]),x=(0,n.useMemo)(()=>new Set(void 0===l?e.map(e=>e.name):l),[l,e]);return 0===e.length?null:(0,t.jsx)("div",{className:"space-y-3",children:p.map(e=>{let n,l=b[e];if(0===l.length)return null;if(d){let e=d.toLowerCase();if(!l.some(t=>t.name.toLowerCase().includes(e)||(t.description??"").toLowerCase().includes(e)))return null}let c=h[e],p=(n=b[e]).length>0&&n.every(e=>x.has(e.name)),y=(e=>{let t=b[e];if(0===t.length)return!1;let n=t.filter(e=>x.has(e.name)).length;return n>0&&n{g(t=>({...t,[e]:!t[e]}))},children:[j?(0,t.jsx)(r.ChevronRightIcon,{className:"w-4 h-4 text-muted-foreground shrink-0"}):(0,t.jsx)(s.ChevronDownIcon,{className:"w-4 h-4 text-muted-foreground shrink-0"}),(0,t.jsx)("span",{className:"font-semibold text-foreground text-sm",children:c.label}),(0,t.jsx)("span",{className:`text-xs px-2 py-0.5 rounded-full ${m[c.risk]}`,children:"high"===c.risk?"High Risk":"medium"===c.risk?"Medium Risk":"low"===c.risk?"Safe":"Unclassified"}),(0,t.jsxs)("span",{className:"text-xs text-muted-foreground ml-1",children:[l.filter(e=>x.has(e.name)).length,"/",l.length," allowed"]})]}),!a&&(0,t.jsxs)("div",{className:"flex items-center gap-2 ml-4",children:[(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:p?"All on":y?"Partial":"All off"}),(0,t.jsx)(i.Checkbox,{"aria-label":`Allow all ${c.label} tools`,checked:p,indeterminate:y,onCheckedChange:t=>((e,t)=>{if(a)return;let n=new Set(x);for(let i of b[e])t?n.add(i.name):n.delete(i.name);o(Array.from(n))})(e,t),onClick:e=>e.stopPropagation()})]})]}),!j&&(0,t.jsx)("div",{className:"px-4 pt-2 pb-1 text-xs text-muted-foreground bg-card border-b border-border",children:c.description}),!j&&(0,t.jsx)("div",{className:"bg-card divide-y divide-gray-50",children:l.filter(e=>!d||e.name.toLowerCase().includes(d.toLowerCase())||(e.description??"").toLowerCase().includes(d.toLowerCase())).map(e=>{let n,s=(n=e.name,x.has(n));return(0,t.jsxs)("div",{className:`flex items-start gap-3 px-4 py-2.5 transition-colors hover:bg-accent ${!a?"cursor-pointer":""} ${s?"":"opacity-60"}`,onClick:()=>(e=>{if(a)return;let t=new Set(x);t.has(e)?t.delete(e):t.add(e),o(Array.from(t))})(e.name),children:[(0,t.jsx)(i.Checkbox,{"aria-label":e.name,checked:s,disabled:a,onClick:e=>e.stopPropagation()}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsx)("p",{className:"font-medium text-foreground text-sm",children:e.name}),e.description&&(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5 leading-snug",children:e.description})]}),(0,t.jsx)("span",{className:`text-xs px-1.5 py-0.5 rounded shrink-0 ${s?"bg-success/15 text-success":"bg-muted text-muted-foreground"}`,children:s?"on":"off"})]},e.name)})})]},e)})})}],531516)},390605,e=>{"use strict";var t=e.i(843476),n=e.i(271645),i=e.i(602869),s=e.i(629288),r=e.i(571303),l=e.i(500727),o=e.i(531516),a=e.i(696609);e.s(["default",0,({accessToken:e,selectedServers:d,toolPermissions:u,onChange:c,disabled:h=!1})=>{let{data:p=[]}=(0,l.useMCPServers)(),[m,v]=(0,n.useState)({}),[f,g]=(0,n.useState)({}),[b,x]=(0,n.useState)({}),[y,j]=(0,n.useState)({}),C=(0,n.useRef)(u);(0,n.useEffect)(()=>{C.current=u},[u]);let S=(0,n.useMemo)(()=>0===d.length?[]:p.filter(e=>d.includes(e.server_id)),[p,d]),E=async(e,t)=>{g(t=>({...t,[e]:!0})),x(t=>({...t,[e]:""}));try{let n=await (0,i.listMCPTools)(t,e);if(n.error)x(t=>({...t,[e]:n.message||"Failed to fetch tools"})),v(t=>({...t,[e]:[]}));else{let t=n.tools||[];v(n=>({...n,[e]:t}));let i=C.current;if(!i[e]&&t.length>0){let n=t.filter(e=>"delete"!==(0,a.classifyToolOp)(e.name,e.description||"")).map(e=>e.name);c({...i,[e]:n})}}}catch(t){console.error(`Error fetching tools for server ${e}:`,t),x(t=>({...t,[e]:"Failed to fetch tools"})),v(t=>({...t,[e]:[]}))}finally{g(t=>({...t,[e]:!1}))}};(0,n.useEffect)(()=>{S.forEach(t=>{m[t.server_id]||f[t.server_id]||E(t.server_id,e)})},[S,e]);let w=(e,t)=>{c({...u,[e]:t})};return 0===d.length?null:(0,t.jsx)("div",{className:"space-y-4",children:S.map(e=>{let n=e.server_name||e.alias||e.server_id,i=m[e.server_id]||[],l=u[e.server_id]||[],a=f[e.server_id],d=b[e.server_id],p=y[e.server_id]??"crud";return(0,t.jsxs)("div",{className:"border rounded-lg bg-muted",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between p-4 border-b bg-card rounded-t-lg",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:n}),e.description&&(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:e.description})]}),(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[!h&&i.length>0&&(0,t.jsxs)(s.RadioGroup,{value:p,onValueChange:t=>j(n=>({...n,[e.server_id]:t})),className:"flex w-auto items-center gap-4",children:[(0,t.jsxs)("label",{className:"flex items-center gap-2 text-sm",children:[(0,t.jsx)(s.RadioGroupItem,{value:"crud"}),"Risk Groups"]}),(0,t.jsxs)("label",{className:"flex items-center gap-2 text-sm",children:[(0,t.jsx)(s.RadioGroupItem,{value:"flat"}),"Flat List"]})]}),!h&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("button",{type:"button",className:"text-sm text-info hover:text-info/80 font-medium",onClick:()=>{var t;let n;return n=m[t=e.server_id]||[],void c({...u,[t]:n.map(e=>e.name)})},disabled:a,children:"Select All"}),(0,t.jsx)("button",{type:"button",className:"text-sm text-info hover:text-info/80 font-medium",onClick:()=>{var t;return t=e.server_id,void c({...u,[t]:[]})},disabled:a,children:"Deselect All"})]})]})]}),(0,t.jsxs)("div",{className:"p-4",children:[a&&(0,t.jsxs)("div",{className:"flex items-center justify-center py-8",children:[(0,t.jsx)(r.UiLoadingSpinner,{}),(0,t.jsx)("p",{className:"ml-3 text-sm text-muted-foreground",children:"Loading tools..."})]}),d&&!a&&(0,t.jsxs)("div",{className:"p-4 bg-destructive/10 border border-destructive/20 rounded-lg text-center",children:[(0,t.jsx)("p",{className:"text-sm text-destructive font-medium",children:"Unable to load tools"}),(0,t.jsx)("p",{className:"text-sm text-destructive mt-1",children:d})]}),!a&&!d&&i.length>0&&"crud"===p&&(0,t.jsx)(o.default,{tools:i,value:u[e.server_id]?l:void 0,onChange:t=>w(e.server_id,t),readOnly:h}),!a&&!d&&i.length>0&&"flat"===p&&(0,t.jsx)("div",{className:"space-y-2",children:i.map(n=>{let i=l.includes(n.name);return(0,t.jsxs)("div",{className:"flex items-start gap-2",children:[(0,t.jsx)("input",{type:"checkbox","aria-label":n.name,checked:i,onChange:()=>{if(h)return;let t=i?l.filter(e=>e!==n.name):[...l,n.name];w(e.server_id,t)},disabled:h,className:"mt-0.5"}),(0,t.jsx)("div",{className:"flex-1 min-w-0",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:n.name}),(0,t.jsxs)("p",{className:"text-sm text-muted-foreground",children:["- ",n.description||"No description"]})]})})]},n.name)})}),!a&&!d&&0===i.length&&(0,t.jsx)("div",{className:"text-center py-6",children:(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"No tools available"})})]})]},e.server_id)})})}])},558364,e=>{"use strict";var t=e.i(843476),n=e.i(552546),i=e.i(542450),s=e.i(519455),r=e.i(950594),l=e.i(967489),o=e.i(107233),a=e.i(37727),d=e.i(271645);let u=["budget_limit","time_period","max_budget","budget_duration"],c=e=>{let t="string"==typeof e?Number(e):e;return"number"==typeof t&&Number.isFinite(t)?t:null},h=e=>"string"==typeof e&&""!==e?e:null,p=[{value:"1h",label:"Hourly"},{value:"24h",label:"Daily"},{value:"7d",label:"Weekly"},{value:"30d",label:"Monthly"},{value:"1mo",label:"Calendar month"}],m="Premium feature - Upgrade to set per-model budgets";function v({value:e,onChange:i,availableModels:f,premiumUser:g,usage:b}){let[x,y]=(0,d.useState)(()=>Object.entries(e??{}).map(([e,t],n)=>({id:`existing-${n}`,model:e,budgetLimit:c(t?.budget_limit)??c(t?.max_budget),timePeriod:h(t?.time_period)??h(t?.budget_duration)??"30d",extra:Object.fromEntries(Object.entries(t??{}).filter(([e])=>!u.includes(e)))}))),j=e=>{y(e),i(Object.fromEntries(e.filter(e=>null!==e.model&&null!==e.budgetLimit).map(e=>[e.model,{...e.extra,budget_limit:e.budgetLimit,time_period:e.timePeriod}])))},C=()=>j([...x,{id:Date.now().toString(),model:null,budgetLimit:null,timePeriod:"30d",extra:{}}]),S=(e,t)=>j(x.map(n=>n.id===e?{...n,...t}:n)),E=new Set(x.map(e=>e.model).filter(Boolean)),w=g?void 0:m,_=(0,t.jsx)("div",{className:"text-xs text-muted-foreground",children:g?"Cap spend per model over its own window. A budget set on the bare model name also covers the provider-prefixed spelling of that model.":m});return 0===x.length?(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"mb-2",children:_}),(0,t.jsxs)(s.Button,{variant:"outline",size:"sm",onClick:C,disabled:!g,title:w,children:[(0,t.jsx)(o.Plus,{className:"w-3 h-3"}),"Add Model Budget"]})]}):(0,t.jsxs)("div",{className:"space-y-4",children:[_,x.map(e=>{let i=f.filter(t=>t===e.model||!E.has(t)),s=e.model?b?.[e.model]?.current_spend:void 0;return(0,t.jsxs)("div",{className:"relative rounded-lg border border-border bg-muted p-4",children:[(0,t.jsx)("button",{type:"button",onClick:()=>{let t;return t=e.id,j(x.filter(e=>e.id!==t))},disabled:!g,title:w,className:"absolute top-2 right-2 text-muted-foreground hover:text-destructive transition-colors p-1",children:(0,t.jsx)(a.X,{className:"w-4 h-4"})}),(0,t.jsxs)("div",{className:"mb-3",children:[(0,t.jsx)("label",{className:"block text-xs font-medium text-muted-foreground mb-1",children:"Model"}),(0,t.jsx)(n.SearchSelect,{options:i.map(e=>({label:e,value:e})),value:e.model??"",onValueChange:t=>S(e.id,{model:""===t?null:t}),placeholder:"Select model",emptyText:"No models found",disabled:!g})]}),(0,t.jsxs)("div",{className:"flex gap-2 items-center",children:[(0,t.jsxs)(r.InputGroup,{className:"w-40",children:[(0,t.jsx)(r.InputGroupAddon,{children:(0,t.jsx)(r.InputGroupText,{children:"$"})}),(0,t.jsx)(r.InputGroupInput,{type:"number",step:"any",min:0,value:e.budgetLimit??"",onChange:t=>{let n=t.target.valueAsNumber;S(e.id,{budgetLimit:Number.isNaN(n)?null:n})},placeholder:"Max spend ($)",disabled:!g})]}),(0,t.jsxs)(l.Select,{items:p,value:e.timePeriod,onValueChange:t=>t&&S(e.id,{timePeriod:t}),children:[(0,t.jsx)(l.SelectTrigger,{className:"w-[150px]",disabled:!g,title:w,children:(0,t.jsx)(l.SelectValue,{})}),(0,t.jsx)(l.SelectContent,{children:p.map(e=>(0,t.jsx)(l.SelectItem,{value:e.value,children:e.label},e.value))})]})]}),void 0!==s&&(0,t.jsxs)("div",{className:"text-[11px] text-muted-foreground mt-2 ml-1",children:["Current window spend: $",s,null!==e.budgetLimit&&` of $${e.budgetLimit}`]})]},e.id)}),(0,t.jsxs)(s.Button,{variant:"outline",size:"sm",onClick:C,disabled:!g,title:w,children:[(0,t.jsx)(o.Plus,{className:"w-3 h-3"}),"Add Model Budget"]})]})}e.s(["ModelMaxBudgetEditor",0,v,"ModelMaxBudgetField",0,function({hint:e,...n}){return(0,t.jsxs)(i.Field,{children:[(0,t.jsx)(i.FieldLabel,{children:(0,t.jsx)("span",{title:e,children:"Per-Model Budgets"})}),(0,t.jsx)(v,{...n})]})}])},371455,172372,e=>{"use strict";var t=e.i(843476),n=e.i(912598),i=e.i(109799),s=e.i(845150),r=e.i(542450),l=e.i(182668),o=e.i(519455),a=e.i(257428),d=e.i(204258),u=e.i(776639),c=e.i(793479),h=e.i(967489),p=e.i(624687),m=e.i(746798),v=e.i(204290),f=e.i(929592),g=e.i(463059),b=e.i(359360),x=e.i(952571),y=e.i(879002),j=e.i(271645),C=e.i(653145),S=e.i(663435),E=e.i(355619),w=e.i(417385),_=e.i(602869),N=e.i(237016);function T({isInvitationLinkModalVisible:e,setIsInvitationLinkModalVisible:n,baseUrl:i,invitationLinkData:s,modalType:r="invitation"}){let l=()=>(function({baseUrl:e,invitationId:t,hasUserSetupSso:n,resetPassword:i}){if(!e)return"";let s=new URL(e).pathname,r=s&&"/"!==s?`${s}/ui`:"ui";return n?new URL(r,e).toString():t?new URL(`${r}/onboarding?invitation_id=${t}${i?"&action=reset_password":""}`,e).toString():""})({baseUrl:i,invitationId:s?.id,hasUserSetupSso:s?.has_user_setup_sso??!1,resetPassword:"resetPassword"===r});return(0,t.jsx)(u.Dialog,{open:e,onOpenChange:e=>!e&&void n(!1),children:(0,t.jsxs)(u.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,t.jsx)(u.DialogHeader,{children:(0,t.jsx)(u.DialogTitle,{children:"invitation"===r?"Invitation Link":"Reset Password Link"})}),(0,t.jsx)("p",{className:"text-sm text-foreground",children:"invitation"===r?"Copy and send the generated link to onboard this user to the proxy.":"Copy and send the generated link to the user to reset their password."}),(0,t.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,t.jsx)("p",{className:"text-base",children:"User ID"}),(0,t.jsx)("p",{className:"text-sm",children:s?.user_id})]}),(0,t.jsxs)("div",{className:"flex justify-between pt-5 pb-2",children:[(0,t.jsx)("p",{className:"text-sm",children:"invitation"===r?"Invitation Link":"Reset Password Link"}),(0,t.jsx)("p",{className:"text-sm",children:l()})]}),(0,t.jsx)("div",{className:"flex justify-end mt-5",children:(0,t.jsx)(N.CopyToClipboard,{text:l(),onCopy:()=>w.toast.success("Copied!"),children:(0,t.jsx)(o.Button,{children:"invitation"===r?"Copy invitation link":"Copy password reset link"})})})]})})}e.s(["default",0,T],172372);let k={user_email:void 0,user_role:"internal_user_viewer",team_id:void 0,metadata:void 0,send_invite_email:!0},L={user_email:void 0,user_role:"internal_user_viewer",team_id:void 0,organization_ids:void 0,metadata:void 0,send_invite_email:!0},P=(e,n)=>(0,t.jsxs)(t.Fragment,{children:[e,(0,t.jsxs)(m.Tooltip,{children:[(0,t.jsx)(m.TooltipTrigger,{render:(0,t.jsx)(b.CircleHelp,{className:"size-3.5 shrink-0 cursor-help text-muted-foreground"})}),(0,t.jsx)(m.TooltipContent,{children:n})]})]}),I=()=>(0,t.jsxs)(v.Alert,{variant:"info",className:"mb-4",children:[(0,t.jsx)(x.Info,{}),(0,t.jsx)(f.AlertTitle,{children:"Email invitations"}),(0,t.jsxs)(f.AlertDescription,{children:["New users receive an email invite only when an email integration (SMTP, Resend, or SendGrid) is configured."," ",(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/email",target:"_blank",rel:"noreferrer",children:"Learn how to set up email notifications"})]})]});e.s(["CreateUserButton",0,({userID:e,accessToken:v,possibleUIRoles:f,onUserCreated:b,isEmbedded:x=!1})=>{let N=(0,n.useQueryClient)(),[O,D]=(0,j.useState)(null),M=x?k:L,R=(0,C.useForm)({defaultValues:M}),[A,U]=(0,j.useState)(!1),[$,F]=(0,j.useState)(!1),[B,V]=(0,j.useState)([]),[G,z]=(0,j.useState)(!1),[q,K]=(0,j.useState)(!1),[H,W]=(0,j.useState)(null),[Q,X]=(0,j.useState)(null),{data:Y=[]}=(0,i.useOrganizations)(),J=Y.map(e=>({label:`${e.organization_alias} (${e.organization_id})`,value:e.organization_id??""}));(0,j.useEffect)(()=>{let t=async()=>{try{let t=await (0,_.modelAvailableCall)(v,e,"any"),n=[];for(let e=0;e{try{w.toast.info("Making API Call"),x||U(!0);let n=(e=>{let t=e.models&&0!==e.models.length||"proxy_admin"===e.user_role?e:{...e,models:["no-default-models"]};if(!t.organization_ids)return t;let{organization_ids:n,...i}=t;return{...i,organizations:n}})(((e,t)=>{if(t)return e;let{models:n,...i}=e;return i})(t,G)),i=await (0,_.userCreateCall)(v,null,n);await N.invalidateQueries({queryKey:["userList"]}),F(!0);let s=i.data?.user_id||i.user_id;if(b&&x){b(s),R.reset(M);return}if(O?.SSO_ENABLED){let t;W((t=new Date,{id:"u">typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){let t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)}),user_id:s,is_accepted:!1,accepted_at:null,expires_at:new Date(t.getTime()+6048e5),created_at:t,created_by:e,updated_at:t,updated_by:e,has_user_setup_sso:!0})),K(!0)}else(0,_.invitationCreateCall)(v,s).then(e=>{e.has_user_setup_sso=!1,W(e),K(!0)});w.toast.success("API user Created"),R.reset(M),localStorage.removeItem("userData"+e)}catch(t){let e=t.response?.data?.detail||t?.message||"Error creating the user";w.toast.fromError(e),console.error("Error creating the user:",t)}},ee=Object.entries(f??{}).map(([e,{ui_label:t,description:n}])=>({value:e,label:t,description:n})),et=(0,t.jsx)(l.FormField,{control:R.control,name:"user_email",label:"User Email",children:({ref:e,value:n,...i})=>(0,t.jsx)(c.Input,{...i,ref:e,value:n??""})}),en=(0,t.jsx)(l.FormField,{control:R.control,name:"team_id",label:"Team",description:"If selected, user will be added as a 'user' role to the team.",children:({id:e,value:n,onChange:i})=>(0,t.jsx)(S.default,{id:e,value:n,onChange:i})}),ei=(0,t.jsx)(l.FormField,{control:R.control,name:"metadata",label:"Metadata",children:({ref:e,value:n,...i})=>(0,t.jsx)(p.Textarea,{...i,ref:e,value:n??"",rows:4,placeholder:"Enter metadata as JSON"})}),es=(0,t.jsx)(l.FormField,{control:R.control,name:"send_invite_email",label:"Send invitation email",children:({id:e,value:n,onChange:i,onBlur:s})=>(0,t.jsx)(a.Checkbox,{id:e,checked:n,onCheckedChange:i,onBlur:s})}),er=e=>(0,t.jsx)(l.FormField,{control:R.control,name:"user_role",label:e,children:({id:e,value:n,onChange:i})=>(0,t.jsxs)(h.Select,{items:ee,value:void 0===n||""===n?null:n,onValueChange:e=>i(e??void 0),children:[(0,t.jsx)(h.SelectTrigger,{id:e,className:"w-full",children:(0,t.jsx)(h.SelectValue,{})}),(0,t.jsx)(h.SelectContent,{children:ee.map(e=>(0,t.jsxs)(h.SelectItem,{value:e.value,children:[(0,t.jsx)("span",{children:e.label}),(0,t.jsx)("span",{className:"ml-2 text-xs text-muted-foreground",children:e.description})]},e.value))})]})});return x?(0,t.jsx)(m.TooltipProvider,{children:(0,t.jsxs)("form",{onSubmit:R.handleSubmit(Z),children:[(0,t.jsx)(I,{}),(0,t.jsxs)(r.FieldGroup,{children:[et,er("User Role"),en,ei,es]}),(0,t.jsx)("div",{className:"mt-4 text-right",children:(0,t.jsx)(o.Button,{type:"submit",children:"Create User"})})]})}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(o.Button,{type:"button",onClick:()=>U(!0),children:"+ Invite User"}),(0,t.jsx)(u.Dialog,{open:A,onOpenChange:e=>!e&&void(U(!1),F(!1),R.reset(M)),children:(0,t.jsxs)(u.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,t.jsx)(u.DialogHeader,{children:(0,t.jsx)(u.DialogTitle,{children:"Invite User"})}),(0,t.jsxs)("div",{className:"flex flex-col gap-3",children:[(0,t.jsx)("p",{className:"mb-1 text-sm text-foreground",children:"Create a User who can own keys"}),(0,t.jsx)(I,{})]}),(0,t.jsx)(m.TooltipProvider,{children:(0,t.jsxs)("form",{onSubmit:R.handleSubmit(Z),children:[(0,t.jsxs)(r.FieldGroup,{children:[et,er(P("Global Proxy Role","This role is independent of any team/org specific roles. Configure Team / Organization Admins in the Settings")),en,(0,t.jsx)(l.FormField,{control:R.control,name:"organization_ids",label:"Organization",description:"The user will be added to the selected organization(s).",children:({id:e,value:n,onChange:i})=>(0,t.jsxs)(h.Select,{multiple:!0,items:J,value:n??[],onValueChange:e=>i(0===e.length?void 0:e),children:[(0,t.jsx)(h.SelectTrigger,{id:e,className:"w-full",children:(0,t.jsx)(h.SelectValue,{placeholder:"Select Organization",children:e=>0===e.length?"Select Organization":J.filter(t=>e.includes(t.value)).map(e=>e.label).join(", ")})}),(0,t.jsx)(h.SelectContent,{children:J.map(e=>(0,t.jsx)(h.SelectItem,{value:e.value,children:e.label},e.value))})]})}),ei,es,(0,t.jsxs)(d.Collapsible,{open:G,onOpenChange:z,children:[(0,t.jsxs)(d.CollapsibleTrigger,{className:"flex w-full items-center gap-2 rounded-md border border-border px-3 py-2 text-left text-sm font-semibold text-foreground",children:[(0,t.jsx)(g.ChevronRight,{className:`size-4 transition-transform ${G?"rotate-90":""}`,"aria-hidden":!0}),"Personal Key Creation"]}),(0,t.jsx)(d.CollapsibleContent,{className:"pt-4",children:(0,t.jsx)(l.FormField,{control:R.control,name:"models",label:P("Models","Models user has access to, outside of team scope."),description:"Models user has access to, outside of team scope.",children:({value:e,onChange:n})=>(0,t.jsx)(s.MultiSelect,{options:[{label:"All Proxy Models",value:"all-proxy-models"},{label:"No Default Models",value:"no-default-models"},...B.map(e=>({label:(0,E.getModelDisplayName)(e),value:e}))],value:e??[],onValueChange:n,placeholder:"Select models"})})})]})]}),(0,t.jsx)("div",{className:"mt-4 text-right",children:(0,t.jsxs)(o.Button,{type:"submit",children:[(0,t.jsx)(y.UserPlus,{}),"Invite User"]})})]})})]})}),$&&(0,t.jsx)(T,{isInvitationLinkModalVisible:q,setIsInvitationLinkModalVisible:K,baseUrl:Q||"",invitationLinkData:H})]})}],371455)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0002gr7w0f3nn.js b/litellm/proxy/_experimental/out/_next/static/chunks/0002gr7w0f3nn.js
deleted file mode 100644
index 4a4ec24ea11..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/0002gr7w0f3nn.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,302747,e=>{"use strict";var t=e.i(843476),a=e.i(196631);e.s(["Skeleton",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"skeleton",className:(0,a.cn)("animate-pulse rounded-md bg-muted",e),...r})}])},784774,e=>{"use strict";var t=e.i(843476),a=e.i(271645),r=e.i(196631);let l=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("div",{"data-slot":"table-container",className:"relative w-full overflow-x-auto",children:(0,t.jsx)("table",{ref:l,"data-slot":"table",className:(0,r.cn)("w-full caption-bottom text-sm",e),...a})}));l.displayName="Table";let n=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("thead",{ref:l,"data-slot":"table-header",className:(0,r.cn)("[&_tr]:border-b",e),...a}));n.displayName="TableHeader";let i=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tbody",{ref:l,"data-slot":"table-body",className:(0,r.cn)("[&_tr:last-child]:border-0",e),...a}));i.displayName="TableBody";let s=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tfoot",{ref:l,"data-slot":"table-footer",className:(0,r.cn)("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...a}));s.displayName="TableFooter";let o=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tr",{ref:l,"data-slot":"table-row",className:(0,r.cn)("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",e),...a}));o.displayName="TableRow";let d=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("th",{ref:l,"data-slot":"table-head",className:(0,r.cn)("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));d.displayName="TableHead";let u=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("td",{ref:l,"data-slot":"table-cell",className:(0,r.cn)("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));u.displayName="TableCell",a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("caption",{ref:l,"data-slot":"table-caption",className:(0,r.cn)("mt-4 text-sm text-muted-foreground",e),...a})).displayName="TableCaption",e.s(["Table",0,l,"TableBody",0,i,"TableCell",0,u,"TableFooter",0,s,"TableHead",0,d,"TableHeader",0,n,"TableRow",0,o])},16715,e=>{"use strict";let t=(0,e.i(475254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",0,t],16715)},157153,e=>{"use strict";var t=e.i(271645);let a=t.createContext({disabled:!1});e.s(["useFieldItemContext",0,function(){return t.useContext(a)}])},257428,e=>{"use strict";var t,a=e.i(843476);e.s([],392299),e.i(392299),e.i(247167);var r=e.i(271645),l=e.i(956789),n=e.i(951437),i=e.i(146376),s=e.i(828918),o=e.i(921374),d=e.i(502077),u=e.i(333848);let c=((t={}).checked="data-checked",t.unchecked="data-unchecked",t.indeterminate="data-indeterminate",t.disabled="data-disabled",t.readonly="data-readonly",t.required="data-required",t.valid="data-valid",t.invalid="data-invalid",t.touched="data-touched",t.dirty="data-dirty",t.filled="data-filled",t.focused="data-focused",t);var m=e.i(875812);function f(e){return r.useMemo(()=>({checked:t=>e.indeterminate?{}:t?{[c.checked]:""}:{[c.unchecked]:""},...m.fieldValidityMapping}),[e.indeterminate])}var p=e.i(552245),x=e.i(788015),h=e.i(176782),y=e.i(540886),b=e.i(469690),g=e.i(381104),v=e.i(157153),w=e.i(884708),C=e.i(247778),N=e.i(31421),k=e.i(733332);let j=r.createContext(void 0),M=r.createContext(void 0);var T=e.i(675606),R=e.i(56434),$=e.i(606039);let I=r.forwardRef(function(e,t){let{checked:c,className:m,defaultChecked:I=!1,"aria-labelledby":A,disabled:S=!1,form:K,id:P,indeterminate:F=!1,inputRef:D,name:B,onCheckedChange:_,parent:E=!1,readOnly:q=!1,render:Q,required:H=!1,uncheckedValue:W,value:L,nativeButton:O=!1,style:U,...z}=e,{clearErrors:V}=(0,w.useFormContext)(),{disabled:G,name:J,setDirty:Y,setFilled:Z,setFocused:X,setTouched:ee,state:et,validationMode:ea,validityData:er,validation:el}=(0,b.useFieldRootContext)(),en=(0,v.useFieldItemContext)(),{labelId:ei,controlId:es,registerControlId:eo,getDescriptionProps:ed}=(0,C.useLabelableContext)(),eu=function(e=!0){let t=r.useContext(j);if(void 0===t&&!e)throw Error((0,k.default)(3));return t}(),ec=eu?.parent,em=ec&&eu.allValues,ef=G||en.disabled||eu?.disabled||S,ep=J??B,ex=L??ep,eh=(0,x.useBaseUiId)(),ey=(0,x.useBaseUiId)(),eb=es;em?eb=E?ey:`${ec.id}-${ex}`:P&&(eb=P);let eg={};em&&(E?eg=eu.parent.getParentProps():ex&&(eg=eu.parent.getChildProps(ex)));let{checked:ev=c,indeterminate:ew=F,onCheckedChange:eC,...eN}=eg,ek=eu?.value,ej=eu?.setValue,eM=eu?.defaultValue,eT=r.useRef(null),eR=(0,o.useRefWithInit)(()=>Symbol("checkbox-control")),e$=r.useRef(!1),{getButtonProps:eI,buttonRef:eA}=(0,y.useButton)({disabled:ef,native:O}),eS=eu?.validation??el,[eK,eP]=(0,n.useControlled)({controlled:ex&&ek&&!E?ek.includes(ex):ev,default:ex&&eM&&!E?eM.includes(ex):I,name:"Checkbox",state:"checked"}),eF=em?!!ev:eK,eD=em&&ew||F;(0,i.useIsoLayoutEffect)(()=>{eo!==l.NOOP&&(e$.current=!0,eo(eR.current,eb))},[eb,eo,eR]),r.useEffect(()=>{let e=eR.current;return()=>{e$.current&&eo!==l.NOOP&&(e$.current=!1,eo(e,void 0))}},[eo,eR]),(0,g.useRegisterFieldControl)(eT,eh,eK,void 0,!eu&&!ef,B);let eB=r.useRef(null),e_=(0,s.useMergedRefs)(D,eB,eS.inputRef,eS.registerInput),eE=(0,N.useAriaLabelledBy)(A,ei,eB,!O,eb??void 0);(0,i.useIsoLayoutEffect)(()=>{eB.current&&(eB.current.indeterminate=eD,eK&&Z(!0))},[eK,eD,Z]),(0,$.useValueChanged)(eK,()=>{eu||(V(ep),Z(eK),Y(eK!==er.initialValue),eS.change(eK))});let eq=(0,h.mergeProps)({checked:eK,disabled:ef,form:K,name:E?void 0:ep,id:O?void 0:eb??void 0,required:H,ref:e_,style:ep?d.visuallyHiddenInput:d.visuallyHidden,tabIndex:-1,type:"checkbox","aria-hidden":!0,onChange(e){if(e.nativeEvent.defaultPrevented)return;if(q)return void e.preventDefault();let t=e.currentTarget.checked,a=(0,T.createChangeEventDetails)(R.REASONS.none,e.nativeEvent);_?.(t,a),a.isCanceled||(eC?.(t,a),!a.isCanceled&&(eP(t),ex&&ek&&ej&&!E&&!em&&ej(t?[...ek,ex]:ek.filter(e=>e!==ex),a)))},onFocus(){eT.current?.focus()}},void 0!==L?{value:(eu?eK&&L:L)||""}:l.EMPTY_OBJECT,ed,e=>eS.getValidationProps(ef,e));r.useEffect(()=>{if(!ec||!ex)return;let e=ec.disabledStatesRef.current;return e.set(ex,ef),()=>{e.delete(ex)}},[ec,ef,ex]);let eQ=r.useMemo(()=>({...et,checked:eF,disabled:ef,readOnly:q,required:H,indeterminate:eD}),[et,eF,ef,q,H,eD]),eH=f(eQ),eW=(0,p.useRenderElement)("span",e,{state:eQ,ref:[eA,eT,t,eu?.registerControlRef],props:[{id:O?eb??void 0:eh,role:"checkbox","aria-checked":eD?"mixed":eF,"aria-readonly":q||void 0,"aria-required":H||void 0,"aria-labelledby":eE,"data-parent":E?"":void 0,onFocus(){ef||X(!0)},onBlur(){let e=eB.current;e&&(ee(!0),X(!1),"onBlur"===ea&&eS.commit(eu?ek:e.checked))},onKeyDown(e){if("Enter"!==e.key||(e.preventBaseUIHandler(),e.defaultPrevented))return;let t=eB.current?.form??null,a=e.currentTarget,r=e.nativeEvent,l=e.preventDefault,n=r.preventDefault,i=!1;e.preventDefault=()=>{i=!0,l.call(e)},r.preventDefault=()=>{i=!0,n.call(r)},n.call(r),(0,u.ownerWindow)(a).queueMicrotask(()=>{e.preventDefault=l,r.preventDefault=n,i||(function(e){if(!e)return null;for(let t of e.elements){let e=t.tagName;if(("BUTTON"===e||"INPUT"===e)&&"submit"===t.type)return t}return null})(t)?.click()})},onClick(e){if(q||ef)return;e.preventDefault();let t=eB.current;t&&t.dispatchEvent(new((0,u.ownerWindow)(t)).PointerEvent("click",{bubbles:!0,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,altKey:e.altKey,metaKey:e.metaKey}))}},z,eN,eI,ed,e=>eS.getValidationProps(ef,e)],stateAttributesMapping:eH});return(0,a.jsxs)(M.Provider,{value:eQ,children:[eW,!eK&&!eu&&ep&&!E&&void 0!==W&&(0,a.jsx)("input",{type:"hidden",form:K,name:ep,value:W,disabled:ef}),(0,a.jsx)("input",{...eq,suppressHydrationWarning:!0})]})});var A=e.i(137584),S=e.i(223910),K=e.i(209407);let P=r.forwardRef(function(e,t){let{render:a,className:l,style:n,keepMounted:i=!1,...s}=e,o=function(){let e=r.useContext(M);if(void 0===e)throw Error((0,k.default)(14));return e}(),d=o.checked||o.indeterminate,{mounted:u,transitionStatus:c,setMounted:x}=(0,S.useTransitionStatus)(d),h=r.useRef(null),y={...o,transitionStatus:c};(0,A.useOpenChangeComplete)({open:d,ref:h,onComplete(){d||x(!1)}});let b={...f(o),...K.transitionStatusMapping,...m.fieldValidityMapping},g=(0,p.useRenderElement)("span",e,{ref:[t,h],state:y,stateAttributesMapping:b,props:s});return i||u?g:null});e.s(["Indicator",0,P,"Root",0,I],26749);var F=e.i(26749),F=F,D=e.i(196631),B=e.i(678784);e.s(["Checkbox",0,function({className:e,...t}){return(0,a.jsx)(F.Root,{"data-slot":"checkbox",className:(0,D.cn)("peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",e),...t,children:(0,a.jsx)(F.Indicator,{"data-slot":"checkbox-indicator",className:"grid place-content-center text-current transition-none [&>svg]:size-3.5",children:(0,a.jsx)(B.CheckIcon,{})})})}],257428)},500330,e=>{"use strict";var t=e.i(417385);let a=(e,t=0,a=!1,r=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!r)return"-";let l={minimumFractionDigits:t,maximumFractionDigits:t};if(!a)return e.toLocaleString("en-US",l);let n=e<0?"-":"",i=Math.abs(e),s=i,o="";return i>=1e6?(s=i/1e6,o="M"):i>=1e3&&(s=i/1e3,o="K"),`${n}${s.toLocaleString("en-US",l)}${o}`},r=async(e,a="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return l(e,a);try{return await navigator.clipboard.writeText(e),t.toast.success(a),!0}catch(t){return console.error("Clipboard API failed: ",t),l(e,a)}},l=(e,a)=>{try{let r=document.createElement("textarea");r.value=e,r.style.position="fixed",r.style.left="-999999px",r.style.top="-999999px",r.setAttribute("readonly",""),document.body.appendChild(r),r.focus(),r.select();let l=document.execCommand("copy");if(document.body.removeChild(r),l)return t.toast.success(a),!0;throw Error("execCommand failed")}catch(e){return t.toast.fromError("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,r,"formatNumberWithCommas",0,a,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let r=a(e,t,!1,!1);if(0===Number(r.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${r}`}])},581070,e=>{"use strict";var t=e.i(843476),a=e.i(746798);e.s(["CellTooltip",0,function({content:e,trigger:r}){return(0,t.jsx)(a.TooltipProvider,{delay:300,children:(0,t.jsxs)(a.Tooltip,{children:[(0,t.jsx)(a.TooltipTrigger,{render:r}),(0,t.jsx)(a.TooltipContent,{children:e})]})})}])},67488,e=>{"use strict";var t=e.i(843476),a=e.i(463059),r=e.i(618566),l=e.i(196631);function n(e){let t=(0,r.useRouter)();return a=>{a.metaKey||a.ctrlKey||a.shiftKey||1===a.button||(a.preventDefault(),t.push(e))}}e.s(["EntityLink",0,function({href:e,className:r,children:i}){let s=n(e);return(0,t.jsxs)("a",{href:e,onClick:s,className:(0,l.cn)("group inline-flex min-w-0 max-w-full items-center gap-0.5 font-semibold underline-offset-4 hover:underline",r),children:[(0,t.jsx)("span",{className:"min-w-0 truncate",children:i}),(0,t.jsx)(a.ChevronRight,{className:"size-3.5 shrink-0 text-muted-foreground transition-colors group-hover:text-foreground"})]})},"useEntityLinkClick",0,n])},112179,e=>{"use strict";var t=e.i(843476),a=e.i(67488),r=e.i(487486),l=e.i(196631),n=e.i(581070);let i={success:"border-success/20 bg-success/10 text-success",error:"border-destructive/20 bg-destructive/10 text-destructive",warning:"border-warning/20 bg-warning/10 text-warning",neutral:"border-border bg-muted text-muted-foreground",info:"border-info/20 bg-info/10 text-info"};function s({href:e,dataTestId:n,className:i,children:o}){let d=(0,a.useEntityLinkClick)(e);return(0,t.jsx)(r.Badge,{variant:"outline","data-testid":n,className:(0,l.cn)("cursor-pointer hover:underline",i),render:(0,t.jsx)("a",{href:e,onClick:d}),children:o})}e.s(["StatusBadge",0,function({tone:e,label:a,tooltip:o,dataTestId:d,className:u,href:c}){let m=(0,l.cn)("whitespace-nowrap font-normal",i[e],u),f=c?(0,t.jsx)(s,{href:c,dataTestId:d,className:m,children:a}):(0,t.jsx)(r.Badge,{variant:"outline","data-testid":d,className:m,children:a});return o?(0,t.jsx)(n.CellTooltip,{content:o,trigger:f}):f}])},625901,e=>{"use strict";var t=e.i(266027),a=e.i(621482),r=e.i(912598),l=e.i(243652),n=e.i(602869),i=e.i(135214);let s=(0,l.createQueryKeys)("models"),o=(0,l.createQueryKeys)("modelHub"),d=(0,l.createQueryKeys)("allProxyModels");(0,l.createQueryKeys)("selectedTeamModels");let u=(0,l.createQueryKeys)("infiniteModels"),c=(0,l.createQueryKeys)("userModels"),m=new Set,f=e=>!!e?.litellm_params?.model?.startsWith("auto_router/"),p=e=>new Set(e.filter(f).map(e=>e.model_name).filter(e=>!!e)),x=e=>e.filter(f),h=e=>{let t=p(e);return new Set(e.map(e=>e.model_name).filter(e=>!!e).filter(e=>!t.has(e)))},y=async(e,t,a)=>{let r=await (0,n.modelInfoCall)(e,t,a,1,1e3),l=r?.total_pages??1;return[r,...await Promise.all(Array.from({length:Math.max(0,l-1)},(r,l)=>(0,n.modelInfoCall)(e,t,a,l+2,1e3)))].flatMap(e=>e?.data??[])},b=(e,t)=>s.list({filters:{scope:"autoRouters",...e&&{userId:e},...t&&{userRole:t}}});e.s(["autoRouterListKey",0,b,"fetchAllModelDeployments",0,y,"useAllProxyModels",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:d.list({}),queryFn:async()=>await (0,n.modelAvailableCall)(e,a,r,!0,null,!0,!1,"expand"),enabled:!!(e&&a&&r)})},"useAutoRouterModelGroups",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)(),{data:l}=(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await y(e,a,r),enabled:!!(e&&a&&r),select:p});return l??m},"useAutoRouters",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await y(e,a,r),enabled:!!(e&&a&&r),select:x})},"useInfiniteModelInfo",0,(e=50,t)=>{let{accessToken:r,userId:l,userRole:s}=(0,i.default)();return(0,a.useInfiniteQuery)({queryKey:u.list({filters:{...l&&{userId:l},...s&&{userRole:s},size:e,...t&&{search:t}}}),queryFn:async({pageParam:a})=>await (0,n.modelInfoCall)(r,l,s,a,e,t),initialPageParam:1,getNextPageParam:e=>{if(e.current_page{let e=(0,r.useQueryClient)();return async()=>{await e.invalidateQueries({queryKey:s.lists()})}},"useModelHub",0,()=>{let{accessToken:e}=(0,i.default)();return(0,t.useQuery)({queryKey:o.list({}),queryFn:async()=>await (0,n.modelHubCall)(e),enabled:!!e})},"useModelsInfo",0,(e=1,a=50,r,l,o,d,u,c=!1,m)=>{let{accessToken:f,userId:p,userRole:x}=(0,i.default)();return(0,t.useQuery)({queryKey:s.list({filters:{...p&&{userId:p},...x&&{userRole:x},page:e,size:a,...r&&{search:r},...m&&{modelName:m},...l&&{modelId:l},...o&&{teamId:o},...d&&{sortBy:d},...u&&{sortOrder:u},...c&&{excludeAutoRouters:"true"}}}),queryFn:async()=>await (0,n.modelInfoCall)(f,p,x,e,a,r,l,o,d,u,c,m),enabled:!!(f&&p&&x)})},"usePlainModelGroups",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)(),{data:l}=(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await y(e,a,r),enabled:!!(e&&a&&r),select:h});return l??m},"useUserModels",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:c.list({}),queryFn:async()=>(await (0,n.modelAvailableCall)(e,a,r)).data.map(e=>e.id),enabled:!!(e&&a&&r)})}])},199931,e=>{"use strict";let t=(0,e.i(475254).default)("waypoints",[["circle",{cx:"12",cy:"4.5",r:"2.5",key:"r5ysbb"}],["path",{d:"m10.2 6.3-3.9 3.9",key:"1nzqf6"}],["circle",{cx:"4.5",cy:"12",r:"2.5",key:"jydg6v"}],["path",{d:"M7 12h10",key:"b7w52i"}],["circle",{cx:"19.5",cy:"12",r:"2.5",key:"1piiel"}],["path",{d:"m13.8 17.7 3.9-3.9",key:"1wyg1y"}],["circle",{cx:"12",cy:"19.5",r:"2.5",key:"13o1pw"}]]);e.s(["Waypoints",0,t],199931)},622826,548151,200208,399536,997422,146512,547227,964471,92982,630500,e=>{"use strict";var t=e.i(843476),a=e.i(271645),r=e.i(199931),l=e.i(625901),n=e.i(487486),i=e.i(196631);let s=new Set,o=(0,a.createContext)(s);function d(e){let t=(0,a.useContext)(o);return!!e&&t.has(e)}e.s(["AutoRouterIcon",0,function({size:e=12,className:a}){return(0,t.jsx)(r.Waypoints,{size:e,className:a,"aria-hidden":!0})},"AutoRouterModelGroupsProvider",0,function({children:e}){let a=(0,l.useAutoRouterModelGroups)();return(0,t.jsx)(o.Provider,{value:a,children:e})},"AutoRouterTag",0,function({modelGroup:e,className:a}){return d(e)?(0,t.jsxs)(n.Badge,{variant:"secondary",title:`Routed by auto-router "${e}"`,className:(0,i.cn)("gap-1.5 px-2.5 py-1 text-sm font-normal text-foreground",a),children:[(0,t.jsx)(r.Waypoints,{"aria-hidden":!0}),e]}):null},"useIsAutoRoutedModelGroup",0,d],548151);var u=e.i(581070);let c=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],m=e=>String(e).padStart(2,"0"),f=(e,t)=>"date"===t?`${c[e.getMonth()]} ${e.getDate()}, ${e.getFullYear()}`:`${c[e.getMonth()]} ${e.getDate()}, ${m(e.getHours())}:${m(e.getMinutes())}:${m(e.getSeconds())}`;e.s(["DateCell",0,function({value:e,precision:a="datetime",fallback:r="-"}){let l,n,i,s=e?new Date(e):null;return!s||Number.isNaN(s.getTime())?(0,t.jsx)("span",{className:"text-muted-foreground",children:r}):(0,t.jsx)(u.CellTooltip,{content:(l=Intl.DateTimeFormat().resolvedOptions().timeZone,n=`${c[s.getMonth()]} ${s.getDate()}, ${s.getFullYear()}`,i=`${m(s.getHours())}:${m(s.getMinutes())}:${m(s.getSeconds())}`,`${n}, ${i} (${l})`),trigger:(0,t.jsx)("span",{className:"whitespace-nowrap",children:f(s,a)})})},"formatCellDate",0,f],200208);var p=e.i(174886),x=e.i(500330);let h={pill:{base:"font-mono text-xs font-normal px-2 py-0.5 rounded-md text-left bg-info/10 text-info",clickable:"hover:bg-info/15 cursor-pointer"},plain:{base:"font-mono text-xs text-left",clickable:"hover:text-info cursor-pointer"}};e.s(["IdCell",0,function({value:e,variant:a="pill",onClick:r,copyable:l=!1,truncate:n=!0,fallback:s="-",tooltip:o,disabled:d=!1,dataTestId:c,className:m}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:s});let f=!!r&&!d,y=(0,i.cn)(h[a].base,f&&h[a].clickable,n&&"block max-w-[15ch] truncate",d&&"opacity-50",m),b=f?(0,t.jsx)("button",{type:"button",className:y,"data-testid":c,onClick:()=>r(e),children:e}):(0,t.jsx)("span",{className:y,"data-testid":c,children:e}),g=(0,t.jsx)(u.CellTooltip,{content:o??e,trigger:b});return l?(0,t.jsxs)("span",{className:"inline-flex max-w-full items-center gap-1",children:[g,(0,t.jsx)("button",{type:"button","aria-label":"Copy ID",className:"shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",onClick:t=>{t.stopPropagation(),(0,x.copyToClipboard)(e)},children:(0,t.jsx)(p.Copy,{className:"size-3"})})]}):g}],399536);var y=e.i(463059),b=e.i(67488);let g="group -mx-2 flex w-[calc(100%+1rem)] cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-left transition-colors hover:bg-muted",v=()=>(0,t.jsx)(y.ChevronRight,{className:"ml-auto size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"});function w({href:e,className:a,body:r}){let l=(0,b.useEntityLinkClick)(e);return(0,t.jsxs)("a",{href:e,onClick:l,className:(0,i.cn)(g,a),children:[r,(0,t.jsx)(v,{})]})}e.s(["IdentityCell",0,function({title:e,subtitle:a,badge:r,onClick:l,href:n,className:s,titleClassName:o}){let d=(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[(0,t.jsx)("span",{className:(0,i.cn)("truncate text-sm font-medium text-foreground",o),children:e}),(null!=a&&""!==a||null!=r)&&(0,t.jsxs)("span",{className:"flex min-w-0 items-center gap-2",children:[null!=a&&""!==a&&(0,t.jsx)("span",{className:"truncate font-mono text-xs text-muted-foreground",children:a}),r]})]});return null!=n?(0,t.jsx)(w,{href:n,className:s,body:d}):null!=l?(0,t.jsxs)("button",{type:"button",onClick:l,className:(0,i.cn)(g,s),children:[d,(0,t.jsx)(v,{})]}):(0,t.jsx)("div",{className:(0,i.cn)("min-w-0",s),children:d})}],997422);let C={hasModelAccess:!1,label:"Management"},N={hasModelAccess:!1,label:"Read-only"},k={hasModelAccess:!1,label:"SCIM"},j={hasModelAccess:!0,label:null},M=e=>e.startsWith("/scim"),T=(e,t)=>1===e.length&&e[0]===t,R=(e,t)=>"management"===t?C:"read_only"===t?N:Array.isArray(e)&&0!==e.length?e.every(M)?k:T(e,"management_routes")?C:T(e,"info_routes")?N:j:j;e.s(["deriveKeyModelScope",0,R],146512);var $=e.i(355619);let I="all-proxy-models",A=e=>{if(e===I)return"All Proxy Models";let t=(0,$.getModelDisplayName)(e);return t.length>30?`${t.slice(0,30)}...`:t};e.s(["ModelsCell",0,function({models:e,maxVisible:a=3,allowedRoutes:r,keyType:l}){if(!Array.isArray(e)||0===e.length){let e=R(r,l);return e.hasModelAccess?(0,t.jsx)(n.Badge,{variant:"secondary",children:"All Proxy Models"}):(0,t.jsx)(u.CellTooltip,{content:`Scoped to ${e.label} routes; this key cannot call any models`,trigger:(0,t.jsx)(n.Badge,{variant:"secondary",className:"cursor-default",children:"No model access"})})}let i=e.slice(0,a),s=e.slice(a);return(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-1",children:[i.map((e,a)=>(0,t.jsx)(n.Badge,{variant:e===I?"secondary":"outline",children:A(e)},a)),s.length>0&&(0,t.jsx)(u.CellTooltip,{content:(0,t.jsx)("div",{className:"flex max-w-[280px] flex-col gap-0.5",children:s.map((e,a)=>(0,t.jsx)("span",{children:A(e)},a))}),trigger:(0,t.jsxs)(n.Badge,{variant:"outline",className:"cursor-default",children:["+",s.length," more"]})})]})}],547227);let S="block w-full whitespace-nowrap text-right tabular-nums text-muted-foreground";e.s(["MoneyCell",0,function({value:e,decimals:a=4,emptyText:r="-",showZero:l=!1}){if(null==e||!Number.isFinite(e))return(0,t.jsx)("span",{className:S,children:r});if(0===e&&!l)return(0,t.jsx)("span",{className:S,children:"-"});let n=0===e?`$${(0,x.formatNumberWithCommas)(0,a,!1,!0)}`:(0,x.getSpendString)(e,a);return(0,t.jsx)("span",{"data-slot":"money-cell",className:"block w-full whitespace-nowrap text-right tabular-nums",children:n})}],964471);var K=e.i(746798);function P({gates:e}){return 0===e.length?null:(0,t.jsx)(K.SimpleTooltip,{content:(0,t.jsxs)("div",{"data-testid":"inherited-budget-hint",className:"flex flex-col gap-1",children:[(0,t.jsx)("span",{children:"This key has no budget of its own, but its spend still counts toward:"}),e.map(e=>(0,t.jsx)("span",{children:`${e.scope} ${e.alias}: $${(0,x.formatNumberWithCommas)(e.maxBudget,2)}${e.budgetDuration?` / ${e.budgetDuration}`:""}`},e.scope))]})})}e.s(["InheritedBudgetHint",0,P,"inheritedBudgetGates",0,(e,t)=>{let a;return[e&&null!=e.max_budget?{scope:"Team",alias:e.team_alias||e.team_id,maxBudget:e.max_budget,budgetDuration:e.budget_duration??null}:null,(a=t?.litellm_budget_table,t&&a?.max_budget!=null?{scope:"Organization",alias:t.organization_alias||t.organization_id,maxBudget:a.max_budget,budgetDuration:a.budget_duration??null}:null)].filter(e=>null!==e)}],92982);var F=e.i(936557);e.s(["SpendBudgetCell",0,function({spend:e,maxBudget:a,inheritedGates:r=[],spendDecimals:l=4,budgetDecimals:n=0}){let i="number"!=typeof e||Number.isNaN(e)?0:e,s=a??null,o="number"==typeof s&&s>0,d=o?i/s*100:0,u=i>0?(0,x.getSpendString)(i,l):"$0.00",c=null===s?"· Unlimited":`of $${(0,x.formatNumberWithCommas)(s,n)}`;return(0,t.jsxs)("div",{className:"flex min-w-[130px] flex-col gap-1",children:[(0,t.jsxs)("div",{className:"whitespace-nowrap text-xs",children:[(0,t.jsx)("span",{className:"font-medium tabular-nums text-foreground",children:u})," ",(0,t.jsx)("span",{className:"text-muted-foreground",children:c}),null===s&&(0,t.jsx)(P,{gates:r})]}),o&&(0,t.jsx)(F.Meter,{value:i,max:s,"aria-valuetext":`${u} of $${(0,x.formatNumberWithCommas)(s,n)}`,children:(0,t.jsx)(F.MeterTrack,{children:(0,t.jsx)(F.MeterIndicator,{tone:d>100?"over":d>=80?"warning":"default"})})})]})}],630500),e.i(112179),e.s([],622826)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/00dvxqp6f0f6s.js b/litellm/proxy/_experimental/out/_next/static/chunks/00dvxqp6f0f6s.js
deleted file mode 100644
index 8bb8b665ff4..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/00dvxqp6f0f6s.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,302747,e=>{"use strict";var t=e.i(843476),a=e.i(196631);e.s(["Skeleton",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"skeleton",className:(0,a.cn)("animate-pulse rounded-md bg-muted",e),...r})}])},784774,e=>{"use strict";var t=e.i(843476),a=e.i(271645),r=e.i(196631);let l=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("div",{"data-slot":"table-container",className:"relative w-full overflow-x-auto",children:(0,t.jsx)("table",{ref:l,"data-slot":"table",className:(0,r.cn)("w-full caption-bottom text-sm",e),...a})}));l.displayName="Table";let n=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("thead",{ref:l,"data-slot":"table-header",className:(0,r.cn)("[&_tr]:border-b",e),...a}));n.displayName="TableHeader";let i=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tbody",{ref:l,"data-slot":"table-body",className:(0,r.cn)("[&_tr:last-child]:border-0",e),...a}));i.displayName="TableBody";let s=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tfoot",{ref:l,"data-slot":"table-footer",className:(0,r.cn)("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...a}));s.displayName="TableFooter";let o=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tr",{ref:l,"data-slot":"table-row",className:(0,r.cn)("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",e),...a}));o.displayName="TableRow";let d=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("th",{ref:l,"data-slot":"table-head",className:(0,r.cn)("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));d.displayName="TableHead";let u=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("td",{ref:l,"data-slot":"table-cell",className:(0,r.cn)("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));u.displayName="TableCell",a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("caption",{ref:l,"data-slot":"table-caption",className:(0,r.cn)("mt-4 text-sm text-muted-foreground",e),...a})).displayName="TableCaption",e.s(["Table",0,l,"TableBody",0,i,"TableCell",0,u,"TableFooter",0,s,"TableHead",0,d,"TableHeader",0,n,"TableRow",0,o])},16715,e=>{"use strict";let t=(0,e.i(475254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",0,t],16715)},157153,e=>{"use strict";var t=e.i(271645);let a=t.createContext({disabled:!1});e.s(["useFieldItemContext",0,function(){return t.useContext(a)}])},257428,e=>{"use strict";var t,a=e.i(843476);e.s([],392299),e.i(392299),e.i(247167);var r=e.i(271645),l=e.i(956789),n=e.i(951437),i=e.i(146376),s=e.i(828918),o=e.i(921374),d=e.i(502077),u=e.i(333848);let c=((t={}).checked="data-checked",t.unchecked="data-unchecked",t.indeterminate="data-indeterminate",t.disabled="data-disabled",t.readonly="data-readonly",t.required="data-required",t.valid="data-valid",t.invalid="data-invalid",t.touched="data-touched",t.dirty="data-dirty",t.filled="data-filled",t.focused="data-focused",t);var m=e.i(875812);function f(e){return r.useMemo(()=>({checked:t=>e.indeterminate?{}:t?{[c.checked]:""}:{[c.unchecked]:""},...m.fieldValidityMapping}),[e.indeterminate])}var p=e.i(552245),x=e.i(788015),h=e.i(176782),y=e.i(540886),b=e.i(469690),g=e.i(381104),v=e.i(157153),w=e.i(884708),C=e.i(247778),N=e.i(31421),k=e.i(733332);let j=r.createContext(void 0),M=r.createContext(void 0);var T=e.i(675606),R=e.i(56434),$=e.i(606039);let I=r.forwardRef(function(e,t){let{checked:c,className:m,defaultChecked:I=!1,"aria-labelledby":A,disabled:S=!1,form:K,id:P,indeterminate:F=!1,inputRef:D,name:B,onCheckedChange:_,parent:E=!1,readOnly:q=!1,render:Q,required:H=!1,uncheckedValue:W,value:L,nativeButton:O=!1,style:U,...z}=e,{clearErrors:V}=(0,w.useFormContext)(),{disabled:G,name:J,setDirty:Y,setFilled:Z,setFocused:X,setTouched:ee,state:et,validationMode:ea,validityData:er,validation:el}=(0,b.useFieldRootContext)(),en=(0,v.useFieldItemContext)(),{labelId:ei,controlId:es,registerControlId:eo,getDescriptionProps:ed}=(0,C.useLabelableContext)(),eu=function(e=!0){let t=r.useContext(j);if(void 0===t&&!e)throw Error((0,k.default)(3));return t}(),ec=eu?.parent,em=ec&&eu.allValues,ef=G||en.disabled||eu?.disabled||S,ep=J??B,ex=L??ep,eh=(0,x.useBaseUiId)(),ey=(0,x.useBaseUiId)(),eb=es;em?eb=E?ey:`${ec.id}-${ex}`:P&&(eb=P);let eg={};em&&(E?eg=eu.parent.getParentProps():ex&&(eg=eu.parent.getChildProps(ex)));let{checked:ev=c,indeterminate:ew=F,onCheckedChange:eC,...eN}=eg,ek=eu?.value,ej=eu?.setValue,eM=eu?.defaultValue,eT=r.useRef(null),eR=(0,o.useRefWithInit)(()=>Symbol("checkbox-control")),e$=r.useRef(!1),{getButtonProps:eI,buttonRef:eA}=(0,y.useButton)({disabled:ef,native:O}),eS=eu?.validation??el,[eK,eP]=(0,n.useControlled)({controlled:ex&&ek&&!E?ek.includes(ex):ev,default:ex&&eM&&!E?eM.includes(ex):I,name:"Checkbox",state:"checked"}),eF=em?!!ev:eK,eD=em&&ew||F;(0,i.useIsoLayoutEffect)(()=>{eo!==l.NOOP&&(e$.current=!0,eo(eR.current,eb))},[eb,eo,eR]),r.useEffect(()=>{let e=eR.current;return()=>{e$.current&&eo!==l.NOOP&&(e$.current=!1,eo(e,void 0))}},[eo,eR]),(0,g.useRegisterFieldControl)(eT,eh,eK,void 0,!eu&&!ef,B);let eB=r.useRef(null),e_=(0,s.useMergedRefs)(D,eB,eS.inputRef,eS.registerInput),eE=(0,N.useAriaLabelledBy)(A,ei,eB,!O,eb??void 0);(0,i.useIsoLayoutEffect)(()=>{eB.current&&(eB.current.indeterminate=eD,eK&&Z(!0))},[eK,eD,Z]),(0,$.useValueChanged)(eK,()=>{eu||(V(ep),Z(eK),Y(eK!==er.initialValue),eS.change(eK))});let eq=(0,h.mergeProps)({checked:eK,disabled:ef,form:K,name:E?void 0:ep,id:O?void 0:eb??void 0,required:H,ref:e_,style:ep?d.visuallyHiddenInput:d.visuallyHidden,tabIndex:-1,type:"checkbox","aria-hidden":!0,onChange(e){if(e.nativeEvent.defaultPrevented)return;if(q)return void e.preventDefault();let t=e.currentTarget.checked,a=(0,T.createChangeEventDetails)(R.REASONS.none,e.nativeEvent);_?.(t,a),a.isCanceled||(eC?.(t,a),!a.isCanceled&&(eP(t),ex&&ek&&ej&&!E&&!em&&ej(t?[...ek,ex]:ek.filter(e=>e!==ex),a)))},onFocus(){eT.current?.focus()}},void 0!==L?{value:(eu?eK&&L:L)||""}:l.EMPTY_OBJECT,ed,e=>eS.getValidationProps(ef,e));r.useEffect(()=>{if(!ec||!ex)return;let e=ec.disabledStatesRef.current;return e.set(ex,ef),()=>{e.delete(ex)}},[ec,ef,ex]);let eQ=r.useMemo(()=>({...et,checked:eF,disabled:ef,readOnly:q,required:H,indeterminate:eD}),[et,eF,ef,q,H,eD]),eH=f(eQ),eW=(0,p.useRenderElement)("span",e,{state:eQ,ref:[eA,eT,t,eu?.registerControlRef],props:[{id:O?eb??void 0:eh,role:"checkbox","aria-checked":eD?"mixed":eF,"aria-readonly":q||void 0,"aria-required":H||void 0,"aria-labelledby":eE,"data-parent":E?"":void 0,onFocus(){ef||X(!0)},onBlur(){let e=eB.current;e&&(ee(!0),X(!1),"onBlur"===ea&&eS.commit(eu?ek:e.checked))},onKeyDown(e){if("Enter"!==e.key||(e.preventBaseUIHandler(),e.defaultPrevented))return;let t=eB.current?.form??null,a=e.currentTarget,r=e.nativeEvent,l=e.preventDefault,n=r.preventDefault,i=!1;e.preventDefault=()=>{i=!0,l.call(e)},r.preventDefault=()=>{i=!0,n.call(r)},n.call(r),(0,u.ownerWindow)(a).queueMicrotask(()=>{e.preventDefault=l,r.preventDefault=n,i||(function(e){if(!e)return null;for(let t of e.elements){let e=t.tagName;if(("BUTTON"===e||"INPUT"===e)&&"submit"===t.type)return t}return null})(t)?.click()})},onClick(e){if(q||ef)return;e.preventDefault();let t=eB.current;t&&t.dispatchEvent(new((0,u.ownerWindow)(t)).PointerEvent("click",{bubbles:!0,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,altKey:e.altKey,metaKey:e.metaKey}))}},z,eN,eI,ed,e=>eS.getValidationProps(ef,e)],stateAttributesMapping:eH});return(0,a.jsxs)(M.Provider,{value:eQ,children:[eW,!eK&&!eu&&ep&&!E&&void 0!==W&&(0,a.jsx)("input",{type:"hidden",form:K,name:ep,value:W,disabled:ef}),(0,a.jsx)("input",{...eq,suppressHydrationWarning:!0})]})});var A=e.i(137584),S=e.i(223910),K=e.i(209407);let P=r.forwardRef(function(e,t){let{render:a,className:l,style:n,keepMounted:i=!1,...s}=e,o=function(){let e=r.useContext(M);if(void 0===e)throw Error((0,k.default)(14));return e}(),d=o.checked||o.indeterminate,{mounted:u,transitionStatus:c,setMounted:x}=(0,S.useTransitionStatus)(d),h=r.useRef(null),y={...o,transitionStatus:c};(0,A.useOpenChangeComplete)({open:d,ref:h,onComplete(){d||x(!1)}});let b={...f(o),...K.transitionStatusMapping,...m.fieldValidityMapping},g=(0,p.useRenderElement)("span",e,{ref:[t,h],state:y,stateAttributesMapping:b,props:s});return i||u?g:null});e.s(["Indicator",0,P,"Root",0,I],26749);var F=e.i(26749),F=F,D=e.i(196631),B=e.i(678784);e.s(["Checkbox",0,function({className:e,...t}){return(0,a.jsx)(F.Root,{"data-slot":"checkbox",className:(0,D.cn)("peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",e),...t,children:(0,a.jsx)(F.Indicator,{"data-slot":"checkbox-indicator",className:"grid place-content-center text-current transition-none [&>svg]:size-3.5",children:(0,a.jsx)(B.CheckIcon,{})})})}],257428)},500330,e=>{"use strict";var t=e.i(417385);let a=(e,t=0,a=!1,r=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!r)return"-";let l={minimumFractionDigits:t,maximumFractionDigits:t};if(!a)return e.toLocaleString("en-US",l);let n=e<0?"-":"",i=Math.abs(e),s=i,o="";return i>=1e6?(s=i/1e6,o="M"):i>=1e3&&(s=i/1e3,o="K"),`${n}${s.toLocaleString("en-US",l)}${o}`},r=async(e,a="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return l(e,a);try{return await navigator.clipboard.writeText(e),t.toast.success(a),!0}catch(t){return console.error("Clipboard API failed: ",t),l(e,a)}},l=(e,a)=>{try{let r=document.createElement("textarea");r.value=e,r.style.position="fixed",r.style.left="-999999px",r.style.top="-999999px",r.setAttribute("readonly",""),document.body.appendChild(r),r.focus(),r.select();let l=document.execCommand("copy");if(document.body.removeChild(r),l)return t.toast.success(a),!0;throw Error("execCommand failed")}catch(e){return t.toast.fromError("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,r,"formatNumberWithCommas",0,a,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let r=a(e,t,!1,!1);if(0===Number(r.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${r}`}])},581070,e=>{"use strict";var t=e.i(843476),a=e.i(746798);e.s(["CellTooltip",0,function({content:e,trigger:r}){return(0,t.jsx)(a.TooltipProvider,{delay:300,children:(0,t.jsxs)(a.Tooltip,{children:[(0,t.jsx)(a.TooltipTrigger,{render:r}),(0,t.jsx)(a.TooltipContent,{children:e})]})})}])},67488,e=>{"use strict";var t=e.i(843476),a=e.i(463059),r=e.i(618566),l=e.i(196631);function n(e){let t=(0,r.useRouter)();return a=>{a.metaKey||a.ctrlKey||a.shiftKey||1===a.button||(a.preventDefault(),t.push(e))}}e.s(["EntityLink",0,function({href:e,className:r,children:i}){let s=n(e);return(0,t.jsxs)("a",{href:e,onClick:s,className:(0,l.cn)("group inline-flex min-w-0 max-w-full items-center gap-0.5 font-semibold underline-offset-4 hover:underline",r),children:[(0,t.jsx)("span",{className:"min-w-0 truncate",children:i}),(0,t.jsx)(a.ChevronRight,{className:"size-3.5 shrink-0 text-muted-foreground transition-colors group-hover:text-foreground"})]})},"useEntityLinkClick",0,n])},112179,e=>{"use strict";var t=e.i(843476),a=e.i(67488),r=e.i(487486),l=e.i(196631),n=e.i(581070);let i={success:"border-success/20 bg-success/10 text-success",error:"border-destructive/20 bg-destructive/10 text-destructive",warning:"border-warning/20 bg-warning/10 text-warning",neutral:"border-border bg-muted text-muted-foreground",info:"border-info/20 bg-info/10 text-info"};function s({href:e,dataTestId:n,className:i,children:o}){let d=(0,a.useEntityLinkClick)(e);return(0,t.jsx)(r.Badge,{variant:"outline","data-testid":n,className:(0,l.cn)("cursor-pointer hover:underline",i),render:(0,t.jsx)("a",{href:e,onClick:d}),children:o})}e.s(["StatusBadge",0,function({tone:e,label:a,tooltip:o,dataTestId:d,className:u,href:c}){let m=(0,l.cn)("whitespace-nowrap font-normal",i[e],u),f=c?(0,t.jsx)(s,{href:c,dataTestId:d,className:m,children:a}):(0,t.jsx)(r.Badge,{variant:"outline","data-testid":d,className:m,children:a});return o?(0,t.jsx)(n.CellTooltip,{content:o,trigger:f}):f}])},199931,e=>{"use strict";let t=(0,e.i(475254).default)("waypoints",[["circle",{cx:"12",cy:"4.5",r:"2.5",key:"r5ysbb"}],["path",{d:"m10.2 6.3-3.9 3.9",key:"1nzqf6"}],["circle",{cx:"4.5",cy:"12",r:"2.5",key:"jydg6v"}],["path",{d:"M7 12h10",key:"b7w52i"}],["circle",{cx:"19.5",cy:"12",r:"2.5",key:"1piiel"}],["path",{d:"m13.8 17.7 3.9-3.9",key:"1wyg1y"}],["circle",{cx:"12",cy:"19.5",r:"2.5",key:"13o1pw"}]]);e.s(["Waypoints",0,t],199931)},625901,e=>{"use strict";var t=e.i(266027),a=e.i(621482),r=e.i(912598),l=e.i(243652),n=e.i(602869),i=e.i(135214);let s=(0,l.createQueryKeys)("models"),o=(0,l.createQueryKeys)("modelHub"),d=(0,l.createQueryKeys)("allProxyModels");(0,l.createQueryKeys)("selectedTeamModels");let u=(0,l.createQueryKeys)("infiniteModels"),c=(0,l.createQueryKeys)("userModels"),m=new Set,f=e=>!!e?.litellm_params?.model?.startsWith("auto_router/"),p=e=>new Set(e.filter(f).map(e=>e.model_name).filter(e=>!!e)),x=e=>e.filter(f),h=e=>{let t=p(e);return new Set(e.map(e=>e.model_name).filter(e=>!!e).filter(e=>!t.has(e)))},y=async(e,t,a)=>{let r=await (0,n.modelInfoCall)(e,t,a,1,1e3),l=r?.total_pages??1;return[r,...await Promise.all(Array.from({length:Math.max(0,l-1)},(r,l)=>(0,n.modelInfoCall)(e,t,a,l+2,1e3)))].flatMap(e=>e?.data??[])},b=(e,t)=>s.list({filters:{scope:"autoRouters",...e&&{userId:e},...t&&{userRole:t}}});e.s(["autoRouterListKey",0,b,"fetchAllModelDeployments",0,y,"useAllProxyModels",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:d.list({}),queryFn:async()=>await (0,n.modelAvailableCall)(e,a,r,!0,null,!0,!1,"expand"),enabled:!!(e&&a&&r)})},"useAutoRouterModelGroups",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)(),{data:l}=(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await y(e,a,r),enabled:!!(e&&a&&r),select:p});return l??m},"useAutoRouters",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await y(e,a,r),enabled:!!(e&&a&&r),select:x})},"useInfiniteModelInfo",0,(e=50,t)=>{let{accessToken:r,userId:l,userRole:s}=(0,i.default)();return(0,a.useInfiniteQuery)({queryKey:u.list({filters:{...l&&{userId:l},...s&&{userRole:s},size:e,...t&&{search:t}}}),queryFn:async({pageParam:a})=>await (0,n.modelInfoCall)(r,l,s,a,e,t),initialPageParam:1,getNextPageParam:e=>{if(e.current_page{let e=(0,r.useQueryClient)();return async()=>{await e.invalidateQueries({queryKey:s.lists()})}},"useModelHub",0,()=>{let{accessToken:e}=(0,i.default)();return(0,t.useQuery)({queryKey:o.list({}),queryFn:async()=>await (0,n.modelHubCall)(e),enabled:!!e})},"useModelsInfo",0,(e=1,a=50,r,l,o,d,u,c=!1,m)=>{let{accessToken:f,userId:p,userRole:x}=(0,i.default)();return(0,t.useQuery)({queryKey:s.list({filters:{...p&&{userId:p},...x&&{userRole:x},page:e,size:a,...r&&{search:r},...m&&{modelName:m},...l&&{modelId:l},...o&&{teamId:o},...d&&{sortBy:d},...u&&{sortOrder:u},...c&&{excludeAutoRouters:"true"}}}),queryFn:async()=>await (0,n.modelInfoCall)(f,p,x,e,a,r,l,o,d,u,c,m),enabled:!!(f&&p&&x)})},"usePlainModelGroups",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)(),{data:l}=(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await y(e,a,r),enabled:!!(e&&a&&r),select:h});return l??m},"useUserModels",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:c.list({}),queryFn:async()=>(await (0,n.modelAvailableCall)(e,a,r)).data.map(e=>e.id),enabled:!!(e&&a&&r)})}])},622826,548151,200208,399536,997422,146512,547227,964471,92982,630500,e=>{"use strict";var t=e.i(843476),a=e.i(271645),r=e.i(199931),l=e.i(625901),n=e.i(487486),i=e.i(196631);let s=new Set,o=(0,a.createContext)(s);function d(e){let t=(0,a.useContext)(o);return!!e&&t.has(e)}e.s(["AutoRouterIcon",0,function({size:e=12,className:a}){return(0,t.jsx)(r.Waypoints,{size:e,className:a,"aria-hidden":!0})},"AutoRouterModelGroupsProvider",0,function({children:e}){let a=(0,l.useAutoRouterModelGroups)();return(0,t.jsx)(o.Provider,{value:a,children:e})},"AutoRouterTag",0,function({modelGroup:e,className:a}){return d(e)?(0,t.jsxs)(n.Badge,{variant:"secondary",title:`Routed by auto-router "${e}"`,className:(0,i.cn)("gap-1.5 px-2.5 py-1 text-sm font-normal text-foreground",a),children:[(0,t.jsx)(r.Waypoints,{"aria-hidden":!0}),e]}):null},"useIsAutoRoutedModelGroup",0,d],548151);var u=e.i(581070);let c=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],m=e=>String(e).padStart(2,"0"),f=(e,t)=>"date"===t?`${c[e.getMonth()]} ${e.getDate()}, ${e.getFullYear()}`:`${c[e.getMonth()]} ${e.getDate()}, ${m(e.getHours())}:${m(e.getMinutes())}:${m(e.getSeconds())}`;e.s(["DateCell",0,function({value:e,precision:a="datetime",fallback:r="-"}){let l,n,i,s=e?new Date(e):null;return!s||Number.isNaN(s.getTime())?(0,t.jsx)("span",{className:"text-muted-foreground",children:r}):(0,t.jsx)(u.CellTooltip,{content:(l=Intl.DateTimeFormat().resolvedOptions().timeZone,n=`${c[s.getMonth()]} ${s.getDate()}, ${s.getFullYear()}`,i=`${m(s.getHours())}:${m(s.getMinutes())}:${m(s.getSeconds())}`,`${n}, ${i} (${l})`),trigger:(0,t.jsx)("span",{className:"whitespace-nowrap",children:f(s,a)})})},"formatCellDate",0,f],200208);var p=e.i(174886),x=e.i(500330);let h={pill:{base:"font-mono text-xs font-normal px-2 py-0.5 rounded-md text-left bg-info/10 text-info",clickable:"hover:bg-info/15 cursor-pointer"},plain:{base:"font-mono text-xs text-left",clickable:"hover:text-info cursor-pointer"}};e.s(["IdCell",0,function({value:e,variant:a="pill",onClick:r,copyable:l=!1,truncate:n=!0,fallback:s="-",tooltip:o,disabled:d=!1,dataTestId:c,className:m}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:s});let f=!!r&&!d,y=(0,i.cn)(h[a].base,f&&h[a].clickable,n&&"block max-w-[15ch] truncate",d&&"opacity-50",m),b=f?(0,t.jsx)("button",{type:"button",className:y,"data-testid":c,onClick:()=>r(e),children:e}):(0,t.jsx)("span",{className:y,"data-testid":c,children:e}),g=(0,t.jsx)(u.CellTooltip,{content:o??e,trigger:b});return l?(0,t.jsxs)("span",{className:"inline-flex max-w-full items-center gap-1",children:[g,(0,t.jsx)("button",{type:"button","aria-label":"Copy ID",className:"shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",onClick:t=>{t.stopPropagation(),(0,x.copyToClipboard)(e)},children:(0,t.jsx)(p.Copy,{className:"size-3"})})]}):g}],399536);var y=e.i(463059),b=e.i(67488);let g="group -mx-2 flex w-[calc(100%+1rem)] cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-left transition-colors hover:bg-muted",v=()=>(0,t.jsx)(y.ChevronRight,{className:"ml-auto size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"});function w({href:e,className:a,body:r}){let l=(0,b.useEntityLinkClick)(e);return(0,t.jsxs)("a",{href:e,onClick:l,className:(0,i.cn)(g,a),children:[r,(0,t.jsx)(v,{})]})}e.s(["IdentityCell",0,function({title:e,subtitle:a,badge:r,onClick:l,href:n,className:s,titleClassName:o}){let d=(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[(0,t.jsx)("span",{className:(0,i.cn)("truncate text-sm font-medium text-foreground",o),children:e}),(null!=a&&""!==a||null!=r)&&(0,t.jsxs)("span",{className:"flex min-w-0 items-center gap-2",children:[null!=a&&""!==a&&(0,t.jsx)("span",{className:"truncate font-mono text-xs text-muted-foreground",children:a}),r]})]});return null!=n?(0,t.jsx)(w,{href:n,className:s,body:d}):null!=l?(0,t.jsxs)("button",{type:"button",onClick:l,className:(0,i.cn)(g,s),children:[d,(0,t.jsx)(v,{})]}):(0,t.jsx)("div",{className:(0,i.cn)("min-w-0",s),children:d})}],997422);let C={hasModelAccess:!1,label:"Management"},N={hasModelAccess:!1,label:"Read-only"},k={hasModelAccess:!1,label:"SCIM"},j={hasModelAccess:!0,label:null},M=e=>e.startsWith("/scim"),T=(e,t)=>1===e.length&&e[0]===t,R=(e,t)=>"management"===t?C:"read_only"===t?N:Array.isArray(e)&&0!==e.length?e.every(M)?k:T(e,"management_routes")?C:T(e,"info_routes")?N:j:j;e.s(["deriveKeyModelScope",0,R],146512);var $=e.i(355619);let I="all-proxy-models",A=e=>{if(e===I)return"All Proxy Models";let t=(0,$.getModelDisplayName)(e);return t.length>30?`${t.slice(0,30)}...`:t};e.s(["ModelsCell",0,function({models:e,maxVisible:a=3,allowedRoutes:r,keyType:l}){if(!Array.isArray(e)||0===e.length){let e=R(r,l);return e.hasModelAccess?(0,t.jsx)(n.Badge,{variant:"secondary",children:"All Proxy Models"}):(0,t.jsx)(u.CellTooltip,{content:`Scoped to ${e.label} routes; this key cannot call any models`,trigger:(0,t.jsx)(n.Badge,{variant:"secondary",className:"cursor-default",children:"No model access"})})}let i=e.slice(0,a),s=e.slice(a);return(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-1",children:[i.map((e,a)=>(0,t.jsx)(n.Badge,{variant:e===I?"secondary":"outline",children:A(e)},a)),s.length>0&&(0,t.jsx)(u.CellTooltip,{content:(0,t.jsx)("div",{className:"flex max-w-[280px] flex-col gap-0.5",children:s.map((e,a)=>(0,t.jsx)("span",{children:A(e)},a))}),trigger:(0,t.jsxs)(n.Badge,{variant:"outline",className:"cursor-default",children:["+",s.length," more"]})})]})}],547227);let S="block w-full whitespace-nowrap text-right tabular-nums text-muted-foreground";e.s(["MoneyCell",0,function({value:e,decimals:a=4,emptyText:r="-",showZero:l=!1}){if(null==e||!Number.isFinite(e))return(0,t.jsx)("span",{className:S,children:r});if(0===e&&!l)return(0,t.jsx)("span",{className:S,children:"-"});let n=0===e?`$${(0,x.formatNumberWithCommas)(0,a,!1,!0)}`:(0,x.getSpendString)(e,a);return(0,t.jsx)("span",{"data-slot":"money-cell",className:"block w-full whitespace-nowrap text-right tabular-nums",children:n})}],964471);var K=e.i(746798);function P({gates:e}){return 0===e.length?null:(0,t.jsx)(K.SimpleTooltip,{content:(0,t.jsxs)("div",{"data-testid":"inherited-budget-hint",className:"flex flex-col gap-1",children:[(0,t.jsx)("span",{children:"This key has no budget of its own, but its spend still counts toward:"}),e.map(e=>(0,t.jsx)("span",{children:`${e.scope} ${e.alias}: $${(0,x.formatNumberWithCommas)(e.maxBudget,2)}${e.budgetDuration?` / ${e.budgetDuration}`:""}`},e.scope))]})})}e.s(["InheritedBudgetHint",0,P,"inheritedBudgetGates",0,(e,t)=>{let a;return[e&&null!=e.max_budget?{scope:"Team",alias:e.team_alias||e.team_id,maxBudget:e.max_budget,budgetDuration:e.budget_duration??null}:null,(a=t?.litellm_budget_table,t&&a?.max_budget!=null?{scope:"Organization",alias:t.organization_alias||t.organization_id,maxBudget:a.max_budget,budgetDuration:a.budget_duration??null}:null)].filter(e=>null!==e)}],92982);var F=e.i(936557);e.s(["SpendBudgetCell",0,function({spend:e,maxBudget:a,inheritedGates:r=[],spendDecimals:l=4,budgetDecimals:n=0}){let i="number"!=typeof e||Number.isNaN(e)?0:e,s=a??null,o="number"==typeof s&&s>0,d=o?i/s*100:0,u=i>0?(0,x.getSpendString)(i,l):"$0.00",c=null===s?"· Unlimited":`of $${(0,x.formatNumberWithCommas)(s,n)}`;return(0,t.jsxs)("div",{className:"flex min-w-[130px] flex-col gap-1",children:[(0,t.jsxs)("div",{className:"whitespace-nowrap text-xs",children:[(0,t.jsx)("span",{className:"font-medium tabular-nums text-foreground",children:u})," ",(0,t.jsx)("span",{className:"text-muted-foreground",children:c}),null===s&&(0,t.jsx)(P,{gates:r})]}),o&&(0,t.jsx)(F.Meter,{value:i,max:s,"aria-valuetext":`${u} of $${(0,x.formatNumberWithCommas)(s,n)}`,children:(0,t.jsx)(F.MeterTrack,{children:(0,t.jsx)(F.MeterIndicator,{tone:d>100?"over":d>=80?"warning":"default"})})})]})}],630500),e.i(112179),e.s([],622826)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01benr9g1pe74.js b/litellm/proxy/_experimental/out/_next/static/chunks/01benr9g1pe74.js
deleted file mode 100644
index f0525deb2af..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/01benr9g1pe74.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,11751,e=>{"use strict";e.s(["mapEmptyStringToNull",0,function(e){return""===e?null:e}])},643449,e=>{"use strict";var t=e.i(843476),s=e.i(487486),a=e.i(810757),l=e.i(477386),i=e.i(557662),r=e.i(174553);e.s(["default",0,function({loggingConfigs:e=[],disabledCallbacks:n=[],variant:o="card",className:d=""}){let c=(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(a.CogIcon,{className:"h-4 w-4 text-info"}),(0,t.jsx)("span",{className:"font-semibold text-foreground",children:"Logging Integrations"}),(0,t.jsx)(s.Badge,{variant:"secondary",children:e.length})]}),e.length>0?(0,t.jsx)("div",{className:"space-y-3",children:e.map((e,a)=>{var l;let n=(l=e.callback_name,Object.entries(i.callback_map).find(([e,t])=>t===l)?.[0]||l);return(0,t.jsxs)("div",{className:"flex items-center justify-between p-3 rounded-lg bg-info/10 border border-info/20",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)(r.Logo,{src:i.callbackInfo[n]?.logo,label:n,className:"w-5 h-5 object-contain"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"block font-medium text-info",children:n}),(0,t.jsxs)("span",{className:"block text-xs text-info",children:[Object.keys(e.callback_vars).length," parameters configured"]})]})]}),(0,t.jsx)(s.Badge,{variant:(e=>{switch(e){case"success":return"default";case"failure":return"destructive";case"success_and_failure":return"secondary";default:return"outline"}})(e.callback_type),children:(e=>{switch(e){case"success":return"Success Only";case"failure":return"Failure Only";case"success_and_failure":return"Success & Failure";default:return e}})(e.callback_type)})]},a)})}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(a.CogIcon,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-muted-foreground text-sm",children:"No logging integrations configured"})]})]}),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(l.BanIcon,{className:"h-4 w-4 text-destructive"}),(0,t.jsx)("span",{className:"font-semibold text-foreground",children:"Disabled Callbacks"}),(0,t.jsx)(s.Badge,{variant:"destructive",children:n.length})]}),n.length>0?(0,t.jsx)("div",{className:"space-y-3",children:n.map((e,a)=>{let l=i.reverse_callback_map[e]||e;return(0,t.jsxs)("div",{className:"flex items-center justify-between p-3 rounded-lg bg-destructive/10 border border-destructive/20",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)(r.Logo,{src:i.callbackInfo[l]?.logo,label:l,className:"w-5 h-5 object-contain"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"block font-medium text-destructive",children:l}),(0,t.jsx)("span",{className:"block text-xs text-destructive",children:"Disabled for this key"})]})]}),(0,t.jsx)(s.Badge,{variant:"destructive",children:"Disabled"})]},a)})}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(l.BanIcon,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-muted-foreground text-sm",children:"No callbacks disabled"})]})]})]});return"card"===o?(0,t.jsxs)("div",{className:`bg-card border border-border rounded-lg p-6 ${d}`,children:[(0,t.jsx)("div",{className:"flex items-center gap-2 mb-6",children:(0,t.jsxs)("div",{children:[(0,t.jsx)("span",{className:"block font-semibold text-foreground",children:"Logging Settings"}),(0,t.jsx)("span",{className:"block text-xs text-muted-foreground",children:"Active logging integrations and disabled callbacks for this key"})]})}),c]}):(0,t.jsxs)("div",{className:`${d}`,children:[(0,t.jsx)("span",{className:"block font-medium text-foreground mb-3",children:"Logging Settings"}),c]})}])},597427,e=>{"use strict";let t="default_estimated_output_tokens",s="default_estimated_output_tokens_per_model",a=e=>"number"==typeof e&&Number.isInteger(e)&&e>0,l=e=>{let t;try{t=JSON.parse(e)}catch{return null}if(null==t||"object"!=typeof t||Array.isArray(t))return null;let s=Object.entries(t);return 0!==s.length&&s.every(([,e])=>a(e))?Object.fromEntries(s):null},i="Only a proxy admin can change this. It sets how many output tokens the rate limiter reserves for a request that omits max_tokens, which is charged against the team and organization TPM windows.",r={perModel:{isValid:e=>"string"!=typeof e||""===e.trim()||null!==l(e),message:'Enter a JSON object of positive integers, e.g. {"gpt-4": 4096}'},positive:{isValid:e=>""===e||null==e||a(Number(e)),message:"Enter a positive integer"}},n=({isValid:e,message:t})=>({validator:(s,a)=>e(a)?Promise.resolve():Promise.reject(Error(t))});n(r.perModel),n(r.positive),e.s(["estimateChecks",0,r,"estimateFields",0,e=>{let a;return{[t]:e?.[t],[s]:null!=(a=e?.[s])&&"object"==typeof a?JSON.stringify(a):""}},"estimateTooltips",0,(e,t="key")=>({estimate:e?`Expected output tokens reserved for TPM limiting when a request omits max_tokens. Overrides the built-in estimate for this ${t}.`:i,perModel:e?`Per-model expected output tokens reserved for TPM limiting when a request omits max_tokens. Takes precedence over the ${t}-wide estimate.`:i}),"withNormalizedEstimates",0,e=>{let{[t]:a,[s]:i,...r}=e,n=""===a||null==a?null:Number(a),o="string"==typeof i?l(i):null;return{...r,...null===n?{}:{[t]:n},...null===o?{}:{[s]:o}}}])},183588,e=>{"use strict";var t=e.i(843476),s=e.i(266484);e.s(["default",0,({value:e,onChange:a,disabledCallbacks:l=[],onDisabledCallbacksChange:i})=>(0,t.jsx)(s.default,{value:e,onChange:a,disabledCallbacks:l,onDisabledCallbacksChange:i})])},436589,e=>{"use strict";var t,s=e.i(843476);e.s([],550146),e.i(550146),e.i(247167);var a=e.i(271645),l=e.i(896499),i=e.i(956789),r=e.i(146376),n=e.i(17989),o=e.i(46420),d=e.i(733332);let c=a.createContext(void 0);function m(e){let t=a.useContext(c);if(void 0===t&&!e)throw Error((0,d.default)(50));return t}var u=e.i(675606),p=e.i(56434),g=e.i(616269),x=e.i(301252),h=e.i(264111),_=e.i(116786),f=e.i(990627),j=e.i(229315);function b(e,t,s,a){return{left:e,top:t,right:s,bottom:a,x:e,y:t,width:s-e,height:a-t}}function v(e){let t,s=[],a=1/0,l=1/0,i=-1/0,r=-1/0;for(let n of Array.from(e).sort((e,t)=>e.top-t.top)){if(a=Math.min(a,n.left),l=Math.min(l,n.top),i=Math.max(i,n.right),r=Math.max(r,n.bottom),!t||n.top-t.top>t.height/2)s.push({left:n.left,top:n.top,right:n.right,bottom:n.bottom,width:n.width,height:n.height});else{let e=s[s.length-1];e.left=Math.min(e.left,n.left),e.right=Math.max(e.right,n.right),e.bottom=Math.max(e.bottom,n.bottom),e.width=e.right-e.left,e.height=e.bottom-e.top}t=n}return{lines:s,fallback:b(a,l,i,r)}}function y(e,t,s){return e.findIndex(e=>t>e.left-2&&te.top-2&&se.instantType),hasViewport:(0,g.createSelector)(e=>e.hasViewport)};class S extends x.ReactStore{constructor(e,t,s=!1){const l=new f.PopupTriggerMap,i={...(0,_.createInitialPopupStoreState)(),instantType:void 0,hasViewport:!1,...e};i.floatingRootContext=(0,_.createPopupFloatingRootContext)(l,t,s),super(i,{popupRef:a.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:l,closeDelayRef:{current:300},inlineRectCoordsRef:{current:void 0}},w)}setOpen=(e,t)=>{let{inlineRectCoordsRef:s}=this.context;(0,h.applyPopupOpenChange)(this,e,t,{onBeforeDispatch(){let a=t.event;e&&t.reason===p.REASONS.triggerHover&&t.trigger&&"clientX"in a&&"clientY"in a&&s.current?.element!==t.trigger&&N(s,t.trigger,a.clientX,a.clientY)}})};static useStore(e,t){return(0,h.usePopupStore)(e,(e,s)=>new S(t,e,s)).store}}var C=e.i(176782);function T(e){let{open:t,defaultOpen:l=!1,onOpenChange:i,onOpenChangeComplete:n,actionsRef:o,handle:d,triggerId:m,defaultTriggerId:g=null,children:x}=e,_=S.useStore(d?.store,{open:l,openProp:t,activeTriggerId:g,triggerIdProp:m});(0,h.useInitialOpenSync)(_,t,l,g),_.useControlledProp("openProp",t),_.useControlledProp("triggerIdProp",m),_.useContextCallback("onOpenChange",i),_.useContextCallback("onOpenChangeComplete",n);let f=_.useState("open"),j=_.useState("activeTriggerId"),b=_.useState("mounted"),v=_.useState("payload");(0,h.useImplicitActiveTrigger)(_,{closeOnActiveTriggerUnmount:!0});let{forceUnmount:y}=(0,h.useOpenStateTransitions)(f,_,()=>{_.context.inlineRectCoordsRef.current=void 0});(0,r.useIsoLayoutEffect)(()=>{f&&null==j&&_.set("payload",void 0)},[_,j,f]);let k=a.useCallback(()=>{_.setOpen(!1,(0,u.createChangeEventDetails)(p.REASONS.imperativeAction))},[_]);a.useImperativeHandle(o,()=>({unmount:y,close:k}),[y,k]);let N=f||b;return(0,s.jsxs)(c.Provider,{value:_,children:[N&&(0,s.jsx)(A,{store:_}),"function"==typeof x?x({payload:v}):x]})}function A({store:e}){let t=e.useState("floatingRootContext"),s=(0,n.useDismiss)(t),l=s.reference??i.EMPTY_OBJECT,r=s.trigger??i.EMPTY_OBJECT,o=a.useMemo(()=>(0,C.mergeProps)(h.FOCUSABLE_POPUP_PROPS,s.floating),[s.floating]);return(0,h.usePopupInteractionProps)(e,{activeTriggerProps:l,inactiveTriggerProps:r,popupProps:o}),null}let E=(0,l.fastComponent)(function(e){return m(!0)?(0,s.jsx)(T,{...e}):(0,s.jsx)(o.FloatingTree,{children:(0,s.jsx)(T,{...e})})}),R=a.createContext(void 0);var F=e.i(378680);let M=a.forwardRef(function(e,t){let{keepMounted:a=!1,...l}=e;return m().useState("mounted")||a?(0,s.jsx)(R.Provider,{value:a,children:(0,s.jsx)(F.FloatingPortalLite,{ref:t,...l})}):null});var I=e.i(405005),P=e.i(552245),z=e.i(788015),D=e.i(650316),O=e.i(413082),B=e.i(872135);let L=(0,l.fastComponentRef)(function(e,t){let{render:s,className:l,delay:i,closeDelay:n,id:o,payload:c,handle:u,style:p,...g}=e,x=m(!0),_=u?.store??x;if(!_)throw Error((0,d.default)(89));let f=(0,z.useBaseUiId)(o),j=_.useState("isTriggerActive",f),b=_.useState("isOpenedByTrigger",f),v=_.useState("floatingRootContext"),y=_.context.inlineRectCoordsRef,k=a.useRef(null),w=i??600,S=n??300,{registerTrigger:C,isMountedByThisTrigger:T}=(0,h.useTriggerDataForwarding)(f,k,_,{payload:c});(0,r.useIsoLayoutEffect)(()=>{T&&(_.context.closeDelayRef.current=S)},[_,T,S]);let A=(0,B.useHoverReferenceInteraction)(v,{mouseOnly:!0,move:!1,handleClose:(0,D.safePolygon)(),delay:()=>({open:w,close:S}),triggerElementRef:k,isActiveTrigger:j,isClosing:()=>"ending"===_.select("transitionStatus")}),E=(0,O.useFocus)(v,{delay:w}),R=_.useState("triggerProps",T),F=function(e,t){function s(s){t||N(e,s.currentTarget,s.clientX,s.clientY)}return{onFocus(){e.current=void 0},onMouseEnter:s,onMouseMove:s}}(y,b);return(0,P.useRenderElement)("a",e,{state:{open:b},ref:[t,C,k],props:[A,E.reference,R,F,{id:f},g],stateAttributesMapping:I.triggerOpenStateMapping})}),K=a.createContext(void 0);function V(){let e=a.useContext(K);if(void 0===e)throw Error((0,d.default)(49));return e}var U=e.i(329365),H=e.i(638396),$=e.i(360495),W=e.i(789579);let q=a.forwardRef(function(e,t){let{render:l,className:i,anchor:n,positionMethod:c="absolute",side:u="bottom",align:p="center",sideOffset:g=0,alignOffset:x=0,collisionBoundary:h="clipping-ancestors",collisionPadding:_=5,arrowPadding:f=5,sticky:N=!1,disableAnchorTracking:w=!1,collisionAvoidance:S=H.POPUP_COLLISION_AVOIDANCE,style:C,...T}=e,A=m(),E=function(){let e=a.useContext(R);if(void 0===e)throw Error((0,d.default)(48));return e}(),F=(0,o.useFloatingNodeId)(),M=A.useState("open"),I=A.useState("mounted"),P=A.useState("floatingRootContext"),z=A.useState("instantType"),D=A.useState("transitionStatus"),O=A.useState("hasViewport"),B=A.context.inlineRectCoordsRef,L=(0,U.useAnchorPositioning)({anchor:n,floatingRootContext:P,positionMethod:c,mounted:I,side:u,sideOffset:g,align:p,alignOffset:x,arrowPadding:f,collisionBoundary:h,collisionPadding:_,sticky:N,disableAnchorTracking:w,keepMounted:E,nodeId:F,collisionAvoidance:S,adaptiveOrigin:O?$.adaptiveOrigin:void 0,inline:{name:"inline",async fn(e){let t=e.elements.reference;if("function"!=typeof t?.getClientRects)return{};let s="contextElement"in t&&t.contextElement?t.contextElement:(0,j.isElement)(t)?t:void 0,a=B.current,l=a?.element===t||a?.element===s?a:void 0,i=function(e,t,s){let{lines:a,fallback:l}=v(e.getClientRects());if(a.length<2)return null;let i=s?.x,r=s?.y,n=t[0];if(s?.lineIndex!=null&&a[s.lineIndex])return k(a[s.lineIndex]);if(null!=i&&null!=r){let e=y(a,i,r);if(-1!==e)return k(a[e])}if(2===a.length&&a[0].left>a[1].right&&null!=i&&null!=r)return l;if("t"===n||"b"===n){let e=a[0],t=a[a.length-1],s="t"===n?e:t;return b(s.left,e.top,s.right,t.bottom)}let o="l"===n,d=a[0].left,c=a[0].right,m=o?1/0:-1/0,u=a[0],p=a[0];for(let e of a){d=Math.min(d,e.left),c=Math.max(c,e.right);let t=o?e.left:e.right;o&&tm?(m=t,u=e,p=e):t===m&&(p=e)}return b(d,u.top,c,p.bottom)}(t,e.placement,l);if(!i||"function"!=typeof e.platform.getElementRects)return{};let r=await e.platform.getElementRects({reference:{contextElement:s,getBoundingClientRect:()=>i},floating:e.elements.floating,strategy:e.strategy});return e.rects.reference.x===r.reference.x&&e.rects.reference.y===r.reference.y&&e.rects.reference.width===r.reference.width&&e.rects.reference.height===r.reference.height?{}:{reset:{rects:r}}}}}),V=L.update;(0,r.useIsoLayoutEffect)(()=>{M&&I&&V()},[M,I,V]);let q={open:M,side:L.side,align:L.align,anchorHidden:L.anchorHidden,instant:z},G=(0,W.usePositioner)(e,q,{styles:L.positionerStyles,transitionStatus:D,props:T,refs:[t,A.useStateSetter("positionerElement")],hidden:!I,inert:!M});return(0,s.jsx)(K.Provider,{value:L,children:(0,s.jsx)(o.FloatingNode,{id:F,children:G})})});var G=e.i(667865),J=e.i(209407),Q=e.i(137584),Y=e.i(815982),X=e.i(431157);let Z={...I.popupStateMapping,...J.transitionStatusMapping},ee=a.forwardRef(function(e,t){let{className:s,render:a,style:l,...i}=e,r=m(),{side:n,align:o}=V(),d=r.useState("open"),c=r.useState("instantType"),u=r.useState("transitionStatus"),p=r.useState("popupProps"),g=r.useState("floatingRootContext");(0,Q.useOpenChangeComplete)({open:d,ref:r.context.popupRef,onComplete(){d&&r.context.onOpenChangeComplete?.(!0)}});let x=(0,G.useStableCallback)(()=>r.context.closeDelayRef.current);return(0,X.useHoverFloatingInteraction)(g,{closeDelay:x}),(0,P.useRenderElement)("div",e,{state:{open:d,side:n,align:o,instant:c,transitionStatus:u},ref:[t,r.context.popupRef,r.useStateSetter("popupElement")],props:[p,(0,Y.getDisabledMountTransitionStyles)(u),i],stateAttributesMapping:Z})}),et=a.forwardRef(function(e,t){let{render:s,className:a,style:l,...i}=e,r=m(),{arrowRef:n,side:o,align:d,arrowUncentered:c,arrowStyles:u}=V(),p=r.useState("open");return(0,P.useRenderElement)("div",e,{state:{open:p,side:o,align:d,uncentered:c},ref:[n,t],props:[{style:u,"aria-hidden":!0},i],stateAttributesMapping:I.popupStateMapping})}),es={...I.popupStateMapping,...J.transitionStatusMapping},ea=a.forwardRef(function(e,t){let{render:s,className:a,style:l,...i}=e,r=m(),n=r.useState("open"),o=r.useState("mounted"),d=r.useState("transitionStatus");return(0,P.useRenderElement)("div",e,{state:{open:n,transitionStatus:d},ref:[t],props:[{role:"presentation",hidden:!o,style:{pointerEvents:"none",userSelect:"none",WebkitUserSelect:"none"}},i],stateAttributesMapping:es})}),el=((t={}).popupWidth="--popup-width",t.popupHeight="--popup-height",t);var ei=e.i(818390);let er={activationDirection:e=>e?{"data-activation-direction":e}:null},en=a.forwardRef(function(e,t){let{render:s,className:a,style:l,children:i,...r}=e,n=m(),o=V(),d=n.useState("instantType"),{children:c,state:u}=(0,ei.usePopupViewport)({store:n,side:o.side,cssVars:el,children:i}),p={activationDirection:u.activationDirection,transitioning:u.transitioning,instant:d};return(0,P.useRenderElement)("div",e,{state:p,ref:t,props:[r,{children:c}],stateAttributesMapping:er})});class eo{constructor(){this.store=new S}open(e){let t=e?this.store.context.triggerElements.getById(e):void 0;if(e&&!t)throw Error((0,d.default)(88,e));this.store.setOpen(!0,(0,u.createChangeEventDetails)(p.REASONS.imperativeAction,void 0,t))}close(){this.store.setOpen(!1,(0,u.createChangeEventDetails)(p.REASONS.imperativeAction,void 0,void 0))}get isOpen(){return this.store.select("open")}}e.s(["Arrow",0,et,"Backdrop",0,ea,"Handle",0,eo,"Popup",0,ee,"Portal",0,M,"Positioner",0,q,"Root",0,E,"Trigger",0,L,"Viewport",0,en,"createHandle",0,function(){return new eo}],37379);var ed=e.i(37379),ed=ed,ec=e.i(196631);e.s(["HoverCard",0,function({...e}){return(0,s.jsx)(ed.Root,{"data-slot":"hover-card",...e})},"HoverCardContent",0,function({className:e,side:t="bottom",sideOffset:a=4,align:l="center",alignOffset:i=4,...r}){return(0,s.jsx)(ed.Portal,{"data-slot":"hover-card-portal",children:(0,s.jsx)(ed.Positioner,{align:l,alignOffset:i,side:t,sideOffset:a,className:"isolate z-popup",children:(0,s.jsx)(ed.Popup,{"data-slot":"hover-card-content",className:(0,ec.cn)("z-popup w-64 origin-(--transform-origin) rounded-lg bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",e),...r})})})},"HoverCardTrigger",0,function({...e}){return(0,s.jsx)(ed.Trigger,{"data-slot":"hover-card-trigger",...e})}],436589)},214541,e=>{"use strict";var t=e.i(271645),s=e.i(135214),a=e.i(270345);e.s(["default",0,()=>{let[e,l]=(0,t.useState)([]),{accessToken:i,userId:r,userRole:n}=(0,s.default)();return(0,t.useEffect)(()=>{(async()=>{l(await (0,a.fetchTeams)(i,r,n,null))})()},[i,r,n]),{teams:e,setTeams:l}}])},915505,417835,e=>{"use strict";var t=e.i(475254);let s=(0,t.default)("arrow-left-right",[["path",{d:"M8 3 4 7l4 4",key:"9rb6wj"}],["path",{d:"M4 7h16",key:"6tx8e3"}],["path",{d:"m16 21 4-4-4-4",key:"siv7j2"}],["path",{d:"M20 17H4",key:"h6l3hr"}]]);e.s(["ArrowLeftRight",0,s],915505);let a=(0,t.default)("timer",[["line",{x1:"10",x2:"14",y1:"2",y2:"2",key:"14vaq8"}],["line",{x1:"12",x2:"15",y1:"14",y2:"11",key:"17fdiu"}],["circle",{cx:"12",cy:"14",r:"8",key:"1e1u0o"}]]);e.s(["Timer",0,a],417835)},784647,422183,505022,875989,331755,721929,e=>{"use strict";var t=e.i(843476),s=e.i(871689),a=e.i(915505),l=e.i(223622),i=e.i(607486),r=e.i(87316),n=e.i(101048),o=e.i(503116),d=e.i(323585),c=e.i(107233),m=e.i(16715),u=e.i(581418),p=e.i(417835),g=e.i(727612),x=e.i(284614),h=e.i(761911),_=e.i(39312),f=e.i(487486),j=e.i(519455),b=e.i(755146),v=e.i(436589),y=e.i(772436),k=e.i(746798),N=e.i(922407),w=e.i(67488),S=e.i(422444),C=e.i(196631),T=e.i(304911);function A({label:e,value:s,icon:a,href:l,truncate:i=!1,copyable:r=!1,defaultUserIdCheck:n=!1}){let o=!s,d=n&&"default_user_id"===s,c=o?"-":s,m=null!=l&&!o&&!d,u=d?(0,t.jsx)(T.default,{userId:s}):(0,t.jsxs)("span",{className:"inline-flex min-w-0 items-center gap-1",children:[m?(0,t.jsx)(w.EntityLink,{href:l,className:(0,C.cx)(i&&"max-w-40"),children:c}):(0,t.jsx)("strong",{className:(0,C.cx)("font-semibold",i?"block max-w-40 truncate":"break-words"),children:c}),r&&!o&&!d&&(0,t.jsx)(N.default,{value:s,label:`Copy ${e}`})]});return(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsxs)("div",{className:"flex items-center gap-1 text-muted-foreground",children:[a,(0,t.jsx)("span",{className:"text-xs tracking-wider uppercase",children:e})]}),(0,t.jsx)("div",{className:"min-w-0",children:u})]})}function E({userAlias:e,userEmail:s,userId:a}){let l=(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:(0,t.jsx)(x.User,{className:"size-3.5"})}),(0,t.jsx)("span",{className:"text-xs uppercase tracking-[0.05em] text-muted-foreground",children:"User"})]});if(!e&&!s&&!a)return(0,t.jsxs)("div",{children:[l,(0,t.jsx)("div",{children:(0,t.jsx)("span",{className:"font-semibold",children:"-"})})]});let i="default_user_id"===a,r=e||s||a,n=(0,t.jsx)("div",{className:"flex flex-col gap-2 text-xs min-w-[200px] max-w-[300px]",children:[{label:"User Alias",value:e??null},{label:"User Email",value:s||null},{label:"User ID",value:a||null}].map(({label:e,value:s})=>(0,t.jsxs)("div",{className:"flex flex-col min-w-0",children:[(0,t.jsx)("span",{className:"text-muted-foreground",children:e}),s?(0,t.jsxs)("div",{className:"flex min-w-0 items-center gap-1",children:[(0,t.jsx)("span",{className:"min-w-0 flex-1 truncate font-mono text-xs",title:s,children:s}),(0,t.jsx)(N.default,{value:s,label:`Copy ${e}`,iconClassName:"size-3.5"})]}):(0,t.jsx)("span",{className:"font-mono",children:"-"})]},e))});return!i||e||s?(0,t.jsxs)("div",{children:[l,(0,t.jsx)("div",{children:(0,t.jsxs)(v.HoverCard,{children:[(0,t.jsx)(v.HoverCardTrigger,{render:(0,t.jsx)("span",{className:"block max-w-[200px] cursor-default truncate font-semibold",children:a?(0,t.jsx)(w.EntityLink,{href:(0,S.userDetailHref)(a),children:r}):r})}),(0,t.jsx)(v.HoverCardContent,{side:"bottom",align:"start",className:"w-auto",children:n})]})})]}):(0,t.jsxs)("div",{children:[l,(0,t.jsx)("div",{children:(0,t.jsxs)(v.HoverCard,{children:[(0,t.jsx)(v.HoverCardTrigger,{render:(0,t.jsx)("span",{className:"cursor-default",children:(0,t.jsx)(T.default,{userId:a})})}),(0,t.jsx)(v.HoverCardContent,{side:"bottom",align:"start",className:"w-auto",children:n})]})})]})}e.s(["KeyInfoHeader",0,function({data:e,onBack:x,onCreateNew:v,onRegenerate:w,onDelete:C,onResetSpend:T,onToggleBlocked:R,isBlocked:F=!1,canModifyKey:M=!0,backButtonText:I="Back to Keys",regenerateDisabled:P=!1,regenerateTooltip:z}){let D=(0,t.jsx)("span",{children:(0,t.jsxs)(j.Button,{variant:"outline",onClick:w,disabled:P,children:[(0,t.jsx)(m.RefreshCw,{className:"size-3.5"}),"Regenerate Key"]})});return(0,t.jsxs)("div",{children:[v&&(0,t.jsx)("div",{style:{marginBottom:16},children:(0,t.jsxs)(j.Button,{onClick:v,children:[(0,t.jsx)(c.Plus,{className:"size-3.5"}),"Create New Key"]})}),(0,t.jsx)("div",{style:{marginBottom:16},children:(0,t.jsxs)(j.Button,{variant:"ghost",onClick:x,children:[(0,t.jsx)(s.ArrowLeft,{className:"size-3.5"}),I]})}),(0,t.jsxs)("div",{className:"flex items-start justify-between",style:{marginBottom:20},children:[(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsxs)("h3",{className:"m-0 flex items-center gap-1 text-2xl font-semibold",children:[e.keyName,(0,t.jsx)(N.default,{value:e.keyName,label:"Copy Key Alias",iconClassName:"size-4"})]}),F&&(0,t.jsxs)(f.Badge,{variant:"destructive",children:[(0,t.jsx)(l.Ban,{className:"size-3"}),"Blocked"]})]}),(0,t.jsxs)("div",{className:"flex min-w-0 items-center gap-1",children:[(0,t.jsxs)("span",{className:"min-w-0 break-words text-muted-foreground",children:["Key ID: ",e.keyId]}),(0,t.jsx)(N.default,{value:e.keyId,label:"Copy Key ID",iconClassName:"size-3.5"})]})]}),M&&(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[z?(0,t.jsx)(k.TooltipProvider,{delay:300,children:(0,t.jsxs)(k.Tooltip,{children:[(0,t.jsx)(k.TooltipTrigger,{render:D}),(0,t.jsx)(k.TooltipContent,{children:z})]})}):D,(0,t.jsxs)(b.DropdownMenu,{children:[(0,t.jsx)(b.DropdownMenuTrigger,{render:(0,t.jsx)(j.Button,{variant:"outline",size:"icon","aria-label":"More key actions"}),children:(0,t.jsx)(d.MoreVertical,{className:"size-3.5"})}),(0,t.jsxs)(b.DropdownMenuContent,{align:"end",className:"w-auto",children:[R&&(F?(0,t.jsxs)(b.DropdownMenuItem,{onClick:R,children:[(0,t.jsx)(n.CircleCheck,{className:"size-3.5"}),"Unblock Key"]}):(0,t.jsxs)(b.DropdownMenuItem,{variant:"destructive",onClick:R,children:[(0,t.jsx)(l.Ban,{className:"size-3.5"}),"Block Key"]})),T&&(0,t.jsxs)(b.DropdownMenuItem,{variant:"destructive",onClick:T,children:[(0,t.jsx)(a.ArrowLeftRight,{className:"size-3.5"}),"Reset Spend"]}),(0,t.jsxs)(b.DropdownMenuItem,{variant:"destructive",onClick:C,children:[(0,t.jsx)(g.Trash2,{className:"size-3.5"}),"Delete Key"]})]})]})]})]}),(0,t.jsxs)("div",{className:"flex items-stretch gap-10",style:{marginBottom:40},children:[(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-4",children:[(0,t.jsx)(E,{userAlias:e.userAlias,userEmail:e.userEmail,userId:e.userId}),(0,t.jsx)(A,{label:"Expires",value:e.expires,icon:(0,t.jsx)(p.Timer,{className:"size-3.5"})})]}),(0,t.jsx)(y.Separator,{orientation:"vertical"}),(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-4",children:[(0,t.jsx)(A,{label:"Created At",value:e.createdAt,icon:(0,t.jsx)(r.Calendar,{className:"size-3.5"})}),(0,t.jsx)(A,{label:"Created By",value:e.createdBy,icon:(0,t.jsx)(u.ShieldCheck,{className:"size-3.5"}),href:e.createdById?(0,S.userDetailHref)(e.createdById):void 0,truncate:!0,copyable:!0,defaultUserIdCheck:!0})]}),(0,t.jsx)(y.Separator,{orientation:"vertical"}),(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-4",children:[(0,t.jsx)(A,{label:"Last Updated",value:e.lastUpdated,icon:(0,t.jsx)(o.Clock,{className:"size-3.5"})}),(0,t.jsx)(A,{label:"Last Active",value:e.lastActive,icon:(0,t.jsx)(_.Zap,{className:"size-3.5"})})]}),(0,t.jsx)(y.Separator,{orientation:"vertical"}),(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-4",children:[(0,t.jsx)(A,{label:"Team",value:e.teamAlias||e.teamId,icon:(0,t.jsx)(h.Users,{className:"size-3.5"}),href:e.teamId?(0,S.teamDetailHref)(e.teamId):void 0,truncate:!0}),(0,t.jsx)(A,{label:"Organization",value:e.orgAlias||e.orgId,icon:(0,t.jsx)(i.Building2,{className:"size-3.5"}),href:e.orgId?(0,S.orgDetailHref)(e.orgId):void 0,truncate:!0})]})]})]})}],784647);var R=e.i(271645);e.i(32117);var F=e.i(591025),M=e.i(343053),I=e.i(594772),P=e.i(973706),z=e.i(811033),D=e.i(515288),O=e.i(677572),B=e.i(708347),L=e.i(79361),K=e.i(555376);e.s(["default",0,({accessToken:e,keyToken:s,userId:a,userRole:l})=>{let i=(0,B.hasProxyWideSpendView)(l),{dateValue:r,onDateChange:n,results:o,loading:d,isFetchingMore:c}=(0,K.useScopedDailyActivityRange)(e,{userId:(0,B.spendScopeUserId)(l,a),apiKey:s}),m=r.from??null,u=r.to??null,[p,g]=(0,R.useState)("cumulative"),x=(0,R.useMemo)(()=>(0,L.savingsSeriesOf)(o),[o]),h=(0,R.useMemo)(()=>{if("cumulative"!==p)return x;let e=m?(0,L.shortDate)((0,L.localIsoDay)(m)):"";return(0,L.withStartAnchor)((0,L.toCumulative)(x),e)},[p,x,m]),_="Per day",f=(0,L.formatRangeLabel)(m??void 0,u??void 0),j=["cumulative"===p?"Running total saved":`Saved ${_.toLowerCase()}`,f&&`${f} (UTC)`].filter(Boolean).join(" · "),b=d||c,v=o.length>0,y={data:h,index:"date",categories:L.SAVINGS_SERIES,colors:L.SAVINGS_COLORS,valueFormatter:L.usd,showLegend:!1};return(0,t.jsxs)("div",{className:"w-full space-y-6",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center justify-end gap-4",children:[(0,t.jsx)("span",{className:"text-sm text-muted-foreground",children:"Spend is bucketed by UTC day"}),(0,t.jsx)(P.default,{value:r,onValueChange:n})]}),!i&&(0,t.jsx)("p",{className:"text-sm text-muted-foreground","data-testid":"key-savings-scope-note",children:"Showing your own requests on this key. A key shared across a team will have spend from other members that is not counted here."}),(0,t.jsx)(z.default,{results:o,isLoading:b}),(0,t.jsxs)(D.Card,{children:[(0,t.jsxs)(D.CardHeader,{children:[(0,t.jsx)(D.CardTitle,{children:"Savings"}),(0,t.jsx)(D.CardDescription,{children:j}),(0,t.jsxs)(D.CardAction,{className:"flex flex-wrap items-center justify-end gap-x-4 gap-y-2",children:[(0,t.jsx)(I.CustomLegend,{categories:L.SAVINGS_SERIES,colors:L.SAVINGS_COLORS}),(0,t.jsx)(O.Tabs,{value:p,onValueChange:e=>g(e),children:(0,t.jsxs)(O.TabsList,{children:[(0,t.jsx)(O.TabsTrigger,{value:"cumulative",children:"Cumulative"}),(0,t.jsx)(O.TabsTrigger,{value:"per-interval",children:_})]})})]})]}),(0,t.jsxs)(D.CardContent,{children:[!v&&(0,t.jsx)("p",{className:"py-12 text-center text-sm text-muted-foreground","data-testid":"key-savings-empty",children:b?"Loading savings...":"No usage recorded for this key in this range."}),v&&"cumulative"===p&&(0,t.jsx)(F.AreaChart,{...y,showDots:h.length<=L.MAX_POINTS_WITH_DOTS}),v&&"cumulative"!==p&&(0,t.jsx)(M.BarChart,{...y})]})]})]})}],422183),e.i(622826);var V=e.i(112179),U=e.i(278587);let H=R.forwardRef(function(e,t){return R.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),R.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["default",0,({autoRotate:e=!1,rotationInterval:s,lastRotationAt:a,keyRotationAt:l,nextRotationAt:i,variant:r="card",className:n=""})=>{let o=e=>{let t=new Date(e),s=t.toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}),a=t.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0});return`${s} at ${a}`},d=(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsx)("div",{className:"space-y-3",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(U.RefreshIcon,{className:"h-4 w-4 text-info"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"Auto-Rotation"}),(0,t.jsx)(V.StatusBadge,{tone:e?"success":"neutral",label:e?"Enabled":"Disabled"}),e&&s&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"•"}),(0,t.jsxs)("p",{className:"text-sm text-muted-foreground",children:["Every ",s]})]})]})}),(e||a||l||i)&&(0,t.jsxs)("div",{className:"space-y-3",children:[a&&(0,t.jsxs)("div",{className:"flex items-center gap-2 rounded-md border border-border bg-muted p-3",children:[(0,t.jsx)(H,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Last Rotation"}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:o(a)})]})]}),(l||i)&&(0,t.jsxs)("div",{className:"flex items-center gap-2 rounded-md border border-border bg-muted p-3",children:[(0,t.jsx)(H,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Next Scheduled Rotation"}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:o(i||l||"")})]})]}),e&&!a&&!l&&!i&&(0,t.jsxs)("div",{className:"flex items-center gap-2 rounded-md border border-border bg-muted p-3",children:[(0,t.jsx)(H,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"No rotation history available"})]})]}),!e&&!a&&!l&&!i&&(0,t.jsxs)("div",{className:"flex items-center gap-2 rounded-md border border-border bg-muted p-3",children:[(0,t.jsx)(U.RefreshIcon,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"Auto-rotation is not enabled for this key"})]})]});return"card"===r?(0,t.jsxs)("div",{className:`rounded-lg border border-border bg-card p-6 ${n}`,children:[(0,t.jsx)("div",{className:"mb-6 flex items-center gap-2",children:(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"Auto-Rotation"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Automatic key rotation settings and status for this key"})]})}),d]}):(0,t.jsxs)("div",{className:`${n}`,children:[(0,t.jsx)("p",{className:"mb-3 text-sm font-medium text-foreground",children:"Auto-Rotation"}),d]})}],505022);let $=["routing_strategy","allowed_fails","cooldown_time","num_retries","timeout","retry_after","fallbacks","context_window_fallbacks","retry_policy","model_group_alias","enable_tag_filtering","routing_strategy_args"],W=e=>null!=e&&""!==e&&!1!==e&&(Array.isArray(e)?e.length>0:"object"!=typeof e||Object.keys(e).length>0),q=e=>null!=e&&Object.values(e).some(W);e.s(["hasRouterSettings",0,q,"routerSettingsEditorValue",0,e=>e?{router_settings:Object.fromEntries($.filter(t=>t in e).map(t=>[t,e[t]]))}:void 0,"routerSettingsUpdate",0,(e,t)=>{if(!e)return;let s=Object.fromEntries($.map(t=>[t,e[t]??null])),a={...t,...s};return q(a)?a:q(t)?{}:void 0}],875989),e.s(["default",0,function({routerSettings:e,emptyText:s="No router settings configured"}){var a;if(!q(e))return(0,t.jsx)("div",{className:"text-muted-foreground",children:s});let l=Array.isArray(a=e.fallbacks)?a.flatMap(e=>e&&"object"==typeof e?Object.entries(e):[]):[];return(0,t.jsxs)("div",{className:"space-y-1 text-sm",children:[null!=e.routing_strategy&&(0,t.jsxs)("div",{children:["Routing Strategy: ",(0,t.jsx)(f.Badge,{variant:"secondary",children:String(e.routing_strategy)})]}),null!=e.num_retries&&(0,t.jsxs)("div",{children:["Number of Retries: ",String(e.num_retries)]}),null!=e.allowed_fails&&(0,t.jsxs)("div",{children:["Allowed Failures: ",String(e.allowed_fails)]}),null!=e.cooldown_time&&(0,t.jsxs)("div",{children:["Cooldown Time: ",String(e.cooldown_time),"s"]}),null!=e.timeout&&(0,t.jsxs)("div",{children:["Timeout: ",String(e.timeout),"s"]}),null!=e.retry_after&&(0,t.jsxs)("div",{children:["Retry After: ",String(e.retry_after),"s"]}),!!e.enable_tag_filtering&&(0,t.jsx)("div",{children:"Tag Filtering: Enabled"}),l.length>0&&(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{children:"Fallbacks:"}),(0,t.jsx)("div",{className:"mt-1 space-y-1",children:l.map(([e,s])=>(0,t.jsxs)("div",{className:"text-xs text-muted-foreground",children:[(0,t.jsx)("span",{className:"font-medium",children:e}),(0,t.jsx)("span",{className:"mx-1 text-muted-foreground",children:"->"}),Array.isArray(s)?s.join(", "):String(s)]},e))})]})]})}],331755);let G=["logging"];e.s(["extractLoggingSettings",0,e=>e&&"object"==typeof e&&Array.isArray(e.logging)?e.logging:[],"formatMetadataForDisplay",0,(e,t=2)=>JSON.stringify(e&&"object"==typeof e?Object.fromEntries(Object.entries(e).filter(([e])=>!G.includes(e))):{},null,t),"stripTagsFromMetadata",0,e=>{if(!e||"object"!=typeof e)return e;let{tags:t,...s}=e;return s}],721929)},65932,286047,272753,e=>{"use strict";var t=e.i(954616),s=e.i(912598),a=e.i(602869),l=e.i(431703),i=e.i(135214),r=e.i(207082);let n=async(e,t)=>{let s=(0,a.getProxyBaseUrl)(),i=`${s?`${s}/key/${t}/reset_spend`:`/key/${t}/reset_spend`}`,r=await fetch(i,{method:"POST",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({reset_to:0})});if(!r.ok){let e=await r.json(),t=(0,l.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return r.json()};e.s(["useResetKeySpend",0,()=>{let{accessToken:e}=(0,i.default)(),a=(0,s.useQueryClient)();return(0,t.useMutation)({mutationFn:async t=>{if(!e)throw Error("Access token is required");return n(e,t)},onSuccess:()=>{a.invalidateQueries({queryKey:r.keyKeys.all})}})}],65932);let o=async(e,{keyToken:t,blocked:s})=>{let l=await a.apiClient.post(s?"/key/block":"/key/unblock",{accessToken:e,body:{key:t}});return{blocked:l?.blocked??s}};e.s(["useSetKeyBlockedState",0,()=>{let{accessToken:e}=(0,i.default)(),a=(0,s.useQueryClient)();return(0,t.useMutation)({mutationFn:async t=>{if(!e)throw Error("Access token is required");return o(e,t)},onSuccess:()=>{a.invalidateQueries({queryKey:r.keyKeys.all})}})}],286047);var d=e.i(843476),c=e.i(204290),m=e.i(929592),u=e.i(519455),p=e.i(776639),g=e.i(643531),x=e.i(359360),h=e.i(174886),_=e.i(16715),f=e.i(89128),j=e.i(271645),b=e.i(653145),v=e.i(237016),y=e.i(681307),k=e.i(417385),N=e.i(542450),w=e.i(182668),S=e.i(793479),C=e.i(746798),T=e.i(991326),A=e.i(24529);let E=(e,t)=>{let[s,a="0"]=e.toExponential().split("e");return Number(`${s}e${Number(a)+t}`)},R=/^(\d+(s|m|h|d|w|mo))?$/,F="Must be a duration like 30s, 30m, 24h, 2d, 1w, or 1mo",M={key_alias:void 0,max_budget:void 0,tpm_limit:void 0,rpm_limit:void 0,duration:"",grace_period:""};e.s(["RegenerateKeyModal",0,function({selectedToken:e,visible:t,onClose:s,onKeyUpdate:l}){let{accessToken:r}=(0,i.default)(),[n,o]=(0,j.useState)(null),[I,P]=(0,j.useState)(!1),[z,D]=(0,j.useState)(!1),O=(0,A.isKeyExpired)(e?.expires),B=(0,j.useMemo)(()=>{let e;return e={key_alias:y.z.string().nullish(),max_budget:y.z.number().nullish(),tpm_limit:y.z.number().nullish(),rpm_limit:y.z.number().nullish(),duration:O?y.z.string().min(1,"Expiration is required for expired keys").regex(R,F):y.z.string().regex(R,F),grace_period:y.z.string().regex(R,F)},y.z.object(e)},[O]),L=(0,T.useZodForm)(B,{defaultValues:M}),K=(0,b.useWatch)({control:L.control,name:"duration"});(0,j.useEffect)(()=>{if(t&&e&&r){let t={key_alias:e.key_alias,max_budget:e.max_budget,tpm_limit:e.tpm_limit,rpm_limit:e.rpm_limit,duration:e.duration||"",grace_period:""};L.reset(t)}},[t,e,L,r]);let V=K?(0,A.calculateExpiryPreviewFromDuration)(K):null,U=async t=>{if(!e||!r)return;let s={...t,max_budget:"number"==typeof t.max_budget?(e=>{let t=E(Math.abs(e),2);if(!Number.isFinite(t))return e;let s=E(Math.round(t),-2);return e<0?-s:s})(t.max_budget):t.max_budget};try{let t=await (0,a.regenerateKeyCall)(r,e.token||e.token_id,s);o(t.key),k.toast.success("Virtual Key regenerated successfully");let i={...t,token:t.token_id||t.token||e.token,key_name:t.key,max_budget:s.max_budget,tpm_limit:s.tpm_limit,rpm_limit:s.rpm_limit,expires:t.expires??e.expires};l&&l(i),P(!1)}catch(e){P(!1),console.error("Error regenerating key:",e),k.toast.fromError(e)}},H=()=>{o(null),P(!1),D(!1),L.reset(M),s()};return(0,d.jsx)(p.Dialog,{open:t,onOpenChange:e=>!e&&H(),disablePointerDismissal:!0,children:(0,d.jsxs)(p.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[520px]",children:[(0,d.jsx)(p.DialogHeader,{children:(0,d.jsx)(p.DialogTitle,{children:"Regenerate Virtual Key"})}),n?(0,d.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,d.jsxs)(c.Alert,{variant:"warning",children:[(0,d.jsx)(f.TriangleAlert,{}),(0,d.jsx)(m.AlertTitle,{children:"Save it now, you will not see it again"})]}),(0,d.jsxs)("div",{className:"flex flex-col gap-0.5",children:[(0,d.jsx)("span",{className:"text-xs text-muted-foreground",children:"Key Alias"}),(0,d.jsx)("span",{className:"text-sm text-foreground",children:e?.key_alias||"No alias set"})]}),(0,d.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,d.jsx)("span",{className:"text-xs text-muted-foreground",children:"Virtual Key"}),(0,d.jsx)("div",{className:"rounded-md border border-border bg-muted px-4 py-3.5 font-mono text-base break-all text-foreground",children:n})]})]}):(0,d.jsx)(C.TooltipProvider,{children:(0,d.jsx)("form",{onSubmit:e=>e.preventDefault(),noValidate:!0,className:"mt-1",children:(0,d.jsxs)(N.FieldGroup,{children:[(0,d.jsx)(w.FormField,{control:L.control,name:"key_alias",label:"Key Alias",children:({ref:e,value:t,...s})=>(0,d.jsx)(S.Input,{...s,ref:e,value:t??"",disabled:!0})}),(0,d.jsxs)("div",{className:"grid grid-cols-3 gap-3",children:[(0,d.jsx)(w.FormField,{control:L.control,name:"max_budget",label:"Max Budget (USD)",children:({ref:e,value:t,onChange:s,...a})=>(0,d.jsx)(S.Input,{...a,ref:e,type:"number",step:.01,value:t??"",onChange:e=>s(""===e.target.value?null:e.target.valueAsNumber)})}),(0,d.jsx)(w.FormField,{control:L.control,name:"tpm_limit",label:"TPM Limit",children:({ref:e,value:t,onChange:s,...a})=>(0,d.jsx)(S.Input,{...a,ref:e,type:"number",value:t??"",onChange:e=>s(""===e.target.value?null:e.target.valueAsNumber)})}),(0,d.jsx)(w.FormField,{control:L.control,name:"rpm_limit",label:"RPM Limit",children:({ref:e,value:t,onChange:s,...a})=>(0,d.jsx)(S.Input,{...a,ref:e,type:"number",value:t??"",onChange:e=>s(""===e.target.value?null:e.target.valueAsNumber)})})]}),(0,d.jsxs)("div",{className:"grid grid-cols-2 gap-3",children:[(0,d.jsx)(w.FormField,{control:L.control,name:"duration",label:"Expire Key",description:(0,d.jsxs)("span",{className:"flex flex-col gap-0.5 text-xs",children:[(0,d.jsxs)("span",{className:O?"text-destructive":"text-muted-foreground",children:["Current expiry: ",e?.expires?(0,A.formatExpiresUtc)(e.expires):"Never",O&&" (expired)"]}),V&&(0,d.jsxs)("span",{className:"text-success",children:["New expiry: ",V]})]}),children:({ref:e,...t})=>(0,d.jsx)(S.Input,{...t,ref:e,placeholder:"e.g. 30s, 30h, 30d"})}),(0,d.jsx)(w.FormField,{control:L.control,name:"grace_period",label:(0,d.jsxs)(d.Fragment,{children:["Grace Period",(0,d.jsxs)(C.Tooltip,{children:[(0,d.jsx)(C.TooltipTrigger,{render:(0,d.jsx)(x.CircleHelp,{className:"size-3.5 shrink-0 cursor-help text-muted-foreground"})}),(0,d.jsx)(C.TooltipContent,{children:"Keep the old key valid for this duration after rotation. Both keys work during this period for seamless cutover. Empty = immediate revoke."})]})]}),description:(0,d.jsx)("span",{className:"text-xs",children:"Recommended: 24h to 72h for production keys"}),children:({ref:e,...t})=>(0,d.jsx)(S.Input,{...t,ref:e,placeholder:"e.g. 24h, 2d"})})]})]})})}),(0,d.jsx)(p.DialogFooter,{children:n?(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(u.Button,{variant:"outline",onClick:H,children:"Close"}),(0,d.jsx)(v.CopyToClipboard,{text:n,onCopy:()=>{D(!0)},children:(0,d.jsxs)(u.Button,{children:[z?(0,d.jsx)(g.Check,{}):(0,d.jsx)(h.Copy,{}),z?"Copied":"Copy Key"]})})]}):(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(u.Button,{variant:"outline",onClick:H,children:"Cancel"}),(0,d.jsxs)(u.Button,{onClick:()=>{e&&r&&(P(!0),L.handleSubmit(U,()=>P(!1))())},disabled:I,"aria-busy":I,children:[(0,d.jsx)(_.RefreshCw,{}),"Regenerate"]})]})})]})})}],272753)},433344,26761,418300,618938,e=>{"use strict";let t={hourly:"1h",daily:"24h",weekly:"7d",monthly:"30d"},s=e=>e?t[e]??e:null;e.s(["canonicalBudgetDuration",0,s,"currentValuePlaceholder",0,(e,t,s,a)=>e?Array.isArray(t)&&t.length>0?`Current: ${t.join(", ")}`:a:s,"keyTypeFromRoutes",0,e=>e&&0!==e.length?e.includes("llm_api_routes")?"llm_api":e.includes("management_routes")?"management":e.includes("info_routes")?"read_only":"default":"default","modelSentinelOptions",0,(e,t)=>null==e?[{value:"all-proxy-models",label:"All Proxy Models"}]:t?[{value:"all-team-models",label:"All Team Models"}]:[],"parseAllowedRoutes",0,e=>"string"==typeof e&&""!==e.trim()?e.split(",").map(e=>e.trim()).filter(e=>e.length>0):[]],433344);var a=e.i(843476),l=e.i(967489),i=e.i(746798),r=e.i(359360);let n=[{value:"default",label:"Full Access",hint:"Can call all routes (AI APIs, Management, and read-only)"},{value:"llm_api",label:"AI APIs",hint:"Can call only AI API routes (chat/completions, embeddings, etc.)"},{value:"management",label:"Management",hint:"Can call only management routes (user/team/key management)"}];e.s(["KeyTypeSelect",0,({id:e,value:t,onChange:s})=>(0,a.jsxs)(l.Select,{items:Object.fromEntries(n.map(e=>[e.value,e.label])),value:t,onValueChange:e=>null!=e&&s(e),children:[(0,a.jsx)(l.SelectTrigger,{id:e,className:"w-full",children:(0,a.jsx)(l.SelectValue,{placeholder:"Select key type"})}),(0,a.jsx)(l.SelectContent,{children:n.map(e=>(0,a.jsx)(l.SelectItem,{value:e.value,children:(0,a.jsxs)("div",{className:"py-1",children:[(0,a.jsx)("div",{className:"font-medium",children:e.label}),(0,a.jsx)("div",{className:"mt-0.5 text-[11px] text-muted-foreground",children:e.hint})]})},e.value))})]}),"labelWithHint",0,(e,t)=>(0,a.jsxs)(a.Fragment,{children:[e,(0,a.jsxs)(i.Tooltip,{children:[(0,a.jsx)(i.TooltipTrigger,{render:(0,a.jsx)(r.CircleHelp,{className:"size-3.5 shrink-0 cursor-help text-muted-foreground"})}),(0,a.jsx)(i.TooltipContent,{className:"max-w-xs",children:t})]})]})],26761);var o=e.i(681307),d=e.i(721929),c=e.i(557662),m=e.i(597427);let u=(e,t)=>null!=e.metadata&&"object"==typeof e.metadata?e.metadata[t]:void 0,p=o.z.object({key_alias:o.z.custom(),models:o.z.custom(),allowed_routes:o.z.custom(),max_budget:o.z.custom(),budget_duration:o.z.custom(),tpm_limit:o.z.custom(),tpm_limit_type:o.z.custom(),rpm_limit:o.z.custom(),rpm_limit_type:o.z.custom(),throttle_on_budget_exceeded:o.z.custom(),enable_prompt_caching:o.z.custom(),max_parallel_requests:o.z.custom(),model_tpm_limit:o.z.custom(),model_rpm_limit:o.z.custom(),default_estimated_output_tokens:o.z.custom().refine(m.estimateChecks.positive.isValid,m.estimateChecks.positive.message),default_estimated_output_tokens_per_model:o.z.custom().refine(m.estimateChecks.perModel.isValid,m.estimateChecks.perModel.message),guardrails:o.z.custom(),disable_global_guardrails:o.z.custom(),policies:o.z.custom(),tags:o.z.custom(),prompts:o.z.custom(),access_group_ids:o.z.custom(),allowed_passthrough_routes:o.z.custom(),vector_stores:o.z.custom(),mcp_servers_and_groups:o.z.custom(),mcp_tool_permissions:o.z.custom(),agents_and_groups:o.z.custom(),organization_id:o.z.custom(),team_id:o.z.custom(),logging_settings:o.z.custom(),metadata:o.z.custom(),duration:o.z.custom(),token:o.z.custom(),disabled_callbacks:o.z.custom(),auto_rotate:o.z.custom(),rotation_interval:o.z.custom()});e.s(["keyEditFormSchema",0,p,"toKeyEditFormValues",0,e=>({key_alias:e.key_alias,models:e.models,allowed_routes:Array.isArray(e.allowed_routes)&&e.allowed_routes.length>0?e.allowed_routes.join(", "):"",max_budget:e.max_budget,budget_duration:s(e.budget_duration),tpm_limit:e.tpm_limit,tpm_limit_type:e.tpm_limit_type??null,rpm_limit:e.rpm_limit,rpm_limit_type:e.rpm_limit_type??null,throttle_on_budget_exceeded:!!u(e,"throttle_on_budget_exceeded"),enable_prompt_caching:!!u(e,"enable_prompt_caching"),max_parallel_requests:e.max_parallel_requests,model_tpm_limit:e.model_tpm_limit,model_rpm_limit:e.model_rpm_limit,...(0,m.estimateFields)(e.metadata),guardrails:u(e,"guardrails"),disable_global_guardrails:!!u(e,"disable_global_guardrails"),policies:e.policies,tags:u(e,"tags"),prompts:u(e,"prompts"),access_group_ids:e.access_group_ids||[],allowed_passthrough_routes:e.allowed_passthrough_routes,vector_stores:e.object_permission?.vector_stores||[],mcp_servers_and_groups:{servers:e.object_permission?.mcp_servers||[],accessGroups:e.object_permission?.mcp_access_groups||[],toolsets:e.object_permission?.mcp_toolsets||[]},mcp_tool_permissions:e.object_permission?.mcp_tool_permissions||{},agents_and_groups:{agents:e.object_permission?.agents||[],accessGroups:e.object_permission?.agent_access_groups||[]},organization_id:e.organization_id,team_id:e.team_id,logging_settings:(0,d.extractLoggingSettings)(e.metadata),metadata:(0,d.formatMetadataForDisplay)((0,d.stripTagsFromMetadata)(e.metadata)),duration:e.duration??"",token:e.token||e.token_id,disabled_callbacks:Array.isArray(u(e,"litellm_disabled_callbacks"))?(0,c.mapInternalToDisplayNames)(u(e,"litellm_disabled_callbacks")):[],auto_rotate:e.auto_rotate||!1,rotation_interval:e.rotation_interval}),"toSubmittedValues",0,(e,{canViewPolicies:t,canViewPrompts:s})=>({key_alias:e.key_alias,models:e.models,allowed_routes:e.allowed_routes,max_budget:e.max_budget,budget_duration:e.budget_duration,tpm_limit:e.tpm_limit,tpm_limit_type:e.tpm_limit_type,rpm_limit:e.rpm_limit,rpm_limit_type:e.rpm_limit_type,throttle_on_budget_exceeded:e.throttle_on_budget_exceeded,enable_prompt_caching:e.enable_prompt_caching,max_parallel_requests:e.max_parallel_requests,model_tpm_limit:e.model_tpm_limit,model_rpm_limit:e.model_rpm_limit,default_estimated_output_tokens:e.default_estimated_output_tokens,default_estimated_output_tokens_per_model:e.default_estimated_output_tokens_per_model,guardrails:e.guardrails,disable_global_guardrails:e.disable_global_guardrails,...t?{policies:e.policies}:{},tags:e.tags,...s?{prompts:e.prompts}:{},access_group_ids:e.access_group_ids,allowed_passthrough_routes:e.allowed_passthrough_routes,vector_stores:e.vector_stores,mcp_servers_and_groups:e.mcp_servers_and_groups,mcp_tool_permissions:e.mcp_tool_permissions,agents_and_groups:e.agents_and_groups,organization_id:e.organization_id,team_id:e.team_id,logging_settings:e.logging_settings,metadata:e.metadata,duration:e.duration,token:e.token,disabled_callbacks:e.disabled_callbacks,auto_rotate:e.auto_rotate,rotation_interval:e.rotation_interval})],418300);var g=e.i(904031),x=e.i(953563);e.s(["useModelMaxBudgetField",0,function(e,t){let[s,a]=(0,x.useSeededState)(e,()=>t??{});return{value:s,setValue:a,applyTo:e=>{let a=(0,g.modelMaxBudgetUpdate)(s,t);void 0!==a&&(e.model_max_budget=a)}}}],618938)},20147,e=>{"use strict";var t=e.i(843476),s=e.i(135214),a=e.i(510674),l=e.i(292639),i=e.i(214541),r=e.i(109799),n=e.i(500330),o=e.i(11751),d=e.i(871689),c=e.i(487486),m=e.i(519455),u=e.i(515288),p=e.i(776639),g=e.i(677572),x=e.i(67488),h=e.i(422444),_=e.i(556908),f=e.i(784647),j=e.i(422183),b=e.i(271645),v=e.i(708347),y=e.i(557662),k=e.i(505022),N=e.i(127952),w=e.i(331755),S=e.i(875989),C=e.i(721929),T=e.i(643449),A=e.i(417385),E=e.i(602869),R=e.i(65932),F=e.i(286047),M=e.i(207082),I=e.i(912598),P=e.i(500727),z=e.i(699857),D=e.i(247482),O=e.i(384767),B=e.i(272753),L=e.i(190702),K=e.i(92982),V=e.i(891547),U=e.i(921511),H=e.i(793479),$=e.i(967489),W=e.i(699375),q=e.i(624687),G=e.i(746798),J=e.i(571303),Q=e.i(542450),Y=e.i(182668),X=e.i(751247),Z=e.i(552130),ee=e.i(9314),et=e.i(860585),es=e.i(392110),ea=e.i(844565),el=e.i(939510),ei=e.i(363256),er=e.i(460285),en=e.i(597427),eo=e.i(433344),ed=e.i(26761),ec=e.i(418300),em=e.i(128233),eu=e.i(558364),ep=e.i(618938),eg=e.i(319312),ex=e.i(833400),eh=e.i(355619),e_=e.i(75921),ef=e.i(234713),ej=e.i(390605),eb=e.i(702597),ev=e.i(435451),ey=e.i(845150),ek=e.i(421436),eN=e.i(183588),ew=e.i(991326),eS=e.i(916940);function eC({keyData:e,onCancel:s,onSubmit:i,teams:n,accessToken:o,userID:d,userRole:c,premiumUser:u=!1}){let p=u||null!=c&&v.rolesWithWriteAccess.includes(c),g=(0,X.hasCapability)(c,"viewPolicies"),x=(0,X.hasCapability)(c,"viewPrompts"),h=null!=c&&(0,v.isProxyAdminRole)(c),_=(0,en.estimateTooltips)(h),f=(0,ew.useZodForm)(ec.keyEditFormSchema,{defaultValues:(0,ec.toKeyEditFormValues)(e)}),[j,k]=(0,b.useState)([]),[N,w]=(0,b.useState)({}),C=n?.find(t=>t.team_id===e.team_id),[T,R]=(0,b.useState)([]),[F,M]=(0,b.useState)(Array.isArray(e.metadata?.litellm_disabled_callbacks)?(0,y.mapInternalToDisplayNames)(e.metadata.litellm_disabled_callbacks):[]),[I,P]=(0,b.useState)(e.organization_id||null),[z,D]=(0,b.useState)(e.auto_rotate||!1),[O,B]=(0,b.useState)(e.rotation_interval||""),[L,K]=(0,b.useState)(!e.expires),[eT,eA]=(0,b.useState)(!1),[eE,eR]=(0,b.useState)(Array.isArray(e.budget_limits)?e.budget_limits:[]),[eF,eM]=(0,b.useState)((0,ex.tagLimitsToRows)(e.metadata?.tag_rpm_limit)),[eI,eP]=(0,b.useState)(e.budget_fallbacks&&"object"==typeof e.budget_fallbacks?e.budget_fallbacks:{}),ez=(0,ep.useModelMaxBudgetField)(e.token,e.model_max_budget),eD=(0,b.useRef)(null),eO=b.default.useId(),eB=b.default.useId(),{data:eL,isLoading:eK}=(0,r.useOrganizations)(),{data:eV}=(0,a.useProjects)(),{data:eU}=(0,l.useUISettings)(),eH=!!eU?.values?.enable_projects_ui,e$=!!e.project_id,eW=(()=>{if(!e.project_id)return null;let t=eV?.find(t=>t.project_id===e.project_id);return t?.project_alias?`${t.project_alias} (${e.project_id})`:e.project_id})(),eq=f.watch("allowed_routes"),eG=f.watch("models")??[],eJ=(0,eo.parseAllowedRoutes)(eq),eQ=eJ.includes("management_routes")||eJ.includes("info_routes"),eY=f.watch("mcp_servers_and_groups"),eX=f.watch("mcp_tool_permissions");(0,b.useEffect)(()=>{let t=async()=>{if(d&&c&&o)try{if(null===e.team_id){let e=(await (0,E.modelAvailableCall)(o,d,c)).data.map(e=>e.id);R((0,eh.excludeProxyWideSentinel)(e))}else if(C?.team_id){let e=await (0,eb.fetchTeamModels)(d,c,o,C.team_id);R((0,eh.excludeProxyWideSentinel)(Array.from(new Set([...C.models,...e]))))}}catch(e){console.error("Error fetching models:",e)}},s=async()=>{if(o)try{let e=await (0,E.getPromptsList)(o);k(e.prompts.map(e=>e.prompt_id))}catch(e){console.error("Failed to fetch prompts:",e)}};x&&s(),t()},[d,c,o,C,e.team_id,x]),(0,b.useEffect)(()=>{f.setValue("disabled_callbacks",F)},[f,F]),(0,b.useEffect)(()=>{f.reset((0,ec.toKeyEditFormValues)(e))},[e,f]),(0,b.useEffect)(()=>{f.setValue("auto_rotate",z)},[z,f]),(0,b.useEffect)(()=>{O&&f.setValue("rotation_interval",O)},[O,f]),(0,b.useEffect)(()=>{(async()=>{if(o)try{let e=await (0,E.tagListCall)(o);w(e)}catch(e){A.toast.fromError("Error fetching tags: "+e)}})()},[o]);let eZ=async t=>{try{if(eA(!0),"string"==typeof t.allowed_routes){let e=t.allowed_routes.trim();""===e?t.allowed_routes=[]:t.allowed_routes=e.split(",").map(e=>e.trim()).filter(e=>e.length>0)}let s=new Set(Array.isArray(e.allowed_routes)?e.allowed_routes:[]),a=new Set(Array.isArray(t.allowed_routes)?t.allowed_routes:[]);s.size===a.size&&[...a].every(e=>s.has(e))&&delete t.allowed_routes,L&&(t.duration=null),e.budget_duration&&!t.budget_duration&&(t.budget_duration=null);let l=e=>(e??[]).filter(e=>e.budget_duration&&null!==e.max_budget&&void 0!==e.max_budget).map(e=>`${e.budget_duration}:${e.max_budget}`).sort().join("|"),r=eE.filter(e=>e.budget_duration&&null!==e.max_budget&&void 0!==e.max_budget);l(e.budget_limits)===l(r)||(r.length>0?t.budget_limits=r:0===eE.length&&(t.budget_limits=[]));let{tag_rpm_limit:n}=(0,ex.tagRowsToLimits)(eF);t.tag_rpm_limit=n;let o=null!=e.budget_fallbacks&&Object.keys(e.budget_fallbacks).length>0;Object.keys(eI).length>0?t.budget_fallbacks=eI:o&&(t.budget_fallbacks={}),ez.applyTo(t);let d=(0,S.routerSettingsUpdate)(eD.current?.getValue()?.router_settings,e.router_settings);d&&(t.router_settings=d),await i((0,en.withNormalizedEstimates)(t))}finally{eA(!1)}},e0=e=>{M((0,y.mapInternalToDisplayNames)(e)),f.setValue("disabled_callbacks",e)},e1=[...(0,eo.modelSentinelOptions)(e.team_id,null!=C),...T.map(e=>({value:e,label:e,disabled:(0,eh.hasAllModelsSentinel)(eG)}))],e4=I?n?.filter(e=>e.organization_id===I):n;return(0,t.jsx)(G.TooltipProvider,{children:(0,t.jsxs)("form",{onSubmit:f.handleSubmit(e=>eZ((0,ec.toSubmittedValues)(e,{canViewPolicies:g,canViewPrompts:x}))),children:[(0,t.jsxs)(Q.FieldGroup,{children:[(0,t.jsx)(Y.FormField,{control:f.control,name:"key_alias",label:"Key Alias",children:e=>(0,t.jsx)(H.Input,{...e,value:e.value??""})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"models",label:"Models",description:eQ?"Models field is disabled for this key type":void 0,children:({value:e,onChange:s,id:a})=>(0,t.jsx)(ey.MultiSelect,{id:a,options:e1,value:eQ?[]:e??[],onValueChange:e=>{e.includes("all-team-models")?s(["all-team-models"]):e.includes("all-proxy-models")?s(["all-proxy-models"]):s(e)},disabled:eQ,placeholder:"Select models"})}),(0,t.jsxs)(Q.Field,{children:[(0,t.jsx)(Q.FieldLabel,{htmlFor:eO,children:"Key Type"}),(0,t.jsx)(ed.KeyTypeSelect,{id:eO,value:(0,eo.keyTypeFromRoutes)(eJ),onChange:e=>{switch(e){case"default":f.setValue("allowed_routes","");break;case"llm_api":f.setValue("allowed_routes","llm_api_routes");break;case"management":f.setValue("allowed_routes","management_routes"),f.setValue("models",[])}}})]}),(0,t.jsx)(Y.FormField,{control:f.control,name:"allowed_routes",label:(0,ed.labelWithHint)("Allowed Routes","List of allowed routes for the key (comma-separated). Can be specific routes (e.g., '/chat/completions') or route patterns (e.g., 'llm_api_routes', 'management_routes', '/keys/*'). Leave empty to allow all routes."),children:e=>(0,t.jsx)(H.Input,{...e,value:e.value??"",placeholder:"Enter allowed routes (comma-separated). Special values: llm_api_routes, management_routes. Examples: llm_api_routes, /chat/completions, /keys/*. Leave empty to allow all routes"})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"max_budget",label:"Max Budget (USD)",children:({ref:e,...s})=>(0,t.jsx)(ev.default,{...s,value:s.value??"",step:.01,style:{width:"100%"},placeholder:"Enter a numerical value"})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"budget_duration",label:"Reset Budget",children:({value:e,onChange:s,id:a})=>(0,t.jsx)(et.default,{id:a,value:e,onChange:e=>s(e??null),placeholder:"Never resets"})}),(0,t.jsxs)(Q.Field,{children:[(0,t.jsx)(Q.FieldLabel,{children:(0,ed.labelWithHint)("Budget Windows","Set multiple independent budget windows (e.g., hourly $10 AND monthly $200). Each window tracks spend separately and resets on its own schedule.")}),(0,t.jsx)(eg.BudgetWindowsEditor,{value:eE,onChange:eR})]}),(0,t.jsx)(eu.ModelMaxBudgetField,{premiumUser:u,value:ez.value,onChange:ez.setValue,availableModels:T,usage:e.model_max_budget_usage,hint:"Cap spend on individual models, each with its own reset window. Enforced across every request this key makes."},e.token),(0,t.jsxs)(Q.Field,{children:[(0,t.jsx)(Q.FieldLabel,{children:(0,ed.labelWithHint)("Budget Fallbacks","When a model exceeds its per-model budget, requests automatically reroute to fallback models instead of failing")}),(0,t.jsx)(em.BudgetFallbacksEditor,{value:eI,onChange:eP,availableModels:T})]}),(0,t.jsx)(Y.FormField,{control:f.control,name:"tpm_limit",label:"TPM Limit",children:({ref:e,...s})=>(0,t.jsx)(ev.default,{...s,value:s.value??"",min:0})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"tpm_limit_type",children:({value:e,onChange:s,id:a})=>(0,t.jsx)(el.default,{id:a,type:"tpm",name:"tpm_limit_type",showDetailedDescriptions:!1,value:e,onChange:s})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"rpm_limit",label:"RPM Limit",children:({ref:e,...s})=>(0,t.jsx)(ev.default,{...s,value:s.value??"",min:0})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"rpm_limit_type",children:({value:e,onChange:s,id:a})=>(0,t.jsx)(el.default,{id:a,type:"rpm",name:"rpm_limit_type",showDetailedDescriptions:!1,value:e,onChange:s})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"throttle_on_budget_exceeded",label:(0,ed.labelWithHint)("Throttle on budget exceeded","When this key exceeds its max budget, throttle its TPM/RPM to the globally configured percentage instead of blocking access entirely. Requires budget_exceeded_throttle_percentage in litellm_settings and a TPM/RPM limit on the key."),children:({value:e,onChange:s,ref:a,...l})=>(0,t.jsx)(W.Switch,{...l,checked:!!e,onCheckedChange:s})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"enable_prompt_caching",label:(0,ed.labelWithHint)("Enable Prompt Caching","Automatically add prompt caching breakpoints (cache_control markers) to requests made with this key, cutting input cost on repeated prompts. Applies to Anthropic and Bedrock Claude models; requests that already set their own cache_control markers are left untouched."),children:({value:e,onChange:s,ref:a,...l})=>(0,t.jsx)(W.Switch,{...l,checked:!!e,onCheckedChange:s})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"max_parallel_requests",label:"Max Parallel Requests",children:({ref:e,...s})=>(0,t.jsx)(ev.default,{...s,value:s.value??"",min:0})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"model_tpm_limit",label:"Model TPM Limit",children:e=>(0,t.jsx)(q.Textarea,{...e,value:e.value??"",rows:4,placeholder:'{"gpt-4": 100, "claude-v1": 200}'})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"model_rpm_limit",label:"Model RPM Limit",children:e=>(0,t.jsx)(q.Textarea,{...e,value:e.value??"",rows:4,placeholder:'{"gpt-4": 100, "claude-v1": 200}'})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"default_estimated_output_tokens",label:(0,ed.labelWithHint)("Estimated Output Tokens",_.estimate),children:({ref:e,...s})=>(0,t.jsx)(ev.default,{...s,value:s.value??"",min:1,step:1,disabled:!h})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"default_estimated_output_tokens_per_model",label:(0,ed.labelWithHint)("Estimated Output Tokens Per Model",_.perModel),children:e=>(0,t.jsx)(q.Textarea,{...e,value:e.value??"",rows:4,placeholder:'{"gpt-4": 4096}',disabled:!h})}),(0,t.jsxs)(Q.Field,{children:[(0,t.jsx)(Q.FieldLabel,{children:(0,ed.labelWithHint)("Per-Tag Rate Limits","Scope rate limits to a request tag so each tag (e.g. a cell or group) gets its own RPM counter. Requests without a matching tag fall back to the key-level limit.")}),(0,t.jsx)(ex.TagRateLimitEditor,{value:eF,onChange:eM})]}),(0,t.jsx)(Y.FormField,{control:f.control,name:"guardrails",label:"Guardrails",children:({value:e,onChange:s})=>o?(0,t.jsx)(V.default,{onChange:s,value:e,accessToken:o,disabled:!p}):(0,t.jsx)("div",{})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"disable_global_guardrails",label:(0,ed.labelWithHint)("Disable Global Guardrails","When enabled, this key will bypass any guardrails configured to run on every request (global guardrails)"),children:({value:e,onChange:s,ref:a,...l})=>(0,t.jsx)(W.Switch,{...l,checked:!!e,onCheckedChange:s,disabled:!p})}),g&&(0,t.jsx)(Y.FormField,{control:f.control,name:"policies",label:(0,ed.labelWithHint)("Policies","Apply policies to this key to control guardrails and other settings"),children:({value:e,onChange:s})=>o?(0,t.jsx)(U.default,{onChange:s,value:e,accessToken:o,disabled:!u}):(0,t.jsx)("div",{})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"tags",label:"Tags",children:({value:e,onChange:s,id:a})=>(0,t.jsx)(ek.TagsInput,{id:a,value:e??[],onValueChange:s,options:Object.values(N).map(e=>({value:e.name,label:e.name})),placeholder:"Select or enter tags"})}),x&&(0,t.jsx)(Y.FormField,{control:f.control,name:"prompts",label:u?"Prompts":(0,ed.labelWithHint)("Prompts","Setting prompts by key is a premium feature"),children:({value:s,onChange:a,id:l})=>(0,t.jsx)(ek.TagsInput,{id:l,value:s??[],onValueChange:a,options:j.map(e=>({value:e,label:e})),disabled:!u,placeholder:(0,eo.currentValuePlaceholder)(u,e.metadata?.prompts,"Premium feature - Upgrade to set prompts by key","Select or enter prompts")})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"access_group_ids",label:(0,ed.labelWithHint)("Access Groups","Assign access groups to this key. Access groups control which models, MCP servers, and agents this key can use"),children:({value:e,onChange:s})=>(0,t.jsx)(ee.default,{value:e,onChange:s,placeholder:"Select access groups (optional)"})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"allowed_passthrough_routes",label:u?"Allowed Pass Through Routes":(0,ed.labelWithHint)("Allowed Pass Through Routes","Setting allowed pass through routes by key is a premium feature"),children:({value:s,onChange:a})=>(0,t.jsx)(ea.default,{value:s,onChange:a,accessToken:o||"",placeholder:(0,eo.currentValuePlaceholder)(u,e.metadata?.allowed_passthrough_routes,"Premium feature - Upgrade to set allowed pass through routes by key","Select or enter allowed pass through routes"),disabled:!u})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"vector_stores",label:"Vector Stores",children:({value:e,onChange:s})=>(0,t.jsx)(eS.default,{onChange:s,value:e,accessToken:o||"",placeholder:"Select vector stores"})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"mcp_servers_and_groups",label:"MCP Servers / Access Groups",children:({value:e,onChange:s})=>(0,t.jsx)(e_.default,{onChange:s,value:e,accessToken:o||"",placeholder:"Select MCP servers or access groups (optional)",allowNoMcpServers:!0})}),(0,t.jsx)("div",{className:"mb-6",children:(0,t.jsx)(ej.default,{accessToken:o||"",selectedServers:(eY?.servers||[]).filter(e=>e!==ef.NO_MCP_SERVERS_SENTINEL),toolPermissions:eX||{},onChange:e=>f.setValue("mcp_tool_permissions",e)})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"agents_and_groups",label:"Agents / Access Groups",children:({value:e,onChange:s})=>(0,t.jsx)(Z.default,{onChange:s,value:e,accessToken:o||"",placeholder:"Select agents or access groups (optional)"})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"organization_id",label:(0,ed.labelWithHint)("Organization","The organization this key belongs to. Selecting an organization filters the available teams."),children:({value:e,onChange:s,id:a})=>(0,t.jsx)(ei.default,{id:a,value:e??void 0,organizations:eL,loading:eK,disabled:"Admin"!==c,onChange:e=>{s(e),P(e||null),f.setValue("team_id",void 0)}})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"team_id",label:"Team ID",description:eH&&e$?"Team is locked because this key belongs to a project":void 0,children:({value:e,onChange:s,id:a})=>(0,t.jsxs)($.Select,{value:e??null,onValueChange:e=>{let t;return s(e),t=n?.find(t=>t.team_id===e)||null,void(t?.organization_id?(P(t.organization_id),f.setValue("organization_id",t.organization_id)):!e&&(P(null),f.setValue("organization_id",void 0)))},disabled:eH&&e$,items:Object.fromEntries((e4??[]).map(e=>[e.team_id,`${e.team_alias} (${e.team_id})`])),children:[(0,t.jsx)($.SelectTrigger,{id:a,className:"w-full",children:(0,t.jsx)($.SelectValue,{placeholder:"Select team"})}),(0,t.jsx)($.SelectContent,{children:e4?.map(e=>(0,t.jsx)($.SelectItem,{value:e.team_id,children:`${e.team_alias} (${e.team_id})`},e.team_id))})]})}),eH&&e$&&(0,t.jsxs)(Q.Field,{children:[(0,t.jsx)(Q.FieldLabel,{htmlFor:eB,children:"Project"}),(0,t.jsx)(H.Input,{id:eB,value:eW??"",disabled:!0,readOnly:!0})]}),(0,t.jsxs)(Q.Field,{children:[(0,t.jsx)(Q.FieldLabel,{children:"Router Settings"}),(0,t.jsx)(er.default,{ref:eD,accessToken:o||"",teamId:e.team_id,value:(0,S.routerSettingsEditorValue)(e.router_settings)})]}),(0,t.jsx)(Y.FormField,{control:f.control,name:"logging_settings",label:"Logging Settings",children:({value:e,onChange:s})=>(0,t.jsx)(eN.default,{value:e??[],onChange:s,disabledCallbacks:F,onDisabledCallbacksChange:e0})}),(0,t.jsx)(Y.FormField,{control:f.control,name:"metadata",label:"Metadata",children:e=>(0,t.jsx)(q.Textarea,{...e,value:e.value??"",rows:10})}),(0,t.jsx)("div",{className:"mb-4",children:(0,t.jsx)(Y.FormField,{control:f.control,name:"duration",children:({value:e,onChange:s,id:a})=>(0,t.jsx)(es.default,{id:a,value:e??"",onChange:s,autoRotationEnabled:z,onAutoRotationChange:D,rotationInterval:O,onRotationIntervalChange:B,neverExpire:L,onNeverExpireChange:K})})})]}),(0,t.jsx)("div",{className:"sticky z-chrome bg-background p-4 border-t border-border -bottom-6 -inset-x-6",children:(0,t.jsxs)("div",{className:"flex justify-end items-center gap-2",children:[(0,t.jsx)(m.Button,{type:"button",variant:"secondary",onClick:s,disabled:eT,children:"Cancel"}),(0,t.jsxs)(m.Button,{type:"submit",disabled:eT,"aria-busy":eT,children:[eT&&(0,t.jsx)(J.UiLoadingSpinner,{className:"size-4"}),"Save Changes"]})]})})]})})}let eT=["policies","guardrails","prompts","tags","allowed_passthrough_routes"],eA=e=>null==e||Array.isArray(e)&&0===e.length||"string"==typeof e&&""===e.trim();e.s(["default",0,function({onClose:e,keyData:V,teams:U,onKeyDataUpdate:H,onDelete:$,backButtonText:W="Back to Keys"}){let q,{accessToken:G,userId:J,userRole:Q,premiumUser:Y}=(0,s.default)(),X=(0,I.useQueryClient)(),Z=Y||null!=Q&&v.rolesWithWriteAccess.includes(Q),{teams:ee}=(0,i.default)(),{data:et}=(0,r.useOrganizations)(),{data:es}=(0,a.useProjects)(),{data:ea}=(0,l.useUISettings)(),{data:el}=(0,P.useMCPServers)(),{data:ei}=(0,z.useMCPToolsets)(),er=!!ea?.values?.enable_projects_ui,[en,eo]=(0,b.useState)(!1),[ed,ec]=(0,b.useState)(!1),[em,eu]=(0,b.useState)(!1),[ep,eg]=(0,b.useState)(!1),[ex,eh]=(0,b.useState)(!1),[e_,ef]=(0,b.useState)(!1),{mutate:ej,isPending:eb}=(0,R.useResetKeySpend)(),{mutate:ev,isPending:ey}=(0,F.useSetKeyBlockedState)(),[ek,eN]=(0,b.useState)(V),[ew,eS]=(0,b.useState)(null),[eE,eR]=(0,b.useState)(null),[eF,eM]=(0,b.useState)(!1),[eI,eP]=(0,b.useState)({}),[ez,eD]=(0,b.useState)(!1);if((0,b.useEffect)(()=>{V&&eN(V)},[V]),(0,b.useEffect)(()=>{(async()=>{let e=ek?.metadata?.policies;if(!G||!e||!Array.isArray(e)||0===e.length)return;eD(!0);let t={};try{await Promise.all(e.map(async e=>{try{let s=await (0,E.getPolicyInfoWithGuardrails)(G,e);t[e]=s.resolved_guardrails||[]}catch(s){console.error(`Failed to fetch guardrails for policy ${e}:`,s),t[e]=[]}})),eP(t)}catch(e){console.error("Failed to fetch policy guardrails:",e)}finally{eD(!1)}})()},[G,ek?.metadata?.policies]),(0,b.useEffect)(()=>{if(eF){let e=setTimeout(()=>{eM(!1)},5e3);return()=>clearTimeout(e)}},[eF]),!ek)return(0,t.jsxs)("div",{className:"p-4",children:[(0,t.jsxs)(m.Button,{variant:"ghost",onClick:e,className:"mb-4",children:[(0,t.jsx)(d.ArrowLeft,{className:"size-4"}),W]}),(0,t.jsx)("p",{className:"text-sm",children:"Key not found"})]});let eO=async e=>{try{if(!G)return;let t=e.token;for(let s of(e.key=t,Z||(delete e.guardrails,delete e.prompts),eT)){let t=ek.metadata?.[s]??ek[s];eA(e[s])&&eA(t)&&delete e[s]}let s=!!ek.metadata?.disable_global_guardrails;!!e.disable_global_guardrails===s&&delete e.disable_global_guardrails,e.max_budget=(0,o.mapEmptyStringToNull)(e.max_budget),void 0!==e.vector_stores&&(e.object_permission={...ek.object_permission,vector_stores:e.vector_stores||[]},delete e.vector_stores);let a=(0,D.extractMcpEntitlement)(e,el??[],ei??[]);if(a){if((void 0===el||a.mcp_toolsets.some(e=>!(ei??[]).some(t=>t.toolset_id===e)))&&Object.keys(a.mcp_tool_permissions).length>0)return void A.toast.error("MCP server or toolset list is unavailable, so MCP permissions cannot be saved yet. Retry.");e.object_permission={...e.object_permission??ek.object_permission,...a}}if(delete e.mcp_servers_and_groups,delete e.mcp_tool_permissions,void 0!==e.agents_and_groups){let{agents:t,accessGroups:s}=e.agents_and_groups||{agents:[],accessGroups:[]};e.object_permission={...e.object_permission,agents:t||[],agent_access_groups:s||[]},delete e.agents_and_groups}if(e.max_budget=(0,o.mapEmptyStringToNull)(e.max_budget),e.tpm_limit=(0,o.mapEmptyStringToNull)(e.tpm_limit),e.rpm_limit=(0,o.mapEmptyStringToNull)(e.rpm_limit),e.max_parallel_requests=(0,o.mapEmptyStringToNull)(e.max_parallel_requests),e.metadata&&"string"==typeof e.metadata)try{let t=JSON.parse(e.metadata);"tags"in t&&delete t.tags,e.metadata={...t,...Array.isArray(e.tags)&&e.tags.length>0?{tags:e.tags}:{},...e.guardrails?.length>0?{guardrails:e.guardrails}:{},...Array.isArray(e.logging_settings)&&e.logging_settings.length>0?{logging:e.logging_settings}:{},...e.disabled_callbacks?.length>0?{litellm_disabled_callbacks:(0,y.mapDisplayToInternalNames)(e.disabled_callbacks)}:{}}}catch(e){console.error("Error parsing metadata JSON:",e),A.toast.error("Invalid metadata JSON");return}else{let{tags:t,...s}=e.metadata||{};e.metadata={...s,...Array.isArray(e.tags)&&e.tags.length>0?{tags:e.tags}:{},...e.guardrails?.length>0?{guardrails:e.guardrails}:{},...Array.isArray(e.logging_settings)&&e.logging_settings.length>0?{logging:e.logging_settings}:{},...e.disabled_callbacks?.length>0?{litellm_disabled_callbacks:(0,y.mapDisplayToInternalNames)(e.disabled_callbacks)}:{}}}"tags"in e&&delete e.tags,delete e.logging_settings,e.budget_duration&&(e.budget_duration=({hourly:"1h",daily:"24h",weekly:"7d",monthly:"30d"})[e.budget_duration]??e.budget_duration);let l=await (0,E.keyUpdateCall)(G,e);eN(e=>e?{...e,...l}:void 0),H&&H(l),A.toast.success("Key updated successfully"),eo(!1)}catch(e){A.toast.fromError((0,L.parseErrorMessage)(e)),console.error("Error updating key:",e)}},eB=async()=>{try{if(eu(!0),!G)return;await (0,E.keyDeleteCall)(G,ek.token||ek.token_id),A.toast.success("Key deleted successfully"),await X.invalidateQueries({queryKey:M.keyKeys.lists()}),$&&$(),e()}catch(e){console.error("Error deleting the key:",e),A.toast.fromError(e)}finally{eu(!1),ec(!1)}},eL=e=>{let t=new Date(e),s=t.toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}),a=t.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0});return`${s} at ${a}`},eK=(0,v.isProxyAdminRole)(Q||"")||ee&&(0,v.isUserTeamAdminForSingleTeam)(ee?.filter(e=>e.team_id===ek.team_id)[0]?.members_with_roles,J||"")||J===ek.user_id&&"Internal Viewer"!==Q,eV=(0,v.isProxyAdminRole)(Q||"")||!!(ee&&(0,v.isUserTeamAdminForSingleTeam)(ee?.filter(e=>e.team_id===ek.team_id)[0]?.members_with_roles,J||"")),eU=!0===ek.blocked,eH=ek.settings_updated_at||ek.created_at,e$=ek.team_id?ee?.find(e=>e.team_id===ek.team_id):null,eW=ek.organization_id||ek.org_id||e$?.organization_id||"",eq=eW?et?.find(e=>e.organization_id===eW):null,eG=null!==ek.max_budget,eJ=eG?`$${(0,n.formatNumberWithCommas)(ek.max_budget,2)}`:"Unlimited",eQ=eG?[]:(0,K.inheritedBudgetGates)(e$,eq);return(0,t.jsxs)("div",{className:"w-full h-full overflow-y-auto p-4",children:[(0,t.jsx)(f.KeyInfoHeader,{data:{keyName:ek.key_alias||"Virtual Key",keyId:ek.token_id||ek.token,userId:ek.user_id||"",userEmail:ek.user_email||"",userAlias:ek.user?.user_alias??null,teamId:ek.team_id||"",teamAlias:e$?.team_alias??null,orgId:eW,orgAlias:eq?.organization_alias??null,createdBy:ek.created_by_user?.user_alias||ek.created_by_user?.user_email||ek.created_by||"",createdById:ek.created_by_user?.user_id||ek.created_by||"",createdAt:ek.created_at?eL(ek.created_at):"",lastUpdated:eH?eL(eH):"",lastActive:ek.last_active?eL(ek.last_active):"Never",expires:ek.expires?eL(ek.expires):"Never"},onBack:e,onRegenerate:()=>eg(!0),onDelete:()=>ec(!0),onResetSpend:eV?()=>eh(!0):void 0,onToggleBlocked:eV?()=>ef(!0):void 0,isBlocked:eU,canModifyKey:eK,backButtonText:W,regenerateDisabled:!Y,regenerateTooltip:Y?void 0:"This is a LiteLLM Enterprise feature, and requires a valid key to use."}),(0,t.jsx)(B.RegenerateKeyModal,{selectedToken:ek,visible:ep,onClose:()=>{eg(!1),eE&&(eR(null),H?.(eE))},onKeyUpdate:e=>{let t=new Date;eN(s=>{if(s)return{...s,...e,created_at:t.toLocaleString()}}),eS(t),eM(!0),eR({...e,created_at:t.toLocaleString()})}}),(0,t.jsx)(N.default,{isOpen:ed,title:"Delete Key",alertMessage:"This action is irreversible and will immediately revoke access for any applications using this key.",message:"Are you sure you want to delete this Virtual Key?",resourceInformationTitle:"Key Information",resourceInformation:[{label:"Key Alias",value:ek?.key_alias||"-"},{label:"Key ID",value:ek?.token_id||ek?.token||"-",code:!0},{label:"Team ID",value:ek?.team_id||"-",code:!0},{label:"Spend",value:ek?.spend?`$${(0,n.formatNumberWithCommas)(ek.spend,4)}`:"$0.0000"}],onCancel:()=>{ec(!1)},onOk:eB,confirmLoading:em,requiredConfirmation:ek?.key_alias}),(0,t.jsx)(p.Dialog,{open:ex,onOpenChange:e=>eh(e),children:(0,t.jsxs)(p.DialogContent,{children:[(0,t.jsx)(p.DialogHeader,{children:(0,t.jsx)(p.DialogTitle,{children:"Reset Key Spend"})}),(0,t.jsxs)("p",{children:["Reset spend for ",(0,t.jsx)("strong",{children:ek?.key_alias||ek?.token_id||"this key"})," to"," ",(0,t.jsx)("strong",{children:"$0"}),"?"]}),(0,t.jsxs)("p",{style:{color:"#666",fontSize:"0.875rem",marginTop:8},children:["Current spend: ",(0,t.jsxs)("strong",{children:["$",(0,n.formatNumberWithCommas)(ek.spend,4)]}),". Spend history is preserved in logs. This resets the current period spend counter, the same as an automatic budget reset."]}),(0,t.jsxs)(p.DialogFooter,{children:[(0,t.jsx)(m.Button,{variant:"outline",onClick:()=>eh(!1),children:"Cancel"}),(0,t.jsx)(m.Button,{variant:"destructive",onClick:()=>{ej(ek.token||ek.token_id,{onSuccess:()=>{eN(e=>e?{...e,spend:0}:void 0),H&&H({spend:0}),A.toast.success("Key spend reset to $0"),eh(!1)},onError:e=>{A.toast.fromError((0,L.parseErrorMessage)(e)),console.error("Error resetting key spend:",e)}})},disabled:eb,children:"Reset"})]})]})}),(0,t.jsx)(p.Dialog,{open:e_,onOpenChange:e=>ef(e),children:(0,t.jsxs)(p.DialogContent,{children:[(0,t.jsx)(p.DialogHeader,{children:(0,t.jsx)(p.DialogTitle,{children:eU?"Unblock Key":"Block Key"})}),(0,t.jsxs)("p",{children:[eU?"Unblock":"Block"," ",(0,t.jsx)("strong",{children:ek?.key_alias||ek?.token_id||"this key"}),"?"]}),(0,t.jsx)("p",{style:{color:"#666",fontSize:"0.875rem",marginTop:8},children:eU?"Requests using this key will be accepted again.":"Requests using this key will be rejected with a 401 error until it is unblocked. The key is not deleted and can be unblocked at any time."}),(0,t.jsxs)(p.DialogFooter,{children:[(0,t.jsx)(m.Button,{variant:"outline",onClick:()=>ef(!1),children:"Cancel"}),(0,t.jsx)(m.Button,{variant:eU?"default":"destructive",onClick:()=>{ev({keyToken:ek.token||ek.token_id,blocked:!eU},{onSuccess:e=>{let t=!0===e.blocked;eN(e=>e?{...e,blocked:t}:void 0),H&&H({blocked:t}),A.toast.success(t?"Key blocked":"Key unblocked"),ef(!1)},onError:e=>{A.toast.fromError((0,L.parseErrorMessage)(e)),console.error("Error updating key blocked state:",e)}})},disabled:ey,children:eU?"Unblock":"Block"})]})]})}),(0,t.jsxs)(g.Tabs,{defaultValue:"overview",children:[(0,t.jsxs)(g.TabsList,{variant:"line",className:"mb-4 h-auto w-full justify-start rounded-none border-b p-0",children:[(0,t.jsx)(g.TabsTrigger,{value:"overview",className:"flex-none rounded-none px-4 py-2",children:"Overview"}),(0,t.jsx)(g.TabsTrigger,{value:"savings",className:"flex-none rounded-none px-4 py-2",children:"Savings"}),(0,t.jsx)(g.TabsTrigger,{value:"settings",className:"flex-none rounded-none px-4 py-2",children:"Settings"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)(g.TabsContent,{value:"overview",keepMounted:!0,children:(0,t.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6",children:[(0,t.jsxs)(u.Card,{className:"block p-6",children:[(0,t.jsx)("p",{className:"text-sm",children:"Spend"}),(0,t.jsxs)("div",{className:"mt-2",children:[(0,t.jsxs)("h3",{className:"text-lg font-medium",children:["$",(0,n.formatNumberWithCommas)(ek.spend,4)]}),(0,t.jsxs)("p",{className:"text-sm",children:["of ",eJ,(0,t.jsx)(K.InheritedBudgetHint,{gates:eQ})]}),ek.budget_reset_at&&(0,t.jsxs)("p",{className:"text-sm",children:["Resets ",eL(ek.budget_reset_at)]})]})]}),(0,t.jsxs)(u.Card,{className:"block p-6",children:[(0,t.jsx)("p",{className:"text-sm",children:"Rate Limits"}),(0,t.jsxs)("div",{className:"mt-2",children:[(0,t.jsxs)("p",{className:"text-sm",children:["TPM: ",null!==ek.tpm_limit?ek.tpm_limit:"Unlimited"]}),(0,t.jsxs)("p",{className:"text-sm",children:["RPM: ",null!==ek.rpm_limit?ek.rpm_limit:"Unlimited"]}),!!ek.metadata?.throttle_on_budget_exceeded&&(0,t.jsx)("p",{className:"text-sm",children:"Throttle on budget exceeded: Yes"})]})]}),(0,t.jsxs)(u.Card,{className:"block p-6",children:[(0,t.jsx)("p",{className:"text-sm",children:"Models"}),(0,t.jsx)("div",{className:"mt-2 flex flex-wrap gap-2",children:ek.models&&ek.models.length>0?ek.models.map((e,s)=>(0,t.jsx)(_.BadgeLink,{href:(0,h.modelGroupHref)(e),className:"min-w-0 break-words",children:e},s)):(0,t.jsx)("p",{className:"text-sm",children:"No models specified"})})]}),(0,t.jsx)(u.Card,{className:"block p-6",children:(0,t.jsx)(O.default,{objectPermission:ek.object_permission,variant:"inline",accessToken:G})}),(0,t.jsxs)(u.Card,{className:"block p-6",children:[(0,t.jsx)("p",{className:"text-sm font-medium mb-3",children:"Guardrails"}),Array.isArray(ek.metadata?.guardrails)&&ek.metadata.guardrails.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:ek.metadata.guardrails.map((e,s)=>(0,t.jsx)(c.Badge,{variant:"secondary",className:"min-w-0 break-words",children:e},s))}):(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"No guardrails configured"}),"boolean"==typeof ek.metadata?.disable_global_guardrails&&!0===ek.metadata.disable_global_guardrails&&(0,t.jsx)("div",{className:"mt-3 pt-3 border-t border-border",children:(0,t.jsx)(c.Badge,{variant:"destructive",children:"Global Guardrails Disabled"})})]}),(0,t.jsxs)(u.Card,{className:"block p-6",children:[(0,t.jsx)("p",{className:"text-sm font-medium mb-3",children:"Policies"}),Array.isArray(ek.metadata?.policies)&&ek.metadata.policies.length>0?(0,t.jsx)("div",{className:"space-y-4",children:ek.metadata.policies.map((e,s)=>(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(c.Badge,{variant:"secondary",className:"min-w-0 break-words",children:e}),ez&&(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Loading guardrails..."})]}),!ez&&eI[e]&&eI[e].length>0&&(0,t.jsxs)("div",{className:"ml-4 pl-3 border-l-2 border-border",children:[(0,t.jsx)("p",{className:"text-xs text-muted-foreground mb-1",children:"Resolved Guardrails:"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-1",children:eI[e].map((e,s)=>(0,t.jsx)(c.Badge,{variant:"secondary",className:"min-w-0 break-words",children:e},s))})]})]},s))}):(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"No policies configured"})]}),(0,t.jsx)(T.default,{loggingConfigs:(0,C.extractLoggingSettings)(ek.metadata),disabledCallbacks:Array.isArray(ek.metadata?.litellm_disabled_callbacks)?(0,y.mapInternalToDisplayNames)(ek.metadata.litellm_disabled_callbacks):[],variant:"card"}),(0,t.jsx)(k.default,{autoRotate:ek.auto_rotate,rotationInterval:ek.rotation_interval,lastRotationAt:ek.last_rotation_at,keyRotationAt:ek.key_rotation_at,nextRotationAt:ek.next_rotation_at,variant:"card"})]})}),(0,t.jsx)(g.TabsContent,{value:"savings",children:(0,t.jsx)(j.default,{accessToken:G,keyToken:ek.token,userId:J,userRole:Q})}),(0,t.jsx)(g.TabsContent,{value:"settings",keepMounted:!0,children:(0,t.jsxs)(u.Card,{className:"block p-6",children:[(0,t.jsxs)("div",{className:"flex justify-between items-center mb-4",children:[(0,t.jsx)("h3",{className:"text-lg font-medium",children:"Key Settings"}),!en&&eK&&(0,t.jsx)(m.Button,{variant:"outline",onClick:()=>eo(!0),children:"Edit Settings"})]}),en?(0,t.jsx)(eC,{keyData:ek,onCancel:()=>eo(!1),onSubmit:eO,teams:U,accessToken:G,userID:J,userRole:Q,premiumUser:Y}):(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Key ID"}),(0,t.jsx)("p",{className:"text-sm font-mono",children:ek.token_id||ek.token})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Key Alias"}),(0,t.jsx)("p",{className:"text-sm",children:ek.key_alias||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Secret Key"}),(0,t.jsx)("p",{className:"text-sm font-mono",children:ek.key_name})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Team ID"}),(0,t.jsx)("p",{className:"text-sm",children:ek.team_id?(0,t.jsx)(x.EntityLink,{href:(0,h.teamDetailHref)(ek.team_id),className:"font-normal",children:ek.team_id}):"Not Set"})]}),er&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Project"}),(0,t.jsx)("p",{className:"text-sm",children:ek.project_id?(q=es?.find(e=>e.project_id===ek.project_id),q?.project_alias?`${q.project_alias} (${ek.project_id})`:ek.project_id):"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Organization"}),(0,t.jsx)("p",{className:"text-sm",children:(ek.organization_id??ek.org_id)||"Not Set"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Created"}),(0,t.jsx)("p",{className:"text-sm",children:eL(ek.created_at)})]}),ew&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Last Regenerated"}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("p",{className:"text-sm",children:eL(ew)}),(0,t.jsx)(c.Badge,{variant:"secondary",children:"Recent"})]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Expires"}),(0,t.jsx)("p",{className:"text-sm",children:ek.expires?eL(ek.expires):"Never"})]}),!!ek.metadata?.enable_prompt_caching&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Prompt Caching"}),(0,t.jsx)("p",{className:"text-sm",children:"Enabled (auto-injects cache_control markers on Anthropic and Bedrock Claude requests)"})]}),(0,t.jsx)(k.default,{autoRotate:ek.auto_rotate,rotationInterval:ek.rotation_interval,lastRotationAt:ek.last_rotation_at,keyRotationAt:ek.key_rotation_at,nextRotationAt:ek.next_rotation_at,variant:"inline",className:"pt-4 border-t border-border"}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Spend"}),(0,t.jsxs)("p",{className:"text-sm",children:["$",(0,n.formatNumberWithCommas)(ek.spend,4)," USD"]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Budget"}),(0,t.jsx)("p",{className:"text-sm",children:null!==ek.max_budget?`$${(0,n.formatNumberWithCommas)(ek.max_budget,2)}`:"Unlimited"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Budget Reset"}),(0,t.jsx)("p",{className:"text-sm",children:ek.budget_reset_at?`${ek.budget_duration?`Every ${ek.budget_duration}, next `:""}${eL(ek.budget_reset_at)}`:"Never"})]}),ek.budget_fallbacks&&Object.keys(ek.budget_fallbacks).length>0&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Budget Fallbacks"}),(0,t.jsx)("div",{className:"mt-1 space-y-1",children:Object.entries(ek.budget_fallbacks).map(([e,s])=>(0,t.jsxs)("div",{className:"text-xs text-muted-foreground",children:[(0,t.jsx)("span",{className:"font-medium",children:e}),(0,t.jsx)("span",{className:"mx-1 text-muted-foreground",children:"->"}),s.join(", ")]},e))})]}),(0,S.hasRouterSettings)(ek.router_settings)&&(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Router Settings"}),(0,t.jsx)("div",{className:"mt-1",children:(0,t.jsx)(w.default,{routerSettings:ek.router_settings})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Tags"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-1",children:Array.isArray(ek.metadata?.tags)&&ek.metadata.tags.length>0?ek.metadata.tags.map((e,s)=>(0,t.jsx)("span",{className:"px-2 mr-2 py-1 bg-info/15 rounded-sm text-xs",children:e},s)):"No tags specified"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Prompts"}),(0,t.jsx)("p",{className:"text-sm",children:Array.isArray(ek.metadata?.prompts)&&ek.metadata.prompts.length>0?ek.metadata.prompts.map((e,s)=>(0,t.jsx)("span",{className:"px-2 mr-2 py-1 bg-info/15 rounded-sm text-xs",children:e},s)):"No prompts specified"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Allowed Routes"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-1",children:Array.isArray(ek.allowed_routes)&&ek.allowed_routes.length>0?ek.allowed_routes.map((e,s)=>(0,t.jsx)("span",{className:"px-2 py-1 bg-info/15 rounded-sm text-xs",children:e},s)):(0,t.jsx)(c.Badge,{variant:"secondary",children:"All routes allowed"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Allowed Pass Through Routes"}),(0,t.jsx)("p",{className:"text-sm",children:Array.isArray(ek.metadata?.allowed_passthrough_routes)&&ek.metadata.allowed_passthrough_routes.length>0?ek.metadata.allowed_passthrough_routes.map((e,s)=>(0,t.jsx)("span",{className:"px-2 mr-2 py-1 bg-info/15 rounded-sm text-xs",children:e},s)):"No pass through routes specified"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Disable Global Guardrails"}),(0,t.jsx)("p",{className:"text-sm",children:ek.metadata?.disable_global_guardrails===!0?(0,t.jsx)(c.Badge,{variant:"destructive",children:"Enabled - Global guardrails bypassed"}):(0,t.jsx)(c.Badge,{variant:"secondary",children:"Disabled - Global guardrails active"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Models"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2 mt-1",children:ek.models&&ek.models.length>0?ek.models.map((e,s)=>(0,t.jsx)(_.BadgeLink,{href:(0,h.modelGroupHref)(e),className:"min-w-0 break-words",children:e},s)):(0,t.jsx)("p",{className:"text-sm",children:"No models specified"})})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Rate Limits"}),(0,t.jsxs)("p",{className:"text-sm",children:["TPM: ",null!==ek.tpm_limit?ek.tpm_limit:"Unlimited"]}),(0,t.jsxs)("p",{className:"text-sm",children:["RPM: ",null!==ek.rpm_limit?ek.rpm_limit:"Unlimited"]}),(0,t.jsxs)("p",{className:"text-sm",children:["Max Parallel Requests:"," ",null!==ek.max_parallel_requests?ek.max_parallel_requests:"Unlimited"]}),(0,t.jsxs)("p",{className:"text-sm",children:["Model TPM Limits:"," ",ek.metadata?.model_tpm_limit?JSON.stringify(ek.metadata.model_tpm_limit):"Unlimited"]}),(0,t.jsxs)("p",{className:"text-sm",children:["Model RPM Limits:"," ",ek.metadata?.model_rpm_limit?JSON.stringify(ek.metadata.model_rpm_limit):"Unlimited"]}),(0,t.jsxs)("p",{className:"text-sm",children:["Tag RPM Limits:"," ",ek.metadata?.tag_rpm_limit&&Object.keys(ek.metadata.tag_rpm_limit).length>0?JSON.stringify(ek.metadata.tag_rpm_limit):"Unlimited"]}),(0,t.jsxs)("p",{className:"text-sm",children:["Estimated Output Tokens:"," ",ek.metadata?.default_estimated_output_tokens!=null?String(ek.metadata.default_estimated_output_tokens):"Default"]}),(0,t.jsxs)("p",{className:"text-sm",children:["Estimated Output Tokens Per Model:"," ",ek.metadata?.default_estimated_output_tokens_per_model?JSON.stringify(ek.metadata.default_estimated_output_tokens_per_model):"Default"]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-sm font-medium",children:"Metadata"}),(0,t.jsx)("pre",{className:"bg-muted p-2 rounded-sm text-xs overflow-auto mt-1",children:(0,C.formatMetadataForDisplay)((0,C.stripTagsFromMetadata)(ek.metadata))})]}),(0,t.jsx)(O.default,{objectPermission:ek.object_permission,variant:"inline",className:"pt-4 border-t border-border",accessToken:G}),(0,t.jsx)(T.default,{loggingConfigs:(0,C.extractLoggingSettings)(ek.metadata),disabledCallbacks:Array.isArray(ek.metadata?.litellm_disabled_callbacks)?(0,y.mapInternalToDisplayNames)(ek.metadata.litellm_disabled_callbacks):[],variant:"inline",className:"pt-4 border-t border-border"})]})]})})]})]})]})}],20147)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/01oqh-5b0ytmu.js b/litellm/proxy/_experimental/out/_next/static/chunks/01oqh-5b0ytmu.js
new file mode 100644
index 00000000000..622c11900a3
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/01oqh-5b0ytmu.js
@@ -0,0 +1,420 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,541071,373488,e=>{"use strict";let t=(0,e.i(475254).default)("ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]);e.s(["default",0,t],373488),e.s(["MoreHorizontal",0,t],541071)},332102,e=>{"use strict";let t=(0,e.i(475254).default)("inbox",[["polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12",key:"o97t9d"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}]]);e.s(["Inbox",0,t],332102)},655063,e=>{"use strict";var t=e.i(540626),i=e.i(271645);e.s(["useDebouncedValue",0,function(e,n,s){let[r,a,o]=function(e,n,s){let[r,a]=(0,i.useState)(e),o=(0,t.useDebouncer)(a,n,s);return[r,o.maybeExecute,o]}(e,n,s);return(0,i.useEffect)(()=>{a(e)},[e,a]),[r,o]}],655063)},68155,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,i],68155)},250980,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlusCircleIcon",0,i],250980)},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},871689,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeft",()=>t.default])},845150,e=>{"use strict";var t=e.i(843476),i=e.i(271645),n=e.i(131792);let s=(e,t)=>{let i=t.trim().toLowerCase();return!i||e.label.toLowerCase().includes(i)||e.value.toLowerCase().includes(i)||(e.description?.toLowerCase().includes(i)??!1)};e.s(["MultiSelect",0,function({id:e,options:r,value:a=[],onValueChange:o,placeholder:l="Select options",emptyText:d="No options found",disabled:u=!1,loading:c=!1,allowCustomValues:p=!1,className:m}){let g=(0,n.useComboboxAnchor)(),[h,f]=(0,i.useState)(""),b=r.filter(e=>null!=e&&"string"==typeof e.value&&e.value.length>0),x=a.filter(e=>"string"==typeof e&&e.length>0).map(e=>b.find(t=>t.value===e)??{label:e,value:e}),v=h.trim(),_=b.some(e=>e.value.toLowerCase()===v.toLowerCase()),y=p&&v&&!_?[...b,{label:`Create "${v}"`,value:v}]:b;return(0,t.jsxs)(n.Combobox,{multiple:!0,items:y,value:x,onValueChange:e=>{o(Array.from(new Set(p?e.flatMap(e=>a.includes(e.value)?[e.value]:e.value.split(",").map(e=>e.trim()).filter(e=>e.length>0)):e.map(e=>e.value)))),f("")},inputValue:h,onInputValueChange:f,isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:s,disabled:u||c,children:[(0,t.jsx)(n.ComboboxChips,{render:(0,t.jsx)("div",{ref:g}),className:`min-h-8 py-1 text-sm ${m??""}`,children:(0,t.jsx)(n.ComboboxValue,{children:i=>(0,t.jsxs)(t.Fragment,{children:[i.map(e=>(0,t.jsx)(n.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),(0,t.jsx)(n.ComboboxChipsInput,{id:e,placeholder:c?"Loading...":l,className:"min-w-24","aria-label":l||void 0}),i.length>0&&!u&&!c&&(0,t.jsx)(n.ComboboxClear,{className:"ml-auto self-center","aria-label":"Clear all"})]})})}),(0,t.jsxs)(n.ComboboxContent,{anchor:g,children:[(0,t.jsx)(n.ComboboxEmpty,{children:d}),(0,t.jsx)(n.ComboboxList,{children:e=>(0,t.jsx)(n.ComboboxItem,{value:e,disabled:e.disabled,children:(0,t.jsxs)("span",{className:"min-w-0",children:[(0,t.jsx)("span",{className:"block truncate",children:e.label}),e.description&&(0,t.jsx)("span",{className:"block truncate text-xs text-muted-foreground",children:e.description})]})},e.value)})]})]})}])},540626,e=>{"use strict";let t;var i=e.i(271645);let n=(0,i.createContext)(null);function s(e,t){if(Object.is(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[i,n]of e)if(!t.has(i)||!Object.is(n,t.get(i)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let i of e)if(!t.has(i))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();let i=r(e);if(i.length!==r(t).length)return!1;for(let n=0;ne,n){let s=n?.compare??o,r=(0,i.useCallback)(t=>{let{unsubscribe:i}=e.subscribe(t);return i},[e]),d=(0,i.useCallback)(()=>e.get(),[e]);return(0,a.useSyncExternalStoreWithSelector)(r,d,d,t,s)}function d(e,...t){return"function"==typeof e?e(...t):e}var u=class{#e=!0;#t;#i;#n;#s;#r;#a;#o;#l=0;#d=5;#u=!1;#c=!1;#p=null;#m=()=>{this.debugLog("Connected to event bus"),this.#r=!0,this.#u=!1,this.debugLog("Emitting queued events",this.#s),this.#s.forEach(e=>this.emitEventToBus(e)),this.#s=[],this.stopConnectLoop(),this.#i().removeEventListener("tanstack-connect-success",this.#m)};#g=()=>{if(this.#l{this.#u||(this.#u=!0,this.#i().addEventListener("tanstack-connect-success",this.#m),this.#g())};constructor({pluginId:e,debug:t=!1,enabled:i=!0,reconnectEveryMs:n=300}){this.#t=e,this.#e=i,this.#i=this.getGlobalTarget,this.#n=t,this.debugLog(" Initializing event subscription for plugin",this.#t),this.#s=[],this.#r=!1,this.#c=!1,this.#a=null,this.#o=n}startConnectLoop(){null!==this.#a||this.#r||(this.debugLog(`Starting connect loop (every ${this.#o}ms)`),this.#a=setInterval(this.#g,this.#o))}stopConnectLoop(){this.#u=!1,null!==this.#a&&(clearInterval(this.#a),this.#a=null,this.#s=[],this.debugLog("Stopped connect loop"))}debugLog(...e){this.#n&&console.log(`🌴 [tanstack-devtools:${this.#t}-plugin]`,...e)}getGlobalTarget(){if("u">typeof globalThis&&globalThis.__TANSTACK_EVENT_TARGET__)return this.debugLog("Using global event target"),globalThis.__TANSTACK_EVENT_TARGET__;if("u">typeof window&&void 0!==window.addEventListener)return this.debugLog("Using window as event target"),window;let e="u">typeof EventTarget?new EventTarget:void 0;return void 0===e||void 0===e.addEventListener?(this.debugLog("No event mechanism available, running in non-web environment"),{addEventListener:()=>{},removeEventListener:()=>{},dispatchEvent:()=>!1}):(this.debugLog("Using new EventTarget as fallback"),e)}getPluginId(){return this.#t}dispatchCustomEventShim(e,t){try{let i=new Event(e,{detail:t});this.#i().dispatchEvent(i)}catch(e){this.debugLog("Failed to dispatch shim event")}}dispatchCustomEvent(e,t){try{this.#i().dispatchEvent(new CustomEvent(e,{detail:t}))}catch(i){this.dispatchCustomEventShim(e,t)}}emitEventToBus(e){this.debugLog("Emitting event to client bus",e),this.dispatchCustomEvent("tanstack-dispatch-event",e)}createEventPayload(e,t){return{type:`${this.#t}:${e}`,payload:t,pluginId:this.#t}}emit(e,t){if(!this.#e)return void this.debugLog("Event bus client is disabled, not emitting event",e,t);if(this.#p&&(this.debugLog("Emitting event to internal event target",e,t),this.#p.dispatchEvent(new CustomEvent(`${this.#t}:${e}`,{detail:this.createEventPayload(e,t)}))),this.#c)return void this.debugLog("Previously failed to connect, not emitting to bus");if(!this.#r){this.debugLog("Bus not available, will be pushed as soon as connected"),this.#s.push(this.createEventPayload(e,t)),"u">typeof CustomEvent&&!this.#u&&(this.#h(),this.startConnectLoop());return}return this.emitEventToBus(this.createEventPayload(e,t))}on(e,t,i){let n=i?.withEventTarget??!1,s=`${this.#t}:${e}`;if(n&&(this.#p||(this.#p=new EventTarget),this.#p.addEventListener(s,e=>{t(e.detail)})),!this.#e)return this.debugLog("Event bus client is disabled, not registering event",s),()=>{};let r=e=>{this.debugLog("Received event from bus",e.detail),t(e.detail)};return this.#i().addEventListener(s,r),this.debugLog("Registered event to bus",s),()=>{n&&this.#p?.removeEventListener(s,r),this.#i().removeEventListener(s,r)}}onAll(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{e(t.detail)};return this.#i().addEventListener("tanstack-devtools-global",t),()=>this.#i().removeEventListener("tanstack-devtools-global",t)}onAllPluginEvents(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{let i=t.detail;this.#t&&i.pluginId!==this.#t||e(i)};return this.#i().addEventListener("tanstack-devtools-global",t),()=>this.#i().removeEventListener("tanstack-devtools-global",t)}};let c=new Map;function p(e){if(void 0!==e)try{return JSON.parse(JSON.stringify(e))}catch{return null}}let m=new class extends u{constructor(e){super({pluginId:"pacer",debug:e?.debug,reconnectEveryMs:1e3})}};function g(e,t,i){let n="object"==typeof e,s=n?e:void 0;return{next:(n?e.next:e)?.bind(s),error:(n?e.error:t)?.bind(s),complete:(n?e.complete:i)?.bind(s)}}let h=[],f=0,{link:b,unlink:x,propagate:v,checkDirty:_,shallowPropagate:y}=function({update:e,notify:t,unwatched:i}){return{link:function(e,t,i){let n=t.depsTail;if(void 0!==n&&n.dep===e)return;let s=void 0!==n?n.nextDep:t.deps;if(void 0!==s&&s.dep===e){s.version=i,t.depsTail=s;return}let r=e.subsTail;if(void 0!==r&&r.version===i&&r.sub===t)return;let a=t.depsTail=e.subsTail={version:i,dep:e,sub:t,prevDep:n,nextDep:s,prevSub:r,nextSub:void 0};void 0!==s&&(s.prevDep=a),void 0!==n?n.nextDep=a:t.deps=a,void 0!==r?r.nextSub=a:e.subs=a},unlink:function(e,t=e.sub){let n=e.dep,s=e.prevDep,r=e.nextDep,a=e.nextSub,o=e.prevSub;return void 0!==r?r.prevDep=s:t.depsTail=s,void 0!==s?s.nextDep=r:t.deps=r,void 0!==a?a.prevSub=o:n.subsTail=o,void 0!==o?o.nextSub=a:void 0===(n.subs=a)&&i(n),r},propagate:function(e){let i,n=e.nextSub;e:for(;;){let s=e.sub,r=s.flags;if(60&r?12&r?4&r?!(48&r)&&function(e,t){let i=t.depsTail;for(;void 0!==i;){if(i===e)return!0;i=i.prevDep}return!1}(e,s)?(s.flags=40|r,r&=1):r=0:s.flags=-9&r|32:r=0:s.flags=32|r,2&r&&t(s),1&r){let t=s.subs;if(void 0!==t){let s=(e=t).nextSub;void 0!==s&&(i={value:n,prev:i},n=s);continue}}if(void 0!==(e=n)){n=e.nextSub;continue}for(;void 0!==i;)if(e=i.value,i=i.prev,void 0!==e){n=e.nextSub;continue e}break}},checkDirty:function(t,i){let s,r=0,a=!1;e:for(;;){let o=t.dep,l=o.flags;if(16&i.flags)a=!0;else if((17&l)==17){if(e(o)){let e=o.subs;void 0!==e.nextSub&&n(e),a=!0}}else if((33&l)==33){(void 0!==t.nextSub||void 0!==t.prevSub)&&(s={value:t,prev:s}),t=o.deps,i=o,++r;continue}if(!a){let e=t.nextDep;if(void 0!==e){t=e;continue}}for(;r--;){let r=i.subs,o=void 0!==r.nextSub;if(o?(t=s.value,s=s.prev):t=r,a){if(e(i)){o&&n(r),i=t.sub;continue}a=!1}else i.flags&=-33;i=t.sub;let l=t.nextDep;if(void 0!==l){t=l;continue e}}return a}},shallowPropagate:n};function n(e){do{let i=e.sub,n=i.flags;(48&n)==32&&(i.flags=16|n,(6&n)==2&&t(i))}while(void 0!==(e=e.nextSub))}}({update:e=>e._update(),notify(e){h[E++]=e,e.flags&=-3},unwatched(e){void 0!==e.depsTail&&(e.depsTail=void 0,e.flags=17,j(e))}}),w=0,E=0;function j(e){let t=e.depsTail,i=void 0!==t?t.nextDep:e.deps;for(;void 0!==i;)i=x(i,e)}var k=class{constructor(e,i){this.atom=function(e){let i="function"==typeof e,n={_snapshot:i?void 0:e,subs:void 0,subsTail:void 0,deps:void 0,depsTail:void 0,flags:+!i,get:()=>(void 0!==t&&b(n,t,f),n._snapshot),subscribe(e){var i;let s,r,a=g(e),o={current:!1},l=(i=()=>{n.get(),o.current?a.next?.(n._snapshot):o.current=!0},s=()=>{let e=t;t=r,++f,r.depsTail=void 0,r.flags=6;try{return i()}finally{t=e,r.flags&=-5,j(r)}},r={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:6,notify(){let e=this.flags;16&e||32&e&&_(this.deps,this)?s():this.flags=2},stop(){this.flags=0,this.depsTail=void 0,j(this)}},s(),r);return{unsubscribe:()=>{l.stop()}}},_update(s){let r=t,a=(void 0)??Object.is;if(i)t=n,++f,n.depsTail=void 0;else if(void 0===s)return!1;i&&(n.flags=5);try{let t=n._snapshot,r="function"==typeof s?s(t):void 0===s&&i?e(t):s;if(void 0===t||!a(t,r))return n._snapshot=r,!0;return!1}finally{t=r,i&&(n.flags&=-5),j(n)}}};return i?(n.flags=17,n.get=function(){let e=n.flags;if(16&e||32&e&&_(n.deps,n)){if(n._update()){let e=n.subs;void 0!==e&&y(e)}}else 32&e&&(n.flags=-33&e);return void 0!==t&&b(n,t,f),n._snapshot}):n.set=function(e){if(n._update(e)){let e=n.subs;if(void 0!==e&&(v(e),y(e),1)){for(;w{this.options={...this.options,...e},this.#b()||this.cancel()},this.#x=e=>{this.store.setState(t=>{let i={...t,...e},{isPending:n}=i;return{...i,status:this.#b()?n?"pending":"idle":"disabled"}}),((e,t)=>{let i=t.key;if(i){var n,s;c.set(i,t),m.emit(e,{key:(n={...t,key:i}).key,store:{state:p("function"==typeof(s=n.store).get?s.get():s.state)},options:p(n.options)})}})("Debouncer",this)},this.#b=()=>!!d(this.options.enabled,this),this.#v=()=>d(this.options.wait,this),this.maybeExecute=(...e)=>{if(!this.#b())return;this.#x({maybeExecuteCount:this.store.state.maybeExecuteCount+1});let t=!1;this.options.leading&&this.store.state.canLeadingExecute&&(this.#x({canLeadingExecute:!1}),t=!0,this.#_(...e)),this.options.trailing&&this.#x({isPending:!0,lastArgs:e}),this.#f&&clearTimeout(this.#f),this.#f=setTimeout(()=>{this.#x({canLeadingExecute:!0}),this.options.trailing&&!t&&this.#_(...e)},this.#v())},this.#_=(...e)=>{this.#b()&&(this.fn(...e),this.#x({executionCount:this.store.state.executionCount+1,isPending:!1,lastArgs:void 0}),this.options.onExecute?.(e,this))},this.flush=()=>{this.store.state.isPending&&this.store.state.lastArgs&&(this.#y(),this.#_(...this.store.state.lastArgs))},this.#y=()=>{this.#f&&(clearTimeout(this.#f),this.#f=void 0)},this.cancel=()=>{this.#y(),this.#x({canLeadingExecute:!0,isPending:!1})},this.reset=()=>{this.#x(C())},this.key=t.key,this.options={...N,...t},this.#x(this.options.initialState??{}),this.key&&m.on("d-Debouncer",e=>{e.payload.key===this.key&&(this.#x(e.payload.store.state),this.setOptions(e.payload.options))})}#x;#b;#v;#_;#y};e.s(["useDebouncer",0,function(e,t,r=()=>({})){let a={...((0,i.useContext)(n)?.defaultOptions??{}).debouncer,...t},[o]=(0,i.useState)(()=>{let t=new I(e,a);return t.Subscribe=function(e){let i=l(t.store,e.selector,{compare:s});return"function"==typeof e.children?e.children(i):e.children},t});o.fn=e,o.setOptions(a),(0,i.useEffect)(()=>()=>{a.onUnmount?a.onUnmount(o):o.cancel()},[]);let d=l(o.store,r,{compare:s});return(0,i.useMemo)(()=>({...o,state:d}),[o,d])}],540626)},741466,e=>{"use strict";e.s(["DEBOUNCE_WAIT_MS",0,300])},871943,502547,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,i],871943);let n=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"}))});e.s(["ChevronRightIcon",0,n],502547)},278587,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,i],278587)},360820,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,i],360820)},434626,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"}))});e.s(["ExternalLinkIcon",0,i],434626)},902555,e=>{"use strict";var t=e.i(843476),i=e.i(746798),n=e.i(271645);let s=n.forwardRef(function(e,t){return n.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"}))}),r=n.forwardRef(function(e,t){return n.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"}),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21 12a9 9 0 11-18 0 9 9 0 0118 0z"}))});var a=e.i(278587),o=e.i(68155),l=e.i(360820),d=e.i(871943),u=e.i(434626);let c=n.forwardRef(function(e,t){return n.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),n.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"}))});var p=e.i(196631);function m({icon:e,onClick:i,className:n,disabled:s,dataTestId:r}){return s?(0,t.jsx)("span",{className:"inline-flex shrink-0 cursor-not-allowed items-center justify-center p-1.5 opacity-50","data-testid":r,children:(0,t.jsx)(e,{className:"size-5 shrink-0"})}):(0,t.jsx)("span",{className:(0,p.cx)("inline-flex shrink-0 cursor-pointer items-center justify-center p-1.5",n),onClick:i,"data-testid":r,children:(0,t.jsx)(e,{className:"size-5 shrink-0"})})}let g={Edit:{icon:s,className:"hover:text-info"},Delete:{icon:o.TrashIcon,className:"hover:text-destructive"},Test:{icon:r,className:"hover:text-info"},Regenerate:{icon:a.RefreshIcon,className:"hover:text-success"},Up:{icon:l.ChevronUpIcon,className:"hover:text-info"},Down:{icon:d.ChevronDownIcon,className:"hover:text-info"},Open:{icon:u.ExternalLinkIcon,className:"hover:text-success"},Copy:{icon:c,className:"hover:text-info"}};e.s(["default",0,function({onClick:e,tooltipText:n,disabled:s=!1,disabledTooltipText:r,dataTestId:a,variant:o}){let{icon:l,className:d}=g[o],u=s?r:n,c=(0,t.jsx)(m,{icon:l,onClick:e,className:d,disabled:s,dataTestId:a});return u?(0,t.jsx)(i.TooltipProvider,{children:(0,t.jsxs)(i.Tooltip,{children:[(0,t.jsx)(i.TooltipTrigger,{render:(0,t.jsx)("span",{}),children:c}),(0,t.jsx)(i.TooltipContent,{children:u})]})}):(0,t.jsx)("span",{children:c})}],902555)},198458,e=>{"use strict";var t=e.i(655063),i=e.i(266027),n=e.i(271645),s=e.i(741466);e.s(["useResourceList",0,function(e){let{queryKey:r,fetchPage:a,serializeFilters:o,defaultSorting:l,defaultPageSize:d,enabled:u}=e,[c,p]=(0,n.useState)(l),[m,g]=(0,n.useState)({pageIndex:0,pageSize:d}),[h,f]=(0,n.useState)([]),[b,x]=(0,n.useState)(""),[v]=(0,t.useDebouncedValue)(b,{wait:s.DEBOUNCE_WAIT_MS}),_=(0,n.useMemo)(()=>{let e=c.map(e=>e.desc?`-${e.id}`:e.id).join(","),t=v.trim();return{page:m.pageIndex+1,page_size:m.pageSize,...""===e?{}:{sort:e},...""===t?{}:{q:t},...o(h)}},[c,m.pageIndex,m.pageSize,v,h,o]),y={queryKey:[...r,_],queryFn:({signal:e})=>a(_,e),enabled:u,placeholderData:e=>e},{data:w,isLoading:E,isFetching:j,error:k,refetch:C}=(0,i.useQuery)(y),N=(0,n.useCallback)(()=>g(e=>({...e,pageIndex:0})),[]),I=(0,n.useCallback)(e=>{p(e),N()},[N]),T=(0,n.useCallback)(e=>{f(e),N()},[N]),S=(0,n.useCallback)(e=>{x(e),N()},[N]),L=(0,n.useCallback)(()=>{C()},[C]);return{rows:(0,n.useMemo)(()=>w?.data??[],[w]),rowCount:w?.meta.total_count??0,isLoading:E,isFetching:j,error:k,refetch:L,sorting:c,onSortingChange:I,pagination:m,onPaginationChange:g,columnFilters:h,onColumnFiltersChange:T,searchValue:b,onSearchChange:S}}])},455037,e=>{"use strict";var t=e.i(494144);e.s(["prism",()=>t.default])},306228,e=>{"use strict";let t=(0,e.i(475254).default)("link-2",[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",key:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]]);e.s(["Link2",0,t],306228)},652272,209261,e=>{"use strict";var t=e.i(843476),i=e.i(271645),n=e.i(871689),s=e.i(643531),r=e.i(174886),a=e.i(306228),o=e.i(196631);let l=/^[a-zA-Z0-9][a-zA-Z0-9._-]*(\/[a-zA-Z0-9][a-zA-Z0-9._-]*)*$/,d=e=>e.trim().replace(/\/+$/,""),u=/\.(md|markdown|txt|json|ya?ml|toml)$/i,c=/^\d{1,3}(\.\d{1,3}){3}$/,p=/^[A-Za-z0-9-]+$/,m=/^[A-Za-z0-9._-]+$/,g=e=>e.pathname.split("/").filter(e=>""!==e),h=e=>{let t=e.split("/").filter(e=>""!==e);return t[t.length-1]??""},f=e=>e.toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,""),b=e=>JSON.stringify({extraKnownMarketplaces:{litellm:{source:{source:"url",url:`${e}/claude-code/marketplace.json`}}}},null,2),x=e=>`/plugin install ${e.name}@litellm`;e.s(["buildMarketplaceSettingsSnippet",0,b,"formatInstallCommand",0,x,"getCategoryBadgeColor",0,e=>{if(!e)return"gray";let t=e.toLowerCase();if(t.includes("development")||t.includes("dev"))return"blue";if(t.includes("productivity")||t.includes("workflow"))return"green";if(t.includes("learning")||t.includes("education"))return"purple";if(t.includes("security")||t.includes("safety"))return"red";if(t.includes("data")||t.includes("analytics"))return"orange";else if(t.includes("integration")||t.includes("api"))return"yellow";return"gray"},"isValidEmail",0,e=>!e||/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e),"isValidSemanticVersion",0,e=>!e||/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$/.test(e),"isValidSubPath",0,e=>{let t=d(e);return""!==t&&l.test(t)},"parseKeywords",0,e=>e&&""!==e.trim()?e.split(",").map(e=>e.trim()).filter(e=>""!==e):[],"parseSkillSource",0,(e,t)=>{let i=(e=>{let t,i=e.trim();if(""===i||i.startsWith("//"))return null;let n=/^[a-z][a-z0-9+.-]*:\/\//i.test(i)?i:`https://${i}`;try{t=new URL(n)}catch{return null}return"https:"!==t.protocol||""!==t.username||""!==t.password||!t.hostname.includes(".")||t.hostname.startsWith("[")||c.test(t.hostname)?null:t})(e);if(!i)return null;if("github.com"===i.hostname.replace(/^www\./,""))return((e,t)=>{let i=g(e);if(i.length<2)return null;let n=i[0],s=i[1].replace(/\.git$/,"");if(!p.test(n)||!m.test(s))return null;let r=`${n}/${s}`,a=`https://github.com/${r}`,o={parsed:{source:"github",repo:r},label:`GitHub repo — ${r}`,suggestedName:f(s)};if(i.length>=4&&("tree"===i[2]||"blob"===i[2])){let e=i.slice(4),t=h(e.join("/")),n=u.test(t)?e.slice(0,-1):e;if(0===n.length)return o;let s=d(n.join("/"));return l.test(s)?{parsed:{source:"git-subdir",url:a,path:s},label:`GitHub subdir — ${r} @ ${s}`,suggestedName:f(h(s))}:null}if(2!==i.length)return null;let c=d(t??"");return""!==c?l.test(c)?{parsed:{source:"git-subdir",url:a,path:c},label:`GitHub subdir — ${r} @ ${c}`,suggestedName:f(h(c))}:null:o})(i,t);if(g(i).length<2)return null;let n=`${i.protocol}//${i.host}${i.pathname.replace(/\/+$/,"")}`,s=d(t??"");return""!==s?l.test(s)?{parsed:{source:"git-subdir",url:n,path:s},label:`Git subdir — ${n} @ ${s}`,suggestedName:f(h(s))}:null:{parsed:{source:"url",url:n},label:`Git repo — ${n}`,suggestedName:f(h(i.pathname).replace(/\.git$/,""))}},"validatePluginName",0,e=>!!e&&""!==e.trim()&&/^[a-z0-9-]+$/.test(e)],209261),e.s(["default",0,({skill:e,onBack:l})=>{let d,[u,c]=(0,i.useState)("overview"),[p,m]=(0,i.useState)(null),g=(e,t)=>{navigator.clipboard.writeText(e),m(t),setTimeout(()=>m(null),2e3)},h="github"===(d=e.source).source&&d.repo?`https://github.com/${d.repo}`:"git-subdir"===d.source&&d.url?d.path?`${d.url}/tree/main/${d.path}`:d.url:"url"===d.source&&d.url?d.url:null,f=x(e),v=b(window.location.origin),_=[...e.category?[{property:"Category",value:e.category}]:[],...e.domain?[{property:"Domain",value:e.domain}]:[],...e.namespace?[{property:"Namespace",value:e.namespace}]:[],...e.version?[{property:"Version",value:e.version}]:[],...e.author?.name?[{property:"Author",value:e.author.name}]:[],...e.created_at?[{property:"Added",value:new Date(e.created_at).toLocaleDateString()}]:[]];return(0,t.jsxs)("div",{className:"py-6 pl-0 pr-8",children:[(0,t.jsxs)("div",{onClick:l,className:"mb-6 inline-flex cursor-pointer items-center gap-1.5 text-sm text-muted-foreground",children:[(0,t.jsx)(n.ArrowLeft,{className:"size-3"}),(0,t.jsx)("span",{children:"Skills"})]}),(0,t.jsxs)("div",{className:"mb-2",children:[(0,t.jsx)("h1",{className:"m-0 text-[28px] font-normal leading-tight text-foreground",children:e.name}),e.description&&(0,t.jsx)("p",{className:"mb-0 ml-0 mr-0 mt-2 text-sm leading-relaxed text-muted-foreground",children:e.description})]}),(0,t.jsx)("div",{className:"mb-7 mt-6 border-b border-border",children:(0,t.jsx)("div",{className:"flex",children:[{key:"overview",label:"Overview"},{key:"usage",label:"How to Use"}].map(e=>(0,t.jsx)("div",{onClick:()=>c(e.key),className:(0,o.cn)("-mb-px cursor-pointer border-b-[3px] px-5 py-3 text-sm",u===e.key?"border-info font-medium text-info":"border-transparent font-normal text-muted-foreground"),children:e.label},e.key))})}),"overview"===u&&(0,t.jsxs)("div",{className:"flex gap-16",children:[(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("h2",{className:"m-0 mb-1 text-lg font-normal text-foreground",children:"Skill Details"}),(0,t.jsx)("p",{className:"m-0 mb-4 text-[13px] text-muted-foreground",children:"Metadata registered with this skill"}),(0,t.jsxs)("table",{className:"w-full border-collapse text-sm",children:[(0,t.jsx)("thead",{children:(0,t.jsxs)("tr",{className:"border-b border-border",children:[(0,t.jsx)("th",{className:"w-40 py-3 text-left font-medium text-muted-foreground",children:"Property"}),(0,t.jsx)("th",{className:"py-3 text-left font-medium text-muted-foreground",children:e.name})]})}),(0,t.jsx)("tbody",{children:_.map((e,i)=>(0,t.jsxs)("tr",{className:"border-b border-border",children:[(0,t.jsx)("td",{className:"py-3 text-foreground",children:e.property}),(0,t.jsx)("td",{className:"py-3 text-foreground",children:e.value})]},i))})]})]}),(0,t.jsxs)("div",{className:"w-60 shrink-0",children:[(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)("div",{className:"mb-1 text-xs text-muted-foreground",children:"Status"}),(0,t.jsx)("span",{className:(0,o.cn)("rounded-xl px-2.5 py-[3px] text-xs font-medium",e.enabled?"bg-success/10 text-success":"bg-muted text-muted-foreground"),children:e.enabled?"Public":"Draft"})]}),h&&(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)("div",{className:"mb-1 text-xs text-muted-foreground",children:"Source"}),(0,t.jsxs)("a",{href:h,target:"_blank",rel:"noopener noreferrer",className:"flex items-center gap-1 break-all text-[13px] text-info",children:[h.replace("https://",""),(0,t.jsx)(a.Link2,{className:"size-3 shrink-0"})]})]}),e.keywords&&e.keywords.length>0&&(0,t.jsxs)("div",{className:"mb-6",children:[(0,t.jsx)("div",{className:"mb-2 text-xs text-muted-foreground",children:"Tags"}),(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:e.keywords.map(e=>(0,t.jsx)("span",{className:"rounded-2xl border border-border bg-card px-3 py-1 text-xs text-foreground",children:e},e))})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"mb-1 text-xs text-muted-foreground",children:"Skill ID"}),(0,t.jsx)("div",{className:"break-all font-mono text-xs text-foreground",children:e.id})]})]})]}),"usage"===u&&(0,t.jsxs)("div",{className:"max-w-[640px]",children:[(0,t.jsx)("h2",{className:"m-0 mb-2 text-lg font-normal text-foreground",children:"Using this skill"}),(0,t.jsx)("p",{className:"m-0 mb-6 text-sm leading-relaxed text-muted-foreground",children:"Once your proxy is set as a marketplace, enable this skill in Claude Code with one command:"}),(0,t.jsxs)("div",{className:"mb-6 overflow-hidden rounded-lg border border-border",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between border-b border-border bg-muted px-4 py-2.5",children:[(0,t.jsx)("span",{className:"text-[13px] font-medium text-foreground",children:"Run in Claude Code"}),(0,t.jsxs)("button",{onClick:()=>g(f,"install"),className:(0,o.cn)("flex cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-xs","install"===p?"text-success":"text-info"),children:["install"===p?(0,t.jsx)(s.Check,{className:"size-3"}):(0,t.jsx)(r.Copy,{className:"size-3"}),"install"===p?"Copied":"Copy"]})]}),(0,t.jsx)("pre",{className:"m-0 bg-card px-4 py-3.5 font-mono text-sm text-foreground",children:f})]}),(0,t.jsxs)("div",{className:"mb-4 rounded-lg border border-warning/30 bg-warning/10 px-4 py-3",children:[(0,t.jsxs)("p",{className:"m-0 mb-2 text-[13px] leading-relaxed text-muted-foreground",children:['If you see "Plugin ',e.name,'not found in marketplace", update the catalog first:']}),(0,t.jsx)("pre",{className:"m-0 bg-transparent font-mono text-[13px] text-foreground",children:"/plugin marketplace update litellm"})]}),(0,t.jsxs)("p",{className:"m-0 text-[13px] leading-relaxed text-muted-foreground",children:["Don't have the marketplace configured yet?"," ",(0,t.jsx)("span",{onClick:()=>c("setup"),className:"cursor-pointer text-info",children:"See one-time setup →"})]})]}),"setup"===u&&(0,t.jsxs)("div",{className:"max-w-[640px]",children:[(0,t.jsx)("h2",{className:"m-0 mb-2 text-lg font-normal text-foreground",children:"One-time marketplace setup"}),(0,t.jsx)("p",{className:"m-0 mb-3 text-sm leading-relaxed text-muted-foreground",children:"Run this command in Claude Code to register the marketplace:"}),(0,t.jsxs)("div",{className:"mb-6 overflow-hidden rounded-lg border border-border",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between border-b border-border bg-muted px-4 py-2.5",children:[(0,t.jsx)("span",{className:"text-[13px] font-medium text-foreground",children:"Run in Claude Code"}),(0,t.jsxs)("button",{onClick:()=>{let e=window.location.origin;g(`/plugin marketplace add ${e}/claude-code/marketplace.json`,"marketplace-cmd")},className:(0,o.cn)("flex cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-xs","marketplace-cmd"===p?"text-success":"text-info"),children:["marketplace-cmd"===p?(0,t.jsx)(s.Check,{className:"size-3"}):(0,t.jsx)(r.Copy,{className:"size-3"}),"marketplace-cmd"===p?"Copied":"Copy"]})]}),(0,t.jsx)("pre",{className:"m-0 bg-card px-4 py-3.5 font-mono text-[13px] text-foreground",children:`/plugin marketplace add ${window.location.origin}/claude-code/marketplace.json`})]}),(0,t.jsxs)("p",{className:"m-0 mb-3 text-sm leading-relaxed text-muted-foreground",children:["Or add this to ",(0,t.jsx)("code",{className:"rounded bg-muted px-1.5 py-px text-[13px]",children:"~/.claude/settings.json"})," ","for a persistent configuration:"]}),(0,t.jsxs)("div",{className:"overflow-hidden rounded-lg border border-border",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between border-b border-border bg-muted px-4 py-2.5",children:[(0,t.jsx)("span",{className:"text-[13px] font-medium text-foreground",children:"~/.claude/settings.json"}),(0,t.jsxs)("button",{onClick:()=>g(v,"settings"),className:(0,o.cn)("flex cursor-pointer items-center gap-1 border-none bg-transparent p-0 text-xs","settings"===p?"text-success":"text-info"),children:["settings"===p?(0,t.jsx)(s.Check,{className:"size-3"}):(0,t.jsx)(r.Copy,{className:"size-3"}),"settings"===p?"Copied":"Copy"]})]}),(0,t.jsx)("pre",{className:"m-0 bg-card px-4 py-3.5 font-mono text-[13px] text-foreground",children:v})]})]})]})}],652272)},899426,e=>{"use strict";let t=e=>e.trim().toLowerCase();function i(e,i){let n=t(e);if(""===n)return!0;let s=i.filter(e=>"string"==typeof e).map(e=>e.toLowerCase());return!!s.some(e=>e.includes(n))||n.split(/\s+/).every(e=>s.some(t=>t.includes(e)))}e.s(["filterBySearchTerm",0,function(e,t,n){return e.filter(e=>i(t,n(e)))},"matchesSearchTerm",0,i,"rankBySearchRelevance",0,function(e,i,n){let s=t(i);if(""===s)return[...e];let r=e=>{let t=n(e).toLowerCase();return 1e3*(t===s)+100*!!t.startsWith(s)+(1e3-t.length)};return[...e].sort((e,t)=>r(t)-r(e))}])},909947,865361,e=>{"use strict";var t,i,n=((t={}).AUDIO_SPEECH="audio_speech",t.AUDIO_TRANSCRIPTION="audio_transcription",t.IMAGE_GENERATION="image_generation",t.VIDEO_GENERATION="video_generation",t.CHAT="chat",t.COMPLETION="completion",t.RESPONSES="responses",t.IMAGE_EDITS="image_edit",t.ANTHROPIC_MESSAGES="anthropic_messages",t.EMBEDDING="embedding",t.REALTIME="realtime",t),s=((i={}).IMAGE="image",i.VIDEO="video",i.CHAT="chat",i.RESPONSES="responses",i.IMAGE_EDITS="image_edits",i.ANTHROPIC_MESSAGES="anthropic_messages",i.EMBEDDINGS="embeddings",i.SPEECH="speech",i.TRANSCRIPTION="transcription",i.A2A_AGENTS="a2a_agents",i.MCP="mcp",i.REALTIME="realtime",i.INTERACTIONS="interactions",i);let r={image_generation:"image",video_generation:"video",chat:"chat",completion:"chat",responses:"responses",image_edit:"image_edits",anthropic_messages:"anthropic_messages",audio_speech:"speech",audio_transcription:"transcription",embedding:"embeddings",realtime:"realtime"};e.s(["EndpointType",()=>s,"ModelMode",()=>n,"getEndpointType",0,e=>Object.values(n).includes(e)?r[e]:"chat"],865361),e.s(["generateCodeSnippet",0,e=>{let t,{apiKeySource:i,accessToken:n,apiKey:r,inputMessage:a,chatHistory:o,selectedTags:l,selectedVectorStores:d,selectedGuardrails:u,selectedPolicies:c,selectedVoice:p,endpointType:m,selectedModel:g,selectedSdk:h,proxySettings:f}=e,b="session"===i?n:r,x=window.location.origin,v=f?.LITELLM_UI_API_DOC_BASE_URL;v&&v.trim()?x=v:f?.PROXY_BASE_URL&&(x=f.PROXY_BASE_URL);let _=a||"Your prompt here",y=_.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),w=o.filter(e=>!e.isImage).map(({role:e,content:t})=>({role:e,content:t})),E={};l.length>0&&(E.tags=l),d.length>0&&(E.vector_stores=d),u.length>0&&(E.guardrails=u),c.length>0&&(E.policies=c);let j=g||"your-model-name",k="azure"===h?`import openai
+
+client = openai.AzureOpenAI(
+ api_key="${b||"YOUR_LITELLM_API_KEY"}",
+ azure_endpoint="${x}",
+ api_version="2024-02-01"
+)`:`import openai
+
+client = openai.OpenAI(
+ api_key="${b||"YOUR_LITELLM_API_KEY"}",
+ base_url="${x}"
+)`;switch(m){case s.CHAT:{let e=Object.keys(E).length>0,i="";if(e){let e=JSON.stringify({metadata:E},null,2).split("\n").map(e=>" ".repeat(4)+e).join("\n").trim();i=`,
+ extra_body=${e}`}let n=w.length>0?w:[{role:"user",content:_}];t=`
+import base64
+
+# Helper function to encode images to base64
+def encode_image(image_path):
+ with open(image_path, "rb") as image_file:
+ return base64.b64encode(image_file.read()).decode('utf-8')
+
+# Example with text only
+response = client.chat.completions.create(
+ model="${j}",
+ messages=${JSON.stringify(n,null,4)}${i}
+)
+
+print(response)
+
+# Example with image or PDF (uncomment and provide file path to use)
+# base64_file = encode_image("path/to/your/file.jpg") # or .pdf
+# response_with_file = client.chat.completions.create(
+# model="${j}",
+# messages=[
+# {
+# "role": "user",
+# "content": [
+# {
+# "type": "text",
+# "text": "${y}"
+# },
+# {
+# "type": "image_url",
+# "image_url": {
+# "url": f"data:image/jpeg;base64,{base64_file}" # or data:application/pdf;base64,{base64_file}
+# }
+# }
+# ]
+# }
+# ]${i}
+# )
+# print(response_with_file)
+`;break}case s.RESPONSES:{let e=Object.keys(E).length>0,i="";if(e){let e=JSON.stringify({metadata:E},null,2).split("\n").map(e=>" ".repeat(4)+e).join("\n").trim();i=`,
+ extra_body=${e}`}let n=w.length>0?w:[{role:"user",content:_}];t=`
+import base64
+
+# Helper function to encode images to base64
+def encode_image(image_path):
+ with open(image_path, "rb") as image_file:
+ return base64.b64encode(image_file.read()).decode('utf-8')
+
+# Example with text only
+response = client.responses.create(
+ model="${j}",
+ input=${JSON.stringify(n,null,4)}${i}
+)
+
+print(response.output_text)
+
+# Example with image or PDF (uncomment and provide file path to use)
+# base64_file = encode_image("path/to/your/file.jpg") # or .pdf
+# response_with_file = client.responses.create(
+# model="${j}",
+# input=[
+# {
+# "role": "user",
+# "content": [
+# {"type": "input_text", "text": "${y}"},
+# {
+# "type": "input_image",
+# "image_url": f"data:image/jpeg;base64,{base64_file}", # or data:application/pdf;base64,{base64_file}
+# },
+# ],
+# }
+# ]${i}
+# )
+# print(response_with_file.output_text)
+`;break}case s.IMAGE:t="azure"===h?`
+# NOTE: The Azure SDK does not have a direct equivalent to the multi-modal 'responses.create' method shown for OpenAI.
+# This snippet uses 'client.images.generate' and will create a new image based on your prompt.
+# It does not use the uploaded image, as 'client.images.generate' does not support image inputs in this context.
+import os
+import requests
+import json
+import time
+from PIL import Image
+
+result = client.images.generate(
+ model="${j}",
+ prompt="${a}",
+ n=1
+)
+
+json_response = json.loads(result.model_dump_json())
+
+# Set the directory for the stored image
+image_dir = os.path.join(os.curdir, 'images')
+
+# If the directory doesn't exist, create it
+if not os.path.isdir(image_dir):
+ os.mkdir(image_dir)
+
+# Initialize the image path
+image_filename = f"generated_image_{int(time.time())}.png"
+image_path = os.path.join(image_dir, image_filename)
+
+try:
+ # Retrieve the generated image
+ if json_response.get("data") && len(json_response["data"]) > 0 && json_response["data"][0].get("url"):
+ image_url = json_response["data"][0]["url"]
+ generated_image = requests.get(image_url).content
+ with open(image_path, "wb") as image_file:
+ image_file.write(generated_image)
+
+ print(f"Image saved to {image_path}")
+ # Display the image
+ image = Image.open(image_path)
+ image.show()
+ else:
+ print("Could not find image URL in response.")
+ print("Full response:", json_response)
+except Exception as e:
+ print(f"An error occurred: {e}")
+ print("Full response:", json_response)
+`:`
+import base64
+import os
+import time
+import json
+from PIL import Image
+import requests
+
+# Helper function to encode images to base64
+def encode_image(image_path):
+ with open(image_path, "rb") as image_file:
+ return base64.b64encode(image_file.read()).decode('utf-8')
+
+# Helper function to create a file (simplified for this example)
+def create_file(image_path):
+ # In a real implementation, this would upload the file to OpenAI
+ # For this example, we'll just return a placeholder ID
+ return f"file_{os.path.basename(image_path).replace('.', '_')}"
+
+# The prompt entered by the user
+prompt = "${y}"
+
+# Encode images to base64
+base64_image1 = encode_image("body-lotion.png")
+base64_image2 = encode_image("soap.png")
+
+# Create file IDs
+file_id1 = create_file("body-lotion.png")
+file_id2 = create_file("incense-kit.png")
+
+response = client.responses.create(
+ model="${j}",
+ input=[
+ {
+ "role": "user",
+ "content": [
+ {"type": "input_text", "text": prompt},
+ {
+ "type": "input_image",
+ "image_url": f"data:image/jpeg;base64,{base64_image1}",
+ },
+ {
+ "type": "input_image",
+ "image_url": f"data:image/jpeg;base64,{base64_image2}",
+ },
+ {
+ "type": "input_image",
+ "file_id": file_id1,
+ },
+ {
+ "type": "input_image",
+ "file_id": file_id2,
+ }
+ ],
+ }
+ ],
+ tools=[{"type": "image_generation"}],
+)
+
+# Process the response
+image_generation_calls = [
+ output
+ for output in response.output
+ if output.type == "image_generation_call"
+]
+
+image_data = [output.result for output in image_generation_calls]
+
+if image_data:
+ image_base64 = image_data[0]
+ image_filename = f"edited_image_{int(time.time())}.png"
+ with open(image_filename, "wb") as f:
+ f.write(base64.b64decode(image_base64))
+ print(f"Image saved to {image_filename}")
+else:
+ # If no image is generated, there might be a text response with an explanation
+ text_response = [output.text for output in response.output if hasattr(output, 'text')]
+ if text_response:
+ print("No image generated. Model response:")
+ print("\\n".join(text_response))
+ else:
+ print("No image data found in response.")
+ print("Full response for debugging:")
+ print(response)
+`;break;case s.IMAGE_EDITS:t="azure"===h?`
+import base64
+import os
+import time
+import json
+from PIL import Image
+import requests
+
+# Helper function to encode images to base64
+def encode_image(image_path):
+ with open(image_path, "rb") as image_file:
+ return base64.b64encode(image_file.read()).decode('utf-8')
+
+# The prompt entered by the user
+prompt = "${y}"
+
+# Encode images to base64
+base64_image1 = encode_image("body-lotion.png")
+base64_image2 = encode_image("soap.png")
+
+# Create file IDs
+file_id1 = create_file("body-lotion.png")
+file_id2 = create_file("incense-kit.png")
+
+response = client.responses.create(
+ model="${j}",
+ input=[
+ {
+ "role": "user",
+ "content": [
+ {"type": "input_text", "text": prompt},
+ {
+ "type": "input_image",
+ "image_url": f"data:image/jpeg;base64,{base64_image1}",
+ },
+ {
+ "type": "input_image",
+ "image_url": f"data:image/jpeg;base64,{base64_image2}",
+ },
+ {
+ "type": "input_image",
+ "file_id": file_id1,
+ },
+ {
+ "type": "input_image",
+ "file_id": file_id2,
+ }
+ ],
+ }
+ ],
+ tools=[{"type": "image_generation"}],
+)
+
+# Process the response
+image_generation_calls = [
+ output
+ for output in response.output
+ if output.type == "image_generation_call"
+]
+
+image_data = [output.result for output in image_generation_calls]
+
+if image_data:
+ image_base64 = image_data[0]
+ image_filename = f"edited_image_{int(time.time())}.png"
+ with open(image_filename, "wb") as f:
+ f.write(base64.b64decode(image_base64))
+ print(f"Image saved to {image_filename}")
+else:
+ # If no image is generated, there might be a text response with an explanation
+ text_response = [output.text for output in response.output if hasattr(output, 'text')]
+ if text_response:
+ print("No image generated. Model response:")
+ print("\\n".join(text_response))
+ else:
+ print("No image data found in response.")
+ print("Full response for debugging:")
+ print(response)
+`:`
+import base64
+import os
+import time
+
+# Helper function to encode images to base64
+def encode_image(image_path):
+ with open(image_path, "rb") as image_file:
+ return base64.b64encode(image_file.read()).decode('utf-8')
+
+# Helper function to create a file (simplified for this example)
+def create_file(image_path):
+ # In a real implementation, this would upload the file to OpenAI
+ # For this example, we'll just return a placeholder ID
+ return f"file_{os.path.basename(image_path).replace('.', '_')}"
+
+# The prompt entered by the user
+prompt = "${y}"
+
+# Encode images to base64
+base64_image1 = encode_image("body-lotion.png")
+base64_image2 = encode_image("soap.png")
+
+# Create file IDs
+file_id1 = create_file("body-lotion.png")
+file_id2 = create_file("incense-kit.png")
+
+response = client.responses.create(
+ model="${j}",
+ input=[
+ {
+ "role": "user",
+ "content": [
+ {"type": "input_text", "text": prompt},
+ {
+ "type": "input_image",
+ "image_url": f"data:image/jpeg;base64,{base64_image1}",
+ },
+ {
+ "type": "input_image",
+ "image_url": f"data:image/jpeg;base64,{base64_image2}",
+ },
+ {
+ "type": "input_image",
+ "file_id": file_id1,
+ },
+ {
+ "type": "input_image",
+ "file_id": file_id2,
+ }
+ ],
+ }
+ ],
+ tools=[{"type": "image_generation"}],
+)
+
+# Process the response
+image_generation_calls = [
+ output
+ for output in response.output
+ if output.type == "image_generation_call"
+]
+
+image_data = [output.result for output in image_generation_calls]
+
+if image_data:
+ image_base64 = image_data[0]
+ image_filename = f"edited_image_{int(time.time())}.png"
+ with open(image_filename, "wb") as f:
+ f.write(base64.b64decode(image_base64))
+ print(f"Image saved to {image_filename}")
+else:
+ # If no image is generated, there might be a text response with an explanation
+ text_response = [output.text for output in response.output if hasattr(output, 'text')]
+ if text_response:
+ print("No image generated. Model response:")
+ print("\\n".join(text_response))
+ else:
+ print("No image data found in response.")
+ print("Full response for debugging:")
+ print(response)
+`;break;case s.EMBEDDINGS:t=`
+response = client.embeddings.create(
+ input="${a||"Your string here"}",
+ model="${j}",
+ encoding_format="base64" # or "float"
+)
+
+print(response.data[0].embedding)
+`;break;case s.TRANSCRIPTION:t=`
+# Open the audio file
+audio_file = open("path/to/your/audio/file.mp3", "rb")
+
+# Make the transcription request
+response = client.audio.transcriptions.create(
+ model="${j}",
+ file=audio_file${a?`,
+ prompt="${a.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`:""}
+)
+
+print(response.text)
+`;break;case s.SPEECH:t=`
+# Make the text-to-speech request
+response = client.audio.speech.create(
+ model="${j}",
+ input="${a||"Your text to convert to speech here"}",
+ voice="${p}" # Options: alloy, ash, ballad, coral, echo, fable, nova, onyx, sage, shimmer
+)
+
+# Save the audio to a file
+output_filename = "output_speech.mp3"
+response.stream_to_file(output_filename)
+print(f"Audio saved to {output_filename}")
+
+# Optional: Customize response format and speed
+# response = client.audio.speech.create(
+# model="${j}",
+# input="${a||"Your text to convert to speech here"}",
+# voice="alloy",
+# response_format="mp3", # Options: mp3, opus, aac, flac, wav, pcm
+# speed=1.0 # Range: 0.25 to 4.0
+# )
+# response.stream_to_file("output_speech.mp3")
+`;break;default:t="\n# Code generation for this endpoint is not implemented yet."}return`${k}
+${t}`}],909947)},157058,e=>{"use strict";var t=e.i(843476),i=e.i(934879),n=e.i(976883),s=e.i(135214),r=e.i(708347);e.s(["default",0,function(){let{accessToken:e,userRole:a,premiumUser:o}=(0,s.default)();return(0,r.isAdminRole)(a)?(0,t.jsx)(i.default,{accessToken:e,publicPage:!1,premiumUser:o,userRole:a}):(0,t.jsx)(n.default,{accessToken:e,isEmbedded:!0})}])}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/027qywrv12iu8.js b/litellm/proxy/_experimental/out/_next/static/chunks/027qywrv12iu8.js
deleted file mode 100644
index 138832c6a88..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/027qywrv12iu8.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,503116,949411,e=>{"use strict";let t=(0,e.i(475254).default)("clock",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polyline",{points:"12 6 12 12 16 14",key:"68esgv"}]]);e.s(["default",0,t],949411),e.s(["Clock",0,t],503116)},663435,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(744582),s=e.i(785242);e.s(["default",0,({value:e,onChange:l,onTeamSelect:r,disabled:n,organizationId:o,pageSize:A=20,id:u})=>{let[d,c]=(0,i.useState)(""),{data:h,fetchNextPage:g,hasNextPage:p,isFetchingNextPage:b,isLoading:m}=(0,s.useInfiniteTeams)(A,d||void 0,o),v=(0,i.useMemo)(()=>{if(!h?.pages)return[];let e=new Set,t=[];for(let i of h.pages)for(let a of i.teams)e.has(a.team_id)||(e.add(a.team_id),t.push(a));return t},[h]);return(0,t.jsx)("div",{"data-testid":"team-dropdown",children:(0,t.jsx)(a.PaginatedSearchSelect,{options:v.map(e=>({label:e.team_alias||e.team_id,value:e.team_id,sublabel:e.team_id})),value:e||void 0,onValueChange:e=>{l?.(e),r&&r(e?v.find(t=>t.team_id===e)??null:null)},onSearchChange:c,onLoadMore:g,hasNextPage:p,isLoading:m,isFetchingNextPage:b,placeholder:"Search or select a team",emptyText:"No teams found",loadingText:"Loading teams…",disabled:n,inputId:u})})}])},343488,e=>{"use strict";var t=e.i(540626),i=e.i(271645);e.s(["useDebouncedCallback",0,function(e,a){let s=(0,t.useDebouncer)(e,a).maybeExecute;return(0,i.useCallback)((...e)=>s(...e),[s])}])},540626,e=>{"use strict";let t;var i=e.i(271645);let a=(0,i.createContext)(null);function s(e,t){if(Object.is(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;if(e instanceof Map&&t instanceof Map){if(e.size!==t.size)return!1;for(let[i,a]of e)if(!t.has(i)||!Object.is(a,t.get(i)))return!1;return!0}if(e instanceof Set&&t instanceof Set){if(e.size!==t.size)return!1;for(let i of e)if(!t.has(i))return!1;return!0}if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();let i=l(e);if(i.length!==l(t).length)return!1;for(let a=0;ae,a){let s=a?.compare??n,l=(0,i.useCallback)(t=>{let{unsubscribe:i}=e.subscribe(t);return i},[e]),A=(0,i.useCallback)(()=>e.get(),[e]);return(0,r.useSyncExternalStoreWithSelector)(l,A,A,t,s)}function A(e,...t){return"function"==typeof e?e(...t):e}var u=class{#e=!0;#t;#i;#a;#s;#l;#r;#n;#o=0;#A=5;#u=!1;#d=!1;#c=null;#h=()=>{this.debugLog("Connected to event bus"),this.#l=!0,this.#u=!1,this.debugLog("Emitting queued events",this.#s),this.#s.forEach(e=>this.emitEventToBus(e)),this.#s=[],this.stopConnectLoop(),this.#i().removeEventListener("tanstack-connect-success",this.#h)};#g=()=>{if(this.#o{this.#u||(this.#u=!0,this.#i().addEventListener("tanstack-connect-success",this.#h),this.#g())};constructor({pluginId:e,debug:t=!1,enabled:i=!0,reconnectEveryMs:a=300}){this.#t=e,this.#e=i,this.#i=this.getGlobalTarget,this.#a=t,this.debugLog(" Initializing event subscription for plugin",this.#t),this.#s=[],this.#l=!1,this.#d=!1,this.#r=null,this.#n=a}startConnectLoop(){null!==this.#r||this.#l||(this.debugLog(`Starting connect loop (every ${this.#n}ms)`),this.#r=setInterval(this.#g,this.#n))}stopConnectLoop(){this.#u=!1,null!==this.#r&&(clearInterval(this.#r),this.#r=null,this.#s=[],this.debugLog("Stopped connect loop"))}debugLog(...e){this.#a&&console.log(`🌴 [tanstack-devtools:${this.#t}-plugin]`,...e)}getGlobalTarget(){if("u">typeof globalThis&&globalThis.__TANSTACK_EVENT_TARGET__)return this.debugLog("Using global event target"),globalThis.__TANSTACK_EVENT_TARGET__;if("u">typeof window&&void 0!==window.addEventListener)return this.debugLog("Using window as event target"),window;let e="u">typeof EventTarget?new EventTarget:void 0;return void 0===e||void 0===e.addEventListener?(this.debugLog("No event mechanism available, running in non-web environment"),{addEventListener:()=>{},removeEventListener:()=>{},dispatchEvent:()=>!1}):(this.debugLog("Using new EventTarget as fallback"),e)}getPluginId(){return this.#t}dispatchCustomEventShim(e,t){try{let i=new Event(e,{detail:t});this.#i().dispatchEvent(i)}catch(e){this.debugLog("Failed to dispatch shim event")}}dispatchCustomEvent(e,t){try{this.#i().dispatchEvent(new CustomEvent(e,{detail:t}))}catch(i){this.dispatchCustomEventShim(e,t)}}emitEventToBus(e){this.debugLog("Emitting event to client bus",e),this.dispatchCustomEvent("tanstack-dispatch-event",e)}createEventPayload(e,t){return{type:`${this.#t}:${e}`,payload:t,pluginId:this.#t}}emit(e,t){if(!this.#e)return void this.debugLog("Event bus client is disabled, not emitting event",e,t);if(this.#c&&(this.debugLog("Emitting event to internal event target",e,t),this.#c.dispatchEvent(new CustomEvent(`${this.#t}:${e}`,{detail:this.createEventPayload(e,t)}))),this.#d)return void this.debugLog("Previously failed to connect, not emitting to bus");if(!this.#l){this.debugLog("Bus not available, will be pushed as soon as connected"),this.#s.push(this.createEventPayload(e,t)),"u">typeof CustomEvent&&!this.#u&&(this.#p(),this.startConnectLoop());return}return this.emitEventToBus(this.createEventPayload(e,t))}on(e,t,i){let a=i?.withEventTarget??!1,s=`${this.#t}:${e}`;if(a&&(this.#c||(this.#c=new EventTarget),this.#c.addEventListener(s,e=>{t(e.detail)})),!this.#e)return this.debugLog("Event bus client is disabled, not registering event",s),()=>{};let l=e=>{this.debugLog("Received event from bus",e.detail),t(e.detail)};return this.#i().addEventListener(s,l),this.debugLog("Registered event to bus",s),()=>{a&&this.#c?.removeEventListener(s,l),this.#i().removeEventListener(s,l)}}onAll(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{e(t.detail)};return this.#i().addEventListener("tanstack-devtools-global",t),()=>this.#i().removeEventListener("tanstack-devtools-global",t)}onAllPluginEvents(e){if(!this.#e)return this.debugLog("Event bus client is disabled, not registering event"),()=>{};let t=t=>{let i=t.detail;this.#t&&i.pluginId!==this.#t||e(i)};return this.#i().addEventListener("tanstack-devtools-global",t),()=>this.#i().removeEventListener("tanstack-devtools-global",t)}};let d=new Map;function c(e){if(void 0!==e)try{return JSON.parse(JSON.stringify(e))}catch{return null}}let h=new class extends u{constructor(e){super({pluginId:"pacer",debug:e?.debug,reconnectEveryMs:1e3})}};function g(e,t,i){let a="object"==typeof e,s=a?e:void 0;return{next:(a?e.next:e)?.bind(s),error:(a?e.error:t)?.bind(s),complete:(a?e.complete:i)?.bind(s)}}let p=[],b=0,{link:m,unlink:v,propagate:f,checkDirty:x,shallowPropagate:E}=function({update:e,notify:t,unwatched:i}){return{link:function(e,t,i){let a=t.depsTail;if(void 0!==a&&a.dep===e)return;let s=void 0!==a?a.nextDep:t.deps;if(void 0!==s&&s.dep===e){s.version=i,t.depsTail=s;return}let l=e.subsTail;if(void 0!==l&&l.version===i&&l.sub===t)return;let r=t.depsTail=e.subsTail={version:i,dep:e,sub:t,prevDep:a,nextDep:s,prevSub:l,nextSub:void 0};void 0!==s&&(s.prevDep=r),void 0!==a?a.nextDep=r:t.deps=r,void 0!==l?l.nextSub=r:e.subs=r},unlink:function(e,t=e.sub){let a=e.dep,s=e.prevDep,l=e.nextDep,r=e.nextSub,n=e.prevSub;return void 0!==l?l.prevDep=s:t.depsTail=s,void 0!==s?s.nextDep=l:t.deps=l,void 0!==r?r.prevSub=n:a.subsTail=n,void 0!==n?n.nextSub=r:void 0===(a.subs=r)&&i(a),l},propagate:function(e){let i,a=e.nextSub;e:for(;;){let s=e.sub,l=s.flags;if(60&l?12&l?4&l?!(48&l)&&function(e,t){let i=t.depsTail;for(;void 0!==i;){if(i===e)return!0;i=i.prevDep}return!1}(e,s)?(s.flags=40|l,l&=1):l=0:s.flags=-9&l|32:l=0:s.flags=32|l,2&l&&t(s),1&l){let t=s.subs;if(void 0!==t){let s=(e=t).nextSub;void 0!==s&&(i={value:a,prev:i},a=s);continue}}if(void 0!==(e=a)){a=e.nextSub;continue}for(;void 0!==i;)if(e=i.value,i=i.prev,void 0!==e){a=e.nextSub;continue e}break}},checkDirty:function(t,i){let s,l=0,r=!1;e:for(;;){let n=t.dep,o=n.flags;if(16&i.flags)r=!0;else if((17&o)==17){if(e(n)){let e=n.subs;void 0!==e.nextSub&&a(e),r=!0}}else if((33&o)==33){(void 0!==t.nextSub||void 0!==t.prevSub)&&(s={value:t,prev:s}),t=n.deps,i=n,++l;continue}if(!r){let e=t.nextDep;if(void 0!==e){t=e;continue}}for(;l--;){let l=i.subs,n=void 0!==l.nextSub;if(n?(t=s.value,s=s.prev):t=l,r){if(e(i)){n&&a(l),i=t.sub;continue}r=!1}else i.flags&=-33;i=t.sub;let o=t.nextDep;if(void 0!==o){t=o;continue e}}return r}},shallowPropagate:a};function a(e){do{let i=e.sub,a=i.flags;(48&a)==32&&(i.flags=16|a,(6&a)==2&&t(i))}while(void 0!==(e=e.nextSub))}}({update:e=>e._update(),notify(e){p[C++]=e,e.flags&=-3},unwatched(e){void 0!==e.depsTail&&(e.depsTail=void 0,e.flags=17,w(e))}}),I=0,C=0;function w(e){let t=e.depsTail,i=void 0!==t?t.nextDep:e.deps;for(;void 0!==i;)i=v(i,e)}var L=class{constructor(e,i){this.atom=function(e){let i="function"==typeof e,a={_snapshot:i?void 0:e,subs:void 0,subsTail:void 0,deps:void 0,depsTail:void 0,flags:+!i,get:()=>(void 0!==t&&m(a,t,b),a._snapshot),subscribe(e){var i;let s,l,r=g(e),n={current:!1},o=(i=()=>{a.get(),n.current?r.next?.(a._snapshot):n.current=!0},s=()=>{let e=t;t=l,++b,l.depsTail=void 0,l.flags=6;try{return i()}finally{t=e,l.flags&=-5,w(l)}},l={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:6,notify(){let e=this.flags;16&e||32&e&&x(this.deps,this)?s():this.flags=2},stop(){this.flags=0,this.depsTail=void 0,w(this)}},s(),l);return{unsubscribe:()=>{o.stop()}}},_update(s){let l=t,r=(void 0)??Object.is;if(i)t=a,++b,a.depsTail=void 0;else if(void 0===s)return!1;i&&(a.flags=5);try{let t=a._snapshot,l="function"==typeof s?s(t):void 0===s&&i?e(t):s;if(void 0===t||!r(t,l))return a._snapshot=l,!0;return!1}finally{t=l,i&&(a.flags&=-5),w(a)}}};return i?(a.flags=17,a.get=function(){let e=a.flags;if(16&e||32&e&&x(a.deps,a)){if(a._update()){let e=a.subs;void 0!==e&&E(e)}}else 32&e&&(a.flags=-33&e);return void 0!==t&&m(a,t,b),a._snapshot}):a.set=function(e){if(a._update(e)){let e=a.subs;if(void 0!==e&&(f(e),E(e),1)){for(;I{this.options={...this.options,...e},this.#m()||this.cancel()},this.#v=e=>{this.store.setState(t=>{let i={...t,...e},{isPending:a}=i;return{...i,status:this.#m()?a?"pending":"idle":"disabled"}}),((e,t)=>{let i=t.key;if(i){var a,s;d.set(i,t),h.emit(e,{key:(a={...t,key:i}).key,store:{state:c("function"==typeof(s=a.store).get?s.get():s.state)},options:c(a.options)})}})("Debouncer",this)},this.#m=()=>!!A(this.options.enabled,this),this.#f=()=>A(this.options.wait,this),this.maybeExecute=(...e)=>{if(!this.#m())return;this.#v({maybeExecuteCount:this.store.state.maybeExecuteCount+1});let t=!1;this.options.leading&&this.store.state.canLeadingExecute&&(this.#v({canLeadingExecute:!1}),t=!0,this.#x(...e)),this.options.trailing&&this.#v({isPending:!0,lastArgs:e}),this.#b&&clearTimeout(this.#b),this.#b=setTimeout(()=>{this.#v({canLeadingExecute:!0}),this.options.trailing&&!t&&this.#x(...e)},this.#f())},this.#x=(...e)=>{this.#m()&&(this.fn(...e),this.#v({executionCount:this.store.state.executionCount+1,isPending:!1,lastArgs:void 0}),this.options.onExecute?.(e,this))},this.flush=()=>{this.store.state.isPending&&this.store.state.lastArgs&&(this.#E(),this.#x(...this.store.state.lastArgs))},this.#E=()=>{this.#b&&(clearTimeout(this.#b),this.#b=void 0)},this.cancel=()=>{this.#E(),this.#v({canLeadingExecute:!0,isPending:!1})},this.reset=()=>{this.#v(_())},this.key=t.key,this.options={...T,...t},this.#v(this.options.initialState??{}),this.key&&h.on("d-Debouncer",e=>{e.payload.key===this.key&&(this.#v(e.payload.store.state),this.setOptions(e.payload.options))})}#v;#m;#f;#x;#E};e.s(["useDebouncer",0,function(e,t,l=()=>({})){let r={...((0,i.useContext)(a)?.defaultOptions??{}).debouncer,...t},[n]=(0,i.useState)(()=>{let t=new O(e,r);return t.Subscribe=function(e){let i=o(t.store,e.selector,{compare:s});return"function"==typeof e.children?e.children(i):e.children},t});n.fn=e,n.setOptions(r),(0,i.useEffect)(()=>()=>{r.onUnmount?r.onUnmount(n):n.cancel()},[]);let A=o(n.store,l,{compare:s});return(0,i.useMemo)(()=>({...n,state:A}),[n,A])}],540626)},741466,e=>{"use strict";e.s(["DEBOUNCE_WAIT_MS",0,300])},186248,e=>{"use strict";var t=e.i(343488),i=e.i(271645),a=e.i(741466);let s=new Set(["input-change","input-clear","clear-press"]);e.s(["usePaginatedCombobox",0,function({onSearchChange:e,onLoadMore:l,hasNextPage:r,isFetchingNextPage:n}){let o=(0,t.useDebouncedCallback)(e,{wait:a.DEBOUNCE_WAIT_MS}),[A,u]=(0,i.useState)(null);return{typedQuery:A,handleInputValueChange:(e,t)=>{s.has(t)?(u(e),o(e)):u(null)},handleOpenChange:(e,t)=>{if(!e){A&&o(""),u(null);return}s.has(t)||u("")},handleScroll:e=>{let t=e.currentTarget;0===t.scrollHeight||(t.scrollTop+t.clientHeight)/t.scrollHeight>=.8&&r&&!n&&l?.()}}}])},744582,e=>{"use strict";var t=e.i(843476),i=e.i(531278),a=e.i(271645),s=e.i(131792),l=e.i(186248);e.s(["PaginatedSearchSelect",0,function({options:e,value:r,onValueChange:n,onSearchChange:o,onLoadMore:A,hasNextPage:u=!1,isLoading:d=!1,isFetchingNextPage:c=!1,placeholder:h="Search…",emptyText:g="No results",errorText:p,loadingText:b="Loading…",autoHighlight:m=!1,disabled:v=!1,className:f,inputId:x,"aria-required":E,"aria-invalid":I,"aria-describedby":C}){let[w,L]=(0,a.useState)(null),_=(0,a.useRef)(!1),T=e=>{let t=e.currentTarget;_.current=t.value.length>0&&0===t.selectionStart&&t.selectionEnd===t.value.length},O=(0,a.useMemo)(()=>void 0===r||""===r?null:e.find(e=>e.value===r)??(w?.value===r?w:{label:r,value:r}),[e,r,w]),y=(0,a.useMemo)(()=>null===O||e.some(e=>e.value===O.value)?e:[O,...e],[e,O]),{typedQuery:k,handleInputValueChange:S,handleOpenChange:R,handleScroll:B}=(0,l.usePaginatedCombobox)({onSearchChange:o,onLoadMore:A,hasNextPage:u,isFetchingNextPage:c});return(0,t.jsxs)(s.Combobox,{items:y,value:O,inputValue:k??O?.label??"",onValueChange:e=>{L(e),n(e?.value??"")},onInputValueChange:(e,t)=>{var i,a;let s,l;return i=t.reason,s=_.current,_.current=!1,void S(null!==k||s||""===(l=((e,t)=>{let i=0;for(;iR(e,t.reason),isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,autoHighlight:m,filter:null,disabled:v,children:[(0,t.jsx)(s.ComboboxInput,{id:x,"aria-required":E,"aria-invalid":I,"aria-describedby":C,onFocus:e=>e.currentTarget.select(),onKeyDown:T,onPaste:T,placeholder:h,showClear:void 0!==r&&""!==r,className:`w-full ${f??""}`}),(0,t.jsxs)(s.ComboboxContent,{children:[(0,t.jsx)(s.ComboboxEmpty,{className:null==p?void 0:"text-destructive",children:p??(d?b:g)}),(0,t.jsx)(s.ComboboxList,{onScroll:B,"data-testid":"paginated-search-select-list",children:e=>(0,t.jsx)(s.ComboboxItem,{value:e,children:(0,t.jsxs)("span",{className:"flex min-w-0 flex-col",children:[(0,t.jsx)("span",{className:"truncate",children:e.label}),null!=e.sublabel&&""!==e.sublabel&&(0,t.jsx)("span",{className:"truncate text-xs text-muted-foreground",children:e.sublabel})]})},e.value)}),c&&(0,t.jsx)("div",{className:"flex justify-center py-2","data-testid":"paginated-search-select-loading-more",children:(0,t.jsx)(i.Loader2,{className:"size-4 animate-spin text-muted-foreground"})})]})]})}])},435451,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(793479);let s=i.default.forwardRef(({step:e=.01,style:i={width:"100%"},placeholder:s="Enter a numerical value",min:l,max:r,onChange:n,...o},A)=>(0,t.jsx)(a.Input,{ref:A,type:"number",onWheel:e=>e.currentTarget.blur(),step:e,style:i,placeholder:s,min:l,max:r,onChange:n,...o}));s.displayName="NumericalInput",e.s(["default",0,s])},421436,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(131792);let s=(e,t)=>e.label.toLowerCase().includes(t.trim().toLowerCase());e.s(["TagsInput",0,({value:e,onValueChange:l,options:r=[],placeholder:n,emptyText:o="No matching options",tokenSeparators:A=[],loading:u=!1,disabled:d=!1,id:c})=>{let h=(0,a.useComboboxAnchor)(),[g,p]=(0,i.useState)(""),b=e.map(e=>r.find(t=>t.value===e)??{label:e,value:e}),m=g.trim(),v=m.length>0&&!r.some(e=>e.value===m)?[{label:m,value:m},...r]:r,f=t=>{let i=t.map(e=>e.trim()).filter(Boolean).filter((t,i,a)=>a.indexOf(t)===i&&!e.includes(t));i.length>0&&l([...e,...i])},x=()=>{p(""),f([g])},E=e=>{"Enter"!==e.key||(e.preventDefault(),e.currentTarget.getAttribute("aria-activedescendant")||x())};return(0,t.jsxs)(a.Combobox,{multiple:!0,items:v,value:b,onValueChange:e=>{p(""),l(e.map(e=>e.value))},inputValue:g,onInputValueChange:e=>{if(!A.some(t=>e.includes(t)))return void p(e);let t=A.reduce((e,t)=>e.flatMap(e=>e.split(t)),[e]);p(t[t.length-1]??""),f(t.slice(0,-1))},isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:s,openOnInputClick:!0,disabled:d||u,children:[(0,t.jsx)(a.ComboboxChips,{render:(0,t.jsx)("div",{ref:h}),className:"min-h-8 py-1 text-sm",children:(0,t.jsx)(a.ComboboxValue,{children:e=>(0,t.jsxs)(t.Fragment,{children:[e.map(e=>(0,t.jsx)(a.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),(0,t.jsx)(a.ComboboxChipsInput,{id:c,placeholder:u?"Loading...":n,className:"min-w-24",onBlur:x,onKeyDown:E})]})})}),(0,t.jsxs)(a.ComboboxContent,{anchor:h,children:[(0,t.jsx)(a.ComboboxEmpty,{children:o}),(0,t.jsx)(a.ComboboxList,{children:e=>(0,t.jsx)(a.ComboboxItem,{value:e,title:e.label,children:e.label},e.value)})]})]})}])},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},871689,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeft",()=>t.default])},845150,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(131792);let s=(e,t)=>{let i=t.trim().toLowerCase();return!i||e.label.toLowerCase().includes(i)||e.value.toLowerCase().includes(i)||(e.description?.toLowerCase().includes(i)??!1)};e.s(["MultiSelect",0,function({id:e,options:l,value:r=[],onValueChange:n,placeholder:o="Select options",emptyText:A="No options found",disabled:u=!1,loading:d=!1,allowCustomValues:c=!1,className:h}){let g=(0,a.useComboboxAnchor)(),[p,b]=(0,i.useState)(""),m=l.filter(e=>null!=e&&"string"==typeof e.value&&e.value.length>0),v=r.filter(e=>"string"==typeof e&&e.length>0).map(e=>m.find(t=>t.value===e)??{label:e,value:e}),f=p.trim(),x=m.some(e=>e.value.toLowerCase()===f.toLowerCase()),E=c&&f&&!x?[...m,{label:`Create "${f}"`,value:f}]:m;return(0,t.jsxs)(a.Combobox,{multiple:!0,items:E,value:v,onValueChange:e=>{n(Array.from(new Set(c?e.flatMap(e=>r.includes(e.value)?[e.value]:e.value.split(",").map(e=>e.trim()).filter(e=>e.length>0)):e.map(e=>e.value)))),b("")},inputValue:p,onInputValueChange:b,isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:s,disabled:u||d,children:[(0,t.jsx)(a.ComboboxChips,{render:(0,t.jsx)("div",{ref:g}),className:`min-h-8 py-1 text-sm ${h??""}`,children:(0,t.jsx)(a.ComboboxValue,{children:i=>(0,t.jsxs)(t.Fragment,{children:[i.map(e=>(0,t.jsx)(a.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),(0,t.jsx)(a.ComboboxChipsInput,{id:e,placeholder:d?"Loading...":o,className:"min-w-24","aria-label":o||void 0}),i.length>0&&!u&&!d&&(0,t.jsx)(a.ComboboxClear,{className:"ml-auto self-center","aria-label":"Clear all"})]})})}),(0,t.jsxs)(a.ComboboxContent,{anchor:g,children:[(0,t.jsx)(a.ComboboxEmpty,{children:A}),(0,t.jsx)(a.ComboboxList,{children:e=>(0,t.jsx)(a.ComboboxItem,{value:e,disabled:e.disabled,children:(0,t.jsxs)("span",{className:"min-w-0",children:[(0,t.jsx)("span",{className:"block truncate",children:e.label}),e.description&&(0,t.jsx)("span",{className:"block truncate text-xs text-muted-foreground",children:e.description})]})},e.value)})]})]})}])},519380,e=>{e.q("/litellm-asset-prefix/_next/static/media/bedrock.2vhamxr8q6y4o.svg")},946013,e=>{e.q("/litellm-asset-prefix/_next/static/media/google.3y8ypywwtqob_.svg")},641266,e=>{e.q("/litellm-asset-prefix/_next/static/media/microsoft_azure.3626-7zx7wf09.svg")},956529,e=>{e.q("/litellm-asset-prefix/_next/static/media/openai_small.3rj8nedgjpevh.svg")},913383,e=>{e.q("/litellm-asset-prefix/_next/static/media/a2a_agent.14el5-6dflh1h.png")},238564,e=>{e.q("/litellm-asset-prefix/_next/static/media/ai21.0m_u-tih8nm0v.svg")},941533,e=>{e.q("/litellm-asset-prefix/_next/static/media/aiml_api.1dq6dbpwklhlg.svg")},994636,e=>{e.q("/litellm-asset-prefix/_next/static/media/anthropic.3s95kgy8jpc64.svg")},824770,e=>{e.q("/litellm-asset-prefix/_next/static/media/assemblyai_small.0w_dslsra91uw.png")},920076,e=>{e.q("/litellm-asset-prefix/_next/static/media/baseten.41k2lnwp3c5g9.svg")},96889,e=>{e.q("/litellm-asset-prefix/_next/static/media/cerebras.1ur1xyfqk9ncz.svg")},348026,e=>{e.q("/litellm-asset-prefix/_next/static/media/cloudflare.2n1spdq7u5yki.svg")},727148,e=>{e.q("/litellm-asset-prefix/_next/static/media/cohere.22i3i2e449j5i.svg")},411703,e=>{e.q("/litellm-asset-prefix/_next/static/media/cometapi.3w0xficbg3dkk.svg")},922480,e=>{e.q("/litellm-asset-prefix/_next/static/media/cursor.1q1ev-_5l7exg.svg")},769490,e=>{e.q("/litellm-asset-prefix/_next/static/media/databricks.2hiet9qlqzn-g.svg")},829789,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepgram.3-krp20p_xed3.png")},41730,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepinfra.3lr_lsr7mhui6.png")},662576,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepseek.3n4cu0x32i_7w.svg")},987202,e=>{e.q("/litellm-asset-prefix/_next/static/media/elevenlabs.2982m_dk2-h_y.png")},953265,e=>{e.q("/litellm-asset-prefix/_next/static/media/fal_ai.3rahrirki8sby.jpg")},346512,e=>{e.q("/litellm-asset-prefix/_next/static/media/featherless.3hmlef3fhc0h5.svg")},84416,e=>{e.q("/litellm-asset-prefix/_next/static/media/fireworks.3t1b6p8edeqyo.svg")},104602,e=>{e.q("/litellm-asset-prefix/_next/static/media/friendli.0ymiswh6l35bq.svg")},888193,e=>{e.q("/litellm-asset-prefix/_next/static/media/github_copilot.3k-8jyadoaq2u.svg")},447500,e=>{e.q("/litellm-asset-prefix/_next/static/media/groq.20csmqzsusp1k.svg")},270039,e=>{e.q("/litellm-asset-prefix/_next/static/media/huggingface.1-07ypt9ii_-p.svg")},227733,e=>{e.q("/litellm-asset-prefix/_next/static/media/hyperbolic.3le20v59sebn8.svg")},823929,e=>{e.q("/litellm-asset-prefix/_next/static/media/infinity.0s9s12bl4lccx.png")},333845,e=>{e.q("/litellm-asset-prefix/_next/static/media/jina.0ukab8o-3-5m_.png")},813878,e=>{e.q("/litellm-asset-prefix/_next/static/media/lambda.26_vz7cmyuodo.svg")},767788,e=>{e.q("/litellm-asset-prefix/_next/static/media/lmstudio.35s3-83mlhcms.svg")},808630,e=>{e.q("/litellm-asset-prefix/_next/static/media/meta_llama.1kxk24vwsem49.svg")},468732,e=>{e.q("/litellm-asset-prefix/_next/static/media/minimax.2mfkkqc-lnsen.svg")},610503,e=>{e.q("/litellm-asset-prefix/_next/static/media/mistral.0n8jv_67hgq4h.svg")},438969,e=>{e.q("/litellm-asset-prefix/_next/static/media/moonshot.3__i9wvf37ksm.svg")},852459,e=>{e.q("/litellm-asset-prefix/_next/static/media/morph.2av06eo-t0-ve.svg")},494696,e=>{e.q("/litellm-asset-prefix/_next/static/media/nebius.2ipf7rmjccira.svg")},148973,e=>{e.q("/litellm-asset-prefix/_next/static/media/novita.0_nzmm_rl4lrf.svg")},570036,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_nim.1fz-5ugf_um0v.svg")},151170,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_triton.1aotoxig_m2w1.png")},862330,e=>{e.q("/litellm-asset-prefix/_next/static/media/ollama.144cif369atc5.svg")},788158,e=>{e.q("/litellm-asset-prefix/_next/static/media/openrouter.1xk7748-_jixf.svg")},350567,e=>{e.q("/litellm-asset-prefix/_next/static/media/oracle.43kws59xxr8ig.svg")},822797,e=>{e.q("/litellm-asset-prefix/_next/static/media/perplexity-ai.2do8hoc8tw__0.svg")},840911,e=>{e.q("/litellm-asset-prefix/_next/static/media/qwen.0a49x9i08_0gz.png")},445735,e=>{e.q("/litellm-asset-prefix/_next/static/media/recraft.2f4cv-c9ad-mo.svg")},635202,e=>{e.q("/litellm-asset-prefix/_next/static/media/replicate.445bidyix2tyh.svg")},669161,e=>{e.q("/litellm-asset-prefix/_next/static/media/runway.2zzwye1fddnnn.png")},159508,e=>{e.q("/litellm-asset-prefix/_next/static/media/sambanova.1vcyu0faw1x8h.svg")},544025,e=>{e.q("/litellm-asset-prefix/_next/static/media/sap.1367hgge0s0xl.png")},708767,e=>{e.q("/litellm-asset-prefix/_next/static/media/scx_ai.3emo1p5delrhx.svg")},100588,e=>{e.q("/litellm-asset-prefix/_next/static/media/snowflake.2_p8qqpi0r3lr.svg")},183804,e=>{e.q("/litellm-asset-prefix/_next/static/media/soniox.3nhjmssy7ybh7.svg")},865502,e=>{e.q("/litellm-asset-prefix/_next/static/media/togetherai.1wk-mouzgw5ho.svg")},96912,e=>{e.q("/litellm-asset-prefix/_next/static/media/topaz.3rjp3zvx4eags.svg")},395073,e=>{e.q("/litellm-asset-prefix/_next/static/media/v0.15trd3tb1ulop.svg")},407829,e=>{e.q("/litellm-asset-prefix/_next/static/media/vercel.1mvnwxofolt8y.svg")},846077,e=>{e.q("/litellm-asset-prefix/_next/static/media/vllm.3_gqby46r7s3x.png")},914861,e=>{e.q("/litellm-asset-prefix/_next/static/media/volcengine.23ly9ik_qc138.png")},285328,e=>{e.q("/litellm-asset-prefix/_next/static/media/voyage.0krq6ew-yr8dk.webp")},779278,e=>{e.q("/litellm-asset-prefix/_next/static/media/watsonx.19rrg39yvhpk8.svg")},325532,e=>{e.q("/litellm-asset-prefix/_next/static/media/xai.2kc3gjiopn9om.svg")},288330,e=>{e.q("/litellm-asset-prefix/_next/static/media/xinference.063cy_ievvy5u.svg")},922158,336712,39182,980385,e=>{"use strict";let t={src:e.i(519380).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,t],922158);let i={src:e.i(946013).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,i],336712);let a={src:e.i(641266).default,width:200,height:58,blurWidth:0,blurHeight:0};e.s(["default",0,a],39182);let s={src:e.i(956529).default,width:28,height:28,blurWidth:0,blurHeight:0};e.s(["default",0,s],980385)},916925,555987,9774,247044,e=>{"use strict";var t,i=e.i(221688),a=e.i(950643);let s=/^(https?:|data:|blob:|\/\/)/i,l=e=>s.test(e),r=(e,t=i.serverRootPath)=>{let s;if(!e)return;if(l(e)||e.includes("/_next/static/"))return e;let r=(0,a.normalizeRootPath)(t);return r&&(e===r||e.startsWith(`${r}/`))?e:(s=(0,a.normalizeRootPath)(t),`${s}${e.startsWith("/")?e:`/${e}`}`)};e.s(["isExternalAssetSrc",0,l,"resolveLogoSrc",0,r],555987);let n={src:e.i(913383).default,width:661,height:768,blurWidth:7,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAwUlEQVR42h2OvQpGcByFf5dK7oBJFoooJDaDZFA+BoVkNBikGJSUJINyGeft/Q+nznDO00O6rsM0Tfi+z6JpGizLgqqqIEVR0HUdqqqCbdus930PWZZBy7IgCAKkaYpxHJEkCaIowjAMoGmaEMcx8jxHURRo2xZ1XaMsS9B5nrjvG+u6Yp5nfN+H53nwJ9JxHMiyDO/7Mtx1Xey1bRvIcRzwPI993xGGIZqmgSAIMAwDJEkSPM9jphzHsYHruhBFET+hn6S8pf6D7AAAAABJRU5ErkJggg=="},o={src:e.i(238564).default,width:103,height:24,blurWidth:0,blurHeight:0},A={src:e.i(941533).default,width:115,height:24,blurWidth:0,blurHeight:0},u={src:e.i(994636).default,width:46,height:46,blurWidth:0,blurHeight:0},d={src:e.i(824770).default,width:28,height:28,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAlElEQVR42m3OoQqDUBQGYF9mwzLbFiZsMNgwuGa4YFgYLC6PgcXuA5gFzdcgFkExGr33ogZRNIr6CAoKKgo/nAMfh/NTu3u4GWoY+0fIAsIC3C8LuIiRH9S2W5wBXsBPKaHTGGb+lZMJmCe2vPYjZe9/bMDswKMRbq9Yg9VRICcBq3p6FckINIf6o6ECwyOam/1YpwPFUFu+Lt2F2QAAAABJRU5ErkJggg=="},c={src:e.i(920076).default,width:16,height:16,blurWidth:0,blurHeight:0};var h=e.i(922158);let g={src:e.i(96889).default,width:800,height:600,blurWidth:0,blurHeight:0},p={src:e.i(348026).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,p],9774);let b={src:e.i(727148).default,width:75,height:75,blurWidth:0,blurHeight:0},m={src:e.i(411703).default,width:16,height:16,blurWidth:0,blurHeight:0},v={src:e.i(922480).default,width:16,height:16,blurWidth:0,blurHeight:0},f={src:e.i(769490).default,width:16,height:16,blurWidth:0,blurHeight:0},x={src:e.i(829789).default,width:32,height:32,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAzklEQVR42k3PPWuDcBDHccUiiikYSwqhg+IkuKUpOLqK4OYrcBZcFCcH352mgy/Ch9mxEPg2+s+Q4W65zx33kyRJQpZlFOUNTdM4HN45Hi1Op0/O56+7tAHbtqmqiqZpKIqCy+Uby/rYkABhGLKuK+M4siwLt9sv1+sPpmkKEAQBwzCQpilxHDNNE3VdYxiGALqu47oujuMQRdEOyrJEVVUBFEUhSRK6rmOeZ/q+x/f97XkBHqfIsoy2bcnzHM/z9mSP2Q62dt/0c+O1/v4BYRxu3LgaR7UAAAAASUVORK5CYII="},E={src:e.i(41730).default,width:225,height:225,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAfklEQVR42nVOvQqDMBjM+7+RpbQ0Ji2NQhwdzGIwCMZFiCAa9STqIPhxw/3A3UeW41w/AKck87w0tqvbngkFgEDCJOPoKc+fovxKzaUGiXkOk0zei1TRzDxYEbHiIw0kzD2Aji5BqHolW9Uv0+9U01AVxivr4r8CjHX7+N27K5WIrP56XsFTAAAAAElFTkSuQmCC"},I={src:e.i(662576).default,width:293,height:215,blurWidth:0,blurHeight:0},C={src:e.i(987202).default,width:1563,height:1563,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA5ElEQVR42h2PPwtBURjGj3wCk93sC1iUCYXFIlGSMjC4QiiTBSE3Ge5M3e0uPoJFBhOTP8NNukXduFL3uJ1Xzz11znCe93me38uitQSL11Pe8rAanKpycbSa5Ar9UiAmJT3QXHGwHGfvj/vJcRzOfz/7fLvsW4tuJFZLehicEIUQpOs6GYZBOIfrcZPp5f0MsXDatk2yLJOqqu6A9f2YjXk7zNCJWM45KYpCmqa5A6/P+ynNGiEGIHSiwjRNsiyLBAmxPezW6U7Gx0ALIHQiFk6I5WEl6G6BB7QAQqc0a4bgxD/uH4FYoVec8m3dAAAAAElFTkSuQmCC"},w={src:e.i(953265).default,width:400,height:400,blurWidth:8,blurHeight:8,blurDataURL:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAAIAAgDAREAAhEBAxEB/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtP9N/tL+PO/8A7ZeV/wDFUj6L917L+r3/AMj/2Q=="},L={src:e.i(346512).default,width:16,height:16,blurWidth:0,blurHeight:0},_={src:e.i(84416).default,width:16,height:16,blurWidth:0,blurHeight:0},T={src:e.i(104602).default,width:16,height:16,blurWidth:0,blurHeight:0},O={src:e.i(888193).default,width:16,height:16,blurWidth:0,blurHeight:0};var y=e.i(336712);let k={src:e.i(447500).default,width:26,height:26,blurWidth:0,blurHeight:0},S={src:e.i(270039).default,width:16,height:16,blurWidth:0,blurHeight:0},R={src:e.i(227733).default,width:16,height:16,blurWidth:0,blurHeight:0},B={src:e.i(823929).default,width:128,height:129,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAApklEQVR42oWPsQrCMBRFY51KaUuwNktBQbcgSenQ32hCTBAHXfSfulUK4g/0/7yvdO+FB5dzXhLC2FoiJE3TfZ7nYrskyzIBVpBjTdPcu677GGPGtm1fmDd1YnVd31gIYSrLUnLOjxC9tfaLfhBCXLz307xQVZUCODvnfljoceAEpskxKeUV1w0Qo1LqobV+Lk8McI5tkDiOeZIkO9SIBr0gRm71l38QASaqNz7VMwAAAABJRU5ErkJggg=="},D={src:e.i(333845).default,width:200,height:200,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAXUlEQVR42p2MoRHAMAwDQwJzCcgCwQEZIDjA03gED2BzewSPWRe2qFcB3Z+kU0o/lXNea4U/0t77OYeIACDq4FLKnSKimYmIqjKzu885U6117z3GCGitxTbg/flJF7DAEmcR3WAqAAAAAElFTkSuQmCC"},M={src:e.i(813878).default,width:16,height:16,blurWidth:0,blurHeight:0},U={src:e.i(767788).default,width:16,height:16,blurWidth:0,blurHeight:0},H={src:e.i(808630).default,width:16,height:16,blurWidth:0,blurHeight:0};var N=e.i(39182);let q={src:e.i(468732).default,width:490,height:412,blurWidth:0,blurHeight:0},P={src:e.i(610503).default,width:16,height:16,blurWidth:0,blurHeight:0},W={src:e.i(438969).default,width:16,height:16,blurWidth:0,blurHeight:0},V={src:e.i(852459).default,width:16,height:16,blurWidth:0,blurHeight:0},G={src:e.i(494696).default,width:16,height:16,blurWidth:0,blurHeight:0},Q={src:e.i(148973).default,width:16,height:16,blurWidth:0,blurHeight:0},z={src:e.i(570036).default,width:16,height:16,blurWidth:0,blurHeight:0},j={src:e.i(151170).default,width:95,height:81,blurWidth:8,blurHeight:7,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAYAAAA1WQxeAAAA0UlEQVR42kXMvWrCUBjG8VxIL6KX0IvobXQSOrQd2kLSdMzQdMmaEErPUqoIIYtKOC5iFD9BEBwiaAY/AgpH/2oUfOGFh4cfj8blNmrNKK0zmFUZzmust2nea7u9IlkNkBMPv1Xgs3JHoXRDe1o+g8Vmyl/vnf++wU/7EdF54jW8JU6K14WTPgE3fjiCZ77kPa2kdAZZlrFcLpikXYLeN6Lxxm/zhfEsRimF5roupmli2zbGh4Gu61iWlX8URWhSSsIwxPM8hBA4jpNn3/cJgoADqC23HJzwo6wAAAAASUVORK5CYII="},F={src:e.i(862330).default,width:646,height:854,blurWidth:0,blurHeight:0};var K=e.i(980385);let Y={src:e.i(788158).default,width:300,height:300,blurWidth:0,blurHeight:0},J={src:e.i(350567).default,width:231,height:30,blurWidth:0,blurHeight:0},X={src:e.i(822797).default,width:48,height:48,blurWidth:0,blurHeight:0},Z={src:e.i(840911).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABE0lEQVR42gEIAff+AAAAAAAAAAAAEQwmIT8ukIAgGUpBBwYQDQQECggAAAAAAAIBBQQJBhUTFw80LUIxloZbR8+5UUS3oUA4kH0HBxEOACMUUkolFlVNCAYTERwUPzgkHFJIIhxNRCsmYVQODSAbADYffnNFKaCSDgkgHD0tjX4+MI5+CQgVEhQSLCULChgUABAKJiJTM7+vJhlYTzEkb2MxJm9iIh1NQywnZFYhH0o/AA8JIh9RMrurNiR9cQkHFhMQDSUgUkW5o1hOx60pJlxPAAcEDw4qGmJYFw80LhENKCMyKHFjUEK0nhEOJSADAwYFAAAAAAADAgcGBQMLCRUPMClCNJeEIRtLQgAAAQAAAAAAfjQxsiCQipMAAAAASUVORK5CYII="},$={src:e.i(445735).default,width:16,height:16,blurWidth:0,blurHeight:0},ee={src:e.i(635202).default,width:16,height:16,blurWidth:0,blurHeight:0},et={src:e.i(669161).default,width:320,height:320,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7UlEQVR42lVQvc7BYBR+B/kM3w+fFm2p9m3fRhFRP7UQlTAQCVfAgE3EHZAQMTBIzBIrYbEgFhaza3ABrsF7bIYnOTl5/s5BVrvIY5MMvYTbUuy8hN8CcFIdW62CgHCKjFwie/So3PqH+b0Hc+GebkW6Lj9zUtJaHwEbFvGqWf7zOG5GJVmjcwUEAUOevQmhfKSTqJol+7f94RT+L7Yv25OV3PtsI699EByc85qpW5qcUCaMyB7orH9EgJLaTnPNgk/QfUsxKi0QtKWFzjRzA7a08IEPCivYKWkyQHAKtJUMPIVMQCAmz3FKHcELXnxEPy9E1lYCAAAAAElFTkSuQmCC"},ei={src:e.i(159508).default,width:52,height:46,blurWidth:0,blurHeight:0},ea={src:e.i(544025).default,width:3300,height:2550,blurWidth:8,blurHeight:6,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAAZklEQVR42oWNTQ5AMBhE3f8mEhux4BgiIRzAwoKWplrt146fBbVhkpnNvORF+El0jvMAV4RR2qtsJZD3DyA2h6xhiMsRSTUhrRm0DYBFE4qOI285yl5CGvdW0OEYhEE/G6jgvIGv7A4KupBwIVaNAAAAAElFTkSuQmCC"},es={src:e.i(708767).default,width:760,height:277,blurWidth:0,blurHeight:0},el={src:e.i(100588).default,width:146,height:139,blurWidth:0,blurHeight:0};e.s(["default",0,el],247044);let er={src:e.i(183804).default,width:100,height:18,blurWidth:0,blurHeight:0},en={src:e.i(865502).default,width:32,height:32,blurWidth:0,blurHeight:0},eo={src:e.i(96912).default,width:16,height:16,blurWidth:0,blurHeight:0},eA={src:e.i(395073).default,width:16,height:16,blurWidth:0,blurHeight:0},eu={src:e.i(407829).default,width:16,height:16,blurWidth:0,blurHeight:0},ed={src:e.i(846077).default,width:64,height:64,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAo0lEQVR42lWOvQrCQBCE7718oUA6wVcQBF/AXhu1CIgcpgoi/qCNguBPwCaChYHDv9zt3e6ZeEFxq9n5GGaY/T8iq3QhWKFRkZGWzEPaaE/RDoiI5e7z0BILP7tMB2vyO3p2BJew8syvvJLGQTPEaheSVJeAQIi5F2+CWt80uHopLMEnNBpPuNc2vaXK+38A4RauTvUhbBNwDvsOlYD3DA2Se99kLK7hC5QFVQAAAABJRU5ErkJggg=="},ec={src:e.i(914861).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7ElEQVR42l2LMUsCAQBG39GFFQ02ad1oq0QIRR2hER4EGdQqdBDdQZAFEudU0NZSQ0O1VUOjiuJvEBxc3BQFEVQQdFAU9OROFwf9lg/e48Hiti8vWJekBSoIODacLK04CP79IAX8815cW2X3IYL3JIhaKuKLGdNGmMUCTo+Hq1yO72yB6HDEeTrFjm8fUVwGt3uL00eD5+6AfMvixbS5bTR5/43jcm2CooT4KNf56ltUGzafA5uoZZGpdJDlABhPr7z1TJLtMbXamMT0702T//aQu0gM5GOFvRuNkKoTDuucqRpeXePoWuPg0D8BGkpJjYhKXN4AAAAASUVORK5CYII="},eh={src:e.i(285328).default,width:400,height:399,blurWidth:8,blurHeight:8,blurDataURL:"data:image/webp;base64,UklGRgwBAABXRUJQVlA4TAABAAAvB8ABEM1VICICHggIDgIAAIDzDAACD0FoAAARAAwAAAAAAAAAAAAAAACAAABAAcBCAoAWgGyoXwUAAA8E7QQCAADg/N+nrsYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4CClZXkg5AQAAAAA538LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL0HIgEAAAAAcP4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMsHA39Qutr2AtkROu8CASWZ/nMlNyzz5AdgWmkK65oUI6AlgIkY/M3zxIW3iABq15KT/Uz7BXidCOONHieAz1v6HqAC"},eg={src:e.i(779278).default,width:16,height:16,blurWidth:0,blurHeight:0},ep={src:e.i(325532).default,width:1e3,height:1e3,blurWidth:0,blurHeight:0},eb={src:e.i(288330).default,width:16,height:16,blurWidth:0,blurHeight:0};var em=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cognition="Cognition",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="Hosted vLLM",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.NVIDIA_RIVA="Nvidia Riva",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.SCX_AI="SCX.ai",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Local vLLM",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let ev={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cognition:"cognition",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",NVIDIA_RIVA:"nvidia_riva",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",SCX_AI:"scx-ai",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},ef=new Set(["bedrock_mantle"]),ex={"A2A Agent":n.src,Ai21:o.src,"Ai21 Chat":o.src,"AI/ML API":A.src,"Aiohttp Openai":K.default.src,Anthropic:u.src,"Anthropic Text":u.src,AssemblyAI:d.src,Azure:N.default.src,"Azure AI Foundry (Studio)":N.default.src,"Azure Text":N.default.src,Baseten:c.src,"Amazon Bedrock":h.default.src,"Amazon Bedrock Mantle":h.default.src,"AWS SageMaker":h.default.src,Cerebras:g.src,Cloudflare:p.src,Codestral:P.src,Cohere:b.src,"Cohere Chat":b.src,Cometapi:m.src,Cursor:v.src,"Databricks (Qwen API)":f.src,Dashscope:Z.src,Deepseek:I.src,Deepgram:x.src,DeepInfra:E.src,ElevenLabs:C.src,"Fal AI":w.src,"Featherless Ai":L.src,"Fireworks AI":_.src,Friendliai:T.src,"Github Copilot":O.src,"Google AI Studio":y.default.src,Groq:k.src,"Hosted vLLM":ed.src,Huggingface:S.src,Hyperbolic:R.src,Infinity:B.src,"Jina AI":D.src,"Lambda Ai":M.src,"Lm Studio":U.src,"Meta Llama":H.src,MiniMax:q.src,"Mistral AI":P.src,Moonshot:W.src,Morph:V.src,Nebius:G.src,Novita:Q.src,"Nvidia Nim":z.src,"Nvidia Riva":z.src,Ollama:F.src,"Ollama Chat":F.src,Oobabooga:K.default.src,OpenAI:K.default.src,"Openai Like":K.default.src,"OpenAI Text Completion":K.default.src,"OpenAI-Compatible Completions (legacy /v1/completions)":K.default.src,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":K.default.src,Openrouter:Y.src,"Oracle Cloud Infrastructure (OCI)":J.src,Perplexity:X.src,Recraft:$.src,Replicate:ee.src,RunwayML:et.src,Sagemaker:h.default.src,Sambanova:ei.src,"SAP Generative AI Hub":ea.src,"SCX.ai":es.src,Snowflake:el.src,Soniox:er.src,"Text-Completion-Codestral":P.src,TogetherAI:en.src,Topaz:eo.src,Triton:j.src,V0:eA.src,"Vercel Ai Gateway":eu.src,"Vertex AI (Anthropic, Gemini, etc.)":y.default.src,"Vertex Ai Beta":y.default.src,"Local vLLM":ed.src,VolcEngine:ec.src,"Voyage AI":eh.src,Watsonx:eg.src,"Watsonx Text":eg.src,xAI:ep.src,Xinference:eb.src},eE={"AI/ML API":"aiml/flux-pro/v1.1",Anthropic:"claude-3-opus",Azure:"my-deployment","Azure AI Foundry (Studio)":"azure_ai/command-r-plus","Amazon Bedrock":"claude-3-opus",Cognition:"cognition/swe-1.7",Cursor:"cursor/claude-4-sonnet",DeepInfra:"deepinfra/","Fal AI":"fal_ai/fal-ai/flux-pro/v1.1-ultra","Google AI Studio":"gemini-pro","Jina AI":"jina_ai/","Nvidia Riva":"nvidia_riva/nvidia/parakeet-ctc-1_1b-asr","Oracle Cloud Infrastructure (OCI)":"oci/xai.grok-4",RunwayML:"runwayml/gen4_turbo","AWS SageMaker":"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b","SCX.ai":"scx-ai/GLM-5.2",Snowflake:"snowflake/mistral-7b","Vertex AI (Anthropic, Gemini, etc.)":"gemini-pro",VolcEngine:"volcengine/","Voyage AI":"voyage/",Watsonx:"watsonx/ibm/granite-3-3-8b-instruct","Z.AI (Zhipu AI)":"zai/glm-4.5"};e.s(["Providers",()=>em,"getPlaceholder",0,e=>eE[em[e]??e]??"gpt-3.5-turbo","getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:r(ex[e])??"",displayName:e}}let t=Object.keys(ev).find(t=>ev[t].toLowerCase()===e.toLowerCase())??Object.keys(ev).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let i=em[t];return{logo:r(ex[i])??"",displayName:i}},"getProviderModels",0,(e,t)=>{let i=ev[e],a=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let s=t.litellm_provider,l="string"==typeof s&&(s.startsWith(`${i}_`)||s.startsWith(`${i}-`));(s===i||l&&!ef.has(s))&&a.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&a.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&a.push(e)})),a},"providerLogoMap",0,ex,"provider_map",0,ev],916925)},174553,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(916925),s=e.i(555987),l=e.i(196631);let r=/(?:\/assets\/logos\/|\/_next\/static\/media\/)/,n={"baseten.svg":"invert","cursor.svg":"invert","enkrypt_ai.avif":"invert","friendli.svg":"invert","github.svg":"invert","github_copilot.svg":"invert","lago.svg":"invert","lambda.svg":"invert","langflow.svg":"invert","lmstudio.svg":"invert","moonshot.svg":"invert","nebius.svg":"invert","notion.svg":"invert","ollama.svg":"invert","openrouter.svg":"invert","promptguard.svg":"invert","recraft.svg":"invert","replicate.svg":"invert","runway.png":"invert","scx_ai.svg":"invert","secret_detect.png":"invert","topaz.svg":"invert","v0.svg":"invert","vercel.svg":"invert","watsonx.svg":"invert","aiml_api.svg":"plate","akto.svg":"plate","aws.svg":"plate","deepkeep.svg":"plate","fireworks.svg":"plate","llm_guard.png":"plate","pangea.png":"plate","repelloai.png":"plate","sambanova.svg":"plate","sentry.svg":"plate","valkey.svg":"plate"},o={invert:"dark:[filter:brightness(0)_invert(1)]",plate:"dark:bg-logo-surface dark:object-contain dark:p-0.5"};e.s(["Logo",0,({provider:e,src:A,label:u,className:d="w-4 h-4"})=>{let[c,h]=(0,i.useState)(null),g=void 0!==e?(0,a.getProviderLogoAndName)(e).logo:(0,s.resolveLogoSrc)(A)??"",p=u??e??"";if(c===g||!g)return(0,t.jsx)("div",{className:`${d} rounded-full bg-border flex items-center justify-center text-xs`,children:p.charAt(0)||"-"});let b=(e=>{let t;if(!e||(0,s.isExternalAssetSrc)(e)||!r.test(e))return;let i=e.split(/[?#]/)[0].split("/").pop()||void 0,a=void 0===i||(t=i.split(".")).length<2?void 0:`${t[0]}.${t[t.length-1]}`;return void 0===a?void 0:n[a]})(g);return(0,t.jsx)("img",{src:g,alt:`${p||"-"} logo`,className:void 0===b?d:(0,l.cn)(d,o[b]),onError:()=>{console.warn(`Logo failed to load: ${g}`),h(g)}})}],174553)},286536,e=>{"use strict";let t=(0,e.i(475254).default)("eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Eye",0,t],286536)},77705,e=>{"use strict";let t=(0,e.i(475254).default)("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["EyeOff",0,t],77705)},101048,e=>{"use strict";var t=e.i(123287);e.s(["CircleCheck",()=>t.default])},223622,e=>{"use strict";let t=(0,e.i(475254).default)("ban",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m4.9 4.9 14.2 14.2",key:"1m5liu"}]]);e.s(["Ban",0,t],223622)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/028hvx-avwx8g.js b/litellm/proxy/_experimental/out/_next/static/chunks/028hvx-avwx8g.js
new file mode 100644
index 00000000000..9adc0a9f075
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/028hvx-avwx8g.js
@@ -0,0 +1 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,788699,360200,e=>{"use strict";let t=(0,e.i(475254).default)("pencil",[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]]);e.s(["default",0,t],360200),e.s(["Pencil",0,t],788699)},541071,373488,e=>{"use strict";let t=(0,e.i(475254).default)("ellipsis",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]]);e.s(["default",0,t],373488),e.s(["MoreHorizontal",0,t],541071)},332102,e=>{"use strict";let t=(0,e.i(475254).default)("inbox",[["polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12",key:"o97t9d"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}]]);e.s(["Inbox",0,t],332102)},450240,e=>{"use strict";var t=e.i(843476),r=e.i(286536),s=e.i(77705),a=e.i(271645),i=e.i(950594);let l=a.forwardRef(({className:e,groupClassName:l,disabled:o,...n},c)=>{let[u,d]=a.useState(!1);return(0,t.jsxs)(i.InputGroup,{className:l,children:[(0,t.jsx)(i.InputGroupInput,{...n,ref:c,type:u?"text":"password",disabled:o,className:e}),(0,t.jsx)(i.InputGroupAddon,{align:"inline-end",children:(0,t.jsx)(i.InputGroupButton,{size:"icon-xs",disabled:o,"aria-label":u?"Hide password":"Show password",onClick:()=>d(e=>!e),children:u?(0,t.jsx)(s.EyeOff,{}):(0,t.jsx)(r.Eye,{})})})]})});l.displayName="PasswordInput",e.s(["PasswordInput",0,l])},868499,e=>{"use strict";var t=e.i(843476);e.s([],558762),e.i(558762);var r=e.i(366250),s=e.i(402820),a=e.i(156736),i=e.i(209793),l=e.i(784324),o=e.i(264951),n=e.i(77173);let c=e.i(313488).DialogTrigger;var u=e.i(974217),d=e.i(325326),f=e.i(301807);let p={modal:!0,disablePointerDismissal:!0,role:"alertdialog"};class h extends d.DialogHandle{constructor(e){super(e??new f.DialogStore(p)),e&&this.store.update(p)}}e.s(["Backdrop",()=>s.DialogBackdrop,"Close",()=>a.DialogClose,"Description",()=>i.DialogDescription,"Handle",0,h,"Popup",()=>l.DialogPopup,"Portal",()=>o.DialogPortal,"Root",0,function(e){return(0,r.useRenderDialogRoot)(e,"alert-dialog")},"Title",()=>n.DialogTitle,"Trigger",0,c,"Viewport",()=>u.DialogViewport,"createHandle",0,function(){return new h}],734604);var m=e.i(734604),m=m,g=e.i(196631),x=e.i(519455);function y({...e}){return(0,t.jsx)(m.Portal,{"data-slot":"alert-dialog-portal",...e})}function b({className:e,...r}){return(0,t.jsx)(m.Backdrop,{"data-slot":"alert-dialog-overlay",className:(0,g.cn)("fixed inset-0 isolate z-popup bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",e),...r})}e.s(["AlertDialog",0,function({...e}){return(0,t.jsx)(m.Root,{"data-slot":"alert-dialog",...e})},"AlertDialogAction",0,function({className:e,variant:r="default",size:s="default",...a}){return(0,t.jsx)(m.Close,{"data-slot":"alert-dialog-action",className:(0,g.cn)(e),render:(0,t.jsx)(x.Button,{variant:r,size:s}),...a})},"AlertDialogCancel",0,function({className:e,variant:r="outline",size:s="default",...a}){return(0,t.jsx)(m.Close,{"data-slot":"alert-dialog-cancel",className:(0,g.cn)(e),render:(0,t.jsx)(x.Button,{variant:r,size:s}),...a})},"AlertDialogContent",0,function({className:e,size:r="default",...s}){return(0,t.jsxs)(y,{children:[(0,t.jsx)(b,{}),(0,t.jsx)(m.Popup,{"data-slot":"alert-dialog-content","data-size":r,className:(0,g.cn)("group/alert-dialog-content fixed top-1/2 left-1/2 z-popup grid w-full -translate-x-1/2 -translate-y-1/2 gap-6 rounded-xl bg-popover p-6 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",e),...s})]})},"AlertDialogDescription",0,function({className:e,...r}){return(0,t.jsx)(m.Description,{"data-slot":"alert-dialog-description",className:(0,g.cn)("text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",e),...r})},"AlertDialogFooter",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"alert-dialog-footer",className:(0,g.cn)("flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",e),...r})},"AlertDialogHeader",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"alert-dialog-header",className:(0,g.cn)("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",e),...r})},"AlertDialogTitle",0,function({className:e,...r}){return(0,t.jsx)(m.Title,{"data-slot":"alert-dialog-title",className:(0,g.cn)("text-lg font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",e),...r})},"AlertDialogTrigger",0,function({...e}){return(0,t.jsx)(m.Trigger,{"data-slot":"alert-dialog-trigger",...e})}],868499)},768371,e=>{"use strict";let t,r;var s=e.i(247167);let a=/\{[^{}]+\}/g;function i(e,t,r){if(null==t)return"";if("object"==typeof t)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${e}=${r?.allowReserved===!0?t:encodeURIComponent(t)}`}function l(e,t,r){if(!t||"object"!=typeof t)return"";let s=[],a={simple:",",label:".",matrix:";"}[r.style]||"&";if("deepObject"!==r.style&&!1===r.explode){for(let e in t)s.push(e,!0===r.allowReserved?t[e]:encodeURIComponent(t[e]));let a=s.join(",");switch(r.style){case"form":return`${e}=${a}`;case"label":return`.${a}`;case"matrix":return`;${e}=${a}`;default:return a}}for(let a in t){let l="deepObject"===r.style?`${e}[${a}]`:a;s.push(i(l,t[a],r))}let l=s.join(a);return"label"===r.style||"matrix"===r.style?`${a}${l}`:l}function o(e,t,r){if(!Array.isArray(t))return"";if(!1===r.explode){let s={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[r.style]||",",a=(!0===r.allowReserved?t:t.map(e=>encodeURIComponent(e))).join(s);switch(r.style){case"simple":return a;case"label":return`.${a}`;case"matrix":return`;${e}=${a}`;default:return`${e}=${a}`}}let s={simple:",",label:".",matrix:";"}[r.style]||"&",a=[];for(let s of t)"simple"===r.style||"label"===r.style?a.push(!0===r.allowReserved?s:encodeURIComponent(s)):a.push(i(e,s,r));return"label"===r.style||"matrix"===r.style?`${s}${a.join(s)}`:a.join(s)}function n(e){return function(t){let r=[];if(t&&"object"==typeof t)for(let s in t){let a=t[s];if(null!=a){if(Array.isArray(a)){if(0===a.length)continue;r.push(o(s,a,{style:"form",explode:!0,...e?.array,allowReserved:e?.allowReserved||!1}));continue}if("object"==typeof a){r.push(l(s,a,{style:"deepObject",explode:!0,...e?.object,allowReserved:e?.allowReserved||!1}));continue}r.push(i(s,a,e))}}return r.join("&")}}function c(e,t){let r=e;for(let s of e.match(a)??[]){let e=s.substring(1,s.length-1),a=!1,n="simple";if(e.endsWith("*")&&(a=!0,e=e.substring(0,e.length-1)),e.startsWith(".")?(n="label",e=e.substring(1)):e.startsWith(";")&&(n="matrix",e=e.substring(1)),!t||void 0===t[e]||null===t[e])continue;let c=t[e];if(Array.isArray(c)){r=r.replace(s,o(e,c,{style:n,explode:a}));continue}if("object"==typeof c){r=r.replace(s,l(e,c,{style:n,explode:a}));continue}if("matrix"===n){r=r.replace(s,`;${i(e,c)}`);continue}r=r.replace(s,"label"===n?`.${encodeURIComponent(c)}`:encodeURIComponent(c))}return r}function u(e,t){return e instanceof FormData?e:t&&"application/x-www-form-urlencoded"===(t.get instanceof Function?t.get("Content-Type")??t.get("content-type"):t["Content-Type"]??t["content-type"])?new URLSearchParams(e).toString():JSON.stringify(e)}function d(...e){let t=new Headers;for(let r of e)if(r&&"object"==typeof r)for(let[e,s]of r instanceof Headers?r.entries():Object.entries(r))if(null===s)t.delete(e);else if(Array.isArray(s))for(let r of s)t.append(e,r);else void 0!==s&&t.set(e,s);return t}function f(e){return e.endsWith("/")?e.substring(0,e.length-1):e}var p=e.i(954616),h=e.i(621482),m=e.i(869230),g=e.i(469637),x=e.i(254440),y=e.i(266027),b=e.i(431703),v=e.i(97198),_=e.i(950643);let w=function(e){let{baseUrl:t="",Request:r=globalThis.Request,fetch:a=globalThis.fetch,querySerializer:i,bodySerializer:l,pathSerializer:o,headers:p,requestInitExt:h,...m}={...e};h="object"==typeof s.default&&Number.parseInt(s.default?.versions?.node?.substring(0,2))>=18&&s.default.versions.undici?h:void 0,t=f(t);let g=[];async function x(e,s){var x,y;let b,v,_,w,j,{baseUrl:k,fetch:A=a,Request:T=r,headers:E,params:N={},parseAs:O="json",querySerializer:S,bodySerializer:C=l??u,pathSerializer:I,body:R,middleware:P=[],...z}=s||{},U=t;k&&(U=f(k)??t);let q="function"==typeof i?i:n(i);S&&(q="function"==typeof S?S:n({..."object"==typeof i?i:{},...S}));let H=I||o||c,D=void 0===R?void 0:C(R,d(p,E,N.header)),M=d(void 0===D||D instanceof FormData?{}:{"Content-Type":"application/json"},p,E,N.header),L=[...g,...P],$={redirect:"follow",...m,...z,body:D,headers:M},B=new T((x=e,y={baseUrl:U,params:N,querySerializer:q,pathSerializer:H},b=`${y.baseUrl}${x}`,y.params?.path&&(b=y.pathSerializer(b,y.params.path)),(v=y.querySerializer(y.params.query??{})).startsWith("?")&&(v=v.substring(1)),v&&(b+=`?${v}`),b),$);for(let e in z)e in B||(B[e]=z[e]);if(L.length){for(let t of(_=Math.random().toString(36).slice(2,11),w=Object.freeze({baseUrl:U,fetch:A,parseAs:O,querySerializer:q,bodySerializer:C,pathSerializer:H}),L))if(t&&"object"==typeof t&&"function"==typeof t.onRequest){let r=await t.onRequest({request:B,schemaPath:e,params:N,options:w,id:_});if(r)if(r instanceof T)B=r;else if(r instanceof Response){j=r;break}else throw Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!j){try{j=await A(B,h)}catch(r){let t=r;if(L.length)for(let r=L.length-1;r>=0;r--){let s=L[r];if(s&&"object"==typeof s&&"function"==typeof s.onError){let r=await s.onError({request:B,error:t,schemaPath:e,params:N,options:w,id:_});if(r){if(r instanceof Response){t=void 0,j=r;break}if(r instanceof Error){t=r;continue}throw Error("onError: must return new Response() or instance of Error")}}}if(t)throw t}if(L.length)for(let t=L.length-1;t>=0;t--){let r=L[t];if(r&&"object"==typeof r&&"function"==typeof r.onResponse){let t=await r.onResponse({request:B,response:j,schemaPath:e,params:N,options:w,id:_});if(t){if(!(t instanceof Response))throw Error("onResponse: must return new Response() when modifying the response");j=t}}}}let G=j.headers.get("Content-Length");if(204===j.status||"HEAD"===B.method||"0"===G&&!j.headers.get("Transfer-Encoding")?.includes("chunked"))return j.ok?{data:void 0,response:j}:{error:void 0,response:j};if(j.ok){let e=async()=>{if("stream"===O)return j.body;if("json"===O&&!G){let e=await j.text();return e?JSON.parse(e):void 0}return await j[O]()};return{data:await e(),response:j}}let K=await j.text();try{K=JSON.parse(K)}catch{}return{error:K,response:j}}return{request:(e,t,r)=>x(t,{...r,method:e.toUpperCase()}),GET:(e,t)=>x(e,{...t,method:"GET"}),PUT:(e,t)=>x(e,{...t,method:"PUT"}),POST:(e,t)=>x(e,{...t,method:"POST"}),DELETE:(e,t)=>x(e,{...t,method:"DELETE"}),OPTIONS:(e,t)=>x(e,{...t,method:"OPTIONS"}),HEAD:(e,t)=>x(e,{...t,method:"HEAD"}),PATCH:(e,t)=>x(e,{...t,method:"PATCH"}),TRACE:(e,t)=>x(e,{...t,method:"TRACE"}),use(...e){for(let t of e)if(t){if("object"!=typeof t||!("onRequest"in t||"onResponse"in t||"onError"in t))throw Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");g.push(t)}},eject(...e){for(let t of e){let e=g.indexOf(t);-1!==e&&g.splice(e,1)}}}}({Request:function(e,t){return new globalThis.Request((0,_.resolveRequestUrl)(e,{registeredBase:(0,v.getRequestBaseUrl)(),pageOrigin:globalThis.location?.origin}),t)},fetch:e=>globalThis.fetch(e)});w.use({onRequest({request:e}){let t=(0,v.getAuthToken)();t&&e.headers.set((0,v.getAuthHeaderName)(),`Bearer ${t}`)},async onResponse({response:e}){let t;if(e.ok)return e;let r=await e.clone().text(),s=r;try{s=JSON.parse(r),t=(0,b.deriveErrorMessage)(s)}catch{t=r||`HTTP ${e.status}`}throw(0,v.reportError)(t),new b.ApiError(t,e.status,s)}});let j=(t=async({queryKey:[e,t,r],signal:s})=>{let a=w[e.toUpperCase()],{data:i,error:l,response:o}=await a(t,{signal:s,...r});if(l)throw l;return 204===o.status||"0"===o.headers.get("Content-Length")?i??null:i},{queryOptions:r=(e,r,...[s,a])=>({queryKey:void 0===s?[e,r]:[e,r,s],queryFn:t,...a}),useQuery:(e,t,...[s,a,i])=>(0,y.useQuery)(r(e,t,s,a),i),useSuspenseQuery:(e,t,...[s,a,i])=>{var l;return l=r(e,t,s,a),(0,g.useBaseQuery)({...l,enabled:!0,suspense:!0,throwOnError:x.defaultThrowOnError,placeholderData:void 0},m.QueryObserver,i)},useInfiniteQuery:(e,t,s,a,i)=>{let{pageParamName:l="cursor",...o}=a,{queryKey:n}=r(e,t,s);return(0,h.useInfiniteQuery)({queryKey:n,queryFn:async({queryKey:[e,t,r],pageParam:s=0,signal:a})=>{let i=w[e.toUpperCase()],o={...r,signal:a,params:{...r?.params||{},query:{...r?.params?.query,[l]:s}}},{data:n,error:c}=await i(t,o);if(c)throw c;return n},...o},i)},useMutation:(e,t,r,s)=>(0,p.useMutation)({mutationKey:[e,t],mutationFn:async r=>{let s=w[e.toUpperCase()],{data:a,error:i}=await s(t,r);if(i)throw i;return a},...r},s)});e.s(["$api",0,j,"fetchClient",0,w],768371)},118366,e=>{"use strict";var t=e.i(991124);e.s(["CopyIcon",()=>t.default])},541202,e=>{"use strict";var t=e.i(843476),r=e.i(271645),s=e.i(522016),a=e.i(952571),i=e.i(37727);e.s(["DeprecationBanner",0,({featureName:e})=>{let[l,o]=(0,r.useState)(!1);return l?null:(0,t.jsxs)("div",{role:"alert",className:"mb-4 flex items-start gap-3 rounded-lg border border-border bg-muted/50 px-4 py-3 text-sm",children:[(0,t.jsx)(a.Info,{className:"mt-0.5 size-4 shrink-0 text-muted-foreground"}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("p",{className:"font-medium",children:`${e} is on a draft deprecation list`}),(0,t.jsxs)("p",{className:"mt-1 break-words text-muted-foreground",children:[`${e} is one of several experimental features we're considering removing, potentially as early as September 1, 2026. This list is a draft and is not final. If you rely on this feature, please share feedback on the `,(0,t.jsx)(s.default,{href:"https://github.com/BerriAI/litellm/discussions/32090",target:"_blank",rel:"noopener noreferrer",className:"underline underline-offset-4",children:"deprecation discussion"}),"."]})]}),(0,t.jsx)("button",{type:"button","aria-label":"Close",onClick:()=>o(!0),className:"shrink-0 rounded-md p-0.5 text-muted-foreground transition-colors hover:text-foreground",children:(0,t.jsx)(i.X,{className:"size-4"})})]})}])},306228,e=>{"use strict";let t=(0,e.i(475254).default)("link-2",[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",key:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]]);e.s(["Link2",0,t],306228)},990681,e=>{e.q("/litellm-asset-prefix/_next/static/media/postgresql.0a2k5oak2hvw5.svg")},292335,122520,165615,779129,280024,e=>{"use strict";let t={NONE:"none",API_KEY:"api_key",BEARER_TOKEN:"bearer_token",TOKEN:"token",BASIC:"basic",OAUTH2:"oauth2",OAUTH2_TOKEN_EXCHANGE:"oauth2_token_exchange",OAUTH2_ID_JAG:"oauth2_id_jag",AWS_SIGV4:"aws_sigv4",TRUE_PASSTHROUGH:"true_passthrough",OAUTH_DELEGATE:"oauth_delegate"},r=[{value:t.NONE,label:"None"},{value:t.API_KEY,label:"API Key"},{value:t.BEARER_TOKEN,label:"Bearer Token"},{value:t.TOKEN,label:"Token"},{value:t.BASIC,label:"Basic Auth"},{value:t.OAUTH2,label:"OAuth"},{value:t.OAUTH2_TOKEN_EXCHANGE,label:"OAuth Token Exchange (OBO)"},{value:t.OAUTH2_ID_JAG,label:"ID-JAG (Okta Cross App Access)"},{value:t.AWS_SIGV4,label:"AWS SigV4 (Bedrock AgentCore MCPs)"},{value:t.TRUE_PASSTHROUGH,label:"True Passthrough (no LiteLLM auth)"},{value:t.OAUTH_DELEGATE,label:"OAuth Delegate (client-supplied upstream token)"}],s=e=>e===t.TRUE_PASSTHROUGH||e===t.OAUTH_DELEGATE,a={INTERACTIVE:"interactive",M2M:"m2m"},i=e=>{let t=e.credentials??{};return JSON.stringify({url:"string"==typeof e.url?e.url:null,spec_path:"string"==typeof e.spec_path?e.spec_path:null,auth_type:e.auth_type??null,oauth_flow_type:e.oauth_flow_type??null,client_id:t.client_id??null,client_secret:t.client_secret??null,scopes:t.scopes??null,upstream_resource:t.upstream_resource??null,issuer:e.issuer??null,authorization_url:e.authorization_url??null,token_url:e.token_url??null,registration_url:e.registration_url??null})},l=["client_id","client_secret"],o=["upstream_resource","upstream_token_header"],n=["access_token","refresh_token","expires_in","scope"],c=(e,t)=>{if(!e)return;let r=Object.fromEntries(t.filter(t=>"string"==typeof e[t]&&""!==e[t]).map(t=>[t,e[t]]));return Object.keys(r).length>0?r:void 0},u="client_credentials",d={SSE:"sse",HTTP:"http",STDIO:"stdio",OPENAPI:"openapi"},f=[{value:d.HTTP,label:"Streamable HTTP (Recommended)"},{value:d.SSE,label:"Server-Sent Events (SSE)"},{value:d.STDIO,label:"Standard Input/Output (stdio)"},{value:d.OPENAPI,label:"OpenAPI Spec"}];e.s(["ADMIN_CONFIG_CREDENTIAL_KEYS",0,o,"AUTH_TYPE",0,t,"AUTH_TYPE_ITEMS",0,r,"CLEARED_ON_INVALIDATION",0,["credentials"],"MCP_OAUTH2_FLOW_INTERACTIVE",0,"authorization_code","MCP_OAUTH2_FLOW_M2M",0,u,"OAUTH_FLOW",0,a,"TRANSPORT",0,d,"TRANSPORT_ITEMS",0,f,"credentialAuthClass",0,e=>e===t.TRUE_PASSTHROUGH||e===t.OAUTH_DELEGATE?"client_forwarded":e??null,"gatewayMintsClientFor",0,e=>e.auth_type===t.TRUE_PASSTHROUGH||e.auth_type===t.OAUTH_DELEGATE&&!e.dcr_bridge,"getMcpOAuthMode",0,function(e){return e.auth_type===t.OAUTH2_TOKEN_EXCHANGE?"token_exchange":e.auth_type!==t.OAUTH2?null:e.oauth2_flow===u?"m2m":e.delegate_auth_to_upstream?"passthrough":"authorization_code"},"getOAuthAuthorizationIdentity",0,i,"handleAuth",0,e=>null==e?t.NONE:e,"handleTransport",0,(e,t)=>null==e?d.SSE:t&&e!==d.STDIO?d.OPENAPI:e,"isClientForwardedTokenMode",0,s,"isHeldOAuthTokenStale",0,(e,t)=>void 0!==t&&i(e)!==t,"isUnsupportedOnGatewayConnect",0,e=>s(e)||e===t.OAUTH2_TOKEN_EXCHANGE,"oauth2FlowToFormValue",0,function(e){return e===u?a.M2M:e?a.INTERACTIVE:void 0},"preservedAdminCredentials",0,e=>c(e,[...l,...o]),"preservedDeclaredAppCredentials",0,e=>c(e,l),"withoutMintedTokenCredentials",0,e=>{if(!e)return;let t=Object.fromEntries(Object.entries(e).filter(([e])=>!n.includes(e)));return Object.keys(t).length>0?t:void 0}],292335);var p=e.i(271645),h=e.i(602869),m=e.i(417385);function g(e){if(e instanceof Error)return e.message;if(e&&"object"==typeof e){let t=e.detail;return"string"==typeof t?t:Array.isArray(t)?t.map(e=>e&&"object"==typeof e?"string"==typeof e.msg?e.msg:JSON.stringify(e):String(e)).join("; "):t&&"object"==typeof t&&"string"==typeof t.error?t.error:"string"==typeof e.message?e.message:JSON.stringify(e)}return String(e)}e.s(["extractErrorMessage",0,g],122520);let x=e=>{let t=new Uint8Array(e),r="";return t.forEach(e=>r+=String.fromCharCode(e)),btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},y=()=>{let e=new Uint8Array(32);return window.crypto.getRandomValues(e),x(e.buffer)},b=async e=>{let t=new TextEncoder().encode(e);return x(await window.crypto.subtle.digest("SHA-256",t))};e.s(["generateCodeChallenge",0,b,"generateCodeVerifier",0,y],165615);var v=e.i(434166);let _=()=>{{let e=window.location.pathname||"",t=e.indexOf("/ui"),r=t>=0?e.slice(0,t+3).replace(/\/+$/,""):"";return`${window.location.origin}${r}/mcp/oauth/callback`}},w=(...e)=>{e.forEach(e=>{try{window.sessionStorage.removeItem(e)}catch(e){}})};e.s(["TOOLS_OAUTH_UI_STATE_KEY",0,"litellm-mcp-oauth-tools-state","buildCallbackUrl",0,_,"clearStorage",0,w],779129);let j="litellm-user-mcp-oauth-flow-state",k="litellm-user-mcp-oauth-result",A=(e,t)=>{(0,v.setSecureItem)(e,t)},T=e=>(0,v.getSecureItem)(e);e.s(["useUserMcpOAuthFlow",0,({accessToken:e,serverId:t,serverAlias:r,scopes:s,clientId:a,onSuccess:i})=>{let[l,o]=(0,p.useState)("idle"),[n,c]=(0,p.useState)(null),u=(0,p.useRef)(!1),d=(0,p.useCallback)(async()=>{try{let i;o("authorizing"),c(null);let l=a??void 0;if(!l)try{let s=await (0,h.registerMcpOAuthClient)(e,t,{client_name:r||t,grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"});l=s?.client_id,i=s?.client_secret}catch(e){}let n=y(),u=await b(n),d=crypto.randomUUID(),f=_(),p=s?.filter(e=>e.trim()).join(" "),m=(0,h.buildMcpOAuthAuthorizeUrl)({serverId:t,clientId:l,redirectUri:f,state:d,codeChallenge:u,scope:p}),g={state:d,codeVerifier:n,serverId:t,redirectUri:f,clientId:l,clientSecret:i,scopes:s};A(j,JSON.stringify(g));let x=new URL(window.location.href);x.searchParams.set("mcpOauthReturn","apps"),A("litellm-mcp-oauth-return-url",x.toString()),window.location.href=m}catch(t){let e=g(t);c(e),o("error"),m.toast.error(e)}},[e,t,r,s,a]),f=(0,p.useCallback)(async()=>{if(u.current)return;let r=T(k);if(!r)return;let s=T(j);if(!s)return;try{let e=JSON.parse(s);if(e.serverId&&e.serverId!==t)return}catch(e){}u.current=!0,w(k);let a=null,l=null;try{a=JSON.parse(r);let e=T(j);l=e?JSON.parse(e):null}catch(e){c("Failed to resume OAuth flow. Please retry."),o("error"),u.current=!1,w(j);return}try{if(!l?.state||!l.codeVerifier||!l.serverId)throw Error("OAuth session state was lost. Please retry.");if(!a?.state||a.state!==l.state)throw Error("OAuth state mismatch. Please retry.");if(a.error)throw Error(a.error_description||a.error);if(!a.code)throw Error("Authorization code missing in callback.");o("exchanging");let t=await (0,h.exchangeMcpOAuthToken)({serverId:l.serverId,code:a.code,clientId:l.clientId,clientSecret:l.clientSecret,codeVerifier:l.codeVerifier,redirectUri:l.redirectUri,accessToken:e});await (0,h.storeMCPOAuthUserCredential)(e,l.serverId,{access_token:t.access_token,refresh_token:t.refresh_token,expires_in:t.expires_in,scopes:l.scopes}),o("success"),c(null),m.toast.success("Connected successfully"),i()}catch(t){let e=g(t);c(e),o("error"),m.toast.error(e)}finally{w(j),setTimeout(()=>{u.current=!1},1e3)}},[e,t,i]);return(0,p.useEffect)(()=>{f()},[f]),{startOAuthFlow:d,status:l,error:n}}],280024)},440987,e=>{"use strict";var t=e.i(903446);e.s(["SettingsIcon",()=>t.default])},284629,e=>{"use strict";let t={src:e.i(990681).default,width:64,height:64,blurWidth:0,blurHeight:0};e.s(["default",0,t])},703330,e=>{e.q("/litellm-asset-prefix/_next/static/media/github.01qi6qit7j89y.svg")},924056,e=>{e.q("/litellm-asset-prefix/_next/static/media/slack.01ebucngfr3lq.svg")},806471,e=>{e.q("/litellm-asset-prefix/_next/static/media/notion.3ve1izxfth6xd.svg")},67456,e=>{e.q("/litellm-asset-prefix/_next/static/media/linear.0r-vgi7wxinhb.svg")},459465,e=>{e.q("/litellm-asset-prefix/_next/static/media/jira.266jkt8otu3z6.svg")},283873,e=>{e.q("/litellm-asset-prefix/_next/static/media/figma.3-gfkcs78xixl.svg")},88313,e=>{e.q("/litellm-asset-prefix/_next/static/media/gmail.2kxy7ehty9j4p.svg")},243999,e=>{e.q("/litellm-asset-prefix/_next/static/media/google_drive.0t6j-2z4psaod.svg")},798962,e=>{e.q("/litellm-asset-prefix/_next/static/media/stripe.3583qhnprkybz.svg")},762217,e=>{e.q("/litellm-asset-prefix/_next/static/media/shopify.25i2if4d3gr23.svg")},758618,e=>{e.q("/litellm-asset-prefix/_next/static/media/salesforce.20dxbd6cxoyl2.svg")},333191,e=>{e.q("/litellm-asset-prefix/_next/static/media/hubspot.21ls0k94wst4x.svg")},675865,e=>{e.q("/litellm-asset-prefix/_next/static/media/twilio.1vmsvt7mb88__.svg")},301873,e=>{e.q("/litellm-asset-prefix/_next/static/media/sentry.0i-7ujykfedjd.svg")},72982,e=>{e.q("/litellm-asset-prefix/_next/static/media/zapier.3q67ovovgk_25.svg")},521442,e=>{e.q("/litellm-asset-prefix/_next/static/media/gitlab.2a2utw-6akshk.svg")},756788,e=>{e.q("/litellm-asset-prefix/_next/static/media/mcp_logo.008pk5gd77gim.png")},181692,e=>{"use strict";let t=(0,e.i(475254).default)("key",[["path",{d:"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4",key:"g0fldk"}],["path",{d:"m21 2-9.6 9.6",key:"1j0ho8"}],["circle",{cx:"7.5",cy:"15.5",r:"5.5",key:"yqb3hr"}]]);e.s(["default",0,t])},988846,438100,e=>{"use strict";var t=e.i(54943);e.s(["SearchIcon",()=>t.default],988846);var r=e.i(181692);e.s(["KeyIcon",()=>r.default],438100)},302202,e=>{"use strict";var t=e.i(953651);e.s(["ServerIcon",()=>t.default])},339402,e=>{"use strict";let t=(0,e.i(475254).default)("code",[["path",{d:"m16 18 6-6-6-6",key:"eg8j8"}],["path",{d:"m8 6-6 6 6 6",key:"ppft3o"}]]);e.s(["default",0,t])},758472,e=>{"use strict";var t=e.i(339402);e.s(["Code",()=>t.default])},328196,e=>{"use strict";var t=e.i(361653);e.s(["AlertCircleIcon",()=>t.default])},634831,e=>{"use strict";var t=e.i(546467);e.s(["ExternalLinkIcon",()=>t.default])},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},871689,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeft",()=>t.default])},101048,e=>{"use strict";var t=e.i(123287);e.s(["CircleCheck",()=>t.default])},39312,e=>{"use strict";let t=(0,e.i(475254).default)("zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]);e.s(["Zap",0,t],39312)},248256,e=>{"use strict";let t=(0,e.i(475254).default)("globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);e.s(["Globe",0,t],248256)},544394,e=>{"use strict";let t=(0,e.i(475254).default)("circle-minus",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 12h8",key:"1wcyev"}]]);e.s(["CircleMinus",0,t],544394)},630468,e=>{"use strict";e.s(["requiredRule",0,e=>t=>!(null==t||""===t||Array.isArray(t)&&0===t.length)||e,"validatorRules",0,(...e)=>Object.fromEntries(e.map((e,t)=>[`rule_${t}`,async(t,r)=>{let s=("function"==typeof e?e({getFieldValue:e=>r[e]}):e).validator;try{return await s(null,t),!0}catch(e){return e instanceof Error?e.message:String(e)}}]))])},270756,e=>{"use strict";let t=(0,e.i(475254).default)("lock",[["rect",{width:"18",height:"11",x:"3",y:"11",rx:"2",ry:"2",key:"1w4ew1"}],["path",{d:"M7 11V7a5 5 0 0 1 10 0v4",key:"fwvmzm"}]]);e.s(["Lock",0,t],270756)},849550,e=>{"use strict";let t=(0,e.i(475254).default)("dollar-sign",[["line",{x1:"12",x2:"12",y1:"2",y2:"22",key:"7eqyqh"}],["path",{d:"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6",key:"1b0p4s"}]]);e.s(["default",0,t])},212426,e=>{"use strict";var t=e.i(849550);e.s(["DollarSign",()=>t.default])},221345,e=>{"use strict";let t=(0,e.i(475254).default)("link",[["path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",key:"1cjeqo"}],["path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",key:"19qd67"}]]);e.s(["Link",0,t],221345)},834161,e=>{"use strict";var t=e.i(181692);e.s(["Key",()=>t.default])},611052,e=>{"use strict";var t=e.i(843476),r=e.i(271645),s=e.i(417385),a=e.i(768371),i=e.i(431703),l=e.i(871689),o=e.i(972520),n=e.i(643531),c=e.i(834161),u=e.i(306228),d=e.i(270756),f=e.i(37727),p=e.i(776639),h=e.i(450240),m=e.i(699375);e.s(["ByokCredentialModal",0,({server:e,open:g,onClose:x,onSuccess:y})=>{let[b,v]=(0,r.useState)(1),[_,w]=(0,r.useState)(""),[j,k]=(0,r.useState)(!0),[A,T]=(0,r.useState)(!1),E=(0,r.useId)(),N=e.alias||e.server_name||"Service",O=N.charAt(0).toUpperCase(),S=()=>{v(1),w(""),k(!0),T(!1),x()},C=async()=>{if(!_.trim())return void s.toast.error("Please enter your API key");T(!0);try{await a.fetchClient.POST("/v1/mcp/server/{server_id}/user-credential",{params:{path:{server_id:e.server_id}},body:{credential:_.trim(),save:j}}),s.toast.success(`Connected to ${N}`),y(e.server_id),S()}catch(e){s.toast.error((e=>{if(e instanceof i.ApiError){let t=e.body?.detail?.error;if(t)return t}return e instanceof Error&&e.message?e.message:"Failed to connect"})(e))}finally{T(!1)}};return(0,t.jsx)(p.Dialog,{open:g,onOpenChange:e=>!e&&S(),children:(0,t.jsx)(p.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[480px] byok-modal",showCloseButton:!1,children:(0,t.jsxs)("div",{className:"relative p-2",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-6",children:[2===b?(0,t.jsxs)("button",{onClick:()=>v(1),className:"flex items-center gap-1 text-muted-foreground hover:text-foreground text-sm",children:[(0,t.jsx)(l.ArrowLeft,{className:"size-3.5"})," Back"]}):(0,t.jsx)("div",{}),(0,t.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,t.jsx)("div",{className:`w-2 h-2 rounded-full ${1===b?"bg-info":"bg-border"}`}),(0,t.jsx)("div",{className:`w-2 h-2 rounded-full ${2===b?"bg-info":"bg-border"}`})]}),(0,t.jsx)("button",{onClick:S,className:"text-muted-foreground hover:text-foreground",children:(0,t.jsx)(f.X,{className:"size-4"})})]}),1===b?(0,t.jsxs)("div",{className:"text-center",children:[(0,t.jsxs)("div",{className:"flex items-center justify-center gap-3 mb-6",children:[(0,t.jsx)("div",{className:"w-14 h-14 rounded-xl bg-linear-to-br from-teal-400 to-cyan-600 flex items-center justify-center text-white font-bold text-xl shadow-sm",children:"L"}),(0,t.jsx)(o.ArrowRight,{className:"size-4.5 text-muted-foreground"}),(0,t.jsx)("div",{className:"w-14 h-14 rounded-xl bg-linear-to-br from-blue-600 to-indigo-800 flex items-center justify-center text-white font-bold text-xl shadow-sm",children:O})]}),(0,t.jsxs)("h2",{className:"text-2xl font-bold text-foreground mb-2",children:["Connect ",N]}),(0,t.jsxs)("p",{className:"text-muted-foreground mb-6",children:["LiteLLM needs access to ",N," to complete your request."]}),(0,t.jsx)("div",{className:"bg-muted rounded-xl p-4 text-left mb-4",children:(0,t.jsxs)("div",{className:"flex items-start gap-3",children:[(0,t.jsx)("div",{className:"mt-0.5",children:(0,t.jsxs)("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",className:"text-muted-foreground",children:[(0,t.jsx)("rect",{x:"2",y:"4",width:"20",height:"16",rx:"2",stroke:"currentColor",strokeWidth:"2"}),(0,t.jsx)("path",{d:"M8 4v16M16 4v16",stroke:"currentColor",strokeWidth:"2"})]})}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"font-semibold text-foreground mb-1",children:"How it works"}),(0,t.jsxs)("p",{className:"text-muted-foreground text-sm",children:["LiteLLM acts as a secure bridge. Your requests are routed through our MCP client directly to"," ",N,"'s API."]})]})]})}),e.byok_description&&e.byok_description.length>0&&(0,t.jsxs)("div",{className:"bg-muted rounded-xl p-4 text-left mb-6",children:[(0,t.jsxs)("p",{className:"text-xs font-semibold text-muted-foreground uppercase tracking-widest mb-3 flex items-center gap-2",children:[(0,t.jsxs)("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",className:"text-success",children:[(0,t.jsx)("path",{d:"M12 2L12 22M2 12L22 12",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"}),(0,t.jsx)("circle",{cx:"12",cy:"12",r:"9",stroke:"currentColor",strokeWidth:"2"})]}),"Requested Access"]}),(0,t.jsx)("ul",{className:"space-y-2",children:e.byok_description.map((e,r)=>(0,t.jsxs)("li",{className:"flex items-center gap-2 text-sm text-foreground",children:[(0,t.jsx)(n.Check,{className:"size-3.5 shrink-0 text-success"}),e]},r))})]}),(0,t.jsxs)("button",{onClick:()=>v(2),className:"w-full bg-gray-900 hover:bg-gray-700 text-white font-medium py-3 px-6 rounded-xl flex items-center justify-center gap-2 transition-colors",children:["Continue to Authentication ",(0,t.jsx)(o.ArrowRight,{className:"size-4"})]}),(0,t.jsx)("button",{onClick:S,className:"mt-3 w-full text-muted-foreground hover:text-foreground text-sm py-2",children:"Cancel"})]}):(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"w-12 h-12 rounded-full bg-info/10 flex items-center justify-center mb-4",children:(0,t.jsx)(c.Key,{className:"size-5 text-info"})}),(0,t.jsx)("h2",{className:"text-2xl font-bold text-foreground mb-2",children:"Provide API Key"}),(0,t.jsxs)("p",{className:"text-muted-foreground mb-6",children:["Enter your ",N," API key to authorize this connection."]}),(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsxs)("label",{htmlFor:E,className:"block text-sm font-semibold text-foreground mb-2",children:[N," API Key"]}),(0,t.jsx)(h.PasswordInput,{id:E,placeholder:"Enter your API key",value:_,onChange:e=>w(e.target.value),groupClassName:"rounded-lg"}),e.byok_api_key_help_url&&(0,t.jsxs)("a",{href:e.byok_api_key_help_url,target:"_blank",rel:"noopener noreferrer",className:"text-info hover:text-info/80 text-sm mt-2 flex items-center gap-1",children:["Where do I find my API key? ",(0,t.jsx)(u.Link2,{className:"size-3.5"})]})]}),(0,t.jsxs)("div",{className:"bg-muted rounded-xl p-4 flex items-center justify-between mb-4",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",className:"text-muted-foreground",children:(0,t.jsx)("path",{d:"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z",fill:"currentColor"})}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground",children:"Save key for future use"})]}),(0,t.jsx)(m.Switch,{checked:j,onCheckedChange:k,"aria-label":"Save key for future use"})]}),(0,t.jsxs)("div",{className:"bg-info/10 rounded-xl p-4 flex items-start gap-3 mb-6",children:[(0,t.jsx)(d.Lock,{className:"mt-0.5 size-4 shrink-0 text-info"}),(0,t.jsx)("p",{className:"text-sm text-info",children:"Your key is stored securely and transmitted over HTTPS. It is never shared with third parties."})]}),(0,t.jsxs)("button",{onClick:C,disabled:A,className:"w-full bg-info hover:bg-info/80 disabled:opacity-60 text-info-foreground font-medium py-3 px-6 rounded-xl flex items-center justify-center gap-2 transition-colors",children:[(0,t.jsx)(d.Lock,{className:"size-4"}),"Connect & Authorize"]})]})]})})})}])}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/02ic1ccwq2p02.js b/litellm/proxy/_experimental/out/_next/static/chunks/02ic1ccwq2p02.js
new file mode 100644
index 00000000000..737e4ac7ecd
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/02ic1ccwq2p02.js
@@ -0,0 +1 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,332102,e=>{"use strict";let t=(0,e.i(475254).default)("inbox",[["polyline",{points:"22 12 16 12 14 15 10 15 8 12 2 12",key:"o97t9d"}],["path",{d:"M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",key:"oot6mr"}]]);e.s(["Inbox",0,t],332102)},655063,e=>{"use strict";var t=e.i(540626),r=e.i(271645);e.s(["useDebouncedValue",0,function(e,n,i){let[s,a,l]=function(e,n,i){let[s,a]=(0,r.useState)(e),l=(0,t.useDebouncer)(a,n,i);return[s,l.maybeExecute,l]}(e,n,i);return(0,r.useEffect)(()=>{a(e)},[e,a]),[s,l]}],655063)},768371,e=>{"use strict";let t,r;var n=e.i(247167);let i=/\{[^{}]+\}/g;function s(e,t,r){if(null==t)return"";if("object"==typeof t)throw Error("Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.");return`${e}=${r?.allowReserved===!0?t:encodeURIComponent(t)}`}function a(e,t,r){if(!t||"object"!=typeof t)return"";let n=[],i={simple:",",label:".",matrix:";"}[r.style]||"&";if("deepObject"!==r.style&&!1===r.explode){for(let e in t)n.push(e,!0===r.allowReserved?t[e]:encodeURIComponent(t[e]));let i=n.join(",");switch(r.style){case"form":return`${e}=${i}`;case"label":return`.${i}`;case"matrix":return`;${e}=${i}`;default:return i}}for(let i in t){let a="deepObject"===r.style?`${e}[${i}]`:i;n.push(s(a,t[i],r))}let a=n.join(i);return"label"===r.style||"matrix"===r.style?`${i}${a}`:a}function l(e,t,r){if(!Array.isArray(t))return"";if(!1===r.explode){let n={form:",",spaceDelimited:"%20",pipeDelimited:"|"}[r.style]||",",i=(!0===r.allowReserved?t:t.map(e=>encodeURIComponent(e))).join(n);switch(r.style){case"simple":return i;case"label":return`.${i}`;case"matrix":return`;${e}=${i}`;default:return`${e}=${i}`}}let n={simple:",",label:".",matrix:";"}[r.style]||"&",i=[];for(let n of t)"simple"===r.style||"label"===r.style?i.push(!0===r.allowReserved?n:encodeURIComponent(n)):i.push(s(e,n,r));return"label"===r.style||"matrix"===r.style?`${n}${i.join(n)}`:i.join(n)}function o(e){return function(t){let r=[];if(t&&"object"==typeof t)for(let n in t){let i=t[n];if(null!=i){if(Array.isArray(i)){if(0===i.length)continue;r.push(l(n,i,{style:"form",explode:!0,...e?.array,allowReserved:e?.allowReserved||!1}));continue}if("object"==typeof i){r.push(a(n,i,{style:"deepObject",explode:!0,...e?.object,allowReserved:e?.allowReserved||!1}));continue}r.push(s(n,i,e))}}return r.join("&")}}function u(e,t){let r=e;for(let n of e.match(i)??[]){let e=n.substring(1,n.length-1),i=!1,o="simple";if(e.endsWith("*")&&(i=!0,e=e.substring(0,e.length-1)),e.startsWith(".")?(o="label",e=e.substring(1)):e.startsWith(";")&&(o="matrix",e=e.substring(1)),!t||void 0===t[e]||null===t[e])continue;let u=t[e];if(Array.isArray(u)){r=r.replace(n,l(e,u,{style:o,explode:i}));continue}if("object"==typeof u){r=r.replace(n,a(e,u,{style:o,explode:i}));continue}if("matrix"===o){r=r.replace(n,`;${s(e,u)}`);continue}r=r.replace(n,"label"===o?`.${encodeURIComponent(u)}`:encodeURIComponent(u))}return r}function c(e,t){return e instanceof FormData?e:t&&"application/x-www-form-urlencoded"===(t.get instanceof Function?t.get("Content-Type")??t.get("content-type"):t["Content-Type"]??t["content-type"])?new URLSearchParams(e).toString():JSON.stringify(e)}function d(...e){let t=new Headers;for(let r of e)if(r&&"object"==typeof r)for(let[e,n]of r instanceof Headers?r.entries():Object.entries(r))if(null===n)t.delete(e);else if(Array.isArray(n))for(let r of n)t.append(e,r);else void 0!==n&&t.set(e,n);return t}function f(e){return e.endsWith("/")?e.substring(0,e.length-1):e}var p=e.i(954616),h=e.i(621482),m=e.i(869230),y=e.i(469637),b=e.i(254440),g=e.i(266027),v=e.i(431703),w=e.i(97198),j=e.i(950643);let O=function(e){let{baseUrl:t="",Request:r=globalThis.Request,fetch:i=globalThis.fetch,querySerializer:s,bodySerializer:a,pathSerializer:l,headers:p,requestInitExt:h,...m}={...e};h="object"==typeof n.default&&Number.parseInt(n.default?.versions?.node?.substring(0,2))>=18&&n.default.versions.undici?h:void 0,t=f(t);let y=[];async function b(e,n){var b,g;let v,w,j,O,k,{baseUrl:_,fetch:x=i,Request:R=r,headers:S,params:E={},parseAs:q="json",querySerializer:$,bodySerializer:A=a??c,pathSerializer:M,body:T,middleware:C=[],...P}=n||{},N=t;_&&(N=f(_)??t);let U="function"==typeof s?s:o(s);$&&(U="function"==typeof $?$:o({..."object"==typeof s?s:{},...$}));let z=M||l||u,I=void 0===T?void 0:A(T,d(p,S,E.header)),L=d(void 0===I||I instanceof FormData?{}:{"Content-Type":"application/json"},p,S,E.header),D=[...y,...C],H={redirect:"follow",...m,...P,body:I,headers:L},V=new R((b=e,g={baseUrl:N,params:E,querySerializer:U,pathSerializer:z},v=`${g.baseUrl}${b}`,g.params?.path&&(v=g.pathSerializer(v,g.params.path)),(w=g.querySerializer(g.params.query??{})).startsWith("?")&&(w=w.substring(1)),w&&(v+=`?${w}`),v),H);for(let e in P)e in V||(V[e]=P[e]);if(D.length){for(let t of(j=Math.random().toString(36).slice(2,11),O=Object.freeze({baseUrl:N,fetch:x,parseAs:q,querySerializer:U,bodySerializer:A,pathSerializer:z}),D))if(t&&"object"==typeof t&&"function"==typeof t.onRequest){let r=await t.onRequest({request:V,schemaPath:e,params:E,options:O,id:j});if(r)if(r instanceof R)V=r;else if(r instanceof Response){k=r;break}else throw Error("onRequest: must return new Request() or Response() when modifying the request")}}if(!k){try{k=await x(V,h)}catch(r){let t=r;if(D.length)for(let r=D.length-1;r>=0;r--){let n=D[r];if(n&&"object"==typeof n&&"function"==typeof n.onError){let r=await n.onError({request:V,error:t,schemaPath:e,params:E,options:O,id:j});if(r){if(r instanceof Response){t=void 0,k=r;break}if(r instanceof Error){t=r;continue}throw Error("onError: must return new Response() or instance of Error")}}}if(t)throw t}if(D.length)for(let t=D.length-1;t>=0;t--){let r=D[t];if(r&&"object"==typeof r&&"function"==typeof r.onResponse){let t=await r.onResponse({request:V,response:k,schemaPath:e,params:E,options:O,id:j});if(t){if(!(t instanceof Response))throw Error("onResponse: must return new Response() when modifying the response");k=t}}}}let Q=k.headers.get("Content-Length");if(204===k.status||"HEAD"===V.method||"0"===Q&&!k.headers.get("Transfer-Encoding")?.includes("chunked"))return k.ok?{data:void 0,response:k}:{error:void 0,response:k};if(k.ok){let e=async()=>{if("stream"===q)return k.body;if("json"===q&&!Q){let e=await k.text();return e?JSON.parse(e):void 0}return await k[q]()};return{data:await e(),response:k}}let F=await k.text();try{F=JSON.parse(F)}catch{}return{error:F,response:k}}return{request:(e,t,r)=>b(t,{...r,method:e.toUpperCase()}),GET:(e,t)=>b(e,{...t,method:"GET"}),PUT:(e,t)=>b(e,{...t,method:"PUT"}),POST:(e,t)=>b(e,{...t,method:"POST"}),DELETE:(e,t)=>b(e,{...t,method:"DELETE"}),OPTIONS:(e,t)=>b(e,{...t,method:"OPTIONS"}),HEAD:(e,t)=>b(e,{...t,method:"HEAD"}),PATCH:(e,t)=>b(e,{...t,method:"PATCH"}),TRACE:(e,t)=>b(e,{...t,method:"TRACE"}),use(...e){for(let t of e)if(t){if("object"!=typeof t||!("onRequest"in t||"onResponse"in t||"onError"in t))throw Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");y.push(t)}},eject(...e){for(let t of e){let e=y.indexOf(t);-1!==e&&y.splice(e,1)}}}}({Request:function(e,t){return new globalThis.Request((0,j.resolveRequestUrl)(e,{registeredBase:(0,w.getRequestBaseUrl)(),pageOrigin:globalThis.location?.origin}),t)},fetch:e=>globalThis.fetch(e)});O.use({onRequest({request:e}){let t=(0,w.getAuthToken)();t&&e.headers.set((0,w.getAuthHeaderName)(),`Bearer ${t}`)},async onResponse({response:e}){let t;if(e.ok)return e;let r=await e.clone().text(),n=r;try{n=JSON.parse(r),t=(0,v.deriveErrorMessage)(n)}catch{t=r||`HTTP ${e.status}`}throw(0,w.reportError)(t),new v.ApiError(t,e.status,n)}});let k=(t=async({queryKey:[e,t,r],signal:n})=>{let i=O[e.toUpperCase()],{data:s,error:a,response:l}=await i(t,{signal:n,...r});if(a)throw a;return 204===l.status||"0"===l.headers.get("Content-Length")?s??null:s},{queryOptions:r=(e,r,...[n,i])=>({queryKey:void 0===n?[e,r]:[e,r,n],queryFn:t,...i}),useQuery:(e,t,...[n,i,s])=>(0,g.useQuery)(r(e,t,n,i),s),useSuspenseQuery:(e,t,...[n,i,s])=>{var a;return a=r(e,t,n,i),(0,y.useBaseQuery)({...a,enabled:!0,suspense:!0,throwOnError:b.defaultThrowOnError,placeholderData:void 0},m.QueryObserver,s)},useInfiniteQuery:(e,t,n,i,s)=>{let{pageParamName:a="cursor",...l}=i,{queryKey:o}=r(e,t,n);return(0,h.useInfiniteQuery)({queryKey:o,queryFn:async({queryKey:[e,t,r],pageParam:n=0,signal:i})=>{let s=O[e.toUpperCase()],l={...r,signal:i,params:{...r?.params||{},query:{...r?.params?.query,[a]:n}}},{data:o,error:u}=await s(t,l);if(u)throw u;return o},...l},s)},useMutation:(e,t,r,n)=>(0,p.useMutation)({mutationKey:[e,t],mutationFn:async r=>{let n=O[e.toUpperCase()],{data:i,error:s}=await n(t,r);if(s)throw s;return i},...r},n)});e.s(["$api",0,k,"fetchClient",0,O],768371)},438847,e=>{"use strict";var t=e.i(916108),r=e.i(487315),n=e.i(280862),i=e.i(271645);function s(e,t,n){try{return e(t)}catch(e){return n?(0,r.i)(25,t,e,n):(0,r.i)(24,t,e),null}}function a(e){function t(t){if(void 0===t)return null;let r="";if(Array.isArray(t)){if(void 0===t[0])return null;r=t[0]}return"string"==typeof t&&(r=t),s(e.parse,r)}return{type:"single",eq:(e,t)=>e===t,...e,parseServerSide:t,withDefault(e){return{...this,defaultValue:e,parseServerSide:r=>t(r)??e}},withOptions(e){return{...this,...e}}}}let l=a({parse:e=>e,serialize:String}),o=a({parse:e=>{let t=parseInt(e);return t==t?t:null},serialize:e=>""+Math.round(e)});function u(e,t){return e.valueOf()===t.valueOf()}a({parse:e=>{let t=parseInt(e);return t==t?t-1:null},serialize:e=>""+Math.round(e+1)}),a({parse:e=>{let t=parseInt(e,16);return t==t?t:null},serialize:e=>{let t=Math.round(e).toString(16);return t<"0"||!(1&t.length)?t:"0"+t}}),a({parse:e=>{let t=parseFloat(e);return t==t?t:null},serialize:String}),a({parse:e=>"true"===e.toLowerCase(),serialize:String}),a({parse:e=>{let t=new Date(parseInt(e));return t.valueOf()==t.valueOf()?t:null},serialize:e=>""+e.valueOf(),eq:u}),a({parse:e=>{let t=new Date(e);return t.valueOf()==t.valueOf()?t:null},serialize:e=>e.toISOString(),eq:u}),a({parse:e=>{let t=new Date(e.slice(0,10));return t.valueOf()==t.valueOf()?t:null},serialize:e=>e.toISOString().slice(0,10),eq:u});let c=(0,n.o)("sync-emitter",()=>(0,t.i)()),d={},f=(e,t)=>"defaultValue"===e?void 0:t;function p(e,s={}){let a=(0,i.useId)(),l=(0,n.i)(),o=(0,n.a)(),{history:u=l?.history??"replace",scroll:y=l?.scroll??!1,shallow:b=l?.shallow??!0,throttleMs:g=t.l.timeMs,limitUrlUpdates:v=l?.limitUrlUpdates,clearOnDefault:w=l?.clearOnDefault??!0,startTransition:j,urlKeys:O=d}=s,k=Object.keys(e).join(","),_=(0,i.useRef)(e),x=_.current,R=JSON.stringify(Object.entries(x),f)===JSON.stringify(Object.entries(e),f)&&Object.entries(e).every(([e,t])=>{let r=x[e]?.defaultValue,n=t.defaultValue;return!!Object.is(r,n)||void 0!==r&&void 0!==n&&t.eq?.(r,n)===!0})?x:e;_.current=R;let S=(0,i.useMemo)(()=>Object.fromEntries(Object.keys(e).map(e=>[e,O[e]??e])),[k,JSON.stringify(O)]),E=(0,n.r)(Object.values(S)),q=E.searchParams,$=(0,i.useRef)({}),A=(0,i.useRef)(null),M=(0,i.useRef)(null),T=(0,t.n)(Object.values(S)),[C,P]=(0,i.useState)(()=>h(e,O,q,T).state),N=(0,i.useRef)(C),U=Object.values(S).map(e=>`${e}=${q.getAll(e)}`).join("&")+JSON.stringify(T),z=()=>{let{state:t,hasChanged:n}=h(e,O,q,T,$.current,N.current);return n&&((0,r.t)(1,a,k,t),N.current=t,P(t)),n},I=Object.keys($.current).join("&")!==Object.values(S).join("&"),L=null===M.current||M.current===(E.pathname??location.pathname),D=!1;(I||L&&A.current!==U)&&(A.current=U,D=z(),I&&($.current=Object.fromEntries(Object.entries(S).map(([t,r])=>[r,e[t]?.type==="multi"?q.getAll(r):q.get(r)??null])))),I||D||!L||C===N.current||P(N.current),(0,i.useEffect)(()=>{M.current=E.pathname??location.pathname,z()},[U,E.pathname]),(0,i.useEffect)(()=>{let t=Object.keys(e).reduce((t,n)=>(t[n]=({state:t,query:i})=>{P(s=>{let l=S[n];return Object.is(s[n]??null,t)?((0,r.t)(2,a,k,l,t,e[n]?.defaultValue,N.current),s):(N.current={...N.current,[n]:t},$.current[l]=i,(0,r.t)(3,a,k,l,t,e[n]?.defaultValue,N.current),N.current)})},t),{});for(let n of Object.keys(e)){let e=S[n];(0,r.t)(4,a,e,k),c.on(e,t[n])}return()=>{for(let n of Object.keys(e)){let e=S[n];(0,r.t)(5,a,e,k),c.off(e,t[n])}}},[k,S]);let H=(0,i.useCallback)((e,n={})=>{let i,s=Object.fromEntries(Object.keys(R).map(e=>[e,null])),l="function"==typeof e?e(m(N.current,R))??s:e??s;(0,r.t)(6,a,k,l);let d=0,f=!1,p=[];for(let[e,r]of Object.entries(l)){let s=R[e],a=S[e];if(!s||void 0===a||void 0===r)continue;(n.clearOnDefault??s.clearOnDefault??w)&&null!==r&&void 0!==s.defaultValue&&(s.eq??((e,t)=>e===t))(r,s.defaultValue)&&(r=null);let l=null===r?null:(s.serialize??String)(r);c.emit(a,{state:r,query:l});let h={key:a,query:l,options:{history:n.history??s.history??u,shallow:n.shallow??s.shallow??b,scroll:n.scroll??s.scroll??y,startTransition:n.startTransition??s.startTransition??j}},m=n.limitUrlUpdates??s.limitUrlUpdates??v;if(m?.method==="debounce"){let e=m.timeMs??t.l.timeMs,r=t.t.push(h,e,E,o);dt(e),f?t.r.flush(E,o):t.r.getPendingPromise(E));return i??h},[k,u,b,y,g,v?.method,v?.timeMs,j,w,R,S,E.updateUrl,E.getSearchParamsSnapshot,E.rateLimitFactor,o]);return[(0,i.useMemo)(()=>m(C,R),[C,R]),H]}function h(e,r,n,i,a,l){let o=!1,u=Object.entries(e).reduce((e,[u,c])=>{var d;let f=r?.[u]??u,p=i[f],h="multi"===c.type?[]:null,m=void 0===p?("multi"===c.type?n.getAll(f):n.get(f))??h:p;return a&&l&&((d=a[f]??h)===m||null!==d&&null!==m&&"string"!=typeof d&&"string"!=typeof m&&d.length===m.length&&d.every((e,t)=>e===m[t]))?e[u]=l[u]??null:(o=!0,e[u]=((0,t.o)(m)?null:s(c.parse,m,f))??null,a&&(a[f]=m)),e},{});if(!o){let t=Object.keys(e),r=Object.keys(l??{});o=t.length!==r.length||t.some(e=>!r.includes(e))}return{state:u,hasChanged:o}}function m(e,t){return Object.fromEntries(Object.keys(e).map(r=>[r,e[r]??t[r]?.defaultValue??null]))}e.s(["createParser",0,a,"parseAsInteger",0,o,"parseAsString",0,l,"parseAsStringLiteral",0,function(e){return a({parse:t=>e.includes(t)?t:null,serialize:String})},"useQueryState",0,function(e,t={}){let{parse:r,type:n,serialize:s,eq:a,defaultValue:l,...o}=t,[{[e]:u},c]=p({[e]:{parse:r??(e=>e),type:n,serialize:s,eq:a,defaultValue:l}},o);return[u,(0,i.useCallback)((t,r={})=>c(r=>({[e]:"function"==typeof t?t(r[e]):t}),r),[e,c])]},"useQueryStates",0,p],438847)},133356,e=>{"use strict";var t=e.i(843476),r=e.i(199931),n=e.i(487486),i=e.i(196631);let s={complexity:"Auto-Router v2",adaptive:"Adaptive router",quality:"Quality router"},a={heuristic_scorer:"Heuristic scorer",heuristic_v2:"Heuristic v2",heuristic_first_short_circuit:"Heuristic scorer, classifier skipped",hybrid_short_circuit:"Heuristic scorer, score clear of every boundary",classifier_plugin:"Custom classifier plugin",semantic_keyword_match:"Semantic keyword match",session_affinity_pin:"Pinned to session",session_affinity_escalation:"Escalated from session pin",user_turn_continuation:"Continuation turn, classifier skipped",modality_escalation:"Escalated for image input",modality_pin_override:"Overrode session pin for image input",quality_tier:"Quality tier mapping",bandit:"Adaptive bandit",default_fallback:"Default model, no route matched",classifier_fallback:"Fallback tier, LLM classifier failed",default_model_fallback:"Default model, LLM classifier failed"};function l({label:e,children:r}){return(0,t.jsxs)("div",{className:"flex gap-3 py-1 text-sm",children:[(0,t.jsx)("span",{className:"w-28 shrink-0 text-muted-foreground",children:e}),(0,t.jsx)("span",{className:"min-w-0 break-words",children:r})]})}function o({decision:e,className:u}){if(!e||!e.cause)return null;let{router_model_name:c,router_type:d,routed_model:f,tier:p,tier_label:h,request_type:m,score:y,signals:b,escalated:g,escalation_keyword:v,tier_boundaries:w}=e,j=void 0!==y&&"reasoning_override"!==e.cause&&"plan_mode"!==e.cause?function(e,t,r){if(!t)return null;let{simple_medium:n,medium_complex:i,complex_reasoning:s}=t;if(void 0===n||void 0===i||void 0===s)return null;let a=(e,t)=>r?e:`${e}, ${t}`;return e0&&(0,t.jsx)(l,{label:"Signals",children:(0,t.jsx)("span",{className:"flex flex-wrap gap-1",children:b.map(e=>(0,t.jsx)(n.Badge,{variant:"outline",className:"font-normal",children:e},e))})})]})]})}e.s(["RoutingDecisionCard",0,o,"default",0,o])},283086,e=>{"use strict";let t=(0,e.i(475254).default)("sparkles",[["path",{d:"M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",key:"4pj2yx"}],["path",{d:"M20 3v4",key:"1olli1"}],["path",{d:"M22 5h-4",key:"1gvqau"}],["path",{d:"M4 17v2",key:"vumght"}],["path",{d:"M5 18H3",key:"zchphs"}]]);e.s(["Sparkles",0,t],283086)},441773,e=>{"use strict";let t=e=>"number"==typeof e&&Number.isFinite(e)&&e>0?e:void 0;e.s(["PROMPT_CACHE_CREATION_TOOLTIP",0,"Input tokens written to the LLM provider's prompt cache for reuse by later requests.","PROMPT_CACHE_READ_TOOLTIP",0,"Input tokens read from the LLM provider's prompt cache (e.g. Anthropic / OpenAI), billed at a discounted rate. Reported by the provider.","extractPromptCacheTokens",0,e=>{let r=e?.prompt_tokens_details??e?.input_tokens_details,n=t(e?.cache_read_input_tokens)??t(r?.cached_tokens),i=t(e?.cache_creation_input_tokens)??t(r?.cache_write_tokens);return{...void 0!==n&&{cacheReadTokens:n},...void 0!==i&&{cacheCreationTokens:i}}}])},798031,e=>{"use strict";let t=(0,e.i(475254).default)("circle-x",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);e.s(["default",0,t])},686311,e=>{"use strict";let t=(0,e.i(475254).default)("message-square",[["path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",key:"1lielz"}]]);e.s(["MessageSquare",0,t],686311)},832724,e=>{"use strict";var t=e.i(798031);e.s(["CircleX",()=>t.default])},387951,e=>{"use strict";let t=(0,e.i(475254).default)("mic",[["path",{d:"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z",key:"131961"}],["path",{d:"M19 10v2a7 7 0 0 1-14 0v-2",key:"1vc78b"}],["line",{x1:"12",x2:"12",y1:"19",y2:"22",key:"x3vr5v"}]]);e.s(["Mic",0,t],387951)},382373,e=>{"use strict";let t=(0,e.i(475254).default)("volume-2",[["path",{d:"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",key:"uqj9uw"}],["path",{d:"M16 9a5 5 0 0 1 0 6",key:"1q6k2b"}],["path",{d:"M19.364 18.364a9 9 0 0 0 0-12.728",key:"ijwkga"}]]);e.s(["Volume2",0,t],382373)},700514,e=>{"use strict";var t=e.i(271645);e.s(["defaultPageSize",0,25,"useBaseUrl",0,()=>{let[e,r]=(0,t.useState)("http://localhost:4000");return(0,t.useEffect)(()=>{{let{protocol:e,host:t}=window.location;r(`${e}//${t}`)}},[]),e}])}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/03_s-zve24zyk.js b/litellm/proxy/_experimental/out/_next/static/chunks/03_s-zve24zyk.js
new file mode 100644
index 00000000000..4c07850125c
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/03_s-zve24zyk.js
@@ -0,0 +1 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,519380,e=>{e.q("/litellm-asset-prefix/_next/static/media/bedrock.2vhamxr8q6y4o.svg")},946013,e=>{e.q("/litellm-asset-prefix/_next/static/media/google.3y8ypywwtqob_.svg")},641266,e=>{e.q("/litellm-asset-prefix/_next/static/media/microsoft_azure.3626-7zx7wf09.svg")},956529,e=>{e.q("/litellm-asset-prefix/_next/static/media/openai_small.3rj8nedgjpevh.svg")},913383,e=>{e.q("/litellm-asset-prefix/_next/static/media/a2a_agent.14el5-6dflh1h.png")},238564,e=>{e.q("/litellm-asset-prefix/_next/static/media/ai21.0m_u-tih8nm0v.svg")},941533,e=>{e.q("/litellm-asset-prefix/_next/static/media/aiml_api.1dq6dbpwklhlg.svg")},994636,e=>{e.q("/litellm-asset-prefix/_next/static/media/anthropic.3s95kgy8jpc64.svg")},824770,e=>{e.q("/litellm-asset-prefix/_next/static/media/assemblyai_small.0w_dslsra91uw.png")},920076,e=>{e.q("/litellm-asset-prefix/_next/static/media/baseten.41k2lnwp3c5g9.svg")},96889,e=>{e.q("/litellm-asset-prefix/_next/static/media/cerebras.1ur1xyfqk9ncz.svg")},348026,e=>{e.q("/litellm-asset-prefix/_next/static/media/cloudflare.2n1spdq7u5yki.svg")},727148,e=>{e.q("/litellm-asset-prefix/_next/static/media/cohere.22i3i2e449j5i.svg")},411703,e=>{e.q("/litellm-asset-prefix/_next/static/media/cometapi.3w0xficbg3dkk.svg")},922480,e=>{e.q("/litellm-asset-prefix/_next/static/media/cursor.1q1ev-_5l7exg.svg")},769490,e=>{e.q("/litellm-asset-prefix/_next/static/media/databricks.2hiet9qlqzn-g.svg")},829789,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepgram.3-krp20p_xed3.png")},41730,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepinfra.3lr_lsr7mhui6.png")},662576,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepseek.3n4cu0x32i_7w.svg")},987202,e=>{e.q("/litellm-asset-prefix/_next/static/media/elevenlabs.2982m_dk2-h_y.png")},953265,e=>{e.q("/litellm-asset-prefix/_next/static/media/fal_ai.3rahrirki8sby.jpg")},346512,e=>{e.q("/litellm-asset-prefix/_next/static/media/featherless.3hmlef3fhc0h5.svg")},84416,e=>{e.q("/litellm-asset-prefix/_next/static/media/fireworks.3t1b6p8edeqyo.svg")},104602,e=>{e.q("/litellm-asset-prefix/_next/static/media/friendli.0ymiswh6l35bq.svg")},771937,e=>{e.q("/litellm-asset-prefix/_next/static/media/gigachat.37uico956hu-u.svg")},888193,e=>{e.q("/litellm-asset-prefix/_next/static/media/github_copilot.3k-8jyadoaq2u.svg")},447500,e=>{e.q("/litellm-asset-prefix/_next/static/media/groq.20csmqzsusp1k.svg")},270039,e=>{e.q("/litellm-asset-prefix/_next/static/media/huggingface.1-07ypt9ii_-p.svg")},227733,e=>{e.q("/litellm-asset-prefix/_next/static/media/hyperbolic.3le20v59sebn8.svg")},823929,e=>{e.q("/litellm-asset-prefix/_next/static/media/infinity.0s9s12bl4lccx.png")},333845,e=>{e.q("/litellm-asset-prefix/_next/static/media/jina.0ukab8o-3-5m_.png")},813878,e=>{e.q("/litellm-asset-prefix/_next/static/media/lambda.26_vz7cmyuodo.svg")},767788,e=>{e.q("/litellm-asset-prefix/_next/static/media/lmstudio.35s3-83mlhcms.svg")},808630,e=>{e.q("/litellm-asset-prefix/_next/static/media/meta_llama.1kxk24vwsem49.svg")},468732,e=>{e.q("/litellm-asset-prefix/_next/static/media/minimax.2mfkkqc-lnsen.svg")},610503,e=>{e.q("/litellm-asset-prefix/_next/static/media/mistral.0n8jv_67hgq4h.svg")},438969,e=>{e.q("/litellm-asset-prefix/_next/static/media/moonshot.3__i9wvf37ksm.svg")},852459,e=>{e.q("/litellm-asset-prefix/_next/static/media/morph.2av06eo-t0-ve.svg")},494696,e=>{e.q("/litellm-asset-prefix/_next/static/media/nebius.2ipf7rmjccira.svg")},148973,e=>{e.q("/litellm-asset-prefix/_next/static/media/novita.0_nzmm_rl4lrf.svg")},570036,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_nim.1fz-5ugf_um0v.svg")},151170,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_triton.1aotoxig_m2w1.png")},862330,e=>{e.q("/litellm-asset-prefix/_next/static/media/ollama.144cif369atc5.svg")},788158,e=>{e.q("/litellm-asset-prefix/_next/static/media/openrouter.1xk7748-_jixf.svg")},350567,e=>{e.q("/litellm-asset-prefix/_next/static/media/oracle.43kws59xxr8ig.svg")},822797,e=>{e.q("/litellm-asset-prefix/_next/static/media/perplexity-ai.2do8hoc8tw__0.svg")},840911,e=>{e.q("/litellm-asset-prefix/_next/static/media/qwen.0a49x9i08_0gz.png")},445735,e=>{e.q("/litellm-asset-prefix/_next/static/media/recraft.2f4cv-c9ad-mo.svg")},635202,e=>{e.q("/litellm-asset-prefix/_next/static/media/replicate.445bidyix2tyh.svg")},669161,e=>{e.q("/litellm-asset-prefix/_next/static/media/runway.2zzwye1fddnnn.png")},159508,e=>{e.q("/litellm-asset-prefix/_next/static/media/sambanova.1vcyu0faw1x8h.svg")},544025,e=>{e.q("/litellm-asset-prefix/_next/static/media/sap.1367hgge0s0xl.png")},708767,e=>{e.q("/litellm-asset-prefix/_next/static/media/scx_ai.3emo1p5delrhx.svg")},100588,e=>{e.q("/litellm-asset-prefix/_next/static/media/snowflake.2_p8qqpi0r3lr.svg")},183804,e=>{e.q("/litellm-asset-prefix/_next/static/media/soniox.3nhjmssy7ybh7.svg")},865502,e=>{e.q("/litellm-asset-prefix/_next/static/media/togetherai.1wk-mouzgw5ho.svg")},96912,e=>{e.q("/litellm-asset-prefix/_next/static/media/topaz.3rjp3zvx4eags.svg")},395073,e=>{e.q("/litellm-asset-prefix/_next/static/media/v0.15trd3tb1ulop.svg")},407829,e=>{e.q("/litellm-asset-prefix/_next/static/media/vercel.1mvnwxofolt8y.svg")},846077,e=>{e.q("/litellm-asset-prefix/_next/static/media/vllm.3_gqby46r7s3x.png")},914861,e=>{e.q("/litellm-asset-prefix/_next/static/media/volcengine.23ly9ik_qc138.png")},285328,e=>{e.q("/litellm-asset-prefix/_next/static/media/voyage.0krq6ew-yr8dk.webp")},779278,e=>{e.q("/litellm-asset-prefix/_next/static/media/watsonx.19rrg39yvhpk8.svg")},325532,e=>{e.q("/litellm-asset-prefix/_next/static/media/xai.2kc3gjiopn9om.svg")},288330,e=>{e.q("/litellm-asset-prefix/_next/static/media/xinference.063cy_ievvy5u.svg")},922158,336712,39182,980385,e=>{"use strict";let t={src:e.i(519380).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,t],922158);let r={src:e.i(946013).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,r],336712);let i={src:e.i(641266).default,width:200,height:58,blurWidth:0,blurHeight:0};e.s(["default",0,i],39182);let a={src:e.i(956529).default,width:28,height:28,blurWidth:0,blurHeight:0};e.s(["default",0,a],980385)},916925,555987,9774,247044,e=>{"use strict";var t,r=e.i(221688),i=e.i(950643);let a=/^(https?:|data:|blob:|\/\/)/i,l=e=>a.test(e),s=(e,t=r.serverRootPath)=>{let a;if(!e)return;if(l(e)||e.includes("/_next/static/"))return e;let s=(0,i.normalizeRootPath)(t);return s&&(e===s||e.startsWith(`${s}/`))?e:(a=(0,i.normalizeRootPath)(t),`${a}${e.startsWith("/")?e:`/${e}`}`)};e.s(["isExternalAssetSrc",0,l,"resolveLogoSrc",0,s],555987);let n={src:e.i(913383).default,width:661,height:768,blurWidth:7,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAwUlEQVR42h2OvQpGcByFf5dK7oBJFoooJDaDZFA+BoVkNBikGJSUJINyGeft/Q+nznDO00O6rsM0Tfi+z6JpGizLgqqqIEVR0HUdqqqCbdus930PWZZBy7IgCAKkaYpxHJEkCaIowjAMoGmaEMcx8jxHURRo2xZ1XaMsS9B5nrjvG+u6Yp5nfN+H53nwJ9JxHMiyDO/7Mtx1Xey1bRvIcRzwPI993xGGIZqmgSAIMAwDJEkSPM9jphzHsYHruhBFET+hn6S8pf6D7AAAAABJRU5ErkJggg=="},o={src:e.i(238564).default,width:103,height:24,blurWidth:0,blurHeight:0},A={src:e.i(941533).default,width:115,height:24,blurWidth:0,blurHeight:0},c={src:e.i(994636).default,width:46,height:46,blurWidth:0,blurHeight:0},d={src:e.i(824770).default,width:28,height:28,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAlElEQVR42m3OoQqDUBQGYF9mwzLbFiZsMNgwuGa4YFgYLC6PgcXuA5gFzdcgFkExGr33ogZRNIr6CAoKKgo/nAMfh/NTu3u4GWoY+0fIAsIC3C8LuIiRH9S2W5wBXsBPKaHTGGb+lZMJmCe2vPYjZe9/bMDswKMRbq9Yg9VRICcBq3p6FckINIf6o6ECwyOam/1YpwPFUFu+Lt2F2QAAAABJRU5ErkJggg=="},u={src:e.i(920076).default,width:16,height:16,blurWidth:0,blurHeight:0};var h=e.i(922158);let g={src:e.i(96889).default,width:800,height:600,blurWidth:0,blurHeight:0},m={src:e.i(348026).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,m],9774);let p={src:e.i(727148).default,width:75,height:75,blurWidth:0,blurHeight:0},f={src:e.i(411703).default,width:16,height:16,blurWidth:0,blurHeight:0},x={src:e.i(922480).default,width:16,height:16,blurWidth:0,blurHeight:0},b={src:e.i(769490).default,width:16,height:16,blurWidth:0,blurHeight:0},v={src:e.i(829789).default,width:32,height:32,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAzklEQVR42k3PPWuDcBDHccUiiikYSwqhg+IkuKUpOLqK4OYrcBZcFCcH352mgy/Ch9mxEPg2+s+Q4W65zx33kyRJQpZlFOUNTdM4HN45Hi1Op0/O56+7tAHbtqmqiqZpKIqCy+Uby/rYkABhGLKuK+M4siwLt9sv1+sPpmkKEAQBwzCQpilxHDNNE3VdYxiGALqu47oujuMQRdEOyrJEVVUBFEUhSRK6rmOeZ/q+x/f97XkBHqfIsoy2bcnzHM/z9mSP2Q62dt/0c+O1/v4BYRxu3LgaR7UAAAAASUVORK5CYII="},_={src:e.i(41730).default,width:225,height:225,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAfklEQVR42nVOvQqDMBjM+7+RpbQ0Ji2NQhwdzGIwCMZFiCAa9STqIPhxw/3A3UeW41w/AKck87w0tqvbngkFgEDCJOPoKc+fovxKzaUGiXkOk0zei1TRzDxYEbHiIw0kzD2Aji5BqHolW9Uv0+9U01AVxivr4r8CjHX7+N27K5WIrP56XsFTAAAAAElFTkSuQmCC"},E={src:e.i(662576).default,width:293,height:215,blurWidth:0,blurHeight:0},w={src:e.i(987202).default,width:1563,height:1563,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA5ElEQVR42h2PPwtBURjGj3wCk93sC1iUCYXFIlGSMjC4QiiTBSE3Ge5M3e0uPoJFBhOTP8NNukXduFL3uJ1Xzz11znCe93me38uitQSL11Pe8rAanKpycbSa5Ar9UiAmJT3QXHGwHGfvj/vJcRzOfz/7fLvsW4tuJFZLehicEIUQpOs6GYZBOIfrcZPp5f0MsXDatk2yLJOqqu6A9f2YjXk7zNCJWM45KYpCmqa5A6/P+ynNGiEGIHSiwjRNsiyLBAmxPezW6U7Gx0ALIHQiFk6I5WEl6G6BB7QAQqc0a4bgxD/uH4FYoVec8m3dAAAAAElFTkSuQmCC"},I={src:e.i(953265).default,width:400,height:400,blurWidth:8,blurHeight:8,blurDataURL:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAAIAAgDAREAAhEBAxEB/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtP9N/tL+PO/8A7ZeV/wDFUj6L917L+r3/AMj/2Q=="},C={src:e.i(346512).default,width:16,height:16,blurWidth:0,blurHeight:0},O={src:e.i(84416).default,width:16,height:16,blurWidth:0,blurHeight:0},T={src:e.i(104602).default,width:16,height:16,blurWidth:0,blurHeight:0},k={src:e.i(771937).default,width:1e3,height:1e3,blurWidth:0,blurHeight:0},N={src:e.i(888193).default,width:16,height:16,blurWidth:0,blurHeight:0};var y=e.i(336712);let S={src:e.i(447500).default,width:26,height:26,blurWidth:0,blurHeight:0},R={src:e.i(270039).default,width:16,height:16,blurWidth:0,blurHeight:0},L={src:e.i(227733).default,width:16,height:16,blurWidth:0,blurHeight:0},U={src:e.i(823929).default,width:128,height:129,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAApklEQVR42oWPsQrCMBRFY51KaUuwNktBQbcgSenQ32hCTBAHXfSfulUK4g/0/7yvdO+FB5dzXhLC2FoiJE3TfZ7nYrskyzIBVpBjTdPcu677GGPGtm1fmDd1YnVd31gIYSrLUnLOjxC9tfaLfhBCXLz307xQVZUCODvnfljoceAEpskxKeUV1w0Qo1LqobV+Lk8McI5tkDiOeZIkO9SIBr0gRm71l38QASaqNz7VMwAAAABJRU5ErkJggg=="},H={src:e.i(333845).default,width:200,height:200,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAXUlEQVR42p2MoRHAMAwDQwJzCcgCwQEZIDjA03gED2BzewSPWRe2qFcB3Z+kU0o/lXNea4U/0t77OYeIACDq4FLKnSKimYmIqjKzu885U6117z3GCGitxTbg/flJF7DAEmcR3WAqAAAAAElFTkSuQmCC"},M={src:e.i(813878).default,width:16,height:16,blurWidth:0,blurHeight:0},B={src:e.i(767788).default,width:16,height:16,blurWidth:0,blurHeight:0},j={src:e.i(808630).default,width:16,height:16,blurWidth:0,blurHeight:0};var P=e.i(39182);let D={src:e.i(468732).default,width:490,height:412,blurWidth:0,blurHeight:0},G={src:e.i(610503).default,width:16,height:16,blurWidth:0,blurHeight:0},q={src:e.i(438969).default,width:16,height:16,blurWidth:0,blurHeight:0},W={src:e.i(852459).default,width:16,height:16,blurWidth:0,blurHeight:0},Q={src:e.i(494696).default,width:16,height:16,blurWidth:0,blurHeight:0},z={src:e.i(148973).default,width:16,height:16,blurWidth:0,blurHeight:0},F={src:e.i(570036).default,width:16,height:16,blurWidth:0,blurHeight:0},V={src:e.i(151170).default,width:95,height:81,blurWidth:8,blurHeight:7,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAYAAAA1WQxeAAAA0UlEQVR42kXMvWrCUBjG8VxIL6KX0IvobXQSOrQd2kLSdMzQdMmaEErPUqoIIYtKOC5iFD9BEBwiaAY/AgpH/2oUfOGFh4cfj8blNmrNKK0zmFUZzmust2nea7u9IlkNkBMPv1Xgs3JHoXRDe1o+g8Vmyl/vnf++wU/7EdF54jW8JU6K14WTPgE3fjiCZ77kPa2kdAZZlrFcLpikXYLeN6Lxxm/zhfEsRimF5roupmli2zbGh4Gu61iWlX8URWhSSsIwxPM8hBA4jpNn3/cJgoADqC23HJzwo6wAAAAASUVORK5CYII="},K={src:e.i(862330).default,width:646,height:854,blurWidth:0,blurHeight:0};var Y=e.i(980385);let J={src:e.i(788158).default,width:300,height:300,blurWidth:0,blurHeight:0},X={src:e.i(350567).default,width:231,height:30,blurWidth:0,blurHeight:0},Z={src:e.i(822797).default,width:48,height:48,blurWidth:0,blurHeight:0},$={src:e.i(840911).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABE0lEQVR42gEIAff+AAAAAAAAAAAAEQwmIT8ukIAgGUpBBwYQDQQECggAAAAAAAIBBQQJBhUTFw80LUIxloZbR8+5UUS3oUA4kH0HBxEOACMUUkolFlVNCAYTERwUPzgkHFJIIhxNRCsmYVQODSAbADYffnNFKaCSDgkgHD0tjX4+MI5+CQgVEhQSLCULChgUABAKJiJTM7+vJhlYTzEkb2MxJm9iIh1NQywnZFYhH0o/AA8JIh9RMrurNiR9cQkHFhMQDSUgUkW5o1hOx60pJlxPAAcEDw4qGmJYFw80LhENKCMyKHFjUEK0nhEOJSADAwYFAAAAAAADAgcGBQMLCRUPMClCNJeEIRtLQgAAAQAAAAAAfjQxsiCQipMAAAAASUVORK5CYII="},ee={src:e.i(445735).default,width:16,height:16,blurWidth:0,blurHeight:0},et={src:e.i(635202).default,width:16,height:16,blurWidth:0,blurHeight:0},er={src:e.i(669161).default,width:320,height:320,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7UlEQVR42lVQvc7BYBR+B/kM3w+fFm2p9m3fRhFRP7UQlTAQCVfAgE3EHZAQMTBIzBIrYbEgFhaza3ABrsF7bIYnOTl5/s5BVrvIY5MMvYTbUuy8hN8CcFIdW62CgHCKjFwie/So3PqH+b0Hc+GebkW6Lj9zUtJaHwEbFvGqWf7zOG5GJVmjcwUEAUOevQmhfKSTqJol+7f94RT+L7Yv25OV3PtsI699EByc85qpW5qcUCaMyB7orH9EgJLaTnPNgk/QfUsxKi0QtKWFzjRzA7a08IEPCivYKWkyQHAKtJUMPIVMQCAmz3FKHcELXnxEPy9E1lYCAAAAAElFTkSuQmCC"},ei={src:e.i(159508).default,width:52,height:46,blurWidth:0,blurHeight:0},ea={src:e.i(544025).default,width:3300,height:2550,blurWidth:8,blurHeight:6,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAAZklEQVR42oWNTQ5AMBhE3f8mEhux4BgiIRzAwoKWplrt146fBbVhkpnNvORF+El0jvMAV4RR2qtsJZD3DyA2h6xhiMsRSTUhrRm0DYBFE4qOI285yl5CGvdW0OEYhEE/G6jgvIGv7A4KupBwIVaNAAAAAElFTkSuQmCC"},el={src:e.i(708767).default,width:760,height:277,blurWidth:0,blurHeight:0},es={src:e.i(100588).default,width:146,height:139,blurWidth:0,blurHeight:0};e.s(["default",0,es],247044);let en={src:e.i(183804).default,width:100,height:18,blurWidth:0,blurHeight:0},eo={src:e.i(865502).default,width:32,height:32,blurWidth:0,blurHeight:0},eA={src:e.i(96912).default,width:16,height:16,blurWidth:0,blurHeight:0},ec={src:e.i(395073).default,width:16,height:16,blurWidth:0,blurHeight:0},ed={src:e.i(407829).default,width:16,height:16,blurWidth:0,blurHeight:0},eu={src:e.i(846077).default,width:64,height:64,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAo0lEQVR42lWOvQrCQBCE7718oUA6wVcQBF/AXhu1CIgcpgoi/qCNguBPwCaChYHDv9zt3e6ZeEFxq9n5GGaY/T8iq3QhWKFRkZGWzEPaaE/RDoiI5e7z0BILP7tMB2vyO3p2BJew8syvvJLGQTPEaheSVJeAQIi5F2+CWt80uHopLMEnNBpPuNc2vaXK+38A4RauTvUhbBNwDvsOlYD3DA2Se99kLK7hC5QFVQAAAABJRU5ErkJggg=="},eh={src:e.i(914861).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7ElEQVR42l2LMUsCAQBG39GFFQ02ad1oq0QIRR2hER4EGdQqdBDdQZAFEudU0NZSQ0O1VUOjiuJvEBxc3BQFEVQQdFAU9OROFwf9lg/e48Hiti8vWJekBSoIODacLK04CP79IAX8815cW2X3IYL3JIhaKuKLGdNGmMUCTo+Hq1yO72yB6HDEeTrFjm8fUVwGt3uL00eD5+6AfMvixbS5bTR5/43jcm2CooT4KNf56ltUGzafA5uoZZGpdJDlABhPr7z1TJLtMbXamMT0702T//aQu0gM5GOFvRuNkKoTDuucqRpeXePoWuPg0D8BGkpJjYhKXN4AAAAASUVORK5CYII="},eg={src:e.i(285328).default,width:400,height:399,blurWidth:8,blurHeight:8,blurDataURL:"data:image/webp;base64,UklGRgwBAABXRUJQVlA4TAABAAAvB8ABEM1VICICHggIDgIAAIDzDAACD0FoAAARAAwAAAAAAAAAAAAAAACAAABAAcBCAoAWgGyoXwUAAA8E7QQCAADg/N+nrsYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4CClZXkg5AQAAAAA538LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL0HIgEAAAAAcP4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMsHA39Qutr2AtkROu8CASWZ/nMlNyzz5AdgWmkK65oUI6AlgIkY/M3zxIW3iABq15KT/Uz7BXidCOONHieAz1v6HqAC"},em={src:e.i(779278).default,width:16,height:16,blurWidth:0,blurHeight:0},ep={src:e.i(325532).default,width:1e3,height:1e3,blurWidth:0,blurHeight:0},ef={src:e.i(288330).default,width:16,height:16,blurWidth:0,blurHeight:0};var ex=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cognition="Cognition",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GIGACHAT="GigaChat",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="Hosted vLLM",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.NVIDIA_RIVA="Nvidia Riva",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.Qwen_AI_Platform="Qwen AI Platform",t.QwenCloud="QwenCloud",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.SCX_AI="SCX.ai",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Local vLLM",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let eb={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cognition:"cognition",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GIGACHAT:"gigachat",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",NVIDIA_RIVA:"nvidia_riva",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",Qwen_AI_Platform:"qwen_ai_platform",QwenCloud:"qwencloud",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",SCX_AI:"scx-ai",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},ev=new Set(["bedrock_mantle"]),e_={"A2A Agent":n.src,Ai21:o.src,"Ai21 Chat":o.src,"AI/ML API":A.src,"Aiohttp Openai":Y.default.src,Anthropic:c.src,"Anthropic Text":c.src,AssemblyAI:d.src,Azure:P.default.src,"Azure AI Foundry (Studio)":P.default.src,"Azure Text":P.default.src,Baseten:u.src,"Amazon Bedrock":h.default.src,"Amazon Bedrock Mantle":h.default.src,"AWS SageMaker":h.default.src,Cerebras:g.src,Cloudflare:m.src,Codestral:G.src,Cohere:p.src,"Cohere Chat":p.src,Cometapi:f.src,Cursor:x.src,"Databricks (Qwen API)":b.src,Dashscope:$.src,Deepseek:E.src,Deepgram:v.src,DeepInfra:_.src,ElevenLabs:w.src,"Fal AI":I.src,"Featherless Ai":C.src,"Fireworks AI":O.src,Friendliai:T.src,GigaChat:k.src,"Github Copilot":N.src,"Google AI Studio":y.default.src,Groq:S.src,"Hosted vLLM":eu.src,Huggingface:R.src,Hyperbolic:L.src,Infinity:U.src,"Jina AI":H.src,"Lambda Ai":M.src,"Lm Studio":B.src,"Meta Llama":j.src,MiniMax:D.src,"Mistral AI":G.src,Moonshot:q.src,Morph:W.src,Nebius:Q.src,Novita:z.src,"Nvidia Nim":F.src,"Nvidia Riva":F.src,Ollama:K.src,"Ollama Chat":K.src,Oobabooga:Y.default.src,OpenAI:Y.default.src,"Openai Like":Y.default.src,"OpenAI Text Completion":Y.default.src,"OpenAI-Compatible Completions (legacy /v1/completions)":Y.default.src,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":Y.default.src,Openrouter:J.src,"Oracle Cloud Infrastructure (OCI)":X.src,Perplexity:Z.src,"Qwen AI Platform":$.src,QwenCloud:$.src,Recraft:ee.src,Replicate:et.src,RunwayML:er.src,Sagemaker:h.default.src,Sambanova:ei.src,"SAP Generative AI Hub":ea.src,"SCX.ai":el.src,Snowflake:es.src,Soniox:en.src,"Text-Completion-Codestral":G.src,TogetherAI:eo.src,Topaz:eA.src,Triton:V.src,V0:ec.src,"Vercel Ai Gateway":ed.src,"Vertex AI (Anthropic, Gemini, etc.)":y.default.src,"Vertex Ai Beta":y.default.src,"Local vLLM":eu.src,VolcEngine:eh.src,"Voyage AI":eg.src,Watsonx:em.src,"Watsonx Text":em.src,xAI:ep.src,Xinference:ef.src},eE={"AI/ML API":"aiml/flux-pro/v1.1",Anthropic:"claude-3-opus",Azure:"my-deployment","Azure AI Foundry (Studio)":"azure_ai/command-r-plus","Amazon Bedrock":"claude-3-opus",Cognition:"cognition/swe-1.7",Cursor:"cursor/claude-4-sonnet",DeepInfra:"deepinfra/","Fal AI":"fal_ai/fal-ai/flux-pro/v1.1-ultra","Google AI Studio":"gemini-pro","Jina AI":"jina_ai/","Nvidia Riva":"nvidia_riva/nvidia/parakeet-ctc-1_1b-asr","Oracle Cloud Infrastructure (OCI)":"oci/xai.grok-4",RunwayML:"runwayml/gen4_turbo","AWS SageMaker":"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b","SCX.ai":"scx-ai/GLM-5.2",Snowflake:"snowflake/mistral-7b","Vertex AI (Anthropic, Gemini, etc.)":"gemini-pro",VolcEngine:"volcengine/","Voyage AI":"voyage/",Watsonx:"watsonx/ibm/granite-3-3-8b-instruct","Z.AI (Zhipu AI)":"zai/glm-4.5"};e.s(["Providers",()=>ex,"getPlaceholder",0,e=>eE[ex[e]??e]??"gpt-3.5-turbo","getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:s(e_[e])??"",displayName:e}}let t=Object.keys(eb).find(t=>eb[t].toLowerCase()===e.toLowerCase())??Object.keys(eb).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let r=ex[t];return{logo:s(e_[r])??"",displayName:r}},"getProviderModels",0,(e,t)=>{let r=eb[e],i=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let a=t.litellm_provider,l="string"==typeof a&&(a.startsWith(`${r}_`)||a.startsWith(`${r}-`));(a===r||l&&!ev.has(a))&&i.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&i.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&i.push(e)})),i},"providerLogoMap",0,e_,"provider_map",0,eb],916925)},174553,e=>{"use strict";var t=e.i(843476),r=e.i(271645),i=e.i(916925),a=e.i(555987),l=e.i(196631);let s=/(?:\/assets\/logos\/|\/_next\/static\/media\/)/,n={"baseten.svg":"invert","cursor.svg":"invert","enkrypt_ai.avif":"invert","friendli.svg":"invert","github.svg":"invert","github_copilot.svg":"invert","lago.svg":"invert","lambda.svg":"invert","langflow.svg":"invert","lmstudio.svg":"invert","moonshot.svg":"invert","nebius.svg":"invert","notion.svg":"invert","ollama.svg":"invert","openrouter.svg":"invert","promptguard.svg":"invert","recraft.svg":"invert","replicate.svg":"invert","runway.png":"invert","scx_ai.svg":"invert","secret_detect.png":"invert","topaz.svg":"invert","v0.svg":"invert","vercel.svg":"invert","watsonx.svg":"invert","aiml_api.svg":"plate","akto.svg":"plate","aws.svg":"plate","deepkeep.svg":"plate","fireworks.svg":"plate","llm_guard.png":"plate","pangea.png":"plate","repelloai.png":"plate","sambanova.svg":"plate","sentry.svg":"plate","valkey.svg":"plate"},o={invert:"dark:[filter:brightness(0)_invert(1)]",plate:"dark:bg-logo-surface dark:object-contain dark:p-0.5"};e.s(["Logo",0,({provider:e,src:A,label:c,className:d="w-4 h-4"})=>{let[u,h]=(0,r.useState)(null),g=void 0!==e?(0,i.getProviderLogoAndName)(e).logo:(0,a.resolveLogoSrc)(A)??"",m=c??e??"";if(u===g||!g)return(0,t.jsx)("div",{className:`${d} rounded-full bg-border flex items-center justify-center text-xs`,children:m.charAt(0)||"-"});let p=(e=>{let t;if(!e||(0,a.isExternalAssetSrc)(e)||!s.test(e))return;let r=e.split(/[?#]/)[0].split("/").pop()||void 0,i=void 0===r||(t=r.split(".")).length<2?void 0:`${t[0]}.${t[t.length-1]}`;return void 0===i?void 0:n[i]})(g);return(0,t.jsx)("img",{src:g,alt:`${m||"-"} logo`,className:void 0===p?d:(0,l.cn)(d,o[p]),onError:()=>{console.warn(`Logo failed to load: ${g}`),h(g)}})}],174553)},531278,e=>{"use strict";var t=e.i(717521);e.s(["Loader2",()=>t.default])},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},871689,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeft",()=>t.default])},195116,e=>{"use strict";let t=(0,e.i(475254).default)("wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",key:"cbrjhi"}]]);e.s(["Wrench",0,t],195116)},269638,e=>{"use strict";let t=(0,e.i(475254).default)("circle-check-big",[["path",{d:"M21.801 10A10 10 0 1 1 17 3.335",key:"yps3ct"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]);e.s(["CheckCircle",0,t],269638)},292335,122520,165615,779129,280024,e=>{"use strict";let t={NONE:"none",API_KEY:"api_key",BEARER_TOKEN:"bearer_token",TOKEN:"token",BASIC:"basic",OAUTH2:"oauth2",OAUTH2_TOKEN_EXCHANGE:"oauth2_token_exchange",OAUTH2_ID_JAG:"oauth2_id_jag",AWS_SIGV4:"aws_sigv4",TRUE_PASSTHROUGH:"true_passthrough",OAUTH_DELEGATE:"oauth_delegate"},r=[{value:t.NONE,label:"None"},{value:t.API_KEY,label:"API Key"},{value:t.BEARER_TOKEN,label:"Bearer Token"},{value:t.TOKEN,label:"Token"},{value:t.BASIC,label:"Basic Auth"},{value:t.OAUTH2,label:"OAuth"},{value:t.OAUTH2_TOKEN_EXCHANGE,label:"OAuth Token Exchange (OBO)"},{value:t.OAUTH2_ID_JAG,label:"ID-JAG (Okta Cross App Access)"},{value:t.AWS_SIGV4,label:"AWS SigV4 (Bedrock AgentCore MCPs)"},{value:t.TRUE_PASSTHROUGH,label:"True Passthrough (no LiteLLM auth)"},{value:t.OAUTH_DELEGATE,label:"OAuth Delegate (client-supplied upstream token)"}],i=e=>e===t.TRUE_PASSTHROUGH||e===t.OAUTH_DELEGATE,a={INTERACTIVE:"interactive",M2M:"m2m"},l=e=>{let t=e.credentials??{};return JSON.stringify({url:"string"==typeof e.url?e.url:null,spec_path:"string"==typeof e.spec_path?e.spec_path:null,auth_type:e.auth_type??null,oauth_flow_type:e.oauth_flow_type??null,client_id:t.client_id??null,client_secret:t.client_secret??null,scopes:t.scopes??null,upstream_resource:t.upstream_resource??null,issuer:e.issuer??null,authorization_url:e.authorization_url??null,token_url:e.token_url??null,registration_url:e.registration_url??null})},s=["client_id","client_secret"],n=["upstream_resource","upstream_token_header"],o=["access_token","refresh_token","expires_in","scope"],A=(e,t)=>{if(!e)return;let r=Object.fromEntries(t.filter(t=>"string"==typeof e[t]&&""!==e[t]).map(t=>[t,e[t]]));return Object.keys(r).length>0?r:void 0},c="client_credentials",d={SSE:"sse",HTTP:"http",STDIO:"stdio",OPENAPI:"openapi"},u=[{value:d.HTTP,label:"Streamable HTTP (Recommended)"},{value:d.SSE,label:"Server-Sent Events (SSE)"},{value:d.STDIO,label:"Standard Input/Output (stdio)"},{value:d.OPENAPI,label:"OpenAPI Spec"}];e.s(["ADMIN_CONFIG_CREDENTIAL_KEYS",0,n,"AUTH_TYPE",0,t,"AUTH_TYPE_ITEMS",0,r,"CLEARED_ON_INVALIDATION",0,["credentials"],"MCP_OAUTH2_FLOW_INTERACTIVE",0,"authorization_code","MCP_OAUTH2_FLOW_M2M",0,c,"OAUTH_FLOW",0,a,"TRANSPORT",0,d,"TRANSPORT_ITEMS",0,u,"credentialAuthClass",0,e=>e===t.TRUE_PASSTHROUGH||e===t.OAUTH_DELEGATE?"client_forwarded":e??null,"gatewayMintsClientFor",0,e=>e.auth_type===t.TRUE_PASSTHROUGH||e.auth_type===t.OAUTH_DELEGATE&&!e.dcr_bridge,"getMcpOAuthMode",0,function(e){return e.auth_type===t.OAUTH2_TOKEN_EXCHANGE?"token_exchange":e.auth_type!==t.OAUTH2?null:e.oauth2_flow===c?"m2m":e.delegate_auth_to_upstream?"passthrough":"authorization_code"},"getOAuthAuthorizationIdentity",0,l,"handleAuth",0,e=>null==e?t.NONE:e,"handleTransport",0,(e,t)=>null==e?d.SSE:t&&e!==d.STDIO?d.OPENAPI:e,"isClientForwardedTokenMode",0,i,"isHeldOAuthTokenStale",0,(e,t)=>void 0!==t&&l(e)!==t,"isUnsupportedOnGatewayConnect",0,e=>i(e)||e===t.OAUTH2_TOKEN_EXCHANGE,"oauth2FlowToFormValue",0,function(e){return e===c?a.M2M:e?a.INTERACTIVE:void 0},"preservedAdminCredentials",0,e=>A(e,[...s,...n]),"preservedDeclaredAppCredentials",0,e=>A(e,s),"withoutMintedTokenCredentials",0,e=>{if(!e)return;let t=Object.fromEntries(Object.entries(e).filter(([e])=>!o.includes(e)));return Object.keys(t).length>0?t:void 0}],292335);var h=e.i(271645),g=e.i(602869),m=e.i(417385);function p(e){if(e instanceof Error)return e.message;if(e&&"object"==typeof e){let t=e.detail;return"string"==typeof t?t:Array.isArray(t)?t.map(e=>e&&"object"==typeof e?"string"==typeof e.msg?e.msg:JSON.stringify(e):String(e)).join("; "):t&&"object"==typeof t&&"string"==typeof t.error?t.error:"string"==typeof e.message?e.message:JSON.stringify(e)}return String(e)}e.s(["extractErrorMessage",0,p],122520);let f=e=>{let t=new Uint8Array(e),r="";return t.forEach(e=>r+=String.fromCharCode(e)),btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},x=()=>{let e=new Uint8Array(32);return window.crypto.getRandomValues(e),f(e.buffer)},b=async e=>{let t=new TextEncoder().encode(e);return f(await window.crypto.subtle.digest("SHA-256",t))};e.s(["generateCodeChallenge",0,b,"generateCodeVerifier",0,x],165615);var v=e.i(434166);let _=()=>{{let e=window.location.pathname||"",t=e.indexOf("/ui"),r=t>=0?e.slice(0,t+3).replace(/\/+$/,""):"";return`${window.location.origin}${r}/mcp/oauth/callback`}},E=(...e)=>{e.forEach(e=>{try{window.sessionStorage.removeItem(e)}catch(e){}})};e.s(["TOOLS_OAUTH_UI_STATE_KEY",0,"litellm-mcp-oauth-tools-state","buildCallbackUrl",0,_,"clearStorage",0,E],779129);let w="litellm-user-mcp-oauth-flow-state",I="litellm-user-mcp-oauth-result",C=(e,t)=>{(0,v.setSecureItem)(e,t)},O=e=>(0,v.getSecureItem)(e);e.s(["useUserMcpOAuthFlow",0,({accessToken:e,serverId:t,serverAlias:r,scopes:i,clientId:a,onSuccess:l})=>{let[s,n]=(0,h.useState)("idle"),[o,A]=(0,h.useState)(null),c=(0,h.useRef)(!1),d=(0,h.useCallback)(async()=>{try{let l;n("authorizing"),A(null);let s=a??void 0;if(!s)try{let i=await (0,g.registerMcpOAuthClient)(e,t,{client_name:r||t,grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"});s=i?.client_id,l=i?.client_secret}catch(e){}let o=x(),c=await b(o),d=crypto.randomUUID(),u=_(),h=i?.filter(e=>e.trim()).join(" "),m=(0,g.buildMcpOAuthAuthorizeUrl)({serverId:t,clientId:s,redirectUri:u,state:d,codeChallenge:c,scope:h}),p={state:d,codeVerifier:o,serverId:t,redirectUri:u,clientId:s,clientSecret:l,scopes:i};C(w,JSON.stringify(p));let f=new URL(window.location.href);f.searchParams.set("mcpOauthReturn","apps"),C("litellm-mcp-oauth-return-url",f.toString()),window.location.href=m}catch(t){let e=p(t);A(e),n("error"),m.toast.error(e)}},[e,t,r,i,a]),u=(0,h.useCallback)(async()=>{if(c.current)return;let r=O(I);if(!r)return;let i=O(w);if(!i)return;try{let e=JSON.parse(i);if(e.serverId&&e.serverId!==t)return}catch(e){}c.current=!0,E(I);let a=null,s=null;try{a=JSON.parse(r);let e=O(w);s=e?JSON.parse(e):null}catch(e){A("Failed to resume OAuth flow. Please retry."),n("error"),c.current=!1,E(w);return}try{if(!s?.state||!s.codeVerifier||!s.serverId)throw Error("OAuth session state was lost. Please retry.");if(!a?.state||a.state!==s.state)throw Error("OAuth state mismatch. Please retry.");if(a.error)throw Error(a.error_description||a.error);if(!a.code)throw Error("Authorization code missing in callback.");n("exchanging");let t=await (0,g.exchangeMcpOAuthToken)({serverId:s.serverId,code:a.code,clientId:s.clientId,clientSecret:s.clientSecret,codeVerifier:s.codeVerifier,redirectUri:s.redirectUri,accessToken:e});await (0,g.storeMCPOAuthUserCredential)(e,s.serverId,{access_token:t.access_token,refresh_token:t.refresh_token,expires_in:t.expires_in,scopes:s.scopes}),n("success"),A(null),m.toast.success("Connected successfully"),l()}catch(t){let e=p(t);A(e),n("error"),m.toast.error(e)}finally{E(w),setTimeout(()=>{c.current=!1},1e3)}},[e,t,l]);return(0,h.useEffect)(()=>{u()},[u]),{startOAuthFlow:d,status:s,error:o}}],280024)},21040,131913,e=>{"use strict";var t=e.i(843476),r=e.i(271645),i=e.i(266027),a=e.i(555436),l=e.i(871689),s=e.i(463059),n=e.i(195116),o=e.i(269638),A=e.i(531278),c=e.i(519455),d=e.i(793479),u=e.i(302747),h=e.i(677572),g=e.i(602869),m=e.i(292335),p=e.i(174553),f=e.i(417385),x=e.i(280024);let b=({server:e,accessToken:i,onConnect:a,variant:l="badge"})=>{let s=e.server_name??e.alias??e.server_id,{startOAuthFlow:n,status:o}=(0,x.useUserMcpOAuthFlow)({accessToken:i,serverId:e.server_id,serverAlias:s,onSuccess:(0,r.useCallback)(()=>a(e.server_id),[a,e.server_id])}),d="authorizing"===o||"exchanging"===o;return"button"===l?(0,t.jsxs)(c.Button,{onClick:n,disabled:d,className:"font-semibold h-[38px] min-w-[110px]",children:[d&&(0,t.jsx)(A.Loader2,{className:"h-4 w-4 animate-spin mr-1.5"}),d?"Connecting…":"Connect"]}):(0,t.jsx)("span",{onClick:e=>{e.stopPropagation(),d||n()},className:`text-[11px] font-semibold rounded-md px-2 py-0.5 shrink-0 whitespace-nowrap ${d?"text-muted-foreground bg-muted cursor-default":"text-primary-foreground bg-primary cursor-pointer hover:bg-primary/90"}`,children:d?"Connecting…":"Connect"})},v=["#1677ff","#52c41a","#fa8c16","#eb2f96","#722ed1","#13c2c2","#fa541c","#2f54eb","#a0d911","#faad14"];function _(e){let t=0;for(let r=0;r{let[w,I]=(0,r.useState)([]),[C,O]=(0,r.useState)(!0),[T,k]=(0,r.useState)(""),[N,y]=(0,r.useState)("all"),[S,R]=(0,r.useState)(new Set),[L,U]=(0,r.useState)(null),[H,M]=(0,r.useState)({}),[B,j]=(0,r.useState)(!1),[P,D]=(0,r.useState)(new Set),[G,q]=(0,r.useState)(new Set),W=(0,r.useRef)([]),Q=(0,r.useCallback)(e=>{W.current=e,I(e)},[]),z=(0,r.useRef)(x);(0,r.useEffect)(()=>{z.current=x},[x]);let F=(0,r.useRef)(v);(0,r.useEffect)(()=>{F.current=v},[v]);let V=e=>e.server_name??e.alias??e.server_id,K=w.find(e=>e.server_id===L),Y=(0,r.useCallback)(e=>E&&(0,m.isUnsupportedOnGatewayConnect)(e.auth_type)?"Not supported on this connection":null,[E]),J=(0,r.useCallback)(e=>{let t=W.current.find(t=>t.server_id===e);return void 0!==t&&null===Y(t)?t:void 0},[Y]),X=(0,r.useCallback)(async(t,r)=>{try{let i=await (0,g.listMCPTools)(e,t.server_id);if(!r())return;let a=Array.isArray(i?.tools)?i.tools:[];M(e=>({...e,[V(t)]:a.length}))}catch{}},[e]),Z=(0,r.useCallback)(async(t,r)=>{try{let i=await (0,g.getMCPOAuthUserCredentialStatus)(e,t.server_id);if(!r())return;i.has_credential&&!i.is_expired&&D(e=>new Set(e).add(t.server_id))}catch{}finally{r()&&q(e=>{let r=new Set(e);return r.delete(t.server_id),r})}},[e]);(0,r.useEffect)(()=>{let t=!0,r=()=>t;return(0,g.fetchMCPServers)(e,void 0,E).then(async e=>{if(!r())return;let t=Array.isArray(e)?e:e?.data??[],i=E?t.filter(e=>!1!==e.connected_app_reachable):t,a=i.filter(e=>e.auth_type===m.AUTH_TYPE.OAUTH2);for(let e of(Q(i),q(new Set(a.map(e=>e.server_id))),O(!1),a.forEach(e=>Z(e,r)),j(!0),Array.from({length:Math.ceil(i.length/5)},(e,t)=>i.slice(5*t,(t+1)*5)))){if(!r())return;await Promise.allSettled(e.map(e=>X(e,r)))}r()&&j(!1)}).catch(()=>{r()&&(Q([]),O(!1))}),()=>{t=!1}},[e,E,Q,X,Z]),(0,r.useEffect)(()=>{if(0===P.size)return;let e=W.current.filter(e=>P.has(e.server_id)&&!z.current.includes(V(e))&&null===Y(e)).map(V);e.length>0&&F.current([...z.current,...e])},[P,Y]);let $=async(t,r)=>{let i=V(t);if(!r){v(x.filter(e=>e!==i)),D(e=>{let r=new Set(e);return r.delete(t.server_id),r});return}if(void 0!==J(t.server_id)){R(e=>new Set(e).add(i));try{let r=await (0,g.listMCPTools)(e,t.server_id);if(r?.error)return void f.toast.warning(`Could not load tools for ${i}`);if(void 0===J(t.server_id))return;z.current.includes(i)||v([...z.current,i])}catch{f.toast.warning(`Could not load tools for ${i}`)}finally{R(e=>{let t=new Set(e);return t.delete(i),t})}}},{data:ee,isLoading:et}=(0,i.useQuery)({queryKey:["mcp-apps-panel-detail-tools",K?.server_id],queryFn:()=>(0,g.listMCPTools)(e,K.server_id),enabled:!!K}),er=Array.isArray(ee?.tools)?ee.tools:[],ei=w.filter(e=>{let t=V(e),r=!T.trim()||t.toLowerCase().includes(T.toLowerCase())||(e.description??"").toLowerCase().includes(T.toLowerCase()),i="all"===N||x.includes(t)&&null===Y(e);return r&&i}),ea=w.filter(e=>x.includes(V(e))&&null===Y(e)).length,el=Object.values(H).reduce((e,t)=>e+t,0);if(K){let r,i=V(K),a=x.includes(i),s=S.has(i),o=_(i);return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)(c.Button,{variant:"ghost",size:"sm",onClick:()=>U(null),className:"-ml-3 mb-5 gap-1.5 text-muted-foreground hover:text-foreground",children:[(0,t.jsx)(l.ArrowLeft,{className:"h-3 w-3"}),"Back"]}),(0,t.jsxs)("div",{className:"flex items-start gap-5 mb-7",children:[K.mcp_info?.logo_url?(0,t.jsx)(p.Logo,{src:K.mcp_info.logo_url,label:i,className:"w-16 h-16 rounded-2xl object-contain shrink-0 bg-muted/50"}):(0,t.jsx)("div",{className:"w-16 h-16 rounded-2xl flex items-center justify-center text-white font-bold text-[28px] shrink-0",style:{background:o},children:i.charAt(0).toUpperCase()}),(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("h2",{className:"m-0 mb-1 text-[22px] font-bold text-foreground",children:i}),(0,t.jsx)("p",{className:"m-0 text-sm text-muted-foreground",children:K.description??"MCP server"})]}),null!==(r=Y(K))?(0,t.jsx)("span",{className:"text-[13px] text-muted-foreground py-2.5 shrink-0",children:r}):K.auth_type!==m.AUTH_TYPE.OAUTH2?(0,t.jsxs)(c.Button,{variant:a?"outline":"default",disabled:s,onClick:()=>$(K,!a),className:"font-semibold h-[38px] min-w-[110px]",children:[s&&(0,t.jsx)(A.Loader2,{className:"h-4 w-4 animate-spin mr-1.5"}),a?"Disconnect":"Connect"]}):P.has(K.server_id)?(0,t.jsx)(c.Button,{variant:"destructive",onClick:async()=>{try{await (0,g.deleteMCPOAuthUserCredential)(e,K.server_id)}catch(e){}D(e=>{let t=new Set(e);return t.delete(K.server_id),t}),F.current(z.current.filter(e=>e!==i))},className:"font-semibold h-[38px] min-w-[110px]",children:"Disconnect"}):(0,t.jsx)(b,{server:K,accessToken:e,onConnect:e=>{D(t=>new Set(t).add(e))},variant:"button"})]}),(0,t.jsx)("h3",{className:"m-0 mb-3 text-[15px] font-semibold text-foreground",children:"Information"}),(0,t.jsx)("div",{className:"border rounded-lg overflow-hidden mb-7",children:[["Server ID",K.server_id],["Transport",(0,m.handleTransport)(K.transport,K.spec_path)],["Status",a?"Connected":"Not connected"]].filter(([,e])=>e).map(([e,r],i,a)=>(0,t.jsxs)("div",{className:`flex px-4 py-3 text-[13px] ${i(0,t.jsxs)("div",{className:"border rounded-lg px-3.5 py-2.5 bg-muted/30 flex flex-col gap-1.5",children:[(0,t.jsx)(u.Skeleton,{className:"h-3.5 w-1/3"}),(0,t.jsx)(u.Skeleton,{className:"h-3 w-2/3"})]},r))}):0===er.length?(0,t.jsx)("div",{className:"text-muted-foreground text-[13px] py-2",children:"No tools available"}):(0,t.jsx)("div",{className:"flex flex-col gap-2",children:er.map(e=>(0,t.jsxs)("div",{className:"border rounded-lg px-3.5 py-2.5 bg-muted/30",children:[(0,t.jsxs)("div",{className:`flex items-center gap-2 ${e.description?"mb-1":""}`,children:[(0,t.jsx)(n.Wrench,{className:"h-3.5 w-3.5 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-[13px] font-semibold text-foreground font-mono",children:e.name})]}),e.description&&(0,t.jsx)("p",{className:"m-0 text-xs text-muted-foreground pl-[21px]",children:e.description})]},e.name))})]})}return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-5 gap-4 flex-wrap",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-1",children:[(0,t.jsx)("h2",{className:"m-0 text-lg font-semibold text-foreground",children:"MCP Servers"}),!E&&(0,t.jsx)("span",{className:"text-[10px] font-semibold text-primary bg-primary/10 rounded px-1.5 py-0.5 uppercase tracking-wider",children:"Beta"})]}),E?(0,t.jsx)("p",{className:"m-0 text-[13px] text-muted-foreground",children:"Click a server to see its tools and connect"}):(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("p",{className:"m-0 text-[13px] text-muted-foreground",children:"Browse tools, authenticate once, use in chat"}),B?(0,t.jsxs)("span",{className:"flex items-center gap-1.5 text-xs text-muted-foreground",children:[(0,t.jsx)(A.Loader2,{className:"h-3 w-3 animate-spin"}),"Loading tools..."]}):el>0?(0,t.jsxs)("span",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[(0,t.jsx)(n.Wrench,{className:"h-3 w-3"}),el," tool",1!==el?"s":""," available"]}):null]})]}),(0,t.jsxs)("div",{className:"relative w-[220px]",children:[(0,t.jsx)(a.Search,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground"}),(0,t.jsx)(d.Input,{placeholder:"Search servers...",value:T,onChange:e=>k(e.target.value),className:"pl-9 text-[13px] h-9"})]})]}),(0,t.jsx)(h.Tabs,{value:N,onValueChange:e=>y(e),className:"mb-4",children:(0,t.jsxs)(h.TabsList,{variant:"line",className:"border-b rounded-none w-full justify-start h-auto p-0",children:[(0,t.jsx)(h.TabsTrigger,{value:"all",className:"rounded-none px-4 py-2 text-[13px]",children:"All"}),(0,t.jsxs)(h.TabsTrigger,{value:"connected",className:"rounded-none px-4 py-2 text-[13px]",children:["Connected",ea>0?` (${ea})`:""]})]})}),C?(0,t.jsx)("div",{className:"grid grid-cols-2 border rounded-lg overflow-hidden",children:Array.from({length:6},(e,r)=>(0,t.jsxs)("div",{className:`flex items-center gap-3 p-4 ${r%2==0?"border-r":""} ${r<4?"border-b":""}`,children:[(0,t.jsx)(u.Skeleton,{className:"w-[38px] h-[38px] rounded-xl shrink-0"}),(0,t.jsxs)("div",{className:"flex-1 min-w-0 flex flex-col gap-1.5",children:[(0,t.jsx)(u.Skeleton,{className:"h-3.5 w-2/3"}),(0,t.jsx)(u.Skeleton,{className:"h-3 w-1/2"})]})]},r))}):0===ei.length?(0,t.jsx)("div",{className:"text-center text-muted-foreground text-[13px] py-12 px-3",children:0===w.length?E?"No MCP servers are available to this connection yet. Ask an admin to grant your user or team access.":"No MCP servers configured. Add servers in Tools -> MCP Servers.":"connected"===N?"No servers connected yet.":"No servers match your search."}):(0,t.jsx)("div",{className:"grid grid-cols-2 border rounded-lg overflow-hidden",children:ei.map((r,i)=>{var a;let l,A=V(r),c=_(A),d=H[A],h=null!==Y(r);return(0,t.jsxs)("div",{onClick:()=>U(r.server_id),className:`flex items-center gap-3 p-4 bg-card cursor-pointer transition-colors hover:bg-accent/30 min-w-0 ${i%2==0?"border-r":""} ${Math.floor(i/2)0?(0,t.jsxs)("span",{className:"shrink-0 flex items-center gap-1 text-muted-foreground",children:["· ",(0,t.jsx)(n.Wrench,{className:"h-2.5 w-2.5"})," ",d]}):null:B?(0,t.jsx)(u.Skeleton,{className:"w-7 h-3 shrink-0"}):null]})]}),null!==(l=Y(a=r))?(0,t.jsx)("span",{className:"text-[11px] text-muted-foreground shrink-0 whitespace-nowrap",children:l}):a.auth_type===m.AUTH_TYPE.OAUTH2?P.has(a.server_id)?(0,t.jsx)(o.CheckCircle,{className:"h-3.5 w-3.5 text-success shrink-0"}):G.has(a.server_id)?(0,t.jsx)(u.Skeleton,{className:"h-6 w-16 shrink-0 rounded-md"}):(0,t.jsx)(b,{server:a,accessToken:e,onConnect:e=>D(t=>new Set(t).add(e)),variant:"badge"}):x.includes(V(a))?(0,t.jsx)("span",{className:"w-[7px] h-[7px] rounded-full bg-success shrink-0"}):null,(0,t.jsx)(s.ChevronRight,{className:"h-3 w-3 text-muted-foreground/40 shrink-0"})]},r.server_id)})})]})}],21040),e.s(["default",0,({flowHandle:e,clientOrigin:r})=>{let i=`${(0,g.getProxyBaseUrl)()}/authorize/complete`,a=r??"the application",l=function(e){if(!e)return!1;try{let t=new URL(e).hostname.replace(/^\[|\]$/g,"");return"localhost"===t||"::1"===t||/^127(\.\d{1,3}){3}$/.test(t)}catch{return!1}}(r);return(0,t.jsx)("div",{className:"mb-6 rounded-lg border border-primary/30 bg-primary/5 px-5 py-4",children:(0,t.jsxs)("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[(0,t.jsxs)("div",{className:"flex items-start gap-3 min-w-0",children:[(0,t.jsx)(o.CheckCircle,{className:"h-5 w-5 text-primary shrink-0 mt-0.5"}),(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsxs)("p",{className:"text-sm font-semibold text-foreground",children:["Connect your MCP servers to ",a]}),(0,t.jsxs)("p",{className:"text-[13px] text-muted-foreground mt-0.5",children:["Authorize the servers you want to use below, then click Finish connecting to return to ",a,"."]})]})]}),(0,t.jsxs)("form",{method:"POST",action:i,className:"shrink-0",children:[(0,t.jsx)("input",{type:"hidden",name:"flow",value:e}),(0,t.jsx)("button",{type:"submit",className:"h-[38px] rounded-md bg-primary px-4 text-sm font-semibold text-primary-foreground hover:bg-primary/90",children:"Finish connecting"}),l&&(0,t.jsxs)("label",{className:"mt-2 flex items-center gap-2 text-[13px] text-muted-foreground",children:[(0,t.jsx)("input",{type:"checkbox",name:"delivery",value:"manual"}),"My client is on a remote or SSH machine"]})]})]})})}],131913)},178971,e=>{"use strict";var t=e.i(843476),r=e.i(271645),i=e.i(618566),a=e.i(135214),l=e.i(21040),s=e.i(131913);function n(){let{accessToken:e}=(0,a.default)(),[n,o]=(0,r.useState)([]),A=(0,i.useRouter)(),c=(0,i.useSearchParams)(),d=c.get("mcpOauthReturn"),u=c.get("connect_flow"),h=c.get("connect_client");return(0,r.useEffect)(()=>{if(d){let e=new URL(window.location.href);e.searchParams.delete("mcpOauthReturn"),A.replace(e.pathname+e.search)}},[d,A]),(0,t.jsxs)("div",{className:"mx-auto w-full max-w-5xl px-8 py-8",children:[u&&(0,t.jsx)(s.default,{flowHandle:u,clientOrigin:h}),(0,t.jsx)(l.default,{accessToken:e??"",selectedServers:n,onChange:o,connectMode:!!u})]})}e.s(["default",0,function(){return(0,t.jsx)(r.Suspense,{children:(0,t.jsx)(n,{})})}])}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/03k5rtnvgsg9q.js b/litellm/proxy/_experimental/out/_next/static/chunks/03k5rtnvgsg9q.js
deleted file mode 100644
index 543f99a6732..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/03k5rtnvgsg9q.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,916940,e=>{"use strict";var t=e.i(843476),r=e.i(271645),l=e.i(602869),s=e.i(845150);e.s(["default",0,({onChange:e,value:a,className:n,accessToken:i,placeholder:o="Select vector stores",disabled:c=!1})=>{let[d,u]=(0,r.useState)([]),[m,h]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{(async()=>{if(i){h(!0);try{let e=await (0,l.vectorStoreListCall)(i);e.data&&u(e.data)}catch(e){console.error("Error fetching vector stores:",e)}finally{h(!1)}}})()},[i]),(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(s.MultiSelect,{placeholder:o,onValueChange:e,value:a,loading:m,className:n,disabled:c,options:d.map(e=>({label:`${e.vector_store_name||e.vector_store_id} (${e.vector_store_id})`,value:e.vector_store_id,description:e.vector_store_description||void 0}))})})}])},68155,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,r],68155)},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},871689,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeft",()=>t.default])},845150,e=>{"use strict";var t=e.i(843476),r=e.i(271645),l=e.i(131792);let s=(e,t)=>{let r=t.trim().toLowerCase();return!r||e.label.toLowerCase().includes(r)||e.value.toLowerCase().includes(r)||(e.description?.toLowerCase().includes(r)??!1)};e.s(["MultiSelect",0,function({id:e,options:a,value:n=[],onValueChange:i,placeholder:o="Select options",emptyText:c="No options found",disabled:d=!1,loading:u=!1,allowCustomValues:m=!1,className:h}){let p=(0,l.useComboboxAnchor)(),[x,f]=(0,r.useState)(""),g=a.filter(e=>null!=e&&"string"==typeof e.value&&e.value.length>0),v=n.filter(e=>"string"==typeof e&&e.length>0).map(e=>g.find(t=>t.value===e)??{label:e,value:e}),b=x.trim(),j=g.some(e=>e.value.toLowerCase()===b.toLowerCase()),w=m&&b&&!j?[...g,{label:`Create "${b}"`,value:b}]:g;return(0,t.jsxs)(l.Combobox,{multiple:!0,items:w,value:v,onValueChange:e=>{i(Array.from(new Set(m?e.flatMap(e=>n.includes(e.value)?[e.value]:e.value.split(",").map(e=>e.trim()).filter(e=>e.length>0)):e.map(e=>e.value)))),f("")},inputValue:x,onInputValueChange:f,isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:s,disabled:d||u,children:[(0,t.jsx)(l.ComboboxChips,{render:(0,t.jsx)("div",{ref:p}),className:`min-h-8 py-1 text-sm ${h??""}`,children:(0,t.jsx)(l.ComboboxValue,{children:r=>(0,t.jsxs)(t.Fragment,{children:[r.map(e=>(0,t.jsx)(l.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),(0,t.jsx)(l.ComboboxChipsInput,{id:e,placeholder:u?"Loading...":o,className:"min-w-24","aria-label":o||void 0}),r.length>0&&!d&&!u&&(0,t.jsx)(l.ComboboxClear,{className:"ml-auto self-center","aria-label":"Clear all"})]})})}),(0,t.jsxs)(l.ComboboxContent,{anchor:p,children:[(0,t.jsx)(l.ComboboxEmpty,{children:c}),(0,t.jsx)(l.ComboboxList,{children:e=>(0,t.jsx)(l.ComboboxItem,{value:e,disabled:e.disabled,children:(0,t.jsxs)("span",{className:"min-w-0",children:[(0,t.jsx)("span",{className:"block truncate",children:e.label}),e.description&&(0,t.jsx)("span",{className:"block truncate text-xs text-muted-foreground",children:e.description})]})},e.value)})]})]})}])},871943,502547,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,r],871943);let l=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"}))});e.s(["ChevronRightIcon",0,l],502547)},278587,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,r],278587)},384767,e=>{"use strict";var t=e.i(843476),r=e.i(271645);let l=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"}))});var s=e.i(487486),a=e.i(602869);let n=function({vectorStores:e,accessToken:n}){let[i,o]=(0,r.useState)([]);return(0,r.useEffect)(()=>{(async()=>{if(n&&0!==e.length)try{let e=await (0,a.vectorStoreListCall)(n);e.data&&o(e.data.map(e=>({vector_store_id:e.vector_store_id,vector_store_name:e.vector_store_name})))}catch(e){console.error("Error fetching vector stores:",e)}})()},[n,e.length]),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(l,{className:"h-4 w-4 text-info"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"Vector Stores"}),(0,t.jsx)(s.Badge,{variant:"secondary",children:e.length})]}),e.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:e.map((e,r)=>{let l;return(0,t.jsx)("div",{className:"inline-flex min-w-0 items-center px-3 py-1.5 rounded-lg bg-info/10 border border-info/20 text-info text-sm font-medium break-words",children:(l=i.find(t=>t.vector_store_id===e))?`${l.vector_store_name||l.vector_store_id} (${l.vector_store_id})`:e},r)})}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(l,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-muted-foreground text-sm",children:"No vector stores configured"})]})]})};var i=e.i(953960);let o=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"}))});var c=e.i(746798);let d=function({agents:e,agentAccessGroups:l=[],accessToken:n}){let[i,d]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{if(n&&e.length>0)try{let e=await (0,a.getAgentsList)(n);e&&e.agents&&Array.isArray(e.agents)&&d(e.agents)}catch(e){console.error("Error fetching agents:",e)}})()},[n,e.length]);let u=[...e.map(e=>({type:"agent",value:e})),...l.map(e=>({type:"accessGroup",value:e}))],m=u.length;return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(o,{className:"h-4 w-4 text-purple-600"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"Agents"}),(0,t.jsx)(s.Badge,{variant:"secondary",children:m})]}),m>0?(0,t.jsx)("div",{className:"max-h-[400px] overflow-y-auto space-y-2 pr-1",children:u.map((e,r)=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsx)("div",{className:"flex items-center gap-3 py-2 px-3 rounded-lg border border-border bg-card",children:(0,t.jsx)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:"agent"===e.type?(0,t.jsx)(c.TooltipProvider,{delay:300,children:(0,t.jsxs)(c.Tooltip,{children:[(0,t.jsxs)(c.TooltipTrigger,{render:(0,t.jsx)("div",{className:"inline-flex items-center gap-2 min-w-0"}),children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-purple-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:(e=>{let t=i.find(t=>t.agent_id===e);if(t){let r=e.length>7?`${e.slice(0,3)}...${e.slice(-4)}`:e;return`${t.agent_name} (${r})`}return e})(e.value)})]}),(0,t.jsx)(c.TooltipContent,{children:`Full ID: ${e.value}`})]})}):(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-success rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:e.value}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-success bg-success/10 border border-success/20 rounded-sm uppercase tracking-wide shrink-0",children:"Group"})]})})})},r))}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(o,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-muted-foreground text-sm",children:"No agents or access groups configured"})]})]})};e.s(["default",0,function({objectPermission:e,variant:r="card",className:l="",accessToken:s}){let a=e?.vector_stores||[],o=e?.mcp_servers||[],c=e?.mcp_access_groups||[],u=e?.mcp_tool_permissions||{},m=e?.mcp_toolsets||[],h=e?.agents||[],p=e?.agent_access_groups||[],x=e?.search_tools||[],f=(0,t.jsxs)("div",{className:"card"===r?"grid grid-cols-1 @xl:grid-cols-2 @4xl:grid-cols-3 gap-6":"space-y-4",children:[(0,t.jsx)(n,{vectorStores:a,accessToken:s}),(0,t.jsx)(i.default,{mcpServers:o,mcpAccessGroups:c,mcpToolPermissions:u,mcpToolsets:m,accessToken:s}),(0,t.jsx)(d,{agents:h,agentAccessGroups:p,accessToken:s}),(0,t.jsxs)("div",{className:"min-w-0 rounded-md border border-border p-4",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Search tools"}),0===x.length?(0,t.jsx)("p",{className:"mt-1 block text-xs text-muted-foreground",children:"No restriction — all configured search tools are allowed for this team."}):(0,t.jsx)("p",{className:"mt-1 block text-xs break-words text-foreground",children:x.join(", ")})]})]});return"card"===r?(0,t.jsxs)("div",{className:`@container bg-card border border-border rounded-lg p-6 ${l}`,children:[(0,t.jsx)("div",{className:"flex items-center gap-2 mb-6",children:(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"font-semibold text-foreground",children:"Object Permissions"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Access control for Vector Stores and MCP Servers"})]})}),f]}):(0,t.jsxs)("div",{className:`${l}`,children:[(0,t.jsx)("p",{className:"font-medium text-foreground mb-3",children:"Object Permissions"}),f]})}],384767)},438847,e=>{"use strict";var t=e.i(916108),r=e.i(487315),l=e.i(280862),s=e.i(271645);function a(e,t,l){try{return e(t)}catch(e){return l?(0,r.i)(25,t,e,l):(0,r.i)(24,t,e),null}}function n(e){function t(t){if(void 0===t)return null;let r="";if(Array.isArray(t)){if(void 0===t[0])return null;r=t[0]}return"string"==typeof t&&(r=t),a(e.parse,r)}return{type:"single",eq:(e,t)=>e===t,...e,parseServerSide:t,withDefault(e){return{...this,defaultValue:e,parseServerSide:r=>t(r)??e}},withOptions(e){return{...this,...e}}}}let i=n({parse:e=>e,serialize:String}),o=n({parse:e=>{let t=parseInt(e);return t==t?t:null},serialize:e=>""+Math.round(e)});function c(e,t){return e.valueOf()===t.valueOf()}n({parse:e=>{let t=parseInt(e);return t==t?t-1:null},serialize:e=>""+Math.round(e+1)}),n({parse:e=>{let t=parseInt(e,16);return t==t?t:null},serialize:e=>{let t=Math.round(e).toString(16);return t<"0"||!(1&t.length)?t:"0"+t}}),n({parse:e=>{let t=parseFloat(e);return t==t?t:null},serialize:String}),n({parse:e=>"true"===e.toLowerCase(),serialize:String}),n({parse:e=>{let t=new Date(parseInt(e));return t.valueOf()==t.valueOf()?t:null},serialize:e=>""+e.valueOf(),eq:c}),n({parse:e=>{let t=new Date(e);return t.valueOf()==t.valueOf()?t:null},serialize:e=>e.toISOString(),eq:c}),n({parse:e=>{let t=new Date(e.slice(0,10));return t.valueOf()==t.valueOf()?t:null},serialize:e=>e.toISOString().slice(0,10),eq:c});let d=(0,l.o)("sync-emitter",()=>(0,t.i)()),u={},m=(e,t)=>"defaultValue"===e?void 0:t;function h(e,a={}){let n=(0,s.useId)(),i=(0,l.i)(),o=(0,l.a)(),{history:c=i?.history??"replace",scroll:f=i?.scroll??!1,shallow:g=i?.shallow??!0,throttleMs:v=t.l.timeMs,limitUrlUpdates:b=i?.limitUrlUpdates,clearOnDefault:j=i?.clearOnDefault??!0,startTransition:w,urlKeys:y=u}=a,C=Object.keys(e).join(","),N=(0,s.useRef)(e),k=N.current,S=JSON.stringify(Object.entries(k),m)===JSON.stringify(Object.entries(e),m)&&Object.entries(e).every(([e,t])=>{let r=k[e]?.defaultValue,l=t.defaultValue;return!!Object.is(r,l)||void 0!==r&&void 0!==l&&t.eq?.(r,l)===!0})?k:e;N.current=S;let _=(0,s.useMemo)(()=>Object.fromEntries(Object.keys(e).map(e=>[e,y[e]??e])),[C,JSON.stringify(y)]),O=(0,l.r)(Object.values(_)),T=O.searchParams,M=(0,s.useRef)({}),E=(0,s.useRef)(null),L=(0,s.useRef)(null),I=(0,t.n)(Object.values(_)),[A,z]=(0,s.useState)(()=>p(e,y,T,I).state),V=(0,s.useRef)(A),R=Object.values(_).map(e=>`${e}=${T.getAll(e)}`).join("&")+JSON.stringify(I),D=()=>{let{state:t,hasChanged:l}=p(e,y,T,I,M.current,V.current);return l&&((0,r.t)(1,n,C,t),V.current=t,z(t)),l},U=Object.keys(M.current).join("&")!==Object.values(_).join("&"),F=null===L.current||L.current===(O.pathname??location.pathname),P=!1;(U||F&&E.current!==R)&&(E.current=R,P=D(),U&&(M.current=Object.fromEntries(Object.entries(_).map(([t,r])=>[r,e[t]?.type==="multi"?T.getAll(r):T.get(r)??null])))),U||P||!F||A===V.current||z(V.current),(0,s.useEffect)(()=>{L.current=O.pathname??location.pathname,D()},[R,O.pathname]),(0,s.useEffect)(()=>{let t=Object.keys(e).reduce((t,l)=>(t[l]=({state:t,query:s})=>{z(a=>{let i=_[l];return Object.is(a[l]??null,t)?((0,r.t)(2,n,C,i,t,e[l]?.defaultValue,V.current),a):(V.current={...V.current,[l]:t},M.current[i]=s,(0,r.t)(3,n,C,i,t,e[l]?.defaultValue,V.current),V.current)})},t),{});for(let l of Object.keys(e)){let e=_[l];(0,r.t)(4,n,e,C),d.on(e,t[l])}return()=>{for(let l of Object.keys(e)){let e=_[l];(0,r.t)(5,n,e,C),d.off(e,t[l])}}},[C,_]);let B=(0,s.useCallback)((e,l={})=>{let s,a=Object.fromEntries(Object.keys(S).map(e=>[e,null])),i="function"==typeof e?e(x(V.current,S))??a:e??a;(0,r.t)(6,n,C,i);let u=0,m=!1,h=[];for(let[e,r]of Object.entries(i)){let a=S[e],n=_[e];if(!a||void 0===n||void 0===r)continue;(l.clearOnDefault??a.clearOnDefault??j)&&null!==r&&void 0!==a.defaultValue&&(a.eq??((e,t)=>e===t))(r,a.defaultValue)&&(r=null);let i=null===r?null:(a.serialize??String)(r);d.emit(n,{state:r,query:i});let p={key:n,query:i,options:{history:l.history??a.history??c,shallow:l.shallow??a.shallow??g,scroll:l.scroll??a.scroll??f,startTransition:l.startTransition??a.startTransition??w}},x=l.limitUrlUpdates??a.limitUrlUpdates??b;if(x?.method==="debounce"){let e=x.timeMs??t.l.timeMs,r=t.t.push(p,e,O,o);ut(e),m?t.r.flush(O,o):t.r.getPendingPromise(O));return s??p},[C,c,g,f,v,b?.method,b?.timeMs,w,j,S,_,O.updateUrl,O.getSearchParamsSnapshot,O.rateLimitFactor,o]);return[(0,s.useMemo)(()=>x(A,S),[A,S]),B]}function p(e,r,l,s,n,i){let o=!1,c=Object.entries(e).reduce((e,[c,d])=>{var u;let m=r?.[c]??c,h=s[m],p="multi"===d.type?[]:null,x=void 0===h?("multi"===d.type?l.getAll(m):l.get(m))??p:h;return n&&i&&((u=n[m]??p)===x||null!==u&&null!==x&&"string"!=typeof u&&"string"!=typeof x&&u.length===x.length&&u.every((e,t)=>e===x[t]))?e[c]=i[c]??null:(o=!0,e[c]=((0,t.o)(x)?null:a(d.parse,x,m))??null,n&&(n[m]=x)),e},{});if(!o){let t=Object.keys(e),r=Object.keys(i??{});o=t.length!==r.length||t.some(e=>!r.includes(e))}return{state:c,hasChanged:o}}function x(e,t){return Object.fromEntries(Object.keys(e).map(r=>[r,e[r]??t[r]?.defaultValue??null]))}e.s(["parseAsInteger",0,o,"parseAsString",0,i,"useQueryState",0,function(e,t={}){let{parse:r,type:l,serialize:a,eq:n,defaultValue:i,...o}=t,[{[e]:c},d]=h({[e]:{parse:r??(e=>e),type:l,serialize:a,eq:n,defaultValue:i}},o);return[c,(0,s.useCallback)((t,r={})=>d(r=>({[e]:"function"==typeof t?t(r[e]):t}),r),[e,d])]},"useQueryStates",0,h],438847)},738014,e=>{"use strict";var t=e.i(135214),r=e.i(602869),l=e.i(266027);let s=(0,e.i(243652).createQueryKeys)("users");e.s(["useCurrentUser",0,()=>{let{accessToken:e,userId:a}=(0,t.default)();return(0,l.useQuery)({queryKey:s.detail(a),queryFn:async()=>await (0,r.userGetInfoV2)(e),enabled:!!(e&&a)})}])},162386,e=>{"use strict";var t=e.i(843476),r=e.i(625901),l=e.i(109799),s=e.i(785242),a=e.i(738014),n=e.i(131792),i=e.i(302747),o=e.i(746798);let c={label:"All Proxy Models",value:"all-proxy-models"},d={label:"No Default Models",value:"no-default-models"},u=[c,d],m={user:({allProxyModels:e,userModels:t,options:r})=>t&&r?.includeUserModels?t:[],team:({allProxyModels:e,selectedOrganization:t,userModels:r})=>t?t.models.includes(c.value)||0===t.models.length?e:e.filter(e=>t.models.includes(e)):e??[],organization:({allProxyModels:e})=>e,global:({allProxyModels:e})=>e};e.s(["MODEL_SENTINEL_OPTIONS",0,u,"ModelSelect",0,e=>{let h=(0,n.useComboboxAnchor)(),{id:p,teamID:x,organizationID:f,options:g,context:v,dataTestId:b,value:j=[],onChange:w,style:y}=e,{showAllProxyModelsOverride:C,includeSpecialOptions:N}=g||{},{data:k,isLoading:S}=(0,r.useAllProxyModels)(),{data:_,isLoading:O}=(0,s.useTeam)(x),{data:T,isLoading:M}=(0,l.useOrganization)(f),{data:E,isLoading:L}=(0,a.useCurrentUser)(),I=e=>u.some(t=>t.value===e),A=j.some(I),z=T?.models.includes(c.value)||T?.models.length===0;if(S||O||M||L)return(0,t.jsx)(i.Skeleton,{className:"h-9 w-full"});let{wildcard:V,regular:R}=(e=>{let t=[],r=[];for(let l of e)l.endsWith("/*")?t.push(l):r.push(l);return{wildcard:t,regular:r}})(((e,t,r)=>{let l=Array.from(new Map(e.map(e=>[e.id,e])).values()).map(e=>e.id);if(t.options?.showAllProxyModelsOverride)return l;let s=m[t.context];return s?s({allProxyModels:l,...r,options:t.options}):[]})(k?.data??[],e,{selectedTeam:_,selectedOrganization:T,userModels:E?.models})),D=[...N?[{label:"Special Options",items:[...C||z&&N||"global"===v?[{label:c.label,value:c.value,disabled:j.length>0&&j.some(e=>I(e)&&e!==c.value)}]:[],{label:d.label,value:d.value,disabled:j.length>0&&j.some(e=>I(e)&&e!==d.value)}]}]:[],...V.length>0?[{label:"Wildcard Options",items:V.map(e=>{let t=e.replace("/*",""),r=t.charAt(0).toUpperCase()+t.slice(1);return{label:`All ${r} models`,value:e,disabled:A}})}]:[],{label:"Models",items:R.map(e=>({label:e,value:e,disabled:A}))}],U=new Map(D.flatMap(e=>e.items).map(e=>[e.value,e])),F=j.map(e=>U.get(e)??{label:e,value:e}),P=F.slice(5);return(0,t.jsx)(o.TooltipProvider,{children:(0,t.jsxs)(n.Combobox,{multiple:!0,items:D,value:F,onValueChange:e=>{let t=e.map(e=>e.value),r=t.filter(I);w(r.length>0?[r[r.length-1]]:t)},isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,children:[(0,t.jsxs)(n.ComboboxChips,{render:(0,t.jsx)("div",{ref:h}),"data-testid":b,style:y,className:"w-full",children:[(0,t.jsx)(n.ComboboxValue,{children:e=>(0,t.jsxs)(t.Fragment,{children:[e.slice(0,5).map(e=>(0,t.jsx)(n.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),P.length>0&&(0,t.jsxs)(o.Tooltip,{children:[(0,t.jsx)(o.TooltipTrigger,{render:(0,t.jsx)("span",{className:"px-1 text-xs text-muted-foreground"}),children:`+${P.length} more`}),(0,t.jsx)(o.TooltipContent,{children:P.map(e=>e.value).join(", ")})]})]})}),(0,t.jsx)(n.ComboboxChipsInput,{id:p,placeholder:"Select Models","aria-label":"Select Models",className:"min-w-24"})]}),(0,t.jsxs)(n.ComboboxContent,{anchor:h,children:[(0,t.jsx)(n.ComboboxEmpty,{children:"No models found"}),(0,t.jsx)(n.ComboboxList,{children:e=>(0,t.jsxs)(n.ComboboxGroup,{items:e.items,children:[(0,t.jsx)(n.ComboboxLabel,{children:e.label}),(0,t.jsx)(n.ComboboxCollection,{children:e=>(0,t.jsx)(n.ComboboxItem,{value:e,disabled:e.disabled,children:(0,t.jsx)("span",{className:"min-w-0 break-words",children:e.label})},e.value)})]},e.label)})]})]})})}],162386)},360820,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 15l7-7 7 7"}))});e.s(["ChevronUpIcon",0,r],360820)},434626,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"}))});e.s(["ExternalLinkIcon",0,r],434626)},902555,e=>{"use strict";var t=e.i(843476),r=e.i(746798),l=e.i(271645);let s=l.forwardRef(function(e,t){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"}))}),a=l.forwardRef(function(e,t){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"}),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M21 12a9 9 0 11-18 0 9 9 0 0118 0z"}))});var n=e.i(278587),i=e.i(68155),o=e.i(360820),c=e.i(871943),d=e.i(434626);let u=l.forwardRef(function(e,t){return l.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),l.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"}))});var m=e.i(196631);function h({icon:e,onClick:r,className:l,disabled:s,dataTestId:a}){return s?(0,t.jsx)("span",{className:"inline-flex shrink-0 cursor-not-allowed items-center justify-center p-1.5 opacity-50","data-testid":a,children:(0,t.jsx)(e,{className:"size-5 shrink-0"})}):(0,t.jsx)("span",{className:(0,m.cx)("inline-flex shrink-0 cursor-pointer items-center justify-center p-1.5",l),onClick:r,"data-testid":a,children:(0,t.jsx)(e,{className:"size-5 shrink-0"})})}let p={Edit:{icon:s,className:"hover:text-info"},Delete:{icon:i.TrashIcon,className:"hover:text-destructive"},Test:{icon:a,className:"hover:text-info"},Regenerate:{icon:n.RefreshIcon,className:"hover:text-success"},Up:{icon:o.ChevronUpIcon,className:"hover:text-info"},Down:{icon:c.ChevronDownIcon,className:"hover:text-info"},Open:{icon:d.ExternalLinkIcon,className:"hover:text-success"},Copy:{icon:u,className:"hover:text-info"}};e.s(["default",0,function({onClick:e,tooltipText:l,disabled:s=!1,disabledTooltipText:a,dataTestId:n,variant:i}){let{icon:o,className:c}=p[i],d=s?a:l,u=(0,t.jsx)(h,{icon:o,onClick:e,className:c,disabled:s,dataTestId:n});return d?(0,t.jsx)(r.TooltipProvider,{children:(0,t.jsxs)(r.Tooltip,{children:[(0,t.jsx)(r.TooltipTrigger,{render:(0,t.jsx)("span",{}),children:u}),(0,t.jsx)(r.TooltipContent,{children:d})]})}):(0,t.jsx)("span",{children:u})}],902555)},695420,e=>{"use strict";var t=e.i(271645);e.s(["useVisitedTabs",0,function(e){let[r,l]=(0,t.useState)(()=>new Set([e]));return{onTabChange:(0,t.useCallback)(e=>{l(t=>new Set(t).add(String(e)))},[]),hasVisited:(0,t.useCallback)(e=>r.has(e),[r])}}])},294612,e=>{"use strict";var t=e.i(843476),r=e.i(746798);e.i(622826);var l=e.i(112179),s=e.i(519455),a=e.i(784774),n=e.i(243553),i=e.i(952571),o=e.i(284614),c=e.i(879002),d=e.i(902555);let u="sticky right-0 w-[120px] bg-background";e.s(["default",0,function({members:e,canEdit:m,onEdit:h,onDelete:p,onAddMember:x,roleColumnTitle:f="Role",roleTooltip:g,extraColumns:v=[],showDeleteForMember:b,emptyText:j}){return(0,t.jsxs)("div",{className:"flex w-full flex-col gap-2",children:[(0,t.jsxs)("span",{className:"inline-flex text-sm text-foreground",children:[e.length," Member",1!==e.length?"s":""]}),(0,t.jsxs)(a.Table,{children:[(0,t.jsx)(a.TableHeader,{children:(0,t.jsxs)(a.TableRow,{children:[(0,t.jsx)(a.TableHead,{children:"User Email"}),(0,t.jsx)(a.TableHead,{children:"User ID"}),(0,t.jsx)(a.TableHead,{children:g?(0,t.jsxs)("span",{className:"inline-flex items-center gap-2",children:[f,(0,t.jsx)(r.SimpleTooltip,{content:g,children:(0,t.jsx)(i.Info,{className:"size-3.5"})})]}):f}),v.map(e=>(0,t.jsx)(a.TableHead,{children:e.title},e.key)),(0,t.jsx)(a.TableHead,{className:u,children:"Actions"})]})}),(0,t.jsx)(a.TableBody,{children:0===e.length?(0,t.jsx)(a.TableRow,{children:(0,t.jsx)(a.TableCell,{colSpan:v.length+4,className:"text-center text-muted-foreground",children:j??"No data"})}):e.map((e,r)=>(0,t.jsxs)(a.TableRow,{children:[(0,t.jsx)(a.TableCell,{children:e.user_email||"-"}),(0,t.jsx)(a.TableCell,{children:"default_user_id"===e.user_id?(0,t.jsx)(l.StatusBadge,{tone:"info",label:"Default Proxy Admin"}):e.user_id||"-"}),(0,t.jsx)(a.TableCell,{children:(0,t.jsxs)("span",{className:"inline-flex items-center gap-2",children:[e.role?.toLowerCase()==="admin"||e.role?.toLowerCase()==="org_admin"?(0,t.jsx)(n.Crown,{className:"size-3.5"}):(0,t.jsx)(o.User,{className:"size-3.5"}),(0,t.jsx)("span",{className:"capitalize",children:e.role||"-"})]})}),v.map(l=>{let s;return(0,t.jsx)(a.TableCell,{children:(s=l.dataIndex?e[l.dataIndex]:void 0,l.render?l.render(s,e,r):s)},l.key)}),(0,t.jsx)(a.TableCell,{className:u,children:m?(0,t.jsxs)("span",{className:"inline-flex items-center gap-2",children:[(0,t.jsx)(d.default,{variant:"Edit",tooltipText:"Edit member",dataTestId:"edit-member",onClick:()=>h(e)}),(!b||b(e))&&(0,t.jsx)(d.default,{variant:"Delete",tooltipText:"Delete member",dataTestId:"delete-member",onClick:()=>p(e)})]}):null})]},e.user_id??e.user_email??JSON.stringify(e)))})]}),x&&m&&(0,t.jsxs)(s.Button,{onClick:x,className:"self-start",children:[(0,t.jsx)(c.UserPlus,{className:"size-4"}),"Add Member"]})]})}])},907308,276173,e=>{"use strict";var t=e.i(843476),r=e.i(271645),l=e.i(952571),s=e.i(879002),a=e.i(204290),n=e.i(929592),i=e.i(653145),o=e.i(602869),c=e.i(542450),d=e.i(182668),u=e.i(744582),m=e.i(519455),h=e.i(776639),p=e.i(967489),x=e.i(746798),f=e.i(571303);e.s(["default",0,({isVisible:e,onCancel:g,onSubmit:v,accessToken:b,title:j="Add Team Member",roles:w=[{label:"admin",value:"admin",description:"Admin role. Can create team keys, add members, and manage settings."},{label:"user",value:"user",description:"User role. Can view team info, but not manage it."}],defaultRole:y="user",teamId:C})=>{let N={user_email:void 0,user_id:void 0,role:y},k=(0,i.useForm)({defaultValues:N}),[S,_]=(0,r.useState)([]),[O,T]=(0,r.useState)(!1),[M,E]=(0,r.useState)("user_email"),[L,I]=(0,r.useState)(!1),A=(0,r.useRef)(0),z=async(e,t)=>{let r=A.current+1;if(A.current=r,!e){_([]),T(!1);return}T(!0);try{let l=new URLSearchParams;if(l.append(t,e),C&&l.append("team_id",C),null==b)return;let s=await (0,o.userFilterUICall)(b,l);if(r!==A.current)return;let a=s.map(e=>({label:"user_email"===t?`${e.user_email}`:`${e.user_id}`,value:"user_email"===t?e.user_email:e.user_id,user:e}));_(a)}catch(e){console.error("Error fetching users:",e)}finally{r===A.current&&T(!1)}},V=async e=>{I(!0);try{await v(e)}finally{I(!1)}},R=e=>{"Enter"===e.key&&e.preventDefault()},D=(e,r,l,s)=>{let a=M===e?S:[];return(0,t.jsx)("div",{"data-testid":s,onKeyDown:R,children:(0,t.jsx)(u.PaginatedSearchSelect,{options:a,value:l.value,onValueChange:e=>{var t;l.onChange(""===e?void 0:e),t=a.find(t=>t.value===e)??null,t?.user!=null&&(k.setValue("user_email",t.user.user_email),k.setValue("user_id",t.user.user_id))},onSearchChange:t=>{E(e),z(t,e)},autoHighlight:"always",isLoading:O,placeholder:r,emptyText:"No results",loadingText:"Loading...",inputId:l.id})})};return(0,t.jsx)(h.Dialog,{open:e,onOpenChange:e=>!e&&void(k.reset(N),_([]),g()),disablePointerDismissal:L,children:(0,t.jsxs)(h.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,t.jsx)(h.DialogHeader,{children:(0,t.jsx)(h.DialogTitle,{children:j})}),(0,t.jsx)(x.TooltipProvider,{children:(0,t.jsxs)("form",{onSubmit:k.handleSubmit(V),noValidate:!0,children:[(0,t.jsxs)(a.Alert,{variant:"info",className:"mb-4","data-testid":"member-existing-users-notice",children:[(0,t.jsx)(l.Info,{}),(0,t.jsx)(n.AlertTitle,{children:"Search selects from users that already exist. To add someone new, ask a proxy admin to create their account first."})]}),(0,t.jsxs)(c.FieldGroup,{children:[(0,t.jsx)(d.FormField,{control:k.control,name:"user_email",label:"Email",children:({id:e,value:t,onChange:r})=>D("user_email","Search by email",{id:e,value:t,onChange:r},"member-email-search")}),(0,t.jsx)("div",{className:"text-center",children:"OR"}),(0,t.jsx)(d.FormField,{control:k.control,name:"user_id",label:"User ID",children:({id:e,value:t,onChange:r})=>D("user_id","Search by user ID",{id:e,value:t,onChange:r})}),(0,t.jsx)(d.FormField,{control:k.control,name:"role",label:"Member Role",children:({id:e,value:r,onChange:l})=>(0,t.jsxs)(p.Select,{items:w,value:r,onValueChange:e=>l(e),children:[(0,t.jsx)(p.SelectTrigger,{id:e,children:(0,t.jsx)(p.SelectValue,{})}),(0,t.jsx)(p.SelectContent,{children:w.map(e=>(0,t.jsx)(p.SelectItem,{value:e.value,children:(0,t.jsxs)(x.Tooltip,{children:[(0,t.jsx)(x.TooltipTrigger,{render:(0,t.jsxs)("span",{children:[(0,t.jsx)("span",{className:"font-medium",children:e.label}),(0,t.jsxs)("span",{className:"ml-2 text-sm text-muted-foreground",children:["- ",e.description]})]})}),(0,t.jsx)(x.TooltipContent,{children:e.description})]})},e.value))})]})})]}),(0,t.jsx)("div",{className:"mt-4 text-right",children:(0,t.jsxs)(m.Button,{type:"submit",disabled:L,children:[L?(0,t.jsx)(f.UiLoadingSpinner,{className:"size-4"}):(0,t.jsx)(s.UserPlus,{}),L?"Adding...":"Add Member"]})})]})})]})})}],907308);var g=e.i(681307),v=e.i(435451),b=e.i(860585),j=e.i(845150),w=e.i(793479),y=e.i(991326);let C=new Set(["max_budget_in_team","tpm_limit","rpm_limit"]),N=e=>[...e.showEmail?["user_email"]:[],...e.showUserId?["user_id"]:[],"role",...(e.additionalFields??[]).map(e=>e.name)],k=(e,t)=>Object.fromEntries(N(e).map(e=>[e,t[e]])),S=e=>{let t=new Map((e.additionalFields??[]).map(e=>[e.name,e.type]));return Object.fromEntries(N(e).map(e=>[e,(e=>{switch(e){case"multi-select":return[];case"numerical":case"budget-duration":return null;default:return""}})(t.get(e))]))},_="Please select a role!",O=e=>""===e||g.z.email().safeParse(e).success,T=g.z.union([g.z.string(),g.z.number(),g.z.null(),g.z.array(g.z.string())]).optional();e.s(["default",0,({visible:e,onCancel:l,onSubmit:s,initialData:a,mode:n,config:i})=>{let o,u=(0,r.useMemo)(()=>{let e;return e={user_email:g.z.string().refine(O,"Please enter a valid email!").nullish(),user_id:g.z.string().nullish(),role:g.z.string({error:_}).min(1,_),...Object.fromEntries((i.additionalFields??[]).map(e=>[e.name,T]))},g.z.object(e)},[i]),x=(0,y.useZodForm)(u,{defaultValues:S(i)}),[N,M]=(0,r.useState)(!1);(0,r.useEffect)(()=>{e&&x.reset(((e,t,r)=>{if("edit"===e&&t){let e={...t,role:t.role||r.defaultRole,max_budget_in_team:t.max_budget_in_team??null,tpm_limit:t.tpm_limit??null,rpm_limit:t.rpm_limit??null,budget_duration:t.budget_duration||null,allowed_models:t.allowed_models||[]};return k(r,e)}return k(r,{role:r.defaultRole||r.roleOptions[0]?.value})})(n,a,i))},[e,a,n,x,i]);let E=async e=>{try{M(!0),await Promise.resolve(s(Object.fromEntries(Object.entries(e).map(([e,t])=>{if("string"!=typeof t)return[e,t];let r=t.trim();return""===r&&C.has(e)?[e,null]:[e,r]})))),x.reset(S(i))}catch(e){console.error("Form submission error:",e)}finally{M(!1)}},L="edit"===n&&a?[...i.roleOptions.filter(e=>e.value===a.role),...i.roleOptions.filter(e=>e.value!==a.role)]:i.roleOptions;return(0,t.jsx)(h.Dialog,{open:e,onOpenChange:e=>!e&&l(),children:(0,t.jsxs)(h.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[1000px]",children:[(0,t.jsx)(h.DialogHeader,{children:(0,t.jsx)(h.DialogTitle,{children:i.title||("add"===n?"Add Member":"Edit Member")})}),(0,t.jsxs)("form",{onSubmit:x.handleSubmit(E),children:[(0,t.jsxs)(c.FieldGroup,{children:[i.showEmail&&(0,t.jsx)(d.FormField,{control:x.control,name:"user_email",label:"Email",children:({ref:e,value:r,onChange:l,...s})=>(0,t.jsx)(w.Input,{...s,ref:e,placeholder:"user@example.com",value:"string"==typeof r?r:"",onChange:e=>l(e.target.value)})}),i.showEmail&&i.showUserId&&(0,t.jsx)("div",{className:"text-center text-sm text-muted-foreground",children:"OR"}),i.showUserId&&(0,t.jsx)(d.FormField,{control:x.control,name:"user_id",label:"User ID",children:({ref:e,value:r,onChange:l,...s})=>(0,t.jsx)(w.Input,{...s,ref:e,placeholder:"user_123",value:"string"==typeof r?r:"",onChange:e=>l(e.target.value)})}),(0,t.jsx)(d.FormField,{control:x.control,name:"role",label:(0,t.jsxs)("span",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{children:"Role"}),"edit"===n&&a&&(0,t.jsxs)("span",{className:"text-sm text-muted-foreground",children:["(Current: ",(o=a.role,i.roleOptions.find(e=>e.value===o)?.label||o),")"]})]}),children:({id:e,value:r,onChange:l})=>(0,t.jsxs)(p.Select,{items:Object.fromEntries(L.map(e=>[e.value,e.label])),value:"string"==typeof r&&""!==r?r:null,onValueChange:e=>l(e??void 0),children:[(0,t.jsx)(p.SelectTrigger,{id:e,className:"w-full",children:(0,t.jsx)(p.SelectValue,{})}),(0,t.jsx)(p.SelectContent,{children:L.map(e=>(0,t.jsx)(p.SelectItem,{value:e.value,children:e.label},e.value))})]})}),i.additionalFields?.map(e=>{let r;return r=e.name,(0,t.jsx)(d.FormField,{control:x.control,name:r,label:e.label,children:({ref:r,id:l,value:s,onChange:a,...n})=>{switch(e.type){case"input":return(0,t.jsx)(w.Input,{...n,id:l,ref:r,placeholder:e.placeholder,value:"string"==typeof s?s:"",onChange:e=>a(e.target.value)});case"numerical":return(0,t.jsx)(v.default,{...n,id:l,step:e.step||1,min:e.min||0,style:{width:"100%"},placeholder:e.placeholder||"Enter a numerical value",value:s??"",onChange:e=>a(e.target.value)});case"select":return(0,t.jsxs)(p.Select,{items:Object.fromEntries((e.options??[]).map(e=>[e.value,e.label])),value:"string"==typeof s&&""!==s?s:null,onValueChange:e=>a(e??void 0),children:[(0,t.jsx)(p.SelectTrigger,{id:l,className:"w-full",children:(0,t.jsx)(p.SelectValue,{})}),(0,t.jsx)(p.SelectContent,{children:e.options?.map(e=>(0,t.jsx)(p.SelectItem,{value:e.value,children:e.label},e.value))})]});case"multi-select":return(0,t.jsx)(j.MultiSelect,{options:e.options??[],value:Array.isArray(s)?s:[],onValueChange:a,placeholder:e.placeholder||"Select options"});case"budget-duration":return(0,t.jsx)(b.default,{id:l,value:"string"==typeof s?s:null,onChange:e=>a(e)});default:return null}}},r)})]}),(0,t.jsxs)("div",{className:"mt-6 text-right",children:[(0,t.jsx)(m.Button,{type:"button",variant:"outline",onClick:l,disabled:N,className:"mr-2",children:"Cancel"}),(0,t.jsxs)(m.Button,{type:"submit",variant:"outline",disabled:N,children:[N&&(0,t.jsx)(f.UiLoadingSpinner,{className:"size-4"}),"add"===n?N?"Adding...":"Add Member":N?"Saving...":"Save Changes"]})]})]})]})})}],276173)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/03pu_dx0gqja9.js b/litellm/proxy/_experimental/out/_next/static/chunks/03pu_dx0gqja9.js
new file mode 100644
index 00000000000..ea0a1578ede
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/03pu_dx0gqja9.js
@@ -0,0 +1,2 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,233525,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"warnOnce",{enumerable:!0,get:function(){return s}});let s=e=>{}},718967,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={DecodeError:function(){return v},MiddlewareNotFoundError:function(){return S},MissingStaticPage:function(){return w},NormalizeError:function(){return g},PageNotFoundError:function(){return b},SP:function(){return m},ST:function(){return y},WEB_VITALS:function(){return n},execOnce:function(){return a},getDisplayName:function(){return h},getLocationOrigin:function(){return l},getURL:function(){return c},isAbsoluteUrl:function(){return u},isResSent:function(){return d},loadGetInitialProps:function(){return f},normalizeRepeatedSlashes:function(){return p},stringifyError:function(){return C}};for(var i in s)Object.defineProperty(r,i,{enumerable:!0,get:s[i]});let n=["CLS","FCP","FID","INP","LCP","TTFB"];function a(e){let t,r=!1;return(...s)=>(r||(r=!0,t=e(...s)),t)}let o=/^[a-zA-Z][a-zA-Z\d+\-.]*?:/,u=e=>o.test(e);function l(){let{protocol:e,hostname:t,port:r}=window.location;return`${e}//${t}${r?":"+r:""}`}function c(){let{href:e}=window.location,t=l();return e.substring(t.length)}function h(e){return"string"==typeof e?e:e.displayName||e.name||"Unknown"}function d(e){return e.finished||e.headersSent}function p(e){let t=e.split("?");return t[0].replace(/\\/g,"/").replace(/\/\/+/g,"/")+(t[1]?`?${t.slice(1).join("?")}`:"")}async function f(e,t){let r=t.res||t.ctx&&t.ctx.res;if(!e.getInitialProps)return t.ctx&&t.Component?{pageProps:await f(t.Component,t.ctx)}:{};let s=await e.getInitialProps(t);if(r&&d(r))return s;if(!s)throw Object.defineProperty(Error(`"${h(e)}.getInitialProps()" should resolve to an object. But found "${s}" instead.`),"__NEXT_ERROR_CODE",{value:"E1025",enumerable:!1,configurable:!0});return s}let m="u">typeof performance,y=m&&["mark","measure","getEntriesByName"].every(e=>"function"==typeof performance[e]);class v extends Error{}class g extends Error{}class b extends Error{constructor(e){super(),this.code="ENOENT",this.name="PageNotFoundError",this.message=`Cannot find module for page: ${e}`}}class w extends Error{constructor(e,t){super(),this.message=`Failed to load static file for page: ${e} ${t}`}}class S extends Error{constructor(){super(),this.code="ENOENT",this.message="Cannot find the middleware module"}}function C(e){return JSON.stringify({message:e.message,stack:e.stack})}},998183,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0});var s={assign:function(){return u},searchParamsToUrlQuery:function(){return n},urlQueryToSearchParams:function(){return o}};for(var i in s)Object.defineProperty(r,i,{enumerable:!0,get:s[i]});function n(e){let t={};for(let[r,s]of e.entries()){let e=t[r];void 0===e?t[r]=s:Array.isArray(e)?e.push(s):t[r]=[e,s]}return t}function a(e){return"string"==typeof e?e:("number"!=typeof e||isNaN(e))&&"boolean"!=typeof e?"":String(e)}function o(e){let t=new URLSearchParams;for(let[r,s]of Object.entries(e))if(Array.isArray(s))for(let e of s)t.append(r,a(e));else t.set(r,a(s));return t}function u(e,...t){for(let r of t){for(let t of r.keys())e.delete(t);for(let[t,s]of r.entries())e.append(t,s)}return e}},434166,e=>{"use strict";e.s(["getSecureItem",0,function(e){try{let t=window.sessionStorage.getItem(e);if(null===t)return null;return decodeURIComponent(atob(t).split("").map(e=>"%"+e.charCodeAt(0).toString(16).padStart(2,"0")).join(""))}catch{return null}},"setSecureItem",0,function(e,t){window.sessionStorage.setItem(e,btoa(encodeURIComponent(t).replace(/%([0-9A-F]{2})/g,(e,t)=>String.fromCharCode(parseInt(t,16)))))}])},180166,e=>{"use strict";var t={setTimeout:(e,t)=>setTimeout(e,t),clearTimeout:e=>clearTimeout(e),setInterval:(e,t)=>setInterval(e,t),clearInterval:e=>clearInterval(e)},r=new class{#e=t;#t=!1;setTimeoutProvider(e){this.#e=e}setTimeout(e,t){return this.#e.setTimeout(e,t)}clearTimeout(e){this.#e.clearTimeout(e)}setInterval(e,t){return this.#e.setInterval(e,t)}clearInterval(e){this.#e.clearInterval(e)}};e.s(["systemSetTimeoutZero",0,function(e){setTimeout(e,0)},"timeoutManager",0,r])},619273,e=>{"use strict";var t=e.i(180166),r="u"l(t)?Object.keys(t).sort().reduce((e,r)=>(e[r]=t[r],e),{}):t)}function n(e,t){return e===t||typeof e==typeof t&&!!e&&!!t&&"object"==typeof e&&"object"==typeof t&&Object.keys(t).every(r=>n(e[r],t[r]))}var a=Object.prototype.hasOwnProperty;function o(e,t,r=0){if(e===t)return e;if(r>500)return t;let s=u(e)&&u(t);if(!s&&!(l(e)&&l(t)))return t;let i=(s?e:Object.keys(e)).length,n=s?t:Object.keys(t),c=n.length,h=s?Array(c):{},d=0;for(let u=0;u(s??=t(),i||(i=!0,s.aborted?r():s.addEventListener("abort",r,{once:!0})),s)}),e},"addToEnd",0,function(e,t,r=0){let s=[...e,t];return r&&s.length>r?s.slice(1):s},"addToStart",0,function(e,t,r=0){let s=[t,...e];return r&&s.length>r?s.slice(0,-1):s},"ensureQueryFn",0,function(e,t){return!e.queryFn&&t?.initialPromise?()=>t.initialPromise:e.queryFn&&e.queryFn!==h?e.queryFn:()=>Promise.reject(Error(`Missing queryFn: '${e.queryHash}'`))},"functionalUpdate",0,function(e,t){return"function"==typeof e?e(t):e},"hashKey",0,i,"hashQueryKeyByOptions",0,s,"isServer",0,r,"isValidTimeout",0,function(e){return"number"==typeof e&&e>=0&&e!==1/0},"keepPreviousData",0,function(e){return e},"matchMutation",0,function(e,t){let{exact:r,status:s,predicate:a,mutationKey:o}=e;if(o){if(!t.options.mutationKey)return!1;if(r){if(i(t.options.mutationKey)!==i(o))return!1}else if(!n(t.options.mutationKey,o))return!1}return(!s||t.state.status===s)&&(!a||!!a(t))},"matchQuery",0,function(e,t){let{type:r="all",exact:i,fetchStatus:a,predicate:o,queryKey:u,stale:l}=e;if(u){if(i){if(t.queryHash!==s(u,t.options))return!1}else if(!n(t.queryKey,u))return!1}if("all"!==r){let e=t.isActive();if("active"===r&&!e||"inactive"===r&&e)return!1}return("boolean"!=typeof l||t.isStale()===l)&&(!a||a===t.state.fetchStatus)&&(!o||!!o(t))},"noop",0,function(){},"partialMatchKey",0,n,"replaceData",0,function(e,t,r){return"function"==typeof r.structuralSharing?r.structuralSharing(e,t):!1!==r.structuralSharing?o(e,t):t},"replaceEqualDeep",0,o,"resolveQueryBoolean",0,function(e,t){return"function"==typeof e?e(t):e},"resolveStaleTime",0,function(e,t){return"function"==typeof e?e(t):e},"shallowEqualObjects",0,function(e,t){if(!t||Object.keys(e).length!==Object.keys(t).length)return!1;for(let r in e)if(e[r]!==t[r])return!1;return!0},"shouldThrowError",0,function(e,t){return"function"==typeof e?e(...t):!!e},"skipToken",0,h,"sleep",0,function(e){return new Promise(r=>{t.timeoutManager.setTimeout(r,e)})},"timeUntilStale",0,function(e,t){return Math.max(e+(t||0)-Date.now(),0)}])},540143,e=>{"use strict";let t,r,s,i,n,a;var o=e.i(180166).systemSetTimeoutZero,u=(t=[],r=0,s=e=>{e()},i=e=>{e()},n=o,{batch:e=>{let a;r++;try{a=e()}finally{let e;--r||(e=t,t=[],e.length&&n(()=>{i(()=>{e.forEach(e=>{s(e)})})}))}return a},batchCalls:e=>(...t)=>{a(()=>{e(...t)})},schedule:a=e=>{r?t.push(e):n(()=>{s(e)})},setNotifyFunction:e=>{s=e},setBatchNotifyFunction:e=>{i=e},setScheduler:e=>{n=e}});e.s(["notifyManager",0,u])},175555,915823,e=>{"use strict";var t=class{constructor(){this.listeners=new Set,this.subscribe=this.subscribe.bind(this)}subscribe(e){return this.listeners.add(e),this.onSubscribe(),()=>{this.listeners.delete(e),this.onUnsubscribe()}}hasListeners(){return this.listeners.size>0}onSubscribe(){}onUnsubscribe(){}};e.s(["Subscribable",0,t],915823);var r=new class extends t{#r;#s;#i;constructor(){super(),this.#i=e=>{if("u">typeof window&&window.addEventListener){let t=()=>e();return window.addEventListener("visibilitychange",t,!1),()=>{window.removeEventListener("visibilitychange",t)}}}}onSubscribe(){this.#s||this.setEventListener(this.#i)}onUnsubscribe(){this.hasListeners()||(this.#s?.(),this.#s=void 0)}setEventListener(e){this.#i=e,this.#s?.(),this.#s=e(e=>{"boolean"==typeof e?this.setFocused(e):this.onFocus()})}setFocused(e){this.#r!==e&&(this.#r=e,this.onFocus())}onFocus(){let e=this.isFocused();this.listeners.forEach(t=>{t(e)})}isFocused(){return"boolean"==typeof this.#r?this.#r:globalThis.document?.visibilityState!=="hidden"}};e.s(["focusManager",0,r],175555)},814448,793803,e=>{"use strict";var t=e.i(915823),r=new class extends t.Subscribable{#n=!0;#s;#i;constructor(){super(),this.#i=e=>{if("u">typeof window&&window.addEventListener){let t=()=>e(!0),r=()=>e(!1);return window.addEventListener("online",t,!1),window.addEventListener("offline",r,!1),()=>{window.removeEventListener("online",t),window.removeEventListener("offline",r)}}}}onSubscribe(){this.#s||this.setEventListener(this.#i)}onUnsubscribe(){this.hasListeners()||(this.#s?.(),this.#s=void 0)}setEventListener(e){this.#i=e,this.#s?.(),this.#s=e(this.setOnline.bind(this))}setOnline(e){this.#n!==e&&(this.#n=e,this.listeners.forEach(t=>{t(e)}))}isOnline(){return this.#n}};e.s(["onlineManager",0,r],814448),e.i(619273),e.s(["pendingThenable",0,function(){let e,t,r=new Promise((r,s)=>{e=r,t=s});function s(e){Object.assign(r,e),delete r.resolve,delete r.reject}return r.status="pending",r.catch(()=>{}),r.resolve=t=>{s({status:"fulfilled",value:t}),e(t)},r.reject=e=>{s({status:"rejected",reason:e}),t(e)},r}],793803)},273911,e=>{"use strict";let t;var r=e.i(619273),s=(t=()=>r.isServer,{isServer:()=>t(),setIsServer(e){t=e}});e.s(["environmentManager",0,s])},936553,e=>{"use strict";var t=e.i(175555),r=e.i(814448),s=e.i(793803),i=e.i(273911),n=e.i(619273);function a(e){return Math.min(1e3*2**e,3e4)}function o(e){return(e??"online")!=="online"||r.onlineManager.isOnline()}var u=class extends Error{constructor(e){super("CancelledError"),this.revert=e?.revert,this.silent=e?.silent}};e.s(["CancelledError",0,u,"canFetch",0,o,"createRetryer",0,function(e){let l,c=!1,h=0,d=(0,s.pendingThenable)(),p=()=>t.focusManager.isFocused()&&("always"===e.networkMode||r.onlineManager.isOnline())&&e.canRun(),f=()=>o(e.networkMode)&&e.canRun(),m=e=>{"pending"===d.status&&(l?.(),d.resolve(e))},y=e=>{"pending"===d.status&&(l?.(),d.reject(e))},v=()=>new Promise(t=>{l=e=>{("pending"!==d.status||p())&&t(e)},e.onPause?.()}).then(()=>{l=void 0,"pending"===d.status&&e.onContinue?.()}),g=()=>{let t;if("pending"!==d.status)return;let r=0===h?e.initialPromise:void 0;try{t=r??e.fn()}catch(e){t=Promise.reject(e)}Promise.resolve(t).then(m).catch(t=>{if("pending"!==d.status)return;let r=e.retry??3*!i.environmentManager.isServer(),s=e.retryDelay??a,o="function"==typeof s?s(h,t):s,u=!0===r||"number"==typeof r&&hp()?void 0:v()).then(()=>{c?y(t):g()}))})};return{promise:d,status:()=>d.status,cancel:t=>{if("pending"===d.status){let r=new u(t);y(r),e.onCancel?.(r)}},continue:()=>(l?.(),d),cancelRetry:()=>{c=!0},continueRetry:()=>{c=!1},canStart:f,start:()=>(f()?g():v().then(g),d)}}])},88587,e=>{"use strict";var t=e.i(180166),r=e.i(273911),s=e.i(619273),i=class{#a;destroy(){this.clearGcTimeout()}scheduleGc(){this.clearGcTimeout(),(0,s.isValidTimeout)(this.gcTime)&&(this.#a=t.timeoutManager.setTimeout(()=>{this.optionalRemove()},this.gcTime))}updateGcTime(e){this.gcTime=Math.max(this.gcTime||0,e??(r.environmentManager.isServer()?1/0:3e5))}clearGcTimeout(){void 0!==this.#a&&(t.timeoutManager.clearTimeout(this.#a),this.#a=void 0)}};e.s(["Removable",0,i])},286491,992571,e=>{"use strict";e.i(247167);var t=e.i(619273),r=e.i(540143),s=e.i(936553),i=e.i(88587);function n(e){return{onFetch:(r,s)=>{let i=r.options,n=r.fetchOptions?.meta?.fetchMore?.direction,u=r.state.data?.pages||[],l=r.state.data?.pageParams||[],c={pages:[],pageParams:[]},h=0,d=async()=>{let s=!1,d=(0,t.ensureQueryFn)(r.options,r.fetchOptions),p=async(e,i,n)=>{let a;if(s)return Promise.reject(r.signal.reason);if(null==i&&e.pages.length)return Promise.resolve(e);let o=(a={client:r.client,queryKey:r.queryKey,pageParam:i,direction:n?"backward":"forward",meta:r.options.meta},(0,t.addConsumeAwareSignal)(a,()=>r.signal,()=>s=!0),a),u=await d(o),{maxPages:l}=r.options,c=n?t.addToStart:t.addToEnd;return{pages:c(e.pages,u,l),pageParams:c(e.pageParams,i,l)}};if(n&&u.length){let e="backward"===n,t={pages:u,pageParams:l},r=(e?o:a)(i,t);c=await p(t,r,e)}else{let t=e??u.length;do{let e=0===h?l[0]??i.initialPageParam:a(i,c);if(h>0&&null==e)break;c=await p(c,e),h++}while(hr.options.persister?.(d,{client:r.client,queryKey:r.queryKey,meta:r.options.meta,signal:r.signal},s):r.fetchFn=d}}}function a(e,{pages:t,pageParams:r}){let s=t.length-1;return t.length>0?e.getNextPageParam(t[s],t,r[s],r):void 0}function o(e,{pages:t,pageParams:r}){return t.length>0?e.getPreviousPageParam?.(t[0],t,r[0],r):void 0}e.s(["hasNextPage",0,function(e,t){return!!t&&null!=a(e,t)},"hasPreviousPage",0,function(e,t){return!!t&&!!e.getPreviousPageParam&&null!=o(e,t)},"infiniteQueryBehavior",0,n],992571);var u=class extends i.Removable{#o;#u;#l;#c;#h;#d;#p;#f;constructor(e){super(),this.#f=!1,this.#p=e.defaultOptions,this.setOptions(e.options),this.observers=[],this.#h=e.client,this.#c=this.#h.getQueryCache(),this.queryKey=e.queryKey,this.queryHash=e.queryHash,this.#u=h(this.options),this.state=e.state??this.#u,this.scheduleGc()}get meta(){return this.options.meta}get queryType(){return this.#o}get promise(){return this.#d?.promise}setOptions(e){if(this.options={...this.#p,...e},e?._type&&(this.#o=e._type),this.updateGcTime(this.options.gcTime),this.state&&void 0===this.state.data){let e=h(this.options);void 0!==e.data&&(this.setState(c(e.data,e.dataUpdatedAt)),this.#u=e)}}optionalRemove(){this.observers.length||"idle"!==this.state.fetchStatus||this.#c.remove(this)}setData(e,r){let s=(0,t.replaceData)(this.state.data,e,this.options);return this.#m({data:s,type:"success",dataUpdatedAt:r?.updatedAt,manual:r?.manual}),s}setState(e){this.#m({type:"setState",state:e})}cancel(e){let r=this.#d?.promise;return this.#d?.cancel(e),r?r.then(t.noop).catch(t.noop):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}get resetState(){return this.#u}reset(){this.destroy(),this.setState(this.resetState)}isActive(){return this.observers.some(e=>!1!==(0,t.resolveQueryBoolean)(e.options.enabled,this))}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===t.skipToken||!this.isFetched()}isFetched(){return this.state.dataUpdateCount+this.state.errorUpdateCount>0}isStatic(){return this.getObserversCount()>0&&this.observers.some(e=>"static"===(0,t.resolveStaleTime)(e.options.staleTime,this))}isStale(){return this.getObserversCount()>0?this.observers.some(e=>e.getCurrentResult().isStale):void 0===this.state.data||this.state.isInvalidated}isStaleByTime(e=0){return void 0===this.state.data||"static"!==e&&(!!this.state.isInvalidated||!(0,t.timeUntilStale)(this.state.dataUpdatedAt,e))}onFocus(){let e=this.observers.find(e=>e.shouldFetchOnWindowFocus());e?.refetch({cancelRefetch:!1}),this.#d?.continue()}onOnline(){let e=this.observers.find(e=>e.shouldFetchOnReconnect());e?.refetch({cancelRefetch:!1}),this.#d?.continue()}addObserver(e){this.observers.includes(e)||(this.observers.push(e),this.clearGcTimeout(),this.#c.notify({type:"observerAdded",query:this,observer:e}))}removeObserver(e){this.observers.includes(e)&&(this.observers=this.observers.filter(t=>t!==e),this.observers.length||(this.#d&&(this.#f||this.#y()?this.#d.cancel({revert:!0}):this.#d.cancelRetry()),this.scheduleGc()),this.#c.notify({type:"observerRemoved",query:this,observer:e}))}getObserversCount(){return this.observers.length}#y(){return"paused"===this.state.fetchStatus&&"pending"===this.state.status}invalidate(){this.state.isInvalidated||this.#m({type:"invalidate"})}async fetch(e,r){let i;if("idle"!==this.state.fetchStatus&&this.#d?.status()!=="rejected"){if(void 0!==this.state.data&&r?.cancelRefetch)this.cancel({silent:!0});else if(this.#d)return this.#d.continueRetry(),this.#d.promise}if(e&&this.setOptions(e),!this.options.queryFn){let e=this.observers.find(e=>e.options.queryFn);e&&this.setOptions(e.options)}let a=new AbortController,o=e=>{Object.defineProperty(e,"signal",{enumerable:!0,get:()=>(this.#f=!0,a.signal)})},u=()=>{let e,s=(0,t.ensureQueryFn)(this.options,r),i=(o(e={client:this.#h,queryKey:this.queryKey,meta:this.meta}),e);return(this.#f=!1,this.options.persister)?this.options.persister(s,i,this):s(i)},l=(o(i={fetchOptions:r,options:this.options,queryKey:this.queryKey,client:this.#h,state:this.state,fetchFn:u}),i),c="infinite"===this.#o?n(this.options.pages):this.options.behavior;c?.onFetch(l,this),this.#l=this.state,("idle"===this.state.fetchStatus||this.state.fetchMeta!==l.fetchOptions?.meta)&&this.#m({type:"fetch",meta:l.fetchOptions?.meta}),this.#d=(0,s.createRetryer)({initialPromise:r?.initialPromise,fn:l.fetchFn,onCancel:e=>{e instanceof s.CancelledError&&e.revert&&this.setState({...this.#l,fetchStatus:"idle"}),a.abort()},onFail:(e,t)=>{this.#m({type:"failed",failureCount:e,error:t})},onPause:()=>{this.#m({type:"pause"})},onContinue:()=>{this.#m({type:"continue"})},retry:l.options.retry,retryDelay:l.options.retryDelay,networkMode:l.options.networkMode,canRun:()=>!0});try{let e=await this.#d.start();if(void 0===e)throw Error(`${this.queryHash} data is undefined`);return this.setData(e),this.#c.config.onSuccess?.(e,this),this.#c.config.onSettled?.(e,this.state.error,this),e}catch(e){if(e instanceof s.CancelledError){if(e.silent)return this.#d.promise;else if(e.revert){if(void 0===this.state.data)throw e;return this.state.data}}throw this.#m({type:"error",error:e}),this.#c.config.onError?.(e,this),this.#c.config.onSettled?.(this.state.data,e,this),e}finally{this.scheduleGc()}}#m(e){let t=t=>{switch(e.type){case"failed":return{...t,fetchFailureCount:e.failureCount,fetchFailureReason:e.error};case"pause":return{...t,fetchStatus:"paused"};case"continue":return{...t,fetchStatus:"fetching"};case"fetch":return{...t,...l(t.data,this.options),fetchMeta:e.meta??null};case"success":let r={...t,...c(e.data,e.dataUpdatedAt),dataUpdateCount:t.dataUpdateCount+1,...!e.manual&&{fetchStatus:"idle",fetchFailureCount:0,fetchFailureReason:null}};return this.#l=e.manual?r:void 0,r;case"error":let s=e.error;return{...t,error:s,errorUpdateCount:t.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:t.fetchFailureCount+1,fetchFailureReason:s,fetchStatus:"idle",status:"error",isInvalidated:!0};case"invalidate":return{...t,isInvalidated:!0};case"setState":return{...t,...e.state}}};this.state=t(this.state),r.notifyManager.batch(()=>{this.observers.forEach(e=>{e.onQueryUpdate()}),this.#c.notify({query:this,type:"updated",action:e})})}};function l(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:(0,s.canFetch)(t.networkMode)?"fetching":"paused",...void 0===e&&{error:null,status:"pending"}}}function c(e,t){return{data:e,dataUpdatedAt:t??Date.now(),error:null,isInvalidated:!1,status:"success"}}function h(e){let t="function"==typeof e.initialData?e.initialData():e.initialData,r=void 0!==t,s=r?"function"==typeof e.initialDataUpdatedAt?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:r?s??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:r?"success":"pending",fetchStatus:"idle"}}e.s(["Query",0,u,"fetchState",0,l],286491)},912598,e=>{"use strict";var t=e.i(271645),r=e.i(843476),s=t.createContext(void 0);e.s(["QueryClientProvider",0,({client:e,children:i})=>(t.useEffect(()=>(e.mount(),()=>{e.unmount()}),[e]),(0,r.jsx)(s.Provider,{value:e,children:i})),"useQueryClient",0,e=>{let r=t.useContext(s);if(e)return e;if(!r)throw Error("No QueryClient set, use QueryClientProvider to set one");return r}])},618566,(e,t,r)=>{t.exports=e.r(976562)},708347,e=>{"use strict";let t="org_admin",r=["Admin","Admin Viewer"],s=[...r,"proxy_admin","proxy_admin_viewer","org_admin"],i=["Internal User","Admin","proxy_admin"],n=[...i,"Admin Viewer","proxy_admin_viewer"],a=(e,t)=>null!=e&&e.some(e=>e.user_id===t&&"admin"===e.role),o=e=>{if(!e)return"Undefined Role";switch(e.toLowerCase()){case"app_owner":case"demo_app_owner":return"App Owner";case"proxy_admin":return"Admin";case"proxy_admin_viewer":return"Admin Viewer";case"org_admin":return"Org Admin";case"internal_user":return"Internal User";case"internal_user_viewer":case"internal_viewer":return"Internal Viewer";case"app_user":return"App User";default:return"Unknown Role"}},u=["proxy_admin_viewer","internal_user_viewer","internal_viewer"],l=["Admin","Admin Viewer","Org Admin"],c=["Admin","Admin Viewer","proxy_admin","proxy_admin_viewer"],h=e=>c.includes(e??"");e.s(["all_admin_roles",0,s,"effectiveSessionRole",0,e=>e?.toLowerCase()==="proxy_admin_viewer"?"Admin":o(e??""),"formatUserRole",0,o,"hasProxyWideSpendView",0,h,"internalUserRoles",0,["Internal User","Internal Viewer","internal_user","internal_user_viewer"],"isAdminRole",0,e=>s.includes(e),"isOrgAdminForAnyOrg",0,(e,r)=>null!=e&&!!r&&e.some(e=>(e.members??[]).some(e=>e.user_id===r&&e.user_role===t)),"isOrgAdminSessionRole",0,e=>e===t||e===o(t),"isProxyAdminRole",0,e=>"proxy_admin"===e||"Admin"===e,"isUserTeamAdminForAnyTeam",0,(e,t)=>null!=e&&e.some(e=>a(e.members_with_roles,t)),"isUserTeamAdminForSingleTeam",0,a,"isViewOnlySessionRole",0,e=>u.includes(e?.toLowerCase()??""),"old_admin_roles",0,r,"rolesAllowedToViewWriteScopedPages",0,n,"rolesWithWriteAccess",0,i,"spendScopeUserId",0,(e,t)=>h(e)?null:t,"teamListScopeUserId",0,(e,t)=>l.includes(e??"")?null:t])},717521,e=>{"use strict";let t=(0,e.i(475254).default)("loader-circle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);e.s(["default",0,t])},363178,e=>{"use strict";var t=e.i(271645),r=(e,t,r,s,i,n,a,o)=>{let u=document.documentElement,l=["light","dark"];function c(t){var r;(Array.isArray(e)?e:[e]).forEach(e=>{let r="class"===e,s=r&&n?i.map(e=>n[e]||e):i;r?(u.classList.remove(...s),u.classList.add(n&&n[t]?n[t]:t)):u.setAttribute(e,t)}),r=t,o&&l.includes(r)&&(u.style.colorScheme=r)}if(s)c(s);else try{let e=localStorage.getItem(t)||r,s=a&&"system"===e?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":e;c(s)}catch(e){}},s=["light","dark"],i="(prefers-color-scheme: dark)",n="u"{},themes:[]},u=["light","dark"],l=({forcedTheme:e,disableTransitionOnChange:r=!1,enableSystem:n=!0,enableColorScheme:o=!0,storageKey:l="theme",themes:f=u,defaultTheme:m=n?"system":"light",attribute:y="data-theme",value:v,children:g,nonce:b,scriptProps:w})=>{let[S,C]=t.useState(()=>h(l,m)),[P,q]=t.useState(()=>"system"===S?p():S),O=v?Object.values(v):f,A=t.useCallback(e=>{let t=e;if(!t)return;"system"===e&&n&&(t=p());let i=v?v[t]:t,a=r?d(b):null,u=document.documentElement,l=e=>{"class"===e?(u.classList.remove(...O),i&&u.classList.add(i)):e.startsWith("data-")&&(i?u.setAttribute(e,i):u.removeAttribute(e))};if(Array.isArray(y)?y.forEach(l):l(y),o){let e=s.includes(m)?m:null,r=s.includes(t)?t:e;u.style.colorScheme=r}null==a||a()},[b]),M=t.useCallback(e=>{let t="function"==typeof e?e(S):e;C(t);try{localStorage.setItem(l,t)}catch(e){}},[S]),E=t.useCallback(t=>{q(p(t)),"system"===S&&n&&!e&&A("system")},[S,e]);t.useEffect(()=>{let e=window.matchMedia(i);return e.addListener(E),E(e),()=>e.removeListener(E)},[E]),t.useEffect(()=>{let e=e=>{e.key===l&&(e.newValue?C(e.newValue):M(m))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)},[M]),t.useEffect(()=>{A(null!=e?e:S)},[e,S]);let T=t.useMemo(()=>({theme:S,setTheme:M,forcedTheme:e,resolvedTheme:"system"===S?P:S,themes:n?[...f,"system"]:f,systemTheme:n?P:void 0}),[S,M,e,P,n,f]);return t.createElement(a.Provider,{value:T},t.createElement(c,{forcedTheme:e,storageKey:l,attribute:y,enableSystem:n,enableColorScheme:o,defaultTheme:m,value:v,themes:f,nonce:b,scriptProps:w}),g)},c=t.memo(({forcedTheme:e,storageKey:s,attribute:i,enableSystem:n,enableColorScheme:a,defaultTheme:o,value:u,themes:l,nonce:c,scriptProps:h})=>{let d=JSON.stringify([i,s,o,e,l,u,n,a]).slice(1,-1);return t.createElement("script",{...h,suppressHydrationWarning:!0,nonce:"u"{let r;if(!n){try{r=localStorage.getItem(e)||void 0}catch(e){}return r||t}},d=e=>{let t=document.createElement("style");return e&&t.setAttribute("nonce",e),t.appendChild(document.createTextNode("*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}")),document.head.appendChild(t),()=>{window.getComputedStyle(document.body),setTimeout(()=>{document.head.removeChild(t)},1)}},p=e=>(e||(e=window.matchMedia(i)),e.matches?"dark":"light");e.s(["ThemeProvider",0,e=>t.useContext(a)?t.createElement(t.Fragment,null,e.children):t.createElement(l,{...e}),"useTheme",0,()=>{var e;return null!=(e=t.useContext(a))?e:o}])},123287,e=>{"use strict";let t=(0,e.i(475254).default)("circle-check",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m9 12 2 2 4-4",key:"dzmm74"}]]);e.s(["default",0,t])},114272,e=>{"use strict";var t=e.i(540143),r=e.i(88587),s=e.i(936553),i=class extends r.Removable{#h;#v;#g;#d;constructor(e){super(),this.#h=e.client,this.mutationId=e.mutationId,this.#g=e.mutationCache,this.#v=[],this.state=e.state||n(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#v.includes(e)||(this.#v.push(e),this.clearGcTimeout(),this.#g.notify({type:"observerAdded",mutation:this,observer:e}))}removeObserver(e){this.#v=this.#v.filter(t=>t!==e),this.scheduleGc(),this.#g.notify({type:"observerRemoved",mutation:this,observer:e})}optionalRemove(){this.#v.length||("pending"===this.state.status?this.scheduleGc():this.#g.remove(this))}continue(){return this.#d?.continue()??this.execute(this.state.variables)}async execute(e){let t=()=>{this.#m({type:"continue"})},r={client:this.#h,meta:this.options.meta,mutationKey:this.options.mutationKey};this.#d=(0,s.createRetryer)({fn:()=>this.options.mutationFn?this.options.mutationFn(e,r):Promise.reject(Error("No mutationFn found")),onFail:(e,t)=>{this.#m({type:"failed",failureCount:e,error:t})},onPause:()=>{this.#m({type:"pause"})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#g.canRun(this)});let i="pending"===this.state.status,n=!this.#d.canStart();try{if(i)t();else{this.#m({type:"pending",variables:e,isPaused:n}),this.#g.config.onMutate&&await this.#g.config.onMutate(e,this,r);let t=await this.options.onMutate?.(e,r);t!==this.state.context&&this.#m({type:"pending",context:t,variables:e,isPaused:n})}let s=await this.#d.start();return await this.#g.config.onSuccess?.(s,e,this.state.context,this,r),await this.options.onSuccess?.(s,e,this.state.context,r),await this.#g.config.onSettled?.(s,null,this.state.variables,this.state.context,this,r),await this.options.onSettled?.(s,null,e,this.state.context,r),this.#m({type:"success",data:s}),s}catch(t){try{await this.#g.config.onError?.(t,e,this.state.context,this,r)}catch(e){Promise.reject(e)}try{await this.options.onError?.(t,e,this.state.context,r)}catch(e){Promise.reject(e)}try{await this.#g.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,r)}catch(e){Promise.reject(e)}try{await this.options.onSettled?.(void 0,t,e,this.state.context,r)}catch(e){Promise.reject(e)}throw this.#m({type:"error",error:t}),t}finally{this.#g.runNext(this)}}#m(e){this.state=(t=>{switch(e.type){case"failed":return{...t,failureCount:e.failureCount,failureReason:e.error};case"pause":return{...t,isPaused:!0};case"continue":return{...t,isPaused:!1};case"pending":return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:"pending",variables:e.variables,submittedAt:Date.now()};case"success":return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:"success",isPaused:!1};case"error":return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:"error"}}})(this.state),t.notifyManager.batch(()=>{this.#v.forEach(t=>{t.onMutationUpdate(e)}),this.#g.notify({mutation:this,type:"updated",action:e})})}};function n(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:"idle",variables:void 0,submittedAt:0}}e.s(["Mutation",0,i,"getDefaultState",0,n])},582458,e=>{"use strict";let t=(0,e.i(475254).default)("triangle-alert",[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]]);e.s(["default",0,t])},280862,e=>{"use strict";let t;var r,s,i=e.i(271645);let n={303:"Multiple adapter contexts detected. This might happen in monorepos.",404:"nuqs requires an adapter to work with your framework.",409:"Multiple versions of the library are loaded. This may lead to unexpected behavior. Currently using `%s`, but `%s` (via the %s adapter) was about to load on top.",414:"Max safe URL length exceeded. Some browsers may not be able to accept this URL. Consider limiting the amount of state stored in the URL.",429:"URL update rate-limited by the browser. Consider increasing `throttleMs` for key(s) `%s`. %O",500:"Empty search params cache. Search params can't be accessed in Layouts.",501:"Search params cache already populated. Have you called `parse` twice?"};function a(e){return`[nuqs] ${n[e]}
+ See https://nuqs.dev/NUQS-${e}`}let o="2.9.4",u={};function l(e,t){let r=Symbol.for(`nuqs.${o}.${e}`),s=globalThis;if(null!=s[r])return s[r];let i=Object.isExtensible(s)?s:u;return i[r]??=t()}let c=(r=i.createContext,s=()=>{let e=(0,i.createContext)({useAdapter(){throw Error(a(404))}});return e.displayName="NuqsAdapterContext",e},(t=l("adapter-context",()=>new WeakMap)).has(r)||t.set(r,s()),t.get(r));"u">typeof window&&(window.__NuqsAdapterContext&&window.__NuqsAdapterContext!==c&&console.error(a(303)),window.__NuqsAdapterContext=c),e.s(["a",0,()=>(0,i.useContext)(c).processUrlSearchParams,"c",0,function(e){if(0===e.size)return"";let t=[];for(let[r,s]of e.entries()){let e=r.replace(/#/g,"%23").replace(/&/g,"%26").replace(/\+/g,"%2B").replace(/=/g,"%3D").replace(/\?/g,"%3F");t.push(`${e}=${s.replace(/%/g,"%25").replace(/\+/g,"%2B").replace(/ /g,"+").replace(/#/g,"%23").replace(/&/g,"%26").replace(/"/g,"%22").replace(/'/g,"%27").replace(/`/g,"%60").replace(//g,"%3E").replace(/[\x00-\x1F]/g,e=>encodeURIComponent(e))}`)}return"?"+t.join("&")},"i",0,()=>(0,i.useContext)(c).defaultOptions,"l",0,a,"n",0,function(e){return({children:t,defaultOptions:r,processUrlSearchParams:s,...n})=>(0,i.createElement)(c.Provider,{...n,value:{useAdapter:e,defaultOptions:r,processUrlSearchParams:s}},t)},"o",0,l,"r",0,function(e){let t=(0,i.useContext)(c);if(!("useAdapter"in t))throw Error(a(404));return t.useAdapter(e)},"s",0,o])},487315,e=>{"use strict";e.s(["i",0,function(e){},"t",0,function(e){}])},916108,e=>{"use strict";var t=e.i(487315),r=e.i(280862),s=e.i(271645);function i(e){return{method:"throttle",timeMs:e}}let n=i(function(){if("u"=17?120:320}catch{return 320}}());function a(e,t,r){if("string"==typeof r)e.set(t,r);else{for(let s of(e.delete(t),r))e.append(t,s);e.has(t)||e.set(t,"")}return e}function o(){let e=new Map;return{on(t,r){let s=e.get(t)||[];return s.push(r),e.set(t,s),()=>this.off(t,r)},off(t,r){let s=e.get(t);s&&e.set(t,s.filter(e=>e!==r))},emit(t,r){e.get(t)?.forEach(e=>e(r))}}}function u(e,t,r){let s=setTimeout(function(){e(),r.removeEventListener("abort",i)},t);function i(){clearTimeout(s),r.removeEventListener("abort",i)}r.addEventListener("abort",i)}function l(){let e=Promise;if(Promise.hasOwnProperty("withResolvers"))return Promise.withResolvers();let t=()=>{},r=()=>{};return{promise:new e((e,s)=>{t=e,r=s}),resolve:t,reject:r}}function c(){return new URLSearchParams(location.search)}var h=class{updateMap=new Map;options={history:"replace",scroll:!1,shallow:!0};timeMs=n.timeMs;transitions=new Set;resolvers=null;controller=null;lastFlushedAt=0;resetQueueOnNextPush=!1;push({key:e,query:r,options:s},i=n.timeMs){this.resetQueueOnNextPush&&(this.reset(),this.resetQueueOnNextPush=!1),(0,t.t)(7,e,r,s),this.updateMap.set(e,r),"push"===s.history&&(this.options.history="push"),s.scroll&&(this.options.scroll=!0),!1===s.shallow&&(this.options.shallow=!1),s.startTransition&&this.transitions.add(s.startTransition),(!Number.isFinite(this.timeMs)||i>this.timeMs)&&(this.timeMs=i)}getQueuedQuery(e){return this.updateMap.get(e)}getPendingPromise({getSearchParamsSnapshot:e=c}){return this.resolvers?.promise??Promise.resolve(e())}flush({getSearchParamsSnapshot:e=c,rateLimitFactor:r=1,...s},i){if(this.controller??=new AbortController,!Number.isFinite(this.timeMs))return(0,t.t)(8),Promise.resolve(e());if(this.resolvers)return this.resolvers.promise;this.resolvers=l();let n=()=>{this.lastFlushedAt=performance.now();let[t,r]=this.applyPendingUpdates({...s,autoResetQueueOnUpdate:s.autoResetQueueOnUpdate??!0,getSearchParamsSnapshot:e},i);null===r?(this.resolvers.resolve(t),this.resetQueueOnNextPush=!0):this.resolvers.reject(t),this.resolvers=null},a=()=>{let e=performance.now()-this.lastFlushedAt,s=this.timeMs,i=r*Math.max(0,s-e);(0,t.t)(9,i,s,r),0===i?n():u(n,i,this.controller.signal)};return u(a,0,this.controller.signal),this.resolvers.promise}abort(){return this.controller?.abort(),this.controller=new AbortController,this.resolvers?.resolve(new URLSearchParams),this.resolvers=null,this.reset()}reset(){let e=Array.from(this.updateMap.keys());return(0,t.t)(10,JSON.stringify(Object.fromEntries(this.updateMap))),this.updateMap.clear(),this.transitions.clear(),this.options={history:"replace",scroll:!1,shallow:!0},this.timeMs=n.timeMs,e}applyPendingUpdates(e,s){let{updateUrl:i,getSearchParamsSnapshot:n}=e,o=n();if((0,t.t)(11,this.updateMap.size,o.toString()),0===this.updateMap.size)return[o,null];let u=Array.from(this.updateMap.entries()),l={...this.options},c=Array.from(this.transitions);for(let[r,s]of(e.autoResetQueueOnUpdate&&this.reset(),(0,t.t)(12,u,l),u))null===s?o.delete(r):o=a(o,r,s);s&&(o=s(o));try{return!function(e,t){let r=t;for(let t=e.length-1;t>=0;t--){let s=e[t];if(!s)continue;let i=r;r=()=>s(i)}r()}(c,()=>i(o,l)),[o,null]}catch(e){return console.error((0,r.l)(429),u.map(([e])=>e).join(),e),[o,e]}}};let d=(0,r.o)("throttle-queue",()=>new h);var p=class{callback;resolvers=l();controller=new AbortController;queuedValue=void 0;constructor(e){this.callback=e}abort(){this.controller.abort(),this.queuedValue=void 0}push(e,r){return this.queuedValue=e,this.controller.abort(),this.controller=new AbortController,u(()=>{let r=this.resolvers;try{(0,t.t)(13,e);let s=this.callback(e);(0,t.t)(14,this.queuedValue),this.queuedValue=void 0,this.resolvers=l(),s.then(e=>r.resolve(e)).catch(e=>r.reject(e))}catch(e){this.queuedValue=void 0,r.reject(e)}},r,this.controller.signal),this.resolvers.promise}},f=class{throttleQueue;queues=new Map;queuedQuerySync=o();constructor(e=new h){this.throttleQueue=e}push(e,r,s,i){if(!Number.isFinite(r))return Promise.resolve((s.getSearchParamsSnapshot??c)());let n=e.key;if(!this.queues.has(n)){(0,t.t)(15,n);let e=new p(e=>(this.throttleQueue.push(e),this.throttleQueue.flush(s,i).finally(()=>{this.queues.get(e.key)?.queuedValue===void 0&&((0,t.t)(16,e.key),this.queues.delete(e.key)),this.queuedQuerySync.emit(e.key)})));this.queues.set(n,e)}(0,t.t)(17,e);let a=this.queues.get(n).push(e,r);return this.queuedQuerySync.emit(n),a}abort(e){let r=this.queues.get(e);return r?((0,t.t)(18,e,r.queuedValue?.query),this.queues.delete(e),r.abort(),this.queuedQuerySync.emit(e),e=>(e.then(r.resolvers.resolve,r.resolvers.reject),e)):e=>e}abortAll(){for(let[e,r]of this.queues.entries())(0,t.t)(18,e,r.queuedValue?.query),r.abort(),r.resolvers.resolve(new URLSearchParams),this.queuedQuerySync.emit(e);this.queues.clear()}getQueuedQuery(e){let t=this.queues.get(e)?.queuedValue?.query;return void 0!==t?t:this.throttleQueue.getQueuedQuery(e)}};let m=(0,r.o)("debounce-controller",()=>new f(d));e.s(["a",0,function(e){if(e instanceof URL)return e.searchParams;if(e.startsWith("?"))return new URLSearchParams(e);try{return new URL(e,location.origin).searchParams}catch{return new URLSearchParams(e)}},"c",0,function(e){return{method:"debounce",timeMs:e}},"i",0,o,"l",0,n,"n",0,function(e){var t,r;let i,n;return t=(e,t)=>m.queuedQuerySync.on(e,t),r=e=>m.getQueuedQuery(e),i=(0,s.useCallback)(()=>{let t=Object.fromEntries(e.map(e=>[e,r(e)]));return[JSON.stringify(t),t]},[e.join(","),r]),null===(n=(0,s.useRef)(null)).current&&(n.current=i()),(0,s.useSyncExternalStore)((0,s.useCallback)(r=>{let s=e.map(e=>t(e,r));return()=>s.forEach(e=>e())},[e.join(","),t]),()=>{let[e,t]=i();return n.current[0]===e?n.current[1]:(n.current=[e,t],t)},()=>n.current[1])},"o",0,function(e){return null===e||Array.isArray(e)&&0===e.length},"r",0,d,"s",0,a,"t",0,m,"u",0,i])},557951,e=>{"use strict";var t=e.i(843476),r=e.i(271645),s=e.i(947293),i=e.i(268004),n=e.i(161281),a=e.i(708347),o=e.i(602869);function u(e,t="/"){document.cookie=`${e}=; Max-Age=0; Path=${t}`,"token"===e&&(0,i.clearTokenCookies)()}let l=(0,r.createContext)(null);e.s(["AuthProvider",0,function({children:e}){let[c,h]=(0,r.useState)(!0),[d,p]=(0,r.useState)(null),[f,m]=(0,r.useState)(null),[y,v]=(0,r.useState)(""),[g,b]=(0,r.useState)(null),[w,S]=(0,r.useState)(null),[C,P]=(0,r.useState)(!1),[q,O]=(0,r.useState)(!1),[A,M]=(0,r.useState)(!0);return(0,r.useEffect)(()=>{let e=!1;return(async()=>{try{await (0,o.getUiConfig)()}catch{}if(e)return;let t=(0,i.getCookie)("token"),r=t&&!(0,n.isJwtExpired)(t)?t:null;t&&!r&&u("token","/"),p(r),h(!1)})(),()=>{e=!0}},[]),(0,r.useEffect)(()=>{if(!d)return;if((0,n.isJwtExpired)(d)){u("token","/"),p(null);return}let e=null;try{e=(0,s.jwtDecode)(d)}catch{u("token","/"),p(null);return}e&&(S(e.key),O(e.disabled_non_admin_personal_key_creation),e.user_role&&v((0,a.effectiveSessionRole)(e.user_role)),e.user_email&&b(e.user_email),e.login_method&&M("username_password"===e.login_method),e.premium_user&&P(e.premium_user),e.auth_header_name&&(0,o.setGlobalLitellmHeaderName)(e.auth_header_name),e.user_id&&m(e.user_id))},[d]),(0,t.jsx)(l.Provider,{value:{authLoading:c,token:d,userID:f,userRole:y,userEmail:g,accessToken:w,premiumUser:C,disabledPersonalKeyCreation:q,showSSOBanner:A,setToken:p,setUserID:m,setUserRole:v,setUserEmail:b,setAccessToken:S,setPremiumUser:P,setShowSSOBanner:M},children:e})},"useAuth",0,function(){let e=(0,r.useContext)(l);if(!e)throw Error("useAuth must be used within an AuthProvider");return e}])},168118,e=>{"use strict";var t=e.i(879664);e.s(["InfoIcon",()=>t.default])},12985,e=>{"use strict";var t=e.i(280862),r=e.i(916108),s=e.i(487315);let i=(0,t.o)("queue-reset",()=>({mutex:0}));function n(e=1){i.mutex=e}function a(){(0,s.t)(19),r.t.abortAll(),r.r.abort().forEach(e=>r.t.queuedQuerySync.emit(e))}var o=e.i(271645),u=e.i(618566);function l(){n(0),a()}function c(){let e=(0,u.usePathname)(),s=(0,o.useRef)(e);return s.current!==e&&(s.current=e,r.r.reset()),(0,o.useEffect)(()=>(!function(){var e;if(e="next/app","u"0||e()}(()=>{queueMicrotask(a)}),s.call(history,e,"__nuqs__"===t?"":t,r)},history.nuqs=history.nuqs??{version:"2.9.4",adapters:[]},history.nuqs.adapters.push("next/app")}(),window.addEventListener("popstate",l),()=>window.removeEventListener("popstate",l)),[]),null}let h=(0,t.n)(function(){let e=(0,u.useRouter)(),r=(0,u.usePathname)(),[i,a]=(0,o.useOptimistic)((0,u.useSearchParams)()??new URLSearchParams);return{searchParams:i,pathname:r,updateUrl:(0,o.useCallback)((r,i)=>{(0,o.startTransition)(()=>{i.shallow||a(r);let o=function(e){let{origin:r,pathname:s,hash:i}=location;return r+s+(0,t.c)(e)+i}(r);(0,s.t)(20,"next/app",o);let u="push"===i.history?history.pushState:history.replaceState;n(0),u.call(history,null,"__nuqs__",o),i.scroll&&window.scrollTo(0,0),i.shallow||e.replace(o,{scroll:!1})})},[]),rateLimitFactor:3,autoResetQueueOnUpdate:!1}});e.s(["NuqsAdapter",0,function({children:e,...t}){return(0,o.createElement)(h,{...t,children:[(0,o.createElement)(o.Suspense,{key:"nuqs-adapter-suspense-navspy",children:(0,o.createElement)(c)}),e]})}],12985)},867271,e=>{"use strict";var t=e.i(843476),r=e.i(619273),s=e.i(286491),i=e.i(540143),n=e.i(915823),a=class extends n.Subscribable{constructor(e={}){super(),this.config=e,this.#b=new Map}#b;build(e,t,i){let n=t.queryKey,a=t.queryHash??(0,r.hashQueryKeyByOptions)(n,t),o=this.get(a);return o||(o=new s.Query({client:e,queryKey:n,queryHash:a,options:e.defaultQueryOptions(t),state:i,defaultOptions:e.getQueryDefaults(n)}),this.add(o)),o}add(e){this.#b.has(e.queryHash)||(this.#b.set(e.queryHash,e),this.notify({type:"added",query:e}))}remove(e){let t=this.#b.get(e.queryHash);t&&(e.destroy(),t===e&&this.#b.delete(e.queryHash),this.notify({type:"removed",query:e}))}clear(){i.notifyManager.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#b.get(e)}getAll(){return[...this.#b.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>(0,r.matchQuery)(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>(0,r.matchQuery)(e,t)):t}notify(e){i.notifyManager.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){i.notifyManager.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){i.notifyManager.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},o=e.i(114272),u=n,l=class extends u.Subscribable{constructor(e={}){super(),this.config=e,this.#w=new Set,this.#S=new Map,this.#C=0}#w;#S;#C;build(e,t,r){let s=new o.Mutation({client:e,mutationCache:this,mutationId:++this.#C,options:e.defaultMutationOptions(t),state:r});return this.add(s),s}add(e){this.#w.add(e);let t=c(e);if("string"==typeof t){let r=this.#S.get(t);r?r.push(e):this.#S.set(t,[e])}this.notify({type:"added",mutation:e})}remove(e){if(this.#w.delete(e)){let t=c(e);if("string"==typeof t){let r=this.#S.get(t);if(r)if(r.length>1){let t=r.indexOf(e);-1!==t&&r.splice(t,1)}else r[0]===e&&this.#S.delete(t)}}this.notify({type:"removed",mutation:e})}canRun(e){let t=c(e);if("string"!=typeof t)return!0;{let r=this.#S.get(t),s=r?.find(e=>"pending"===e.state.status);return!s||s===e}}runNext(e){let t=c(e);if("string"!=typeof t)return Promise.resolve();{let r=this.#S.get(t)?.find(t=>t!==e&&t.state.isPaused);return r?.continue()??Promise.resolve()}}clear(){i.notifyManager.batch(()=>{this.#w.forEach(e=>{this.notify({type:"removed",mutation:e})}),this.#w.clear(),this.#S.clear()})}getAll(){return Array.from(this.#w)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>(0,r.matchMutation)(t,e))}findAll(e={}){return this.getAll().filter(t=>(0,r.matchMutation)(e,t))}notify(e){i.notifyManager.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return i.notifyManager.batch(()=>Promise.all(e.map(e=>e.continue().catch(r.noop))))}};function c(e){return e.options.scope?.id}var h=e.i(175555),d=e.i(814448),p=class{#P;#g;#p;#q;#O;#A;#M;#E;constructor(e={}){this.#P=e.queryCache||new a,this.#g=e.mutationCache||new l,this.#p=e.defaultOptions||{},this.#q=new Map,this.#O=new Map,this.#A=0}mount(){this.#A++,1===this.#A&&(this.#M=h.focusManager.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#P.onFocus())}),this.#E=d.onlineManager.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#P.onOnline())}))}unmount(){this.#A--,0===this.#A&&(this.#M?.(),this.#M=void 0,this.#E?.(),this.#E=void 0)}isFetching(e){return this.#P.findAll({...e,fetchStatus:"fetching"}).length}isMutating(e){return this.#g.findAll({...e,status:"pending"}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#P.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),s=this.#P.build(this,t),i=s.state.data;return void 0===i?this.fetchQuery(e):(e.revalidateIfStale&&s.isStaleByTime((0,r.resolveStaleTime)(t.staleTime,s))&&this.prefetchQuery(t),Promise.resolve(i))}getQueriesData(e){return this.#P.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,s){let i=this.defaultQueryOptions({queryKey:e}),n=this.#P.get(i.queryHash),a=n?.state.data,o=(0,r.functionalUpdate)(t,a);if(void 0!==o)return this.#P.build(this,i).setData(o,{...s,manual:!0})}setQueriesData(e,t,r){return i.notifyManager.batch(()=>this.#P.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,r)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#P.get(t.queryHash)?.state}removeQueries(e){let t=this.#P;i.notifyManager.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let r=this.#P;return i.notifyManager.batch(()=>(r.findAll(e).forEach(e=>{e.reset()}),this.refetchQueries({type:"active",...e},t)))}cancelQueries(e,t={}){let s={revert:!0,...t};return Promise.all(i.notifyManager.batch(()=>this.#P.findAll(e).map(e=>e.cancel(s)))).then(r.noop).catch(r.noop)}invalidateQueries(e,t={}){return i.notifyManager.batch(()=>(this.#P.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType==="none")?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??"active"},t))}refetchQueries(e,t={}){let s={...t,cancelRefetch:t.cancelRefetch??!0};return Promise.all(i.notifyManager.batch(()=>this.#P.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,s);return s.throwOnError||(t=t.catch(r.noop)),"paused"===e.state.fetchStatus?Promise.resolve():t}))).then(r.noop)}fetchQuery(e){let t=this.defaultQueryOptions(e);void 0===t.retry&&(t.retry=!1);let s=this.#P.build(this,t);return s.isStaleByTime((0,r.resolveStaleTime)(t.staleTime,s))?s.fetch(t):Promise.resolve(s.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(r.noop).catch(r.noop)}fetchInfiniteQuery(e){return e._type="infinite",this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(r.noop).catch(r.noop)}ensureInfiniteQueryData(e){return e._type="infinite",this.ensureQueryData(e)}resumePausedMutations(){return d.onlineManager.isOnline()?this.#g.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#P}getMutationCache(){return this.#g}getDefaultOptions(){return this.#p}setDefaultOptions(e){this.#p=e}setQueryDefaults(e,t){this.#q.set((0,r.hashKey)(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#q.values()],s={};return t.forEach(t=>{(0,r.partialMatchKey)(e,t.queryKey)&&Object.assign(s,t.defaultOptions)}),s}setMutationDefaults(e,t){this.#O.set((0,r.hashKey)(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#O.values()],s={};return t.forEach(t=>{(0,r.partialMatchKey)(e,t.mutationKey)&&Object.assign(s,t.defaultOptions)}),s}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#p.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||(t.queryHash=(0,r.hashQueryKeyByOptions)(t.queryKey,t)),void 0===t.refetchOnReconnect&&(t.refetchOnReconnect="always"!==t.networkMode),void 0===t.throwOnError&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode="offlineFirst"),t.queryFn===r.skipToken&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#p.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#P.clear(),this.#g.clear()}},f=e.i(912598);let m=new p;e.s(["default",0,function({children:e}){return(0,t.jsx)(f.QueryClientProvider,{client:m,children:e})}],867271)},713354,e=>{"use strict";var t=e.i(843476),r=e.i(123287),r=r,s=e.i(168118),i=e.i(717521),i=i;let n=(0,e.i(475254).default)("octagon-x",[["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z",key:"2d38gg"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);var a=e.i(582458),a=a,o=e.i(363178),u=e.i(846696);e.s(["Toaster",0,function({...e}){let{resolvedTheme:l}=(0,o.useTheme)();return(0,t.jsx)(u.Toaster,{theme:"dark"===l?"dark":"light",position:"top-right",closeButton:!0,className:"toaster group",icons:{success:(0,t.jsx)(r.default,{className:"size-4"}),info:(0,t.jsx)(s.InfoIcon,{className:"size-4"}),warning:(0,t.jsx)(a.default,{className:"size-4"}),error:(0,t.jsx)(n,{className:"size-4"}),loading:(0,t.jsx)(i.default,{className:"size-4 animate-spin"})},style:{"--normal-bg":"var(--popover)","--normal-text":"var(--popover-foreground)","--normal-border":"var(--border)","--border-radius":"var(--radius)"},toastOptions:{classNames:{toast:"cn-toast"}},...e})}],713354)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/04fw18d3dx40b.js b/litellm/proxy/_experimental/out/_next/static/chunks/04fw18d3dx40b.js
new file mode 100644
index 00000000000..98c1ddf8a35
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/04fw18d3dx40b.js
@@ -0,0 +1 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,302747,e=>{"use strict";var t=e.i(843476),a=e.i(196631);e.s(["Skeleton",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"skeleton",className:(0,a.cn)("animate-pulse rounded-md bg-muted",e),...r})}])},784774,e=>{"use strict";var t=e.i(843476),a=e.i(271645),r=e.i(196631);let l=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("div",{"data-slot":"table-container",className:"relative w-full overflow-x-auto",children:(0,t.jsx)("table",{ref:l,"data-slot":"table",className:(0,r.cn)("w-full caption-bottom text-sm",e),...a})}));l.displayName="Table";let n=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("thead",{ref:l,"data-slot":"table-header",className:(0,r.cn)("[&_tr]:border-b",e),...a}));n.displayName="TableHeader";let i=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tbody",{ref:l,"data-slot":"table-body",className:(0,r.cn)("[&_tr:last-child]:border-0",e),...a}));i.displayName="TableBody";let s=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tfoot",{ref:l,"data-slot":"table-footer",className:(0,r.cn)("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",e),...a}));s.displayName="TableFooter";let o=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("tr",{ref:l,"data-slot":"table-row",className:(0,r.cn)("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",e),...a}));o.displayName="TableRow";let d=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("th",{ref:l,"data-slot":"table-head",className:(0,r.cn)("h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));d.displayName="TableHead";let u=a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("td",{ref:l,"data-slot":"table-cell",className:(0,r.cn)("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",e),...a}));u.displayName="TableCell",a.forwardRef(({className:e,...a},l)=>(0,t.jsx)("caption",{ref:l,"data-slot":"table-caption",className:(0,r.cn)("mt-4 text-sm text-muted-foreground",e),...a})).displayName="TableCaption",e.s(["Table",0,l,"TableBody",0,i,"TableCell",0,u,"TableFooter",0,s,"TableHead",0,d,"TableHeader",0,n,"TableRow",0,o])},16715,e=>{"use strict";let t=(0,e.i(475254).default)("refresh-cw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);e.s(["RefreshCw",0,t],16715)},157153,e=>{"use strict";var t=e.i(271645);let a=t.createContext({disabled:!1});e.s(["useFieldItemContext",0,function(){return t.useContext(a)}])},257428,e=>{"use strict";var t,a=e.i(843476);e.s([],392299),e.i(392299),e.i(247167);var r=e.i(271645),l=e.i(956789),n=e.i(951437),i=e.i(146376),s=e.i(828918),o=e.i(921374),d=e.i(502077),u=e.i(333848);let c=((t={}).checked="data-checked",t.unchecked="data-unchecked",t.indeterminate="data-indeterminate",t.disabled="data-disabled",t.readonly="data-readonly",t.required="data-required",t.valid="data-valid",t.invalid="data-invalid",t.touched="data-touched",t.dirty="data-dirty",t.filled="data-filled",t.focused="data-focused",t);var m=e.i(875812);function f(e){return r.useMemo(()=>({checked:t=>e.indeterminate?{}:t?{[c.checked]:""}:{[c.unchecked]:""},...m.fieldValidityMapping}),[e.indeterminate])}var p=e.i(552245),x=e.i(788015),y=e.i(176782),h=e.i(540886),b=e.i(469690),g=e.i(381104),v=e.i(157153),w=e.i(884708),C=e.i(247778),N=e.i(31421),k=e.i(733332);let j=r.createContext(void 0),M=r.createContext(void 0);var T=e.i(675606),R=e.i(56434),$=e.i(606039);let I=r.forwardRef(function(e,t){let{checked:c,className:m,defaultChecked:I=!1,"aria-labelledby":A,disabled:S=!1,form:K,id:P,indeterminate:D=!1,inputRef:F,name:B,onCheckedChange:_,parent:E=!1,readOnly:q=!1,render:Q,required:H=!1,uncheckedValue:O,value:W,nativeButton:L=!1,style:U,...z}=e,{clearErrors:V}=(0,w.useFormContext)(),{disabled:G,name:J,setDirty:Y,setFilled:Z,setFocused:X,setTouched:ee,state:et,validationMode:ea,validityData:er,validation:el}=(0,b.useFieldRootContext)(),en=(0,v.useFieldItemContext)(),{labelId:ei,controlId:es,registerControlId:eo,getDescriptionProps:ed}=(0,C.useLabelableContext)(),eu=function(e=!0){let t=r.useContext(j);if(void 0===t&&!e)throw Error((0,k.default)(3));return t}(),ec=eu?.parent,em=ec&&eu.allValues,ef=G||en.disabled||eu?.disabled||S,ep=J??B,ex=W??ep,ey=(0,x.useBaseUiId)(),eh=(0,x.useBaseUiId)(),eb=es;em?eb=E?eh:`${ec.id}-${ex}`:P&&(eb=P);let eg={};em&&(E?eg=eu.parent.getParentProps():ex&&(eg=eu.parent.getChildProps(ex)));let{checked:ev=c,indeterminate:ew=D,onCheckedChange:eC,...eN}=eg,ek=eu?.value,ej=eu?.setValue,eM=eu?.defaultValue,eT=r.useRef(null),eR=(0,o.useRefWithInit)(()=>Symbol("checkbox-control")),e$=r.useRef(!1),{getButtonProps:eI,buttonRef:eA}=(0,h.useButton)({disabled:ef,native:L}),eS=eu?.validation??el,[eK,eP]=(0,n.useControlled)({controlled:ex&&ek&&!E?ek.includes(ex):ev,default:ex&&eM&&!E?eM.includes(ex):I,name:"Checkbox",state:"checked"}),eD=em?!!ev:eK,eF=em&&ew||D;(0,i.useIsoLayoutEffect)(()=>{eo!==l.NOOP&&(e$.current=!0,eo(eR.current,eb))},[eb,eo,eR]),r.useEffect(()=>{let e=eR.current;return()=>{e$.current&&eo!==l.NOOP&&(e$.current=!1,eo(e,void 0))}},[eo,eR]),(0,g.useRegisterFieldControl)(eT,ey,eK,void 0,!eu&&!ef,B);let eB=r.useRef(null),e_=(0,s.useMergedRefs)(F,eB,eS.inputRef,eS.registerInput),eE=(0,N.useAriaLabelledBy)(A,ei,eB,!L,eb??void 0);(0,i.useIsoLayoutEffect)(()=>{eB.current&&(eB.current.indeterminate=eF,eK&&Z(!0))},[eK,eF,Z]),(0,$.useValueChanged)(eK,()=>{eu||(V(ep),Z(eK),Y(eK!==er.initialValue),eS.change(eK))});let eq=(0,y.mergeProps)({checked:eK,disabled:ef,form:K,name:E?void 0:ep,id:L?void 0:eb??void 0,required:H,ref:e_,style:ep?d.visuallyHiddenInput:d.visuallyHidden,tabIndex:-1,type:"checkbox","aria-hidden":!0,onChange(e){if(e.nativeEvent.defaultPrevented)return;if(q)return void e.preventDefault();let t=e.currentTarget.checked,a=(0,T.createChangeEventDetails)(R.REASONS.none,e.nativeEvent);_?.(t,a),a.isCanceled||(eC?.(t,a),!a.isCanceled&&(eP(t),ex&&ek&&ej&&!E&&!em&&ej(t?[...ek,ex]:ek.filter(e=>e!==ex),a)))},onFocus(){eT.current?.focus()}},void 0!==W?{value:(eu?eK&&W:W)||""}:l.EMPTY_OBJECT,ed,e=>eS.getValidationProps(ef,e));r.useEffect(()=>{if(!ec||!ex)return;let e=ec.disabledStatesRef.current;return e.set(ex,ef),()=>{e.delete(ex)}},[ec,ef,ex]);let eQ=r.useMemo(()=>({...et,checked:eD,disabled:ef,readOnly:q,required:H,indeterminate:eF}),[et,eD,ef,q,H,eF]),eH=f(eQ),eO=(0,p.useRenderElement)("span",e,{state:eQ,ref:[eA,eT,t,eu?.registerControlRef],props:[{id:L?eb??void 0:ey,role:"checkbox","aria-checked":eF?"mixed":eD,"aria-readonly":q||void 0,"aria-required":H||void 0,"aria-labelledby":eE,"data-parent":E?"":void 0,onFocus(){ef||X(!0)},onBlur(){let e=eB.current;e&&(ee(!0),X(!1),"onBlur"===ea&&eS.commit(eu?ek:e.checked))},onKeyDown(e){if("Enter"!==e.key||(e.preventBaseUIHandler(),e.defaultPrevented))return;let t=eB.current?.form??null,a=e.currentTarget,r=e.nativeEvent,l=e.preventDefault,n=r.preventDefault,i=!1;e.preventDefault=()=>{i=!0,l.call(e)},r.preventDefault=()=>{i=!0,n.call(r)},n.call(r),(0,u.ownerWindow)(a).queueMicrotask(()=>{e.preventDefault=l,r.preventDefault=n,i||(function(e){if(!e)return null;for(let t of e.elements){let e=t.tagName;if(("BUTTON"===e||"INPUT"===e)&&"submit"===t.type)return t}return null})(t)?.click()})},onClick(e){if(q||ef)return;e.preventDefault();let t=eB.current;t&&t.dispatchEvent(new((0,u.ownerWindow)(t)).PointerEvent("click",{bubbles:!0,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,altKey:e.altKey,metaKey:e.metaKey}))}},z,eN,eI,ed,e=>eS.getValidationProps(ef,e)],stateAttributesMapping:eH});return(0,a.jsxs)(M.Provider,{value:eQ,children:[eO,!eK&&!eu&&ep&&!E&&void 0!==O&&(0,a.jsx)("input",{type:"hidden",form:K,name:ep,value:O,disabled:ef}),(0,a.jsx)("input",{...eq,suppressHydrationWarning:!0})]})});var A=e.i(137584),S=e.i(223910),K=e.i(209407);let P=r.forwardRef(function(e,t){let{render:a,className:l,style:n,keepMounted:i=!1,...s}=e,o=function(){let e=r.useContext(M);if(void 0===e)throw Error((0,k.default)(14));return e}(),d=o.checked||o.indeterminate,{mounted:u,transitionStatus:c,setMounted:x}=(0,S.useTransitionStatus)(d),y=r.useRef(null),h={...o,transitionStatus:c};(0,A.useOpenChangeComplete)({open:d,ref:y,onComplete(){d||x(!1)}});let b={...f(o),...K.transitionStatusMapping,...m.fieldValidityMapping},g=(0,p.useRenderElement)("span",e,{ref:[t,y],state:h,stateAttributesMapping:b,props:s});return i||u?g:null});e.s(["Indicator",0,P,"Root",0,I],26749);var D=e.i(26749),D=D,F=e.i(196631),B=e.i(678784);e.s(["Checkbox",0,function({className:e,...t}){return(0,a.jsx)(D.Root,{"data-slot":"checkbox",className:(0,F.cn)("peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",e),...t,children:(0,a.jsx)(D.Indicator,{"data-slot":"checkbox-indicator",className:"grid place-content-center text-current transition-none [&>svg]:size-3.5",children:(0,a.jsx)(B.CheckIcon,{})})})}],257428)},500330,e=>{"use strict";var t=e.i(417385);let a=(e,t=0,a=!1,r=!0)=>{if(null==e||!Number.isFinite(e)||0===e&&!r)return"-";let l={minimumFractionDigits:t,maximumFractionDigits:t};if(!a)return e.toLocaleString("en-US",l);let n=e<0?"-":"",i=Math.abs(e),s=i,o="";return i>=1e6?(s=i/1e6,o="M"):i>=1e3&&(s=i/1e3,o="K"),`${n}${s.toLocaleString("en-US",l)}${o}`},r=async(e,a="Copied to clipboard")=>{if(!e)return!1;if(!navigator||!navigator.clipboard||!navigator.clipboard.writeText)return l(e,a);try{return await navigator.clipboard.writeText(e),t.toast.success(a),!0}catch(t){return console.error("Clipboard API failed: ",t),l(e,a)}},l=(e,a)=>{try{let r=document.createElement("textarea");r.value=e,r.style.position="fixed",r.style.left="-999999px",r.style.top="-999999px",r.setAttribute("readonly",""),document.body.appendChild(r),r.focus(),r.select();let l=document.execCommand("copy");if(document.body.removeChild(r),l)return t.toast.success(a),!0;throw Error("execCommand failed")}catch(e){return t.toast.fromError("Failed to copy to clipboard"),console.error("Failed to copy: ",e),!1}};e.s(["copyToClipboard",0,r,"formatNumberWithCommas",0,a,"getSpendString",0,(e,t=6)=>{if(null==e||!Number.isFinite(e)||0===e)return"-";let r=a(e,t,!1,!1);if(0===Number(r.replace(/,/g,""))){let e=(1/10**t).toFixed(t);return`< $${e}`}return`$${r}`}])},67488,e=>{"use strict";var t=e.i(843476),a=e.i(463059),r=e.i(618566),l=e.i(196631);function n(e){let t=(0,r.useRouter)();return a=>{a.metaKey||a.ctrlKey||a.shiftKey||1===a.button||(a.preventDefault(),t.push(e))}}e.s(["EntityLink",0,function({href:e,className:r,children:i}){let s=n(e);return(0,t.jsxs)("a",{href:e,onClick:s,className:(0,l.cn)("group inline-flex min-w-0 max-w-full items-center gap-0.5 font-semibold underline-offset-4 hover:underline",r),children:[(0,t.jsx)("span",{className:"min-w-0 truncate",children:i}),(0,t.jsx)(a.ChevronRight,{className:"size-3.5 shrink-0 text-muted-foreground transition-colors group-hover:text-foreground"})]})},"useEntityLinkClick",0,n])},581070,e=>{"use strict";var t=e.i(843476),a=e.i(746798);e.s(["CellTooltip",0,function({content:e,trigger:r}){return(0,t.jsx)(a.TooltipProvider,{delay:300,children:(0,t.jsxs)(a.Tooltip,{children:[(0,t.jsx)(a.TooltipTrigger,{render:r}),(0,t.jsx)(a.TooltipContent,{children:e})]})})}])},112179,e=>{"use strict";var t=e.i(843476),a=e.i(67488),r=e.i(487486),l=e.i(196631),n=e.i(581070);let i={success:"border-success/20 bg-success/10 text-success",error:"border-destructive/20 bg-destructive/10 text-destructive",warning:"border-warning/20 bg-warning/10 text-warning",neutral:"border-border bg-muted text-muted-foreground",info:"border-info/20 bg-info/10 text-info"};function s({href:e,dataTestId:n,className:i,children:o}){let d=(0,a.useEntityLinkClick)(e);return(0,t.jsx)(r.Badge,{variant:"outline","data-testid":n,className:(0,l.cn)("cursor-pointer hover:underline",i),render:(0,t.jsx)("a",{href:e,onClick:d}),children:o})}e.s(["StatusBadge",0,function({tone:e,label:a,tooltip:o,dataTestId:d,className:u,href:c}){let m=(0,l.cn)("whitespace-nowrap font-normal",i[e],u),f=c?(0,t.jsx)(s,{href:c,dataTestId:d,className:m,children:a}):(0,t.jsx)(r.Badge,{variant:"outline","data-testid":d,className:m,children:a});return o?(0,t.jsx)(n.CellTooltip,{content:o,trigger:f}):f}])},625901,e=>{"use strict";var t=e.i(266027),a=e.i(621482),r=e.i(912598),l=e.i(243652),n=e.i(602869),i=e.i(135214);let s=(0,l.createQueryKeys)("models"),o=(0,l.createQueryKeys)("modelHub"),d=(0,l.createQueryKeys)("allProxyModels");(0,l.createQueryKeys)("selectedTeamModels");let u=(0,l.createQueryKeys)("infiniteModels"),c=(0,l.createQueryKeys)("userModels"),m=new Set,f=e=>!!e?.litellm_params?.model?.startsWith("auto_router/"),p=e=>new Set(e.filter(f).map(e=>e.model_name).filter(e=>!!e)),x=e=>e.filter(f),y=e=>{let t=p(e);return new Set(e.map(e=>e.model_name).filter(e=>!!e).filter(e=>!t.has(e)))},h=async(e,t,a)=>{let r=await (0,n.modelInfoCall)(e,t,a,1,1e3),l=r?.total_pages??1;return[r,...await Promise.all(Array.from({length:Math.max(0,l-1)},(r,l)=>(0,n.modelInfoCall)(e,t,a,l+2,1e3)))].flatMap(e=>e?.data??[])},b=(e,t)=>s.list({filters:{scope:"autoRouters",...e&&{userId:e},...t&&{userRole:t}}});e.s(["autoRouterListKey",0,b,"fetchAllModelDeployments",0,h,"isAutoRouterDeployment",0,f,"useAllProxyModels",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:d.list({}),queryFn:async()=>await (0,n.modelAvailableCall)(e,a,r,!0,null,!0,!1,"expand"),enabled:!!(e&&a&&r)})},"useAutoRouterModelGroups",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)(),{data:l}=(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await h(e,a,r),enabled:!!(e&&a&&r),select:p});return l??m},"useAutoRouters",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await h(e,a,r),enabled:!!(e&&a&&r),select:x})},"useInfiniteModelInfo",0,(e=50,t)=>{let{accessToken:r,userId:l,userRole:s}=(0,i.default)();return(0,a.useInfiniteQuery)({queryKey:u.list({filters:{...l&&{userId:l},...s&&{userRole:s},size:e,...t&&{search:t}}}),queryFn:async({pageParam:a})=>await (0,n.modelInfoCall)(r,l,s,a,e,t),initialPageParam:1,getNextPageParam:e=>{if(e.current_page{let e=(0,r.useQueryClient)();return async()=>{await e.invalidateQueries({queryKey:s.lists()})}},"useModelHub",0,()=>{let{accessToken:e}=(0,i.default)();return(0,t.useQuery)({queryKey:o.list({}),queryFn:async()=>await (0,n.modelHubCall)(e),enabled:!!e})},"useModelsInfo",0,(e=1,a=50,r,l,o,d,u,c=!1,m,f,p=!1)=>{let{accessToken:x,userId:y,userRole:h}=(0,i.default)();return(0,t.useQuery)({queryKey:s.list({filters:{...y&&{userId:y},...h&&{userRole:h},page:e,size:a,...r&&{search:r},...m&&{modelName:m},...l&&{modelId:l},...o&&{teamId:o},...d&&{sortBy:d},...u&&{sortOrder:u},...c&&{excludeAutoRouters:"true"},...f&&{accessGroup:f},...p&&{wildcardOnly:"true"}}}),queryFn:async()=>await (0,n.modelInfoCall)(x,y,h,e,a,r,l,o,d,u,c,m,f,p),enabled:!!(x&&y&&h)})},"usePlainModelGroups",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)(),{data:l}=(0,t.useQuery)({queryKey:b(a,r),queryFn:async()=>await h(e,a,r),enabled:!!(e&&a&&r),select:y});return l??m},"useUserModels",0,()=>{let{accessToken:e,userId:a,userRole:r}=(0,i.default)();return(0,t.useQuery)({queryKey:c.list({}),queryFn:async()=>(await (0,n.modelAvailableCall)(e,a,r)).data.map(e=>e.id),enabled:!!(e&&a&&r)})}])},199931,e=>{"use strict";let t=(0,e.i(475254).default)("waypoints",[["circle",{cx:"12",cy:"4.5",r:"2.5",key:"r5ysbb"}],["path",{d:"m10.2 6.3-3.9 3.9",key:"1nzqf6"}],["circle",{cx:"4.5",cy:"12",r:"2.5",key:"jydg6v"}],["path",{d:"M7 12h10",key:"b7w52i"}],["circle",{cx:"19.5",cy:"12",r:"2.5",key:"1piiel"}],["path",{d:"m13.8 17.7 3.9-3.9",key:"1wyg1y"}],["circle",{cx:"12",cy:"19.5",r:"2.5",key:"13o1pw"}]]);e.s(["Waypoints",0,t],199931)},548151,200208,e=>{"use strict";var t=e.i(843476),a=e.i(271645),r=e.i(199931),l=e.i(625901),n=e.i(487486),i=e.i(196631);let s=new Set,o=(0,a.createContext)(s);function d(e){let t=(0,a.useContext)(o);return!!e&&t.has(e)}e.s(["AutoRouterIcon",0,function({size:e=12,className:a}){return(0,t.jsx)(r.Waypoints,{size:e,className:a,"aria-hidden":!0})},"AutoRouterModelGroupsProvider",0,function({children:e}){let a=(0,l.useAutoRouterModelGroups)();return(0,t.jsx)(o.Provider,{value:a,children:e})},"AutoRouterTag",0,function({modelGroup:e,className:a}){return d(e)?(0,t.jsxs)(n.Badge,{variant:"secondary",title:`Routed by auto-router "${e}"`,className:(0,i.cn)("gap-1.5 px-2.5 py-1 text-sm font-normal text-foreground",a),children:[(0,t.jsx)(r.Waypoints,{"aria-hidden":!0}),e]}):null},"useIsAutoRoutedModelGroup",0,d],548151);var u=e.i(581070);let c=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],m=e=>String(e).padStart(2,"0"),f=(e,t)=>"date"===t?`${c[e.getMonth()]} ${e.getDate()}, ${e.getFullYear()}`:`${c[e.getMonth()]} ${e.getDate()}, ${m(e.getHours())}:${m(e.getMinutes())}:${m(e.getSeconds())}`;e.s(["DateCell",0,function({value:e,precision:a="datetime",fallback:r="-"}){let l,n,i,s=e?new Date(e):null;return!s||Number.isNaN(s.getTime())?(0,t.jsx)("span",{className:"text-muted-foreground",children:r}):(0,t.jsx)(u.CellTooltip,{content:(l=Intl.DateTimeFormat().resolvedOptions().timeZone,n=`${c[s.getMonth()]} ${s.getDate()}, ${s.getFullYear()}`,i=`${m(s.getHours())}:${m(s.getMinutes())}:${m(s.getSeconds())}`,`${n}, ${i} (${l})`),trigger:(0,t.jsx)("span",{className:"whitespace-nowrap",children:f(s,a)})})},"formatCellDate",0,f],200208)},399536,e=>{"use strict";var t=e.i(843476),a=e.i(174886),r=e.i(196631),l=e.i(500330),n=e.i(581070);let i={pill:{base:"font-mono text-xs font-normal px-2 py-0.5 rounded-md text-left bg-info/10 text-info",clickable:"hover:bg-info/15 cursor-pointer"},plain:{base:"font-mono text-xs text-left",clickable:"hover:text-info cursor-pointer"}};e.s(["IdCell",0,function({value:e,variant:s="pill",onClick:o,copyable:d=!1,truncate:u=!0,fallback:c="-",tooltip:m,disabled:f=!1,dataTestId:p,className:x}){if(!e)return(0,t.jsx)("span",{className:"text-muted-foreground",children:c});let y=!!o&&!f,h=(0,r.cn)(i[s].base,y&&i[s].clickable,u&&"block max-w-[15ch] truncate",f&&"opacity-50",x),b=y?(0,t.jsx)("button",{type:"button",className:h,"data-testid":p,onClick:()=>o(e),children:e}):(0,t.jsx)("span",{className:h,"data-testid":p,children:e}),g=(0,t.jsx)(n.CellTooltip,{content:m??e,trigger:b});return d?(0,t.jsxs)("span",{className:"inline-flex max-w-full items-center gap-1",children:[g,(0,t.jsx)("button",{type:"button","aria-label":"Copy ID",className:"shrink-0 cursor-pointer text-muted-foreground hover:text-foreground",onClick:t=>{t.stopPropagation(),(0,l.copyToClipboard)(e)},children:(0,t.jsx)(a.Copy,{className:"size-3"})})]}):g}])},997422,146512,547227,e=>{"use strict";var t=e.i(843476),a=e.i(463059),r=e.i(67488),l=e.i(196631);let n="group -mx-2 flex w-[calc(100%+1rem)] cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-left transition-colors hover:bg-muted",i=()=>(0,t.jsx)(a.ChevronRight,{className:"ml-auto size-4 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100"});function s({href:e,className:a,body:o}){let d=(0,r.useEntityLinkClick)(e);return(0,t.jsxs)("a",{href:e,onClick:d,className:(0,l.cn)(n,a),children:[o,(0,t.jsx)(i,{})]})}e.s(["IdentityCell",0,function({title:e,subtitle:a,badge:r,onClick:o,href:d,className:u,titleClassName:c}){let m=(0,t.jsxs)("div",{className:"flex min-w-0 flex-col gap-0.5",children:[(0,t.jsx)("span",{className:(0,l.cn)("truncate text-sm font-medium text-foreground",c),children:e}),(null!=a&&""!==a||null!=r)&&(0,t.jsxs)("span",{className:"flex min-w-0 items-center gap-2",children:[null!=a&&""!==a&&(0,t.jsx)("span",{className:"truncate font-mono text-xs text-muted-foreground",children:a}),r]})]});return null!=d?(0,t.jsx)(s,{href:d,className:u,body:m}):null!=o?(0,t.jsxs)("button",{type:"button",onClick:o,className:(0,l.cn)(n,u),children:[m,(0,t.jsx)(i,{})]}):(0,t.jsx)("div",{className:(0,l.cn)("min-w-0",u),children:m})}],997422);let o={hasModelAccess:!1,label:"Management"},d={hasModelAccess:!1,label:"Read-only"},u={hasModelAccess:!1,label:"SCIM"},c={hasModelAccess:!0,label:null},m=e=>e.startsWith("/scim"),f=(e,t)=>1===e.length&&e[0]===t,p=(e,t)=>"management"===t?o:"read_only"===t?d:Array.isArray(e)&&0!==e.length?e.every(m)?u:f(e,"management_routes")?o:f(e,"info_routes")?d:c:c;e.s(["deriveKeyModelScope",0,p],146512);var x=e.i(355619),y=e.i(487486),h=e.i(581070);let b="all-proxy-models",g=e=>{if(e===b)return"All Proxy Models";let t=(0,x.getModelDisplayName)(e);return t.length>30?`${t.slice(0,30)}...`:t};e.s(["ModelsCell",0,function({models:e,maxVisible:a=3,allowedRoutes:r,keyType:l}){if(!Array.isArray(e)||0===e.length){let e=p(r,l);return e.hasModelAccess?(0,t.jsx)(y.Badge,{variant:"secondary",children:"All Proxy Models"}):(0,t.jsx)(h.CellTooltip,{content:`Scoped to ${e.label} routes; this key cannot call any models`,trigger:(0,t.jsx)(y.Badge,{variant:"secondary",className:"cursor-default",children:"No model access"})})}let n=e.slice(0,a),i=e.slice(a);return(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-1",children:[n.map((e,a)=>(0,t.jsx)(y.Badge,{variant:e===b?"secondary":"outline",children:g(e)},a)),i.length>0&&(0,t.jsx)(h.CellTooltip,{content:(0,t.jsx)("div",{className:"flex max-w-[280px] flex-col gap-0.5",children:i.map((e,a)=>(0,t.jsx)("span",{children:g(e)},a))}),trigger:(0,t.jsxs)(y.Badge,{variant:"outline",className:"cursor-default",children:["+",i.length," more"]})})]})}],547227)},964471,e=>{"use strict";var t=e.i(843476),a=e.i(500330);let r="block w-full whitespace-nowrap text-right tabular-nums text-muted-foreground";e.s(["MoneyCell",0,function({value:e,decimals:l=4,emptyText:n="-",showZero:i=!1}){if(null==e||!Number.isFinite(e))return(0,t.jsx)("span",{className:r,children:n});if(0===e&&!i)return(0,t.jsx)("span",{className:r,children:"-"});let s=0===e?`$${(0,a.formatNumberWithCommas)(0,l,!1,!0)}`:(0,a.getSpendString)(e,l);return(0,t.jsx)("span",{"data-slot":"money-cell",className:"block w-full whitespace-nowrap text-right tabular-nums",children:s})}])},622826,92982,630500,e=>{"use strict";e.i(548151),e.i(581070),e.i(200208),e.i(399536),e.i(997422),e.i(547227),e.i(964471);var t=e.i(843476),a=e.i(746798),r=e.i(500330);function l({gates:e}){return 0===e.length?null:(0,t.jsx)(a.SimpleTooltip,{content:(0,t.jsxs)("div",{"data-testid":"inherited-budget-hint",className:"flex flex-col gap-1",children:[(0,t.jsx)("span",{children:"This key has no budget of its own, but its spend still counts toward:"}),e.map(e=>(0,t.jsx)("span",{children:`${e.scope} ${e.alias}: $${(0,r.formatNumberWithCommas)(e.maxBudget,2)}${e.budgetDuration?` / ${e.budgetDuration}`:""}`},e.scope))]})})}e.s(["InheritedBudgetHint",0,l,"inheritedBudgetGates",0,(e,t)=>{let a;return[e&&null!=e.max_budget?{scope:"Team",alias:e.team_alias||e.team_id,maxBudget:e.max_budget,budgetDuration:e.budget_duration??null}:null,(a=t?.litellm_budget_table,t&&a?.max_budget!=null?{scope:"Organization",alias:t.organization_alias||t.organization_id,maxBudget:a.max_budget,budgetDuration:a.budget_duration??null}:null)].filter(e=>null!==e)}],92982);var n=e.i(936557);e.s(["SpendBudgetCell",0,function({spend:e,maxBudget:a,inheritedGates:i=[],spendDecimals:s=4,budgetDecimals:o=0}){let d="number"!=typeof e||Number.isNaN(e)?0:e,u=a??null,c="number"==typeof u&&u>0,m=c?d/u*100:0,f=d>0?(0,r.getSpendString)(d,s):"$0.00",p=null===u?"· Unlimited":`of $${(0,r.formatNumberWithCommas)(u,o)}`;return(0,t.jsxs)("div",{className:"flex min-w-[130px] flex-col gap-1",children:[(0,t.jsxs)("div",{className:"whitespace-nowrap text-xs",children:[(0,t.jsx)("span",{className:"font-medium tabular-nums text-foreground",children:f})," ",(0,t.jsx)("span",{className:"text-muted-foreground",children:p}),null===u&&(0,t.jsx)(l,{gates:i})]}),c&&(0,t.jsx)(n.Meter,{value:d,max:u,"aria-valuetext":`${f} of $${(0,r.formatNumberWithCommas)(u,o)}`,children:(0,t.jsx)(n.MeterTrack,{children:(0,t.jsx)(n.MeterIndicator,{tone:m>100?"over":m>=80?"warning":"default"})})})]})}],630500),e.i(112179),e.s([],622826)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/04oxg_atba30d.js b/litellm/proxy/_experimental/out/_next/static/chunks/04oxg_atba30d.js
new file mode 100644
index 00000000000..7b85e6eab72
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/04oxg_atba30d.js
@@ -0,0 +1 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,196361,e=>{e.q("/litellm-asset-prefix/_next/static/media/arize.2q0zcoh7v2j00.png")},614148,e=>{e.q("/litellm-asset-prefix/_next/static/media/aws.2vuu_29f0wx7g.svg")},858236,e=>{e.q("/litellm-asset-prefix/_next/static/media/braintrust.1qnhppdggfxdj.png")},508296,e=>{e.q("/litellm-asset-prefix/_next/static/media/datadog.20j6djly_hrsx.png")},324755,e=>{e.q("/litellm-asset-prefix/_next/static/media/galileo.1jnyj81fv75mp.ico")},475151,e=>{e.q("/litellm-asset-prefix/_next/static/media/lago.146vobxeazdxy.svg")},274286,e=>{e.q("/litellm-asset-prefix/_next/static/media/langfuse.1y39530irujaj.png")},436494,e=>{e.q("/litellm-asset-prefix/_next/static/media/langsmith.0cuekyutow5l_.png")},989974,e=>{e.q("/litellm-asset-prefix/_next/static/media/newrelic.2xvdqc3-98gjw.png")},204086,e=>{e.q("/litellm-asset-prefix/_next/static/media/openmeter.1wzo3xv7qwtb8.png")},531150,e=>{e.q("/litellm-asset-prefix/_next/static/media/otel.1dei3v2u03nit.png")},992619,e=>{"use strict";var t=e.i(843476),a=e.i(271645),l=e.i(531245),r=e.i(343488),s=e.i(793479),i=e.i(552546),n=e.i(695411);e.s(["default",0,({accessToken:e,value:o,placeholder:d="Select a Model",onChange:c,disabled:u=!1,style:m,className:x,showLabel:f=!0,labelText:g="Select Model"})=>{let[p,h]=(0,a.useState)(o),[b,v]=(0,a.useState)(!1),[y,j]=(0,a.useState)([]);(0,a.useEffect)(()=>{h(o)},[o]),(0,a.useEffect)(()=>{e&&(async()=>{try{let t=await (0,n.fetchAvailableModels)(e);t.length>0&&j(t)}catch(e){console.error("Error fetching model info:",e)}})()},[e]);let N=(0,r.useDebouncedCallback)(e=>{h(e),c?.(e)},{wait:500});return(0,t.jsxs)("div",{children:[f&&(0,t.jsxs)("p",{className:"font-medium block mb-2 text-foreground flex items-center",children:[(0,t.jsx)(l.Bot,{className:"mr-2 size-3.5"})," ",g]}),(0,t.jsx)("div",{style:{width:"100%",...m},className:`rounded-md ${x||""}`,children:(0,t.jsx)(i.SearchSelect,{options:[...Array.from(new Set(y.map(e=>e.model_group))).map(e=>({value:e,label:e})),{value:"custom",label:"Enter custom model"}],value:p,placeholder:d,onValueChange:e=>{"custom"===e?(v(!0),h(void 0)):(v(!1),h(e),c&&c(e))},disabled:u})}),b&&(0,t.jsx)(s.Input,{className:"mt-2",placeholder:"Enter custom model name",onChange:e=>N(e.target.value),disabled:u})]})}])},916940,e=>{"use strict";var t=e.i(843476),a=e.i(271645),l=e.i(602869),r=e.i(845150);e.s(["default",0,({onChange:e,value:s,className:i,accessToken:n,placeholder:o="Select vector stores",disabled:d=!1})=>{let[c,u]=(0,a.useState)([]),[m,x]=(0,a.useState)(!1);return(0,a.useEffect)(()=>{(async()=>{if(n){x(!0);try{let e=await (0,l.vectorStoreListCall)(n);e.data&&u(e.data)}catch(e){console.error("Error fetching vector stores:",e)}finally{x(!1)}}})()},[n]),(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(r.MultiSelect,{placeholder:o,onValueChange:e,value:s,loading:m,className:i,disabled:d,options:c.map(e=>({label:`${e.vector_store_name||e.vector_store_id} (${e.vector_store_id})`,value:e.vector_store_id,description:e.vector_store_description||void 0}))})})}])},68155,e=>{"use strict";var t=e.i(271645);let a=t.forwardRef(function(e,a){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:a},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,a],68155)},250980,e=>{"use strict";var t=e.i(271645);let a=t.forwardRef(function(e,a){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:a},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlusCircleIcon",0,a],250980)},663435,e=>{"use strict";var t=e.i(843476),a=e.i(271645),l=e.i(744582),r=e.i(785242);e.s(["default",0,({value:e,onChange:s,onTeamSelect:i,disabled:n,organizationId:o,pageSize:d=20,id:c})=>{let[u,m]=(0,a.useState)(""),{data:x,fetchNextPage:f,hasNextPage:g,isFetchingNextPage:p,isLoading:h}=(0,r.useInfiniteTeams)(d,u||void 0,o),b=(0,a.useMemo)(()=>{if(!x?.pages)return[];let e=new Set,t=[];for(let a of x.pages)for(let l of a.teams)e.has(l.team_id)||(e.add(l.team_id),t.push(l));return t},[x]);return(0,t.jsx)("div",{"data-testid":"team-dropdown",children:(0,t.jsx)(l.PaginatedSearchSelect,{options:b.map(e=>({label:e.team_alias||e.team_id,value:e.team_id,sublabel:e.team_id})),value:e||void 0,onValueChange:e=>{s?.(e||null),i&&i(e?b.find(t=>t.team_id===e)??null:null)},onSearchChange:m,onLoadMore:f,hasNextPage:g,isLoading:h,isFetchingNextPage:p,placeholder:"Search or select a team",emptyText:"No teams found",loadingText:"Loading teams…",disabled:n,inputId:c})})}])},421436,e=>{"use strict";var t=e.i(843476),a=e.i(271645),l=e.i(131792);let r=(e,t)=>e.label.toLowerCase().includes(t.trim().toLowerCase());e.s(["TagsInput",0,({value:e,onValueChange:s,options:i=[],placeholder:n,emptyText:o="No matching options",tokenSeparators:d=[],loading:c=!1,disabled:u=!1,id:m})=>{let x=(0,l.useComboboxAnchor)(),[f,g]=(0,a.useState)(""),p=e.map(e=>i.find(t=>t.value===e)??{label:e,value:e}),h=f.trim(),b=h.length>0&&!i.some(e=>e.value===h)?[{label:h,value:h},...i]:i,v=t=>{let a=t.map(e=>e.trim()).filter(Boolean).filter((t,a,l)=>l.indexOf(t)===a&&!e.includes(t));a.length>0&&s([...e,...a])},y=()=>{g(""),v([f])},j=e=>{"Enter"!==e.key||(e.preventDefault(),e.currentTarget.getAttribute("aria-activedescendant")||y())};return(0,t.jsxs)(l.Combobox,{multiple:!0,items:b,value:p,onValueChange:e=>{g(""),s(e.map(e=>e.value))},inputValue:f,onInputValueChange:e=>{if(!d.some(t=>e.includes(t)))return void g(e);let t=d.reduce((e,t)=>e.flatMap(e=>e.split(t)),[e]);g(t[t.length-1]??""),v(t.slice(0,-1))},isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:r,openOnInputClick:!0,disabled:u||c,children:[(0,t.jsx)(l.ComboboxChips,{render:(0,t.jsx)("div",{ref:x}),className:"min-h-8 py-1 text-sm",children:(0,t.jsx)(l.ComboboxValue,{children:e=>(0,t.jsxs)(t.Fragment,{children:[e.map(e=>(0,t.jsx)(l.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),(0,t.jsx)(l.ComboboxChipsInput,{id:m,placeholder:c?"Loading...":n,className:"min-w-24",onBlur:y,onKeyDown:j})]})})}),(0,t.jsxs)(l.ComboboxContent,{anchor:x,children:[(0,t.jsx)(l.ComboboxEmpty,{children:o}),(0,t.jsx)(l.ComboboxList,{children:e=>(0,t.jsx)(l.ComboboxItem,{value:e,title:e.label,children:e.label},e.value)})]})]})}])},629288,e=>{"use strict";var t,a=e.i(843476);e.s([],506329),e.i(506329),e.i(247167);var l=e.i(271645),r=e.i(828918),s=e.i(146376),i=e.i(667865),n=e.i(502077),o=e.i(956789),d=e.i(333848),c=e.i(675606),u=e.i(56434),m=e.i(209407),x=e.i(875812);let f=((t={}).checked="data-checked",t.unchecked="data-unchecked",t.disabled="data-disabled",t.readonly="data-readonly",t.required="data-required",t.valid="data-valid",t.invalid="data-invalid",t.touched="data-touched",t.dirty="data-dirty",t.filled="data-filled",t.focused="data-focused",t),g={checked:e=>e?{[f.checked]:""}:{[f.unchecked]:""},...m.transitionStatusMapping,...x.fieldValidityMapping};var p=e.i(788015),h=e.i(552245),b=e.i(540886),v=e.i(370359),y=e.i(348990),j=e.i(469690),N=e.i(157153),k=e.i(247778),w=e.i(31421),_=e.i(538489);let C=l.createContext(void 0);var S=e.i(186698),M=e.i(733332);let I=l.createContext(void 0),T=l.forwardRef(function(e,t){let{render:m,className:x,disabled:f=!1,readOnly:M=!1,required:T=!1,"aria-labelledby":E,value:R,inputRef:F,nativeButton:q=!1,id:A,style:P,...L}=e,O=l.useContext(C),{disabled:K,readOnly:V,required:D,form:B,checkedValue:$,touched:z=!1,validation:H,name:G}=O??{},Q=O?.setCheckedValue??o.NOOP,U=O?.setTouched??o.NOOP,W=O?.registerControlRef??o.NOOP,J=O?.registerInputRef??o.NOOP,{setTouched:Y,setFilled:X,state:Z,disabled:ee}=(0,j.useFieldRootContext)(),et=(0,N.useFieldItemContext)(),{labelId:ea,getDescriptionProps:el}=(0,k.useLabelableContext)(),er=ee||et.disabled||K||f,es=V||M,ei=D||T,en=O?$===R:""===R,eo=l.useRef(null),ed=l.useRef(null),ec=(0,i.useStableCallback)(e=>{e&&W(e,er)}),eu=(0,r.useMergedRefs)(F,ed,J);(0,s.useIsoLayoutEffect)(()=>{ed.current?.checked&&X(!0)},[X]),(0,s.useIsoLayoutEffect)(()=>{if(ed.current){if(er&&en)return void J(null);eo.current&&W(eo.current,er),J(ed.current)}},[en,er,W,J]);let em=(0,p.useBaseUiId)(),ex=(0,_.useLabelableId)({id:A,implicit:!1,controlRef:eo}),ef=q?void 0:ex,eg={role:"radio","aria-checked":en,"aria-required":ei||void 0,"aria-readonly":es||void 0,"aria-labelledby":(0,w.useAriaLabelledBy)(E,ea,ed,!q,ef),[v.ACTIVE_COMPOSITE_ITEM]:en?"":void 0,id:q?ex:em,onKeyDown(e){"Enter"===e.key&&e.preventDefault()},onClick(e){if(e.defaultPrevented||er||es)return;e.preventDefault();let t=ed.current;t&&t.dispatchEvent(new((0,d.ownerWindow)(t)).PointerEvent("click",{bubbles:!0,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,altKey:e.altKey,metaKey:e.metaKey}))},onFocus(e){e.defaultPrevented||er||es||!z||(ed.current?.click(),U(!1))}},{getButtonProps:ep,buttonRef:eh}=(0,b.useButton)({disabled:er,native:q,composite:!1}),eb={type:"radio",ref:eu,form:B,id:ef,name:G,tabIndex:-1,style:G?n.visuallyHiddenInput:n.visuallyHidden,"aria-hidden":!0,...void 0!==R?{value:(0,S.serializeValue)(R)}:o.EMPTY_OBJECT,disabled:er,checked:en,required:ei,readOnly:es,onChange(e){if(e.nativeEvent.defaultPrevented||er||es||void 0===R)return;let t=(0,c.createChangeEventDetails)(u.REASONS.none,e.nativeEvent);Q(R,t),t.isCanceled||Y(!0)},onFocus(){eo.current?.focus()}},ev=l.useMemo(()=>({...Z,required:ei,disabled:er,readOnly:es,checked:en}),[Z,er,es,en,ei]),ey=void 0!==O,ej=[t,eo,eh,ec],eN=[eg,L,ep,el,H?e=>H.getValidationProps(er,e):o.EMPTY_OBJECT],ek=(0,h.useRenderElement)("span",e,{enabled:!ey,state:ev,ref:ej,props:eN,stateAttributesMapping:g});return(0,a.jsxs)(I.Provider,{value:ev,children:[ey?(0,a.jsx)(y.CompositeItem,{tag:"span",render:m,className:x,style:P,state:ev,refs:ej,props:eN,stateAttributesMapping:g}):ek,(0,a.jsx)("input",{...eb,suppressHydrationWarning:!0})]})});var E=e.i(137584),R=e.i(223910);let F=l.forwardRef(function(e,t){let{render:a,className:r,style:s,keepMounted:i=!1,...n}=e,o=function(){let e=l.useContext(I);if(void 0===e)throw Error((0,M.default)(52));return e}(),d=o.checked,{mounted:c,transitionStatus:u,setMounted:m}=(0,R.useTransitionStatus)(d),x={...o,transitionStatus:u},f=l.useRef(null),p=(0,h.useRenderElement)("span",e,{ref:[t,f],state:x,props:n,stateAttributesMapping:g});return((0,E.useOpenChangeComplete)({open:d,ref:f,onComplete(){d||m(!1)}}),i||c)?p:null});e.s(["Indicator",0,F,"Root",0,T],66747);var q=e.i(66747),q=q,A=e.i(951437),P=e.i(647554),L=e.i(673327),O=e.i(405934),K=e.i(381104);let V=l.createContext(void 0);var D=e.i(884708),B=e.i(606039);let $=[L.SHIFT],z=l.forwardRef(function(e,t){let{render:r,className:s,disabled:n,readOnly:o,required:d,onValueChange:c,value:u,defaultValue:m,form:f,name:g,inputRef:h,id:b,style:v,...y}=e,{setTouched:N,setFocused:w,validationMode:_,name:S,disabled:I,state:T,validation:E,setDirty:R,setFilled:F,validityData:q}=(0,j.useFieldRootContext)(),{labelId:L}=(0,k.useLabelableContext)(),{clearErrors:z}=(0,D.useFormContext)(),H=function(e=!1){let t=l.useContext(V);if(!t&&!e)throw Error((0,M.default)(86));return t}(!0),G=I||n,Q=S??g,U=(0,p.useBaseUiId)(b),[W,J]=(0,A.useControlled)({controlled:u,default:m,name:"RadioGroup",state:"value"}),[Y,X]=l.useState(!1),Z=(0,i.useStableCallback)((e,t)=>{c?.(e,t),t.isCanceled||J(e)}),ee=l.useRef(null),et=l.useRef(null),ea=l.useRef(null);function el(e){let t;return h&&("function"==typeof h?t=h(e):h.current=e),et.current=e,E.inputRef.current=e,t}let er=(0,i.useStableCallback)((e,t=!1)=>{if(e){if(t){ee.current===e&&(ee.current=null);return}null==ee.current&&(ee.current=e)}}),es=(0,i.useStableCallback)(e=>{if(!e||e.disabled)return;ea.current||(ea.current=e);let t=et.current;if(e.checked||null==t||t.disabled)return el(e)}),ei=(0,i.useStableCallback)(()=>{let e=et.current;return e&&!e.disabled&&e.checked?W??null:null});(0,K.useRegisterFieldControl)(ee,U,W??null,ei,!G,g),(0,B.useValueChanged)(W,()=>{z(Q),R(W!==q.initialValue),F(null!=W),E.change(W);let e=ea.current;null==W&&e&&!e.disabled&&el(e)});let en=y["aria-labelledby"]??L??H?.legendId,eo={...T,disabled:G??!1,required:d??!1,readOnly:o??!1},ed=l.useMemo(()=>({...T,checkedValue:W,disabled:G,form:f,validation:E,name:Q,readOnly:o,registerControlRef:er,registerInputRef:es,required:d,setCheckedValue:Z,setTouched:X,touched:Y}),[W,G,f,E,T,Q,o,er,es,d,Z,X,Y]);return(0,a.jsx)(C.Provider,{value:ed,children:(0,a.jsx)(O.CompositeRoot,{render:r,className:s,style:v,state:eo,props:[{id:b,role:"radiogroup","aria-required":d||void 0,"aria-disabled":G||void 0,"aria-readonly":o||void 0,"aria-labelledby":en,onFocus(){w(!0)},onBlur(e){(0,P.contains)(e.currentTarget,e.relatedTarget)||(N(!0),w(!1),"onBlur"===_&&E.commit(W))},onKeyDownCapture(e){e.key.startsWith("Arrow")&&(X(!0),w(!0))}},y,e=>E.getValidationProps(G??!1,e)],refs:[t],stateAttributesMapping:x.fieldValidityMapping,enableHomeAndEndKeys:!1,modifierKeys:$})})});var H=e.i(196631);e.s(["RadioGroup",0,function({className:e,...t}){return(0,a.jsx)(z,{"data-slot":"radio-group",className:(0,H.cn)("grid w-full gap-3",e),...t})},"RadioGroupItem",0,function({className:e,...t}){return(0,a.jsx)(q.Root,{"data-slot":"radio-group-item",className:(0,H.cn)("group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",e),...t,children:(0,a.jsx)(q.Indicator,{"data-slot":"radio-group-indicator",className:"flex size-4 items-center justify-center",children:(0,a.jsx)("span",{className:"absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary-foreground"})})})}],629288)},695411,e=>{"use strict";var t=e.i(355619),a=e.i(602869);let l=e=>({model_group:(e.model_group||e.id||e.model_name)??"",...e.mode&&{mode:e.mode},...!0===e.supports_reasoning&&{supports_reasoning:!0},...void 0!==e.supported_reasoning_efforts&&{supported_reasoning_efforts:e.supported_reasoning_efforts}}),r=async(e,l)=>{let r=await (0,a.modelAvailableCall)(e,"","",!1,l),s=(r?.data??[]).map(e=>e.id);return(0,t.excludeProxyWideSentinel)(Array.from(new Set(s))).sort((e,t)=>e.localeCompare(t)).map(e=>({model_group:e}))},s=async e=>{try{let t=await (0,a.modelHubCall)(e),r=t?.data,s=(Array.isArray(r)?r:[]).map(l).filter(e=>""!==e.model_group).sort((e,t)=>e.model_group.localeCompare(t.model_group));return Array.from(new Map(s.map(e=>[e.model_group,e])).values())}catch(e){throw console.error("Error fetching model info:",e),e}};e.s(["fetchAvailableModels",0,s,"fetchAvailableModelsForTeam",0,r])},552546,e=>{"use strict";var t=e.i(843476),a=e.i(131792);let l=(e,t)=>{let a=t.trim().toLowerCase();return!a||e.label.toLowerCase().includes(a)||(e.sublabel?.toLowerCase().includes(a)??!1)};e.s(["SearchSelect",0,function({options:e,value:r,onValueChange:s,placeholder:i="Select…",emptyText:n="No results",disabled:o=!1,className:d,inputId:c,allowClear:u=!0,"aria-label":m}){let x=void 0===r||""===r?null:e.find(e=>e.value===r)??{label:r,value:r},f=null===x||e.some(e=>e.value===x.value)?e:[x,...e];return(0,t.jsxs)(a.Combobox,{items:f,value:x,onValueChange:e=>s(e?.value??""),isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:l,disabled:o,children:[(0,t.jsx)(a.ComboboxInput,{id:c,"aria-label":m,placeholder:i,showClear:u&&null!=r&&""!==r,className:`h-8 w-full text-sm ${d??""}`}),(0,t.jsxs)(a.ComboboxContent,{side:"bottom",collisionAvoidance:{side:"shift",align:"shift",fallbackAxisSide:"none"},children:[(0,t.jsx)(a.ComboboxEmpty,{children:n}),(0,t.jsx)(a.ComboboxList,{children:e=>(0,t.jsxs)(a.ComboboxItem,{value:e,children:[e.icon,(0,t.jsxs)("span",{className:"flex min-w-0 flex-col",children:[(0,t.jsx)("span",{className:"truncate",children:e.label}),null!=e.sublabel&&""!==e.sublabel&&(0,t.jsx)("span",{className:"truncate text-xs text-muted-foreground",children:e.sublabel})]})]},e.value)})]})]})}])},864261,e=>{"use strict";var t=e.i(751247),a=e.i(135214),l=e.i(441228);e.s(["default",0,e=>{let{userRole:r}=(0,a.default)(),s=(0,l.default)();return(0,t.hasCapability)(r,e,s)}])},63209,e=>{"use strict";var t=e.i(361653);e.s(["AlertCircle",()=>t.default])},158392,425063,334115,419470,e=>{"use strict";var t=e.i(843476),a=e.i(793479);let l={ttl:3600,lowest_latency_buffer:0},r=({routingStrategyArgs:e})=>{let r={ttl:"Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-foreground",children:"Latency-Based Configuration"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Fine-tune latency-based routing behavior"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e||l).map(([e,l])=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-foreground uppercase tracking-wide",children:e.replace(/_/g," ")}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5 mb-2",children:r[e]||""}),(0,t.jsx)(a.Input,{name:e,defaultValue:"object"==typeof l?JSON.stringify(l,null,2):l?.toString(),className:"font-mono text-sm w-full"})]})},e))})]}),(0,t.jsx)("div",{className:"border-t border-border"})]})},s=({routerSettings:e,routerFieldsMetadata:l})=>(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-foreground",children:"Reliability & Retries"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Configure retry logic and failure handling"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e).filter(([e])=>"fallbacks"!=e&&"context_window_fallbacks"!=e&&"routing_strategy_args"!=e&&"routing_strategy"!=e&&"enable_tag_filtering"!=e&&"retry_policy"!=e&&"model_group_retry_policy"!=e&&"routing_groups"!=e).map(([e,r])=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-foreground uppercase tracking-wide",children:l[e]?.ui_field_name||e}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5 mb-2",children:l[e]?.field_description||""}),(0,t.jsx)(a.Input,{name:e,defaultValue:null==r||"null"===r?"":"object"==typeof r?JSON.stringify(r,null,2):r?.toString()||"",placeholder:"—",className:"font-mono text-sm w-full"})]})},e))})]});var i=e.i(967489);let n=({selectedStrategy:e,availableStrategies:a,routingStrategyDescriptions:l,routerFieldsMetadata:r,onStrategyChange:s})=>(0,t.jsxs)("div",{className:"space-y-2 max-w-3xl",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"text-xs font-medium text-foreground uppercase tracking-wide",children:r.routing_strategy?.ui_field_name||"Routing Strategy"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5 mb-2",children:r.routing_strategy?.field_description||""})]}),(0,t.jsx)("div",{className:"routing-strategy-select max-w-3xl",children:(0,t.jsxs)(i.Select,{value:e,onValueChange:e=>e&&s(e),children:[(0,t.jsx)(i.SelectTrigger,{className:"w-full",children:(0,t.jsx)(i.SelectValue,{})}),(0,t.jsx)(i.SelectContent,{children:a.map(e=>(0,t.jsx)(i.SelectItem,{value:e,children:(0,t.jsxs)("div",{className:"flex flex-col gap-0.5 py-1",children:[(0,t.jsx)("span",{className:"font-mono text-sm font-medium",children:e}),l[e]&&(0,t.jsx)("span",{className:"text-xs font-normal text-muted-foreground",children:l[e]})]})},e))})]})})]});var o=e.i(271645),d=e.i(699375);let c=({enabled:e,routerFieldsMetadata:a,onToggle:l})=>{let r=(0,o.useId)();return(0,t.jsx)("div",{className:"space-y-3 max-w-3xl",children:(0,t.jsxs)("div",{className:"flex items-start justify-between",children:[(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("label",{htmlFor:r,className:"text-xs font-medium text-foreground uppercase tracking-wide",children:a.enable_tag_filtering?.ui_field_name||"Enable Tag Filtering"}),(0,t.jsxs)("p",{className:"text-xs text-muted-foreground mt-0.5",children:[a.enable_tag_filtering?.field_description||"",a.enable_tag_filtering?.link&&(0,t.jsxs)(t.Fragment,{children:[" ",(0,t.jsx)("a",{href:a.enable_tag_filtering.link,target:"_blank",rel:"noopener noreferrer",className:"text-info hover:text-info/80 underline",children:"Learn more"})]})]})]}),(0,t.jsx)(d.Switch,{id:r,checked:e,onCheckedChange:l,className:"ml-4"})]})})};e.s(["default",0,({value:e,onChange:a,routerFieldsMetadata:l,availableRoutingStrategies:i,routingStrategyDescriptions:o})=>(0,t.jsxs)("div",{className:"w-full space-y-8 py-2",children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-foreground",children:"Routing Settings"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Configure how requests are routed to deployments"})]}),i.length>0&&(0,t.jsx)(n,{selectedStrategy:e.selectedStrategy||e.routerSettings.routing_strategy||null,availableStrategies:i,routingStrategyDescriptions:o,routerFieldsMetadata:l,onStrategyChange:t=>{a({...e,selectedStrategy:t})}}),(0,t.jsx)(c,{enabled:e.enableTagFiltering,routerFieldsMetadata:l,onToggle:t=>{a({...e,enableTagFiltering:t})}})]}),(0,t.jsx)("div",{className:"border-t border-border"}),"latency-based-routing"===e.selectedStrategy&&(0,t.jsx)(r,{routingStrategyArgs:e.routerSettings.routing_strategy_args}),(0,t.jsx)(s,{routerSettings:e.routerSettings,routerFieldsMetadata:l})]})],158392);var u=e.i(519455),m=e.i(677572),x=e.i(107233),f=e.i(37727),g=e.i(417385),p=e.i(845150),h=e.i(552546),b=e.i(63209);let v=(0,e.i(475254).default)("arrow-down",[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]]);function y({group:e,onChange:a,availableModels:l,maxFallbacks:r,disablePrimaryModel:s=!1}){let i=l.filter(t=>t!==e.primaryModel),n=e.fallbackModels.length({label:e,value:e})),value:e.primaryModel??"",onValueChange:t=>{let l=[...e.fallbackModels];l.includes(t)&&(l=l.filter(e=>e!==t)),a({...e,primaryModel:t,fallbackModels:l})},placeholder:"Select primary model",emptyText:"No models found",disabled:s,className:"h-12"}),!s&&!e.primaryModel&&(0,t.jsxs)("div",{className:"mt-2 flex items-center gap-2 text-warning text-xs bg-warning/10 p-2 rounded-sm",children:[(0,t.jsx)(b.AlertCircle,{className:"w-4 h-4"}),(0,t.jsx)("span",{children:"Select a model to begin configuring fallbacks"})]})]}),(0,t.jsx)("div",{className:"flex items-center justify-center -my-4 z-raised",children:(0,t.jsxs)("div",{className:"bg-indigo-50 text-indigo-500 px-4 py-1 rounded-full text-xs font-bold border border-indigo-100 flex items-center gap-2 shadow-xs dark:bg-indigo-950 dark:text-indigo-300 dark:border-indigo-900",children:[(0,t.jsx)(v,{className:"w-4 h-4"}),"IF FAILS, TRY..."]})}),(0,t.jsxs)("div",{className:`transition-opacity duration-300 ${!e.primaryModel?"opacity-50 pointer-events-none":"opacity-100"}`,children:[(0,t.jsxs)("label",{className:"block text-sm font-semibold text-foreground mb-2",children:["Fallback Chain ",(0,t.jsx)("span",{className:"text-destructive",children:"*"}),(0,t.jsxs)("span",{className:"text-xs text-muted-foreground font-normal ml-2",children:["(Max ",r," fallbacks at a time)"]})]}),(0,t.jsxs)("div",{className:"bg-muted rounded-xl p-4 border border-border",children:[(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)(p.MultiSelect,{options:i.map(e=>({label:e,value:e})),value:e.fallbackModels,onValueChange:t=>{let l=t.slice(0,r);a({...e,fallbackModels:l})},placeholder:n?"Select fallback models to add...":`Maximum ${r} fallbacks reached`,emptyText:"No models found",disabled:!e.primaryModel,className:"w-full"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-1 ml-1",children:n?`Search and select multiple models. Selected models will appear below in order. (${e.fallbackModels.length}/${r} used)`:`Maximum ${r} fallbacks reached. Remove some to add more.`})]}),(0,t.jsx)("div",{className:"space-y-2 min-h-[100px]",children:0===e.fallbackModels.length?(0,t.jsxs)("div",{className:"h-32 border-2 border-dashed border-border rounded-lg flex flex-col items-center justify-center text-muted-foreground",children:[(0,t.jsx)("span",{className:"text-sm",children:"No fallback models selected"}),(0,t.jsx)("span",{className:"text-xs mt-1",children:"Add models from the dropdown above"})]}):(0,t.jsx)("ol",{"aria-label":"Fallback chain",className:"space-y-2",children:e.fallbackModels.map((l,r)=>(0,t.jsxs)("li",{className:"group flex items-center justify-between p-3 bg-card rounded-lg border border-border hover:border-indigo-300 hover:shadow-xs transition-all",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-sm bg-muted text-muted-foreground group-hover:text-indigo-500 group-hover:bg-indigo-50 dark:group-hover:text-indigo-300 dark:group-hover:bg-indigo-950",children:(0,t.jsx)("span",{className:"text-xs font-bold",children:r+1})}),(0,t.jsx)("div",{children:(0,t.jsx)("span",{className:"font-medium text-foreground",children:l})})]}),(0,t.jsx)("button",{type:"button","aria-label":`Remove ${l}`,onClick:()=>{let t;return t=e.fallbackModels.filter((e,t)=>t!==r),void a({...e,fallbackModels:t})},className:"opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive p-1",children:(0,t.jsx)(f.X,{className:"w-4 h-4"})})]},`${l}-${r}`))})})]})]})]})}e.s(["ArrowDown",0,v],425063),e.s(["FallbackGroupConfig",0,y],334115),e.s(["FallbackSelectionForm",0,function({groups:e,onGroupsChange:a,availableModels:l,maxFallbacks:r=10,maxGroups:s=5}){let[i,n]=(0,o.useState)(e.length>0?e[0].id:"1");(0,o.useEffect)(()=>{e.length>0?e.some(e=>e.id===i)||n(e[0].id):n("1")},[e]);let d=()=>{if(e.length>=s)return;let t=Date.now().toString();a([...e,{id:t,primaryModel:null,fallbackModels:[]}]),n(t)},c=t=>{a(e.map(e=>e.id===t.id?t:e))},p=(e,t)=>e.primaryModel?e.primaryModel:`Group ${t+1}`;return 0===e.length?(0,t.jsxs)("div",{className:"text-center py-12 bg-muted rounded-lg border border-dashed border-border",children:[(0,t.jsx)("p",{className:"text-muted-foreground mb-4",children:"No fallback groups configured"}),(0,t.jsxs)(u.Button,{onClick:d,children:[(0,t.jsx)(x.Plus,{className:"w-4 h-4"}),"Create First Group"]})]}):(0,t.jsxs)(m.Tabs,{value:i,onValueChange:n,children:[(0,t.jsxs)("div",{className:"flex items-center border-b",children:[(0,t.jsx)(m.TabsList,{variant:"line",className:"h-auto justify-start rounded-none p-0",children:e.map((l,r)=>(0,t.jsxs)("div",{className:"relative flex items-center",children:[(0,t.jsx)(m.TabsTrigger,{value:l.id,className:`flex-none rounded-none py-2 pl-4 ${e.length>1?"pr-9":"pr-4"}`,children:p(l,r)}),e.length>1&&(0,t.jsx)(u.Button,{variant:"ghost",size:"icon-xs",className:"absolute right-1","aria-label":`Remove ${p(l,r)}`,onClick:()=>(t=>{if(1===e.length)return void g.toast.warning("At least one group is required");let l=e.filter(e=>e.id!==t);a(l),i===t&&l.length>0&&n(l[l.length-1].id)})(l.id),children:(0,t.jsx)(f.X,{})})]},l.id))}),e.length(0,t.jsx)(m.TabsContent,{value:e.id,className:"pt-4",children:(0,t.jsx)(y,{group:e,onChange:c,availableModels:l,maxFallbacks:r})},e.id))]})}],419470)},207082,e=>{"use strict";var t=e.i(619273),a=e.i(621482),l=e.i(266027),r=e.i(243652),s=e.i(602869),i=e.i(431703),n=e.i(135214);let o=(0,r.createQueryKeys)("keys"),d=async(e,t,a,l={})=>{try{let r=(0,s.getProxyBaseUrl)(),n=new URLSearchParams(Object.entries({team_id:l.teamID,project_id:l.projectID,agent_id:l.agentID,organization_id:l.organizationID,key_alias:l.selectedKeyAlias,key_hash:l.keyHash,search:l.search,user_id:l.userID,page:t,size:a,sort_by:l.sortBy,sort_order:l.sortOrder,expand:l.expand,status:l.status,return_full_object:"true",include_team_keys:"true",include_created_by_keys:"true",substring_matching:"true"}).filter(([,e])=>null!=e).map(([e,t])=>[e,String(t)])),o=`${r?`${r}/key/list`:"/key/list"}?${n}`,d=await fetch(o,{method:"GET",headers:{[(0,s.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!d.ok){let e=await d.json(),t=(0,i.deriveErrorMessage)(e);throw(0,s.handleError)(t),Error(t)}return await d.json()}catch(e){throw console.error("Failed to list keys:",e),e}},c=(0,r.createQueryKeys)("infiniteKeys"),u=(0,r.createQueryKeys)("deletedKeys");e.s(["keyKeys",0,o,"useDeletedKeys",0,(e,a,r={})=>{let{accessToken:s}=(0,n.default)();return(0,l.useQuery)({queryKey:u.list({page:e,limit:a,...r}),queryFn:async()=>await d(s,e,a,{...r,status:"deleted"}),enabled:!!s,staleTime:3e4,placeholderData:t.keepPreviousData})},"useInfiniteKeys",0,(e,t={})=>{let{accessToken:l}=(0,n.default)(),r={queryKey:c.list({limit:e,...t}),queryFn:async({pageParam:a})=>{if(!l)throw Error("Access token required");return await d(l,a,e,t)},initialPageParam:1,getNextPageParam:e=>e.current_page{let{accessToken:s}=(0,n.default)();return(0,l.useQuery)({queryKey:o.list({page:e,limit:a,...r}),queryFn:async()=>await d(s,e,a,r),enabled:!!s,staleTime:3e4,placeholderData:t.keepPreviousData})}])}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/059psjgsicqvu.js b/litellm/proxy/_experimental/out/_next/static/chunks/059psjgsicqvu.js
new file mode 100644
index 00000000000..042d9ea0700
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/059psjgsicqvu.js
@@ -0,0 +1 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,196361,e=>{e.q("/litellm-asset-prefix/_next/static/media/arize.2q0zcoh7v2j00.png")},614148,e=>{e.q("/litellm-asset-prefix/_next/static/media/aws.2vuu_29f0wx7g.svg")},858236,e=>{e.q("/litellm-asset-prefix/_next/static/media/braintrust.1qnhppdggfxdj.png")},508296,e=>{e.q("/litellm-asset-prefix/_next/static/media/datadog.20j6djly_hrsx.png")},324755,e=>{e.q("/litellm-asset-prefix/_next/static/media/galileo.1jnyj81fv75mp.ico")},475151,e=>{e.q("/litellm-asset-prefix/_next/static/media/lago.146vobxeazdxy.svg")},274286,e=>{e.q("/litellm-asset-prefix/_next/static/media/langfuse.1y39530irujaj.png")},436494,e=>{e.q("/litellm-asset-prefix/_next/static/media/langsmith.0cuekyutow5l_.png")},989974,e=>{e.q("/litellm-asset-prefix/_next/static/media/newrelic.2xvdqc3-98gjw.png")},204086,e=>{e.q("/litellm-asset-prefix/_next/static/media/openmeter.1wzo3xv7qwtb8.png")},531150,e=>{e.q("/litellm-asset-prefix/_next/static/media/otel.1dei3v2u03nit.png")},992619,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(531245),l=e.i(343488),r=e.i(793479),s=e.i(552546),o=e.i(695411);e.s(["default",0,({accessToken:e,value:n,placeholder:d="Select a Model",onChange:c,disabled:A=!1,style:u,className:g,showLabel:h=!0,labelText:m="Select Model"})=>{let[p,x]=(0,i.useState)(n),[f,b]=(0,i.useState)(!1),[v,_]=(0,i.useState)([]);(0,i.useEffect)(()=>{x(n)},[n]),(0,i.useEffect)(()=>{e&&(async()=>{try{let t=await (0,o.fetchAvailableModels)(e);t.length>0&&_(t)}catch(e){console.error("Error fetching model info:",e)}})()},[e]);let w=(0,l.useDebouncedCallback)(e=>{x(e),c?.(e)},{wait:500});return(0,t.jsxs)("div",{children:[h&&(0,t.jsxs)("p",{className:"font-medium block mb-2 text-foreground flex items-center",children:[(0,t.jsx)(a.Bot,{className:"mr-2 size-3.5"})," ",m]}),(0,t.jsx)("div",{style:{width:"100%",...u},className:`rounded-md ${g||""}`,children:(0,t.jsx)(s.SearchSelect,{options:[...Array.from(new Set(v.map(e=>e.model_group))).map(e=>({value:e,label:e})),{value:"custom",label:"Enter custom model"}],value:p,placeholder:d,onValueChange:e=>{"custom"===e?(b(!0),x(void 0)):(b(!1),x(e),c&&c(e))},disabled:A})}),f&&(0,t.jsx)(r.Input,{className:"mt-2",placeholder:"Enter custom model name",onChange:e=>w(e.target.value),disabled:A})]})}])},68155,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"}))});e.s(["TrashIcon",0,i],68155)},250980,e=>{"use strict";var t=e.i(271645);let i=t.forwardRef(function(e,i){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:i},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"}))});e.s(["PlusCircleIcon",0,i],250980)},916940,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(602869),l=e.i(845150);e.s(["default",0,({onChange:e,value:r,className:s,accessToken:o,placeholder:n="Select vector stores",disabled:d=!1})=>{let[c,A]=(0,i.useState)([]),[u,g]=(0,i.useState)(!1);return(0,i.useEffect)(()=>{(async()=>{if(o){g(!0);try{let e=await (0,a.vectorStoreListCall)(o);e.data&&A(e.data)}catch(e){console.error("Error fetching vector stores:",e)}finally{g(!1)}}})()},[o]),(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(l.MultiSelect,{placeholder:n,onValueChange:e,value:r,loading:u,className:s,disabled:d,options:c.map(e=>({label:`${e.vector_store_name||e.vector_store_id} (${e.vector_store_id})`,value:e.vector_store_id,description:e.vector_store_description||void 0}))})})}])},519380,e=>{e.q("/litellm-asset-prefix/_next/static/media/bedrock.2vhamxr8q6y4o.svg")},946013,e=>{e.q("/litellm-asset-prefix/_next/static/media/google.3y8ypywwtqob_.svg")},641266,e=>{e.q("/litellm-asset-prefix/_next/static/media/microsoft_azure.3626-7zx7wf09.svg")},956529,e=>{e.q("/litellm-asset-prefix/_next/static/media/openai_small.3rj8nedgjpevh.svg")},913383,e=>{e.q("/litellm-asset-prefix/_next/static/media/a2a_agent.14el5-6dflh1h.png")},238564,e=>{e.q("/litellm-asset-prefix/_next/static/media/ai21.0m_u-tih8nm0v.svg")},941533,e=>{e.q("/litellm-asset-prefix/_next/static/media/aiml_api.1dq6dbpwklhlg.svg")},994636,e=>{e.q("/litellm-asset-prefix/_next/static/media/anthropic.3s95kgy8jpc64.svg")},824770,e=>{e.q("/litellm-asset-prefix/_next/static/media/assemblyai_small.0w_dslsra91uw.png")},920076,e=>{e.q("/litellm-asset-prefix/_next/static/media/baseten.41k2lnwp3c5g9.svg")},96889,e=>{e.q("/litellm-asset-prefix/_next/static/media/cerebras.1ur1xyfqk9ncz.svg")},348026,e=>{e.q("/litellm-asset-prefix/_next/static/media/cloudflare.2n1spdq7u5yki.svg")},727148,e=>{e.q("/litellm-asset-prefix/_next/static/media/cohere.22i3i2e449j5i.svg")},411703,e=>{e.q("/litellm-asset-prefix/_next/static/media/cometapi.3w0xficbg3dkk.svg")},922480,e=>{e.q("/litellm-asset-prefix/_next/static/media/cursor.1q1ev-_5l7exg.svg")},769490,e=>{e.q("/litellm-asset-prefix/_next/static/media/databricks.2hiet9qlqzn-g.svg")},829789,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepgram.3-krp20p_xed3.png")},41730,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepinfra.3lr_lsr7mhui6.png")},662576,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepseek.3n4cu0x32i_7w.svg")},987202,e=>{e.q("/litellm-asset-prefix/_next/static/media/elevenlabs.2982m_dk2-h_y.png")},953265,e=>{e.q("/litellm-asset-prefix/_next/static/media/fal_ai.3rahrirki8sby.jpg")},346512,e=>{e.q("/litellm-asset-prefix/_next/static/media/featherless.3hmlef3fhc0h5.svg")},84416,e=>{e.q("/litellm-asset-prefix/_next/static/media/fireworks.3t1b6p8edeqyo.svg")},104602,e=>{e.q("/litellm-asset-prefix/_next/static/media/friendli.0ymiswh6l35bq.svg")},771937,e=>{e.q("/litellm-asset-prefix/_next/static/media/gigachat.37uico956hu-u.svg")},888193,e=>{e.q("/litellm-asset-prefix/_next/static/media/github_copilot.3k-8jyadoaq2u.svg")},447500,e=>{e.q("/litellm-asset-prefix/_next/static/media/groq.20csmqzsusp1k.svg")},270039,e=>{e.q("/litellm-asset-prefix/_next/static/media/huggingface.1-07ypt9ii_-p.svg")},227733,e=>{e.q("/litellm-asset-prefix/_next/static/media/hyperbolic.3le20v59sebn8.svg")},823929,e=>{e.q("/litellm-asset-prefix/_next/static/media/infinity.0s9s12bl4lccx.png")},333845,e=>{e.q("/litellm-asset-prefix/_next/static/media/jina.0ukab8o-3-5m_.png")},813878,e=>{e.q("/litellm-asset-prefix/_next/static/media/lambda.26_vz7cmyuodo.svg")},767788,e=>{e.q("/litellm-asset-prefix/_next/static/media/lmstudio.35s3-83mlhcms.svg")},808630,e=>{e.q("/litellm-asset-prefix/_next/static/media/meta_llama.1kxk24vwsem49.svg")},468732,e=>{e.q("/litellm-asset-prefix/_next/static/media/minimax.2mfkkqc-lnsen.svg")},610503,e=>{e.q("/litellm-asset-prefix/_next/static/media/mistral.0n8jv_67hgq4h.svg")},438969,e=>{e.q("/litellm-asset-prefix/_next/static/media/moonshot.3__i9wvf37ksm.svg")},852459,e=>{e.q("/litellm-asset-prefix/_next/static/media/morph.2av06eo-t0-ve.svg")},494696,e=>{e.q("/litellm-asset-prefix/_next/static/media/nebius.2ipf7rmjccira.svg")},148973,e=>{e.q("/litellm-asset-prefix/_next/static/media/novita.0_nzmm_rl4lrf.svg")},570036,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_nim.1fz-5ugf_um0v.svg")},151170,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_triton.1aotoxig_m2w1.png")},862330,e=>{e.q("/litellm-asset-prefix/_next/static/media/ollama.144cif369atc5.svg")},788158,e=>{e.q("/litellm-asset-prefix/_next/static/media/openrouter.1xk7748-_jixf.svg")},350567,e=>{e.q("/litellm-asset-prefix/_next/static/media/oracle.43kws59xxr8ig.svg")},822797,e=>{e.q("/litellm-asset-prefix/_next/static/media/perplexity-ai.2do8hoc8tw__0.svg")},840911,e=>{e.q("/litellm-asset-prefix/_next/static/media/qwen.0a49x9i08_0gz.png")},445735,e=>{e.q("/litellm-asset-prefix/_next/static/media/recraft.2f4cv-c9ad-mo.svg")},635202,e=>{e.q("/litellm-asset-prefix/_next/static/media/replicate.445bidyix2tyh.svg")},669161,e=>{e.q("/litellm-asset-prefix/_next/static/media/runway.2zzwye1fddnnn.png")},159508,e=>{e.q("/litellm-asset-prefix/_next/static/media/sambanova.1vcyu0faw1x8h.svg")},544025,e=>{e.q("/litellm-asset-prefix/_next/static/media/sap.1367hgge0s0xl.png")},708767,e=>{e.q("/litellm-asset-prefix/_next/static/media/scx_ai.3emo1p5delrhx.svg")},100588,e=>{e.q("/litellm-asset-prefix/_next/static/media/snowflake.2_p8qqpi0r3lr.svg")},183804,e=>{e.q("/litellm-asset-prefix/_next/static/media/soniox.3nhjmssy7ybh7.svg")},865502,e=>{e.q("/litellm-asset-prefix/_next/static/media/togetherai.1wk-mouzgw5ho.svg")},96912,e=>{e.q("/litellm-asset-prefix/_next/static/media/topaz.3rjp3zvx4eags.svg")},395073,e=>{e.q("/litellm-asset-prefix/_next/static/media/v0.15trd3tb1ulop.svg")},407829,e=>{e.q("/litellm-asset-prefix/_next/static/media/vercel.1mvnwxofolt8y.svg")},846077,e=>{e.q("/litellm-asset-prefix/_next/static/media/vllm.3_gqby46r7s3x.png")},914861,e=>{e.q("/litellm-asset-prefix/_next/static/media/volcengine.23ly9ik_qc138.png")},285328,e=>{e.q("/litellm-asset-prefix/_next/static/media/voyage.0krq6ew-yr8dk.webp")},779278,e=>{e.q("/litellm-asset-prefix/_next/static/media/watsonx.19rrg39yvhpk8.svg")},325532,e=>{e.q("/litellm-asset-prefix/_next/static/media/xai.2kc3gjiopn9om.svg")},288330,e=>{e.q("/litellm-asset-prefix/_next/static/media/xinference.063cy_ievvy5u.svg")},922158,336712,39182,980385,e=>{"use strict";let t={src:e.i(519380).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,t],922158);let i={src:e.i(946013).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,i],336712);let a={src:e.i(641266).default,width:200,height:58,blurWidth:0,blurHeight:0};e.s(["default",0,a],39182);let l={src:e.i(956529).default,width:28,height:28,blurWidth:0,blurHeight:0};e.s(["default",0,l],980385)},916925,555987,9774,247044,e=>{"use strict";var t,i=e.i(221688),a=e.i(950643);let l=/^(https?:|data:|blob:|\/\/)/i,r=e=>l.test(e),s=(e,t=i.serverRootPath)=>{let l;if(!e)return;if(r(e)||e.includes("/_next/static/"))return e;let s=(0,a.normalizeRootPath)(t);return s&&(e===s||e.startsWith(`${s}/`))?e:(l=(0,a.normalizeRootPath)(t),`${l}${e.startsWith("/")?e:`/${e}`}`)};e.s(["isExternalAssetSrc",0,r,"resolveLogoSrc",0,s],555987);let o={src:e.i(913383).default,width:661,height:768,blurWidth:7,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAwUlEQVR42h2OvQpGcByFf5dK7oBJFoooJDaDZFA+BoVkNBikGJSUJINyGeft/Q+nznDO00O6rsM0Tfi+z6JpGizLgqqqIEVR0HUdqqqCbdus930PWZZBy7IgCAKkaYpxHJEkCaIowjAMoGmaEMcx8jxHURRo2xZ1XaMsS9B5nrjvG+u6Yp5nfN+H53nwJ9JxHMiyDO/7Mtx1Xey1bRvIcRzwPI993xGGIZqmgSAIMAwDJEkSPM9jphzHsYHruhBFET+hn6S8pf6D7AAAAABJRU5ErkJggg=="},n={src:e.i(238564).default,width:103,height:24,blurWidth:0,blurHeight:0},d={src:e.i(941533).default,width:115,height:24,blurWidth:0,blurHeight:0},c={src:e.i(994636).default,width:46,height:46,blurWidth:0,blurHeight:0},A={src:e.i(824770).default,width:28,height:28,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAlElEQVR42m3OoQqDUBQGYF9mwzLbFiZsMNgwuGa4YFgYLC6PgcXuA5gFzdcgFkExGr33ogZRNIr6CAoKKgo/nAMfh/NTu3u4GWoY+0fIAsIC3C8LuIiRH9S2W5wBXsBPKaHTGGb+lZMJmCe2vPYjZe9/bMDswKMRbq9Yg9VRICcBq3p6FckINIf6o6ECwyOam/1YpwPFUFu+Lt2F2QAAAABJRU5ErkJggg=="},u={src:e.i(920076).default,width:16,height:16,blurWidth:0,blurHeight:0};var g=e.i(922158);let h={src:e.i(96889).default,width:800,height:600,blurWidth:0,blurHeight:0},m={src:e.i(348026).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,m],9774);let p={src:e.i(727148).default,width:75,height:75,blurWidth:0,blurHeight:0},x={src:e.i(411703).default,width:16,height:16,blurWidth:0,blurHeight:0},f={src:e.i(922480).default,width:16,height:16,blurWidth:0,blurHeight:0},b={src:e.i(769490).default,width:16,height:16,blurWidth:0,blurHeight:0},v={src:e.i(829789).default,width:32,height:32,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAzklEQVR42k3PPWuDcBDHccUiiikYSwqhg+IkuKUpOLqK4OYrcBZcFCcH352mgy/Ch9mxEPg2+s+Q4W65zx33kyRJQpZlFOUNTdM4HN45Hi1Op0/O56+7tAHbtqmqiqZpKIqCy+Uby/rYkABhGLKuK+M4siwLt9sv1+sPpmkKEAQBwzCQpilxHDNNE3VdYxiGALqu47oujuMQRdEOyrJEVVUBFEUhSRK6rmOeZ/q+x/f97XkBHqfIsoy2bcnzHM/z9mSP2Q62dt/0c+O1/v4BYRxu3LgaR7UAAAAASUVORK5CYII="},_={src:e.i(41730).default,width:225,height:225,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAfklEQVR42nVOvQqDMBjM+7+RpbQ0Ji2NQhwdzGIwCMZFiCAa9STqIPhxw/3A3UeW41w/AKck87w0tqvbngkFgEDCJOPoKc+fovxKzaUGiXkOk0zei1TRzDxYEbHiIw0kzD2Aji5BqHolW9Uv0+9U01AVxivr4r8CjHX7+N27K5WIrP56XsFTAAAAAElFTkSuQmCC"},w={src:e.i(662576).default,width:293,height:215,blurWidth:0,blurHeight:0},I={src:e.i(987202).default,width:1563,height:1563,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA5ElEQVR42h2PPwtBURjGj3wCk93sC1iUCYXFIlGSMjC4QiiTBSE3Ge5M3e0uPoJFBhOTP8NNukXduFL3uJ1Xzz11znCe93me38uitQSL11Pe8rAanKpycbSa5Ar9UiAmJT3QXHGwHGfvj/vJcRzOfz/7fLvsW4tuJFZLehicEIUQpOs6GYZBOIfrcZPp5f0MsXDatk2yLJOqqu6A9f2YjXk7zNCJWM45KYpCmqa5A6/P+ynNGiEGIHSiwjRNsiyLBAmxPezW6U7Gx0ALIHQiFk6I5WEl6G6BB7QAQqc0a4bgxD/uH4FYoVec8m3dAAAAAElFTkSuQmCC"},C={src:e.i(953265).default,width:400,height:400,blurWidth:8,blurHeight:8,blurDataURL:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAAIAAgDAREAAhEBAxEB/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtP9N/tL+PO/8A7ZeV/wDFUj6L917L+r3/AMj/2Q=="},y={src:e.i(346512).default,width:16,height:16,blurWidth:0,blurHeight:0},E={src:e.i(84416).default,width:16,height:16,blurWidth:0,blurHeight:0},k={src:e.i(104602).default,width:16,height:16,blurWidth:0,blurHeight:0},O={src:e.i(771937).default,width:1e3,height:1e3,blurWidth:0,blurHeight:0},N={src:e.i(888193).default,width:16,height:16,blurWidth:0,blurHeight:0};var j=e.i(336712);let L={src:e.i(447500).default,width:26,height:26,blurWidth:0,blurHeight:0},R={src:e.i(270039).default,width:16,height:16,blurWidth:0,blurHeight:0},S={src:e.i(227733).default,width:16,height:16,blurWidth:0,blurHeight:0},M={src:e.i(823929).default,width:128,height:129,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAApklEQVR42oWPsQrCMBRFY51KaUuwNktBQbcgSenQ32hCTBAHXfSfulUK4g/0/7yvdO+FB5dzXhLC2FoiJE3TfZ7nYrskyzIBVpBjTdPcu677GGPGtm1fmDd1YnVd31gIYSrLUnLOjxC9tfaLfhBCXLz307xQVZUCODvnfljoceAEpskxKeUV1w0Qo1LqobV+Lk8McI5tkDiOeZIkO9SIBr0gRm71l38QASaqNz7VMwAAAABJRU5ErkJggg=="},T={src:e.i(333845).default,width:200,height:200,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAXUlEQVR42p2MoRHAMAwDQwJzCcgCwQEZIDjA03gED2BzewSPWRe2qFcB3Z+kU0o/lXNea4U/0t77OYeIACDq4FLKnSKimYmIqjKzu885U6117z3GCGitxTbg/flJF7DAEmcR3WAqAAAAAElFTkSuQmCC"},B={src:e.i(813878).default,width:16,height:16,blurWidth:0,blurHeight:0},q={src:e.i(767788).default,width:16,height:16,blurWidth:0,blurHeight:0},D={src:e.i(808630).default,width:16,height:16,blurWidth:0,blurHeight:0};var H=e.i(39182);let U={src:e.i(468732).default,width:490,height:412,blurWidth:0,blurHeight:0},F={src:e.i(610503).default,width:16,height:16,blurWidth:0,blurHeight:0},P={src:e.i(438969).default,width:16,height:16,blurWidth:0,blurHeight:0},Q={src:e.i(852459).default,width:16,height:16,blurWidth:0,blurHeight:0},G={src:e.i(494696).default,width:16,height:16,blurWidth:0,blurHeight:0},W={src:e.i(148973).default,width:16,height:16,blurWidth:0,blurHeight:0},V={src:e.i(570036).default,width:16,height:16,blurWidth:0,blurHeight:0},z={src:e.i(151170).default,width:95,height:81,blurWidth:8,blurHeight:7,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAYAAAA1WQxeAAAA0UlEQVR42kXMvWrCUBjG8VxIL6KX0IvobXQSOrQd2kLSdMzQdMmaEErPUqoIIYtKOC5iFD9BEBwiaAY/AgpH/2oUfOGFh4cfj8blNmrNKK0zmFUZzmust2nea7u9IlkNkBMPv1Xgs3JHoXRDe1o+g8Vmyl/vnf++wU/7EdF54jW8JU6K14WTPgE3fjiCZ77kPa2kdAZZlrFcLpikXYLeN6Lxxm/zhfEsRimF5roupmli2zbGh4Gu61iWlX8URWhSSsIwxPM8hBA4jpNn3/cJgoADqC23HJzwo6wAAAAASUVORK5CYII="},K={src:e.i(862330).default,width:646,height:854,blurWidth:0,blurHeight:0};var Y=e.i(980385);let J={src:e.i(788158).default,width:300,height:300,blurWidth:0,blurHeight:0},X={src:e.i(350567).default,width:231,height:30,blurWidth:0,blurHeight:0},Z={src:e.i(822797).default,width:48,height:48,blurWidth:0,blurHeight:0},$={src:e.i(840911).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABE0lEQVR42gEIAff+AAAAAAAAAAAAEQwmIT8ukIAgGUpBBwYQDQQECggAAAAAAAIBBQQJBhUTFw80LUIxloZbR8+5UUS3oUA4kH0HBxEOACMUUkolFlVNCAYTERwUPzgkHFJIIhxNRCsmYVQODSAbADYffnNFKaCSDgkgHD0tjX4+MI5+CQgVEhQSLCULChgUABAKJiJTM7+vJhlYTzEkb2MxJm9iIh1NQywnZFYhH0o/AA8JIh9RMrurNiR9cQkHFhMQDSUgUkW5o1hOx60pJlxPAAcEDw4qGmJYFw80LhENKCMyKHFjUEK0nhEOJSADAwYFAAAAAAADAgcGBQMLCRUPMClCNJeEIRtLQgAAAQAAAAAAfjQxsiCQipMAAAAASUVORK5CYII="},ee={src:e.i(445735).default,width:16,height:16,blurWidth:0,blurHeight:0},et={src:e.i(635202).default,width:16,height:16,blurWidth:0,blurHeight:0},ei={src:e.i(669161).default,width:320,height:320,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7UlEQVR42lVQvc7BYBR+B/kM3w+fFm2p9m3fRhFRP7UQlTAQCVfAgE3EHZAQMTBIzBIrYbEgFhaza3ABrsF7bIYnOTl5/s5BVrvIY5MMvYTbUuy8hN8CcFIdW62CgHCKjFwie/So3PqH+b0Hc+GebkW6Lj9zUtJaHwEbFvGqWf7zOG5GJVmjcwUEAUOevQmhfKSTqJol+7f94RT+L7Yv25OV3PtsI699EByc85qpW5qcUCaMyB7orH9EgJLaTnPNgk/QfUsxKi0QtKWFzjRzA7a08IEPCivYKWkyQHAKtJUMPIVMQCAmz3FKHcELXnxEPy9E1lYCAAAAAElFTkSuQmCC"},ea={src:e.i(159508).default,width:52,height:46,blurWidth:0,blurHeight:0},el={src:e.i(544025).default,width:3300,height:2550,blurWidth:8,blurHeight:6,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAAZklEQVR42oWNTQ5AMBhE3f8mEhux4BgiIRzAwoKWplrt146fBbVhkpnNvORF+El0jvMAV4RR2qtsJZD3DyA2h6xhiMsRSTUhrRm0DYBFE4qOI285yl5CGvdW0OEYhEE/G6jgvIGv7A4KupBwIVaNAAAAAElFTkSuQmCC"},er={src:e.i(708767).default,width:760,height:277,blurWidth:0,blurHeight:0},es={src:e.i(100588).default,width:146,height:139,blurWidth:0,blurHeight:0};e.s(["default",0,es],247044);let eo={src:e.i(183804).default,width:100,height:18,blurWidth:0,blurHeight:0},en={src:e.i(865502).default,width:32,height:32,blurWidth:0,blurHeight:0},ed={src:e.i(96912).default,width:16,height:16,blurWidth:0,blurHeight:0},ec={src:e.i(395073).default,width:16,height:16,blurWidth:0,blurHeight:0},eA={src:e.i(407829).default,width:16,height:16,blurWidth:0,blurHeight:0},eu={src:e.i(846077).default,width:64,height:64,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAo0lEQVR42lWOvQrCQBCE7718oUA6wVcQBF/AXhu1CIgcpgoi/qCNguBPwCaChYHDv9zt3e6ZeEFxq9n5GGaY/T8iq3QhWKFRkZGWzEPaaE/RDoiI5e7z0BILP7tMB2vyO3p2BJew8syvvJLGQTPEaheSVJeAQIi5F2+CWt80uHopLMEnNBpPuNc2vaXK+38A4RauTvUhbBNwDvsOlYD3DA2Se99kLK7hC5QFVQAAAABJRU5ErkJggg=="},eg={src:e.i(914861).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7ElEQVR42l2LMUsCAQBG39GFFQ02ad1oq0QIRR2hER4EGdQqdBDdQZAFEudU0NZSQ0O1VUOjiuJvEBxc3BQFEVQQdFAU9OROFwf9lg/e48Hiti8vWJekBSoIODacLK04CP79IAX8815cW2X3IYL3JIhaKuKLGdNGmMUCTo+Hq1yO72yB6HDEeTrFjm8fUVwGt3uL00eD5+6AfMvixbS5bTR5/43jcm2CooT4KNf56ltUGzafA5uoZZGpdJDlABhPr7z1TJLtMbXamMT0702T//aQu0gM5GOFvRuNkKoTDuucqRpeXePoWuPg0D8BGkpJjYhKXN4AAAAASUVORK5CYII="},eh={src:e.i(285328).default,width:400,height:399,blurWidth:8,blurHeight:8,blurDataURL:"data:image/webp;base64,UklGRgwBAABXRUJQVlA4TAABAAAvB8ABEM1VICICHggIDgIAAIDzDAACD0FoAAARAAwAAAAAAAAAAAAAAACAAABAAcBCAoAWgGyoXwUAAA8E7QQCAADg/N+nrsYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4CClZXkg5AQAAAAA538LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL0HIgEAAAAAcP4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMsHA39Qutr2AtkROu8CASWZ/nMlNyzz5AdgWmkK65oUI6AlgIkY/M3zxIW3iABq15KT/Uz7BXidCOONHieAz1v6HqAC"},em={src:e.i(779278).default,width:16,height:16,blurWidth:0,blurHeight:0},ep={src:e.i(325532).default,width:1e3,height:1e3,blurWidth:0,blurHeight:0},ex={src:e.i(288330).default,width:16,height:16,blurWidth:0,blurHeight:0};var ef=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cognition="Cognition",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GIGACHAT="GigaChat",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="Hosted vLLM",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.NVIDIA_RIVA="Nvidia Riva",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.Qwen_AI_Platform="Qwen AI Platform",t.QwenCloud="QwenCloud",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.SCX_AI="SCX.ai",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Local vLLM",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let eb={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cognition:"cognition",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GIGACHAT:"gigachat",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",NVIDIA_RIVA:"nvidia_riva",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",Qwen_AI_Platform:"qwen_ai_platform",QwenCloud:"qwencloud",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",SCX_AI:"scx-ai",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},ev=new Set(["bedrock_mantle"]),e_={"A2A Agent":o.src,Ai21:n.src,"Ai21 Chat":n.src,"AI/ML API":d.src,"Aiohttp Openai":Y.default.src,Anthropic:c.src,"Anthropic Text":c.src,AssemblyAI:A.src,Azure:H.default.src,"Azure AI Foundry (Studio)":H.default.src,"Azure Text":H.default.src,Baseten:u.src,"Amazon Bedrock":g.default.src,"Amazon Bedrock Mantle":g.default.src,"AWS SageMaker":g.default.src,Cerebras:h.src,Cloudflare:m.src,Codestral:F.src,Cohere:p.src,"Cohere Chat":p.src,Cometapi:x.src,Cursor:f.src,"Databricks (Qwen API)":b.src,Dashscope:$.src,Deepseek:w.src,Deepgram:v.src,DeepInfra:_.src,ElevenLabs:I.src,"Fal AI":C.src,"Featherless Ai":y.src,"Fireworks AI":E.src,Friendliai:k.src,GigaChat:O.src,"Github Copilot":N.src,"Google AI Studio":j.default.src,Groq:L.src,"Hosted vLLM":eu.src,Huggingface:R.src,Hyperbolic:S.src,Infinity:M.src,"Jina AI":T.src,"Lambda Ai":B.src,"Lm Studio":q.src,"Meta Llama":D.src,MiniMax:U.src,"Mistral AI":F.src,Moonshot:P.src,Morph:Q.src,Nebius:G.src,Novita:W.src,"Nvidia Nim":V.src,"Nvidia Riva":V.src,Ollama:K.src,"Ollama Chat":K.src,Oobabooga:Y.default.src,OpenAI:Y.default.src,"Openai Like":Y.default.src,"OpenAI Text Completion":Y.default.src,"OpenAI-Compatible Completions (legacy /v1/completions)":Y.default.src,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":Y.default.src,Openrouter:J.src,"Oracle Cloud Infrastructure (OCI)":X.src,Perplexity:Z.src,"Qwen AI Platform":$.src,QwenCloud:$.src,Recraft:ee.src,Replicate:et.src,RunwayML:ei.src,Sagemaker:g.default.src,Sambanova:ea.src,"SAP Generative AI Hub":el.src,"SCX.ai":er.src,Snowflake:es.src,Soniox:eo.src,"Text-Completion-Codestral":F.src,TogetherAI:en.src,Topaz:ed.src,Triton:z.src,V0:ec.src,"Vercel Ai Gateway":eA.src,"Vertex AI (Anthropic, Gemini, etc.)":j.default.src,"Vertex Ai Beta":j.default.src,"Local vLLM":eu.src,VolcEngine:eg.src,"Voyage AI":eh.src,Watsonx:em.src,"Watsonx Text":em.src,xAI:ep.src,Xinference:ex.src},ew={"AI/ML API":"aiml/flux-pro/v1.1",Anthropic:"claude-3-opus",Azure:"my-deployment","Azure AI Foundry (Studio)":"azure_ai/command-r-plus","Amazon Bedrock":"claude-3-opus",Cognition:"cognition/swe-1.7",Cursor:"cursor/claude-4-sonnet",DeepInfra:"deepinfra/","Fal AI":"fal_ai/fal-ai/flux-pro/v1.1-ultra","Google AI Studio":"gemini-pro","Jina AI":"jina_ai/","Nvidia Riva":"nvidia_riva/nvidia/parakeet-ctc-1_1b-asr","Oracle Cloud Infrastructure (OCI)":"oci/xai.grok-4",RunwayML:"runwayml/gen4_turbo","AWS SageMaker":"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b","SCX.ai":"scx-ai/GLM-5.2",Snowflake:"snowflake/mistral-7b","Vertex AI (Anthropic, Gemini, etc.)":"gemini-pro",VolcEngine:"volcengine/","Voyage AI":"voyage/",Watsonx:"watsonx/ibm/granite-3-3-8b-instruct","Z.AI (Zhipu AI)":"zai/glm-4.5"};e.s(["Providers",()=>ef,"getPlaceholder",0,e=>ew[ef[e]??e]??"gpt-3.5-turbo","getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:s(e_[e])??"",displayName:e}}let t=Object.keys(eb).find(t=>eb[t].toLowerCase()===e.toLowerCase())??Object.keys(eb).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let i=ef[t];return{logo:s(e_[i])??"",displayName:i}},"getProviderModels",0,(e,t)=>{let i=eb[e],a=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let l=t.litellm_provider,r="string"==typeof l&&(l.startsWith(`${i}_`)||l.startsWith(`${i}-`));(l===i||r&&!ev.has(l))&&a.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&a.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&a.push(e)})),a},"providerLogoMap",0,e_,"provider_map",0,eb],916925)},174553,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(916925),l=e.i(555987),r=e.i(196631);let s=/(?:\/assets\/logos\/|\/_next\/static\/media\/)/,o={"baseten.svg":"invert","cursor.svg":"invert","enkrypt_ai.avif":"invert","friendli.svg":"invert","github.svg":"invert","github_copilot.svg":"invert","lago.svg":"invert","lambda.svg":"invert","langflow.svg":"invert","lmstudio.svg":"invert","moonshot.svg":"invert","nebius.svg":"invert","notion.svg":"invert","ollama.svg":"invert","openrouter.svg":"invert","promptguard.svg":"invert","recraft.svg":"invert","replicate.svg":"invert","runway.png":"invert","scx_ai.svg":"invert","secret_detect.png":"invert","topaz.svg":"invert","v0.svg":"invert","vercel.svg":"invert","watsonx.svg":"invert","aiml_api.svg":"plate","akto.svg":"plate","aws.svg":"plate","deepkeep.svg":"plate","fireworks.svg":"plate","llm_guard.png":"plate","pangea.png":"plate","repelloai.png":"plate","sambanova.svg":"plate","sentry.svg":"plate","valkey.svg":"plate"},n={invert:"dark:[filter:brightness(0)_invert(1)]",plate:"dark:bg-logo-surface dark:object-contain dark:p-0.5"};e.s(["Logo",0,({provider:e,src:d,label:c,className:A="w-4 h-4"})=>{let[u,g]=(0,i.useState)(null),h=void 0!==e?(0,a.getProviderLogoAndName)(e).logo:(0,l.resolveLogoSrc)(d)??"",m=c??e??"";if(u===h||!h)return(0,t.jsx)("div",{className:`${A} rounded-full bg-border flex items-center justify-center text-xs`,children:m.charAt(0)||"-"});let p=(e=>{let t;if(!e||(0,l.isExternalAssetSrc)(e)||!s.test(e))return;let i=e.split(/[?#]/)[0].split("/").pop()||void 0,a=void 0===i||(t=i.split(".")).length<2?void 0:`${t[0]}.${t[t.length-1]}`;return void 0===a?void 0:o[a]})(h);return(0,t.jsx)("img",{src:h,alt:`${m||"-"} logo`,className:void 0===p?A:(0,r.cn)(A,n[p]),onError:()=>{console.warn(`Logo failed to load: ${h}`),g(h)}})}],174553)},286536,e=>{"use strict";let t=(0,e.i(475254).default)("eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Eye",0,t],286536)},77705,e=>{"use strict";let t=(0,e.i(475254).default)("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["EyeOff",0,t],77705)},663435,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(744582),l=e.i(785242);e.s(["default",0,({value:e,onChange:r,onTeamSelect:s,disabled:o,organizationId:n,pageSize:d=20,id:c})=>{let[A,u]=(0,i.useState)(""),{data:g,fetchNextPage:h,hasNextPage:m,isFetchingNextPage:p,isLoading:x}=(0,l.useInfiniteTeams)(d,A||void 0,n),f=(0,i.useMemo)(()=>{if(!g?.pages)return[];let e=new Set,t=[];for(let i of g.pages)for(let a of i.teams)e.has(a.team_id)||(e.add(a.team_id),t.push(a));return t},[g]);return(0,t.jsx)("div",{"data-testid":"team-dropdown",children:(0,t.jsx)(a.PaginatedSearchSelect,{options:f.map(e=>({label:e.team_alias||e.team_id,value:e.team_id,sublabel:e.team_id})),value:e||void 0,onValueChange:e=>{r?.(e||null),s&&s(e?f.find(t=>t.team_id===e)??null:null)},onSearchChange:u,onLoadMore:h,hasNextPage:m,isLoading:x,isFetchingNextPage:p,placeholder:"Search or select a team",emptyText:"No teams found",loadingText:"Loading teams…",disabled:o,inputId:c})})}])},421436,e=>{"use strict";var t=e.i(843476),i=e.i(271645),a=e.i(131792);let l=(e,t)=>e.label.toLowerCase().includes(t.trim().toLowerCase());e.s(["TagsInput",0,({value:e,onValueChange:r,options:s=[],placeholder:o,emptyText:n="No matching options",tokenSeparators:d=[],loading:c=!1,disabled:A=!1,id:u})=>{let g=(0,a.useComboboxAnchor)(),[h,m]=(0,i.useState)(""),p=e.map(e=>s.find(t=>t.value===e)??{label:e,value:e}),x=h.trim(),f=x.length>0&&!s.some(e=>e.value===x)?[{label:x,value:x},...s]:s,b=t=>{let i=t.map(e=>e.trim()).filter(Boolean).filter((t,i,a)=>a.indexOf(t)===i&&!e.includes(t));i.length>0&&r([...e,...i])},v=()=>{m(""),b([h])},_=e=>{"Enter"!==e.key||(e.preventDefault(),e.currentTarget.getAttribute("aria-activedescendant")||v())};return(0,t.jsxs)(a.Combobox,{multiple:!0,items:f,value:p,onValueChange:e=>{m(""),r(e.map(e=>e.value))},inputValue:h,onInputValueChange:e=>{if(!d.some(t=>e.includes(t)))return void m(e);let t=d.reduce((e,t)=>e.flatMap(e=>e.split(t)),[e]);m(t[t.length-1]??""),b(t.slice(0,-1))},isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:l,openOnInputClick:!0,disabled:A||c,children:[(0,t.jsx)(a.ComboboxChips,{render:(0,t.jsx)("div",{ref:g}),className:"min-h-8 py-1 text-sm",children:(0,t.jsx)(a.ComboboxValue,{children:e=>(0,t.jsxs)(t.Fragment,{children:[e.map(e=>(0,t.jsx)(a.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),(0,t.jsx)(a.ComboboxChipsInput,{id:u,placeholder:c?"Loading...":o,className:"min-w-24",onBlur:v,onKeyDown:_})]})})}),(0,t.jsxs)(a.ComboboxContent,{anchor:g,children:[(0,t.jsx)(a.ComboboxEmpty,{children:n}),(0,t.jsx)(a.ComboboxList,{children:e=>(0,t.jsx)(a.ComboboxItem,{value:e,title:e.label,children:e.label},e.value)})]})]})}])},263147,e=>{"use strict";var t=e.i(266027),i=e.i(243652),a=e.i(602869),l=e.i(431703),r=e.i(708347),s=e.i(135214);let o=(0,i.createQueryKeys)("accessGroups"),n=async e=>{let t=(0,a.getProxyBaseUrl)(),i=`${t}/v1/access_group`,r=await fetch(i,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!r.ok){let e=await r.json(),t=(0,l.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return r.json()};e.s(["accessGroupKeys",0,o,"useAccessGroups",0,()=>{let{accessToken:e,userRole:i}=(0,s.default)();return(0,t.useQuery)({queryKey:o.list({}),queryFn:async()=>n(e),enabled:!!e&&r.all_admin_roles.includes(i||"")})}])},695411,e=>{"use strict";var t=e.i(355619),i=e.i(602869);let a=e=>({model_group:(e.model_group||e.id||e.model_name)??"",...e.mode&&{mode:e.mode},...!0===e.supports_reasoning&&{supports_reasoning:!0},...void 0!==e.supported_reasoning_efforts&&{supported_reasoning_efforts:e.supported_reasoning_efforts}}),l=async(e,a)=>{let l=await (0,i.modelAvailableCall)(e,"","",!1,a),r=(l?.data??[]).map(e=>e.id);return(0,t.excludeProxyWideSentinel)(Array.from(new Set(r))).sort((e,t)=>e.localeCompare(t)).map(e=>({model_group:e}))},r=async e=>{try{let t=await (0,i.modelHubCall)(e),l=t?.data,r=(Array.isArray(l)?l:[]).map(a).filter(e=>""!==e.model_group).sort((e,t)=>e.model_group.localeCompare(t.model_group));return Array.from(new Map(r.map(e=>[e.model_group,e])).values())}catch(e){throw console.error("Error fetching model info:",e),e}};e.s(["fetchAvailableModels",0,r,"fetchAvailableModelsForTeam",0,l])},552546,e=>{"use strict";var t=e.i(843476),i=e.i(131792);let a=(e,t)=>{let i=t.trim().toLowerCase();return!i||e.label.toLowerCase().includes(i)||(e.sublabel?.toLowerCase().includes(i)??!1)};e.s(["SearchSelect",0,function({options:e,value:l,onValueChange:r,placeholder:s="Select…",emptyText:o="No results",disabled:n=!1,className:d,inputId:c,allowClear:A=!0,"aria-label":u}){let g=void 0===l||""===l?null:e.find(e=>e.value===l)??{label:l,value:l},h=null===g||e.some(e=>e.value===g.value)?e:[g,...e];return(0,t.jsxs)(i.Combobox,{items:h,value:g,onValueChange:e=>r(e?.value??""),isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:a,disabled:n,children:[(0,t.jsx)(i.ComboboxInput,{id:c,"aria-label":u,placeholder:s,showClear:A&&null!=l&&""!==l,className:`h-8 w-full text-sm ${d??""}`}),(0,t.jsxs)(i.ComboboxContent,{side:"bottom",collisionAvoidance:{side:"shift",align:"shift",fallbackAxisSide:"none"},children:[(0,t.jsx)(i.ComboboxEmpty,{children:o}),(0,t.jsx)(i.ComboboxList,{children:e=>(0,t.jsxs)(i.ComboboxItem,{value:e,children:[e.icon,(0,t.jsxs)("span",{className:"flex min-w-0 flex-col",children:[(0,t.jsx)("span",{className:"truncate",children:e.label}),null!=e.sublabel&&""!==e.sublabel&&(0,t.jsx)("span",{className:"truncate text-xs text-muted-foreground",children:e.sublabel})]})]},e.value)})]})]})}])},864261,e=>{"use strict";var t=e.i(751247),i=e.i(135214),a=e.i(441228);e.s(["default",0,e=>{let{userRole:l}=(0,i.default)(),r=(0,a.default)();return(0,t.hasCapability)(l,e,r)}])},63209,e=>{"use strict";var t=e.i(361653);e.s(["AlertCircle",()=>t.default])},158392,425063,334115,419470,e=>{"use strict";var t=e.i(843476),i=e.i(793479);let a={ttl:3600,lowest_latency_buffer:0},l=({routingStrategyArgs:e})=>{let l={ttl:"Sliding window to look back over when calculating the average latency of a deployment. Default - 1 hour (in seconds).",lowest_latency_buffer:"Shuffle between deployments within this % of the lowest latency. Default - 0 (i.e. always pick lowest latency)."};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-foreground",children:"Latency-Based Configuration"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Fine-tune latency-based routing behavior"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e||a).map(([e,a])=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-foreground uppercase tracking-wide",children:e.replace(/_/g," ")}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5 mb-2",children:l[e]||""}),(0,t.jsx)(i.Input,{name:e,defaultValue:"object"==typeof a?JSON.stringify(a,null,2):a?.toString(),className:"font-mono text-sm w-full"})]})},e))})]}),(0,t.jsx)("div",{className:"border-t border-border"})]})},r=({routerSettings:e,routerFieldsMetadata:a})=>(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-foreground",children:"Reliability & Retries"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Configure retry logic and failure handling"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3",children:Object.entries(e).filter(([e])=>"fallbacks"!=e&&"context_window_fallbacks"!=e&&"routing_strategy_args"!=e&&"routing_strategy"!=e&&"enable_tag_filtering"!=e&&"retry_policy"!=e&&"model_group_retry_policy"!=e&&"routing_groups"!=e).map(([e,l])=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsxs)("label",{className:"block",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-foreground uppercase tracking-wide",children:a[e]?.ui_field_name||e}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5 mb-2",children:a[e]?.field_description||""}),(0,t.jsx)(i.Input,{name:e,defaultValue:null==l||"null"===l?"":"object"==typeof l?JSON.stringify(l,null,2):l?.toString()||"",placeholder:"—",className:"font-mono text-sm w-full"})]})},e))})]});var s=e.i(967489);let o=({selectedStrategy:e,availableStrategies:i,routingStrategyDescriptions:a,routerFieldsMetadata:l,onStrategyChange:r})=>(0,t.jsxs)("div",{className:"space-y-2 max-w-3xl",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"text-xs font-medium text-foreground uppercase tracking-wide",children:l.routing_strategy?.ui_field_name||"Routing Strategy"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-0.5 mb-2",children:l.routing_strategy?.field_description||""})]}),(0,t.jsx)("div",{className:"routing-strategy-select max-w-3xl",children:(0,t.jsxs)(s.Select,{value:e,onValueChange:e=>e&&r(e),children:[(0,t.jsx)(s.SelectTrigger,{className:"w-full",children:(0,t.jsx)(s.SelectValue,{})}),(0,t.jsx)(s.SelectContent,{children:i.map(e=>(0,t.jsx)(s.SelectItem,{value:e,children:(0,t.jsxs)("div",{className:"flex flex-col gap-0.5 py-1",children:[(0,t.jsx)("span",{className:"font-mono text-sm font-medium",children:e}),a[e]&&(0,t.jsx)("span",{className:"text-xs font-normal text-muted-foreground",children:a[e]})]})},e))})]})})]});var n=e.i(271645),d=e.i(699375);let c=({enabled:e,routerFieldsMetadata:i,onToggle:a})=>{let l=(0,n.useId)();return(0,t.jsx)("div",{className:"space-y-3 max-w-3xl",children:(0,t.jsxs)("div",{className:"flex items-start justify-between",children:[(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("label",{htmlFor:l,className:"text-xs font-medium text-foreground uppercase tracking-wide",children:i.enable_tag_filtering?.ui_field_name||"Enable Tag Filtering"}),(0,t.jsxs)("p",{className:"text-xs text-muted-foreground mt-0.5",children:[i.enable_tag_filtering?.field_description||"",i.enable_tag_filtering?.link&&(0,t.jsxs)(t.Fragment,{children:[" ",(0,t.jsx)("a",{href:i.enable_tag_filtering.link,target:"_blank",rel:"noopener noreferrer",className:"text-info hover:text-info/80 underline",children:"Learn more"})]})]})]}),(0,t.jsx)(d.Switch,{id:l,checked:e,onCheckedChange:a,className:"ml-4"})]})})};e.s(["default",0,({value:e,onChange:i,routerFieldsMetadata:a,availableRoutingStrategies:s,routingStrategyDescriptions:n})=>(0,t.jsxs)("div",{className:"w-full space-y-8 py-2",children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)("div",{className:"max-w-3xl",children:[(0,t.jsx)("h3",{className:"text-sm font-medium text-foreground",children:"Routing Settings"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Configure how requests are routed to deployments"})]}),s.length>0&&(0,t.jsx)(o,{selectedStrategy:e.selectedStrategy||e.routerSettings.routing_strategy||null,availableStrategies:s,routingStrategyDescriptions:n,routerFieldsMetadata:a,onStrategyChange:t=>{i({...e,selectedStrategy:t})}}),(0,t.jsx)(c,{enabled:e.enableTagFiltering,routerFieldsMetadata:a,onToggle:t=>{i({...e,enableTagFiltering:t})}})]}),(0,t.jsx)("div",{className:"border-t border-border"}),"latency-based-routing"===e.selectedStrategy&&(0,t.jsx)(l,{routingStrategyArgs:e.routerSettings.routing_strategy_args}),(0,t.jsx)(r,{routerSettings:e.routerSettings,routerFieldsMetadata:a})]})],158392);var A=e.i(519455),u=e.i(677572),g=e.i(107233),h=e.i(37727),m=e.i(417385),p=e.i(845150),x=e.i(552546),f=e.i(63209);let b=(0,e.i(475254).default)("arrow-down",[["path",{d:"M12 5v14",key:"s699le"}],["path",{d:"m19 12-7 7-7-7",key:"1idqje"}]]);function v({group:e,onChange:i,availableModels:a,maxFallbacks:l,disablePrimaryModel:r=!1}){let s=a.filter(t=>t!==e.primaryModel),o=e.fallbackModels.length({label:e,value:e})),value:e.primaryModel??"",onValueChange:t=>{let a=[...e.fallbackModels];a.includes(t)&&(a=a.filter(e=>e!==t)),i({...e,primaryModel:t,fallbackModels:a})},placeholder:"Select primary model",emptyText:"No models found",disabled:r,className:"h-12"}),!r&&!e.primaryModel&&(0,t.jsxs)("div",{className:"mt-2 flex items-center gap-2 text-warning text-xs bg-warning/10 p-2 rounded-sm",children:[(0,t.jsx)(f.AlertCircle,{className:"w-4 h-4"}),(0,t.jsx)("span",{children:"Select a model to begin configuring fallbacks"})]})]}),(0,t.jsx)("div",{className:"flex items-center justify-center -my-4 z-raised",children:(0,t.jsxs)("div",{className:"bg-indigo-50 text-indigo-500 px-4 py-1 rounded-full text-xs font-bold border border-indigo-100 flex items-center gap-2 shadow-xs dark:bg-indigo-950 dark:text-indigo-300 dark:border-indigo-900",children:[(0,t.jsx)(b,{className:"w-4 h-4"}),"IF FAILS, TRY..."]})}),(0,t.jsxs)("div",{className:`transition-opacity duration-300 ${!e.primaryModel?"opacity-50 pointer-events-none":"opacity-100"}`,children:[(0,t.jsxs)("label",{className:"block text-sm font-semibold text-foreground mb-2",children:["Fallback Chain ",(0,t.jsx)("span",{className:"text-destructive",children:"*"}),(0,t.jsxs)("span",{className:"text-xs text-muted-foreground font-normal ml-2",children:["(Max ",l," fallbacks at a time)"]})]}),(0,t.jsxs)("div",{className:"bg-muted rounded-xl p-4 border border-border",children:[(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)(p.MultiSelect,{options:s.map(e=>({label:e,value:e})),value:e.fallbackModels,onValueChange:t=>{let a=t.slice(0,l);i({...e,fallbackModels:a})},placeholder:o?"Select fallback models to add...":`Maximum ${l} fallbacks reached`,emptyText:"No models found",disabled:!e.primaryModel,className:"w-full"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground mt-1 ml-1",children:o?`Search and select multiple models. Selected models will appear below in order. (${e.fallbackModels.length}/${l} used)`:`Maximum ${l} fallbacks reached. Remove some to add more.`})]}),(0,t.jsx)("div",{className:"space-y-2 min-h-[100px]",children:0===e.fallbackModels.length?(0,t.jsxs)("div",{className:"h-32 border-2 border-dashed border-border rounded-lg flex flex-col items-center justify-center text-muted-foreground",children:[(0,t.jsx)("span",{className:"text-sm",children:"No fallback models selected"}),(0,t.jsx)("span",{className:"text-xs mt-1",children:"Add models from the dropdown above"})]}):(0,t.jsx)("ol",{"aria-label":"Fallback chain",className:"space-y-2",children:e.fallbackModels.map((a,l)=>(0,t.jsxs)("li",{className:"group flex items-center justify-between p-3 bg-card rounded-lg border border-border hover:border-indigo-300 hover:shadow-xs transition-all",children:[(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-sm bg-muted text-muted-foreground group-hover:text-indigo-500 group-hover:bg-indigo-50 dark:group-hover:text-indigo-300 dark:group-hover:bg-indigo-950",children:(0,t.jsx)("span",{className:"text-xs font-bold",children:l+1})}),(0,t.jsx)("div",{children:(0,t.jsx)("span",{className:"font-medium text-foreground",children:a})})]}),(0,t.jsx)("button",{type:"button","aria-label":`Remove ${a}`,onClick:()=>{let t;return t=e.fallbackModels.filter((e,t)=>t!==l),void i({...e,fallbackModels:t})},className:"opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive p-1",children:(0,t.jsx)(h.X,{className:"w-4 h-4"})})]},`${a}-${l}`))})})]})]})]})}e.s(["ArrowDown",0,b],425063),e.s(["FallbackGroupConfig",0,v],334115),e.s(["FallbackSelectionForm",0,function({groups:e,onGroupsChange:i,availableModels:a,maxFallbacks:l=10,maxGroups:r=5}){let[s,o]=(0,n.useState)(e.length>0?e[0].id:"1");(0,n.useEffect)(()=>{e.length>0?e.some(e=>e.id===s)||o(e[0].id):o("1")},[e]);let d=()=>{if(e.length>=r)return;let t=Date.now().toString();i([...e,{id:t,primaryModel:null,fallbackModels:[]}]),o(t)},c=t=>{i(e.map(e=>e.id===t.id?t:e))},p=(e,t)=>e.primaryModel?e.primaryModel:`Group ${t+1}`;return 0===e.length?(0,t.jsxs)("div",{className:"text-center py-12 bg-muted rounded-lg border border-dashed border-border",children:[(0,t.jsx)("p",{className:"text-muted-foreground mb-4",children:"No fallback groups configured"}),(0,t.jsxs)(A.Button,{onClick:d,children:[(0,t.jsx)(g.Plus,{className:"w-4 h-4"}),"Create First Group"]})]}):(0,t.jsxs)(u.Tabs,{value:s,onValueChange:o,children:[(0,t.jsxs)("div",{className:"flex items-center border-b",children:[(0,t.jsx)(u.TabsList,{variant:"line",className:"h-auto justify-start rounded-none p-0",children:e.map((a,l)=>(0,t.jsxs)("div",{className:"relative flex items-center",children:[(0,t.jsx)(u.TabsTrigger,{value:a.id,className:`flex-none rounded-none py-2 pl-4 ${e.length>1?"pr-9":"pr-4"}`,children:p(a,l)}),e.length>1&&(0,t.jsx)(A.Button,{variant:"ghost",size:"icon-xs",className:"absolute right-1","aria-label":`Remove ${p(a,l)}`,onClick:()=>(t=>{if(1===e.length)return void m.toast.warning("At least one group is required");let a=e.filter(e=>e.id!==t);i(a),s===t&&a.length>0&&o(a[a.length-1].id)})(a.id),children:(0,t.jsx)(h.X,{})})]},a.id))}),e.length(0,t.jsx)(u.TabsContent,{value:e.id,className:"pt-4",children:(0,t.jsx)(v,{group:e,onChange:c,availableModels:a,maxFallbacks:l})},e.id))]})}],419470)},207082,e=>{"use strict";var t=e.i(619273),i=e.i(621482),a=e.i(266027),l=e.i(243652),r=e.i(602869),s=e.i(431703),o=e.i(135214);let n=(0,l.createQueryKeys)("keys"),d=async(e,t,i,a={})=>{try{let l=(0,r.getProxyBaseUrl)(),o=new URLSearchParams(Object.entries({team_id:a.teamID,project_id:a.projectID,agent_id:a.agentID,organization_id:a.organizationID,key_alias:a.selectedKeyAlias,key_hash:a.keyHash,search:a.search,user_id:a.userID,page:t,size:i,sort_by:a.sortBy,sort_order:a.sortOrder,expand:a.expand,status:a.status,return_full_object:"true",include_team_keys:"true",include_created_by_keys:"true",substring_matching:"true"}).filter(([,e])=>null!=e).map(([e,t])=>[e,String(t)])),n=`${l?`${l}/key/list`:"/key/list"}?${o}`,d=await fetch(n,{method:"GET",headers:{[(0,r.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!d.ok){let e=await d.json(),t=(0,s.deriveErrorMessage)(e);throw(0,r.handleError)(t),Error(t)}return await d.json()}catch(e){throw console.error("Failed to list keys:",e),e}},c=(0,l.createQueryKeys)("infiniteKeys"),A=(0,l.createQueryKeys)("deletedKeys");e.s(["keyKeys",0,n,"useDeletedKeys",0,(e,i,l={})=>{let{accessToken:r}=(0,o.default)();return(0,a.useQuery)({queryKey:A.list({page:e,limit:i,...l}),queryFn:async()=>await d(r,e,i,{...l,status:"deleted"}),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})},"useInfiniteKeys",0,(e,t={})=>{let{accessToken:a}=(0,o.default)(),l={queryKey:c.list({limit:e,...t}),queryFn:async({pageParam:i})=>{if(!a)throw Error("Access token required");return await d(a,i,e,t)},initialPageParam:1,getNextPageParam:e=>e.current_page{let{accessToken:r}=(0,o.default)();return(0,a.useQuery)({queryKey:n.list({page:e,limit:i,...l}),queryFn:async()=>await d(r,e,i,l),enabled:!!r,staleTime:3e4,placeholderData:t.keepPreviousData})}])}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/05jtp8xqp3j0x.js b/litellm/proxy/_experimental/out/_next/static/chunks/05jtp8xqp3j0x.js
deleted file mode 100644
index fe3ee5143b6..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/05jtp8xqp3j0x.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,108821,e=>{"use strict";var t=e.i(733332),r=e.i(271645);let n=r.createContext(!1),i=r.createContext(void 0);e.s(["DialogRootContext",0,i,"IsDrawerContext",0,n,"useDialogRootContext",0,function(e){let n=r.useContext(i);if(!1===e&&void 0===n)throw Error((0,t.default)(27));return n}])},402820,156736,209793,625834,784324,264951,e=>{"use strict";e.i(247167);var t,r,n=e.i(271645),i=e.i(108821),s=e.i(552245),o=e.i(405005),a=e.i(209407);let l={...o.popupStateMapping,...a.transitionStatusMapping},u=n.forwardRef(function(e,t){let{render:r,className:n,style:o,forceRender:a=!1,...u}=e,{store:d}=(0,i.useDialogRootContext)(),c=d.useState("open"),p=d.useState("nested"),h=d.useState("mounted"),g=d.useState("transitionStatus");return(0,s.useRenderElement)("div",e,{state:{open:c,transitionStatus:g},ref:[d.context.backdropRef,t],stateAttributesMapping:l,props:[{role:"presentation",hidden:!h,style:{userSelect:"none",WebkitUserSelect:"none"}},u],enabled:a||!p})});e.s(["DialogBackdrop",0,u],402820);var d=e.i(540886),c=e.i(675606),p=e.i(56434);let h=n.forwardRef(function(e,t){let{render:r,className:n,style:o,disabled:a=!1,nativeButton:l=!0,...u}=e,{store:h}=(0,i.useDialogRootContext)(),g=h.useState("open"),{getButtonProps:f,buttonRef:v}=(0,d.useButton)({disabled:a,native:l});return(0,s.useRenderElement)("button",e,{state:{disabled:a},ref:[t,v],props:[{onClick:function(e){g&&h.setOpen(!1,(0,c.createChangeEventDetails)(p.REASONS.closePress,e.nativeEvent))}},u,f]})});e.s(["DialogClose",0,h],156736);var g=e.i(788015);let f=n.forwardRef(function(e,t){let{render:r,className:n,style:o,id:a,...l}=e,{store:u}=(0,i.useDialogRootContext)(),d=(0,g.useBaseUiId)(a);return u.useSyncedValueWithCleanup("descriptionElementId",d),(0,s.useRenderElement)("p",e,{ref:t,props:[{id:d},l]})});e.s(["DialogDescription",0,f],209793);var v=e.i(61487);let m=((t={}).nestedDialogs="--nested-dialogs",t),b=((r={})[r.open=o.CommonPopupDataAttributes.open]="open",r[r.closed=o.CommonPopupDataAttributes.closed]="closed",r[r.startingStyle=o.CommonPopupDataAttributes.startingStyle]="startingStyle",r[r.endingStyle=o.CommonPopupDataAttributes.endingStyle]="endingStyle",r.nested="data-nested",r.nestedDialogOpen="data-nested-dialog-open",r);var y=e.i(733332);let x=n.createContext(void 0);function R(){let e=n.useContext(x);if(void 0===e)throw Error((0,y.default)(26));return e}e.s(["DialogPortalContext",0,x,"useDialogPortalContext",0,R],625834);var S=e.i(137584),C=e.i(673327),D=e.i(264111),w=e.i(843476);let O={...o.popupStateMapping,...a.transitionStatusMapping,nestedDialogOpen:e=>e?{[b.nestedDialogOpen]:""}:null},E=n.forwardRef(function(e,t){let{render:r,className:n,style:o,finalFocus:a,initialFocus:l,...u}=e,{store:d}=(0,i.useDialogRootContext)(),c=d.useState("descriptionElementId"),p=d.useState("disablePointerDismissal"),h=d.useState("floatingRootContext"),g=d.useState("popupProps"),f=d.useState("modal"),b=d.useState("mounted"),y=d.useState("nested"),x=d.useState("nestedOpenDialogCount"),E=d.useState("open"),I=d.useState("openMethod"),k=d.useState("titleElementId"),T=d.useState("transitionStatus"),P=d.useState("role"),Q=h.useState("floatingId"),U=u.id??Q;R(),(0,S.useOpenChangeComplete)({open:E,ref:d.context.popupRef,onComplete(){E&&d.context.onOpenChangeComplete?.(!0)}});let B=void 0===l?(0,D.createDefaultInitialFocus)(d.context.popupRef):l,j=d.useStateSetter("popupElement"),_=(0,s.useRenderElement)("div",e,{state:{open:E,nested:y,transitionStatus:T,nestedDialogOpen:x>0},props:[g,{id:U,"aria-labelledby":k??void 0,"aria-describedby":c??void 0,role:P,...D.FOCUSABLE_POPUP_PROPS,hidden:!b,onKeyDown(e){C.COMPOSITE_KEYS.has(e.key)&&e.stopPropagation()},style:{[m.nestedDialogs]:x}},u],ref:[t,d.context.popupRef,j],stateAttributesMapping:O});return(0,w.jsx)(v.FloatingFocusManager,{context:h,openInteractionType:I,disabled:!b,closeOnFocusOut:!p,initialFocus:B,returnFocus:a,modal:!1!==f,restoreFocus:"popup",children:_})});e.s(["DialogPopup",0,E],784324);var I=e.i(144394),k=e.i(726674),T=e.i(426);let P=n.forwardRef(function(e,t){let{keepMounted:r=!1,...n}=e,{store:s}=(0,i.useDialogRootContext)(),o=s.useState("mounted"),a=s.useState("modal"),l=s.useState("open");return o||r?(0,w.jsx)(x.Provider,{value:r,children:(0,w.jsxs)(k.FloatingPortal,{ref:t,...n,children:[o&&!0===a&&(0,w.jsx)(T.InternalBackdrop,{ref:s.context.internalBackdropRef,inert:(0,I.inertValue)(!l)}),e.children]})}):null});e.s(["DialogPortal",0,P],264951)},67530,e=>{"use strict";var t=e.i(271645),r=e.i(145484),n=e.i(956789),i=e.i(17989),s=e.i(647554),o=e.i(675606),a=e.i(56434),l=e.i(264111);e.s(["DialogInteractions",0,function({store:e,parentContext:o,isDrawer:a}){let u=e.useState("open"),d=e.useState("disablePointerDismissal"),c=e.useState("modal"),p=e.useState("popupElement"),h=e.useState("floatingRootContext"),[g,f]=t.useState(0),[v,m]=t.useState(0),b=0===g,y=(0,i.useDismiss)(h,{outsidePressEvent:()=>e.context.internalBackdropRef.current||e.context.backdropRef.current?"intentional":{mouse:"trap-focus"===c?"sloppy":"intentional",touch:"sloppy"},outsidePress(t){if(!e.context.outsidePressEnabledRef.current||"button"in t&&0!==t.button||"touches"in t&&1!==t.touches.length)return!1;let r=(0,s.getTarget)(t);return!!b&&!d&&(!c||!e.context.internalBackdropRef.current&&!e.context.backdropRef.current||e.context.internalBackdropRef.current===r||e.context.backdropRef.current===r||(0,s.contains)(r,p)&&!r?.hasAttribute("data-base-ui-portal"))},escapeKey:b});(0,r.useScrollLock)(u&&!0===c,p),e.useContextCallback("onNestedDialogOpen",(e,t)=>{f(e),m(t)}),e.useContextCallback("onNestedDialogClose",()=>{f(0),m(0)}),t.useEffect(()=>(o?.onNestedDialogOpen&&u&&o.onNestedDialogOpen(g+1,v+ +!!a),o?.onNestedDialogClose&&!u&&o.onNestedDialogClose(),()=>{o?.onNestedDialogClose&&u&&o.onNestedDialogClose()}),[a,u,g,v,o]);let x=y.reference??n.EMPTY_OBJECT,R=y.trigger??n.EMPTY_OBJECT,S=y.floating??n.EMPTY_OBJECT;return(0,l.usePopupInteractionProps)(e,{activeTriggerProps:x,inactiveTriggerProps:R,popupProps:S,nestedOpenDialogCount:g,nestedOpenDrawerCount:v}),null},"useDialogRoot",0,function(e){let{store:r,actionsRef:n}=e,i=r.useState("open");(0,l.usePopupRootSync)(r,i),(0,l.useImplicitActiveTrigger)(r);let{forceUnmount:s}=(0,l.useOpenStateTransitions)(i,r),u=t.useCallback(()=>{r.setOpen(!1,(0,o.createChangeEventDetails)(a.REASONS.imperativeAction))},[r]);t.useImperativeHandle(n,()=>({unmount:s,close:u}),[s,u])}])},366250,301807,e=>{"use strict";var t=e.i(271645),r=e.i(713203),n=e.i(67530),i=e.i(108821),s=e.i(616269),o=e.i(301252),a=e.i(116786),l=e.i(990627),u=e.i(264111);let d={...a.popupStoreSelectors,modal:(0,s.createSelector)(e=>e.modal),nested:(0,s.createSelector)(e=>e.nested),nestedOpenDialogCount:(0,s.createSelector)(e=>e.nestedOpenDialogCount),nestedOpenDrawerCount:(0,s.createSelector)(e=>e.nestedOpenDrawerCount),disablePointerDismissal:(0,s.createSelector)(e=>e.disablePointerDismissal),openMethod:(0,s.createSelector)(e=>e.openMethod),descriptionElementId:(0,s.createSelector)(e=>e.descriptionElementId),titleElementId:(0,s.createSelector)(e=>e.titleElementId),viewportElement:(0,s.createSelector)(e=>e.viewportElement),role:(0,s.createSelector)(e=>e.role)};class c extends o.ReactStore{constructor(e,r,n=!1){const i=new l.PopupTriggerMap,s=function(e={}){return{...(0,a.createInitialPopupStoreState)(),modal:!0,disablePointerDismissal:!1,popupElement:null,viewportElement:null,descriptionElementId:void 0,titleElementId:void 0,openMethod:null,nested:!1,nestedOpenDialogCount:0,nestedOpenDrawerCount:0,role:"dialog",...e}}(e);s.floatingRootContext=(0,a.createPopupFloatingRootContext)(i,r,n),super(s,{popupRef:t.createRef(),backdropRef:t.createRef(),internalBackdropRef:t.createRef(),outsidePressEnabledRef:{current:!0},triggerElements:i,onOpenChange:void 0,onOpenChangeComplete:void 0},d)}setOpen=(e,t)=>{if(t.preventUnmountOnClose=()=>{this.set("preventUnmountingOnClose",!0)},e||null!=t.trigger||null==this.state.activeTriggerId||(t.trigger=this.state.activeTriggerElement??void 0),this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let r={open:e};(0,u.setPopupOpenState)(r,e,t.trigger),this.update(r)};static useStore(e,t){return(0,u.usePopupStore)(e,(e,r)=>new c(t,e,r),!0).store}}e.s(["DialogStore",0,c],301807);var p=e.i(843476);e.s(["useRenderDialogRoot",0,function(e,s="dialog"){let{children:o,open:a,defaultOpen:l=!1,onOpenChange:u,onOpenChangeComplete:d,disablePointerDismissal:h=!1,modal:g=!0,actionsRef:f,handle:v,triggerId:m,defaultTriggerId:b=null}=e,y="alert-dialog"===s,x=(0,i.useDialogRootContext)(!0),R={modal:!!y||g,disablePointerDismissal:y||h,nested:!!x,role:y?"alertdialog":"dialog"},S=c.useStore(v?.store,{open:l,openProp:a,activeTriggerId:b,triggerIdProp:m,...R});(0,r.useOnFirstRender)(()=>{let e=void 0===a&&!1===S.state.open&&!0===l?{open:!0,activeTriggerId:b}:null;y?S.update(e?{...R,...e}:R):e&&S.update(e)}),S.useControlledProp("openProp",a),S.useControlledProp("triggerIdProp",m),S.useSyncedValues(R),S.useContextCallback("onOpenChange",u),S.useContextCallback("onOpenChangeComplete",d);let C=S.useState("open"),D=S.useState("mounted"),w=S.useState("payload");(0,n.useDialogRoot)({store:S,actionsRef:f});let O=t.useMemo(()=>({store:S}),[S]);return(0,p.jsx)(i.IsDrawerContext.Provider,{value:!1,children:(0,p.jsxs)(i.DialogRootContext.Provider,{value:O,children:[(C||D)&&(0,p.jsx)(n.DialogInteractions,{store:S,parentContext:x?.store.context,isDrawer:"drawer"===s}),"function"==typeof o?o({payload:w}):o]})})}],366250)},974217,e=>{"use strict";e.i(247167);var t,r=e.i(271645),n=e.i(552245),i=e.i(405005),s=e.i(209407),o=e.i(108821),a=e.i(625834);let l=((t={})[t.open=i.CommonPopupDataAttributes.open]="open",t[t.closed=i.CommonPopupDataAttributes.closed]="closed",t[t.startingStyle=i.CommonPopupDataAttributes.startingStyle]="startingStyle",t[t.endingStyle=i.CommonPopupDataAttributes.endingStyle]="endingStyle",t.nested="data-nested",t.nestedDialogOpen="data-nested-dialog-open",t),u={...i.popupStateMapping,...s.transitionStatusMapping,nested:e=>e?{[l.nested]:""}:null,nestedDialogOpen:e=>e?{[l.nestedDialogOpen]:""}:null},d=r.forwardRef(function(e,t){let{render:r,className:i,style:s,children:l,...d}=e,c=(0,a.useDialogPortalContext)(),{store:p}=(0,o.useDialogRootContext)(),h=p.useState("open"),g=p.useState("nested"),f=p.useState("transitionStatus"),v=p.useState("nestedOpenDialogCount"),m=p.useState("mounted"),b=p.useStateSetter("viewportElement");return(0,n.useRenderElement)("div",e,{enabled:c||m,state:{open:h,nested:g,transitionStatus:f,nestedDialogOpen:v>0},ref:[t,b],stateAttributesMapping:u,props:[{role:"presentation",hidden:!m,style:{pointerEvents:h?void 0:"none"},children:l},d]})});e.s(["DialogViewport",0,d],974217)},77173,313488,e=>{"use strict";e.i(247167);var t=e.i(271645),r=e.i(108821),n=e.i(552245),i=e.i(788015);let s=t.forwardRef(function(e,t){let{render:s,className:o,style:a,id:l,...u}=e,{store:d}=(0,r.useDialogRootContext)(),c=(0,i.useBaseUiId)(l);return d.useSyncedValueWithCleanup("titleElementId",c),(0,n.useRenderElement)("h2",e,{ref:t,props:[{id:c},u]})});e.s(["DialogTitle",0,s],77173);var o=e.i(733332),a=e.i(540886),l=e.i(405005),u=e.i(638396),d=e.i(264111),c=e.i(385689),p=e.i(32199);let h=t.forwardRef(function(e,s){let{render:h,className:g,style:f,disabled:v=!1,nativeButton:m=!0,id:b,payload:y,handle:x,...R}=e,S=(0,r.useDialogRootContext)(!0),C=x?.store??S?.store;if(!C)throw Error((0,o.default)(79));let D=(0,i.useBaseUiId)(b),w=C.useState("floatingRootContext"),O=C.useState("isOpenedByTrigger",D),E=C.useState("triggerPopupId",D),I=t.useRef(null),{registerTrigger:k,isMountedByThisTrigger:T}=(0,d.useTriggerDataForwarding)(D,I,C,{payload:y}),{getButtonProps:P,buttonRef:Q}=(0,a.useButton)({disabled:v,native:m}),U=(0,c.useClick)(w,{enabled:null!=w}),B=(0,p.useOpenMethodTriggerProps)(()=>C.select("open"),e=>{C.set("openMethod",e)}),j=C.useState("triggerProps",T);return(0,n.useRenderElement)("button",e,{state:{disabled:v,open:O},ref:[Q,s,k,I],props:[U.reference,j,B,{[u.CLICK_TRIGGER_IDENTIFIER]:"",id:D,"aria-haspopup":"dialog","aria-expanded":O,"aria-controls":E},R,P],stateAttributesMapping:l.triggerOpenStateMapping})});e.s(["DialogTrigger",0,h],313488)},325326,e=>{"use strict";var t=e.i(301807),r=e.i(675606),n=e.i(56434);class i{constructor(e){this.store=e??new t.DialogStore}open(e){let t=e?this.store.context.triggerElements.getById(e):void 0;this.store.setOpen(!0,(0,r.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,t))}openWithPayload(e){this.store.set("payload",e),this.store.setOpen(!0,(0,r.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,void 0))}close(){this.store.setOpen(!1,(0,r.createChangeEventDetails)(n.REASONS.imperativeAction,void 0,void 0))}get isOpen(){return this.store.select("open")}}e.s(["DialogHandle",0,i,"createDialogHandle",0,function(){return new i}])},353753,e=>{"use strict";e.s([],914651),e.i(914651);var t=e.i(402820),r=e.i(156736),n=e.i(209793),i=e.i(784324),s=e.i(264951),o=e.i(271645),a=e.i(108821),l=e.i(366250),u=e.i(974217),d=e.i(77173),c=e.i(313488),p=e.i(325326);e.s(["Backdrop",()=>t.DialogBackdrop,"Close",()=>r.DialogClose,"Description",()=>n.DialogDescription,"Handle",()=>p.DialogHandle,"Popup",()=>i.DialogPopup,"Portal",()=>s.DialogPortal,"Root",0,function(e){let t=o.useContext(a.IsDrawerContext)?"drawer":"dialog";return(0,l.useRenderDialogRoot)(e,t)},"Title",()=>d.DialogTitle,"Trigger",()=>c.DialogTrigger,"Viewport",()=>u.DialogViewport,"createHandle",()=>p.createDialogHandle],828376);var h=e.i(828376);e.s(["Dialog",0,h],353753)},776639,e=>{"use strict";var t=e.i(843476),r=e.i(353753),n=e.i(196631),i=e.i(519455),s=e.i(995926);function o({...e}){return(0,t.jsx)(r.Dialog.Portal,{"data-slot":"dialog-portal",...e})}function a({className:e,...i}){return(0,t.jsx)(r.Dialog.Backdrop,{"data-slot":"dialog-overlay",className:(0,n.cn)("fixed inset-0 isolate z-popup bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",e),...i})}e.s(["Dialog",0,function({...e}){return(0,t.jsx)(r.Dialog.Root,{"data-slot":"dialog",...e})},"DialogContent",0,function({className:e,children:l,showCloseButton:u=!0,...d}){return(0,t.jsxs)(o,{children:[(0,t.jsx)(a,{}),(0,t.jsxs)(r.Dialog.Popup,{"data-slot":"dialog-content",className:(0,n.cn)("fixed top-1/2 left-1/2 z-popup grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-6 rounded-xl bg-popover p-6 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-md data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",e),...d,children:[l,u&&(0,t.jsxs)(r.Dialog.Close,{"data-slot":"dialog-close",render:(0,t.jsx)(i.Button,{variant:"ghost",className:"absolute top-4 right-4",size:"icon-sm"}),children:[(0,t.jsx)(s.XIcon,{}),(0,t.jsx)("span",{className:"sr-only",children:"Close"})]})]})]})},"DialogDescription",0,function({className:e,...i}){return(0,t.jsx)(r.Dialog.Description,{"data-slot":"dialog-description",className:(0,n.cn)("text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",e),...i})},"DialogFooter",0,function({className:e,showCloseButton:s=!1,children:o,...a}){return(0,t.jsxs)("div",{"data-slot":"dialog-footer",className:(0,n.cn)("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end",e),...a,children:[o,s&&(0,t.jsx)(r.Dialog.Close,{render:(0,t.jsx)(i.Button,{variant:"outline"}),children:"Close"})]})},"DialogHeader",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"dialog-header",className:(0,n.cn)("flex flex-col gap-2",e),...r})},"DialogTitle",0,function({className:e,...i}){return(0,t.jsx)(r.Dialog.Title,{"data-slot":"dialog-title",className:(0,n.cn)("leading-none font-medium",e),...i})}])},555436,54943,e=>{"use strict";let t=(0,e.i(475254).default)("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]);e.s(["default",0,t],54943),e.s(["Search",0,t],555436)},487486,911825,e=>{"use strict";var t=e.i(176782),r=e.i(552245);function n(e){return(0,r.useRenderElement)(e.defaultTagName??"div",e,e)}e.s(["useRender",0,n],911825);var i=e.i(225913),s=e.i(196631);let o=(0,i.cva)("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",{variants:{variant:{default:"bg-primary text-primary-foreground [a]:hover:bg-primary/80",secondary:"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",destructive:"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",outline:"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",ghost:"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",link:"text-primary underline-offset-4 hover:underline"}},defaultVariants:{variant:"default"}});e.s(["Badge",0,function({className:e,variant:r="default",render:i,...a}){return n({defaultTagName:"span",props:(0,t.mergeProps)({className:(0,s.cn)(o({variant:r}),e)},a),render:i,state:{slot:"badge",variant:r}})}],487486)},344523,e=>{"use strict";let t=(0,e.i(475254).default)("chevrons-up-down",[["path",{d:"m7 15 5 5 5-5",key:"1hf1tw"}],["path",{d:"m7 9 5-5 5 5",key:"sgt6xg"}]]);e.s(["ChevronsUpDown",0,t],344523)},174886,991124,e=>{"use strict";let t=(0,e.i(475254).default)("copy",[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2",key:"17jyea"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2",key:"zix9uf"}]]);e.s(["default",0,t],991124),e.s(["Copy",0,t],174886)},31421,e=>{"use strict";var t=e.i(271645),r=e.i(146376),n=e.i(788015);e.s(["useAriaLabelledBy",0,function(e,i,s,o=!0,a){let[l,u]=t.useState(),d=(0,n.useBaseUiId)(a?`${a}-label`:void 0),c=e??i??l;return(0,r.useIsoLayoutEffect)(()=>{let t=e||i||!o?void 0:function(e,t){let r=function(e){if(!e)return;let t=e.parentElement;if(t&&"LABEL"===t.tagName)return t;let r=e.id;if(r){let t=e.nextElementSibling;if(t&&t.htmlFor===r)return t}let n=e.labels;return n&&n[0]}(e);if(r)return!r.id&&t&&(r.id=t),r.id||void 0}(s.current,d);l!==t&&u(t)}),c}])},841947,e=>{"use strict";let t=(0,e.i(475254).default)("x",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]);e.s(["default",0,t])},995926,e=>{"use strict";var t=e.i(841947);e.s(["XIcon",()=>t.default])},643531,e=>{"use strict";var t=e.i(678745);e.s(["Check",()=>t.default])},346570,e=>{"use strict";var t=e.i(271645),r=e.i(174080),n=e.i(647554),i=e.i(383976),s=e.i(675606),o=e.i(56434);e.s(["useTriggerFocusGuards",0,function(e,a){let l=t.useRef(null);return{preFocusGuardRef:l,handlePreFocusGuardFocus:function(t){r.flushSync(()=>{e.setOpen(!1,(0,s.createChangeEventDetails)(o.REASONS.focusOut,t.nativeEvent,t.currentTarget))});let n=(0,i.getTabbableBeforeElement)(l.current);n?.focus()},handleFocusTargetFocus:function(t){let l=e.select("positionerElement");if(l&&(0,i.isOutsideEvent)(t,l))e.context.beforeContentFocusGuardRef.current?.focus();else{r.flushSync(()=>{e.setOpen(!1,(0,s.createChangeEventDetails)(o.REASONS.focusOut,t.nativeEvent,t.currentTarget))});let u=(0,i.getTabbableAfterElement)(e.context.triggerFocusTargetRef.current||a.current);for(;null!==u&&(0,n.contains)(l,u);){let e=u;if((u=(0,i.getNextTabbable)(u))===e)break}u?.focus()}}}}])},664659,e=>{"use strict";var t=e.i(631171);e.s(["ChevronDown",()=>t.default])},519455,527930,e=>{"use strict";var t=e.i(843476);e.i(247167);var r=e.i(271645),n=e.i(540886),i=e.i(552245);let s=r.forwardRef(function(e,t){let{render:r,className:s,disabled:o=!1,focusableWhenDisabled:a=!1,nativeButton:l=!0,style:u,...d}=e,{getButtonProps:c,buttonRef:p}=(0,n.useButton)({disabled:o,focusableWhenDisabled:a,native:l});return(0,i.useRenderElement)("button",e,{state:{disabled:o},ref:[t,p],props:[d,c]})});e.s(["Button",0,s],527930);var o=e.i(225913),a=e.i(196631);let l=(0,o.cva)("group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",{variants:{variant:{default:"bg-primary text-primary-foreground hover:bg-primary/80",outline:"border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",secondary:"bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",ghost:"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",destructive:"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",xs:"h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",sm:"h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5",lg:"h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",icon:"size-9","icon-xs":"size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3","icon-sm":"size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md","icon-lg":"size-10"}},defaultVariants:{variant:"default",size:"default"}});e.s(["Button",0,function({className:e,variant:r="default",size:n="default",...i}){return(0,t.jsx)(s,{"data-slot":"button",className:(0,a.cn)(l({variant:r,size:n,className:e})),...i})},"buttonVariants",0,l],519455)},266027,869230,254440,469637,e=>{"use strict";let t;var r=e.i(175555),n=e.i(273911),i=e.i(540143),s=e.i(286491),o=e.i(915823),a=e.i(793803),l=e.i(619273),u=e.i(180166),d=class extends o.Subscribable{constructor(e,t){super(),this.options=t,this.#e=e,this.#t=null,this.#r=(0,a.pendingThenable)(),this.bindMethods(),this.setOptions(t)}#e;#n=void 0;#i=void 0;#s=void 0;#o;#a;#r;#t;#l;#u;#d;#c;#p;#h;#g=new Set;bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){1===this.listeners.size&&(this.#n.addObserver(this),c(this.#n,this.options)?this.#f():this.updateResult(),this.#v())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return p(this.#n,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return p(this.#n,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.#m(),this.#b(),this.#n.removeObserver(this)}setOptions(e){let t=this.options,r=this.#n;if(this.options=this.#e.defaultQueryOptions(e),void 0!==this.options.enabled&&"boolean"!=typeof this.options.enabled&&"function"!=typeof this.options.enabled&&"boolean"!=typeof(0,l.resolveQueryBoolean)(this.options.enabled,this.#n))throw Error("Expected enabled to be a boolean or a callback that returns a boolean");this.#y(),this.#n.setOptions(this.options),t._defaulted&&!(0,l.shallowEqualObjects)(this.options,t)&&this.#e.getQueryCache().notify({type:"observerOptionsUpdated",query:this.#n,observer:this});let n=this.hasListeners();n&&h(this.#n,r,this.options,t)&&this.#f(),this.updateResult(),n&&(this.#n!==r||(0,l.resolveQueryBoolean)(this.options.enabled,this.#n)!==(0,l.resolveQueryBoolean)(t.enabled,this.#n)||(0,l.resolveStaleTime)(this.options.staleTime,this.#n)!==(0,l.resolveStaleTime)(t.staleTime,this.#n))&&this.#x();let i=this.#R();n&&(this.#n!==r||(0,l.resolveQueryBoolean)(this.options.enabled,this.#n)!==(0,l.resolveQueryBoolean)(t.enabled,this.#n)||i!==this.#h)&&this.#S(i)}getOptimisticResult(e){var t,r;let n=this.#e.getQueryCache().build(this.#e,e),i=this.createResult(n,e);return t=this,r=i,(0,l.shallowEqualObjects)(t.getCurrentResult(),r)||(this.#s=i,this.#a=this.options,this.#o=this.#n.state),i}getCurrentResult(){return this.#s}trackResult(e,t){return new Proxy(e,{get:(e,r)=>(this.trackProp(r),t?.(r),"promise"===r&&(this.trackProp("data"),this.options.experimental_prefetchInRender||"pending"!==this.#r.status||this.#r.reject(Error("experimental_prefetchInRender feature flag is not enabled"))),Reflect.get(e,r))})}trackProp(e){this.#g.add(e)}getCurrentQuery(){return this.#n}refetch({...e}={}){return this.fetch({...e})}fetchOptimistic(e){let t=this.#e.defaultQueryOptions(e),r=this.#e.getQueryCache().build(this.#e,t);return r.fetch().then(()=>this.createResult(r,t))}fetch(e){return this.#f({...e,cancelRefetch:e.cancelRefetch??!0}).then(()=>(this.updateResult(),this.#s))}#f(e){this.#y();let t=this.#n.fetch(this.options,e);return e?.throwOnError||(t=t.catch(l.noop)),t}#x(){this.#m();let e=(0,l.resolveStaleTime)(this.options.staleTime,this.#n);if(n.environmentManager.isServer()||this.#s.isStale||!(0,l.isValidTimeout)(e))return;let t=(0,l.timeUntilStale)(this.#s.dataUpdatedAt,e);this.#c=u.timeoutManager.setTimeout(()=>{this.#s.isStale||this.updateResult()},t+1)}#R(){return("function"==typeof this.options.refetchInterval?this.options.refetchInterval(this.#n):this.options.refetchInterval)??!1}#S(e){this.#b(),this.#h=e,!n.environmentManager.isServer()&&!1!==(0,l.resolveQueryBoolean)(this.options.enabled,this.#n)&&(0,l.isValidTimeout)(this.#h)&&0!==this.#h&&(this.#p=u.timeoutManager.setInterval(()=>{(this.options.refetchIntervalInBackground||r.focusManager.isFocused())&&this.#f()},this.#h))}#v(){this.#x(),this.#S(this.#R())}#m(){void 0!==this.#c&&(u.timeoutManager.clearTimeout(this.#c),this.#c=void 0)}#b(){void 0!==this.#p&&(u.timeoutManager.clearInterval(this.#p),this.#p=void 0)}createResult(e,t){let r,n=this.#n,i=this.options,o=this.#s,u=this.#o,d=this.#a,p=e!==n?e.state:this.#i,{state:f}=e,v={...f},m=!1;if(t._optimisticResults){let r=this.hasListeners(),o=!r&&c(e,t),a=r&&h(e,n,t,i);(o||a)&&(v={...v,...(0,s.fetchState)(f.data,e.options)}),"isRestoring"===t._optimisticResults&&(v.fetchStatus="idle")}let{error:b,errorUpdatedAt:y,status:x}=v;r=v.data;let R=!1;if(void 0!==t.placeholderData&&void 0===r&&"pending"===x){let e;o?.isPlaceholderData&&t.placeholderData===d?.placeholderData?(e=o.data,R=!0):e="function"==typeof t.placeholderData?t.placeholderData(this.#d?.state.data,this.#d):t.placeholderData,void 0!==e&&(x="success",r=(0,l.replaceData)(o?.data,e,t),m=!0)}if(t.select&&void 0!==r&&!R)if(o&&r===u?.data&&t.select===this.#l)r=this.#u;else try{this.#l=t.select,r=t.select(r),r=(0,l.replaceData)(o?.data,r,t),this.#u=r,this.#t=null}catch(e){this.#t=e}this.#t&&(b=this.#t,r=this.#u,y=Date.now(),x="error");let S="fetching"===v.fetchStatus,C="pending"===x,D="error"===x,w=C&&S,O=void 0!==r,E={status:x,fetchStatus:v.fetchStatus,isPending:C,isSuccess:"success"===x,isError:D,isInitialLoading:w,isLoading:w,data:r,dataUpdatedAt:v.dataUpdatedAt,error:b,errorUpdatedAt:y,failureCount:v.fetchFailureCount,failureReason:v.fetchFailureReason,errorUpdateCount:v.errorUpdateCount,isFetched:e.isFetched(),isFetchedAfterMount:v.dataUpdateCount>p.dataUpdateCount||v.errorUpdateCount>p.errorUpdateCount,isFetching:S,isRefetching:S&&!C,isLoadingError:D&&!O,isPaused:"paused"===v.fetchStatus,isPlaceholderData:m,isRefetchError:D&&O,isStale:g(e,t),refetch:this.refetch,promise:this.#r,isEnabled:!1!==(0,l.resolveQueryBoolean)(t.enabled,e)};if(this.options.experimental_prefetchInRender){let t=void 0!==E.data,r="error"===E.status&&!t,i=e=>{r?e.reject(E.error):t&&e.resolve(E.data)},s=()=>{i(this.#r=E.promise=(0,a.pendingThenable)())},o=this.#r;switch(o.status){case"pending":e.queryHash===n.queryHash&&i(o);break;case"fulfilled":(r||E.data!==o.value)&&s();break;case"rejected":r&&E.error===o.reason||s()}}return E}updateResult(){let e=this.#s,t=this.createResult(this.#n,this.options);if(this.#o=this.#n.state,this.#a=this.options,void 0!==this.#o.data&&(this.#d=this.#n),(0,l.shallowEqualObjects)(t,e))return;this.#s=t;let r=()=>{if(!e)return!0;let{notifyOnChangeProps:t}=this.options,r="function"==typeof t?t():t;if("all"===r||!r&&!this.#g.size)return!0;let n=new Set(r??this.#g);return this.options.throwOnError&&n.add("error"),Object.keys(this.#s).some(t=>this.#s[t]!==e[t]&&n.has(t))};this.#C({listeners:r()})}#y(){let e=this.#e.getQueryCache().build(this.#e,this.options);if(e===this.#n)return;let t=this.#n;this.#n=e,this.#i=e.state,this.hasListeners()&&(t?.removeObserver(this),e.addObserver(this))}onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#v()}#C(e){i.notifyManager.batch(()=>{e.listeners&&this.listeners.forEach(e=>{e(this.#s)}),this.#e.getQueryCache().notify({query:this.#n,type:"observerResultsUpdated"})})}};function c(e,t){return!1!==(0,l.resolveQueryBoolean)(t.enabled,e)&&void 0===e.state.data&&("error"!==e.state.status||!1!==(0,l.resolveQueryBoolean)(t.retryOnMount,e))||void 0!==e.state.data&&p(e,t,t.refetchOnMount)}function p(e,t,r){if(!1!==(0,l.resolveQueryBoolean)(t.enabled,e)&&"static"!==(0,l.resolveStaleTime)(t.staleTime,e)){let n="function"==typeof r?r(e):r;return"always"===n||!1!==n&&g(e,t)}return!1}function h(e,t,r,n){return(e!==t||!1===(0,l.resolveQueryBoolean)(n.enabled,e))&&(!r.suspense||"error"!==e.state.status)&&g(e,r)}function g(e,t){return!1!==(0,l.resolveQueryBoolean)(t.enabled,e)&&e.isStaleByTime((0,l.resolveStaleTime)(t.staleTime,e))}e.s(["QueryObserver",0,d],869230),e.i(247167);var f=e.i(271645),v=e.i(912598);e.i(843476);var m=f.createContext((t=!1,{clearReset:()=>{t=!1},reset:()=>{t=!0},isReset:()=>t})),b=f.createContext(!1);b.Provider;var y=e=>{if(e.suspense){let t=e=>"static"===e?e:Math.max(e??1e3,1e3),r=e.staleTime;e.staleTime="function"==typeof r?(...e)=>t(r(...e)):t(r),"number"==typeof e.gcTime&&(e.gcTime=Math.max(e.gcTime,1e3))}},x=(e,t)=>e.isLoading&&e.isFetching&&!t,R=(e,t)=>e?.suspense&&t.isPending,S=(e,t,r)=>t.fetchOptimistic(e).catch(()=>{r.clearReset()});function C(e,t,r){let s,o=f.useContext(b),a=f.useContext(m),u=(0,v.useQueryClient)(r),d=u.defaultQueryOptions(e);u.getDefaultOptions().queries?._experimental_beforeQuery?.(d);let c=u.getQueryCache().get(d.queryHash);d._optimisticResults=o?"isRestoring":"optimistic",y(d),s=c?.state.error&&"function"==typeof d.throwOnError?(0,l.shouldThrowError)(d.throwOnError,[c.state.error,c]):d.throwOnError,(d.suspense||d.experimental_prefetchInRender||s)&&!a.isReset()&&(d.retryOnMount=!1),f.useEffect(()=>{a.clearReset()},[a]);let p=!u.getQueryCache().get(d.queryHash),[h]=f.useState(()=>new t(u,d)),g=h.getOptimisticResult(d),C=!o&&!1!==e.subscribed;if(f.useSyncExternalStore(f.useCallback(e=>{let t=C?h.subscribe(i.notifyManager.batchCalls(e)):l.noop;return h.updateResult(),t},[h,C]),()=>h.getCurrentResult(),()=>h.getCurrentResult()),f.useEffect(()=>{h.setOptions(d)},[d,h]),R(d,g))throw S(d,h,a);if((({result:e,errorResetBoundary:t,throwOnError:r,query:n,suspense:i})=>e.isError&&!t.isReset()&&!e.isFetching&&n&&(i&&void 0===e.data||(0,l.shouldThrowError)(r,[e.error,n])))({result:g,errorResetBoundary:a,throwOnError:d.throwOnError,query:c,suspense:d.suspense}))throw g.error;if(u.getDefaultOptions().queries?._experimental_afterQuery?.(d,g),d.experimental_prefetchInRender&&!n.environmentManager.isServer()&&x(g,o)){let e=p?S(d,h,a):c?.promise;e?.catch(l.noop).finally(()=>{h.updateResult()})}return d.notifyOnChangeProps?g:h.trackResult(g)}e.s(["defaultThrowOnError",0,(e,t)=>void 0===t.state.data,"ensureSuspenseTimers",0,y,"fetchOptimistic",0,S,"shouldSuspend",0,R,"willFetch",0,x],254440),e.s(["useBaseQuery",0,C],469637),e.s(["useQuery",0,function(e,t){return C(e,d,t)}],266027)},321836,e=>{"use strict";let t="litellm_return_url",r="redirect_to";function n(){return window.location.href}function i(){if("u"typeof document&&(document.cookie=`${t}=; path=/; max-age=0`)}catch(e){console.error("Failed to clear return URL cookie:",e)}}function o(){return new URLSearchParams(window.location.search).get(r)}function a(){let e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e||"::1"===e||e.startsWith("127.")||e.endsWith(".local")}function l(e){if(!e)return!1;if(e.startsWith("/")&&!e.startsWith("//"))return!0;try{let t=new URL(e),r=window.location.hostname;if(t.hostname!==r)return!1;if(a())return!0;return t.origin===window.location.origin}catch{return!1}}e.s(["buildLoginUrlWithReturn",0,function(e,t){let i=t||n();if(!i||i.includes("/login"))return e;let s=e.includes("?")?"&":"?";return`${e}${s}${r}=${encodeURIComponent(i)}`},"clearStoredReturnUrl",0,s,"consumeReturnUrl",0,function(){let e=o();if(e){if(l(e))return s(),e;a()&&console.warn("[returnUrlUtils] Invalid return URL in params rejected:",e)}let t=i();if(t){if(l(t))return s(),t;a()&&console.warn("[returnUrlUtils] Invalid return URL in cookie rejected:",t)}return null},"getLoginUrl",0,function(e=""){return`${e}/ui/login/`},"getReturnUrl",0,function(){let e=o();if(e)return e;let t=i();return t||null},"isValidReturnUrl",0,l,"normalizeUrlForCompare",0,function(e){try{let t=new URL(e,window.location.origin),r=t.pathname;r.length>1&&r.endsWith("/")&&(r=r.slice(0,-1));let n=new URLSearchParams(t.search),i=new URLSearchParams;Array.from(n.entries()).sort(([e],[t])=>e.localeCompare(t)).forEach(([e,t])=>{i.append(e,t)});let s=i.toString(),o=t.hash||"";return`${t.origin}${r}${s?`?${s}`:""}${o}`}catch{return e}},"storeReturnUrl",0,function(){let e=n();e&&function(e,t,r=300){if("u"{"use strict";e.s(["createQueryKeys",0,function(e){let t=[e];return{all:t,lists:()=>[...t,"list"],list:e=>[...t,"list",{params:e}],details:()=>[...t,"detail"],detail:e=>[...t,"detail",e]}}])},612256,e=>{"use strict";var t=e.i(602869),r=e.i(266027);let n=(0,e.i(243652).createQueryKeys)("uiConfig");e.s(["useUIConfig",0,()=>(0,r.useQuery)({queryKey:n.list({}),queryFn:async()=>await (0,t.getUiConfig)(),staleTime:864e5,gcTime:864e5})])},135214,e=>{"use strict";var t=e.i(602869),r=e.i(268004),n=e.i(161281),i=e.i(321836),s=e.i(271645),o=e.i(708347),a=e.i(612256);e.s(["default",0,()=>{let{data:e,isLoading:l}=(0,a.useUIConfig)(),u="u">typeof document?(0,r.getCookie)("token"):null,d=(0,s.useMemo)(()=>(0,n.decodeToken)(u),[u]),c=(0,s.useMemo)(()=>(0,n.checkTokenValidity)(u),[u])&&!e?.admin_ui_disabled,p=(0,s.useCallback)(()=>{(0,i.storeReturnUrl)();let e=(0,i.getLoginUrl)((0,t.getProxyBaseUrl)()),r=(0,i.buildLoginUrlWithReturn)(e);window.location.replace(r)},[]);return(0,s.useEffect)(()=>{!l&&(c||(u&&(0,r.clearTokenCookies)(),p()))},[l,c,u,p]),{isLoading:l,isAuthorized:c,token:c?u:null,accessToken:d?.key??null,userId:d?.user_id??null,userEmail:d?.user_email??null,userRole:(0,o.effectiveSessionRole)(d?.user_role),userRoleLabel:(0,o.formatUserRole)(d?.user_role),isViewOnly:(0,o.isViewOnlySessionRole)(d?.user_role),premiumUser:d?.premium_user??null,disabledPersonalKeyCreation:d?.disabled_non_admin_personal_key_creation??null,showSSOBanner:d?.login_method==="username_password"}}])},246349,e=>{"use strict";let t=(0,e.i(475254).default)("chevron-right",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);e.s(["default",0,t])},395530,e=>{"use strict";var t=e.i(271645),r=e.i(828918),n=e.i(838452),i=e.i(673553);e.s(["useCompositeItem",0,function(e={}){let{highlightItemOnHover:s,highlightedIndex:o,onHighlightedIndexChange:a}=(0,n.useCompositeRootContext)(),{ref:l,index:u}=(0,i.useCompositeListItem)(e),d=o===u,c=t.useRef(null),p=(0,r.useMergedRefs)(l,c);return{compositeProps:{tabIndex:d?0:-1,onFocus(){a(u)},onMouseMove(){let e=c.current;if(!s||!e)return;let t=e.hasAttribute("disabled")||"true"===e.ariaDisabled;d||t||e.focus()}},compositeRef:p,index:u}}])},950594,e=>{"use strict";var t=e.i(843476),r=e.i(225913),n=e.i(196631),i=e.i(519455),s=e.i(793479),o=e.i(624687);let a=(0,r.cva)("flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",{variants:{align:{"inline-start":"order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]","inline-end":"order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]","block-start":"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2","block-end":"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2"}},defaultVariants:{align:"inline-start"}}),l=(0,r.cva)("flex items-center gap-2 text-sm shadow-none",{variants:{size:{xs:"h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",sm:"","icon-xs":"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0","icon-sm":"size-8 p-0 has-[>svg]:p-0"}},defaultVariants:{size:"xs"}});e.s(["InputGroup",0,function({className:e,...r}){return(0,t.jsx)("div",{"data-slot":"input-group",role:"group",className:(0,n.cn)("group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",e),...r})},"InputGroupAddon",0,function({className:e,align:r="inline-start",...i}){return(0,t.jsx)("div",{role:"group","data-slot":"input-group-addon","data-align":r,className:(0,n.cn)(a({align:r}),e),onClick:e=>{e.target.closest("button")||e.currentTarget.parentElement?.querySelector("input")?.focus()},...i})},"InputGroupButton",0,function({className:e,type:r="button",variant:s="ghost",size:o="xs",...a}){return(0,t.jsx)(i.Button,{type:r,"data-size":o,variant:s,className:(0,n.cn)(l({size:o}),e),...a})},"InputGroupInput",0,function({className:e,...r}){return(0,t.jsx)(s.Input,{"data-slot":"input-group-control",className:(0,n.cn)("flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",e),...r})},"InputGroupText",0,function({className:e,...r}){return(0,t.jsx)("span",{className:(0,n.cn)("flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",e),...r})},"InputGroupTextarea",0,function({className:e,...r}){return(0,t.jsx)(o.Textarea,{"data-slot":"input-group-control",className:(0,n.cn)("flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",e),...r})}])},989257,e=>{"use strict";e.s(["stringifyLocale",0,function e(t){return Array.isArray(t)?t.map(t=>e(t)).join(","):null==t?"":String(t)}])}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/1v3m908ycsmt4.js b/litellm/proxy/_experimental/out/_next/static/chunks/07cqsb7poupf9.js
similarity index 59%
rename from litellm/proxy/_experimental/out/_next/static/chunks/1v3m908ycsmt4.js
rename to litellm/proxy/_experimental/out/_next/static/chunks/07cqsb7poupf9.js
index 9d69deb0641..afac03c563b 100644
--- a/litellm/proxy/_experimental/out/_next/static/chunks/1v3m908ycsmt4.js
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/07cqsb7poupf9.js
@@ -1,4 +1,4 @@
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,152990,682830,e=>{"use strict";var t=e.i(271645);function l(e,t){return"function"==typeof e?e(t):e}function n(e,t){return n=>{t.setState(t=>({...t,[e]:l(n,t[e])}))}}function o(e){return e instanceof Function}function i(e,t,l){let n,o=[];return i=>{let a,r;l.key&&l.debug&&(a=Date.now());let s=e(i);if(!(s.length!==o.length||s.some((e,t)=>o[t]!==e)))return n;if(o=s,l.key&&l.debug&&(r=Date.now()),n=t(...s),null==l||null==l.onChange||l.onChange(n),l.key&&l.debug&&null!=l&&l.debug()){let e=Math.round((Date.now()-a)*100)/100,t=Math.round((Date.now()-r)*100)/100,n=t/16,o=(e,t)=>{for(e=String(e);e.length{var l;return null!=(l=null==e?void 0:e.debugAll)?l:e[t]},key:!1,onChange:n}}e.i(247167);let r="debugHeaders";function s(e,t,l){var n;let o={id:null!=(n=l.id)?n:t.id,column:t,index:l.index,isPlaceholder:!!l.isPlaceholder,placeholderId:l.placeholderId,depth:l.depth,subHeaders:[],colSpan:0,rowSpan:0,headerGroup:null,getLeafHeaders:()=>{let e=[],t=l=>{l.subHeaders&&l.subHeaders.length&&l.subHeaders.map(t),e.push(l)};return t(o),e},getContext:()=>({table:e,header:o,column:t})};return e._features.forEach(t=>{null==t.createHeader||t.createHeader(o,e)}),o}function u(e,t,l,n){var o,i;let a=0,r=function(e,t){void 0===t&&(t=1),a=Math.max(a,t),e.filter(e=>e.getIsVisible()).forEach(e=>{var l;null!=(l=e.columns)&&l.length&&r(e.columns,t+1)},0)};r(e);let u=[],d=(e,t)=>{let o={depth:t,id:[n,`${t}`].filter(Boolean).join("_"),headers:[]},i=[];e.forEach(e=>{let a,r=[...i].reverse()[0],u=e.column.depth===o.depth,d=!1;if(u&&e.column.parent?a=e.column.parent:(a=e.column,d=!0),r&&(null==r?void 0:r.column)===a)r.subHeaders.push(e);else{let o=s(l,a,{id:[n,t,a.id,null==e?void 0:e.id].filter(Boolean).join("_"),isPlaceholder:d,placeholderId:d?`${i.filter(e=>e.column===a).length}`:void 0,depth:t,index:i.length});o.subHeaders.push(e),i.push(o)}o.headers.push(e),e.headerGroup=o}),u.push(o),t>0&&d(i,t-1)};d(t.map((e,t)=>s(l,e,{depth:a,index:t})),a-1),u.reverse();let g=e=>e.filter(e=>e.column.getIsVisible()).map(e=>{let t=0,l=0,n=[0];return e.subHeaders&&e.subHeaders.length?(n=[],g(e.subHeaders).forEach(e=>{let{colSpan:l,rowSpan:o}=e;t+=l,n.push(o)})):t=1,l+=Math.min(...n),e.colSpan=t,e.rowSpan=l,{colSpan:t,rowSpan:l}});return g(null!=(o=null==(i=u[0])?void 0:i.headers)?o:[]),u}let d=(e,t,l,n,o,r,s)=>{let u={id:t,index:n,original:l,depth:o,parentId:s,_valuesCache:{},_uniqueValuesCache:{},getValue:t=>{if(u._valuesCache.hasOwnProperty(t))return u._valuesCache[t];let l=e.getColumn(t);if(null!=l&&l.accessorFn)return u._valuesCache[t]=l.accessorFn(u.original,n),u._valuesCache[t]},getUniqueValues:t=>{if(u._uniqueValuesCache.hasOwnProperty(t))return u._uniqueValuesCache[t];let l=e.getColumn(t);if(null!=l&&l.accessorFn)return l.columnDef.getUniqueValues?u._uniqueValuesCache[t]=l.columnDef.getUniqueValues(u.original,n):u._uniqueValuesCache[t]=[u.getValue(t)],u._uniqueValuesCache[t]},renderValue:t=>{var l;return null!=(l=u.getValue(t))?l:e.options.renderFallbackValue},subRows:null!=r?r:[],getLeafRows:()=>{var e,t;let l,n;return e=u.subRows,t=e=>e.subRows,l=[],(n=e=>{e.forEach(e=>{l.push(e);let o=t(e);null!=o&&o.length&&n(o)})})(e),l},getParentRow:()=>u.parentId?e.getRow(u.parentId,!0):void 0,getParentRows:()=>{let e=[],t=u;for(;;){let l=t.getParentRow();if(!l)break;e.push(l),t=l}return e.reverse()},getAllCells:i(()=>[e.getAllLeafColumns()],t=>t.map(t=>{var l;let n;return l=t.id,n={id:`${u.id}_${t.id}`,row:u,column:t,getValue:()=>u.getValue(l),renderValue:()=>{var t;return null!=(t=n.getValue())?t:e.options.renderFallbackValue},getContext:i(()=>[e,t,u,n],(e,t,l,n)=>({table:e,column:t,row:l,cell:n,getValue:n.getValue,renderValue:n.renderValue}),a(e.options,"debugCells","cell.getContext"))},e._features.forEach(l=>{null==l.createCell||l.createCell(n,t,u,e)},{}),n}),a(e.options,"debugRows","getAllCells")),_getAllCellsByColumnId:i(()=>[u.getAllCells()],e=>e.reduce((e,t)=>(e[t.column.id]=t,e),{}),a(e.options,"debugRows","getAllCellsByColumnId"))};for(let t=0;t{var n,o;let i=null==l||null==(n=l.toString())?void 0:n.toLowerCase();return!!(null==(o=e.getValue(t))||null==(o=o.toString())||null==(o=o.toLowerCase())?void 0:o.includes(i))};g.autoRemove=e=>x(e);let c=(e,t,l)=>{var n;return!!(null==(n=e.getValue(t))||null==(n=n.toString())?void 0:n.includes(l))};c.autoRemove=e=>x(e);let m=(e,t,l)=>{var n;return(null==(n=e.getValue(t))||null==(n=n.toString())?void 0:n.toLowerCase())===(null==l?void 0:l.toLowerCase())};m.autoRemove=e=>x(e);let p=(e,t,l)=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)};p.autoRemove=e=>x(e);let f=(e,t,l)=>!l.some(l=>{var n;return!(null!=(n=e.getValue(t))&&n.includes(l))});f.autoRemove=e=>x(e)||!(null!=e&&e.length);let h=(e,t,l)=>l.some(l=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)});h.autoRemove=e=>x(e)||!(null!=e&&e.length);let v=(e,t,l)=>e.getValue(t)===l;v.autoRemove=e=>x(e);let b=(e,t,l)=>e.getValue(t)==l;b.autoRemove=e=>x(e);let w=(e,t,l)=>{let[n,o]=l,i=e.getValue(t);return i>=n&&i<=o};w.resolveFilterValue=e=>{let[t,l]=e,n="number"!=typeof t?parseFloat(t):t,o="number"!=typeof l?parseFloat(l):l,i=null===t||Number.isNaN(n)?-1/0:n,a=null===l||Number.isNaN(o)?1/0:o;if(i>a){let e=i;i=a,a=e}return[i,a]},w.autoRemove=e=>x(e)||x(e[0])&&x(e[1]);let C={includesString:g,includesStringSensitive:c,equalsString:m,arrIncludes:p,arrIncludesAll:f,arrIncludesSome:h,equals:v,weakEquals:b,inNumberRange:w};function x(e){return null==e||""===e}function S(e,t,l){return!!e&&!!e.autoRemove&&e.autoRemove(t,l)||void 0===t||"string"==typeof t&&!t}let R={sum:(e,t,l)=>l.reduce((t,l)=>{let n=l.getValue(e);return t+("number"==typeof n?n:0)},0),min:(e,t,l)=>{let n;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(n>l||void 0===n&&l>=l)&&(n=l)}),n},max:(e,t,l)=>{let n;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(n=l)&&(n=l)}),n},extent:(e,t,l)=>{let n,o;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(void 0===n?l>=l&&(n=o=l):(n>l&&(n=l),o{let l=0,n=0;if(t.forEach(t=>{let o=t.getValue(e);null!=o&&(o*=1)>=o&&(++l,n+=o)}),l)return n/l},median:(e,t)=>{if(!t.length)return;let l=t.map(t=>t.getValue(e));if(!(Array.isArray(l)&&l.every(e=>"number"==typeof e)))return;if(1===l.length)return l[0];let n=Math.floor(l.length/2),o=l.sort((e,t)=>e-t);return l.length%2!=0?o[n]:(o[n-1]+o[n])/2},unique:(e,t)=>Array.from(new Set(t.map(t=>t.getValue(e))).values()),uniqueCount:(e,t)=>new Set(t.map(t=>t.getValue(e))).size,count:(e,t)=>t.length},F=()=>({left:[],right:[]}),y={size:150,minSize:20,maxSize:Number.MAX_SAFE_INTEGER},M=()=>({startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,isResizingColumn:!1,columnSizingStart:[]}),j=null;function P(e){return"touchstart"===e.type}function I(e,t){return t?"center"===t?e.getCenterVisibleLeafColumns():"left"===t?e.getLeftVisibleLeafColumns():e.getRightVisibleLeafColumns():e.getVisibleLeafColumns()}let V=()=>({pageIndex:0,pageSize:10}),_=()=>({top:[],bottom:[]}),z=(e,t,l,n,o)=>{var i;let a=o.getRow(t,!0);l?(a.getCanMultiSelect()||Object.keys(e).forEach(t=>delete e[t]),a.getCanSelect()&&(e[t]=!0)):delete e[t],n&&null!=(i=a.subRows)&&i.length&&a.getCanSelectSubRows()&&a.subRows.forEach(t=>z(e,t.id,l,n,o))};function N(e,t){let l=e.getState().rowSelection,n=[],o={},i=function(e,t){return e.map(e=>{var t;let a=D(e,l);if(a&&(n.push(e),o[e.id]=e),null!=(t=e.subRows)&&t.length&&(e={...e,subRows:i(e.subRows)}),a)return e}).filter(Boolean)};return{rows:i(t.rows),flatRows:n,rowsById:o}}function D(e,t){var l;return null!=(l=t[e.id])&&l}function E(e,t,l){var n;if(!(null!=(n=e.subRows)&&n.length))return!1;let o=!0,i=!1;return e.subRows.forEach(e=>{if((!i||o)&&(e.getCanSelect()&&(D(e,t)?i=!0:o=!1),e.subRows&&e.subRows.length)){let l=E(e,t);"all"===l?i=!0:("some"===l&&(i=!0),o=!1)}}),o?"all":!!i&&"some"}let k=/([0-9]+)/gm;function L(e,t){return e===t?0:e>t?1:-1}function A(e){return"number"==typeof e?isNaN(e)||e===1/0||e===-1/0?"":String(e):"string"==typeof e?e:""}function G(e,t){let l=e.split(k).filter(Boolean),n=t.split(k).filter(Boolean);for(;l.length&&n.length;){let e=l.shift(),t=n.shift(),o=parseInt(e,10),i=parseInt(t,10),a=[o,i].sort();if(isNaN(a[0])){if(e>t)return 1;if(t>e)return -1;continue}if(isNaN(a[1]))return isNaN(o)?-1:1;if(o>i)return 1;if(i>o)return -1}return l.length-n.length}let H={alphanumeric:(e,t,l)=>G(A(e.getValue(l)).toLowerCase(),A(t.getValue(l)).toLowerCase()),alphanumericCaseSensitive:(e,t,l)=>G(A(e.getValue(l)),A(t.getValue(l))),text:(e,t,l)=>L(A(e.getValue(l)).toLowerCase(),A(t.getValue(l)).toLowerCase()),textCaseSensitive:(e,t,l)=>L(A(e.getValue(l)),A(t.getValue(l))),datetime:(e,t,l)=>{let n=e.getValue(l),o=t.getValue(l);return n>o?1:nL(e.getValue(l),t.getValue(l))},T=[{createTable:e=>{e.getHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,l,n,o)=>{var i,a;let r=null!=(i=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?i:[],s=null!=(a=null==o?void 0:o.map(e=>l.find(t=>t.id===e)).filter(Boolean))?a:[];return u(t,[...r,...l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),...s],e)},a(e.options,r,"getHeaderGroups")),e.getCenterHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,l,n,o)=>u(t,l=l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),e,"center"),a(e.options,r,"getCenterHeaderGroups")),e.getLeftHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left],(t,l,n)=>{var o;return u(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"left")},a(e.options,r,"getLeftHeaderGroups")),e.getRightHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.right],(t,l,n)=>{var o;return u(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"right")},a(e.options,r,"getRightHeaderGroups")),e.getFooterGroups=i(()=>[e.getHeaderGroups()],e=>[...e].reverse(),a(e.options,r,"getFooterGroups")),e.getLeftFooterGroups=i(()=>[e.getLeftHeaderGroups()],e=>[...e].reverse(),a(e.options,r,"getLeftFooterGroups")),e.getCenterFooterGroups=i(()=>[e.getCenterHeaderGroups()],e=>[...e].reverse(),a(e.options,r,"getCenterFooterGroups")),e.getRightFooterGroups=i(()=>[e.getRightHeaderGroups()],e=>[...e].reverse(),a(e.options,r,"getRightFooterGroups")),e.getFlatHeaders=i(()=>[e.getHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,r,"getFlatHeaders")),e.getLeftFlatHeaders=i(()=>[e.getLeftHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,r,"getLeftFlatHeaders")),e.getCenterFlatHeaders=i(()=>[e.getCenterHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,r,"getCenterFlatHeaders")),e.getRightFlatHeaders=i(()=>[e.getRightHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,r,"getRightFlatHeaders")),e.getCenterLeafHeaders=i(()=>[e.getCenterFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,r,"getCenterLeafHeaders")),e.getLeftLeafHeaders=i(()=>[e.getLeftFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,r,"getLeftLeafHeaders")),e.getRightLeafHeaders=i(()=>[e.getRightFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,r,"getRightLeafHeaders")),e.getLeafHeaders=i(()=>[e.getLeftHeaderGroups(),e.getCenterHeaderGroups(),e.getRightHeaderGroups()],(e,t,l)=>{var n,o,i,a,r,s;return[...null!=(n=null==(o=e[0])?void 0:o.headers)?n:[],...null!=(i=null==(a=t[0])?void 0:a.headers)?i:[],...null!=(r=null==(s=l[0])?void 0:s.headers)?r:[]].map(e=>e.getLeafHeaders()).flat()},a(e.options,r,"getLeafHeaders"))}},{getInitialState:e=>({columnVisibility:{},...e}),getDefaultOptions:e=>({onColumnVisibilityChange:n("columnVisibility",e)}),createColumn:(e,t)=>{e.toggleVisibility=l=>{e.getCanHide()&&t.setColumnVisibility(t=>({...t,[e.id]:null!=l?l:!e.getIsVisible()}))},e.getIsVisible=()=>{var l,n;let o=e.columns;return null==(l=o.length?o.some(e=>e.getIsVisible()):null==(n=t.getState().columnVisibility)?void 0:n[e.id])||l},e.getCanHide=()=>{var l,n;return(null==(l=e.columnDef.enableHiding)||l)&&(null==(n=t.options.enableHiding)||n)},e.getToggleVisibilityHandler=()=>t=>{null==e.toggleVisibility||e.toggleVisibility(t.target.checked)}},createRow:(e,t)=>{e._getAllVisibleCells=i(()=>[e.getAllCells(),t.getState().columnVisibility],e=>e.filter(e=>e.column.getIsVisible()),a(t.options,"debugRows","_getAllVisibleCells")),e.getVisibleCells=i(()=>[e.getLeftVisibleCells(),e.getCenterVisibleCells(),e.getRightVisibleCells()],(e,t,l)=>[...e,...t,...l],a(t.options,"debugRows","getVisibleCells"))},createTable:e=>{let t=(t,l)=>i(()=>[l(),l().filter(e=>e.getIsVisible()).map(e=>e.id).join("_")],e=>e.filter(e=>null==e.getIsVisible?void 0:e.getIsVisible()),a(e.options,"debugColumns",t));e.getVisibleFlatColumns=t("getVisibleFlatColumns",()=>e.getAllFlatColumns()),e.getVisibleLeafColumns=t("getVisibleLeafColumns",()=>e.getAllLeafColumns()),e.getLeftVisibleLeafColumns=t("getLeftVisibleLeafColumns",()=>e.getLeftLeafColumns()),e.getRightVisibleLeafColumns=t("getRightVisibleLeafColumns",()=>e.getRightLeafColumns()),e.getCenterVisibleLeafColumns=t("getCenterVisibleLeafColumns",()=>e.getCenterLeafColumns()),e.setColumnVisibility=t=>null==e.options.onColumnVisibilityChange?void 0:e.options.onColumnVisibilityChange(t),e.resetColumnVisibility=t=>{var l;e.setColumnVisibility(t?{}:null!=(l=e.initialState.columnVisibility)?l:{})},e.toggleAllColumnsVisible=t=>{var l;t=null!=(l=t)?l:!e.getIsAllColumnsVisible(),e.setColumnVisibility(e.getAllLeafColumns().reduce((e,l)=>({...e,[l.id]:t||!(null!=l.getCanHide&&l.getCanHide())}),{}))},e.getIsAllColumnsVisible=()=>!e.getAllLeafColumns().some(e=>!(null!=e.getIsVisible&&e.getIsVisible())),e.getIsSomeColumnsVisible=()=>e.getAllLeafColumns().some(e=>null==e.getIsVisible?void 0:e.getIsVisible()),e.getToggleAllColumnsVisibilityHandler=()=>t=>{var l;e.toggleAllColumnsVisible(null==(l=t.target)?void 0:l.checked)}}},{getInitialState:e=>({columnOrder:[],...e}),getDefaultOptions:e=>({onColumnOrderChange:n("columnOrder",e)}),createColumn:(e,t)=>{e.getIndex=i(e=>[I(t,e)],t=>t.findIndex(t=>t.id===e.id),a(t.options,"debugColumns","getIndex")),e.getIsFirstColumn=l=>{var n;return(null==(n=I(t,l)[0])?void 0:n.id)===e.id},e.getIsLastColumn=l=>{var n;let o=I(t,l);return(null==(n=o[o.length-1])?void 0:n.id)===e.id}},createTable:e=>{e.setColumnOrder=t=>null==e.options.onColumnOrderChange?void 0:e.options.onColumnOrderChange(t),e.resetColumnOrder=t=>{var l;e.setColumnOrder(t?[]:null!=(l=e.initialState.columnOrder)?l:[])},e._getOrderColumnsFn=i(()=>[e.getState().columnOrder,e.getState().grouping,e.options.groupedColumnMode],(e,t,l)=>n=>{let o=[];if(null!=e&&e.length){let t=[...e],l=[...n];for(;l.length&&t.length;){let e=t.shift(),n=l.findIndex(t=>t.id===e);n>-1&&o.push(l.splice(n,1)[0])}o=[...o,...l]}else o=n;var i=o;if(!(null!=t&&t.length)||!l)return i;let a=i.filter(e=>!t.includes(e.id));return"remove"===l?a:[...t.map(e=>i.find(t=>t.id===e)).filter(Boolean),...a]},a(e.options,"debugTable","_getOrderColumnsFn"))}},{getInitialState:e=>({columnPinning:F(),...e}),getDefaultOptions:e=>({onColumnPinningChange:n("columnPinning",e)}),createColumn:(e,t)=>{e.pin=l=>{let n=e.getLeafColumns().map(e=>e.id).filter(Boolean);t.setColumnPinning(e=>{var t,o,i,a,r,s;return"right"===l?{left:(null!=(i=null==e?void 0:e.left)?i:[]).filter(e=>!(null!=n&&n.includes(e))),right:[...(null!=(a=null==e?void 0:e.right)?a:[]).filter(e=>!(null!=n&&n.includes(e))),...n]}:"left"===l?{left:[...(null!=(r=null==e?void 0:e.left)?r:[]).filter(e=>!(null!=n&&n.includes(e))),...n],right:(null!=(s=null==e?void 0:e.right)?s:[]).filter(e=>!(null!=n&&n.includes(e)))}:{left:(null!=(t=null==e?void 0:e.left)?t:[]).filter(e=>!(null!=n&&n.includes(e))),right:(null!=(o=null==e?void 0:e.right)?o:[]).filter(e=>!(null!=n&&n.includes(e)))}})},e.getCanPin=()=>e.getLeafColumns().some(e=>{var l,n,o;return(null==(l=e.columnDef.enablePinning)||l)&&(null==(n=null!=(o=t.options.enableColumnPinning)?o:t.options.enablePinning)||n)}),e.getIsPinned=()=>{let l=e.getLeafColumns().map(e=>e.id),{left:n,right:o}=t.getState().columnPinning,i=l.some(e=>null==n?void 0:n.includes(e)),a=l.some(e=>null==o?void 0:o.includes(e));return i?"left":!!a&&"right"},e.getPinnedIndex=()=>{var l,n;let o=e.getIsPinned();return o?null!=(l=null==(n=t.getState().columnPinning)||null==(n=n[o])?void 0:n.indexOf(e.id))?l:-1:0}},createRow:(e,t)=>{e.getCenterVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.left,t.getState().columnPinning.right],(e,t,l)=>{let n=[...null!=t?t:[],...null!=l?l:[]];return e.filter(e=>!n.includes(e.column.id))},a(t.options,"debugRows","getCenterVisibleCells")),e.getLeftVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.left],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.column.id===t)).filter(Boolean).map(e=>({...e,position:"left"})),a(t.options,"debugRows","getLeftVisibleCells")),e.getRightVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.right],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.column.id===t)).filter(Boolean).map(e=>({...e,position:"right"})),a(t.options,"debugRows","getRightVisibleCells"))},createTable:e=>{e.setColumnPinning=t=>null==e.options.onColumnPinningChange?void 0:e.options.onColumnPinningChange(t),e.resetColumnPinning=t=>{var l,n;return e.setColumnPinning(t?F():null!=(l=null==(n=e.initialState)?void 0:n.columnPinning)?l:F())},e.getIsSomeColumnsPinned=t=>{var l,n,o;let i=e.getState().columnPinning;return t?!!(null==(l=i[t])?void 0:l.length):!!((null==(n=i.left)?void 0:n.length)||(null==(o=i.right)?void 0:o.length))},e.getLeftLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),a(e.options,"debugColumns","getLeftLeafColumns")),e.getRightLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.right],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),a(e.options,"debugColumns","getRightLeafColumns")),e.getCenterLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(e,t,l)=>{let n=[...null!=t?t:[],...null!=l?l:[]];return e.filter(e=>!n.includes(e.id))},a(e.options,"debugColumns","getCenterLeafColumns"))}},{createColumn:(e,t)=>{e._getFacetedRowModel=t.options.getFacetedRowModel&&t.options.getFacetedRowModel(t,e.id),e.getFacetedRowModel=()=>e._getFacetedRowModel?e._getFacetedRowModel():t.getPreFilteredRowModel(),e._getFacetedUniqueValues=t.options.getFacetedUniqueValues&&t.options.getFacetedUniqueValues(t,e.id),e.getFacetedUniqueValues=()=>e._getFacetedUniqueValues?e._getFacetedUniqueValues():new Map,e._getFacetedMinMaxValues=t.options.getFacetedMinMaxValues&&t.options.getFacetedMinMaxValues(t,e.id),e.getFacetedMinMaxValues=()=>{if(e._getFacetedMinMaxValues)return e._getFacetedMinMaxValues()}}},{getDefaultColumnDef:()=>({filterFn:"auto"}),getInitialState:e=>({columnFilters:[],...e}),getDefaultOptions:e=>({onColumnFiltersChange:n("columnFilters",e),filterFromLeafRows:!1,maxLeafRowFilterDepth:100}),createColumn:(e,t)=>{e.getAutoFilterFn=()=>{let l=t.getCoreRowModel().flatRows[0],n=null==l?void 0:l.getValue(e.id);return"string"==typeof n?C.includesString:"number"==typeof n?C.inNumberRange:"boolean"==typeof n||null!==n&&"object"==typeof n?C.equals:Array.isArray(n)?C.arrIncludes:C.weakEquals},e.getFilterFn=()=>{var l,n;return o(e.columnDef.filterFn)?e.columnDef.filterFn:"auto"===e.columnDef.filterFn?e.getAutoFilterFn():null!=(l=null==(n=t.options.filterFns)?void 0:n[e.columnDef.filterFn])?l:C[e.columnDef.filterFn]},e.getCanFilter=()=>{var l,n,o;return(null==(l=e.columnDef.enableColumnFilter)||l)&&(null==(n=t.options.enableColumnFilters)||n)&&(null==(o=t.options.enableFilters)||o)&&!!e.accessorFn},e.getIsFiltered=()=>e.getFilterIndex()>-1,e.getFilterValue=()=>{var l;return null==(l=t.getState().columnFilters)||null==(l=l.find(t=>t.id===e.id))?void 0:l.value},e.getFilterIndex=()=>{var l,n;return null!=(l=null==(n=t.getState().columnFilters)?void 0:n.findIndex(t=>t.id===e.id))?l:-1},e.setFilterValue=n=>{t.setColumnFilters(t=>{var o,i;let a=e.getFilterFn(),r=null==t?void 0:t.find(t=>t.id===e.id),s=l(n,r?r.value:void 0);if(S(a,s,e))return null!=(o=null==t?void 0:t.filter(t=>t.id!==e.id))?o:[];let u={id:e.id,value:s};return r?null!=(i=null==t?void 0:t.map(t=>t.id===e.id?u:t))?i:[]:null!=t&&t.length?[...t,u]:[u]})}},createRow:(e,t)=>{e.columnFilters={},e.columnFiltersMeta={}},createTable:e=>{e.setColumnFilters=t=>{let n=e.getAllLeafColumns();null==e.options.onColumnFiltersChange||e.options.onColumnFiltersChange(e=>{var o;return null==(o=l(t,e))?void 0:o.filter(e=>{let t=n.find(t=>t.id===e.id);return!(t&&S(t.getFilterFn(),e.value,t))&&!0})})},e.resetColumnFilters=t=>{var l,n;e.setColumnFilters(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.columnFilters)?l:[])},e.getPreFilteredRowModel=()=>e.getCoreRowModel(),e.getFilteredRowModel=()=>(!e._getFilteredRowModel&&e.options.getFilteredRowModel&&(e._getFilteredRowModel=e.options.getFilteredRowModel(e)),e.options.manualFiltering||!e._getFilteredRowModel)?e.getPreFilteredRowModel():e._getFilteredRowModel()}},{createTable:e=>{e._getGlobalFacetedRowModel=e.options.getFacetedRowModel&&e.options.getFacetedRowModel(e,"__global__"),e.getGlobalFacetedRowModel=()=>e.options.manualFiltering||!e._getGlobalFacetedRowModel?e.getPreFilteredRowModel():e._getGlobalFacetedRowModel(),e._getGlobalFacetedUniqueValues=e.options.getFacetedUniqueValues&&e.options.getFacetedUniqueValues(e,"__global__"),e.getGlobalFacetedUniqueValues=()=>e._getGlobalFacetedUniqueValues?e._getGlobalFacetedUniqueValues():new Map,e._getGlobalFacetedMinMaxValues=e.options.getFacetedMinMaxValues&&e.options.getFacetedMinMaxValues(e,"__global__"),e.getGlobalFacetedMinMaxValues=()=>{if(e._getGlobalFacetedMinMaxValues)return e._getGlobalFacetedMinMaxValues()}}},{getInitialState:e=>({globalFilter:void 0,...e}),getDefaultOptions:e=>({onGlobalFilterChange:n("globalFilter",e),globalFilterFn:"auto",getColumnCanGlobalFilter:t=>{var l;let n=null==(l=e.getCoreRowModel().flatRows[0])||null==(l=l._getAllCellsByColumnId()[t.id])?void 0:l.getValue();return"string"==typeof n||"number"==typeof n}}),createColumn:(e,t)=>{e.getCanGlobalFilter=()=>{var l,n,o,i;return(null==(l=e.columnDef.enableGlobalFilter)||l)&&(null==(n=t.options.enableGlobalFilter)||n)&&(null==(o=t.options.enableFilters)||o)&&(null==(i=null==t.options.getColumnCanGlobalFilter?void 0:t.options.getColumnCanGlobalFilter(e))||i)&&!!e.accessorFn}},createTable:e=>{e.getGlobalAutoFilterFn=()=>C.includesString,e.getGlobalFilterFn=()=>{var t,l;let{globalFilterFn:n}=e.options;return o(n)?n:"auto"===n?e.getGlobalAutoFilterFn():null!=(t=null==(l=e.options.filterFns)?void 0:l[n])?t:C[n]},e.setGlobalFilter=t=>{null==e.options.onGlobalFilterChange||e.options.onGlobalFilterChange(t)},e.resetGlobalFilter=t=>{e.setGlobalFilter(t?void 0:e.initialState.globalFilter)}}},{getInitialState:e=>({sorting:[],...e}),getDefaultColumnDef:()=>({sortingFn:"auto",sortUndefined:1}),getDefaultOptions:e=>({onSortingChange:n("sorting",e),isMultiSortEvent:e=>e.shiftKey}),createColumn:(e,t)=>{e.getAutoSortingFn=()=>{let l=t.getFilteredRowModel().flatRows.slice(10),n=!1;for(let t of l){let l=null==t?void 0:t.getValue(e.id);if("[object Date]"===Object.prototype.toString.call(l))return H.datetime;if("string"==typeof l&&(n=!0,l.split(k).length>1))return H.alphanumeric}return n?H.text:H.basic},e.getAutoSortDir=()=>{let l=t.getFilteredRowModel().flatRows[0];return"string"==typeof(null==l?void 0:l.getValue(e.id))?"asc":"desc"},e.getSortingFn=()=>{var l,n;if(!e)throw Error();return o(e.columnDef.sortingFn)?e.columnDef.sortingFn:"auto"===e.columnDef.sortingFn?e.getAutoSortingFn():null!=(l=null==(n=t.options.sortingFns)?void 0:n[e.columnDef.sortingFn])?l:H[e.columnDef.sortingFn]},e.toggleSorting=(l,n)=>{let o=e.getNextSortingOrder(),i=null!=l;t.setSorting(a=>{let r,s=null==a?void 0:a.find(t=>t.id===e.id),u=null==a?void 0:a.findIndex(t=>t.id===e.id),d=[],g=i?l:"desc"===o;if("toggle"!=(r=null!=a&&a.length&&e.getCanMultiSort()&&n?s?"toggle":"add":null!=a&&a.length&&u!==a.length-1?"replace":s?"toggle":"replace")||i||o||(r="remove"),"add"===r){var c;(d=[...a,{id:e.id,desc:g}]).splice(0,d.length-(null!=(c=t.options.maxMultiSortColCount)?c:Number.MAX_SAFE_INTEGER))}else d="toggle"===r?a.map(t=>t.id===e.id?{...t,desc:g}:t):"remove"===r?a.filter(t=>t.id!==e.id):[{id:e.id,desc:g}];return d})},e.getFirstSortDir=()=>{var l,n;return(null!=(l=null!=(n=e.columnDef.sortDescFirst)?n:t.options.sortDescFirst)?l:"desc"===e.getAutoSortDir())?"desc":"asc"},e.getNextSortingOrder=l=>{var n,o;let i=e.getFirstSortDir(),a=e.getIsSorted();return a?(a===i||null!=(n=t.options.enableSortingRemoval)&&!n||!!l&&null!=(o=t.options.enableMultiRemove)&&!o)&&("desc"===a?"asc":"desc"):i},e.getCanSort=()=>{var l,n;return(null==(l=e.columnDef.enableSorting)||l)&&(null==(n=t.options.enableSorting)||n)&&!!e.accessorFn},e.getCanMultiSort=()=>{var l,n;return null!=(l=null!=(n=e.columnDef.enableMultiSort)?n:t.options.enableMultiSort)?l:!!e.accessorFn},e.getIsSorted=()=>{var l;let n=null==(l=t.getState().sorting)?void 0:l.find(t=>t.id===e.id);return!!n&&(n.desc?"desc":"asc")},e.getSortIndex=()=>{var l,n;return null!=(l=null==(n=t.getState().sorting)?void 0:n.findIndex(t=>t.id===e.id))?l:-1},e.clearSorting=()=>{t.setSorting(t=>null!=t&&t.length?t.filter(t=>t.id!==e.id):[])},e.getToggleSortingHandler=()=>{let l=e.getCanSort();return n=>{l&&(null==n.persist||n.persist(),null==e.toggleSorting||e.toggleSorting(void 0,!!e.getCanMultiSort()&&(null==t.options.isMultiSortEvent?void 0:t.options.isMultiSortEvent(n))))}}},createTable:e=>{e.setSorting=t=>null==e.options.onSortingChange?void 0:e.options.onSortingChange(t),e.resetSorting=t=>{var l,n;e.setSorting(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.sorting)?l:[])},e.getPreSortedRowModel=()=>e.getGroupedRowModel(),e.getSortedRowModel=()=>(!e._getSortedRowModel&&e.options.getSortedRowModel&&(e._getSortedRowModel=e.options.getSortedRowModel(e)),e.options.manualSorting||!e._getSortedRowModel)?e.getPreSortedRowModel():e._getSortedRowModel()}},{getDefaultColumnDef:()=>({aggregatedCell:e=>{var t,l;return null!=(t=null==(l=e.getValue())||null==l.toString?void 0:l.toString())?t:null},aggregationFn:"auto"}),getInitialState:e=>({grouping:[],...e}),getDefaultOptions:e=>({onGroupingChange:n("grouping",e),groupedColumnMode:"reorder"}),createColumn:(e,t)=>{e.toggleGrouping=()=>{t.setGrouping(t=>null!=t&&t.includes(e.id)?t.filter(t=>t!==e.id):[...null!=t?t:[],e.id])},e.getCanGroup=()=>{var l,n;return(null==(l=e.columnDef.enableGrouping)||l)&&(null==(n=t.options.enableGrouping)||n)&&(!!e.accessorFn||!!e.columnDef.getGroupingValue)},e.getIsGrouped=()=>{var l;return null==(l=t.getState().grouping)?void 0:l.includes(e.id)},e.getGroupedIndex=()=>{var l;return null==(l=t.getState().grouping)?void 0:l.indexOf(e.id)},e.getToggleGroupingHandler=()=>{let t=e.getCanGroup();return()=>{t&&e.toggleGrouping()}},e.getAutoAggregationFn=()=>{let l=t.getCoreRowModel().flatRows[0],n=null==l?void 0:l.getValue(e.id);return"number"==typeof n?R.sum:"[object Date]"===Object.prototype.toString.call(n)?R.extent:void 0},e.getAggregationFn=()=>{var l,n;if(!e)throw Error();return o(e.columnDef.aggregationFn)?e.columnDef.aggregationFn:"auto"===e.columnDef.aggregationFn?e.getAutoAggregationFn():null!=(l=null==(n=t.options.aggregationFns)?void 0:n[e.columnDef.aggregationFn])?l:R[e.columnDef.aggregationFn]}},createTable:e=>{e.setGrouping=t=>null==e.options.onGroupingChange?void 0:e.options.onGroupingChange(t),e.resetGrouping=t=>{var l,n;e.setGrouping(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.grouping)?l:[])},e.getPreGroupedRowModel=()=>e.getFilteredRowModel(),e.getGroupedRowModel=()=>(!e._getGroupedRowModel&&e.options.getGroupedRowModel&&(e._getGroupedRowModel=e.options.getGroupedRowModel(e)),e.options.manualGrouping||!e._getGroupedRowModel)?e.getPreGroupedRowModel():e._getGroupedRowModel()},createRow:(e,t)=>{e.getIsGrouped=()=>!!e.groupingColumnId,e.getGroupingValue=l=>{if(e._groupingValuesCache.hasOwnProperty(l))return e._groupingValuesCache[l];let n=t.getColumn(l);return null!=n&&n.columnDef.getGroupingValue?(e._groupingValuesCache[l]=n.columnDef.getGroupingValue(e.original),e._groupingValuesCache[l]):e.getValue(l)},e._groupingValuesCache={}},createCell:(e,t,l,n)=>{e.getIsGrouped=()=>t.getIsGrouped()&&t.id===l.groupingColumnId,e.getIsPlaceholder=()=>!e.getIsGrouped()&&t.getIsGrouped(),e.getIsAggregated=()=>{var t;return!e.getIsGrouped()&&!e.getIsPlaceholder()&&!!(null!=(t=l.subRows)&&t.length)}}},{getInitialState:e=>({expanded:{},...e}),getDefaultOptions:e=>({onExpandedChange:n("expanded",e),paginateExpandedRows:!0}),createTable:e=>{let t=!1,l=!1;e._autoResetExpanded=()=>{var n,o;if(!t)return void e._queue(()=>{t=!0});if(null!=(n=null!=(o=e.options.autoResetAll)?o:e.options.autoResetExpanded)?n:!e.options.manualExpanding){if(l)return;l=!0,e._queue(()=>{e.resetExpanded(),l=!1})}},e.setExpanded=t=>null==e.options.onExpandedChange?void 0:e.options.onExpandedChange(t),e.toggleAllRowsExpanded=t=>{(null!=t?t:!e.getIsAllRowsExpanded())?e.setExpanded(!0):e.setExpanded({})},e.resetExpanded=t=>{var l,n;e.setExpanded(t?{}:null!=(l=null==(n=e.initialState)?void 0:n.expanded)?l:{})},e.getCanSomeRowsExpand=()=>e.getPrePaginationRowModel().flatRows.some(e=>e.getCanExpand()),e.getToggleAllRowsExpandedHandler=()=>t=>{null==t.persist||t.persist(),e.toggleAllRowsExpanded()},e.getIsSomeRowsExpanded=()=>{let t=e.getState().expanded;return!0===t||Object.values(t).some(Boolean)},e.getIsAllRowsExpanded=()=>{let t=e.getState().expanded;return"boolean"==typeof t?!0===t:!(!Object.keys(t).length||e.getRowModel().flatRows.some(e=>!e.getIsExpanded()))},e.getExpandedDepth=()=>{let t=0;return(!0===e.getState().expanded?Object.keys(e.getRowModel().rowsById):Object.keys(e.getState().expanded)).forEach(e=>{let l=e.split(".");t=Math.max(t,l.length)}),t},e.getPreExpandedRowModel=()=>e.getSortedRowModel(),e.getExpandedRowModel=()=>(!e._getExpandedRowModel&&e.options.getExpandedRowModel&&(e._getExpandedRowModel=e.options.getExpandedRowModel(e)),e.options.manualExpanding||!e._getExpandedRowModel)?e.getPreExpandedRowModel():e._getExpandedRowModel()},createRow:(e,t)=>{e.toggleExpanded=l=>{t.setExpanded(n=>{var o;let i=!0===n||!!(null!=n&&n[e.id]),a={};if(!0===n?Object.keys(t.getRowModel().rowsById).forEach(e=>{a[e]=!0}):a=n,l=null!=(o=l)?o:!i,!i&&l)return{...a,[e.id]:!0};if(i&&!l){let{[e.id]:t,...l}=a;return l}return n})},e.getIsExpanded=()=>{var l;let n=t.getState().expanded;return!!(null!=(l=null==t.options.getIsRowExpanded?void 0:t.options.getIsRowExpanded(e))?l:!0===n||(null==n?void 0:n[e.id]))},e.getCanExpand=()=>{var l,n,o;return null!=(l=null==t.options.getRowCanExpand?void 0:t.options.getRowCanExpand(e))?l:(null==(n=t.options.enableExpanding)||n)&&!!(null!=(o=e.subRows)&&o.length)},e.getIsAllParentsExpanded=()=>{let l=!0,n=e;for(;l&&n.parentId;)l=(n=t.getRow(n.parentId,!0)).getIsExpanded();return l},e.getToggleExpandedHandler=()=>{let t=e.getCanExpand();return()=>{t&&e.toggleExpanded()}}}},{getInitialState:e=>({...e,pagination:{...V(),...null==e?void 0:e.pagination}}),getDefaultOptions:e=>({onPaginationChange:n("pagination",e)}),createTable:e=>{let t=!1,n=!1;e._autoResetPageIndex=()=>{var l,o;if(!t)return void e._queue(()=>{t=!0});if(null!=(l=null!=(o=e.options.autoResetAll)?o:e.options.autoResetPageIndex)?l:!e.options.manualPagination){if(n)return;n=!0,e._queue(()=>{e.resetPageIndex(),n=!1})}},e.setPagination=t=>null==e.options.onPaginationChange?void 0:e.options.onPaginationChange(e=>l(t,e)),e.resetPagination=t=>{var l;e.setPagination(t?V():null!=(l=e.initialState.pagination)?l:V())},e.setPageIndex=t=>{e.setPagination(n=>{let o=l(t,n.pageIndex);return o=Math.max(0,Math.min(o,void 0===e.options.pageCount||-1===e.options.pageCount?Number.MAX_SAFE_INTEGER:e.options.pageCount-1)),{...n,pageIndex:o}})},e.resetPageIndex=t=>{var l,n;e.setPageIndex(t?0:null!=(l=null==(n=e.initialState)||null==(n=n.pagination)?void 0:n.pageIndex)?l:0)},e.resetPageSize=t=>{var l,n;e.setPageSize(t?10:null!=(l=null==(n=e.initialState)||null==(n=n.pagination)?void 0:n.pageSize)?l:10)},e.setPageSize=t=>{e.setPagination(e=>{let n=Math.max(1,l(t,e.pageSize)),o=Math.floor(e.pageSize*e.pageIndex/n);return{...e,pageIndex:o,pageSize:n}})},e.setPageCount=t=>e.setPagination(n=>{var o;let i=l(t,null!=(o=e.options.pageCount)?o:-1);return"number"==typeof i&&(i=Math.max(-1,i)),{...n,pageCount:i}}),e.getPageOptions=i(()=>[e.getPageCount()],e=>{let t=[];return e&&e>0&&(t=[...Array(e)].fill(null).map((e,t)=>t)),t},a(e.options,"debugTable","getPageOptions")),e.getCanPreviousPage=()=>e.getState().pagination.pageIndex>0,e.getCanNextPage=()=>{let{pageIndex:t}=e.getState().pagination,l=e.getPageCount();return -1===l||0!==l&&te.setPageIndex(e=>e-1),e.nextPage=()=>e.setPageIndex(e=>e+1),e.firstPage=()=>e.setPageIndex(0),e.lastPage=()=>e.setPageIndex(e.getPageCount()-1),e.getPrePaginationRowModel=()=>e.getExpandedRowModel(),e.getPaginationRowModel=()=>(!e._getPaginationRowModel&&e.options.getPaginationRowModel&&(e._getPaginationRowModel=e.options.getPaginationRowModel(e)),e.options.manualPagination||!e._getPaginationRowModel)?e.getPrePaginationRowModel():e._getPaginationRowModel(),e.getPageCount=()=>{var t;return null!=(t=e.options.pageCount)?t:Math.ceil(e.getRowCount()/e.getState().pagination.pageSize)},e.getRowCount=()=>{var t;return null!=(t=e.options.rowCount)?t:e.getPrePaginationRowModel().rows.length}}},{getInitialState:e=>({rowPinning:_(),...e}),getDefaultOptions:e=>({onRowPinningChange:n("rowPinning",e)}),createRow:(e,t)=>{e.pin=(l,n,o)=>{let i=n?e.getLeafRows().map(e=>{let{id:t}=e;return t}):[],a=new Set([...o?e.getParentRows().map(e=>{let{id:t}=e;return t}):[],e.id,...i]);t.setRowPinning(e=>{var t,n,o,i,r,s;return"bottom"===l?{top:(null!=(o=null==e?void 0:e.top)?o:[]).filter(e=>!(null!=a&&a.has(e))),bottom:[...(null!=(i=null==e?void 0:e.bottom)?i:[]).filter(e=>!(null!=a&&a.has(e))),...Array.from(a)]}:"top"===l?{top:[...(null!=(r=null==e?void 0:e.top)?r:[]).filter(e=>!(null!=a&&a.has(e))),...Array.from(a)],bottom:(null!=(s=null==e?void 0:e.bottom)?s:[]).filter(e=>!(null!=a&&a.has(e)))}:{top:(null!=(t=null==e?void 0:e.top)?t:[]).filter(e=>!(null!=a&&a.has(e))),bottom:(null!=(n=null==e?void 0:e.bottom)?n:[]).filter(e=>!(null!=a&&a.has(e)))}})},e.getCanPin=()=>{var l;let{enableRowPinning:n,enablePinning:o}=t.options;return"function"==typeof n?n(e):null==(l=null!=n?n:o)||l},e.getIsPinned=()=>{let l=[e.id],{top:n,bottom:o}=t.getState().rowPinning,i=l.some(e=>null==n?void 0:n.includes(e)),a=l.some(e=>null==o?void 0:o.includes(e));return i?"top":!!a&&"bottom"},e.getPinnedIndex=()=>{var l,n;let o=e.getIsPinned();if(!o)return -1;let i=null==(l="top"===o?t.getTopRows():t.getBottomRows())?void 0:l.map(e=>{let{id:t}=e;return t});return null!=(n=null==i?void 0:i.indexOf(e.id))?n:-1}},createTable:e=>{e.setRowPinning=t=>null==e.options.onRowPinningChange?void 0:e.options.onRowPinningChange(t),e.resetRowPinning=t=>{var l,n;return e.setRowPinning(t?_():null!=(l=null==(n=e.initialState)?void 0:n.rowPinning)?l:_())},e.getIsSomeRowsPinned=t=>{var l,n,o;let i=e.getState().rowPinning;return t?!!(null==(l=i[t])?void 0:l.length):!!((null==(n=i.top)?void 0:n.length)||(null==(o=i.bottom)?void 0:o.length))},e._getPinnedRows=(t,l,n)=>{var o;return(null==(o=e.options.keepPinnedRows)||o?(null!=l?l:[]).map(t=>{let l=e.getRow(t,!0);return l.getIsAllParentsExpanded()?l:null}):(null!=l?l:[]).map(e=>t.find(t=>t.id===e))).filter(Boolean).map(e=>({...e,position:n}))},e.getTopRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.top],(t,l)=>e._getPinnedRows(t,l,"top"),a(e.options,"debugRows","getTopRows")),e.getBottomRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.bottom],(t,l)=>e._getPinnedRows(t,l,"bottom"),a(e.options,"debugRows","getBottomRows")),e.getCenterRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.top,e.getState().rowPinning.bottom],(e,t,l)=>{let n=new Set([...null!=t?t:[],...null!=l?l:[]]);return e.filter(e=>!n.has(e.id))},a(e.options,"debugRows","getCenterRows"))}},{getInitialState:e=>({rowSelection:{},...e}),getDefaultOptions:e=>({onRowSelectionChange:n("rowSelection",e),enableRowSelection:!0,enableMultiRowSelection:!0,enableSubRowSelection:!0}),createTable:e=>{e.setRowSelection=t=>null==e.options.onRowSelectionChange?void 0:e.options.onRowSelectionChange(t),e.resetRowSelection=t=>{var l;return e.setRowSelection(t?{}:null!=(l=e.initialState.rowSelection)?l:{})},e.toggleAllRowsSelected=t=>{e.setRowSelection(l=>{t=void 0!==t?t:!e.getIsAllRowsSelected();let n={...l},o=e.getPreGroupedRowModel().flatRows;return t?o.forEach(e=>{e.getCanSelect()&&(n[e.id]=!0)}):o.forEach(e=>{delete n[e.id]}),n})},e.toggleAllPageRowsSelected=t=>e.setRowSelection(l=>{let n=void 0!==t?t:!e.getIsAllPageRowsSelected(),o={...l};return e.getRowModel().rows.forEach(t=>{z(o,t.id,n,!0,e)}),o}),e.getPreSelectedRowModel=()=>e.getCoreRowModel(),e.getSelectedRowModel=i(()=>[e.getState().rowSelection,e.getCoreRowModel()],(t,l)=>Object.keys(t).length?N(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getSelectedRowModel")),e.getFilteredSelectedRowModel=i(()=>[e.getState().rowSelection,e.getFilteredRowModel()],(t,l)=>Object.keys(t).length?N(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getFilteredSelectedRowModel")),e.getGroupedSelectedRowModel=i(()=>[e.getState().rowSelection,e.getSortedRowModel()],(t,l)=>Object.keys(t).length?N(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getGroupedSelectedRowModel")),e.getIsAllRowsSelected=()=>{let t=e.getFilteredRowModel().flatRows,{rowSelection:l}=e.getState(),n=!!(t.length&&Object.keys(l).length);return n&&t.some(e=>e.getCanSelect()&&!l[e.id])&&(n=!1),n},e.getIsAllPageRowsSelected=()=>{let t=e.getPaginationRowModel().flatRows.filter(e=>e.getCanSelect()),{rowSelection:l}=e.getState(),n=!!t.length;return n&&t.some(e=>!l[e.id])&&(n=!1),n},e.getIsSomeRowsSelected=()=>{var t;let l=Object.keys(null!=(t=e.getState().rowSelection)?t:{}).length;return l>0&&l{let t=e.getPaginationRowModel().flatRows;return!e.getIsAllPageRowsSelected()&&t.filter(e=>e.getCanSelect()).some(e=>e.getIsSelected()||e.getIsSomeSelected())},e.getToggleAllRowsSelectedHandler=()=>t=>{e.toggleAllRowsSelected(t.target.checked)},e.getToggleAllPageRowsSelectedHandler=()=>t=>{e.toggleAllPageRowsSelected(t.target.checked)}},createRow:(e,t)=>{e.toggleSelected=(l,n)=>{let o=e.getIsSelected();t.setRowSelection(i=>{var a;if(l=void 0!==l?l:!o,e.getCanSelect()&&o===l)return i;let r={...i};return z(r,e.id,l,null==(a=null==n?void 0:n.selectChildren)||a,t),r})},e.getIsSelected=()=>{let{rowSelection:l}=t.getState();return D(e,l)},e.getIsSomeSelected=()=>{let{rowSelection:l}=t.getState();return"some"===E(e,l)},e.getIsAllSubRowsSelected=()=>{let{rowSelection:l}=t.getState();return"all"===E(e,l)},e.getCanSelect=()=>{var l;return"function"==typeof t.options.enableRowSelection?t.options.enableRowSelection(e):null==(l=t.options.enableRowSelection)||l},e.getCanSelectSubRows=()=>{var l;return"function"==typeof t.options.enableSubRowSelection?t.options.enableSubRowSelection(e):null==(l=t.options.enableSubRowSelection)||l},e.getCanMultiSelect=()=>{var l;return"function"==typeof t.options.enableMultiRowSelection?t.options.enableMultiRowSelection(e):null==(l=t.options.enableMultiRowSelection)||l},e.getToggleSelectedHandler=()=>{let t=e.getCanSelect();return l=>{var n;t&&e.toggleSelected(null==(n=l.target)?void 0:n.checked)}}}},{getDefaultColumnDef:()=>y,getInitialState:e=>({columnSizing:{},columnSizingInfo:M(),...e}),getDefaultOptions:e=>({columnResizeMode:"onEnd",columnResizeDirection:"ltr",onColumnSizingChange:n("columnSizing",e),onColumnSizingInfoChange:n("columnSizingInfo",e)}),createColumn:(e,t)=>{e.getSize=()=>{var l,n,o;let i=t.getState().columnSizing[e.id];return Math.min(Math.max(null!=(l=e.columnDef.minSize)?l:y.minSize,null!=(n=null!=i?i:e.columnDef.size)?n:y.size),null!=(o=e.columnDef.maxSize)?o:y.maxSize)},e.getStart=i(e=>[e,I(t,e),t.getState().columnSizing],(t,l)=>l.slice(0,e.getIndex(t)).reduce((e,t)=>e+t.getSize(),0),a(t.options,"debugColumns","getStart")),e.getAfter=i(e=>[e,I(t,e),t.getState().columnSizing],(t,l)=>l.slice(e.getIndex(t)+1).reduce((e,t)=>e+t.getSize(),0),a(t.options,"debugColumns","getAfter")),e.resetSize=()=>{t.setColumnSizing(t=>{let{[e.id]:l,...n}=t;return n})},e.getCanResize=()=>{var l,n;return(null==(l=e.columnDef.enableResizing)||l)&&(null==(n=t.options.enableColumnResizing)||n)},e.getIsResizing=()=>t.getState().columnSizingInfo.isResizingColumn===e.id},createHeader:(e,t)=>{e.getSize=()=>{let t=0,l=e=>{if(e.subHeaders.length)e.subHeaders.forEach(l);else{var n;t+=null!=(n=e.column.getSize())?n:0}};return l(e),t},e.getStart=()=>{if(e.index>0){let t=e.headerGroup.headers[e.index-1];return t.getStart()+t.getSize()}return 0},e.getResizeHandler=l=>{let n=t.getColumn(e.column.id),o=null==n?void 0:n.getCanResize();return i=>{if(!n||!o||(null==i.persist||i.persist(),P(i)&&i.touches&&i.touches.length>1))return;let a=e.getSize(),r=e?e.getLeafHeaders().map(e=>[e.column.id,e.column.getSize()]):[[n.id,n.getSize()]],s=P(i)?Math.round(i.touches[0].clientX):i.clientX,u={},d=(e,l)=>{"number"==typeof l&&(t.setColumnSizingInfo(e=>{var n,o;let i="rtl"===t.options.columnResizeDirection?-1:1,a=(l-(null!=(n=null==e?void 0:e.startOffset)?n:0))*i,r=Math.max(a/(null!=(o=null==e?void 0:e.startSize)?o:0),-.999999);return e.columnSizingStart.forEach(e=>{let[t,l]=e;u[t]=Math.round(100*Math.max(l+l*r,0))/100}),{...e,deltaOffset:a,deltaPercentage:r}}),("onChange"===t.options.columnResizeMode||"end"===e)&&t.setColumnSizing(e=>({...e,...u})))},g=e=>{d("end",e),t.setColumnSizingInfo(e=>({...e,isResizingColumn:!1,startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,columnSizingStart:[]}))},c=l||("u">typeof document?document:null),m={moveHandler:e=>d("move",e.clientX),upHandler:e=>{null==c||c.removeEventListener("mousemove",m.moveHandler),null==c||c.removeEventListener("mouseup",m.upHandler),g(e.clientX)}},p={moveHandler:e=>(e.cancelable&&(e.preventDefault(),e.stopPropagation()),d("move",e.touches[0].clientX),!1),upHandler:e=>{var t;null==c||c.removeEventListener("touchmove",p.moveHandler),null==c||c.removeEventListener("touchend",p.upHandler),e.cancelable&&(e.preventDefault(),e.stopPropagation()),g(null==(t=e.touches[0])?void 0:t.clientX)}},f=!!function(){if("boolean"==typeof j)return j;let e=!1;try{let t=()=>{};window.addEventListener("test",t,{get passive(){return e=!0,!1}}),window.removeEventListener("test",t)}catch(t){e=!1}return j=e}()&&{passive:!1};P(i)?(null==c||c.addEventListener("touchmove",p.moveHandler,f),null==c||c.addEventListener("touchend",p.upHandler,f)):(null==c||c.addEventListener("mousemove",m.moveHandler,f),null==c||c.addEventListener("mouseup",m.upHandler,f)),t.setColumnSizingInfo(e=>({...e,startOffset:s,startSize:a,deltaOffset:0,deltaPercentage:0,columnSizingStart:r,isResizingColumn:n.id}))}}},createTable:e=>{e.setColumnSizing=t=>null==e.options.onColumnSizingChange?void 0:e.options.onColumnSizingChange(t),e.setColumnSizingInfo=t=>null==e.options.onColumnSizingInfoChange?void 0:e.options.onColumnSizingInfoChange(t),e.resetColumnSizing=t=>{var l;e.setColumnSizing(t?{}:null!=(l=e.initialState.columnSizing)?l:{})},e.resetHeaderSizeInfo=t=>{var l;e.setColumnSizingInfo(t?M():null!=(l=e.initialState.columnSizingInfo)?l:M())},e.getTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getLeftTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getLeftHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getCenterTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getCenterHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getRightTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getRightHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0}}}];function O(e){var t,n;let o=[...T,...null!=(t=e._features)?t:[]],r={_features:o},s=r._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultOptions?void 0:t.getDefaultOptions(r)),{}),u={...null!=(n=e.initialState)?n:{}};r._features.forEach(e=>{var t;u=null!=(t=null==e.getInitialState?void 0:e.getInitialState(u))?t:u});let d=[],g=!1,c={_features:o,options:{...s,...e},initialState:u,_queue:e=>{d.push(e),g||(g=!0,Promise.resolve().then(()=>{for(;d.length;)d.shift()();g=!1}).catch(e=>setTimeout(()=>{throw e})))},reset:()=>{r.setState(r.initialState)},setOptions:e=>{var t;t=l(e,r.options),r.options=r.options.mergeOptions?r.options.mergeOptions(s,t):{...s,...t}},getState:()=>r.options.state,setState:e=>{null==r.options.onStateChange||r.options.onStateChange(e)},_getRowId:(e,t,l)=>{var n;return null!=(n=null==r.options.getRowId?void 0:r.options.getRowId(e,t,l))?n:`${l?[l.id,t].join("."):t}`},getCoreRowModel:()=>(r._getCoreRowModel||(r._getCoreRowModel=r.options.getCoreRowModel(r)),r._getCoreRowModel()),getRowModel:()=>r.getPaginationRowModel(),getRow:(e,t)=>{let l=(t?r.getPrePaginationRowModel():r.getRowModel()).rowsById[e];if(!l&&!(l=r.getCoreRowModel().rowsById[e]))throw Error();return l},_getDefaultColumnDef:i(()=>[r.options.defaultColumn],e=>{var t;return e=null!=(t=e)?t:{},{header:e=>{let t=e.header.column.columnDef;return t.accessorKey?t.accessorKey:t.accessorFn?t.id:null},cell:e=>{var t,l;return null!=(t=null==(l=e.renderValue())||null==l.toString?void 0:l.toString())?t:null},...r._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultColumnDef?void 0:t.getDefaultColumnDef()),{}),...e}},a(e,"debugColumns","_getDefaultColumnDef")),_getColumnDefs:()=>r.options.columns,getAllColumns:i(()=>[r._getColumnDefs()],e=>{let t=function(e,l,n){return void 0===n&&(n=0),e.map(e=>{let o=function(e,t,l,n){var o,r;let s,u={...e._getDefaultColumnDef(),...t},d=u.accessorKey,g=null!=(o=null!=(r=u.id)?r:d?"function"==typeof String.prototype.replaceAll?d.replaceAll(".","_"):d.replace(/\./g,"_"):void 0)?o:"string"==typeof u.header?u.header:void 0;if(u.accessorFn?s=u.accessorFn:d&&(s=d.includes(".")?e=>{let t=e;for(let e of d.split(".")){var l;t=null==(l=t)?void 0:l[e]}return t}:e=>e[u.accessorKey]),!g)throw Error();let c={id:`${String(g)}`,accessorFn:s,parent:n,depth:l,columnDef:u,columns:[],getFlatColumns:i(()=>[!0],()=>{var e;return[c,...null==(e=c.columns)?void 0:e.flatMap(e=>e.getFlatColumns())]},a(e.options,"debugColumns","column.getFlatColumns")),getLeafColumns:i(()=>[e._getOrderColumnsFn()],e=>{var t;return null!=(t=c.columns)&&t.length?e(c.columns.flatMap(e=>e.getLeafColumns())):[c]},a(e.options,"debugColumns","column.getLeafColumns"))};for(let t of e._features)null==t.createColumn||t.createColumn(c,e);return c}(r,e,n,l);return o.columns=e.columns?t(e.columns,o,n+1):[],o})};return t(e)},a(e,"debugColumns","getAllColumns")),getAllFlatColumns:i(()=>[r.getAllColumns()],e=>e.flatMap(e=>e.getFlatColumns()),a(e,"debugColumns","getAllFlatColumns")),_getAllFlatColumnsById:i(()=>[r.getAllFlatColumns()],e=>e.reduce((e,t)=>(e[t.id]=t,e),{}),a(e,"debugColumns","getAllFlatColumnsById")),getAllLeafColumns:i(()=>[r.getAllColumns(),r._getOrderColumnsFn()],(e,t)=>t(e.flatMap(e=>e.getLeafColumns())),a(e,"debugColumns","getAllLeafColumns")),getColumn:e=>r._getAllFlatColumnsById()[e]};Object.assign(r,c);for(let e=0;e{var n;t.push(e),null!=(n=e.subRows)&&n.length&&e.getIsExpanded()&&e.subRows.forEach(l)};return e.rows.forEach(l),{rows:t,flatRows:e.flatRows,rowsById:e.rowsById}}e.s(["createTable",0,O,"getCoreRowModel",0,function(){return e=>i(()=>[e.options.data],t=>{let l={rows:[],flatRows:[],rowsById:{}},n=function(t,o,i){void 0===o&&(o=0);let a=[];for(let s=0;se._autoResetPageIndex()))},"getExpandedRowModel",0,function(){return e=>i(()=>[e.getState().expanded,e.getPreExpandedRowModel(),e.options.paginateExpandedRows],(e,t,l)=>t.rows.length&&(!0===e||Object.keys(null!=e?e:{}).length)&&l?B(t):t,a(e.options,"debugTable","getExpandedRowModel"))},"getFilteredRowModel",0,function(){return e=>i(()=>[e.getPreFilteredRowModel(),e.getState().columnFilters,e.getState().globalFilter],(t,l,n)=>{var o,i,a,r,s,u,g,c,m,p;let f,h,v,b,w,C,x,S,R,F;if(!t.rows.length||!(null!=l&&l.length)&&!n){for(let e=0;e{var l;let n=e.getColumn(t.id);if(!n)return;let o=n.getFilterFn();o&&y.push({id:t.id,filterFn:o,resolvedValue:null!=(l=null==o.resolveFilterValue?void 0:o.resolveFilterValue(t.value))?l:t.value})});let j=(null!=l?l:[]).map(e=>e.id),P=e.getGlobalFilterFn(),I=e.getAllLeafColumns().filter(e=>e.getCanGlobalFilter());n&&P&&I.length&&(j.push("__global__"),I.forEach(e=>{var t;M.push({id:e.id,filterFn:P,resolvedValue:null!=(t=null==P.resolveFilterValue?void 0:P.resolveFilterValue(n))?t:n})}));for(let e=0;e{l.columnFiltersMeta[t]=e})}if(M.length){for(let e=0;e{l.columnFiltersMeta[t]=e})){l.columnFilters.__global__=!0;break}}!0!==l.columnFilters.__global__&&(l.columnFilters.__global__=!1)}}return o=t.rows,i=e=>{for(let t=0;te._autoResetPageIndex()))},"getPaginationRowModel",0,function(e){return e=>i(()=>[e.getState().pagination,e.getPrePaginationRowModel(),e.options.paginateExpandedRows?void 0:e.getState().expanded],(t,l)=>{let n;if(!l.rows.length)return l;let{pageSize:o,pageIndex:i}=t,{rows:a,flatRows:r,rowsById:s}=l,u=o*i;a=a.slice(u,u+o),(n=e.options.paginateExpandedRows?{rows:a,flatRows:r,rowsById:s}:B({rows:a,flatRows:r,rowsById:s})).flatRows=[];let d=e=>{n.flatRows.push(e),e.subRows.length&&e.subRows.forEach(d)};return n.rows.forEach(d),n},a(e.options,"debugTable","getPaginationRowModel"))},"getSortedRowModel",0,function(){return e=>i(()=>[e.getState().sorting,e.getPreSortedRowModel()],(t,l)=>{if(!l.rows.length||!(null!=t&&t.length))return l;let n=e.getState().sorting,o=[],i=n.filter(t=>{var l;return null==(l=e.getColumn(t.id))?void 0:l.getCanSort()}),a={};i.forEach(t=>{let l=e.getColumn(t.id);l&&(a[t.id]={sortUndefined:l.columnDef.sortUndefined,invertSorting:l.columnDef.invertSorting,sortingFn:l.getSortingFn()})});let r=e=>{let t=e.map(e=>({...e}));return t.sort((e,t)=>{for(let n=0;n{var t;o.push(e),null!=(t=e.subRows)&&t.length&&(e.subRows=r(e.subRows))}),t};return{rows:r(l.rows),flatRows:o,rowsById:l.rowsById}},a(e.options,"debugTable","getSortedRowModel",()=>e._autoResetPageIndex()))}],682830),e.s(["flexRender",0,function(e,l){var n,o,i;let a;return e?"function"==typeof(o=n=e)&&(a=Object.getPrototypeOf(o)).prototype&&a.prototype.isReactComponent||"function"==typeof n||"object"==typeof(i=n)&&"symbol"==typeof i.$$typeof&&["react.memo","react.forward_ref"].includes(i.$$typeof.description)?t.createElement(e,l):e:null},"useReactTable",0,function(e){let l={state:{},onStateChange:()=>{},renderFallbackValue:null,...e},[n]=t.useState(()=>({current:O(l)})),[o,i]=t.useState(()=>n.current.initialState);return n.current.setOptions(t=>({...t,...e,state:{...o,...e.state},onStateChange:t=>{i(t),null==e.onStateChange||e.onStateChange(t)}})),n.current}],152990)},886407,e=>{"use strict";let t=(0,e.i(475254).default)("search-x",[["path",{d:"m13.5 8.5-5 5",key:"1cs55j"}],["path",{d:"m8.5 8.5 5 5",key:"a8mexj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["path",{d:"m21 21-4.3-4.3",key:"1qie3q"}]]);e.s(["SearchX",0,t],886407)},373375,e=>{"use strict";let t=(0,e.i(475254).default)("chevron-left",[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]]);e.s(["ChevronLeft",0,t],373375)},807235,152370,e=>{"use strict";var t=e.i(843476),l=e.i(152990),n=e.i(682830),o=e.i(886407),i=e.i(271645),a=e.i(302747),r=e.i(784774),s=e.i(196631),u=e.i(373375),d=e.i(463059),g=e.i(475254);let c=(0,g.default)("chevrons-left",[["path",{d:"m11 17-5-5 5-5",key:"13zhaf"}],["path",{d:"m18 17-5-5 5-5",key:"h8a8et"}]]),m=(0,g.default)("chevrons-right",[["path",{d:"m6 17 5-5-5-5",key:"xnjwq"}],["path",{d:"m13 17 5-5-5-5",key:"17xmmf"}]]);var p=e.i(519455),f=e.i(967489);let h=[25,50,100];function v({page:e,pageSize:l,rowCount:n,onPageChange:o,onPageSizeChange:i,pageSizeOptions:a=h,isLoading:r=!1,className:g}){let b=l>0?Math.ceil(n/l):0,w=Math.min((e+1)*l,n),C=e>0&&!r,x=e{"string"==typeof e&&i(Number(e))},children:[(0,t.jsx)(f.SelectTrigger,{size:"sm","data-testid":"pagination-page-size",className:"w-[4.5rem]",children:(0,t.jsx)(f.SelectValue,{})}),(0,t.jsx)(f.SelectContent,{children:a.map(e=>(0,t.jsx)(f.SelectItem,{value:String(e),children:e},e))})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)("span",{"data-testid":"pagination-range",className:"text-sm text-muted-foreground tabular-nums",children:0===n?"No results":`Showing ${0===n?0:e*l+1}-${w} of ${n}`}),(0,t.jsxs)("span",{"data-testid":"pagination-page",className:"text-sm text-muted-foreground tabular-nums",children:["Page ",e+1," of ",Math.max(b,1)]}),(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)(p.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-first","aria-label":"Go to first page",disabled:!C,onClick:()=>o(0),children:(0,t.jsx)(c,{})}),(0,t.jsx)(p.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-prev","aria-label":"Go to previous page",disabled:!C,onClick:()=>o(e-1),children:(0,t.jsx)(u.ChevronLeft,{})}),(0,t.jsx)(p.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-next","aria-label":"Go to next page",disabled:!x,onClick:()=>o(e+1),children:(0,t.jsx)(d.ChevronRight,{})}),(0,t.jsx)(p.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-last","aria-label":"Go to last page",disabled:!x,onClick:()=>o(S),children:(0,t.jsx)(m,{})})]})]})]})}e.s(["DEFAULT_PAGE_SIZE_OPTIONS",0,h,"DataTablePagination",0,v],152370);let b=()=>{},w={outer:"flex max-h-full min-h-0 flex-col",frame:"flex min-h-0 flex-col",body:"min-h-0 [&_[data-slot=table-container]]:overflow-visible",header:"bg-background"},C={outer:"",frame:"",body:"",header:""};function x(e){return"id"in e&&"string"==typeof e.id?e.id:"accessorKey"in e&&null!=e.accessorKey?String(e.accessorKey):void 0}function S(e,t,l){let n=e.getIsPinned(),o=t&&l;if(!n&&!o)return{style:{},className:""};let i="left"===n?e.getStart("left"):void 0,a="right"===n?e.getAfter("right"):void 0;return{style:{position:"sticky",...o?{top:0}:{},...void 0!==i?{left:i}:{},...void 0!==a?{right:a}:{}},className:(0,s.cn)(!1!==n&&t?"z-sticky-pinned":t?"z-sticky":"z-raised",n?"bg-background":"","left"===n?"shadow-[inset_-1px_0_0_var(--color-border)]":"right"===n?"shadow-[inset_1px_0_0_var(--color-border)]":"")}}function R(e,t){if(t||void 0!==e.columnDef.size)return{width:e.getSize()}}function F({header:e,size:n,stickyHeader:o,enableColumnResizing:i}){let{column:a}=e,u=a.columnDef.meta,d=S(a,!0,o),g=i&&a.getCanResize();return(0,t.jsxs)(r.TableHead,{"data-header-id":e.id,className:(0,s.cn)("relative text-muted-foreground","compact"===n?"h-8 px-2 py-1 text-xs":"",u?.numeric?"text-right":"",u?.className,u?.headerClassName,d.className),style:{...d.style,...R(a,i)},children:[e.isPlaceholder?null:(0,t.jsx)("div",{className:(0,s.cn)("flex items-center gap-1",u?.numeric?"justify-end":""),children:(0,l.flexRender)(a.columnDef.header,e.getContext())}),g&&(0,t.jsx)("div",{"data-resizer":!0,"data-header-id":e.id,onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),onDoubleClick:()=>a.resetSize(),className:(0,s.cn)("absolute top-0 right-0 h-full w-1 cursor-col-resize touch-none select-none hover:bg-border",a.getIsResizing()?"bg-primary":"")})]})}function y({cell:e,size:n,stickyHeader:o,enableColumnResizing:i}){let{column:a}=e,u=a.columnDef.meta,d=S(a,!1,o);return(0,t.jsx)(r.TableCell,{className:(0,s.cn)("overflow-hidden text-ellipsis","compact"===n?"px-2 py-1 text-xs":"",u?.numeric?"text-right tabular-nums":"",u?.className,d.className),style:{...d.style,...R(a,i)},children:(0,l.flexRender)(a.columnDef.cell,e.getContext())})}function M({row:e,size:l,stickyHeader:n,enableColumnResizing:o,onRowClick:a,rowClassName:u,renderSubComponent:d}){let g=void 0!==a,c=e.getVisibleCells();return(0,t.jsxs)(i.Fragment,{children:[(0,t.jsx)(r.TableRow,{"data-row-id":e.id,className:(0,s.cn)(g?"cursor-pointer":"","compact"===l?"h-8":"",u?.(e)),onClick:g?t=>{if(void 0===a)return;let l=t.target;null!==l&&t.currentTarget.contains(l)&&null===l.closest("button, a, input, select, textarea, [role=checkbox], [data-row-click-exempt]")&&a(e.original)}:void 0,children:c.map(e=>(0,t.jsx)(y,{cell:e,size:l,stickyHeader:n,enableColumnResizing:o},e.id))}),void 0!==d&&e.getIsExpanded()&&(0,t.jsx)(r.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(r.TableCell,{colSpan:c.length,className:"p-0",children:d({row:e})})})]})}function j({colSpan:e,children:l}){return(0,t.jsx)(r.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(r.TableCell,{colSpan:e,className:"h-24 text-center align-middle text-sm whitespace-normal text-muted-foreground",children:l})})}function P(){return(0,t.jsxs)("div",{className:"flex flex-col items-center gap-1 py-6",children:[(0,t.jsx)("div",{className:"mb-1 flex size-10 items-center justify-center rounded-lg bg-muted",children:(0,t.jsx)(o.SearchX,{className:"size-5 text-muted-foreground"})}),(0,t.jsx)("div",{className:"text-sm font-medium text-foreground",children:"No results"}),(0,t.jsx)("div",{className:"text-sm text-muted-foreground",children:"No rows match your search or filters."})]})}let I=["w-[58%]","w-[44%]","w-[70%]","w-[50%]","w-[64%]","w-[48%]"];function V({column:e,index:l}){let n=e?.columnDef.meta,o=I[l%I.length],i=n?.skeleton;return n?.renderSkeleton!==void 0?(0,t.jsx)(t.Fragment,{children:n.renderSkeleton()}):"twoLine"===i?(0,t.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,t.jsx)(a.Skeleton,{className:(0,s.cn)("h-3.5",o)}),(0,t.jsx)(a.Skeleton,{className:"h-2.5 w-2/5 opacity-65"})]}):"badge"===i?(0,t.jsx)(a.Skeleton,{className:(0,s.cn)("h-5 w-16 rounded-full",n?.numeric?"ml-auto":"")}):"chips"===i?(0,t.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,t.jsx)(a.Skeleton,{className:"h-5 w-14 rounded-full"}),(0,t.jsx)(a.Skeleton,{className:"h-5 w-20 rounded-full"}),(0,t.jsx)(a.Skeleton,{className:"h-5 w-9 rounded-full opacity-65"})]}):"meter"===i?(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsx)(a.Skeleton,{className:"h-3.5 w-24"}),(0,t.jsx)(a.Skeleton,{className:"h-1.5 w-full rounded-full"})]}):(0,t.jsx)(a.Skeleton,{className:(0,s.cn)("h-3.5",o,n?.numeric?"ml-auto":"")})}function _({rowCount:e,columns:l,size:n,message:o}){let a=Array.from({length:Math.max(e,1)},(e,t)=>t),u=l.length>0?l:[void 0];return(0,t.jsx)(i.Fragment,{children:a.map(e=>(0,t.jsx)(r.TableRow,{className:(0,s.cn)("hover:bg-transparent","compact"===n?"h-8":""),"data-testid":"skeleton-row",children:u.map((l,i)=>(0,t.jsxs)(r.TableCell,{className:"compact"===n?"px-2 py-1":"",children:[(0,t.jsx)(V,{column:l,index:i}),0===e&&0===i&&void 0!==o?(0,t.jsx)("span",{className:"sr-only",children:o}):null]},l?.id??i))},`skeleton-${e}`))})}function z(e,t,l){let[n,o]=(0,i.useState)(l);return void 0!==e?{value:e,onChange:t??b}:{value:n,onChange:o}}e.s(["DataTable",0,function(e){let{isLoading:o=!1,loadingMessage:a="Loading…",skeletonRowCount:u=8,noDataMessage:d,paginationMode:g="none",rowCount:c,pageSizeOptions:m=h,enableColumnResizing:p=!1,onRowClick:f,rowClassName:b,renderSubComponent:S,maxBodyHeight:R,fillHeight:y=!1,size:I="default",toolbar:V,paginationSlot:N,footer:D}=e,E=function(e){var t;let{data:o,columns:a,getRowId:r,sortingMode:s="none",sorting:u,onSortingChange:d,defaultSorting:g,enableSortingRemoval:c=!1,paginationMode:m="none",pagination:p,onPaginationChange:f,rowCount:v,pageSizeOptions:b=h,filterMode:w="none",columnFilters:C,onColumnFiltersChange:S,defaultColumnFilters:R,globalFilter:F,onGlobalFilterChange:y,enableColumnResizing:M=!1,columnResizeMode:j="onEnd",defaultColumnVisibility:P,getRowCanExpand:I,renderSubComponent:V,expanded:_,onExpandedChange:N,enableRowSelection:D,rowSelection:E,onRowSelectionChange:k}=e,L=z(u,d,g??[]),A=z(p,f,{pageIndex:0,pageSize:b[0]??25}),G=z(C,S,R??[]),H=z(F,y,""),T=z(_,N,{}),O=z(E,k,{}),[B,q]=(0,i.useState)(P??{}),[$,U]=(0,i.useState)({}),X=i.useMemo(()=>{let e;return{left:(e=e=>a.filter(t=>t.meta?.pinned===e).map(x).filter(e=>void 0!==e))("left"),right:e("right")}},[a]),K={data:o,columns:a,state:{sorting:L.value,pagination:A.value,columnFilters:G.value,globalFilter:H.value,expanded:T.value,rowSelection:O.value,columnVisibility:B,columnSizing:$},initialState:{columnPinning:X},manualSorting:"server"===s,manualPagination:"server"===m,manualFiltering:"server"===w,enableSortingRemoval:c,enableColumnResizing:M,columnResizeMode:j,onSortingChange:L.onChange,onPaginationChange:A.onChange,onColumnFiltersChange:G.onChange,onGlobalFilterChange:H.onChange,onExpandedChange:T.onChange,onRowSelectionChange:O.onChange,onColumnVisibilityChange:q,onColumnSizingChange:U,getCoreRowModel:(0,n.getCoreRowModel)(),...(t=void 0!==V?I:void 0,{..."client"===w?{getFilteredRowModel:(0,n.getFilteredRowModel)()}:{},..."client"===s?{getSortedRowModel:(0,n.getSortedRowModel)()}:{},..."client"===m?{getPaginationRowModel:(0,n.getPaginationRowModel)()}:{},...void 0!==t?{getRowCanExpand:t,getExpandedRowModel:(0,n.getExpandedRowModel)()}:{}}),...void 0!==r?{getRowId:r}:{},...void 0!==D?{enableRowSelection:D}:{},..."server"===m&&void 0!==v?{rowCount:v}:{}};return(0,l.useReactTable)(K)}(e),k=E.getRowModel().rows,L=E.getVisibleLeafColumns().length,A=void 0!==R||y,G=y?w:C,H=p?{width:E.getTotalSize(),minWidth:"100%"}:void 0,T=(()=>{if(void 0!==N)return N(E);if("none"===g)return null;let e=E.getState().pagination,l="server"===g?c??0:E.getPrePaginationRowModel().rows.length;return(0,t.jsx)(v,{page:e.pageIndex,pageSize:e.pageSize,rowCount:l,onPageChange:e=>E.setPageIndex(e),onPageSizeChange:e=>E.setPageSize(e),pageSizeOptions:m,isLoading:o})})();return(0,t.jsx)("div",{className:(0,s.cn)("w-full",G.outer),children:(0,t.jsxs)("div",{className:(0,s.cn)("overflow-hidden rounded-lg border border-border",G.frame),children:[void 0!==V&&(0,t.jsx)("div",{className:"shrink-0 border-b border-border px-4 py-3",children:V(E)}),(0,t.jsx)("div",{className:(0,s.cn)(A?"overflow-auto":"overflow-x-auto",G.body),style:void 0!==R?{maxHeight:R}:void 0,children:(0,t.jsxs)(r.Table,{className:p?"table-fixed":"",style:H,children:[(0,t.jsx)(r.TableHeader,{className:(0,s.cn)(A?"sticky top-0 z-sticky":"",G.header),children:E.getHeaderGroups().map(e=>(0,t.jsx)(r.TableRow,{className:"bg-muted/50",children:e.headers.map(e=>(0,t.jsx)(F,{header:e,size:I,stickyHeader:A,enableColumnResizing:p},e.id))},e.id))}),(0,t.jsx)(r.TableBody,{children:o?(0,t.jsx)(_,{rowCount:u,columns:E.getVisibleLeafColumns(),size:I,message:a}):0===k.length?(0,t.jsx)(j,{colSpan:L,children:d??(0,t.jsx)(P,{})}):k.map(e=>(0,t.jsx)(M,{row:e,size:I,stickyHeader:A,enableColumnResizing:p,onRowClick:f,rowClassName:b,renderSubComponent:S},e.id))}),void 0!==D&&(0,t.jsx)(r.TableFooter,{children:D(E)})]})}),null!==T&&(0,t.jsx)("div",{className:"shrink-0 border-t border-border",children:T})]})})}],807235)},980376,e=>{"use strict";var t=e.i(843476),l=e.i(353753),n=e.i(196631),o=e.i(519455),i=e.i(995926);function a({...e}){return(0,t.jsx)(l.Dialog.Portal,{"data-slot":"sheet-portal",...e})}function r({className:e,...o}){return(0,t.jsx)(l.Dialog.Backdrop,{"data-slot":"sheet-overlay",className:(0,n.cn)("fixed inset-0 z-popup bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",e),...o})}e.s(["Sheet",0,function({...e}){return(0,t.jsx)(l.Dialog.Root,{"data-slot":"sheet",...e})},"SheetContent",0,function({className:e,children:s,side:u="right",showCloseButton:d=!0,...g}){return(0,t.jsxs)(a,{children:[(0,t.jsx)(r,{}),(0,t.jsxs)(l.Dialog.Popup,{"data-slot":"sheet-content","data-side":u,className:(0,n.cn)("fixed z-popup flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",e),...g,children:[s,d&&(0,t.jsxs)(l.Dialog.Close,{"data-slot":"sheet-close",render:(0,t.jsx)(o.Button,{variant:"ghost",className:"absolute top-4 right-4",size:"icon-sm"}),children:[(0,t.jsx)(i.XIcon,{}),(0,t.jsx)("span",{className:"sr-only",children:"Close"})]})]})]})},"SheetDescription",0,function({className:e,...o}){return(0,t.jsx)(l.Dialog.Description,{"data-slot":"sheet-description",className:(0,n.cn)("text-sm text-muted-foreground",e),...o})},"SheetFooter",0,function({className:e,...l}){return(0,t.jsx)("div",{"data-slot":"sheet-footer",className:(0,n.cn)("mt-auto flex flex-col gap-2 p-4",e),...l})},"SheetHeader",0,function({className:e,...l}){return(0,t.jsx)("div",{"data-slot":"sheet-header",className:(0,n.cn)("flex flex-col gap-1.5 p-4",e),...l})},"SheetTitle",0,function({className:e,...o}){return(0,t.jsx)(l.Dialog.Title,{"data-slot":"sheet-title",className:(0,n.cn)("font-medium text-foreground",e),...o})}])},981080,735419,884916,531649,e=>{"use strict";var t=e.i(843476),l=e.i(271645),n=e.i(519455),o=e.i(110204),i=e.i(980376);function a(e){return Object.fromEntries(e.map(e=>[e.id,e.value]))}e.s(["DataTableFilterDrawer",0,function({table:e,open:o,onOpenChange:r,title:s="Filters",description:u,applyLabel:d="Apply Filters",resetLabel:g="Reset",onReset:c,children:m}){let[p,f]=l.useState(()=>a(e.getState().columnFilters)),[h,v]=l.useState(o);return o!==h&&(v(o),o&&f(a(e.getState().columnFilters))),(0,t.jsx)(i.Sheet,{open:o,onOpenChange:r,children:(0,t.jsxs)(i.SheetContent,{side:"right",children:[(0,t.jsxs)(i.SheetHeader,{children:[(0,t.jsx)(i.SheetTitle,{children:s}),void 0!==u&&(0,t.jsx)(i.SheetDescription,{children:u})]}),(0,t.jsx)("div",{className:"flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4","data-testid":"filter-drawer-body",children:m({get:e=>p[e],set:(e,t)=>f(l=>({...l,[e]:t}))})}),(0,t.jsxs)(i.SheetFooter,{className:"flex-row",children:[(0,t.jsx)(n.Button,{variant:"outline",className:"flex-1",onClick:()=>{(f({}),void 0!==c)?c():e.setColumnFilters([])},"data-testid":"filter-drawer-reset",children:g}),(0,t.jsx)(n.Button,{className:"flex-1",onClick:()=>{e.setColumnFilters(Object.entries(p).filter(([,e])=>!(Array.isArray(e)?0===e.length:null==e||""===e)).map(([e,t])=>({id:e,value:t}))),r(!1)},"data-testid":"filter-drawer-apply",children:d})]})]})})},"DataTableFilterField",0,function({label:e,children:l}){return(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsx)(o.Label,{children:e}),l]})}],981080);var r=e.i(257428);function s({table:e}){let l=e.getIsAllPageRowsSelected(),n=e.getIsSomePageRowsSelected();return(0,t.jsx)(r.Checkbox,{"aria-label":"Select all rows","data-testid":"datatable-select-all",checked:l,indeterminate:n&&!l,onCheckedChange:t=>e.toggleAllPageRowsSelected(!!t)})}function u({row:e,label:l}){return(0,t.jsx)(r.Checkbox,{"aria-label":l,"data-testid":`datatable-select-row-${e.id}`,checked:e.getIsSelected(),disabled:!e.getCanSelect(),onCheckedChange:t=>e.toggleSelected(!!t)})}e.s(["createSelectionColumn",0,function(e={}){let{rowAriaLabel:l}=e;return{id:"select",size:44,enableSorting:!1,enableHiding:!1,enableResizing:!1,meta:{title:"Select",className:"w-11",headerClassName:"w-11"},header:({table:e})=>(0,t.jsx)(s,{table:e}),cell:({row:e})=>(0,t.jsx)(u,{row:e,label:l?.(e)??"Select row"})}}],735419);var d=e.i(16715),g=e.i(555436),c=e.i(475254);let m=(0,c.default)("sliders-horizontal",[["line",{x1:"21",x2:"14",y1:"4",y2:"4",key:"obuewd"}],["line",{x1:"10",x2:"3",y1:"4",y2:"4",key:"1q6298"}],["line",{x1:"21",x2:"12",y1:"12",y2:"12",key:"1iu8h1"}],["line",{x1:"8",x2:"3",y1:"12",y2:"12",key:"ntss68"}],["line",{x1:"21",x2:"16",y1:"20",y2:"20",key:"14d8ph"}],["line",{x1:"12",x2:"3",y1:"20",y2:"20",key:"m0wm8r"}],["line",{x1:"14",x2:"14",y1:"2",y2:"6",key:"14e1ph"}],["line",{x1:"8",x2:"8",y1:"10",y2:"14",key:"1i6ji0"}],["line",{x1:"16",x2:"16",y1:"18",y2:"22",key:"1lctlv"}]]);var p=e.i(37727),f=e.i(487486),h=e.i(793479),v=e.i(196631),b=e.i(451512),w=e.i(643531);let C=(0,c.default)("columns-3",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"M15 3v18",key:"14nvp0"}]]);function x({table:e,label:l="View",className:o}){let i=e.getAllLeafColumns().filter(e=>e.getCanHide());return 0===i.length?null:(0,t.jsxs)(b.Menu.Root,{children:[(0,t.jsx)(b.Menu.Trigger,{render:(0,t.jsxs)(n.Button,{variant:"outline",size:"sm",className:o,"data-testid":"view-options-trigger",children:[(0,t.jsx)(C,{}),l]})}),(0,t.jsx)(b.Menu.Portal,{children:(0,t.jsx)(b.Menu.Positioner,{side:"bottom",align:"end",sideOffset:4,className:"isolate z-popup",children:(0,t.jsx)(b.Menu.Popup,{className:"min-w-[12rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:i.map(e=>(0,t.jsxs)(b.Menu.CheckboxItem,{checked:e.getIsVisible(),onCheckedChange:t=>e.toggleVisibility(t),closeOnClick:!1,"data-testid":`view-option-${e.id}`,className:"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-7 capitalize outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground",children:[(0,t.jsx)(b.Menu.CheckboxItemIndicator,{className:"absolute left-2 flex size-4 items-center justify-center",children:(0,t.jsx)(w.Check,{className:"size-3.5"})}),e.columnDef.meta?.title??("string"==typeof e.columnDef.header?e.columnDef.header:e.id)]},e.id))})})})]})}e.s(["DataTableViewOptions",0,x],884916),e.s(["DataTableToolbar",0,function({table:e,searchValue:l,onSearchChange:o,searchPlaceholder:i="Search",onOpenFilters:a,onRefresh:r,isRefreshing:s=!1,filterLabels:u,formatFilterValue:c,showViewOptions:b=!0,children:w,className:C}){let S=e.getState().columnFilters,R=t=>u?.[t]??e.getColumn(t)?.columnDef.meta?.title??t;return(0,t.jsxs)("div",{className:(0,v.cn)("flex flex-wrap items-center justify-between gap-2",C),children:[(0,t.jsxs)("div",{className:"flex flex-1 flex-wrap items-center gap-2",children:[void 0!==o&&(0,t.jsxs)("div",{className:"relative",children:[(0,t.jsx)(g.Search,{className:"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"}),(0,t.jsx)(h.Input,{value:l??"",onChange:e=>o(e.target.value),placeholder:i,className:"h-8 w-56 pl-8","data-testid":"datatable-search"})]}),S.map(l=>{var n,o;return(0,t.jsxs)(f.Badge,{variant:"outline",className:"gap-1 py-1","data-testid":`filter-chip-${l.id}`,children:[(0,t.jsxs)("span",{className:"text-muted-foreground",children:[R(l.id),":"]}),(n=l.id,o=l.value,c?.(n,o)??(Array.isArray(o)?o.join(", "):String(o))),(0,t.jsx)("button",{type:"button","aria-label":`Remove ${R(l.id)} filter`,"data-testid":`filter-chip-remove-${l.id}`,onClick:()=>e.setColumnFilters(e=>e.filter(e=>e.id!==l.id)),className:"ml-0.5 rounded-full text-muted-foreground hover:text-foreground",children:(0,t.jsx)(p.X,{className:"size-3"})})]},l.id)}),S.length>0&&(0,t.jsx)(n.Button,{variant:"ghost",size:"sm",onClick:()=>e.setColumnFilters([]),"data-testid":"datatable-clear-filters",children:"Clear all"})]}),(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[w,void 0!==r&&(0,t.jsx)(n.Button,{variant:"outline",size:"icon-sm",onClick:r,disabled:s,"aria-label":"Refresh",title:"Refresh","data-testid":"datatable-refresh",children:(0,t.jsx)(d.RefreshCw,{className:s?"animate-spin":""})}),b&&(0,t.jsx)(x,{table:e,label:"Columns"}),void 0!==a&&(0,t.jsxs)(n.Button,{variant:"outline",size:"sm",onClick:a,"data-testid":"datatable-filters-trigger",children:[(0,t.jsx)(m,{}),"Filters",S.length>0&&(0,t.jsx)(f.Badge,{className:"ml-1 h-5 min-w-5 justify-center rounded-full px-1","data-testid":"datatable-filter-count",children:S.length})]})]})]})}],531649)},655900,e=>{"use strict";var t=e.i(399219);e.s(["ChevronUp",()=>t.default])},707701,494862,e=>{"use strict";e.i(807235),e.i(981080),e.i(152370),e.i(735419),e.i(531649),e.i(884916);var t=e.i(843476),l=e.i(451512),n=e.i(643531),o=e.i(664659),i=e.i(344523),a=e.i(655900),r=e.i(37727),s=e.i(196631);function u({sorted:e}){return"asc"===e?(0,t.jsx)(a.ChevronUp,{className:"size-3.5","data-sort-indicator":"asc"}):"desc"===e?(0,t.jsx)(o.ChevronDown,{className:"size-3.5","data-sort-indicator":"desc"}):(0,t.jsx)(i.ChevronsUpDown,{className:"size-3.5 text-muted-foreground","data-sort-indicator":"none"})}let d="flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground";e.s(["DataTableMultiSortHeader",0,function({table:e,fields:i,className:g}){let c=e.getState().sorting[0],m=void 0!==c&&i.some(e=>e.id===c.id)?c:void 0,p=m?.desc===!0?"desc":"asc",f=void 0!==m&&p,h=i.flatMap(e=>[{key:`${e.id}-asc`,id:e.id,desc:!1,label:`${e.label} ascending`,Icon:a.ChevronUp},{key:`${e.id}-desc`,id:e.id,desc:!0,label:`${e.label} descending`,Icon:o.ChevronDown}]),v=i.flatMap((e,l)=>{let n=m?.id===e.id,o=(0,t.jsx)("span",{"data-sort-field":e.id,className:n?"font-semibold text-foreground":m?"text-muted-foreground":"",children:e.label},e.id);return 0===l?[o]:[(0,t.jsx)("span",{className:"text-muted-foreground",children:" / "},`sep-${e.id}`),o]});return(0,t.jsxs)("div",{className:(0,s.cn)("flex items-center gap-1",g),children:[(0,t.jsx)("span",{className:"font-medium",children:v}),(0,t.jsxs)(l.Menu.Root,{children:[(0,t.jsx)(l.Menu.Trigger,{render:(0,t.jsx)("button",{type:"button","data-testid":`sort-trigger-${i[0]?.id??"field"}`,"aria-label":`Sort options for ${i.map(e=>e.label).join(" or ")}`,onClick:e=>e.stopPropagation(),className:(0,s.cn)("inline-flex size-6 items-center justify-center rounded-md hover:bg-muted",f?"text-primary":"text-muted-foreground"),children:(0,t.jsx)(u,{sorted:f})})}),(0,t.jsx)(l.Menu.Portal,{children:(0,t.jsx)(l.Menu.Positioner,{side:"bottom",align:"start",sideOffset:4,className:"isolate z-popup",children:(0,t.jsxs)(l.Menu.Popup,{className:"min-w-[9rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:[h.map(o=>{let i=m?.id===o.id&&m.desc===o.desc;return(0,t.jsxs)(l.Menu.Item,{className:(0,s.cn)(d,i?"text-primary":""),onClick:()=>e.setSorting([{id:o.id,desc:o.desc}]),children:[(0,t.jsx)(o.Icon,{className:"size-3.5"})," ",o.label,i&&(0,t.jsx)(n.Check,{className:"ml-auto size-3.5"})]},o.key)}),(0,t.jsxs)(l.Menu.Item,{className:d,onClick:()=>e.setSorting([]),children:[(0,t.jsx)(r.X,{className:"size-3.5"})," Reset"]})]})})})]})]})},"DataTableSortHeader",0,function({column:e,title:n,variant:i="header-cycle",className:g}){let c=e.getIsSorted();return e.getCanSort()?"dropdown-tristate"===i?(0,t.jsxs)("div",{className:(0,s.cn)("flex items-center gap-1",g),children:[(0,t.jsx)("span",{className:"font-medium",children:n}),(0,t.jsxs)(l.Menu.Root,{children:[(0,t.jsx)(l.Menu.Trigger,{render:(0,t.jsx)("button",{type:"button","data-testid":`sort-trigger-${e.id}`,"aria-label":`Sort options for ${e.id}`,onClick:e=>e.stopPropagation(),className:(0,s.cn)("inline-flex size-6 items-center justify-center rounded-md hover:bg-muted",c?"text-primary":"text-muted-foreground"),children:(0,t.jsx)(u,{sorted:c})})}),(0,t.jsx)(l.Menu.Portal,{children:(0,t.jsx)(l.Menu.Positioner,{side:"bottom",align:"start",sideOffset:4,className:"isolate z-popup",children:(0,t.jsxs)(l.Menu.Popup,{className:"min-w-[9rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:[(0,t.jsxs)(l.Menu.Item,{className:d,onClick:()=>e.toggleSorting(!1),children:[(0,t.jsx)(a.ChevronUp,{className:"size-3.5"})," Ascending"]}),(0,t.jsxs)(l.Menu.Item,{className:d,onClick:()=>e.toggleSorting(!0),children:[(0,t.jsx)(o.ChevronDown,{className:"size-3.5"})," Descending"]}),(0,t.jsxs)(l.Menu.Item,{className:d,onClick:()=>e.clearSorting(),children:[(0,t.jsx)(r.X,{className:"size-3.5"})," Reset"]})]})})})]})]}):(0,t.jsxs)("button",{type:"button","data-testid":`sort-header-${e.id}`,onClick:e.getToggleSortingHandler(),className:(0,s.cn)("flex items-center gap-1 font-medium select-none hover:text-foreground",g),children:[(0,t.jsx)("span",{children:n}),(0,t.jsx)(u,{sorted:c})]}):(0,t.jsx)("span",{className:(0,s.cn)("font-medium",g),children:n})}],494862),e.s([],707701)}]);
\ No newline at end of file
+ color: hsl(${Math.max(0,Math.min(120-120*n,120))}deg 100% 31%);`,null==l?void 0:l.key)}return n}}function a(e,t,l,n){return{debug:()=>{var l;return null!=(l=null==e?void 0:e.debugAll)?l:e[t]},key:!1,onChange:n}}e.i(247167);let r="debugHeaders";function s(e,t,l){var n;let o={id:null!=(n=l.id)?n:t.id,column:t,index:l.index,isPlaceholder:!!l.isPlaceholder,placeholderId:l.placeholderId,depth:l.depth,subHeaders:[],colSpan:0,rowSpan:0,headerGroup:null,getLeafHeaders:()=>{let e=[],t=l=>{l.subHeaders&&l.subHeaders.length&&l.subHeaders.map(t),e.push(l)};return t(o),e},getContext:()=>({table:e,header:o,column:t})};return e._features.forEach(t=>{null==t.createHeader||t.createHeader(o,e)}),o}function u(e,t,l,n){var o,i;let a=0,r=function(e,t){void 0===t&&(t=1),a=Math.max(a,t),e.filter(e=>e.getIsVisible()).forEach(e=>{var l;null!=(l=e.columns)&&l.length&&r(e.columns,t+1)},0)};r(e);let u=[],d=(e,t)=>{let o={depth:t,id:[n,`${t}`].filter(Boolean).join("_"),headers:[]},i=[];e.forEach(e=>{let a,r=[...i].reverse()[0],u=e.column.depth===o.depth,d=!1;if(u&&e.column.parent?a=e.column.parent:(a=e.column,d=!0),r&&(null==r?void 0:r.column)===a)r.subHeaders.push(e);else{let o=s(l,a,{id:[n,t,a.id,null==e?void 0:e.id].filter(Boolean).join("_"),isPlaceholder:d,placeholderId:d?`${i.filter(e=>e.column===a).length}`:void 0,depth:t,index:i.length});o.subHeaders.push(e),i.push(o)}o.headers.push(e),e.headerGroup=o}),u.push(o),t>0&&d(i,t-1)};d(t.map((e,t)=>s(l,e,{depth:a,index:t})),a-1),u.reverse();let g=e=>e.filter(e=>e.column.getIsVisible()).map(e=>{let t=0,l=0,n=[0];return e.subHeaders&&e.subHeaders.length?(n=[],g(e.subHeaders).forEach(e=>{let{colSpan:l,rowSpan:o}=e;t+=l,n.push(o)})):t=1,l+=Math.min(...n),e.colSpan=t,e.rowSpan=l,{colSpan:t,rowSpan:l}});return g(null!=(o=null==(i=u[0])?void 0:i.headers)?o:[]),u}let d=(e,t,l,n,o,r,s)=>{let u={id:t,index:n,original:l,depth:o,parentId:s,_valuesCache:{},_uniqueValuesCache:{},getValue:t=>{if(u._valuesCache.hasOwnProperty(t))return u._valuesCache[t];let l=e.getColumn(t);if(null!=l&&l.accessorFn)return u._valuesCache[t]=l.accessorFn(u.original,n),u._valuesCache[t]},getUniqueValues:t=>{if(u._uniqueValuesCache.hasOwnProperty(t))return u._uniqueValuesCache[t];let l=e.getColumn(t);if(null!=l&&l.accessorFn)return l.columnDef.getUniqueValues?u._uniqueValuesCache[t]=l.columnDef.getUniqueValues(u.original,n):u._uniqueValuesCache[t]=[u.getValue(t)],u._uniqueValuesCache[t]},renderValue:t=>{var l;return null!=(l=u.getValue(t))?l:e.options.renderFallbackValue},subRows:null!=r?r:[],getLeafRows:()=>{var e,t;let l,n;return e=u.subRows,t=e=>e.subRows,l=[],(n=e=>{e.forEach(e=>{l.push(e);let o=t(e);null!=o&&o.length&&n(o)})})(e),l},getParentRow:()=>u.parentId?e.getRow(u.parentId,!0):void 0,getParentRows:()=>{let e=[],t=u;for(;;){let l=t.getParentRow();if(!l)break;e.push(l),t=l}return e.reverse()},getAllCells:i(()=>[e.getAllLeafColumns()],t=>t.map(t=>{var l;let n;return l=t.id,n={id:`${u.id}_${t.id}`,row:u,column:t,getValue:()=>u.getValue(l),renderValue:()=>{var t;return null!=(t=n.getValue())?t:e.options.renderFallbackValue},getContext:i(()=>[e,t,u,n],(e,t,l,n)=>({table:e,column:t,row:l,cell:n,getValue:n.getValue,renderValue:n.renderValue}),a(e.options,"debugCells","cell.getContext"))},e._features.forEach(l=>{null==l.createCell||l.createCell(n,t,u,e)},{}),n}),a(e.options,"debugRows","getAllCells")),_getAllCellsByColumnId:i(()=>[u.getAllCells()],e=>e.reduce((e,t)=>(e[t.column.id]=t,e),{}),a(e.options,"debugRows","getAllCellsByColumnId"))};for(let t=0;t{var n,o;let i=null==l||null==(n=l.toString())?void 0:n.toLowerCase();return!!(null==(o=e.getValue(t))||null==(o=o.toString())||null==(o=o.toLowerCase())?void 0:o.includes(i))};g.autoRemove=e=>x(e);let c=(e,t,l)=>{var n;return!!(null==(n=e.getValue(t))||null==(n=n.toString())?void 0:n.includes(l))};c.autoRemove=e=>x(e);let m=(e,t,l)=>{var n;return(null==(n=e.getValue(t))||null==(n=n.toString())?void 0:n.toLowerCase())===(null==l?void 0:l.toLowerCase())};m.autoRemove=e=>x(e);let p=(e,t,l)=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)};p.autoRemove=e=>x(e);let f=(e,t,l)=>!l.some(l=>{var n;return!(null!=(n=e.getValue(t))&&n.includes(l))});f.autoRemove=e=>x(e)||!(null!=e&&e.length);let h=(e,t,l)=>l.some(l=>{var n;return null==(n=e.getValue(t))?void 0:n.includes(l)});h.autoRemove=e=>x(e)||!(null!=e&&e.length);let v=(e,t,l)=>e.getValue(t)===l;v.autoRemove=e=>x(e);let b=(e,t,l)=>e.getValue(t)==l;b.autoRemove=e=>x(e);let w=(e,t,l)=>{let[n,o]=l,i=e.getValue(t);return i>=n&&i<=o};w.resolveFilterValue=e=>{let[t,l]=e,n="number"!=typeof t?parseFloat(t):t,o="number"!=typeof l?parseFloat(l):l,i=null===t||Number.isNaN(n)?-1/0:n,a=null===l||Number.isNaN(o)?1/0:o;if(i>a){let e=i;i=a,a=e}return[i,a]},w.autoRemove=e=>x(e)||x(e[0])&&x(e[1]);let C={includesString:g,includesStringSensitive:c,equalsString:m,arrIncludes:p,arrIncludesAll:f,arrIncludesSome:h,equals:v,weakEquals:b,inNumberRange:w};function x(e){return null==e||""===e}function S(e,t,l){return!!e&&!!e.autoRemove&&e.autoRemove(t,l)||void 0===t||"string"==typeof t&&!t}let R={sum:(e,t,l)=>l.reduce((t,l)=>{let n=l.getValue(e);return t+("number"==typeof n?n:0)},0),min:(e,t,l)=>{let n;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(n>l||void 0===n&&l>=l)&&(n=l)}),n},max:(e,t,l)=>{let n;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(n=l)&&(n=l)}),n},extent:(e,t,l)=>{let n,o;return l.forEach(t=>{let l=t.getValue(e);null!=l&&(void 0===n?l>=l&&(n=o=l):(n>l&&(n=l),o{let l=0,n=0;if(t.forEach(t=>{let o=t.getValue(e);null!=o&&(o*=1)>=o&&(++l,n+=o)}),l)return n/l},median:(e,t)=>{if(!t.length)return;let l=t.map(t=>t.getValue(e));if(!(Array.isArray(l)&&l.every(e=>"number"==typeof e)))return;if(1===l.length)return l[0];let n=Math.floor(l.length/2),o=l.sort((e,t)=>e-t);return l.length%2!=0?o[n]:(o[n-1]+o[n])/2},unique:(e,t)=>Array.from(new Set(t.map(t=>t.getValue(e))).values()),uniqueCount:(e,t)=>new Set(t.map(t=>t.getValue(e))).size,count:(e,t)=>t.length},F=()=>({left:[],right:[]}),y={size:150,minSize:20,maxSize:Number.MAX_SAFE_INTEGER},M=()=>({startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,isResizingColumn:!1,columnSizingStart:[]}),j=null;function P(e){return"touchstart"===e.type}function I(e,t){return t?"center"===t?e.getCenterVisibleLeafColumns():"left"===t?e.getLeftVisibleLeafColumns():e.getRightVisibleLeafColumns():e.getVisibleLeafColumns()}let V=()=>({pageIndex:0,pageSize:10}),_=()=>({top:[],bottom:[]}),z=(e,t,l,n,o)=>{var i;let a=o.getRow(t,!0);l?(a.getCanMultiSelect()||Object.keys(e).forEach(t=>delete e[t]),a.getCanSelect()&&(e[t]=!0)):delete e[t],n&&null!=(i=a.subRows)&&i.length&&a.getCanSelectSubRows()&&a.subRows.forEach(t=>z(e,t.id,l,n,o))};function N(e,t){let l=e.getState().rowSelection,n=[],o={},i=function(e,t){return e.map(e=>{var t;let a=D(e,l);if(a&&(n.push(e),o[e.id]=e),null!=(t=e.subRows)&&t.length&&(e={...e,subRows:i(e.subRows)}),a)return e}).filter(Boolean)};return{rows:i(t.rows),flatRows:n,rowsById:o}}function D(e,t){var l;return null!=(l=t[e.id])&&l}function E(e,t,l){var n;if(!(null!=(n=e.subRows)&&n.length))return!1;let o=!0,i=!1;return e.subRows.forEach(e=>{if((!i||o)&&(e.getCanSelect()&&(D(e,t)?i=!0:o=!1),e.subRows&&e.subRows.length)){let l=E(e,t);"all"===l?i=!0:("some"===l&&(i=!0),o=!1)}}),o?"all":!!i&&"some"}let k=/([0-9]+)/gm;function L(e,t){return e===t?0:e>t?1:-1}function A(e){return"number"==typeof e?isNaN(e)||e===1/0||e===-1/0?"":String(e):"string"==typeof e?e:""}function G(e,t){let l=e.split(k).filter(Boolean),n=t.split(k).filter(Boolean);for(;l.length&&n.length;){let e=l.shift(),t=n.shift(),o=parseInt(e,10),i=parseInt(t,10),a=[o,i].sort();if(isNaN(a[0])){if(e>t)return 1;if(t>e)return -1;continue}if(isNaN(a[1]))return isNaN(o)?-1:1;if(o>i)return 1;if(i>o)return -1}return l.length-n.length}let H={alphanumeric:(e,t,l)=>G(A(e.getValue(l)).toLowerCase(),A(t.getValue(l)).toLowerCase()),alphanumericCaseSensitive:(e,t,l)=>G(A(e.getValue(l)),A(t.getValue(l))),text:(e,t,l)=>L(A(e.getValue(l)).toLowerCase(),A(t.getValue(l)).toLowerCase()),textCaseSensitive:(e,t,l)=>L(A(e.getValue(l)),A(t.getValue(l))),datetime:(e,t,l)=>{let n=e.getValue(l),o=t.getValue(l);return n>o?1:nL(e.getValue(l),t.getValue(l))},T=[{createTable:e=>{e.getHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,l,n,o)=>{var i,a;let r=null!=(i=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?i:[],s=null!=(a=null==o?void 0:o.map(e=>l.find(t=>t.id===e)).filter(Boolean))?a:[];return u(t,[...r,...l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),...s],e)},a(e.options,r,"getHeaderGroups")),e.getCenterHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(t,l,n,o)=>u(t,l=l.filter(e=>!(null!=n&&n.includes(e.id))&&!(null!=o&&o.includes(e.id))),e,"center"),a(e.options,r,"getCenterHeaderGroups")),e.getLeftHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.left],(t,l,n)=>{var o;return u(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"left")},a(e.options,r,"getLeftHeaderGroups")),e.getRightHeaderGroups=i(()=>[e.getAllColumns(),e.getVisibleLeafColumns(),e.getState().columnPinning.right],(t,l,n)=>{var o;return u(t,null!=(o=null==n?void 0:n.map(e=>l.find(t=>t.id===e)).filter(Boolean))?o:[],e,"right")},a(e.options,r,"getRightHeaderGroups")),e.getFooterGroups=i(()=>[e.getHeaderGroups()],e=>[...e].reverse(),a(e.options,r,"getFooterGroups")),e.getLeftFooterGroups=i(()=>[e.getLeftHeaderGroups()],e=>[...e].reverse(),a(e.options,r,"getLeftFooterGroups")),e.getCenterFooterGroups=i(()=>[e.getCenterHeaderGroups()],e=>[...e].reverse(),a(e.options,r,"getCenterFooterGroups")),e.getRightFooterGroups=i(()=>[e.getRightHeaderGroups()],e=>[...e].reverse(),a(e.options,r,"getRightFooterGroups")),e.getFlatHeaders=i(()=>[e.getHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,r,"getFlatHeaders")),e.getLeftFlatHeaders=i(()=>[e.getLeftHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,r,"getLeftFlatHeaders")),e.getCenterFlatHeaders=i(()=>[e.getCenterHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,r,"getCenterFlatHeaders")),e.getRightFlatHeaders=i(()=>[e.getRightHeaderGroups()],e=>e.map(e=>e.headers).flat(),a(e.options,r,"getRightFlatHeaders")),e.getCenterLeafHeaders=i(()=>[e.getCenterFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,r,"getCenterLeafHeaders")),e.getLeftLeafHeaders=i(()=>[e.getLeftFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,r,"getLeftLeafHeaders")),e.getRightLeafHeaders=i(()=>[e.getRightFlatHeaders()],e=>e.filter(e=>{var t;return!(null!=(t=e.subHeaders)&&t.length)}),a(e.options,r,"getRightLeafHeaders")),e.getLeafHeaders=i(()=>[e.getLeftHeaderGroups(),e.getCenterHeaderGroups(),e.getRightHeaderGroups()],(e,t,l)=>{var n,o,i,a,r,s;return[...null!=(n=null==(o=e[0])?void 0:o.headers)?n:[],...null!=(i=null==(a=t[0])?void 0:a.headers)?i:[],...null!=(r=null==(s=l[0])?void 0:s.headers)?r:[]].map(e=>e.getLeafHeaders()).flat()},a(e.options,r,"getLeafHeaders"))}},{getInitialState:e=>({columnVisibility:{},...e}),getDefaultOptions:e=>({onColumnVisibilityChange:n("columnVisibility",e)}),createColumn:(e,t)=>{e.toggleVisibility=l=>{e.getCanHide()&&t.setColumnVisibility(t=>({...t,[e.id]:null!=l?l:!e.getIsVisible()}))},e.getIsVisible=()=>{var l,n;let o=e.columns;return null==(l=o.length?o.some(e=>e.getIsVisible()):null==(n=t.getState().columnVisibility)?void 0:n[e.id])||l},e.getCanHide=()=>{var l,n;return(null==(l=e.columnDef.enableHiding)||l)&&(null==(n=t.options.enableHiding)||n)},e.getToggleVisibilityHandler=()=>t=>{null==e.toggleVisibility||e.toggleVisibility(t.target.checked)}},createRow:(e,t)=>{e._getAllVisibleCells=i(()=>[e.getAllCells(),t.getState().columnVisibility],e=>e.filter(e=>e.column.getIsVisible()),a(t.options,"debugRows","_getAllVisibleCells")),e.getVisibleCells=i(()=>[e.getLeftVisibleCells(),e.getCenterVisibleCells(),e.getRightVisibleCells()],(e,t,l)=>[...e,...t,...l],a(t.options,"debugRows","getVisibleCells"))},createTable:e=>{let t=(t,l)=>i(()=>[l(),l().filter(e=>e.getIsVisible()).map(e=>e.id).join("_")],e=>e.filter(e=>null==e.getIsVisible?void 0:e.getIsVisible()),a(e.options,"debugColumns",t));e.getVisibleFlatColumns=t("getVisibleFlatColumns",()=>e.getAllFlatColumns()),e.getVisibleLeafColumns=t("getVisibleLeafColumns",()=>e.getAllLeafColumns()),e.getLeftVisibleLeafColumns=t("getLeftVisibleLeafColumns",()=>e.getLeftLeafColumns()),e.getRightVisibleLeafColumns=t("getRightVisibleLeafColumns",()=>e.getRightLeafColumns()),e.getCenterVisibleLeafColumns=t("getCenterVisibleLeafColumns",()=>e.getCenterLeafColumns()),e.setColumnVisibility=t=>null==e.options.onColumnVisibilityChange?void 0:e.options.onColumnVisibilityChange(t),e.resetColumnVisibility=t=>{var l;e.setColumnVisibility(t?{}:null!=(l=e.initialState.columnVisibility)?l:{})},e.toggleAllColumnsVisible=t=>{var l;t=null!=(l=t)?l:!e.getIsAllColumnsVisible(),e.setColumnVisibility(e.getAllLeafColumns().reduce((e,l)=>({...e,[l.id]:t||!(null!=l.getCanHide&&l.getCanHide())}),{}))},e.getIsAllColumnsVisible=()=>!e.getAllLeafColumns().some(e=>!(null!=e.getIsVisible&&e.getIsVisible())),e.getIsSomeColumnsVisible=()=>e.getAllLeafColumns().some(e=>null==e.getIsVisible?void 0:e.getIsVisible()),e.getToggleAllColumnsVisibilityHandler=()=>t=>{var l;e.toggleAllColumnsVisible(null==(l=t.target)?void 0:l.checked)}}},{getInitialState:e=>({columnOrder:[],...e}),getDefaultOptions:e=>({onColumnOrderChange:n("columnOrder",e)}),createColumn:(e,t)=>{e.getIndex=i(e=>[I(t,e)],t=>t.findIndex(t=>t.id===e.id),a(t.options,"debugColumns","getIndex")),e.getIsFirstColumn=l=>{var n;return(null==(n=I(t,l)[0])?void 0:n.id)===e.id},e.getIsLastColumn=l=>{var n;let o=I(t,l);return(null==(n=o[o.length-1])?void 0:n.id)===e.id}},createTable:e=>{e.setColumnOrder=t=>null==e.options.onColumnOrderChange?void 0:e.options.onColumnOrderChange(t),e.resetColumnOrder=t=>{var l;e.setColumnOrder(t?[]:null!=(l=e.initialState.columnOrder)?l:[])},e._getOrderColumnsFn=i(()=>[e.getState().columnOrder,e.getState().grouping,e.options.groupedColumnMode],(e,t,l)=>n=>{let o=[];if(null!=e&&e.length){let t=[...e],l=[...n];for(;l.length&&t.length;){let e=t.shift(),n=l.findIndex(t=>t.id===e);n>-1&&o.push(l.splice(n,1)[0])}o=[...o,...l]}else o=n;var i=o;if(!(null!=t&&t.length)||!l)return i;let a=i.filter(e=>!t.includes(e.id));return"remove"===l?a:[...t.map(e=>i.find(t=>t.id===e)).filter(Boolean),...a]},a(e.options,"debugTable","_getOrderColumnsFn"))}},{getInitialState:e=>({columnPinning:F(),...e}),getDefaultOptions:e=>({onColumnPinningChange:n("columnPinning",e)}),createColumn:(e,t)=>{e.pin=l=>{let n=e.getLeafColumns().map(e=>e.id).filter(Boolean);t.setColumnPinning(e=>{var t,o,i,a,r,s;return"right"===l?{left:(null!=(i=null==e?void 0:e.left)?i:[]).filter(e=>!(null!=n&&n.includes(e))),right:[...(null!=(a=null==e?void 0:e.right)?a:[]).filter(e=>!(null!=n&&n.includes(e))),...n]}:"left"===l?{left:[...(null!=(r=null==e?void 0:e.left)?r:[]).filter(e=>!(null!=n&&n.includes(e))),...n],right:(null!=(s=null==e?void 0:e.right)?s:[]).filter(e=>!(null!=n&&n.includes(e)))}:{left:(null!=(t=null==e?void 0:e.left)?t:[]).filter(e=>!(null!=n&&n.includes(e))),right:(null!=(o=null==e?void 0:e.right)?o:[]).filter(e=>!(null!=n&&n.includes(e)))}})},e.getCanPin=()=>e.getLeafColumns().some(e=>{var l,n,o;return(null==(l=e.columnDef.enablePinning)||l)&&(null==(n=null!=(o=t.options.enableColumnPinning)?o:t.options.enablePinning)||n)}),e.getIsPinned=()=>{let l=e.getLeafColumns().map(e=>e.id),{left:n,right:o}=t.getState().columnPinning,i=l.some(e=>null==n?void 0:n.includes(e)),a=l.some(e=>null==o?void 0:o.includes(e));return i?"left":!!a&&"right"},e.getPinnedIndex=()=>{var l,n;let o=e.getIsPinned();return o?null!=(l=null==(n=t.getState().columnPinning)||null==(n=n[o])?void 0:n.indexOf(e.id))?l:-1:0}},createRow:(e,t)=>{e.getCenterVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.left,t.getState().columnPinning.right],(e,t,l)=>{let n=[...null!=t?t:[],...null!=l?l:[]];return e.filter(e=>!n.includes(e.column.id))},a(t.options,"debugRows","getCenterVisibleCells")),e.getLeftVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.left],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.column.id===t)).filter(Boolean).map(e=>({...e,position:"left"})),a(t.options,"debugRows","getLeftVisibleCells")),e.getRightVisibleCells=i(()=>[e._getAllVisibleCells(),t.getState().columnPinning.right],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.column.id===t)).filter(Boolean).map(e=>({...e,position:"right"})),a(t.options,"debugRows","getRightVisibleCells"))},createTable:e=>{e.setColumnPinning=t=>null==e.options.onColumnPinningChange?void 0:e.options.onColumnPinningChange(t),e.resetColumnPinning=t=>{var l,n;return e.setColumnPinning(t?F():null!=(l=null==(n=e.initialState)?void 0:n.columnPinning)?l:F())},e.getIsSomeColumnsPinned=t=>{var l,n,o;let i=e.getState().columnPinning;return t?!!(null==(l=i[t])?void 0:l.length):!!((null==(n=i.left)?void 0:n.length)||(null==(o=i.right)?void 0:o.length))},e.getLeftLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),a(e.options,"debugColumns","getLeftLeafColumns")),e.getRightLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.right],(e,t)=>(null!=t?t:[]).map(t=>e.find(e=>e.id===t)).filter(Boolean),a(e.options,"debugColumns","getRightLeafColumns")),e.getCenterLeafColumns=i(()=>[e.getAllLeafColumns(),e.getState().columnPinning.left,e.getState().columnPinning.right],(e,t,l)=>{let n=[...null!=t?t:[],...null!=l?l:[]];return e.filter(e=>!n.includes(e.id))},a(e.options,"debugColumns","getCenterLeafColumns"))}},{createColumn:(e,t)=>{e._getFacetedRowModel=t.options.getFacetedRowModel&&t.options.getFacetedRowModel(t,e.id),e.getFacetedRowModel=()=>e._getFacetedRowModel?e._getFacetedRowModel():t.getPreFilteredRowModel(),e._getFacetedUniqueValues=t.options.getFacetedUniqueValues&&t.options.getFacetedUniqueValues(t,e.id),e.getFacetedUniqueValues=()=>e._getFacetedUniqueValues?e._getFacetedUniqueValues():new Map,e._getFacetedMinMaxValues=t.options.getFacetedMinMaxValues&&t.options.getFacetedMinMaxValues(t,e.id),e.getFacetedMinMaxValues=()=>{if(e._getFacetedMinMaxValues)return e._getFacetedMinMaxValues()}}},{getDefaultColumnDef:()=>({filterFn:"auto"}),getInitialState:e=>({columnFilters:[],...e}),getDefaultOptions:e=>({onColumnFiltersChange:n("columnFilters",e),filterFromLeafRows:!1,maxLeafRowFilterDepth:100}),createColumn:(e,t)=>{e.getAutoFilterFn=()=>{let l=t.getCoreRowModel().flatRows[0],n=null==l?void 0:l.getValue(e.id);return"string"==typeof n?C.includesString:"number"==typeof n?C.inNumberRange:"boolean"==typeof n||null!==n&&"object"==typeof n?C.equals:Array.isArray(n)?C.arrIncludes:C.weakEquals},e.getFilterFn=()=>{var l,n;return o(e.columnDef.filterFn)?e.columnDef.filterFn:"auto"===e.columnDef.filterFn?e.getAutoFilterFn():null!=(l=null==(n=t.options.filterFns)?void 0:n[e.columnDef.filterFn])?l:C[e.columnDef.filterFn]},e.getCanFilter=()=>{var l,n,o;return(null==(l=e.columnDef.enableColumnFilter)||l)&&(null==(n=t.options.enableColumnFilters)||n)&&(null==(o=t.options.enableFilters)||o)&&!!e.accessorFn},e.getIsFiltered=()=>e.getFilterIndex()>-1,e.getFilterValue=()=>{var l;return null==(l=t.getState().columnFilters)||null==(l=l.find(t=>t.id===e.id))?void 0:l.value},e.getFilterIndex=()=>{var l,n;return null!=(l=null==(n=t.getState().columnFilters)?void 0:n.findIndex(t=>t.id===e.id))?l:-1},e.setFilterValue=n=>{t.setColumnFilters(t=>{var o,i;let a=e.getFilterFn(),r=null==t?void 0:t.find(t=>t.id===e.id),s=l(n,r?r.value:void 0);if(S(a,s,e))return null!=(o=null==t?void 0:t.filter(t=>t.id!==e.id))?o:[];let u={id:e.id,value:s};return r?null!=(i=null==t?void 0:t.map(t=>t.id===e.id?u:t))?i:[]:null!=t&&t.length?[...t,u]:[u]})}},createRow:(e,t)=>{e.columnFilters={},e.columnFiltersMeta={}},createTable:e=>{e.setColumnFilters=t=>{let n=e.getAllLeafColumns();null==e.options.onColumnFiltersChange||e.options.onColumnFiltersChange(e=>{var o;return null==(o=l(t,e))?void 0:o.filter(e=>{let t=n.find(t=>t.id===e.id);return!(t&&S(t.getFilterFn(),e.value,t))&&!0})})},e.resetColumnFilters=t=>{var l,n;e.setColumnFilters(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.columnFilters)?l:[])},e.getPreFilteredRowModel=()=>e.getCoreRowModel(),e.getFilteredRowModel=()=>(!e._getFilteredRowModel&&e.options.getFilteredRowModel&&(e._getFilteredRowModel=e.options.getFilteredRowModel(e)),e.options.manualFiltering||!e._getFilteredRowModel)?e.getPreFilteredRowModel():e._getFilteredRowModel()}},{createTable:e=>{e._getGlobalFacetedRowModel=e.options.getFacetedRowModel&&e.options.getFacetedRowModel(e,"__global__"),e.getGlobalFacetedRowModel=()=>e.options.manualFiltering||!e._getGlobalFacetedRowModel?e.getPreFilteredRowModel():e._getGlobalFacetedRowModel(),e._getGlobalFacetedUniqueValues=e.options.getFacetedUniqueValues&&e.options.getFacetedUniqueValues(e,"__global__"),e.getGlobalFacetedUniqueValues=()=>e._getGlobalFacetedUniqueValues?e._getGlobalFacetedUniqueValues():new Map,e._getGlobalFacetedMinMaxValues=e.options.getFacetedMinMaxValues&&e.options.getFacetedMinMaxValues(e,"__global__"),e.getGlobalFacetedMinMaxValues=()=>{if(e._getGlobalFacetedMinMaxValues)return e._getGlobalFacetedMinMaxValues()}}},{getInitialState:e=>({globalFilter:void 0,...e}),getDefaultOptions:e=>({onGlobalFilterChange:n("globalFilter",e),globalFilterFn:"auto",getColumnCanGlobalFilter:t=>{var l;let n=null==(l=e.getCoreRowModel().flatRows[0])||null==(l=l._getAllCellsByColumnId()[t.id])?void 0:l.getValue();return"string"==typeof n||"number"==typeof n}}),createColumn:(e,t)=>{e.getCanGlobalFilter=()=>{var l,n,o,i;return(null==(l=e.columnDef.enableGlobalFilter)||l)&&(null==(n=t.options.enableGlobalFilter)||n)&&(null==(o=t.options.enableFilters)||o)&&(null==(i=null==t.options.getColumnCanGlobalFilter?void 0:t.options.getColumnCanGlobalFilter(e))||i)&&!!e.accessorFn}},createTable:e=>{e.getGlobalAutoFilterFn=()=>C.includesString,e.getGlobalFilterFn=()=>{var t,l;let{globalFilterFn:n}=e.options;return o(n)?n:"auto"===n?e.getGlobalAutoFilterFn():null!=(t=null==(l=e.options.filterFns)?void 0:l[n])?t:C[n]},e.setGlobalFilter=t=>{null==e.options.onGlobalFilterChange||e.options.onGlobalFilterChange(t)},e.resetGlobalFilter=t=>{e.setGlobalFilter(t?void 0:e.initialState.globalFilter)}}},{getInitialState:e=>({sorting:[],...e}),getDefaultColumnDef:()=>({sortingFn:"auto",sortUndefined:1}),getDefaultOptions:e=>({onSortingChange:n("sorting",e),isMultiSortEvent:e=>e.shiftKey}),createColumn:(e,t)=>{e.getAutoSortingFn=()=>{let l=t.getFilteredRowModel().flatRows.slice(10),n=!1;for(let t of l){let l=null==t?void 0:t.getValue(e.id);if("[object Date]"===Object.prototype.toString.call(l))return H.datetime;if("string"==typeof l&&(n=!0,l.split(k).length>1))return H.alphanumeric}return n?H.text:H.basic},e.getAutoSortDir=()=>{let l=t.getFilteredRowModel().flatRows[0];return"string"==typeof(null==l?void 0:l.getValue(e.id))?"asc":"desc"},e.getSortingFn=()=>{var l,n;if(!e)throw Error();return o(e.columnDef.sortingFn)?e.columnDef.sortingFn:"auto"===e.columnDef.sortingFn?e.getAutoSortingFn():null!=(l=null==(n=t.options.sortingFns)?void 0:n[e.columnDef.sortingFn])?l:H[e.columnDef.sortingFn]},e.toggleSorting=(l,n)=>{let o=e.getNextSortingOrder(),i=null!=l;t.setSorting(a=>{let r,s=null==a?void 0:a.find(t=>t.id===e.id),u=null==a?void 0:a.findIndex(t=>t.id===e.id),d=[],g=i?l:"desc"===o;if("toggle"!=(r=null!=a&&a.length&&e.getCanMultiSort()&&n?s?"toggle":"add":null!=a&&a.length&&u!==a.length-1?"replace":s?"toggle":"replace")||i||o||(r="remove"),"add"===r){var c;(d=[...a,{id:e.id,desc:g}]).splice(0,d.length-(null!=(c=t.options.maxMultiSortColCount)?c:Number.MAX_SAFE_INTEGER))}else d="toggle"===r?a.map(t=>t.id===e.id?{...t,desc:g}:t):"remove"===r?a.filter(t=>t.id!==e.id):[{id:e.id,desc:g}];return d})},e.getFirstSortDir=()=>{var l,n;return(null!=(l=null!=(n=e.columnDef.sortDescFirst)?n:t.options.sortDescFirst)?l:"desc"===e.getAutoSortDir())?"desc":"asc"},e.getNextSortingOrder=l=>{var n,o;let i=e.getFirstSortDir(),a=e.getIsSorted();return a?(a===i||null!=(n=t.options.enableSortingRemoval)&&!n||!!l&&null!=(o=t.options.enableMultiRemove)&&!o)&&("desc"===a?"asc":"desc"):i},e.getCanSort=()=>{var l,n;return(null==(l=e.columnDef.enableSorting)||l)&&(null==(n=t.options.enableSorting)||n)&&!!e.accessorFn},e.getCanMultiSort=()=>{var l,n;return null!=(l=null!=(n=e.columnDef.enableMultiSort)?n:t.options.enableMultiSort)?l:!!e.accessorFn},e.getIsSorted=()=>{var l;let n=null==(l=t.getState().sorting)?void 0:l.find(t=>t.id===e.id);return!!n&&(n.desc?"desc":"asc")},e.getSortIndex=()=>{var l,n;return null!=(l=null==(n=t.getState().sorting)?void 0:n.findIndex(t=>t.id===e.id))?l:-1},e.clearSorting=()=>{t.setSorting(t=>null!=t&&t.length?t.filter(t=>t.id!==e.id):[])},e.getToggleSortingHandler=()=>{let l=e.getCanSort();return n=>{l&&(null==n.persist||n.persist(),null==e.toggleSorting||e.toggleSorting(void 0,!!e.getCanMultiSort()&&(null==t.options.isMultiSortEvent?void 0:t.options.isMultiSortEvent(n))))}}},createTable:e=>{e.setSorting=t=>null==e.options.onSortingChange?void 0:e.options.onSortingChange(t),e.resetSorting=t=>{var l,n;e.setSorting(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.sorting)?l:[])},e.getPreSortedRowModel=()=>e.getGroupedRowModel(),e.getSortedRowModel=()=>(!e._getSortedRowModel&&e.options.getSortedRowModel&&(e._getSortedRowModel=e.options.getSortedRowModel(e)),e.options.manualSorting||!e._getSortedRowModel)?e.getPreSortedRowModel():e._getSortedRowModel()}},{getDefaultColumnDef:()=>({aggregatedCell:e=>{var t,l;return null!=(t=null==(l=e.getValue())||null==l.toString?void 0:l.toString())?t:null},aggregationFn:"auto"}),getInitialState:e=>({grouping:[],...e}),getDefaultOptions:e=>({onGroupingChange:n("grouping",e),groupedColumnMode:"reorder"}),createColumn:(e,t)=>{e.toggleGrouping=()=>{t.setGrouping(t=>null!=t&&t.includes(e.id)?t.filter(t=>t!==e.id):[...null!=t?t:[],e.id])},e.getCanGroup=()=>{var l,n;return(null==(l=e.columnDef.enableGrouping)||l)&&(null==(n=t.options.enableGrouping)||n)&&(!!e.accessorFn||!!e.columnDef.getGroupingValue)},e.getIsGrouped=()=>{var l;return null==(l=t.getState().grouping)?void 0:l.includes(e.id)},e.getGroupedIndex=()=>{var l;return null==(l=t.getState().grouping)?void 0:l.indexOf(e.id)},e.getToggleGroupingHandler=()=>{let t=e.getCanGroup();return()=>{t&&e.toggleGrouping()}},e.getAutoAggregationFn=()=>{let l=t.getCoreRowModel().flatRows[0],n=null==l?void 0:l.getValue(e.id);return"number"==typeof n?R.sum:"[object Date]"===Object.prototype.toString.call(n)?R.extent:void 0},e.getAggregationFn=()=>{var l,n;if(!e)throw Error();return o(e.columnDef.aggregationFn)?e.columnDef.aggregationFn:"auto"===e.columnDef.aggregationFn?e.getAutoAggregationFn():null!=(l=null==(n=t.options.aggregationFns)?void 0:n[e.columnDef.aggregationFn])?l:R[e.columnDef.aggregationFn]}},createTable:e=>{e.setGrouping=t=>null==e.options.onGroupingChange?void 0:e.options.onGroupingChange(t),e.resetGrouping=t=>{var l,n;e.setGrouping(t?[]:null!=(l=null==(n=e.initialState)?void 0:n.grouping)?l:[])},e.getPreGroupedRowModel=()=>e.getFilteredRowModel(),e.getGroupedRowModel=()=>(!e._getGroupedRowModel&&e.options.getGroupedRowModel&&(e._getGroupedRowModel=e.options.getGroupedRowModel(e)),e.options.manualGrouping||!e._getGroupedRowModel)?e.getPreGroupedRowModel():e._getGroupedRowModel()},createRow:(e,t)=>{e.getIsGrouped=()=>!!e.groupingColumnId,e.getGroupingValue=l=>{if(e._groupingValuesCache.hasOwnProperty(l))return e._groupingValuesCache[l];let n=t.getColumn(l);return null!=n&&n.columnDef.getGroupingValue?(e._groupingValuesCache[l]=n.columnDef.getGroupingValue(e.original),e._groupingValuesCache[l]):e.getValue(l)},e._groupingValuesCache={}},createCell:(e,t,l,n)=>{e.getIsGrouped=()=>t.getIsGrouped()&&t.id===l.groupingColumnId,e.getIsPlaceholder=()=>!e.getIsGrouped()&&t.getIsGrouped(),e.getIsAggregated=()=>{var t;return!e.getIsGrouped()&&!e.getIsPlaceholder()&&!!(null!=(t=l.subRows)&&t.length)}}},{getInitialState:e=>({expanded:{},...e}),getDefaultOptions:e=>({onExpandedChange:n("expanded",e),paginateExpandedRows:!0}),createTable:e=>{let t=!1,l=!1;e._autoResetExpanded=()=>{var n,o;if(!t)return void e._queue(()=>{t=!0});if(null!=(n=null!=(o=e.options.autoResetAll)?o:e.options.autoResetExpanded)?n:!e.options.manualExpanding){if(l)return;l=!0,e._queue(()=>{e.resetExpanded(),l=!1})}},e.setExpanded=t=>null==e.options.onExpandedChange?void 0:e.options.onExpandedChange(t),e.toggleAllRowsExpanded=t=>{(null!=t?t:!e.getIsAllRowsExpanded())?e.setExpanded(!0):e.setExpanded({})},e.resetExpanded=t=>{var l,n;e.setExpanded(t?{}:null!=(l=null==(n=e.initialState)?void 0:n.expanded)?l:{})},e.getCanSomeRowsExpand=()=>e.getPrePaginationRowModel().flatRows.some(e=>e.getCanExpand()),e.getToggleAllRowsExpandedHandler=()=>t=>{null==t.persist||t.persist(),e.toggleAllRowsExpanded()},e.getIsSomeRowsExpanded=()=>{let t=e.getState().expanded;return!0===t||Object.values(t).some(Boolean)},e.getIsAllRowsExpanded=()=>{let t=e.getState().expanded;return"boolean"==typeof t?!0===t:!(!Object.keys(t).length||e.getRowModel().flatRows.some(e=>!e.getIsExpanded()))},e.getExpandedDepth=()=>{let t=0;return(!0===e.getState().expanded?Object.keys(e.getRowModel().rowsById):Object.keys(e.getState().expanded)).forEach(e=>{let l=e.split(".");t=Math.max(t,l.length)}),t},e.getPreExpandedRowModel=()=>e.getSortedRowModel(),e.getExpandedRowModel=()=>(!e._getExpandedRowModel&&e.options.getExpandedRowModel&&(e._getExpandedRowModel=e.options.getExpandedRowModel(e)),e.options.manualExpanding||!e._getExpandedRowModel)?e.getPreExpandedRowModel():e._getExpandedRowModel()},createRow:(e,t)=>{e.toggleExpanded=l=>{t.setExpanded(n=>{var o;let i=!0===n||!!(null!=n&&n[e.id]),a={};if(!0===n?Object.keys(t.getRowModel().rowsById).forEach(e=>{a[e]=!0}):a=n,l=null!=(o=l)?o:!i,!i&&l)return{...a,[e.id]:!0};if(i&&!l){let{[e.id]:t,...l}=a;return l}return n})},e.getIsExpanded=()=>{var l;let n=t.getState().expanded;return!!(null!=(l=null==t.options.getIsRowExpanded?void 0:t.options.getIsRowExpanded(e))?l:!0===n||(null==n?void 0:n[e.id]))},e.getCanExpand=()=>{var l,n,o;return null!=(l=null==t.options.getRowCanExpand?void 0:t.options.getRowCanExpand(e))?l:(null==(n=t.options.enableExpanding)||n)&&!!(null!=(o=e.subRows)&&o.length)},e.getIsAllParentsExpanded=()=>{let l=!0,n=e;for(;l&&n.parentId;)l=(n=t.getRow(n.parentId,!0)).getIsExpanded();return l},e.getToggleExpandedHandler=()=>{let t=e.getCanExpand();return()=>{t&&e.toggleExpanded()}}}},{getInitialState:e=>({...e,pagination:{...V(),...null==e?void 0:e.pagination}}),getDefaultOptions:e=>({onPaginationChange:n("pagination",e)}),createTable:e=>{let t=!1,n=!1;e._autoResetPageIndex=()=>{var l,o;if(!t)return void e._queue(()=>{t=!0});if(null!=(l=null!=(o=e.options.autoResetAll)?o:e.options.autoResetPageIndex)?l:!e.options.manualPagination){if(n)return;n=!0,e._queue(()=>{e.resetPageIndex(),n=!1})}},e.setPagination=t=>null==e.options.onPaginationChange?void 0:e.options.onPaginationChange(e=>l(t,e)),e.resetPagination=t=>{var l;e.setPagination(t?V():null!=(l=e.initialState.pagination)?l:V())},e.setPageIndex=t=>{e.setPagination(n=>{let o=l(t,n.pageIndex);return o=Math.max(0,Math.min(o,void 0===e.options.pageCount||-1===e.options.pageCount?Number.MAX_SAFE_INTEGER:e.options.pageCount-1)),{...n,pageIndex:o}})},e.resetPageIndex=t=>{var l,n;e.setPageIndex(t?0:null!=(l=null==(n=e.initialState)||null==(n=n.pagination)?void 0:n.pageIndex)?l:0)},e.resetPageSize=t=>{var l,n;e.setPageSize(t?10:null!=(l=null==(n=e.initialState)||null==(n=n.pagination)?void 0:n.pageSize)?l:10)},e.setPageSize=t=>{e.setPagination(e=>{let n=Math.max(1,l(t,e.pageSize)),o=Math.floor(e.pageSize*e.pageIndex/n);return{...e,pageIndex:o,pageSize:n}})},e.setPageCount=t=>e.setPagination(n=>{var o;let i=l(t,null!=(o=e.options.pageCount)?o:-1);return"number"==typeof i&&(i=Math.max(-1,i)),{...n,pageCount:i}}),e.getPageOptions=i(()=>[e.getPageCount()],e=>{let t=[];return e&&e>0&&(t=[...Array(e)].fill(null).map((e,t)=>t)),t},a(e.options,"debugTable","getPageOptions")),e.getCanPreviousPage=()=>e.getState().pagination.pageIndex>0,e.getCanNextPage=()=>{let{pageIndex:t}=e.getState().pagination,l=e.getPageCount();return -1===l||0!==l&&te.setPageIndex(e=>e-1),e.nextPage=()=>e.setPageIndex(e=>e+1),e.firstPage=()=>e.setPageIndex(0),e.lastPage=()=>e.setPageIndex(e.getPageCount()-1),e.getPrePaginationRowModel=()=>e.getExpandedRowModel(),e.getPaginationRowModel=()=>(!e._getPaginationRowModel&&e.options.getPaginationRowModel&&(e._getPaginationRowModel=e.options.getPaginationRowModel(e)),e.options.manualPagination||!e._getPaginationRowModel)?e.getPrePaginationRowModel():e._getPaginationRowModel(),e.getPageCount=()=>{var t;return null!=(t=e.options.pageCount)?t:Math.ceil(e.getRowCount()/e.getState().pagination.pageSize)},e.getRowCount=()=>{var t;return null!=(t=e.options.rowCount)?t:e.getPrePaginationRowModel().rows.length}}},{getInitialState:e=>({rowPinning:_(),...e}),getDefaultOptions:e=>({onRowPinningChange:n("rowPinning",e)}),createRow:(e,t)=>{e.pin=(l,n,o)=>{let i=n?e.getLeafRows().map(e=>{let{id:t}=e;return t}):[],a=new Set([...o?e.getParentRows().map(e=>{let{id:t}=e;return t}):[],e.id,...i]);t.setRowPinning(e=>{var t,n,o,i,r,s;return"bottom"===l?{top:(null!=(o=null==e?void 0:e.top)?o:[]).filter(e=>!(null!=a&&a.has(e))),bottom:[...(null!=(i=null==e?void 0:e.bottom)?i:[]).filter(e=>!(null!=a&&a.has(e))),...Array.from(a)]}:"top"===l?{top:[...(null!=(r=null==e?void 0:e.top)?r:[]).filter(e=>!(null!=a&&a.has(e))),...Array.from(a)],bottom:(null!=(s=null==e?void 0:e.bottom)?s:[]).filter(e=>!(null!=a&&a.has(e)))}:{top:(null!=(t=null==e?void 0:e.top)?t:[]).filter(e=>!(null!=a&&a.has(e))),bottom:(null!=(n=null==e?void 0:e.bottom)?n:[]).filter(e=>!(null!=a&&a.has(e)))}})},e.getCanPin=()=>{var l;let{enableRowPinning:n,enablePinning:o}=t.options;return"function"==typeof n?n(e):null==(l=null!=n?n:o)||l},e.getIsPinned=()=>{let l=[e.id],{top:n,bottom:o}=t.getState().rowPinning,i=l.some(e=>null==n?void 0:n.includes(e)),a=l.some(e=>null==o?void 0:o.includes(e));return i?"top":!!a&&"bottom"},e.getPinnedIndex=()=>{var l,n;let o=e.getIsPinned();if(!o)return -1;let i=null==(l="top"===o?t.getTopRows():t.getBottomRows())?void 0:l.map(e=>{let{id:t}=e;return t});return null!=(n=null==i?void 0:i.indexOf(e.id))?n:-1}},createTable:e=>{e.setRowPinning=t=>null==e.options.onRowPinningChange?void 0:e.options.onRowPinningChange(t),e.resetRowPinning=t=>{var l,n;return e.setRowPinning(t?_():null!=(l=null==(n=e.initialState)?void 0:n.rowPinning)?l:_())},e.getIsSomeRowsPinned=t=>{var l,n,o;let i=e.getState().rowPinning;return t?!!(null==(l=i[t])?void 0:l.length):!!((null==(n=i.top)?void 0:n.length)||(null==(o=i.bottom)?void 0:o.length))},e._getPinnedRows=(t,l,n)=>{var o;return(null==(o=e.options.keepPinnedRows)||o?(null!=l?l:[]).map(t=>{let l=e.getRow(t,!0);return l.getIsAllParentsExpanded()?l:null}):(null!=l?l:[]).map(e=>t.find(t=>t.id===e))).filter(Boolean).map(e=>({...e,position:n}))},e.getTopRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.top],(t,l)=>e._getPinnedRows(t,l,"top"),a(e.options,"debugRows","getTopRows")),e.getBottomRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.bottom],(t,l)=>e._getPinnedRows(t,l,"bottom"),a(e.options,"debugRows","getBottomRows")),e.getCenterRows=i(()=>[e.getRowModel().rows,e.getState().rowPinning.top,e.getState().rowPinning.bottom],(e,t,l)=>{let n=new Set([...null!=t?t:[],...null!=l?l:[]]);return e.filter(e=>!n.has(e.id))},a(e.options,"debugRows","getCenterRows"))}},{getInitialState:e=>({rowSelection:{},...e}),getDefaultOptions:e=>({onRowSelectionChange:n("rowSelection",e),enableRowSelection:!0,enableMultiRowSelection:!0,enableSubRowSelection:!0}),createTable:e=>{e.setRowSelection=t=>null==e.options.onRowSelectionChange?void 0:e.options.onRowSelectionChange(t),e.resetRowSelection=t=>{var l;return e.setRowSelection(t?{}:null!=(l=e.initialState.rowSelection)?l:{})},e.toggleAllRowsSelected=t=>{e.setRowSelection(l=>{t=void 0!==t?t:!e.getIsAllRowsSelected();let n={...l},o=e.getPreGroupedRowModel().flatRows;return t?o.forEach(e=>{e.getCanSelect()&&(n[e.id]=!0)}):o.forEach(e=>{delete n[e.id]}),n})},e.toggleAllPageRowsSelected=t=>e.setRowSelection(l=>{let n=void 0!==t?t:!e.getIsAllPageRowsSelected(),o={...l};return e.getRowModel().rows.forEach(t=>{z(o,t.id,n,!0,e)}),o}),e.getPreSelectedRowModel=()=>e.getCoreRowModel(),e.getSelectedRowModel=i(()=>[e.getState().rowSelection,e.getCoreRowModel()],(t,l)=>Object.keys(t).length?N(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getSelectedRowModel")),e.getFilteredSelectedRowModel=i(()=>[e.getState().rowSelection,e.getFilteredRowModel()],(t,l)=>Object.keys(t).length?N(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getFilteredSelectedRowModel")),e.getGroupedSelectedRowModel=i(()=>[e.getState().rowSelection,e.getSortedRowModel()],(t,l)=>Object.keys(t).length?N(e,l):{rows:[],flatRows:[],rowsById:{}},a(e.options,"debugTable","getGroupedSelectedRowModel")),e.getIsAllRowsSelected=()=>{let t=e.getFilteredRowModel().flatRows,{rowSelection:l}=e.getState(),n=!!(t.length&&Object.keys(l).length);return n&&t.some(e=>e.getCanSelect()&&!l[e.id])&&(n=!1),n},e.getIsAllPageRowsSelected=()=>{let t=e.getPaginationRowModel().flatRows.filter(e=>e.getCanSelect()),{rowSelection:l}=e.getState(),n=!!t.length;return n&&t.some(e=>!l[e.id])&&(n=!1),n},e.getIsSomeRowsSelected=()=>{var t;let l=Object.keys(null!=(t=e.getState().rowSelection)?t:{}).length;return l>0&&l{let t=e.getPaginationRowModel().flatRows;return!e.getIsAllPageRowsSelected()&&t.filter(e=>e.getCanSelect()).some(e=>e.getIsSelected()||e.getIsSomeSelected())},e.getToggleAllRowsSelectedHandler=()=>t=>{e.toggleAllRowsSelected(t.target.checked)},e.getToggleAllPageRowsSelectedHandler=()=>t=>{e.toggleAllPageRowsSelected(t.target.checked)}},createRow:(e,t)=>{e.toggleSelected=(l,n)=>{let o=e.getIsSelected();t.setRowSelection(i=>{var a;if(l=void 0!==l?l:!o,e.getCanSelect()&&o===l)return i;let r={...i};return z(r,e.id,l,null==(a=null==n?void 0:n.selectChildren)||a,t),r})},e.getIsSelected=()=>{let{rowSelection:l}=t.getState();return D(e,l)},e.getIsSomeSelected=()=>{let{rowSelection:l}=t.getState();return"some"===E(e,l)},e.getIsAllSubRowsSelected=()=>{let{rowSelection:l}=t.getState();return"all"===E(e,l)},e.getCanSelect=()=>{var l;return"function"==typeof t.options.enableRowSelection?t.options.enableRowSelection(e):null==(l=t.options.enableRowSelection)||l},e.getCanSelectSubRows=()=>{var l;return"function"==typeof t.options.enableSubRowSelection?t.options.enableSubRowSelection(e):null==(l=t.options.enableSubRowSelection)||l},e.getCanMultiSelect=()=>{var l;return"function"==typeof t.options.enableMultiRowSelection?t.options.enableMultiRowSelection(e):null==(l=t.options.enableMultiRowSelection)||l},e.getToggleSelectedHandler=()=>{let t=e.getCanSelect();return l=>{var n;t&&e.toggleSelected(null==(n=l.target)?void 0:n.checked)}}}},{getDefaultColumnDef:()=>y,getInitialState:e=>({columnSizing:{},columnSizingInfo:M(),...e}),getDefaultOptions:e=>({columnResizeMode:"onEnd",columnResizeDirection:"ltr",onColumnSizingChange:n("columnSizing",e),onColumnSizingInfoChange:n("columnSizingInfo",e)}),createColumn:(e,t)=>{e.getSize=()=>{var l,n,o;let i=t.getState().columnSizing[e.id];return Math.min(Math.max(null!=(l=e.columnDef.minSize)?l:y.minSize,null!=(n=null!=i?i:e.columnDef.size)?n:y.size),null!=(o=e.columnDef.maxSize)?o:y.maxSize)},e.getStart=i(e=>[e,I(t,e),t.getState().columnSizing],(t,l)=>l.slice(0,e.getIndex(t)).reduce((e,t)=>e+t.getSize(),0),a(t.options,"debugColumns","getStart")),e.getAfter=i(e=>[e,I(t,e),t.getState().columnSizing],(t,l)=>l.slice(e.getIndex(t)+1).reduce((e,t)=>e+t.getSize(),0),a(t.options,"debugColumns","getAfter")),e.resetSize=()=>{t.setColumnSizing(t=>{let{[e.id]:l,...n}=t;return n})},e.getCanResize=()=>{var l,n;return(null==(l=e.columnDef.enableResizing)||l)&&(null==(n=t.options.enableColumnResizing)||n)},e.getIsResizing=()=>t.getState().columnSizingInfo.isResizingColumn===e.id},createHeader:(e,t)=>{e.getSize=()=>{let t=0,l=e=>{if(e.subHeaders.length)e.subHeaders.forEach(l);else{var n;t+=null!=(n=e.column.getSize())?n:0}};return l(e),t},e.getStart=()=>{if(e.index>0){let t=e.headerGroup.headers[e.index-1];return t.getStart()+t.getSize()}return 0},e.getResizeHandler=l=>{let n=t.getColumn(e.column.id),o=null==n?void 0:n.getCanResize();return i=>{if(!n||!o||(null==i.persist||i.persist(),P(i)&&i.touches&&i.touches.length>1))return;let a=e.getSize(),r=e?e.getLeafHeaders().map(e=>[e.column.id,e.column.getSize()]):[[n.id,n.getSize()]],s=P(i)?Math.round(i.touches[0].clientX):i.clientX,u={},d=(e,l)=>{"number"==typeof l&&(t.setColumnSizingInfo(e=>{var n,o;let i="rtl"===t.options.columnResizeDirection?-1:1,a=(l-(null!=(n=null==e?void 0:e.startOffset)?n:0))*i,r=Math.max(a/(null!=(o=null==e?void 0:e.startSize)?o:0),-.999999);return e.columnSizingStart.forEach(e=>{let[t,l]=e;u[t]=Math.round(100*Math.max(l+l*r,0))/100}),{...e,deltaOffset:a,deltaPercentage:r}}),("onChange"===t.options.columnResizeMode||"end"===e)&&t.setColumnSizing(e=>({...e,...u})))},g=e=>{d("end",e),t.setColumnSizingInfo(e=>({...e,isResizingColumn:!1,startOffset:null,startSize:null,deltaOffset:null,deltaPercentage:null,columnSizingStart:[]}))},c=l||("u">typeof document?document:null),m={moveHandler:e=>d("move",e.clientX),upHandler:e=>{null==c||c.removeEventListener("mousemove",m.moveHandler),null==c||c.removeEventListener("mouseup",m.upHandler),g(e.clientX)}},p={moveHandler:e=>(e.cancelable&&(e.preventDefault(),e.stopPropagation()),d("move",e.touches[0].clientX),!1),upHandler:e=>{var t;null==c||c.removeEventListener("touchmove",p.moveHandler),null==c||c.removeEventListener("touchend",p.upHandler),e.cancelable&&(e.preventDefault(),e.stopPropagation()),g(null==(t=e.touches[0])?void 0:t.clientX)}},f=!!function(){if("boolean"==typeof j)return j;let e=!1;try{let t=()=>{};window.addEventListener("test",t,{get passive(){return e=!0,!1}}),window.removeEventListener("test",t)}catch(t){e=!1}return j=e}()&&{passive:!1};P(i)?(null==c||c.addEventListener("touchmove",p.moveHandler,f),null==c||c.addEventListener("touchend",p.upHandler,f)):(null==c||c.addEventListener("mousemove",m.moveHandler,f),null==c||c.addEventListener("mouseup",m.upHandler,f)),t.setColumnSizingInfo(e=>({...e,startOffset:s,startSize:a,deltaOffset:0,deltaPercentage:0,columnSizingStart:r,isResizingColumn:n.id}))}}},createTable:e=>{e.setColumnSizing=t=>null==e.options.onColumnSizingChange?void 0:e.options.onColumnSizingChange(t),e.setColumnSizingInfo=t=>null==e.options.onColumnSizingInfoChange?void 0:e.options.onColumnSizingInfoChange(t),e.resetColumnSizing=t=>{var l;e.setColumnSizing(t?{}:null!=(l=e.initialState.columnSizing)?l:{})},e.resetHeaderSizeInfo=t=>{var l;e.setColumnSizingInfo(t?M():null!=(l=e.initialState.columnSizingInfo)?l:M())},e.getTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getLeftTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getLeftHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getCenterTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getCenterHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0},e.getRightTotalSize=()=>{var t,l;return null!=(t=null==(l=e.getRightHeaderGroups()[0])?void 0:l.headers.reduce((e,t)=>e+t.getSize(),0))?t:0}}}];function O(e){var t,n;let o=[...T,...null!=(t=e._features)?t:[]],r={_features:o},s=r._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultOptions?void 0:t.getDefaultOptions(r)),{}),u={...null!=(n=e.initialState)?n:{}};r._features.forEach(e=>{var t;u=null!=(t=null==e.getInitialState?void 0:e.getInitialState(u))?t:u});let d=[],g=!1,c={_features:o,options:{...s,...e},initialState:u,_queue:e=>{d.push(e),g||(g=!0,Promise.resolve().then(()=>{for(;d.length;)d.shift()();g=!1}).catch(e=>setTimeout(()=>{throw e})))},reset:()=>{r.setState(r.initialState)},setOptions:e=>{var t;t=l(e,r.options),r.options=r.options.mergeOptions?r.options.mergeOptions(s,t):{...s,...t}},getState:()=>r.options.state,setState:e=>{null==r.options.onStateChange||r.options.onStateChange(e)},_getRowId:(e,t,l)=>{var n;return null!=(n=null==r.options.getRowId?void 0:r.options.getRowId(e,t,l))?n:`${l?[l.id,t].join("."):t}`},getCoreRowModel:()=>(r._getCoreRowModel||(r._getCoreRowModel=r.options.getCoreRowModel(r)),r._getCoreRowModel()),getRowModel:()=>r.getPaginationRowModel(),getRow:(e,t)=>{let l=(t?r.getPrePaginationRowModel():r.getRowModel()).rowsById[e];if(!l&&!(l=r.getCoreRowModel().rowsById[e]))throw Error();return l},_getDefaultColumnDef:i(()=>[r.options.defaultColumn],e=>{var t;return e=null!=(t=e)?t:{},{header:e=>{let t=e.header.column.columnDef;return t.accessorKey?t.accessorKey:t.accessorFn?t.id:null},cell:e=>{var t,l;return null!=(t=null==(l=e.renderValue())||null==l.toString?void 0:l.toString())?t:null},...r._features.reduce((e,t)=>Object.assign(e,null==t.getDefaultColumnDef?void 0:t.getDefaultColumnDef()),{}),...e}},a(e,"debugColumns","_getDefaultColumnDef")),_getColumnDefs:()=>r.options.columns,getAllColumns:i(()=>[r._getColumnDefs()],e=>{let t=function(e,l,n){return void 0===n&&(n=0),e.map(e=>{let o=function(e,t,l,n){var o,r;let s,u={...e._getDefaultColumnDef(),...t},d=u.accessorKey,g=null!=(o=null!=(r=u.id)?r:d?"function"==typeof String.prototype.replaceAll?d.replaceAll(".","_"):d.replace(/\./g,"_"):void 0)?o:"string"==typeof u.header?u.header:void 0;if(u.accessorFn?s=u.accessorFn:d&&(s=d.includes(".")?e=>{let t=e;for(let e of d.split(".")){var l;t=null==(l=t)?void 0:l[e]}return t}:e=>e[u.accessorKey]),!g)throw Error();let c={id:`${String(g)}`,accessorFn:s,parent:n,depth:l,columnDef:u,columns:[],getFlatColumns:i(()=>[!0],()=>{var e;return[c,...null==(e=c.columns)?void 0:e.flatMap(e=>e.getFlatColumns())]},a(e.options,"debugColumns","column.getFlatColumns")),getLeafColumns:i(()=>[e._getOrderColumnsFn()],e=>{var t;return null!=(t=c.columns)&&t.length?e(c.columns.flatMap(e=>e.getLeafColumns())):[c]},a(e.options,"debugColumns","column.getLeafColumns"))};for(let t of e._features)null==t.createColumn||t.createColumn(c,e);return c}(r,e,n,l);return o.columns=e.columns?t(e.columns,o,n+1):[],o})};return t(e)},a(e,"debugColumns","getAllColumns")),getAllFlatColumns:i(()=>[r.getAllColumns()],e=>e.flatMap(e=>e.getFlatColumns()),a(e,"debugColumns","getAllFlatColumns")),_getAllFlatColumnsById:i(()=>[r.getAllFlatColumns()],e=>e.reduce((e,t)=>(e[t.id]=t,e),{}),a(e,"debugColumns","getAllFlatColumnsById")),getAllLeafColumns:i(()=>[r.getAllColumns(),r._getOrderColumnsFn()],(e,t)=>t(e.flatMap(e=>e.getLeafColumns())),a(e,"debugColumns","getAllLeafColumns")),getColumn:e=>r._getAllFlatColumnsById()[e]};Object.assign(r,c);for(let e=0;e{var n;t.push(e),null!=(n=e.subRows)&&n.length&&e.getIsExpanded()&&e.subRows.forEach(l)};return e.rows.forEach(l),{rows:t,flatRows:e.flatRows,rowsById:e.rowsById}}e.s(["createTable",0,O,"functionalUpdate",0,l,"getCoreRowModel",0,function(){return e=>i(()=>[e.options.data],t=>{let l={rows:[],flatRows:[],rowsById:{}},n=function(t,o,i){void 0===o&&(o=0);let a=[];for(let s=0;se._autoResetPageIndex()))},"getExpandedRowModel",0,function(){return e=>i(()=>[e.getState().expanded,e.getPreExpandedRowModel(),e.options.paginateExpandedRows],(e,t,l)=>t.rows.length&&(!0===e||Object.keys(null!=e?e:{}).length)&&l?B(t):t,a(e.options,"debugTable","getExpandedRowModel"))},"getFilteredRowModel",0,function(){return e=>i(()=>[e.getPreFilteredRowModel(),e.getState().columnFilters,e.getState().globalFilter],(t,l,n)=>{var o,i,a,r,s,u,g,c,m,p;let f,h,v,b,w,C,x,S,R,F;if(!t.rows.length||!(null!=l&&l.length)&&!n){for(let e=0;e{var l;let n=e.getColumn(t.id);if(!n)return;let o=n.getFilterFn();o&&y.push({id:t.id,filterFn:o,resolvedValue:null!=(l=null==o.resolveFilterValue?void 0:o.resolveFilterValue(t.value))?l:t.value})});let j=(null!=l?l:[]).map(e=>e.id),P=e.getGlobalFilterFn(),I=e.getAllLeafColumns().filter(e=>e.getCanGlobalFilter());n&&P&&I.length&&(j.push("__global__"),I.forEach(e=>{var t;M.push({id:e.id,filterFn:P,resolvedValue:null!=(t=null==P.resolveFilterValue?void 0:P.resolveFilterValue(n))?t:n})}));for(let e=0;e{l.columnFiltersMeta[t]=e})}if(M.length){for(let e=0;e{l.columnFiltersMeta[t]=e})){l.columnFilters.__global__=!0;break}}!0!==l.columnFilters.__global__&&(l.columnFilters.__global__=!1)}}return o=t.rows,i=e=>{for(let t=0;te._autoResetPageIndex()))},"getPaginationRowModel",0,function(e){return e=>i(()=>[e.getState().pagination,e.getPrePaginationRowModel(),e.options.paginateExpandedRows?void 0:e.getState().expanded],(t,l)=>{let n;if(!l.rows.length)return l;let{pageSize:o,pageIndex:i}=t,{rows:a,flatRows:r,rowsById:s}=l,u=o*i;a=a.slice(u,u+o),(n=e.options.paginateExpandedRows?{rows:a,flatRows:r,rowsById:s}:B({rows:a,flatRows:r,rowsById:s})).flatRows=[];let d=e=>{n.flatRows.push(e),e.subRows.length&&e.subRows.forEach(d)};return n.rows.forEach(d),n},a(e.options,"debugTable","getPaginationRowModel"))},"getSortedRowModel",0,function(){return e=>i(()=>[e.getState().sorting,e.getPreSortedRowModel()],(t,l)=>{if(!l.rows.length||!(null!=t&&t.length))return l;let n=e.getState().sorting,o=[],i=n.filter(t=>{var l;return null==(l=e.getColumn(t.id))?void 0:l.getCanSort()}),a={};i.forEach(t=>{let l=e.getColumn(t.id);l&&(a[t.id]={sortUndefined:l.columnDef.sortUndefined,invertSorting:l.columnDef.invertSorting,sortingFn:l.getSortingFn()})});let r=e=>{let t=e.map(e=>({...e}));return t.sort((e,t)=>{for(let n=0;n{var t;o.push(e),null!=(t=e.subRows)&&t.length&&(e.subRows=r(e.subRows))}),t};return{rows:r(l.rows),flatRows:o,rowsById:l.rowsById}},a(e.options,"debugTable","getSortedRowModel",()=>e._autoResetPageIndex()))}],682830),e.s(["flexRender",0,function(e,l){var n,o,i;let a;return e?"function"==typeof(o=n=e)&&(a=Object.getPrototypeOf(o)).prototype&&a.prototype.isReactComponent||"function"==typeof n||"object"==typeof(i=n)&&"symbol"==typeof i.$$typeof&&["react.memo","react.forward_ref"].includes(i.$$typeof.description)?t.createElement(e,l):e:null},"useReactTable",0,function(e){let l={state:{},onStateChange:()=>{},renderFallbackValue:null,...e},[n]=t.useState(()=>({current:O(l)})),[o,i]=t.useState(()=>n.current.initialState);return n.current.setOptions(t=>({...t,...e,state:{...o,...e.state},onStateChange:t=>{i(t),null==e.onStateChange||e.onStateChange(t)}})),n.current}],152990)},886407,e=>{"use strict";let t=(0,e.i(475254).default)("search-x",[["path",{d:"m13.5 8.5-5 5",key:"1cs55j"}],["path",{d:"m8.5 8.5 5 5",key:"a8mexj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["path",{d:"m21 21-4.3-4.3",key:"1qie3q"}]]);e.s(["SearchX",0,t],886407)},373375,e=>{"use strict";let t=(0,e.i(475254).default)("chevron-left",[["path",{d:"m15 18-6-6 6-6",key:"1wnfg3"}]]);e.s(["ChevronLeft",0,t],373375)},807235,152370,e=>{"use strict";var t=e.i(843476),l=e.i(152990),n=e.i(682830),o=e.i(886407),i=e.i(271645),a=e.i(302747),r=e.i(784774),s=e.i(196631),u=e.i(373375),d=e.i(463059),g=e.i(475254);let c=(0,g.default)("chevrons-left",[["path",{d:"m11 17-5-5 5-5",key:"13zhaf"}],["path",{d:"m18 17-5-5 5-5",key:"h8a8et"}]]),m=(0,g.default)("chevrons-right",[["path",{d:"m6 17 5-5-5-5",key:"xnjwq"}],["path",{d:"m13 17 5-5-5-5",key:"17xmmf"}]]);var p=e.i(519455),f=e.i(967489);let h=[25,50,100];function v({page:e,pageSize:l,rowCount:n,onPageChange:o,onPageSizeChange:i,pageSizeOptions:a=h,isLoading:r=!1,className:g}){let b=l>0?Math.ceil(n/l):0,w=Math.min((e+1)*l,n),C=e>0&&!r,x=e{"string"==typeof e&&i(Number(e))},children:[(0,t.jsx)(f.SelectTrigger,{size:"sm","data-testid":"pagination-page-size",className:"w-[4.5rem]",children:(0,t.jsx)(f.SelectValue,{})}),(0,t.jsx)(f.SelectContent,{children:a.map(e=>(0,t.jsx)(f.SelectItem,{value:String(e),children:e},e))})]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-4",children:[(0,t.jsx)("span",{"data-testid":"pagination-range",className:"text-sm text-muted-foreground tabular-nums",children:0===n?"No results":`Showing ${0===n?0:e*l+1}-${w} of ${n}`}),(0,t.jsxs)("span",{"data-testid":"pagination-page",className:"text-sm text-muted-foreground tabular-nums",children:["Page ",e+1," of ",Math.max(b,1)]}),(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)(p.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-first","aria-label":"Go to first page",disabled:!C,onClick:()=>o(0),children:(0,t.jsx)(c,{})}),(0,t.jsx)(p.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-prev","aria-label":"Go to previous page",disabled:!C,onClick:()=>o(e-1),children:(0,t.jsx)(u.ChevronLeft,{})}),(0,t.jsx)(p.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-next","aria-label":"Go to next page",disabled:!x,onClick:()=>o(e+1),children:(0,t.jsx)(d.ChevronRight,{})}),(0,t.jsx)(p.Button,{variant:"outline",size:"icon-sm","data-testid":"pagination-last","aria-label":"Go to last page",disabled:!x,onClick:()=>o(S),children:(0,t.jsx)(m,{})})]})]})]})}e.s(["DEFAULT_PAGE_SIZE_OPTIONS",0,h,"DataTablePagination",0,v],152370);let b=()=>{},w={outer:"flex max-h-full min-h-0 flex-col",frame:"flex min-h-0 flex-col",body:"min-h-0"},C={outer:"",frame:"",body:""},x={body:"[&_[data-slot=table-container]]:overflow-visible",header:"bg-background"},S={body:"",header:""};function R(e){return"id"in e&&"string"==typeof e.id?e.id:"accessorKey"in e&&null!=e.accessorKey?String(e.accessorKey):void 0}function F(e,t,l){let n=e.getIsPinned(),o=t&&l;if(!n&&!o)return{style:{},className:""};let i="left"===n?e.getStart("left"):void 0,a="right"===n?e.getAfter("right"):void 0;return{style:{position:"sticky",...o?{top:0}:{},...void 0!==i?{left:i}:{},...void 0!==a?{right:a}:{}},className:(0,s.cn)(!1!==n&&t?"z-sticky-pinned":t?"z-sticky":"z-raised",n?"bg-background":"","left"===n?"shadow-[inset_-1px_0_0_var(--color-border)]":"right"===n?"shadow-[inset_1px_0_0_var(--color-border)]":"")}}function y(e,t){if(t||void 0!==e.columnDef.size)return{width:e.getSize()}}function M({header:e,size:n,stickyHeader:o,enableColumnResizing:i}){let{column:a}=e,u=a.columnDef.meta,d=F(a,!0,o),g=i&&a.getCanResize();return(0,t.jsxs)(r.TableHead,{"data-header-id":e.id,className:(0,s.cn)("relative text-muted-foreground","compact"===n?"h-8 px-2 py-1 text-xs":"",u?.numeric?"text-right":"",u?.className,u?.headerClassName,d.className),style:{...d.style,...y(a,i)},children:[e.isPlaceholder?null:(0,t.jsx)("div",{className:(0,s.cn)("flex items-center gap-1",u?.numeric?"justify-end":""),children:(0,l.flexRender)(a.columnDef.header,e.getContext())}),g&&(0,t.jsx)("div",{"data-testid":`column-resizer-${e.id}`,onMouseDown:e.getResizeHandler(),onTouchStart:e.getResizeHandler(),onDoubleClick:()=>a.resetSize(),className:(0,s.cn)("absolute top-0 right-0 h-full w-1 cursor-col-resize touch-none select-none hover:bg-border",a.getIsResizing()?"bg-primary":"")})]})}function j({cell:e,size:n,stickyHeader:o,enableColumnResizing:i}){let{column:a}=e,u=a.columnDef.meta,d=F(a,!1,o);return(0,t.jsx)(r.TableCell,{className:(0,s.cn)("overflow-hidden text-ellipsis","compact"===n?"px-2 py-1 text-xs":"",u?.numeric?"text-right tabular-nums":"",u?.className,d.className),style:{...d.style,...y(a,i)},children:(0,l.flexRender)(a.columnDef.cell,e.getContext())})}function P({row:e,size:l,stickyHeader:n,enableColumnResizing:o,onRowClick:a,rowClassName:u,renderSubComponent:d}){let g=void 0!==a,c=e.getVisibleCells();return(0,t.jsxs)(i.Fragment,{children:[(0,t.jsx)(r.TableRow,{"data-row-id":e.id,className:(0,s.cn)(g?"cursor-pointer":"","compact"===l?"h-8":"",u?.(e)),onClick:g?t=>{if(void 0===a)return;let l=t.target;null!==l&&t.currentTarget.contains(l)&&null===l.closest("button, a, input, select, textarea, [role=checkbox], [data-row-click-exempt]")&&a(e.original)}:void 0,children:c.map(e=>(0,t.jsx)(j,{cell:e,size:l,stickyHeader:n,enableColumnResizing:o},e.id))}),void 0!==d&&e.getIsExpanded()&&(0,t.jsx)(r.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(r.TableCell,{colSpan:c.length,className:"p-0",children:d({row:e})})})]})}function I({colSpan:e,children:l}){return(0,t.jsx)(r.TableRow,{className:"hover:bg-transparent",children:(0,t.jsx)(r.TableCell,{colSpan:e,className:"h-24 text-center align-middle text-sm whitespace-normal text-muted-foreground",children:l})})}function V(){return(0,t.jsxs)("div",{className:"flex flex-col items-center gap-1 py-6",children:[(0,t.jsx)("div",{className:"mb-1 flex size-10 items-center justify-center rounded-lg bg-muted",children:(0,t.jsx)(o.SearchX,{className:"size-5 text-muted-foreground"})}),(0,t.jsx)("div",{className:"text-sm font-medium text-foreground",children:"No results"}),(0,t.jsx)("div",{className:"text-sm text-muted-foreground",children:"No rows match your search or filters."})]})}let _=["w-[58%]","w-[44%]","w-[70%]","w-[50%]","w-[64%]","w-[48%]"];function z({column:e,index:l}){let n=e?.columnDef.meta,o=_[l%_.length],i=n?.skeleton;return n?.renderSkeleton!==void 0?(0,t.jsx)(t.Fragment,{children:n.renderSkeleton()}):"twoLine"===i?(0,t.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,t.jsx)(a.Skeleton,{className:(0,s.cn)("h-3.5",o)}),(0,t.jsx)(a.Skeleton,{className:"h-2.5 w-2/5 opacity-65"})]}):"badge"===i?(0,t.jsx)(a.Skeleton,{className:(0,s.cn)("h-5 w-16 rounded-full",n?.numeric?"ml-auto":"")}):"chips"===i?(0,t.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,t.jsx)(a.Skeleton,{className:"h-5 w-14 rounded-full"}),(0,t.jsx)(a.Skeleton,{className:"h-5 w-20 rounded-full"}),(0,t.jsx)(a.Skeleton,{className:"h-5 w-9 rounded-full opacity-65"})]}):"meter"===i?(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsx)(a.Skeleton,{className:"h-3.5 w-24"}),(0,t.jsx)(a.Skeleton,{className:"h-1.5 w-full rounded-full"})]}):(0,t.jsx)(a.Skeleton,{className:(0,s.cn)("h-3.5",o,n?.numeric?"ml-auto":"")})}function N({rowCount:e,columns:l,size:n,message:o}){let a=Array.from({length:Math.max(e,1)},(e,t)=>t),u=l.length>0?l:[void 0];return(0,t.jsx)(i.Fragment,{children:a.map(e=>(0,t.jsx)(r.TableRow,{className:(0,s.cn)("hover:bg-transparent","compact"===n?"h-8":""),"data-testid":"skeleton-row",children:u.map((l,i)=>(0,t.jsxs)(r.TableCell,{className:"compact"===n?"px-2 py-1":"",children:[(0,t.jsx)(z,{column:l,index:i}),0===e&&0===i&&void 0!==o?(0,t.jsx)("span",{className:"sr-only",children:o}):null]},l?.id??i))},`skeleton-${e}`))})}function D(e,t,l){let[n,o]=(0,i.useState)(l);return void 0!==e?{value:e,onChange:t??b}:{value:n,onChange:o}}e.s(["DataTable",0,function(e){let{isLoading:o=!1,loadingMessage:a="Loading…",skeletonRowCount:u=8,noDataMessage:d,paginationMode:g="none",rowCount:c,pageSizeOptions:m=h,enableColumnResizing:p=!1,onRowClick:f,rowClassName:b,renderSubComponent:F,maxBodyHeight:y,fillHeight:j=!1,size:_="default",toolbar:z,paginationSlot:E,footer:k}=e,L=function(e){var t;let{data:o,columns:a,getRowId:r,sortingMode:s="none",sorting:u,onSortingChange:d,defaultSorting:g,enableSortingRemoval:c=!1,paginationMode:m="none",pagination:p,onPaginationChange:f,rowCount:v,isLoading:b=!1,pageSizeOptions:w=h,filterMode:C="none",columnFilters:x,onColumnFiltersChange:S,defaultColumnFilters:F,globalFilter:y,onGlobalFilterChange:M,enableColumnResizing:j=!1,columnResizeMode:P="onEnd",defaultColumnVisibility:I,getRowCanExpand:V,renderSubComponent:_,expanded:z,onExpandedChange:N,enableRowSelection:E,rowSelection:k,onRowSelectionChange:L}=e,A=D(u,d,g??[]),G=D(p,f,{pageIndex:0,pageSize:w[0]??25});!function(e,t,l){let{pageIndex:n,pageSize:o}=l.value,{onChange:a}=l;(0,i.useEffect)(()=>{if(!e||void 0===t)return;let l=Math.max(Math.ceil(t/o)-1,0);n<=l||a({pageIndex:l,pageSize:o})},[e,t,n,o,a])}("server"===m&&!b,v,G);let H=D(x,S,F??[]),T=D(y,M,""),O=D(z,N,{}),B=D(k,L,{}),[q,$]=(0,i.useState)(I??{}),[U,X]=(0,i.useState)({}),K=i.useMemo(()=>{let e;return{left:(e=e=>a.filter(t=>t.meta?.pinned===e).map(R).filter(e=>void 0!==e))("left"),right:e("right")}},[a]),W={data:o,columns:a,state:{sorting:A.value,pagination:G.value,columnFilters:H.value,globalFilter:T.value,expanded:O.value,rowSelection:B.value,columnVisibility:q,columnSizing:U},initialState:{columnPinning:K},manualSorting:"server"===s,manualPagination:"server"===m,manualFiltering:"server"===C,enableSortingRemoval:c,enableColumnResizing:j,columnResizeMode:P,onSortingChange:A.onChange,onPaginationChange:G.onChange,onColumnFiltersChange:H.onChange,onGlobalFilterChange:T.onChange,onExpandedChange:O.onChange,onRowSelectionChange:B.onChange,onColumnVisibilityChange:$,onColumnSizingChange:X,getCoreRowModel:(0,n.getCoreRowModel)(),...(t=void 0!==_?V:void 0,{..."client"===C?{getFilteredRowModel:(0,n.getFilteredRowModel)()}:{},..."client"===s?{getSortedRowModel:(0,n.getSortedRowModel)()}:{},..."client"===m?{getPaginationRowModel:(0,n.getPaginationRowModel)()}:{},...void 0!==t?{getRowCanExpand:t,getExpandedRowModel:(0,n.getExpandedRowModel)()}:{}}),...void 0!==r?{getRowId:r}:{},...void 0!==E?{enableRowSelection:E}:{},..."server"===m&&void 0!==v?{rowCount:v}:{}};return(0,l.useReactTable)(W)}(e),A=L.getRowModel().rows,G=L.getVisibleLeafColumns().length,H=void 0!==y||j,T=j?w:C,O=H?x:S,B=p?{width:L.getTotalSize(),minWidth:"100%"}:void 0,q=(()=>{if(void 0!==E)return E(L);if("none"===g)return null;let e=L.getState().pagination,l="server"===g?c??0:L.getPrePaginationRowModel().rows.length;return(0,t.jsx)(v,{page:e.pageIndex,pageSize:e.pageSize,rowCount:l,onPageChange:e=>L.setPageIndex(e),onPageSizeChange:e=>L.setPageSize(e),pageSizeOptions:m,isLoading:o})})();return(0,t.jsx)("div",{"data-testid":"data-table-root",className:(0,s.cn)("w-full",T.outer),children:(0,t.jsxs)("div",{"data-testid":"data-table-frame",className:(0,s.cn)("overflow-hidden rounded-lg border border-border",T.frame),children:[void 0!==z&&(0,t.jsx)("div",{className:"shrink-0 border-b border-border px-4 py-3",children:z(L)}),(0,t.jsx)("div",{"data-testid":"data-table-scroller",className:(0,s.cn)(H?"overflow-auto":"overflow-x-auto",O.body,T.body),style:void 0!==y?{maxHeight:y}:void 0,children:(0,t.jsxs)(r.Table,{className:p?"table-fixed":"",style:B,children:[(0,t.jsx)(r.TableHeader,{"data-testid":"data-table-head",className:(0,s.cn)(H?"sticky top-0 z-sticky":"",O.header),children:L.getHeaderGroups().map(e=>(0,t.jsx)(r.TableRow,{className:"bg-muted/50",children:e.headers.map(e=>(0,t.jsx)(M,{header:e,size:_,stickyHeader:H,enableColumnResizing:p},e.id))},e.id))}),(0,t.jsx)(r.TableBody,{children:o?(0,t.jsx)(N,{rowCount:u,columns:L.getVisibleLeafColumns(),size:_,message:a}):0===A.length?(0,t.jsx)(I,{colSpan:G,children:d??(0,t.jsx)(V,{})}):A.map(e=>(0,t.jsx)(P,{row:e,size:_,stickyHeader:H,enableColumnResizing:p,onRowClick:f,rowClassName:b,renderSubComponent:F},e.id))}),void 0!==k&&(0,t.jsx)(r.TableFooter,{children:k(L)})]})}),null!==q&&(0,t.jsx)("div",{className:"shrink-0 border-t border-border",children:q})]})})}],807235)},980376,e=>{"use strict";var t=e.i(843476),l=e.i(353753),n=e.i(196631),o=e.i(519455),i=e.i(995926);function a({...e}){return(0,t.jsx)(l.Dialog.Portal,{"data-slot":"sheet-portal",...e})}function r({className:e,...o}){return(0,t.jsx)(l.Dialog.Backdrop,{"data-slot":"sheet-overlay",className:(0,n.cn)("fixed inset-0 z-popup bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",e),...o})}e.s(["Sheet",0,function({...e}){return(0,t.jsx)(l.Dialog.Root,{"data-slot":"sheet",...e})},"SheetContent",0,function({className:e,children:s,side:u="right",showCloseButton:d=!0,...g}){return(0,t.jsxs)(a,{children:[(0,t.jsx)(r,{}),(0,t.jsxs)(l.Dialog.Popup,{"data-slot":"sheet-content","data-side":u,className:(0,n.cn)("fixed z-popup flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",e),...g,children:[s,d&&(0,t.jsxs)(l.Dialog.Close,{"data-slot":"sheet-close",render:(0,t.jsx)(o.Button,{variant:"ghost",className:"absolute top-4 right-4",size:"icon-sm"}),children:[(0,t.jsx)(i.XIcon,{}),(0,t.jsx)("span",{className:"sr-only",children:"Close"})]})]})]})},"SheetDescription",0,function({className:e,...o}){return(0,t.jsx)(l.Dialog.Description,{"data-slot":"sheet-description",className:(0,n.cn)("text-sm text-muted-foreground",e),...o})},"SheetFooter",0,function({className:e,...l}){return(0,t.jsx)("div",{"data-slot":"sheet-footer",className:(0,n.cn)("mt-auto flex flex-col gap-2 p-4",e),...l})},"SheetHeader",0,function({className:e,...l}){return(0,t.jsx)("div",{"data-slot":"sheet-header",className:(0,n.cn)("flex flex-col gap-1.5 p-4",e),...l})},"SheetTitle",0,function({className:e,...o}){return(0,t.jsx)(l.Dialog.Title,{"data-slot":"sheet-title",className:(0,n.cn)("font-medium text-foreground",e),...o})}])},981080,735419,884916,531649,e=>{"use strict";var t=e.i(843476),l=e.i(271645),n=e.i(519455),o=e.i(110204),i=e.i(980376);function a(e){return Object.fromEntries(e.map(e=>[e.id,e.value]))}e.s(["DataTableFilterDrawer",0,function({table:e,open:o,onOpenChange:r,title:s="Filters",description:u,applyLabel:d="Apply Filters",resetLabel:g="Reset",onReset:c,children:m}){let[p,f]=l.useState(()=>a(e.getState().columnFilters)),[h,v]=l.useState(o);return o!==h&&(v(o),o&&f(a(e.getState().columnFilters))),(0,t.jsx)(i.Sheet,{open:o,onOpenChange:r,children:(0,t.jsxs)(i.SheetContent,{side:"right",children:[(0,t.jsxs)(i.SheetHeader,{children:[(0,t.jsx)(i.SheetTitle,{children:s}),void 0!==u&&(0,t.jsx)(i.SheetDescription,{children:u})]}),(0,t.jsx)("div",{className:"flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto p-4","data-testid":"filter-drawer-body",children:m({get:e=>p[e],set:(e,t)=>f(l=>({...l,[e]:t}))})}),(0,t.jsxs)(i.SheetFooter,{className:"flex-row",children:[(0,t.jsx)(n.Button,{variant:"outline",className:"flex-1",onClick:()=>{(f({}),void 0!==c)?c():e.setColumnFilters([])},"data-testid":"filter-drawer-reset",children:g}),(0,t.jsx)(n.Button,{className:"flex-1",onClick:()=>{e.setColumnFilters(Object.entries(p).filter(([,e])=>!(Array.isArray(e)?0===e.length:null==e||""===e)).map(([e,t])=>({id:e,value:t}))),r(!1)},"data-testid":"filter-drawer-apply",children:d})]})]})})},"DataTableFilterField",0,function({label:e,children:l}){return(0,t.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,t.jsx)(o.Label,{children:e}),l]})}],981080);var r=e.i(257428);function s({table:e}){let l=e.getIsAllPageRowsSelected(),n=e.getIsSomePageRowsSelected();return(0,t.jsx)(r.Checkbox,{"aria-label":"Select all rows","data-testid":"datatable-select-all",checked:l,indeterminate:n&&!l,onCheckedChange:t=>e.toggleAllPageRowsSelected(!!t)})}function u({row:e,label:l}){return(0,t.jsx)(r.Checkbox,{"aria-label":l,"data-testid":`datatable-select-row-${e.id}`,checked:e.getIsSelected(),disabled:!e.getCanSelect(),onCheckedChange:t=>e.toggleSelected(!!t)})}e.s(["createSelectionColumn",0,function(e={}){let{rowAriaLabel:l}=e;return{id:"select",size:44,enableSorting:!1,enableHiding:!1,enableResizing:!1,meta:{title:"Select",className:"w-11",headerClassName:"w-11"},header:({table:e})=>(0,t.jsx)(s,{table:e}),cell:({row:e})=>(0,t.jsx)(u,{row:e,label:l?.(e)??"Select row"})}}],735419);var d=e.i(16715),g=e.i(555436),c=e.i(475254);let m=(0,c.default)("sliders-horizontal",[["line",{x1:"21",x2:"14",y1:"4",y2:"4",key:"obuewd"}],["line",{x1:"10",x2:"3",y1:"4",y2:"4",key:"1q6298"}],["line",{x1:"21",x2:"12",y1:"12",y2:"12",key:"1iu8h1"}],["line",{x1:"8",x2:"3",y1:"12",y2:"12",key:"ntss68"}],["line",{x1:"21",x2:"16",y1:"20",y2:"20",key:"14d8ph"}],["line",{x1:"12",x2:"3",y1:"20",y2:"20",key:"m0wm8r"}],["line",{x1:"14",x2:"14",y1:"2",y2:"6",key:"14e1ph"}],["line",{x1:"8",x2:"8",y1:"10",y2:"14",key:"1i6ji0"}],["line",{x1:"16",x2:"16",y1:"18",y2:"22",key:"1lctlv"}]]);var p=e.i(37727),f=e.i(487486),h=e.i(793479),v=e.i(196631),b=e.i(451512),w=e.i(643531);let C=(0,c.default)("columns-3",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M9 3v18",key:"fh3hqa"}],["path",{d:"M15 3v18",key:"14nvp0"}]]);function x({table:e,label:l="View",className:o}){let i=e.getAllLeafColumns().filter(e=>e.getCanHide());return 0===i.length?null:(0,t.jsxs)(b.Menu.Root,{children:[(0,t.jsx)(b.Menu.Trigger,{render:(0,t.jsxs)(n.Button,{variant:"outline",size:"sm",className:o,"data-testid":"view-options-trigger",children:[(0,t.jsx)(C,{}),l]})}),(0,t.jsx)(b.Menu.Portal,{children:(0,t.jsx)(b.Menu.Positioner,{side:"bottom",align:"end",sideOffset:4,className:"isolate z-popup",children:(0,t.jsx)(b.Menu.Popup,{className:"min-w-[12rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:i.map(e=>(0,t.jsxs)(b.Menu.CheckboxItem,{checked:e.getIsVisible(),onCheckedChange:t=>e.toggleVisibility(t),closeOnClick:!1,"data-testid":`view-option-${e.id}`,className:"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-7 capitalize outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground",children:[(0,t.jsx)(b.Menu.CheckboxItemIndicator,{className:"absolute left-2 flex size-4 items-center justify-center",children:(0,t.jsx)(w.Check,{className:"size-3.5"})}),e.columnDef.meta?.title??("string"==typeof e.columnDef.header?e.columnDef.header:e.id)]},e.id))})})})]})}e.s(["DataTableViewOptions",0,x],884916),e.s(["DataTableToolbar",0,function({table:e,searchValue:l,onSearchChange:o,searchPlaceholder:i="Search",onOpenFilters:a,onRefresh:r,isRefreshing:s=!1,filterLabels:u,formatFilterValue:c,showViewOptions:b=!0,children:w,className:C}){let S=e.getState().columnFilters,R=t=>u?.[t]??e.getColumn(t)?.columnDef.meta?.title??t;return(0,t.jsxs)("div",{className:(0,v.cn)("flex flex-wrap items-center justify-between gap-2",C),children:[(0,t.jsxs)("div",{className:"flex flex-1 flex-wrap items-center gap-2",children:[void 0!==o&&(0,t.jsxs)("div",{className:"relative",children:[(0,t.jsx)(g.Search,{className:"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground"}),(0,t.jsx)(h.Input,{value:l??"",onChange:e=>o(e.target.value),placeholder:i,className:"h-8 w-56 pl-8","data-testid":"datatable-search"})]}),S.map(l=>{var n,o;return(0,t.jsxs)(f.Badge,{variant:"outline",className:"gap-1 py-1","data-testid":`filter-chip-${l.id}`,children:[(0,t.jsxs)("span",{className:"text-muted-foreground",children:[R(l.id),":"]}),(n=l.id,o=l.value,c?.(n,o)??(Array.isArray(o)?o.join(", "):String(o))),(0,t.jsx)("button",{type:"button","aria-label":`Remove ${R(l.id)} filter`,"data-testid":`filter-chip-remove-${l.id}`,onClick:()=>e.setColumnFilters(e=>e.filter(e=>e.id!==l.id)),className:"ml-0.5 rounded-full text-muted-foreground hover:text-foreground",children:(0,t.jsx)(p.X,{className:"size-3"})})]},l.id)}),S.length>0&&(0,t.jsx)(n.Button,{variant:"ghost",size:"sm",onClick:()=>e.setColumnFilters([]),"data-testid":"datatable-clear-filters",children:"Clear all"})]}),(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[w,void 0!==r&&(0,t.jsx)(n.Button,{variant:"outline",size:"icon-sm",onClick:r,disabled:s,"aria-label":"Refresh",title:"Refresh","data-testid":"datatable-refresh",children:(0,t.jsx)(d.RefreshCw,{className:s?"animate-spin":""})}),b&&(0,t.jsx)(x,{table:e,label:"Columns"}),void 0!==a&&(0,t.jsxs)(n.Button,{variant:"outline",size:"sm",onClick:a,"data-testid":"datatable-filters-trigger",children:[(0,t.jsx)(m,{}),"Filters",S.length>0&&(0,t.jsx)(f.Badge,{className:"ml-1 h-5 min-w-5 justify-center rounded-full px-1","data-testid":"datatable-filter-count",children:S.length})]})]})]})}],531649)},655900,e=>{"use strict";var t=e.i(399219);e.s(["ChevronUp",()=>t.default])},707701,494862,e=>{"use strict";e.i(807235),e.i(981080),e.i(152370),e.i(735419),e.i(531649),e.i(884916);var t=e.i(843476),l=e.i(451512),n=e.i(643531),o=e.i(664659),i=e.i(344523),a=e.i(655900),r=e.i(37727),s=e.i(196631);function u({sorted:e}){return"asc"===e?(0,t.jsx)(a.ChevronUp,{className:"size-3.5","data-sort-indicator":"asc"}):"desc"===e?(0,t.jsx)(o.ChevronDown,{className:"size-3.5","data-sort-indicator":"desc"}):(0,t.jsx)(i.ChevronsUpDown,{className:"size-3.5 text-muted-foreground","data-sort-indicator":"none"})}let d="flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground";e.s(["DataTableMultiSortHeader",0,function({table:e,fields:i,className:g}){let c=e.getState().sorting[0],m=void 0!==c&&i.some(e=>e.id===c.id)?c:void 0,p=m?.desc===!0?"desc":"asc",f=void 0!==m&&p,h=i.flatMap(e=>[{key:`${e.id}-asc`,id:e.id,desc:!1,label:`${e.label} ascending`,Icon:a.ChevronUp},{key:`${e.id}-desc`,id:e.id,desc:!0,label:`${e.label} descending`,Icon:o.ChevronDown}]),v=i.flatMap((e,l)=>{let n=m?.id===e.id,o=(0,t.jsx)("span",{"data-sort-field":e.id,className:n?"font-semibold text-foreground":m?"text-muted-foreground":"",children:e.label},e.id);return 0===l?[o]:[(0,t.jsx)("span",{className:"text-muted-foreground",children:" / "},`sep-${e.id}`),o]});return(0,t.jsxs)("div",{className:(0,s.cn)("flex items-center gap-1",g),children:[(0,t.jsx)("span",{className:"font-medium",children:v}),(0,t.jsxs)(l.Menu.Root,{children:[(0,t.jsx)(l.Menu.Trigger,{render:(0,t.jsx)("button",{type:"button","data-testid":`sort-trigger-${i[0]?.id??"field"}`,"aria-label":`Sort options for ${i.map(e=>e.label).join(" or ")}`,onClick:e=>e.stopPropagation(),className:(0,s.cn)("inline-flex size-6 items-center justify-center rounded-md hover:bg-muted",f?"text-primary":"text-muted-foreground"),children:(0,t.jsx)(u,{sorted:f})})}),(0,t.jsx)(l.Menu.Portal,{children:(0,t.jsx)(l.Menu.Positioner,{side:"bottom",align:"start",sideOffset:4,className:"isolate z-popup",children:(0,t.jsxs)(l.Menu.Popup,{className:"min-w-[9rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:[h.map(o=>{let i=m?.id===o.id&&m.desc===o.desc;return(0,t.jsxs)(l.Menu.Item,{className:(0,s.cn)(d,i?"text-primary":""),onClick:()=>e.setSorting([{id:o.id,desc:o.desc}]),children:[(0,t.jsx)(o.Icon,{className:"size-3.5"})," ",o.label,i&&(0,t.jsx)(n.Check,{className:"ml-auto size-3.5"})]},o.key)}),(0,t.jsxs)(l.Menu.Item,{className:d,onClick:()=>e.setSorting([]),children:[(0,t.jsx)(r.X,{className:"size-3.5"})," Reset"]})]})})})]})]})},"DataTableSortHeader",0,function({column:e,title:n,variant:i="header-cycle",className:g}){let c=e.getIsSorted();return e.getCanSort()?"dropdown-tristate"===i?(0,t.jsxs)("div",{className:(0,s.cn)("flex items-center gap-1",g),children:[(0,t.jsx)("span",{className:"font-medium",children:n}),(0,t.jsxs)(l.Menu.Root,{children:[(0,t.jsx)(l.Menu.Trigger,{render:(0,t.jsx)("button",{type:"button","data-testid":`sort-trigger-${e.id}`,"aria-label":`Sort options for ${e.id}`,onClick:e=>e.stopPropagation(),className:(0,s.cn)("inline-flex size-6 items-center justify-center rounded-md hover:bg-muted",c?"text-primary":"text-muted-foreground"),children:(0,t.jsx)(u,{sorted:c})})}),(0,t.jsx)(l.Menu.Portal,{children:(0,t.jsx)(l.Menu.Positioner,{side:"bottom",align:"start",sideOffset:4,className:"isolate z-popup",children:(0,t.jsxs)(l.Menu.Popup,{className:"min-w-[9rem] rounded-md bg-popover p-1 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden",children:[(0,t.jsxs)(l.Menu.Item,{className:d,onClick:()=>e.toggleSorting(!1),children:[(0,t.jsx)(a.ChevronUp,{className:"size-3.5"})," Ascending"]}),(0,t.jsxs)(l.Menu.Item,{className:d,onClick:()=>e.toggleSorting(!0),children:[(0,t.jsx)(o.ChevronDown,{className:"size-3.5"})," Descending"]}),(0,t.jsxs)(l.Menu.Item,{className:d,onClick:()=>e.clearSorting(),children:[(0,t.jsx)(r.X,{className:"size-3.5"})," Reset"]})]})})})]})]}):(0,t.jsxs)("button",{type:"button","data-testid":`sort-header-${e.id}`,onClick:e.getToggleSortingHandler(),className:(0,s.cn)("flex items-center gap-1 font-medium select-none hover:text-foreground",g),children:[(0,t.jsx)("span",{children:n}),(0,t.jsx)(u,{sorted:c})]}):(0,t.jsx)("span",{className:(0,s.cn)("font-medium",g),children:n})}],494862),e.s([],707701)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/08lua1iopk_79.js b/litellm/proxy/_experimental/out/_next/static/chunks/08lua1iopk_79.js
deleted file mode 100644
index c677cb029cb..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/08lua1iopk_79.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,519380,e=>{e.q("/litellm-asset-prefix/_next/static/media/bedrock.2vhamxr8q6y4o.svg")},946013,e=>{e.q("/litellm-asset-prefix/_next/static/media/google.3y8ypywwtqob_.svg")},641266,e=>{e.q("/litellm-asset-prefix/_next/static/media/microsoft_azure.3626-7zx7wf09.svg")},956529,e=>{e.q("/litellm-asset-prefix/_next/static/media/openai_small.3rj8nedgjpevh.svg")},913383,e=>{e.q("/litellm-asset-prefix/_next/static/media/a2a_agent.14el5-6dflh1h.png")},238564,e=>{e.q("/litellm-asset-prefix/_next/static/media/ai21.0m_u-tih8nm0v.svg")},941533,e=>{e.q("/litellm-asset-prefix/_next/static/media/aiml_api.1dq6dbpwklhlg.svg")},994636,e=>{e.q("/litellm-asset-prefix/_next/static/media/anthropic.3s95kgy8jpc64.svg")},824770,e=>{e.q("/litellm-asset-prefix/_next/static/media/assemblyai_small.0w_dslsra91uw.png")},920076,e=>{e.q("/litellm-asset-prefix/_next/static/media/baseten.41k2lnwp3c5g9.svg")},96889,e=>{e.q("/litellm-asset-prefix/_next/static/media/cerebras.1ur1xyfqk9ncz.svg")},348026,e=>{e.q("/litellm-asset-prefix/_next/static/media/cloudflare.2n1spdq7u5yki.svg")},727148,e=>{e.q("/litellm-asset-prefix/_next/static/media/cohere.22i3i2e449j5i.svg")},411703,e=>{e.q("/litellm-asset-prefix/_next/static/media/cometapi.3w0xficbg3dkk.svg")},922480,e=>{e.q("/litellm-asset-prefix/_next/static/media/cursor.1q1ev-_5l7exg.svg")},769490,e=>{e.q("/litellm-asset-prefix/_next/static/media/databricks.2hiet9qlqzn-g.svg")},829789,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepgram.3-krp20p_xed3.png")},41730,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepinfra.3lr_lsr7mhui6.png")},662576,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepseek.3n4cu0x32i_7w.svg")},987202,e=>{e.q("/litellm-asset-prefix/_next/static/media/elevenlabs.2982m_dk2-h_y.png")},953265,e=>{e.q("/litellm-asset-prefix/_next/static/media/fal_ai.3rahrirki8sby.jpg")},346512,e=>{e.q("/litellm-asset-prefix/_next/static/media/featherless.3hmlef3fhc0h5.svg")},84416,e=>{e.q("/litellm-asset-prefix/_next/static/media/fireworks.3t1b6p8edeqyo.svg")},104602,e=>{e.q("/litellm-asset-prefix/_next/static/media/friendli.0ymiswh6l35bq.svg")},888193,e=>{e.q("/litellm-asset-prefix/_next/static/media/github_copilot.3k-8jyadoaq2u.svg")},447500,e=>{e.q("/litellm-asset-prefix/_next/static/media/groq.20csmqzsusp1k.svg")},270039,e=>{e.q("/litellm-asset-prefix/_next/static/media/huggingface.1-07ypt9ii_-p.svg")},227733,e=>{e.q("/litellm-asset-prefix/_next/static/media/hyperbolic.3le20v59sebn8.svg")},823929,e=>{e.q("/litellm-asset-prefix/_next/static/media/infinity.0s9s12bl4lccx.png")},333845,e=>{e.q("/litellm-asset-prefix/_next/static/media/jina.0ukab8o-3-5m_.png")},813878,e=>{e.q("/litellm-asset-prefix/_next/static/media/lambda.26_vz7cmyuodo.svg")},767788,e=>{e.q("/litellm-asset-prefix/_next/static/media/lmstudio.35s3-83mlhcms.svg")},808630,e=>{e.q("/litellm-asset-prefix/_next/static/media/meta_llama.1kxk24vwsem49.svg")},468732,e=>{e.q("/litellm-asset-prefix/_next/static/media/minimax.2mfkkqc-lnsen.svg")},610503,e=>{e.q("/litellm-asset-prefix/_next/static/media/mistral.0n8jv_67hgq4h.svg")},438969,e=>{e.q("/litellm-asset-prefix/_next/static/media/moonshot.3__i9wvf37ksm.svg")},852459,e=>{e.q("/litellm-asset-prefix/_next/static/media/morph.2av06eo-t0-ve.svg")},494696,e=>{e.q("/litellm-asset-prefix/_next/static/media/nebius.2ipf7rmjccira.svg")},148973,e=>{e.q("/litellm-asset-prefix/_next/static/media/novita.0_nzmm_rl4lrf.svg")},570036,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_nim.1fz-5ugf_um0v.svg")},151170,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_triton.1aotoxig_m2w1.png")},862330,e=>{e.q("/litellm-asset-prefix/_next/static/media/ollama.144cif369atc5.svg")},788158,e=>{e.q("/litellm-asset-prefix/_next/static/media/openrouter.1xk7748-_jixf.svg")},350567,e=>{e.q("/litellm-asset-prefix/_next/static/media/oracle.43kws59xxr8ig.svg")},822797,e=>{e.q("/litellm-asset-prefix/_next/static/media/perplexity-ai.2do8hoc8tw__0.svg")},840911,e=>{e.q("/litellm-asset-prefix/_next/static/media/qwen.0a49x9i08_0gz.png")},445735,e=>{e.q("/litellm-asset-prefix/_next/static/media/recraft.2f4cv-c9ad-mo.svg")},635202,e=>{e.q("/litellm-asset-prefix/_next/static/media/replicate.445bidyix2tyh.svg")},669161,e=>{e.q("/litellm-asset-prefix/_next/static/media/runway.2zzwye1fddnnn.png")},159508,e=>{e.q("/litellm-asset-prefix/_next/static/media/sambanova.1vcyu0faw1x8h.svg")},544025,e=>{e.q("/litellm-asset-prefix/_next/static/media/sap.1367hgge0s0xl.png")},708767,e=>{e.q("/litellm-asset-prefix/_next/static/media/scx_ai.3emo1p5delrhx.svg")},100588,e=>{e.q("/litellm-asset-prefix/_next/static/media/snowflake.2_p8qqpi0r3lr.svg")},183804,e=>{e.q("/litellm-asset-prefix/_next/static/media/soniox.3nhjmssy7ybh7.svg")},865502,e=>{e.q("/litellm-asset-prefix/_next/static/media/togetherai.1wk-mouzgw5ho.svg")},96912,e=>{e.q("/litellm-asset-prefix/_next/static/media/topaz.3rjp3zvx4eags.svg")},395073,e=>{e.q("/litellm-asset-prefix/_next/static/media/v0.15trd3tb1ulop.svg")},407829,e=>{e.q("/litellm-asset-prefix/_next/static/media/vercel.1mvnwxofolt8y.svg")},846077,e=>{e.q("/litellm-asset-prefix/_next/static/media/vllm.3_gqby46r7s3x.png")},914861,e=>{e.q("/litellm-asset-prefix/_next/static/media/volcengine.23ly9ik_qc138.png")},285328,e=>{e.q("/litellm-asset-prefix/_next/static/media/voyage.0krq6ew-yr8dk.webp")},779278,e=>{e.q("/litellm-asset-prefix/_next/static/media/watsonx.19rrg39yvhpk8.svg")},325532,e=>{e.q("/litellm-asset-prefix/_next/static/media/xai.2kc3gjiopn9om.svg")},288330,e=>{e.q("/litellm-asset-prefix/_next/static/media/xinference.063cy_ievvy5u.svg")},922158,336712,39182,980385,e=>{"use strict";let t={src:e.i(519380).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,t],922158);let r={src:e.i(946013).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,r],336712);let i={src:e.i(641266).default,width:200,height:58,blurWidth:0,blurHeight:0};e.s(["default",0,i],39182);let a={src:e.i(956529).default,width:28,height:28,blurWidth:0,blurHeight:0};e.s(["default",0,a],980385)},916925,555987,9774,247044,e=>{"use strict";var t,r=e.i(221688),i=e.i(950643);let a=/^(https?:|data:|blob:|\/\/)/i,s=e=>a.test(e),l=(e,t=r.serverRootPath)=>{let a;if(!e)return;if(s(e)||e.includes("/_next/static/"))return e;let l=(0,i.normalizeRootPath)(t);return l&&(e===l||e.startsWith(`${l}/`))?e:(a=(0,i.normalizeRootPath)(t),`${a}${e.startsWith("/")?e:`/${e}`}`)};e.s(["isExternalAssetSrc",0,s,"resolveLogoSrc",0,l],555987);let n={src:e.i(913383).default,width:661,height:768,blurWidth:7,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAwUlEQVR42h2OvQpGcByFf5dK7oBJFoooJDaDZFA+BoVkNBikGJSUJINyGeft/Q+nznDO00O6rsM0Tfi+z6JpGizLgqqqIEVR0HUdqqqCbdus930PWZZBy7IgCAKkaYpxHJEkCaIowjAMoGmaEMcx8jxHURRo2xZ1XaMsS9B5nrjvG+u6Yp5nfN+H53nwJ9JxHMiyDO/7Mtx1Xey1bRvIcRzwPI993xGGIZqmgSAIMAwDJEkSPM9jphzHsYHruhBFET+hn6S8pf6D7AAAAABJRU5ErkJggg=="},o={src:e.i(238564).default,width:103,height:24,blurWidth:0,blurHeight:0},A={src:e.i(941533).default,width:115,height:24,blurWidth:0,blurHeight:0},c={src:e.i(994636).default,width:46,height:46,blurWidth:0,blurHeight:0},d={src:e.i(824770).default,width:28,height:28,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAlElEQVR42m3OoQqDUBQGYF9mwzLbFiZsMNgwuGa4YFgYLC6PgcXuA5gFzdcgFkExGr33ogZRNIr6CAoKKgo/nAMfh/NTu3u4GWoY+0fIAsIC3C8LuIiRH9S2W5wBXsBPKaHTGGb+lZMJmCe2vPYjZe9/bMDswKMRbq9Yg9VRICcBq3p6FckINIf6o6ECwyOam/1YpwPFUFu+Lt2F2QAAAABJRU5ErkJggg=="},u={src:e.i(920076).default,width:16,height:16,blurWidth:0,blurHeight:0};var h=e.i(922158);let g={src:e.i(96889).default,width:800,height:600,blurWidth:0,blurHeight:0},m={src:e.i(348026).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,m],9774);let p={src:e.i(727148).default,width:75,height:75,blurWidth:0,blurHeight:0},f={src:e.i(411703).default,width:16,height:16,blurWidth:0,blurHeight:0},x={src:e.i(922480).default,width:16,height:16,blurWidth:0,blurHeight:0},b={src:e.i(769490).default,width:16,height:16,blurWidth:0,blurHeight:0},v={src:e.i(829789).default,width:32,height:32,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAzklEQVR42k3PPWuDcBDHccUiiikYSwqhg+IkuKUpOLqK4OYrcBZcFCcH352mgy/Ch9mxEPg2+s+Q4W65zx33kyRJQpZlFOUNTdM4HN45Hi1Op0/O56+7tAHbtqmqiqZpKIqCy+Uby/rYkABhGLKuK+M4siwLt9sv1+sPpmkKEAQBwzCQpilxHDNNE3VdYxiGALqu47oujuMQRdEOyrJEVVUBFEUhSRK6rmOeZ/q+x/f97XkBHqfIsoy2bcnzHM/z9mSP2Q62dt/0c+O1/v4BYRxu3LgaR7UAAAAASUVORK5CYII="},_={src:e.i(41730).default,width:225,height:225,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAfklEQVR42nVOvQqDMBjM+7+RpbQ0Ji2NQhwdzGIwCMZFiCAa9STqIPhxw/3A3UeW41w/AKck87w0tqvbngkFgEDCJOPoKc+fovxKzaUGiXkOk0zei1TRzDxYEbHiIw0kzD2Aji5BqHolW9Uv0+9U01AVxivr4r8CjHX7+N27K5WIrP56XsFTAAAAAElFTkSuQmCC"},E={src:e.i(662576).default,width:293,height:215,blurWidth:0,blurHeight:0},w={src:e.i(987202).default,width:1563,height:1563,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA5ElEQVR42h2PPwtBURjGj3wCk93sC1iUCYXFIlGSMjC4QiiTBSE3Ge5M3e0uPoJFBhOTP8NNukXduFL3uJ1Xzz11znCe93me38uitQSL11Pe8rAanKpycbSa5Ar9UiAmJT3QXHGwHGfvj/vJcRzOfz/7fLvsW4tuJFZLehicEIUQpOs6GYZBOIfrcZPp5f0MsXDatk2yLJOqqu6A9f2YjXk7zNCJWM45KYpCmqa5A6/P+ynNGiEGIHSiwjRNsiyLBAmxPezW6U7Gx0ALIHQiFk6I5WEl6G6BB7QAQqc0a4bgxD/uH4FYoVec8m3dAAAAAElFTkSuQmCC"},I={src:e.i(953265).default,width:400,height:400,blurWidth:8,blurHeight:8,blurDataURL:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAAIAAgDAREAAhEBAxEB/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtP9N/tL+PO/8A7ZeV/wDFUj6L917L+r3/AMj/2Q=="},C={src:e.i(346512).default,width:16,height:16,blurWidth:0,blurHeight:0},O={src:e.i(84416).default,width:16,height:16,blurWidth:0,blurHeight:0},T={src:e.i(104602).default,width:16,height:16,blurWidth:0,blurHeight:0},k={src:e.i(888193).default,width:16,height:16,blurWidth:0,blurHeight:0};var N=e.i(336712);let y={src:e.i(447500).default,width:26,height:26,blurWidth:0,blurHeight:0},S={src:e.i(270039).default,width:16,height:16,blurWidth:0,blurHeight:0},R={src:e.i(227733).default,width:16,height:16,blurWidth:0,blurHeight:0},L={src:e.i(823929).default,width:128,height:129,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAApklEQVR42oWPsQrCMBRFY51KaUuwNktBQbcgSenQ32hCTBAHXfSfulUK4g/0/7yvdO+FB5dzXhLC2FoiJE3TfZ7nYrskyzIBVpBjTdPcu677GGPGtm1fmDd1YnVd31gIYSrLUnLOjxC9tfaLfhBCXLz307xQVZUCODvnfljoceAEpskxKeUV1w0Qo1LqobV+Lk8McI5tkDiOeZIkO9SIBr0gRm71l38QASaqNz7VMwAAAABJRU5ErkJggg=="},U={src:e.i(333845).default,width:200,height:200,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAXUlEQVR42p2MoRHAMAwDQwJzCcgCwQEZIDjA03gED2BzewSPWRe2qFcB3Z+kU0o/lXNea4U/0t77OYeIACDq4FLKnSKimYmIqjKzu885U6117z3GCGitxTbg/flJF7DAEmcR3WAqAAAAAElFTkSuQmCC"},H={src:e.i(813878).default,width:16,height:16,blurWidth:0,blurHeight:0},M={src:e.i(767788).default,width:16,height:16,blurWidth:0,blurHeight:0},B={src:e.i(808630).default,width:16,height:16,blurWidth:0,blurHeight:0};var j=e.i(39182);let D={src:e.i(468732).default,width:490,height:412,blurWidth:0,blurHeight:0},P={src:e.i(610503).default,width:16,height:16,blurWidth:0,blurHeight:0},q={src:e.i(438969).default,width:16,height:16,blurWidth:0,blurHeight:0},G={src:e.i(852459).default,width:16,height:16,blurWidth:0,blurHeight:0},W={src:e.i(494696).default,width:16,height:16,blurWidth:0,blurHeight:0},z={src:e.i(148973).default,width:16,height:16,blurWidth:0,blurHeight:0},F={src:e.i(570036).default,width:16,height:16,blurWidth:0,blurHeight:0},V={src:e.i(151170).default,width:95,height:81,blurWidth:8,blurHeight:7,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAYAAAA1WQxeAAAA0UlEQVR42kXMvWrCUBjG8VxIL6KX0IvobXQSOrQd2kLSdMzQdMmaEErPUqoIIYtKOC5iFD9BEBwiaAY/AgpH/2oUfOGFh4cfj8blNmrNKK0zmFUZzmust2nea7u9IlkNkBMPv1Xgs3JHoXRDe1o+g8Vmyl/vnf++wU/7EdF54jW8JU6K14WTPgE3fjiCZ77kPa2kdAZZlrFcLpikXYLeN6Lxxm/zhfEsRimF5roupmli2zbGh4Gu61iWlX8URWhSSsIwxPM8hBA4jpNn3/cJgoADqC23HJzwo6wAAAAASUVORK5CYII="},Q={src:e.i(862330).default,width:646,height:854,blurWidth:0,blurHeight:0};var K=e.i(980385);let Y={src:e.i(788158).default,width:300,height:300,blurWidth:0,blurHeight:0},J={src:e.i(350567).default,width:231,height:30,blurWidth:0,blurHeight:0},X={src:e.i(822797).default,width:48,height:48,blurWidth:0,blurHeight:0},Z={src:e.i(840911).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABE0lEQVR42gEIAff+AAAAAAAAAAAAEQwmIT8ukIAgGUpBBwYQDQQECggAAAAAAAIBBQQJBhUTFw80LUIxloZbR8+5UUS3oUA4kH0HBxEOACMUUkolFlVNCAYTERwUPzgkHFJIIhxNRCsmYVQODSAbADYffnNFKaCSDgkgHD0tjX4+MI5+CQgVEhQSLCULChgUABAKJiJTM7+vJhlYTzEkb2MxJm9iIh1NQywnZFYhH0o/AA8JIh9RMrurNiR9cQkHFhMQDSUgUkW5o1hOx60pJlxPAAcEDw4qGmJYFw80LhENKCMyKHFjUEK0nhEOJSADAwYFAAAAAAADAgcGBQMLCRUPMClCNJeEIRtLQgAAAQAAAAAAfjQxsiCQipMAAAAASUVORK5CYII="},$={src:e.i(445735).default,width:16,height:16,blurWidth:0,blurHeight:0},ee={src:e.i(635202).default,width:16,height:16,blurWidth:0,blurHeight:0},et={src:e.i(669161).default,width:320,height:320,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7UlEQVR42lVQvc7BYBR+B/kM3w+fFm2p9m3fRhFRP7UQlTAQCVfAgE3EHZAQMTBIzBIrYbEgFhaza3ABrsF7bIYnOTl5/s5BVrvIY5MMvYTbUuy8hN8CcFIdW62CgHCKjFwie/So3PqH+b0Hc+GebkW6Lj9zUtJaHwEbFvGqWf7zOG5GJVmjcwUEAUOevQmhfKSTqJol+7f94RT+L7Yv25OV3PtsI699EByc85qpW5qcUCaMyB7orH9EgJLaTnPNgk/QfUsxKi0QtKWFzjRzA7a08IEPCivYKWkyQHAKtJUMPIVMQCAmz3FKHcELXnxEPy9E1lYCAAAAAElFTkSuQmCC"},er={src:e.i(159508).default,width:52,height:46,blurWidth:0,blurHeight:0},ei={src:e.i(544025).default,width:3300,height:2550,blurWidth:8,blurHeight:6,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAAZklEQVR42oWNTQ5AMBhE3f8mEhux4BgiIRzAwoKWplrt146fBbVhkpnNvORF+El0jvMAV4RR2qtsJZD3DyA2h6xhiMsRSTUhrRm0DYBFE4qOI285yl5CGvdW0OEYhEE/G6jgvIGv7A4KupBwIVaNAAAAAElFTkSuQmCC"},ea={src:e.i(708767).default,width:760,height:277,blurWidth:0,blurHeight:0},es={src:e.i(100588).default,width:146,height:139,blurWidth:0,blurHeight:0};e.s(["default",0,es],247044);let el={src:e.i(183804).default,width:100,height:18,blurWidth:0,blurHeight:0},en={src:e.i(865502).default,width:32,height:32,blurWidth:0,blurHeight:0},eo={src:e.i(96912).default,width:16,height:16,blurWidth:0,blurHeight:0},eA={src:e.i(395073).default,width:16,height:16,blurWidth:0,blurHeight:0},ec={src:e.i(407829).default,width:16,height:16,blurWidth:0,blurHeight:0},ed={src:e.i(846077).default,width:64,height:64,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAo0lEQVR42lWOvQrCQBCE7718oUA6wVcQBF/AXhu1CIgcpgoi/qCNguBPwCaChYHDv9zt3e6ZeEFxq9n5GGaY/T8iq3QhWKFRkZGWzEPaaE/RDoiI5e7z0BILP7tMB2vyO3p2BJew8syvvJLGQTPEaheSVJeAQIi5F2+CWt80uHopLMEnNBpPuNc2vaXK+38A4RauTvUhbBNwDvsOlYD3DA2Se99kLK7hC5QFVQAAAABJRU5ErkJggg=="},eu={src:e.i(914861).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7ElEQVR42l2LMUsCAQBG39GFFQ02ad1oq0QIRR2hER4EGdQqdBDdQZAFEudU0NZSQ0O1VUOjiuJvEBxc3BQFEVQQdFAU9OROFwf9lg/e48Hiti8vWJekBSoIODacLK04CP79IAX8815cW2X3IYL3JIhaKuKLGdNGmMUCTo+Hq1yO72yB6HDEeTrFjm8fUVwGt3uL00eD5+6AfMvixbS5bTR5/43jcm2CooT4KNf56ltUGzafA5uoZZGpdJDlABhPr7z1TJLtMbXamMT0702T//aQu0gM5GOFvRuNkKoTDuucqRpeXePoWuPg0D8BGkpJjYhKXN4AAAAASUVORK5CYII="},eh={src:e.i(285328).default,width:400,height:399,blurWidth:8,blurHeight:8,blurDataURL:"data:image/webp;base64,UklGRgwBAABXRUJQVlA4TAABAAAvB8ABEM1VICICHggIDgIAAIDzDAACD0FoAAARAAwAAAAAAAAAAAAAAACAAABAAcBCAoAWgGyoXwUAAA8E7QQCAADg/N+nrsYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4CClZXkg5AQAAAAA538LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL0HIgEAAAAAcP4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMsHA39Qutr2AtkROu8CASWZ/nMlNyzz5AdgWmkK65oUI6AlgIkY/M3zxIW3iABq15KT/Uz7BXidCOONHieAz1v6HqAC"},eg={src:e.i(779278).default,width:16,height:16,blurWidth:0,blurHeight:0},em={src:e.i(325532).default,width:1e3,height:1e3,blurWidth:0,blurHeight:0},ep={src:e.i(288330).default,width:16,height:16,blurWidth:0,blurHeight:0};var ef=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cognition="Cognition",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="Hosted vLLM",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.NVIDIA_RIVA="Nvidia Riva",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.SCX_AI="SCX.ai",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Local vLLM",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let ex={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cognition:"cognition",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",NVIDIA_RIVA:"nvidia_riva",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",SCX_AI:"scx-ai",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},eb=new Set(["bedrock_mantle"]),ev={"A2A Agent":n.src,Ai21:o.src,"Ai21 Chat":o.src,"AI/ML API":A.src,"Aiohttp Openai":K.default.src,Anthropic:c.src,"Anthropic Text":c.src,AssemblyAI:d.src,Azure:j.default.src,"Azure AI Foundry (Studio)":j.default.src,"Azure Text":j.default.src,Baseten:u.src,"Amazon Bedrock":h.default.src,"Amazon Bedrock Mantle":h.default.src,"AWS SageMaker":h.default.src,Cerebras:g.src,Cloudflare:m.src,Codestral:P.src,Cohere:p.src,"Cohere Chat":p.src,Cometapi:f.src,Cursor:x.src,"Databricks (Qwen API)":b.src,Dashscope:Z.src,Deepseek:E.src,Deepgram:v.src,DeepInfra:_.src,ElevenLabs:w.src,"Fal AI":I.src,"Featherless Ai":C.src,"Fireworks AI":O.src,Friendliai:T.src,"Github Copilot":k.src,"Google AI Studio":N.default.src,Groq:y.src,"Hosted vLLM":ed.src,Huggingface:S.src,Hyperbolic:R.src,Infinity:L.src,"Jina AI":U.src,"Lambda Ai":H.src,"Lm Studio":M.src,"Meta Llama":B.src,MiniMax:D.src,"Mistral AI":P.src,Moonshot:q.src,Morph:G.src,Nebius:W.src,Novita:z.src,"Nvidia Nim":F.src,"Nvidia Riva":F.src,Ollama:Q.src,"Ollama Chat":Q.src,Oobabooga:K.default.src,OpenAI:K.default.src,"Openai Like":K.default.src,"OpenAI Text Completion":K.default.src,"OpenAI-Compatible Completions (legacy /v1/completions)":K.default.src,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":K.default.src,Openrouter:Y.src,"Oracle Cloud Infrastructure (OCI)":J.src,Perplexity:X.src,Recraft:$.src,Replicate:ee.src,RunwayML:et.src,Sagemaker:h.default.src,Sambanova:er.src,"SAP Generative AI Hub":ei.src,"SCX.ai":ea.src,Snowflake:es.src,Soniox:el.src,"Text-Completion-Codestral":P.src,TogetherAI:en.src,Topaz:eo.src,Triton:V.src,V0:eA.src,"Vercel Ai Gateway":ec.src,"Vertex AI (Anthropic, Gemini, etc.)":N.default.src,"Vertex Ai Beta":N.default.src,"Local vLLM":ed.src,VolcEngine:eu.src,"Voyage AI":eh.src,Watsonx:eg.src,"Watsonx Text":eg.src,xAI:em.src,Xinference:ep.src},e_={"AI/ML API":"aiml/flux-pro/v1.1",Anthropic:"claude-3-opus",Azure:"my-deployment","Azure AI Foundry (Studio)":"azure_ai/command-r-plus","Amazon Bedrock":"claude-3-opus",Cognition:"cognition/swe-1.7",Cursor:"cursor/claude-4-sonnet",DeepInfra:"deepinfra/","Fal AI":"fal_ai/fal-ai/flux-pro/v1.1-ultra","Google AI Studio":"gemini-pro","Jina AI":"jina_ai/","Nvidia Riva":"nvidia_riva/nvidia/parakeet-ctc-1_1b-asr","Oracle Cloud Infrastructure (OCI)":"oci/xai.grok-4",RunwayML:"runwayml/gen4_turbo","AWS SageMaker":"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b","SCX.ai":"scx-ai/GLM-5.2",Snowflake:"snowflake/mistral-7b","Vertex AI (Anthropic, Gemini, etc.)":"gemini-pro",VolcEngine:"volcengine/","Voyage AI":"voyage/",Watsonx:"watsonx/ibm/granite-3-3-8b-instruct","Z.AI (Zhipu AI)":"zai/glm-4.5"};e.s(["Providers",()=>ef,"getPlaceholder",0,e=>e_[ef[e]??e]??"gpt-3.5-turbo","getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:l(ev[e])??"",displayName:e}}let t=Object.keys(ex).find(t=>ex[t].toLowerCase()===e.toLowerCase())??Object.keys(ex).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let r=ef[t];return{logo:l(ev[r])??"",displayName:r}},"getProviderModels",0,(e,t)=>{let r=ex[e],i=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let a=t.litellm_provider,s="string"==typeof a&&(a.startsWith(`${r}_`)||a.startsWith(`${r}-`));(a===r||s&&!eb.has(a))&&i.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&i.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&i.push(e)})),i},"providerLogoMap",0,ev,"provider_map",0,ex],916925)},174553,e=>{"use strict";var t=e.i(843476),r=e.i(271645),i=e.i(916925),a=e.i(555987),s=e.i(196631);let l=/(?:\/assets\/logos\/|\/_next\/static\/media\/)/,n={"baseten.svg":"invert","cursor.svg":"invert","enkrypt_ai.avif":"invert","friendli.svg":"invert","github.svg":"invert","github_copilot.svg":"invert","lago.svg":"invert","lambda.svg":"invert","langflow.svg":"invert","lmstudio.svg":"invert","moonshot.svg":"invert","nebius.svg":"invert","notion.svg":"invert","ollama.svg":"invert","openrouter.svg":"invert","promptguard.svg":"invert","recraft.svg":"invert","replicate.svg":"invert","runway.png":"invert","scx_ai.svg":"invert","secret_detect.png":"invert","topaz.svg":"invert","v0.svg":"invert","vercel.svg":"invert","watsonx.svg":"invert","aiml_api.svg":"plate","akto.svg":"plate","aws.svg":"plate","deepkeep.svg":"plate","fireworks.svg":"plate","llm_guard.png":"plate","pangea.png":"plate","repelloai.png":"plate","sambanova.svg":"plate","sentry.svg":"plate","valkey.svg":"plate"},o={invert:"dark:[filter:brightness(0)_invert(1)]",plate:"dark:bg-logo-surface dark:object-contain dark:p-0.5"};e.s(["Logo",0,({provider:e,src:A,label:c,className:d="w-4 h-4"})=>{let[u,h]=(0,r.useState)(null),g=void 0!==e?(0,i.getProviderLogoAndName)(e).logo:(0,a.resolveLogoSrc)(A)??"",m=c??e??"";if(u===g||!g)return(0,t.jsx)("div",{className:`${d} rounded-full bg-border flex items-center justify-center text-xs`,children:m.charAt(0)||"-"});let p=(e=>{let t;if(!e||(0,a.isExternalAssetSrc)(e)||!l.test(e))return;let r=e.split(/[?#]/)[0].split("/").pop()||void 0,i=void 0===r||(t=r.split(".")).length<2?void 0:`${t[0]}.${t[t.length-1]}`;return void 0===i?void 0:n[i]})(g);return(0,t.jsx)("img",{src:g,alt:`${m||"-"} logo`,className:void 0===p?d:(0,s.cn)(d,o[p]),onError:()=>{console.warn(`Logo failed to load: ${g}`),h(g)}})}],174553)},531278,e=>{"use strict";var t=e.i(717521);e.s(["Loader2",()=>t.default])},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},871689,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeft",()=>t.default])},195116,e=>{"use strict";let t=(0,e.i(475254).default)("wrench",[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z",key:"cbrjhi"}]]);e.s(["Wrench",0,t],195116)},269638,e=>{"use strict";let t=(0,e.i(475254).default)("circle-check-big",[["path",{d:"M21.801 10A10 10 0 1 1 17 3.335",key:"yps3ct"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]]);e.s(["CheckCircle",0,t],269638)},292335,122520,165615,779129,280024,e=>{"use strict";let t={NONE:"none",API_KEY:"api_key",BEARER_TOKEN:"bearer_token",TOKEN:"token",BASIC:"basic",OAUTH2:"oauth2",OAUTH2_TOKEN_EXCHANGE:"oauth2_token_exchange",OAUTH2_ID_JAG:"oauth2_id_jag",AWS_SIGV4:"aws_sigv4",TRUE_PASSTHROUGH:"true_passthrough",OAUTH_DELEGATE:"oauth_delegate"},r=[{value:t.NONE,label:"None"},{value:t.API_KEY,label:"API Key"},{value:t.BEARER_TOKEN,label:"Bearer Token"},{value:t.TOKEN,label:"Token"},{value:t.BASIC,label:"Basic Auth"},{value:t.OAUTH2,label:"OAuth"},{value:t.OAUTH2_TOKEN_EXCHANGE,label:"OAuth Token Exchange (OBO)"},{value:t.OAUTH2_ID_JAG,label:"ID-JAG (Okta Cross App Access)"},{value:t.AWS_SIGV4,label:"AWS SigV4 (Bedrock AgentCore MCPs)"},{value:t.TRUE_PASSTHROUGH,label:"True Passthrough (no LiteLLM auth)"},{value:t.OAUTH_DELEGATE,label:"OAuth Delegate (client-supplied upstream token)"}],i=e=>e===t.TRUE_PASSTHROUGH||e===t.OAUTH_DELEGATE,a={INTERACTIVE:"interactive",M2M:"m2m"},s=e=>{let t=e.credentials??{};return JSON.stringify({url:"string"==typeof e.url?e.url:null,spec_path:"string"==typeof e.spec_path?e.spec_path:null,auth_type:e.auth_type??null,oauth_flow_type:e.oauth_flow_type??null,client_id:t.client_id??null,client_secret:t.client_secret??null,scopes:t.scopes??null,upstream_resource:t.upstream_resource??null,issuer:e.issuer??null,authorization_url:e.authorization_url??null,token_url:e.token_url??null,registration_url:e.registration_url??null})},l=["client_id","client_secret"],n=["upstream_resource","upstream_token_header"],o=["access_token","refresh_token","expires_in","scope"],A=(e,t)=>{if(!e)return;let r=Object.fromEntries(t.filter(t=>"string"==typeof e[t]&&""!==e[t]).map(t=>[t,e[t]]));return Object.keys(r).length>0?r:void 0},c="client_credentials",d={SSE:"sse",HTTP:"http",STDIO:"stdio",OPENAPI:"openapi"},u=[{value:d.HTTP,label:"Streamable HTTP (Recommended)"},{value:d.SSE,label:"Server-Sent Events (SSE)"},{value:d.STDIO,label:"Standard Input/Output (stdio)"},{value:d.OPENAPI,label:"OpenAPI Spec"}];e.s(["ADMIN_CONFIG_CREDENTIAL_KEYS",0,n,"AUTH_TYPE",0,t,"AUTH_TYPE_ITEMS",0,r,"CLEARED_ON_INVALIDATION",0,["credentials"],"MCP_OAUTH2_FLOW_INTERACTIVE",0,"authorization_code","MCP_OAUTH2_FLOW_M2M",0,c,"OAUTH_FLOW",0,a,"TRANSPORT",0,d,"TRANSPORT_ITEMS",0,u,"credentialAuthClass",0,e=>e===t.TRUE_PASSTHROUGH||e===t.OAUTH_DELEGATE?"client_forwarded":e??null,"gatewayMintsClientFor",0,e=>e.auth_type===t.TRUE_PASSTHROUGH||e.auth_type===t.OAUTH_DELEGATE&&!e.dcr_bridge,"getMcpOAuthMode",0,function(e){return e.auth_type===t.OAUTH2_TOKEN_EXCHANGE?"token_exchange":e.auth_type!==t.OAUTH2?null:e.oauth2_flow===c?"m2m":e.delegate_auth_to_upstream?"passthrough":"authorization_code"},"getOAuthAuthorizationIdentity",0,s,"handleAuth",0,e=>null==e?t.NONE:e,"handleTransport",0,(e,t)=>null==e?d.SSE:t&&e!==d.STDIO?d.OPENAPI:e,"isClientForwardedTokenMode",0,i,"isHeldOAuthTokenStale",0,(e,t)=>void 0!==t&&s(e)!==t,"isUnsupportedOnGatewayConnect",0,e=>i(e)||e===t.OAUTH2_TOKEN_EXCHANGE,"oauth2FlowToFormValue",0,function(e){return e===c?a.M2M:e?a.INTERACTIVE:void 0},"preservedAdminCredentials",0,e=>A(e,[...l,...n]),"preservedDeclaredAppCredentials",0,e=>A(e,l),"withoutMintedTokenCredentials",0,e=>{if(!e)return;let t=Object.fromEntries(Object.entries(e).filter(([e])=>!o.includes(e)));return Object.keys(t).length>0?t:void 0}],292335);var h=e.i(271645),g=e.i(602869),m=e.i(417385);function p(e){if(e instanceof Error)return e.message;if(e&&"object"==typeof e){let t=e.detail;return"string"==typeof t?t:Array.isArray(t)?t.map(e=>e&&"object"==typeof e?"string"==typeof e.msg?e.msg:JSON.stringify(e):String(e)).join("; "):t&&"object"==typeof t&&"string"==typeof t.error?t.error:"string"==typeof e.message?e.message:JSON.stringify(e)}return String(e)}e.s(["extractErrorMessage",0,p],122520);let f=e=>{let t=new Uint8Array(e),r="";return t.forEach(e=>r+=String.fromCharCode(e)),btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},x=()=>{let e=new Uint8Array(32);return window.crypto.getRandomValues(e),f(e.buffer)},b=async e=>{let t=new TextEncoder().encode(e);return f(await window.crypto.subtle.digest("SHA-256",t))};e.s(["generateCodeChallenge",0,b,"generateCodeVerifier",0,x],165615);var v=e.i(434166);let _=()=>{{let e=window.location.pathname||"",t=e.indexOf("/ui"),r=t>=0?e.slice(0,t+3).replace(/\/+$/,""):"";return`${window.location.origin}${r}/mcp/oauth/callback`}},E=(...e)=>{e.forEach(e=>{try{window.sessionStorage.removeItem(e)}catch(e){}})};e.s(["TOOLS_OAUTH_UI_STATE_KEY",0,"litellm-mcp-oauth-tools-state","buildCallbackUrl",0,_,"clearStorage",0,E],779129);let w="litellm-user-mcp-oauth-flow-state",I="litellm-user-mcp-oauth-result",C=(e,t)=>{(0,v.setSecureItem)(e,t)},O=e=>(0,v.getSecureItem)(e);e.s(["useUserMcpOAuthFlow",0,({accessToken:e,serverId:t,serverAlias:r,scopes:i,clientId:a,onSuccess:s})=>{let[l,n]=(0,h.useState)("idle"),[o,A]=(0,h.useState)(null),c=(0,h.useRef)(!1),d=(0,h.useCallback)(async()=>{try{let s;n("authorizing"),A(null);let l=a??void 0;if(!l)try{let i=await (0,g.registerMcpOAuthClient)(e,t,{client_name:r||t,grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"});l=i?.client_id,s=i?.client_secret}catch(e){}let o=x(),c=await b(o),d=crypto.randomUUID(),u=_(),h=i?.filter(e=>e.trim()).join(" "),m=(0,g.buildMcpOAuthAuthorizeUrl)({serverId:t,clientId:l,redirectUri:u,state:d,codeChallenge:c,scope:h}),p={state:d,codeVerifier:o,serverId:t,redirectUri:u,clientId:l,clientSecret:s,scopes:i};C(w,JSON.stringify(p));let f=new URL(window.location.href);f.searchParams.set("mcpOauthReturn","apps"),C("litellm-mcp-oauth-return-url",f.toString()),window.location.href=m}catch(t){let e=p(t);A(e),n("error"),m.toast.error(e)}},[e,t,r,i,a]),u=(0,h.useCallback)(async()=>{if(c.current)return;let r=O(I);if(!r)return;let i=O(w);if(!i)return;try{let e=JSON.parse(i);if(e.serverId&&e.serverId!==t)return}catch(e){}c.current=!0,E(I);let a=null,l=null;try{a=JSON.parse(r);let e=O(w);l=e?JSON.parse(e):null}catch(e){A("Failed to resume OAuth flow. Please retry."),n("error"),c.current=!1,E(w);return}try{if(!l?.state||!l.codeVerifier||!l.serverId)throw Error("OAuth session state was lost. Please retry.");if(!a?.state||a.state!==l.state)throw Error("OAuth state mismatch. Please retry.");if(a.error)throw Error(a.error_description||a.error);if(!a.code)throw Error("Authorization code missing in callback.");n("exchanging");let t=await (0,g.exchangeMcpOAuthToken)({serverId:l.serverId,code:a.code,clientId:l.clientId,clientSecret:l.clientSecret,codeVerifier:l.codeVerifier,redirectUri:l.redirectUri,accessToken:e});await (0,g.storeMCPOAuthUserCredential)(e,l.serverId,{access_token:t.access_token,refresh_token:t.refresh_token,expires_in:t.expires_in,scopes:l.scopes}),n("success"),A(null),m.toast.success("Connected successfully"),s()}catch(t){let e=p(t);A(e),n("error"),m.toast.error(e)}finally{E(w),setTimeout(()=>{c.current=!1},1e3)}},[e,t,s]);return(0,h.useEffect)(()=>{u()},[u]),{startOAuthFlow:d,status:l,error:o}}],280024)},21040,131913,e=>{"use strict";var t=e.i(843476),r=e.i(271645),i=e.i(266027),a=e.i(555436),s=e.i(871689),l=e.i(463059),n=e.i(195116),o=e.i(269638),A=e.i(531278),c=e.i(519455),d=e.i(793479),u=e.i(302747),h=e.i(677572),g=e.i(602869),m=e.i(292335),p=e.i(174553),f=e.i(417385),x=e.i(280024);let b=({server:e,accessToken:i,onConnect:a,variant:s="badge"})=>{let l=e.server_name??e.alias??e.server_id,{startOAuthFlow:n,status:o}=(0,x.useUserMcpOAuthFlow)({accessToken:i,serverId:e.server_id,serverAlias:l,onSuccess:(0,r.useCallback)(()=>a(e.server_id),[a,e.server_id])}),d="authorizing"===o||"exchanging"===o;return"button"===s?(0,t.jsxs)(c.Button,{onClick:n,disabled:d,className:"font-semibold h-[38px] min-w-[110px]",children:[d&&(0,t.jsx)(A.Loader2,{className:"h-4 w-4 animate-spin mr-1.5"}),d?"Connecting…":"Connect"]}):(0,t.jsx)("span",{onClick:e=>{e.stopPropagation(),d||n()},className:`text-[11px] font-semibold rounded-md px-2 py-0.5 shrink-0 whitespace-nowrap ${d?"text-muted-foreground bg-muted cursor-default":"text-primary-foreground bg-primary cursor-pointer hover:bg-primary/90"}`,children:d?"Connecting…":"Connect"})},v=["#1677ff","#52c41a","#fa8c16","#eb2f96","#722ed1","#13c2c2","#fa541c","#2f54eb","#a0d911","#faad14"];function _(e){let t=0;for(let r=0;r{let[w,I]=(0,r.useState)([]),[C,O]=(0,r.useState)(!0),[T,k]=(0,r.useState)(""),[N,y]=(0,r.useState)("all"),[S,R]=(0,r.useState)(new Set),[L,U]=(0,r.useState)(null),[H,M]=(0,r.useState)({}),[B,j]=(0,r.useState)(!1),[D,P]=(0,r.useState)(new Set),[q,G]=(0,r.useState)(new Set),W=(0,r.useRef)([]),z=(0,r.useCallback)(e=>{W.current=e,I(e)},[]),F=(0,r.useRef)(x);(0,r.useEffect)(()=>{F.current=x},[x]);let V=(0,r.useRef)(v);(0,r.useEffect)(()=>{V.current=v},[v]);let Q=e=>e.server_name??e.alias??e.server_id,K=w.find(e=>e.server_id===L),Y=(0,r.useCallback)(e=>E&&(0,m.isUnsupportedOnGatewayConnect)(e.auth_type)?"Not supported on this connection":null,[E]),J=(0,r.useCallback)(e=>{let t=W.current.find(t=>t.server_id===e);return void 0!==t&&null===Y(t)?t:void 0},[Y]),X=(0,r.useCallback)(async(t,r)=>{try{let i=await (0,g.listMCPTools)(e,t.server_id);if(!r())return;let a=Array.isArray(i?.tools)?i.tools:[];M(e=>({...e,[Q(t)]:a.length}))}catch{}},[e]),Z=(0,r.useCallback)(async(t,r)=>{try{let i=await (0,g.getMCPOAuthUserCredentialStatus)(e,t.server_id);if(!r())return;i.has_credential&&!i.is_expired&&P(e=>new Set(e).add(t.server_id))}catch{}finally{r()&&G(e=>{let r=new Set(e);return r.delete(t.server_id),r})}},[e]);(0,r.useEffect)(()=>{let t=!0,r=()=>t;return(0,g.fetchMCPServers)(e,void 0,E).then(async e=>{if(!r())return;let t=Array.isArray(e)?e:e?.data??[],i=E?t.filter(e=>!1!==e.connected_app_reachable):t,a=i.filter(e=>e.auth_type===m.AUTH_TYPE.OAUTH2);for(let e of(z(i),G(new Set(a.map(e=>e.server_id))),O(!1),a.forEach(e=>Z(e,r)),j(!0),Array.from({length:Math.ceil(i.length/5)},(e,t)=>i.slice(5*t,(t+1)*5)))){if(!r())return;await Promise.allSettled(e.map(e=>X(e,r)))}r()&&j(!1)}).catch(()=>{r()&&(z([]),O(!1))}),()=>{t=!1}},[e,E,z,X,Z]),(0,r.useEffect)(()=>{if(0===D.size)return;let e=W.current.filter(e=>D.has(e.server_id)&&!F.current.includes(Q(e))&&null===Y(e)).map(Q);e.length>0&&V.current([...F.current,...e])},[D,Y]);let $=async(t,r)=>{let i=Q(t);if(!r){v(x.filter(e=>e!==i)),P(e=>{let r=new Set(e);return r.delete(t.server_id),r});return}if(void 0!==J(t.server_id)){R(e=>new Set(e).add(i));try{let r=await (0,g.listMCPTools)(e,t.server_id);if(r?.error)return void f.toast.warning(`Could not load tools for ${i}`);if(void 0===J(t.server_id))return;F.current.includes(i)||v([...F.current,i])}catch{f.toast.warning(`Could not load tools for ${i}`)}finally{R(e=>{let t=new Set(e);return t.delete(i),t})}}},{data:ee,isLoading:et}=(0,i.useQuery)({queryKey:["mcp-apps-panel-detail-tools",K?.server_id],queryFn:()=>(0,g.listMCPTools)(e,K.server_id),enabled:!!K}),er=Array.isArray(ee?.tools)?ee.tools:[],ei=w.filter(e=>{let t=Q(e),r=!T.trim()||t.toLowerCase().includes(T.toLowerCase())||(e.description??"").toLowerCase().includes(T.toLowerCase()),i="all"===N||x.includes(t)&&null===Y(e);return r&&i}),ea=w.filter(e=>x.includes(Q(e))&&null===Y(e)).length,es=Object.values(H).reduce((e,t)=>e+t,0);if(K){let r,i=Q(K),a=x.includes(i),l=S.has(i),o=_(i);return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)(c.Button,{variant:"ghost",size:"sm",onClick:()=>U(null),className:"-ml-3 mb-5 gap-1.5 text-muted-foreground hover:text-foreground",children:[(0,t.jsx)(s.ArrowLeft,{className:"h-3 w-3"}),"Back"]}),(0,t.jsxs)("div",{className:"flex items-start gap-5 mb-7",children:[K.mcp_info?.logo_url?(0,t.jsx)(p.Logo,{src:K.mcp_info.logo_url,label:i,className:"w-16 h-16 rounded-2xl object-contain shrink-0 bg-muted/50"}):(0,t.jsx)("div",{className:"w-16 h-16 rounded-2xl flex items-center justify-center text-white font-bold text-[28px] shrink-0",style:{background:o},children:i.charAt(0).toUpperCase()}),(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("h2",{className:"m-0 mb-1 text-[22px] font-bold text-foreground",children:i}),(0,t.jsx)("p",{className:"m-0 text-sm text-muted-foreground",children:K.description??"MCP server"})]}),null!==(r=Y(K))?(0,t.jsx)("span",{className:"text-[13px] text-muted-foreground py-2.5 shrink-0",children:r}):K.auth_type!==m.AUTH_TYPE.OAUTH2?(0,t.jsxs)(c.Button,{variant:a?"outline":"default",disabled:l,onClick:()=>$(K,!a),className:"font-semibold h-[38px] min-w-[110px]",children:[l&&(0,t.jsx)(A.Loader2,{className:"h-4 w-4 animate-spin mr-1.5"}),a?"Disconnect":"Connect"]}):D.has(K.server_id)?(0,t.jsx)(c.Button,{variant:"destructive",onClick:async()=>{try{await (0,g.deleteMCPOAuthUserCredential)(e,K.server_id)}catch(e){}P(e=>{let t=new Set(e);return t.delete(K.server_id),t}),V.current(F.current.filter(e=>e!==i))},className:"font-semibold h-[38px] min-w-[110px]",children:"Disconnect"}):(0,t.jsx)(b,{server:K,accessToken:e,onConnect:e=>{P(t=>new Set(t).add(e))},variant:"button"})]}),(0,t.jsx)("h3",{className:"m-0 mb-3 text-[15px] font-semibold text-foreground",children:"Information"}),(0,t.jsx)("div",{className:"border rounded-lg overflow-hidden mb-7",children:[["Server ID",K.server_id],["Transport",(0,m.handleTransport)(K.transport,K.spec_path)],["Status",a?"Connected":"Not connected"]].filter(([,e])=>e).map(([e,r],i,a)=>(0,t.jsxs)("div",{className:`flex px-4 py-3 text-[13px] ${i(0,t.jsxs)("div",{className:"border rounded-lg px-3.5 py-2.5 bg-muted/30 flex flex-col gap-1.5",children:[(0,t.jsx)(u.Skeleton,{className:"h-3.5 w-1/3"}),(0,t.jsx)(u.Skeleton,{className:"h-3 w-2/3"})]},r))}):0===er.length?(0,t.jsx)("div",{className:"text-muted-foreground text-[13px] py-2",children:"No tools available"}):(0,t.jsx)("div",{className:"flex flex-col gap-2",children:er.map(e=>(0,t.jsxs)("div",{className:"border rounded-lg px-3.5 py-2.5 bg-muted/30",children:[(0,t.jsxs)("div",{className:`flex items-center gap-2 ${e.description?"mb-1":""}`,children:[(0,t.jsx)(n.Wrench,{className:"h-3.5 w-3.5 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-[13px] font-semibold text-foreground font-mono",children:e.name})]}),e.description&&(0,t.jsx)("p",{className:"m-0 text-xs text-muted-foreground pl-[21px]",children:e.description})]},e.name))})]})}return(0,t.jsxs)("div",{className:"w-full",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between mb-5 gap-4 flex-wrap",children:[(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 mb-1",children:[(0,t.jsx)("h2",{className:"m-0 text-lg font-semibold text-foreground",children:"MCP Servers"}),!E&&(0,t.jsx)("span",{className:"text-[10px] font-semibold text-primary bg-primary/10 rounded px-1.5 py-0.5 uppercase tracking-wider",children:"Beta"})]}),E?(0,t.jsx)("p",{className:"m-0 text-[13px] text-muted-foreground",children:"Click a server to see its tools and connect"}):(0,t.jsxs)("div",{className:"flex items-center gap-3",children:[(0,t.jsx)("p",{className:"m-0 text-[13px] text-muted-foreground",children:"Browse tools, authenticate once, use in chat"}),B?(0,t.jsxs)("span",{className:"flex items-center gap-1.5 text-xs text-muted-foreground",children:[(0,t.jsx)(A.Loader2,{className:"h-3 w-3 animate-spin"}),"Loading tools..."]}):es>0?(0,t.jsxs)("span",{className:"flex items-center gap-1 text-xs text-muted-foreground",children:[(0,t.jsx)(n.Wrench,{className:"h-3 w-3"}),es," tool",1!==es?"s":""," available"]}):null]})]}),(0,t.jsxs)("div",{className:"relative w-[220px]",children:[(0,t.jsx)(a.Search,{className:"absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground"}),(0,t.jsx)(d.Input,{placeholder:"Search servers...",value:T,onChange:e=>k(e.target.value),className:"pl-9 text-[13px] h-9"})]})]}),(0,t.jsx)(h.Tabs,{value:N,onValueChange:e=>y(e),className:"mb-4",children:(0,t.jsxs)(h.TabsList,{variant:"line",className:"border-b rounded-none w-full justify-start h-auto p-0",children:[(0,t.jsx)(h.TabsTrigger,{value:"all",className:"rounded-none px-4 py-2 text-[13px]",children:"All"}),(0,t.jsxs)(h.TabsTrigger,{value:"connected",className:"rounded-none px-4 py-2 text-[13px]",children:["Connected",ea>0?` (${ea})`:""]})]})}),C?(0,t.jsx)("div",{className:"grid grid-cols-2 border rounded-lg overflow-hidden",children:Array.from({length:6},(e,r)=>(0,t.jsxs)("div",{className:`flex items-center gap-3 p-4 ${r%2==0?"border-r":""} ${r<4?"border-b":""}`,children:[(0,t.jsx)(u.Skeleton,{className:"w-[38px] h-[38px] rounded-xl shrink-0"}),(0,t.jsxs)("div",{className:"flex-1 min-w-0 flex flex-col gap-1.5",children:[(0,t.jsx)(u.Skeleton,{className:"h-3.5 w-2/3"}),(0,t.jsx)(u.Skeleton,{className:"h-3 w-1/2"})]})]},r))}):0===ei.length?(0,t.jsx)("div",{className:"text-center text-muted-foreground text-[13px] py-12 px-3",children:0===w.length?E?"No MCP servers are available to this connection yet. Ask an admin to grant your user or team access.":"No MCP servers configured. Add servers in Tools -> MCP Servers.":"connected"===N?"No servers connected yet.":"No servers match your search."}):(0,t.jsx)("div",{className:"grid grid-cols-2 border rounded-lg overflow-hidden",children:ei.map((r,i)=>{var a;let s,A=Q(r),c=_(A),d=H[A],h=null!==Y(r);return(0,t.jsxs)("div",{onClick:()=>U(r.server_id),className:`flex items-center gap-3 p-4 bg-card cursor-pointer transition-colors hover:bg-accent/30 min-w-0 ${i%2==0?"border-r":""} ${Math.floor(i/2)0?(0,t.jsxs)("span",{className:"shrink-0 flex items-center gap-1 text-muted-foreground",children:["· ",(0,t.jsx)(n.Wrench,{className:"h-2.5 w-2.5"})," ",d]}):null:B?(0,t.jsx)(u.Skeleton,{className:"w-7 h-3 shrink-0"}):null]})]}),null!==(s=Y(a=r))?(0,t.jsx)("span",{className:"text-[11px] text-muted-foreground shrink-0 whitespace-nowrap",children:s}):a.auth_type===m.AUTH_TYPE.OAUTH2?D.has(a.server_id)?(0,t.jsx)(o.CheckCircle,{className:"h-3.5 w-3.5 text-success shrink-0"}):q.has(a.server_id)?(0,t.jsx)(u.Skeleton,{className:"h-6 w-16 shrink-0 rounded-md"}):(0,t.jsx)(b,{server:a,accessToken:e,onConnect:e=>P(t=>new Set(t).add(e)),variant:"badge"}):x.includes(Q(a))?(0,t.jsx)("span",{className:"w-[7px] h-[7px] rounded-full bg-success shrink-0"}):null,(0,t.jsx)(l.ChevronRight,{className:"h-3 w-3 text-muted-foreground/40 shrink-0"})]},r.server_id)})})]})}],21040),e.s(["default",0,({flowHandle:e,clientOrigin:r})=>{let i=`${(0,g.getProxyBaseUrl)()}/authorize/complete`,a=r??"the application",s=function(e){if(!e)return!1;try{let t=new URL(e).hostname.replace(/^\[|\]$/g,"");return"localhost"===t||"::1"===t||/^127(\.\d{1,3}){3}$/.test(t)}catch{return!1}}(r);return(0,t.jsx)("div",{className:"mb-6 rounded-lg border border-primary/30 bg-primary/5 px-5 py-4",children:(0,t.jsxs)("div",{className:"flex items-start justify-between gap-4 flex-wrap",children:[(0,t.jsxs)("div",{className:"flex items-start gap-3 min-w-0",children:[(0,t.jsx)(o.CheckCircle,{className:"h-5 w-5 text-primary shrink-0 mt-0.5"}),(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsxs)("p",{className:"text-sm font-semibold text-foreground",children:["Connect your MCP servers to ",a]}),(0,t.jsxs)("p",{className:"text-[13px] text-muted-foreground mt-0.5",children:["Authorize the servers you want to use below, then click Finish connecting to return to ",a,"."]})]})]}),(0,t.jsxs)("form",{method:"POST",action:i,className:"shrink-0",children:[(0,t.jsx)("input",{type:"hidden",name:"flow",value:e}),(0,t.jsx)("button",{type:"submit",className:"h-[38px] rounded-md bg-primary px-4 text-sm font-semibold text-primary-foreground hover:bg-primary/90",children:"Finish connecting"}),s&&(0,t.jsxs)("label",{className:"mt-2 flex items-center gap-2 text-[13px] text-muted-foreground",children:[(0,t.jsx)("input",{type:"checkbox",name:"delivery",value:"manual"}),"My client is on a remote or SSH machine"]})]})]})})}],131913)},178971,e=>{"use strict";var t=e.i(843476),r=e.i(271645),i=e.i(618566),a=e.i(135214),s=e.i(21040),l=e.i(131913);function n(){let{accessToken:e}=(0,a.default)(),[n,o]=(0,r.useState)([]),A=(0,i.useRouter)(),c=(0,i.useSearchParams)(),d=c.get("mcpOauthReturn"),u=c.get("connect_flow"),h=c.get("connect_client");return(0,r.useEffect)(()=>{if(d){let e=new URL(window.location.href);e.searchParams.delete("mcpOauthReturn"),A.replace(e.pathname+e.search)}},[d,A]),(0,t.jsxs)("div",{className:"mx-auto w-full max-w-5xl px-8 py-8",children:[u&&(0,t.jsx)(l.default,{flowHandle:u,clientOrigin:h}),(0,t.jsx)(s.default,{accessToken:e??"",selectedServers:n,onChange:o,connectMode:!!u})]})}e.s(["default",0,function(){return(0,t.jsx)(r.Suspense,{children:(0,t.jsx)(n,{})})}])}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0a3n_ovfo3c5s.js b/litellm/proxy/_experimental/out/_next/static/chunks/0a3n_ovfo3c5s.js
deleted file mode 100644
index 87e0597ea93..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/0a3n_ovfo3c5s.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,372024,e=>{"use strict";var t=e.i(843476),a=e.i(271645),s=e.i(653145),r=e.i(542450),l=e.i(519455),n=e.i(515288),i=e.i(131792),o=e.i(776639),c=e.i(793479),d=e.i(699375),u=e.i(784774),m=e.i(677572),h=e.i(950594),x=e.i(286536),g=e.i(77705),p=e.i(417385),j=e.i(602869),f=e.i(257428),b=e.i(772436),C=e.i(302747);let y=({accessToken:e})=>{let[s,r]=(0,a.useState)(!0),[i,o]=(0,a.useState)([]);(0,a.useEffect)(()=>{c()},[e]);let c=async()=>{if(e){r(!0);try{let t=await (0,j.getEmailEventSettings)(e);o(t.settings)}catch(e){console.error("Failed to fetch email event settings:",e),p.toast.fromError(e)}finally{r(!1)}}},d=async()=>{if(e)try{await (0,j.updateEmailEventSettings)(e,{settings:i}),p.toast.success("Email event settings updated successfully")}catch(e){console.error("Failed to update email event settings:",e),p.toast.fromError(e)}},u=async()=>{if(e)try{await (0,j.resetEmailEventSettings)(e),p.toast.success("Email event settings reset to defaults"),c()}catch(e){console.error("Failed to reset email event settings:",e),p.toast.fromError(e)}};return(0,t.jsxs)(n.Card,{children:[(0,t.jsxs)(n.CardHeader,{children:[(0,t.jsx)(n.CardTitle,{className:"text-base",children:"Email Notifications"}),(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"Select which events should trigger email notifications."})]}),(0,t.jsxs)(n.CardContent,{children:[(0,t.jsx)(b.Separator,{className:"mb-6"}),s?(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)(C.Skeleton,{className:"h-10 w-full"}),(0,t.jsx)(C.Skeleton,{className:"h-10 w-full"})]}):(0,t.jsx)("div",{className:"space-y-4",children:i.map(e=>(0,t.jsxs)("div",{className:"flex items-start",children:[(0,t.jsx)(f.Checkbox,{checked:e.enabled,onCheckedChange:t=>{var a,s;return a=e.event,s=!0===t,void o(i.map(e=>e.event===a?{...e,enabled:s}:e))},className:"mt-1"}),(0,t.jsxs)("div",{className:"ml-3",children:[(0,t.jsx)("p",{className:"text-sm",children:e.event}),(0,t.jsx)("div",{className:"block text-sm text-muted-foreground",children:(e=>{if(e.includes("Virtual Key Created"))return"An email will be sent to the user when a new virtual key is created with their user ID";{if(e.includes("New User Invitation"))return"An email will be sent to the email address of the user when a new user is created";let t=e.split(/(?=[A-Z])/).join(" ").toLowerCase();return`Receive an email notification when ${t}`}})(e.event)})]})]},e.event))}),(0,t.jsxs)("div",{className:"mt-6 flex gap-4",children:[(0,t.jsx)(l.Button,{onClick:d,disabled:s,children:"Save Changes"}),(0,t.jsx)(l.Button,{variant:"secondary",onClick:u,disabled:s,children:"Reset to Defaults"})]})]})]})},k=(0,t.jsx)("span",{className:"text-destructive",children:" Required * "}),v={SMTP_HOST:(0,t.jsxs)(t.Fragment,{children:["Enter the SMTP host address, e.g. `smtp.resend.com`",k]}),SMTP_PORT:(0,t.jsxs)(t.Fragment,{children:["Enter the SMTP port number, e.g. `587`",k]}),SMTP_USERNAME:(0,t.jsxs)(t.Fragment,{children:["Enter the SMTP username, e.g. `username`",k]}),SMTP_PASSWORD:k,SMTP_SENDER_EMAIL:(0,t.jsxs)(t.Fragment,{children:["Enter the sender email address, e.g. `sender@berri.ai`",k]}),TEST_EMAIL_ADDRESS:(0,t.jsxs)(t.Fragment,{children:["Email Address to send `Test Email Alert` to. example: `info@berri.ai`",k]}),EMAIL_LOGO_URL:(0,t.jsx)(t.Fragment,{children:"(Optional) Customize the Logo that appears in the email, pass a url to your logo"}),EMAIL_SUPPORT_CONTACT:(0,t.jsx)(t.Fragment,{children:"(Optional) Customize the support email address that appears in the email. Default is support@berri.ai"})},T=["EMAIL_LOGO_URL","EMAIL_SUPPORT_CONTACT"],w=/(PASSWORD|SECRET|KEY|TOKEN)/i,_=({accessToken:e,premiumUser:s,alerts:r})=>{let[i,o]=(0,a.useState)({}),c=async()=>{if(!e)return;let t={};r.filter(e=>"email"===e.name).forEach(e=>{Object.entries(e.variables??{}).forEach(([e,a])=>{let s=document.querySelector(`input[name="${e}"]`);s&&s.value&&s.value!==(null==a?"":String(a))&&(t[e]=s.value)})});try{await (0,j.setCallbacksCall)(e,{general_settings:{alerting:["email"]},environment_variables:t}),p.toast.success("Email settings updated successfully")}catch(e){p.toast.fromError(e)}};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{className:"mt-6 mb-6",children:(0,t.jsx)(y,{accessToken:e})}),(0,t.jsxs)(n.Card,{children:[(0,t.jsxs)(n.CardHeader,{children:[(0,t.jsx)(n.CardTitle,{className:"text-base",children:"Email Server Settings"}),(0,t.jsx)("p",{className:"text-sm",children:(0,t.jsx)("a",{href:"https://docs.litellm.ai/docs/proxy/email",target:"_blank",rel:"noreferrer",className:"text-primary underline underline-offset-4",children:"LiteLLM Docs: email alerts"})})]}),(0,t.jsxs)(n.CardContent,{children:[r.filter(e=>"email"===e.name).map((e,a)=>(0,t.jsx)("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2",children:Object.entries(e.variables??{}).map(([e,a])=>{let r=!s&&T.includes(e),l=w.test(e),n=i[e]||!1;return(0,t.jsxs)("div",{className:"space-y-1",children:[r?(0,t.jsxs)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",rel:"noreferrer",className:"text-sm text-primary underline underline-offset-4",children:["✨ ",e]}):(0,t.jsx)("p",{className:"text-sm",children:e}),(0,t.jsxs)(h.InputGroup,{className:"max-w-100",children:[(0,t.jsx)(h.InputGroupInput,{name:e,defaultValue:a,type:l&&!n?"password":"text",disabled:r}),l&&(0,t.jsx)(h.InputGroupAddon,{align:"inline-end",children:(0,t.jsx)(h.InputGroupButton,{size:"icon-xs",onClick:()=>{o(t=>({...t,[e]:!t[e]}))},"aria-label":n?"Hide credential":"Show credential",children:n?(0,t.jsx)(g.EyeOff,{}):(0,t.jsx)(x.Eye,{})})})]}),(0,t.jsx)("div",{className:"text-xs text-muted-foreground italic",children:v[e]})]},e)})},a)),(0,t.jsxs)("div",{className:"mt-6 flex gap-2",children:[(0,t.jsx)(l.Button,{onClick:()=>c(),children:"Save Changes"}),(0,t.jsx)(l.Button,{variant:"secondary",onClick:async()=>{if(e)try{await (0,j.serviceHealthCheck)(e,"email"),p.toast.success("Email test triggered. Check your configured email inbox/logs.")}catch(e){p.toast.fromError(e)}},children:"Test Email Alerts"})]})]})]})]})},S={MS_TEAMS_WEBHOOK_URL:(0,t.jsxs)(t.Fragment,{children:["Incoming webhook URL for your Teams channel (Workflows or incoming webhook connector)",(0,t.jsx)("span",{className:"text-destructive",children:" Required * "})]})},N=/(PASSWORD|SECRET|KEY|TOKEN|URL)/i,E=({accessToken:e,userID:s,userRole:r,alerts:i})=>{let[o,c]=(0,a.useState)({}),d=async()=>{if(!e||!s||!r)return;let t=Object.fromEntries(i.filter(e=>"ms_teams"===e.name).flatMap(e=>Object.entries(e.variables??{}).flatMap(([e,t])=>{let a=document.querySelector(`input[name="${e}"]`);return a&&a.value&&a.value!==(null==t?"":String(t))?[[e,a.value]]:[]})));try{let a=(await (0,j.getCallbacksCall)(e,s,r)).active_alerting_destinations??[],l={general_settings:{alerting:Array.from(new Set([...a,"ms_teams"]))},environment_variables:t};await (0,j.setCallbacksCall)(e,l),p.toast.success("MS Teams settings updated successfully")}catch(e){p.toast.fromError(e)}};return(0,t.jsxs)(n.Card,{children:[(0,t.jsxs)(n.CardHeader,{children:[(0,t.jsx)(n.CardTitle,{className:"text-base",children:"Microsoft Teams Alerting Settings"}),(0,t.jsxs)("p",{className:"text-sm",children:["Send LiteLLM alerts to a Microsoft Teams channel via an incoming webhook. Create one from"," ",(0,t.jsx)("a",{href:"https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook",target:"_blank",rel:"noreferrer",className:"text-primary underline underline-offset-4",children:"Microsoft Docs: incoming webhooks"})]})]}),(0,t.jsxs)(n.CardContent,{children:[i.filter(e=>"ms_teams"===e.name).map((e,a)=>(0,t.jsx)("div",{className:"grid grid-cols-1 gap-4 sm:grid-cols-2",children:Object.entries(e.variables??{}).map(([e,a])=>{let s=N.test(e),r=o[e]||!1;return(0,t.jsxs)("div",{className:"space-y-1",children:[(0,t.jsx)("p",{className:"text-sm",children:e}),(0,t.jsxs)(h.InputGroup,{className:"max-w-100",children:[(0,t.jsx)(h.InputGroupInput,{name:e,defaultValue:a,type:s&&!r?"password":"text"}),s&&(0,t.jsx)(h.InputGroupAddon,{align:"inline-end",children:(0,t.jsx)(h.InputGroupButton,{size:"icon-xs",onClick:()=>{c(t=>({...t,[e]:!t[e]}))},"aria-label":r?"Hide credential":"Show credential",children:r?(0,t.jsx)(g.EyeOff,{}):(0,t.jsx)(x.Eye,{})})})]}),(0,t.jsx)("div",{className:"text-xs text-muted-foreground italic",children:S[e]})]},e)})},a)),(0,t.jsxs)("div",{className:"mt-6 flex gap-2",children:[(0,t.jsx)(l.Button,{onClick:()=>d(),children:"Save Changes"}),(0,t.jsx)(l.Button,{variant:"secondary",onClick:async()=>{if(e)try{await (0,j.serviceHealthCheck)(e,"ms_teams"),p.toast.success("MS Teams test alert triggered. Check your Teams channel.")}catch(e){p.toast.fromError(e)}},children:"Test MS Teams Alerts"})]})]})]})};var A=e.i(174553),F=e.i(101048),I=e.i(727612),D=e.i(487486);let L=({alertingSettings:e,handleInputChange:a,handleResetField:r,handleSubmit:n,premiumUser:i})=>{let o=(0,s.useForm)({defaultValues:{}});return(0,t.jsxs)("form",{onSubmit:o.handleSubmit(e=>{Object.entries(e).every(([,e])=>"boolean"!=typeof e&&(""===e||null==e))||n(e)}),noValidate:!0,children:[e.map((e,s)=>(0,t.jsxs)(u.TableRow,{children:[(0,t.jsxs)(u.TableCell,{children:[(0,t.jsx)("p",{className:"text-sm",children:e.field_name}),(0,t.jsx)("p",{className:"mt-1 text-[0.65rem] italic text-muted-foreground",children:e.field_description})]}),e.premium_field&&!i?(0,t.jsx)(u.TableCell,{children:(0,t.jsx)(l.Button,{className:"flex items-center justify-center",children:(0,t.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})})}):(0,t.jsx)(u.TableCell,{children:"Integer"===e.field_type?(0,t.jsx)(c.Input,{type:"number",step:1,value:e.field_value??"",onChange:t=>{var s;return s=t.target.value,void(o.setValue(e.field_name,s),a(e.field_name,""===s?null:Number(s)))}}):"Boolean"===e.field_type?(0,t.jsx)(d.Switch,{"aria-label":e.field_name,checked:e.field_value,onCheckedChange:t=>{o.setValue(e.field_name,t),a(e.field_name,t)}}):(0,t.jsx)(c.Input,{value:e.field_value??"",onChange:t=>{o.setValue(e.field_name,t.target.value),a(e.field_name,t)}})}),(0,t.jsx)(u.TableCell,{children:!0==e.stored_in_db?(0,t.jsxs)(D.Badge,{variant:"secondary",children:[(0,t.jsx)(F.CircleCheck,{}),"In DB"]}):!1==e.stored_in_db?(0,t.jsx)(D.Badge,{variant:"outline",children:"In Config"}):(0,t.jsx)(D.Badge,{variant:"outline",children:"Not Set"})}),(0,t.jsx)(u.TableCell,{children:(0,t.jsx)(l.Button,{type:"button",variant:"ghost",size:"icon-sm","aria-label":`Reset ${e.field_name}`,onClick:()=>r(e.field_name,s),className:"text-destructive",children:(0,t.jsx)(I.Trash2,{className:"size-5"})})})]},s)),(0,t.jsx)("div",{children:(0,t.jsx)(l.Button,{type:"submit",children:"Update Settings"})})]})},P=({accessToken:e,premiumUser:s})=>{let[r,l]=(0,a.useState)([]);return(0,a.useEffect)(()=>{e&&(0,j.alertingSettingsCall)(e).then(e=>{l(e)})},[e]),(0,t.jsx)(L,{alertingSettings:r,handleInputChange:(e,t)=>{l(r.map(a=>a.field_name===e?{...a,field_value:t}:a))},handleResetField:(t,a)=>{if(e)try{let e=r.map(e=>e.field_name===t?{...e,stored_in_db:null,field_value:e.field_default_value}:e);l(e)}catch(e){}},handleSubmit:t=>{if(!e||null==t||void 0==t)return;let a={};r.forEach(e=>{a[e.field_name]=e.field_value});let{slack_alerting:s,...l}={...t,...a};try{(0,j.updateConfigFieldSetting)(e,"alerting_args",l),"boolean"==typeof s&&(!0==s?(0,j.updateConfigFieldSetting)(e,"alerting",["slack"]):(0,j.updateConfigFieldSetting)(e,"alerting",[])),p.toast.success("Wait 10s for proxy to update.")}catch(e){}},premiumUser:s})};var z=e.i(954616),M=e.i(266027),O=e.i(912598),B=e.i(243652);let U=(0,B.createQueryKeys)("cloudZeroSettings"),R=async e=>{let t=(0,j.getProxyBaseUrl)(),a=t?`${t}/cloudzero/settings`:"/cloudzero/settings",s=await fetch(a,{method:"GET",headers:{[(0,j.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!s.ok){let e="Failed to fetch CloudZero settings";try{let t=await s.json();"object"==typeof t&&null!==t?e=t?.error?.message||t?.error||t?.message||t?.detail||("string"==typeof t?.error?t.error:e):"string"==typeof t&&(e=t)}catch{e=s.statusText||e}throw Error(e)}let r=await s.json();return r&&(r.api_key_masked||r.connection_id)?r:null},Z=async(e,t)=>{let a=(0,j.getProxyBaseUrl)(),s=a?`${a}/cloudzero/settings`:"/cloudzero/settings",r=await fetch(s,{method:"PUT",headers:{[(0,j.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({...t.connection_id&&{connection_id:t.connection_id},...t.timezone&&{timezone:t.timezone},...t.api_key&&{api_key:t.api_key}})});if(!r.ok){let e="Failed to update CloudZero settings";try{let t=await r.json();"object"==typeof t&&null!==t?e=t?.error?.message||t?.error||t?.message||t?.detail||("string"==typeof t?.error?t.error:e):"string"==typeof t&&(e=t)}catch{e=r.statusText||e}throw Error(e)}return await r.json()},H=async e=>{let t=(0,j.getProxyBaseUrl)(),a=t?`${t}/cloudzero/delete`:"/cloudzero/delete",s=await fetch(a,{method:"DELETE",headers:{[(0,j.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!s.ok){let e="Failed to delete CloudZero settings";try{let t=await s.json();"object"==typeof t&&null!==t?e=t?.error?.message||t?.error||t?.message||t?.detail||("string"==typeof t?.error?t.error:e):"string"==typeof t&&(e=t)}catch{e=s.statusText||e}throw Error(e)}return await s.json()};var $=e.i(135214),G=e.i(332102);function q({startCreation:e}){return(0,t.jsx)("div",{className:"mx-auto mt-8 max-w-2xl rounded-lg border border-dashed border-border bg-card p-12 text-center",children:(0,t.jsxs)("div",{className:"flex flex-col items-center gap-2",children:[(0,t.jsx)(G.Inbox,{className:"size-10 text-muted-foreground","aria-hidden":!0}),(0,t.jsx)("h4",{className:"text-base font-semibold",children:"No CloudZero Integration Found"}),(0,t.jsx)("p",{className:"mx-auto max-w-md text-sm text-muted-foreground",children:"Connect your CloudZero account to start tracking and analyzing your cloud costs directly from LiteLLM."}),(0,t.jsx)(l.Button,{size:"lg",onClick:e,className:"mt-4",children:"Add CloudZero Integration"})]})})}var K=e.i(681307);let W=async(e,t)=>{let a=(0,j.getProxyBaseUrl)(),s=a?`${a}/cloudzero/init`:"/cloudzero/init",r=await fetch(s,{method:"POST",headers:{[(0,j.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({connection_id:t.connection_id,timezone:t.timezone??"UTC",...t.api_key&&{api_key:t.api_key}})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e?.error?.message||e?.message||e?.detail||"Failed to create CloudZero integration")}return await r.json()};var V=e.i(182668),Q=e.i(746798),J=e.i(991326),Y=e.i(359360);let X=(e,a)=>(0,t.jsxs)(t.Fragment,{children:[e,(0,t.jsxs)(Q.Tooltip,{children:[(0,t.jsx)(Q.TooltipTrigger,{render:(0,t.jsx)(Y.CircleHelp,{className:"size-3.5 shrink-0 cursor-help text-muted-foreground"})}),(0,t.jsx)(Q.TooltipContent,{children:a})]})]}),ee=a.forwardRef(({className:e,...s},r)=>{let[l,n]=a.useState(!1);return(0,t.jsxs)(h.InputGroup,{className:e,children:[(0,t.jsx)(h.InputGroupInput,{...s,ref:r,type:l?"text":"password"}),(0,t.jsx)(h.InputGroupAddon,{align:"inline-end",children:(0,t.jsx)(h.InputGroupButton,{size:"icon-xs",variant:"ghost","aria-label":l?"Hide API key":"Show API key",onClick:()=>n(e=>!e),children:l?(0,t.jsx)(g.EyeOff,{}):(0,t.jsx)(x.Eye,{})})})]})});ee.displayName="CloudZeroApiKeyInput";let et={api_key:"",connection_id:"",timezone:""},ea=e=>({connection_id:e.connection_id,timezone:e.timezone||"UTC",...e.api_key&&{api_key:e.api_key}}),es=K.z.object({api_key:K.z.string().min(1,"Please enter your CloudZero API key"),connection_id:K.z.string().min(1,"Please enter your CloudZero connection ID"),timezone:K.z.string()});function er({open:e,onOk:s,onCancel:n}){let i,{accessToken:d}=(0,$.default)(),u=(0,J.useZodForm)(es,{defaultValues:et}),m=(i=d||"",(0,z.useMutation)({mutationFn:async e=>{if(!i)throw Error("Access token is required");return await W(i,e)}}));(0,a.useEffect)(()=>{e&&u.reset(et)},[e,u]);let h=e=>{m.mutate(ea(e),{onSuccess:()=>{p.toast.success("CloudZero integration created successfully"),u.reset(et),s()},onError:e=>{p.toast.error(e.message||"Failed to create CloudZero integration")}})},x=()=>{u.reset(et),n()};return(0,t.jsx)(o.Dialog,{open:e,onOpenChange:e=>!e&&x(),children:(0,t.jsxs)(o.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto",children:[(0,t.jsx)(o.DialogHeader,{children:(0,t.jsx)(o.DialogTitle,{children:"Create CloudZero Integration"})}),(0,t.jsx)(Q.TooltipProvider,{children:(0,t.jsx)("form",{onSubmit:e=>e.preventDefault(),noValidate:!0,children:(0,t.jsxs)(r.FieldGroup,{children:[(0,t.jsx)(V.FormField,{control:u.control,name:"api_key",label:"CloudZero API Key",children:({ref:e,...a})=>(0,t.jsx)(ee,{...a,ref:e,placeholder:"Enter your CloudZero API key"})}),(0,t.jsx)(V.FormField,{control:u.control,name:"connection_id",label:"Connection ID",children:({ref:e,...a})=>(0,t.jsx)(c.Input,{...a,ref:e,placeholder:"Enter your CloudZero connection ID"})}),(0,t.jsx)(V.FormField,{control:u.control,name:"timezone",label:X("Timezone","Timezone for date handling (defaults to UTC if not provided)"),children:({ref:e,...a})=>(0,t.jsx)(c.Input,{...a,ref:e,placeholder:"UTC"})})]})})}),(0,t.jsxs)(o.DialogFooter,{children:[(0,t.jsx)(l.Button,{variant:"outline",onClick:x,disabled:m.isPending,children:"Cancel"}),(0,t.jsx)(l.Button,{onClick:()=>void u.handleSubmit(h)(),disabled:m.isPending,"aria-busy":m.isPending,children:m.isPending?"Creating...":"Create"})]})]})})}let el=async(e,t={})=>{let a=(0,j.getProxyBaseUrl)(),s=a?`${a}/cloudzero/dry-run`:"/cloudzero/dry-run",r=await fetch(s,{method:"POST",headers:{[(0,j.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({limit:t.limit??10})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e?.error?.message||e?.message||e?.detail||"Failed to perform dry run")}return await r.json()},en=async(e,t={})=>{let a=(0,j.getProxyBaseUrl)(),s=a?`${a}/cloudzero/export`:"/cloudzero/export",r=await fetch(s,{method:"POST",headers:{[(0,j.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({operation:t.operation??"replace_hourly"})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e?.error?.message||e?.message||e?.detail||"Failed to export data")}return await r.json()};var ei=e.i(127952),eo=e.i(204290),ec=e.i(929592),ed=e.i(868499),eu=e.i(269638),em=e.i(788699),eh=e.i(431343),ex=e.i(569074);let eg=K.z.object({api_key:K.z.string(),connection_id:K.z.string().min(1,"Please enter your CloudZero connection ID"),timezone:K.z.string()});function ep({open:e,onOk:s,onCancel:n,settings:i}){var d;let u,{accessToken:m}=(0,$.default)(),h=(0,J.useZodForm)(eg,{defaultValues:et}),x=(d=m||"",u=(0,O.useQueryClient)(),(0,z.useMutation)({mutationFn:async e=>{if(!d)throw Error("Access token is required");return await Z(d,e)},onSuccess:()=>{u.invalidateQueries({queryKey:U.list({})})}}));(0,a.useEffect)(()=>{e&&i?h.reset({connection_id:i.connection_id??"",timezone:i.timezone||"UTC",api_key:""}):e&&h.reset(et)},[e,i,h]);let g=e=>{x.mutate(ea(e),{onSuccess:()=>{p.toast.success("CloudZero integration updated successfully"),h.reset(et),s()},onError:e=>{p.toast.error(e.message||"Failed to update CloudZero integration")}})},j=()=>{h.reset(et),n()};return(0,t.jsx)(o.Dialog,{open:e,onOpenChange:e=>!e&&j(),children:(0,t.jsxs)(o.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto",children:[(0,t.jsx)(o.DialogHeader,{children:(0,t.jsx)(o.DialogTitle,{children:"Edit CloudZero Integration"})}),(0,t.jsx)(Q.TooltipProvider,{children:(0,t.jsx)("form",{onSubmit:e=>e.preventDefault(),noValidate:!0,children:(0,t.jsxs)(r.FieldGroup,{children:[(0,t.jsx)(V.FormField,{control:h.control,name:"api_key",label:X("CloudZero API Key","Leave empty to keep the existing API key"),children:({ref:e,...a})=>(0,t.jsx)(ee,{...a,ref:e,placeholder:"Leave empty to keep existing"})}),(0,t.jsx)(V.FormField,{control:h.control,name:"connection_id",label:"Connection ID",children:({ref:e,...a})=>(0,t.jsx)(c.Input,{...a,ref:e,placeholder:"Enter your CloudZero connection ID"})}),(0,t.jsx)(V.FormField,{control:h.control,name:"timezone",label:X("Timezone","Timezone for date handling (defaults to UTC if not provided)"),children:({ref:e,...a})=>(0,t.jsx)(c.Input,{...a,ref:e,placeholder:"UTC"})})]})})}),(0,t.jsxs)(o.DialogFooter,{children:[(0,t.jsx)(l.Button,{variant:"outline",onClick:j,disabled:x.isPending,children:"Cancel"}),(0,t.jsx)(l.Button,{onClick:()=>void h.handleSubmit(g)(),disabled:x.isPending,"aria-busy":x.isPending,children:x.isPending?"Updating...":"Update"})]})]})})}let ej=({label:e,children:a})=>(0,t.jsxs)("div",{className:"grid grid-cols-1 border-b border-border last:border-b-0 sm:grid-cols-[220px_minmax(0,1fr)]",children:[(0,t.jsx)("dt",{className:"bg-muted/50 px-4 py-3 text-sm font-medium",children:e}),(0,t.jsx)("dd",{className:"px-4 py-3 text-sm",children:a})]}),ef=()=>(0,t.jsx)("span",{className:"text-muted-foreground italic",children:"Not configured"});function eb({settings:e,onSettingsUpdated:s}){var r;let i,o,c,{accessToken:d}=(0,$.default)(),[u,m]=(0,a.useState)(!1),[h,x]=(0,a.useState)(!1),[g,j]=(0,a.useState)(!1),f=(i=d||"",(0,z.useMutation)({mutationFn:async(e={})=>{if(!i)throw Error("Access token is required");return await el(i,e)}})),C=(o=d||"",(0,z.useMutation)({mutationFn:async(e={})=>{if(!o)throw Error("Access token is required");return await en(o,e)}})),y=(r=d||"",c=(0,O.useQueryClient)(),(0,z.useMutation)({mutationFn:async()=>{if(!r)throw Error("Access token is required");return await H(r)},onSuccess:()=>{c.invalidateQueries({queryKey:U.list({})})}})),k=f.data?JSON.stringify(f.data,null,2):null,v=async()=>{m(!1),s()};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("div",{className:"mx-auto w-full max-w-4xl space-y-6",children:(0,t.jsxs)(n.Card,{children:[(0,t.jsxs)(n.CardHeader,{children:[(0,t.jsxs)(n.CardTitle,{className:"flex items-center gap-2 text-lg",children:["CloudZero Configuration",(0,t.jsx)(D.Badge,{variant:"secondary",className:"capitalize",children:e.status||"Active"})]}),(0,t.jsxs)(n.CardAction,{className:"flex gap-2",children:[(0,t.jsxs)(l.Button,{variant:"outline",onClick:()=>{m(!0)},children:[(0,t.jsx)(em.Pencil,{}),"Edit"]}),(0,t.jsxs)(l.Button,{variant:"destructive",onClick:()=>{x(!0)},children:[(0,t.jsx)(I.Trash2,{}),"Delete"]})]})]}),(0,t.jsxs)(n.CardContent,{children:[(0,t.jsxs)("dl",{className:"rounded-md border border-border",children:[(0,t.jsx)(ej,{label:"API Key (Redacted)",children:(0,t.jsx)("span",{className:"font-mono",children:e.api_key_masked||(0,t.jsx)(ef,{})})}),(0,t.jsx)(ej,{label:"Connection ID",children:(0,t.jsx)("span",{className:"font-mono",children:e.connection_id||(0,t.jsx)(ef,{})})}),(0,t.jsx)(ej,{label:"Timezone",children:e.timezone||(0,t.jsx)("span",{className:"text-muted-foreground italic",children:"Default (UTC)"})})]}),(0,t.jsxs)("div",{className:"mt-6 flex items-center gap-3",children:[(0,t.jsx)("span",{className:"text-sm text-muted-foreground",children:"Actions"}),(0,t.jsx)(b.Separator,{className:"flex-1"})]}),(0,t.jsxs)("div",{className:"mt-4 mb-6 flex flex-wrap gap-4",children:[(0,t.jsxs)(l.Button,{variant:"outline",onClick:()=>{d&&f.mutate({limit:10},{onSuccess:e=>{p.toast.success("Dry run completed successfully")},onError:e=>{p.toast.error(e?.message||"Failed to perform dry run")}})},disabled:f.isPending,children:[(0,t.jsx)(eh.Play,{}),"Run Dry Run Simulation"]}),(0,t.jsxs)(l.Button,{onClick:()=>j(!0),disabled:C.isPending,children:[(0,t.jsx)(ex.Upload,{}),"Export Data Now"]})]}),k&&(0,t.jsxs)(eo.Alert,{children:[(0,t.jsx)(eu.CheckCircle,{}),(0,t.jsx)(ec.AlertTitle,{children:"Dry Run Results"}),(0,t.jsxs)(ec.AlertDescription,{children:[(0,t.jsxs)("p",{children:["Simulation output for connection: ",e.connection_id]}),(0,t.jsx)("pre",{className:"overflow-x-auto rounded-md border border-border bg-muted p-4 font-mono text-xs text-foreground",children:k})]})]})]})]})}),(0,t.jsx)(ed.AlertDialog,{open:g,onOpenChange:j,children:(0,t.jsxs)(ed.AlertDialogContent,{children:[(0,t.jsxs)(ed.AlertDialogHeader,{children:[(0,t.jsx)(ed.AlertDialogTitle,{children:"Export Data to CloudZero"}),(0,t.jsx)(ed.AlertDialogDescription,{children:"This will push the current accumulated cost data to CloudZero. Continue?"})]}),(0,t.jsxs)(ed.AlertDialogFooter,{children:[(0,t.jsx)(ed.AlertDialogCancel,{disabled:C.isPending,children:"Cancel"}),(0,t.jsx)(l.Button,{onClick:()=>{d&&C.mutate({operation:"replace_hourly"},{onSuccess:()=>{p.toast.success("Data successfully exported to CloudZero"),j(!1)},onError:e=>{p.toast.error(e?.message||"Failed to export data")}})},disabled:C.isPending,children:"Export"})]})]})}),(0,t.jsx)(ep,{open:u,onOk:v,onCancel:()=>{m(!1)},settings:e}),(0,t.jsx)(ei.default,{isOpen:h,title:"Delete CloudZero Integration?",message:"Are you sure you want to delete this CloudZero integration? All associated settings and configurations will be permanently removed.",resourceInformationTitle:"Integration Details",resourceInformation:[{label:"Connection ID",value:e.connection_id,code:!0},{label:"Timezone",value:e.timezone||"Default (UTC)"}],onCancel:()=>{x(!1)},onOk:()=>{d&&y.mutate(void 0,{onSuccess:()=>{p.toast.success("CloudZero integration deleted successfully"),x(!1),s()},onError:e=>{p.toast.error(e?.message||"Failed to delete CloudZero integration")}})},confirmLoading:y.isPending})]})}function eC(){let{accessToken:e}=(0,$.default)(),{data:s,isLoading:r,error:l}=(0,M.useQuery)({queryKey:U.list({}),queryFn:async()=>await R(e),enabled:!!e,staleTime:36e5,gcTime:36e5}),i=(0,O.useQueryClient)(),o=(0,B.createQueryKeys)("cloudZeroSettings"),[c,d]=(0,a.useState)(!1),u=async()=>{d(!1),await i.invalidateQueries({queryKey:o.list({})})};return r?(0,t.jsx)(n.Card,{children:(0,t.jsx)(n.CardContent,{children:(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"Loading CloudZero settings..."})})}):l?(0,t.jsx)(n.Card,{children:(0,t.jsx)(n.CardContent,{children:(0,t.jsxs)("p",{className:"text-sm text-destructive",children:["Error loading CloudZero settings: ",l instanceof Error?l.message:String(l)]})})}):s?(0,t.jsx)(t.Fragment,{children:(0,t.jsx)(eb,{settings:s,onSettingsUpdated:u})}):(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(q,{startCreation:()=>d(!0)}),(0,t.jsx)(er,{open:c,onOk:u,onCancel:()=>{d(!1)}})]})}var ey=e.i(107233);e.i(707701);var ek=e.i(807235),ev=e.i(541071);e.i(622826);var eT=e.i(112179),ew=e.i(755146),e_=e.i(196631);let eS=e=>e.type||e.mode||"success",eN={success:"Success",failure:"Failure",success_and_failure:"Success & Failure"};function eE({callback:e,onTest:a,onEdit:s,onDelete:r}){return(0,t.jsxs)(ew.DropdownMenu,{children:[(0,t.jsx)(ew.DropdownMenuTrigger,{"aria-label":"Open callback actions","data-testid":`callback-actions-${e.name}-${eS(e)}`,className:(0,e_.cn)((0,l.buttonVariants)({variant:"ghost",size:"icon-sm"}),"text-muted-foreground"),children:(0,t.jsx)(ev.MoreHorizontal,{className:"size-4"})}),(0,t.jsxs)(ew.DropdownMenuContent,{align:"end",className:"w-52",children:[(0,t.jsxs)(ew.DropdownMenuItem,{"data-testid":"callback-action-test",onClick:()=>void a(e),children:[(0,t.jsx)(eh.Play,{}),"Test"]}),(0,t.jsxs)(ew.DropdownMenuItem,{"data-testid":"callback-action-edit",onClick:()=>s(e),children:[(0,t.jsx)(em.Pencil,{}),"Edit"]}),(0,t.jsx)(ew.DropdownMenuSeparator,{}),(0,t.jsxs)(ew.DropdownMenuItem,{variant:"destructive","data-testid":"callback-action-delete",onClick:()=>r(e),children:[(0,t.jsx)(I.Trash2,{}),"Delete"]})]})]})}function eA(){return(0,t.jsxs)("div",{className:"flex flex-col items-center gap-1 py-6",children:[(0,t.jsx)("div",{className:"mb-1 flex size-10 items-center justify-center rounded-lg bg-muted",children:(0,t.jsx)(G.Inbox,{className:"size-5 text-muted-foreground"})}),(0,t.jsx)("div",{className:"text-sm font-medium text-foreground",children:"No callbacks configured"}),(0,t.jsx)("div",{className:"text-sm text-muted-foreground",children:"Add your first callback to start logging data to external services."})]})}let eF=({callbacks:e,availableCallbacks:s={},isLoading:r=!1,onTest:n=()=>{},onEdit:i=()=>{},onDelete:o=()=>{},onAdd:c=()=>{}})=>{let d=(0,a.useMemo)(()=>(({availableCallbacks:e,onTest:a,onEdit:s,onDelete:r})=>[{id:"name",accessorKey:"name",meta:{title:"Callback Name"},header:"Callback Name",enableSorting:!1,cell:({row:a})=>{let s=a.original.name,r=e[s]?.ui_callback_name||s;return(0,t.jsx)("span",{className:"block max-w-72 truncate text-sm font-medium",title:r,children:r})}},{id:"mode",meta:{title:"Mode",skeleton:"badge"},header:"Mode",size:240,enableSorting:!1,cell:({row:e})=>{let a=eS(e.original);return(0,t.jsx)(eT.StatusBadge,{tone:"success"===a?"success":"failure"===a?"error":"info",label:eN[a]||a})}},{id:"actions",meta:{className:"text-right",headerClassName:"text-right"},header:()=>(0,t.jsx)("span",{className:"sr-only",children:"Actions"}),size:64,enableSorting:!1,enableHiding:!1,cell:({row:e})=>(0,t.jsx)("div",{className:"flex justify-end",children:(0,t.jsx)(eE,{callback:e.original,onTest:a,onEdit:s,onDelete:r})})}])({availableCallbacks:s,onTest:n,onEdit:i,onDelete:o}),[s,n,i,o]);return(0,t.jsxs)("div",{className:"mt-4 flex w-full flex-col gap-4",children:[(0,t.jsx)("h3",{className:"text-lg font-semibold tracking-tight text-foreground",children:"Active Logging Callbacks"}),(0,t.jsx)("div",{children:(0,t.jsxs)(l.Button,{onClick:c,children:[(0,t.jsx)(ey.Plus,{}),"Add Callback"]})}),(0,t.jsx)(ek.DataTable,{data:e,columns:d,getRowId:(e,t)=>`${e.name||t}-${eS(e)}`,isLoading:r,loadingMessage:"Loading callbacks…",noDataMessage:(0,t.jsx)(eA,{}),size:"compact"})]})};var eI=e.i(190702);let eD=({params:e,callbackConfigs:l,selectedCallback:n})=>{let{register:i,formState:o}=(0,s.useFormContext)(),d=a.default.useId();return e&&0!==e.length?(0,t.jsx)("div",{className:"space-y-4 mt-6 p-4 bg-muted rounded-lg border",children:e.map(e=>{let a=l.find(e=>e.id===n),s=a?.dynamic_params?.[e]||{},u=s.type||"text",m=s.ui_name||e.replace(/_/g," ").replace(/\b\w/g,e=>e.toUpperCase()),h=s.required||!1,x=`${d}-${e}`,g=i(e,h?{required:`Please enter the ${m.toLowerCase()}`}:void 0);return(0,t.jsxs)(r.Field,{className:"mb-4",children:[(0,t.jsx)(r.FieldLabel,{htmlFor:x,children:(0,t.jsxs)("span",{className:"text-sm font-medium text-foreground",children:[m," "]})}),"password"===u?(0,t.jsx)(c.Input,{id:x,type:"password",placeholder:`Enter your ${m.toLowerCase()}`,...g}):"number"===u?(0,t.jsx)(c.Input,{id:x,type:"number",placeholder:`Enter ${m.toLowerCase()}`,min:0,max:1,step:.1,...g}):(0,t.jsx)(c.Input,{id:x,placeholder:`Enter your ${m.toLowerCase()}`,...g}),(0,t.jsx)(r.FieldError,{errors:[o.errors[e]]})]},e)})}):null},eL=({callbackConfigs:e,selectedCallback:l,onCallbackChange:n,disabled:o=!1})=>{let{control:c}=(0,s.useFormContext)(),d=a.default.useId(),u=e.find(e=>e.id===l)??null;return(0,t.jsx)(s.Controller,{control:c,name:"callback",rules:o?void 0:{required:"Please select a callback"},render:({field:a,fieldState:s})=>(0,t.jsxs)(r.Field,{children:[(0,t.jsx)(r.FieldLabel,{htmlFor:d,children:"Callback"}),(0,t.jsxs)(i.Combobox,{items:e,value:u,onValueChange:e=>{a.onChange(e?.id??""),n(e?.id??"")},isItemEqualToValue:(e,t)=>e.id===t.id,itemToStringLabel:e=>e.displayName,filter:(e,t)=>e.id.toLowerCase().includes(t.trim().toLowerCase()),disabled:o,children:[(0,t.jsx)(i.ComboboxInput,{id:d,placeholder:"Choose a logging callback...",className:"w-full",disabled:o,onBlur:a.onBlur,"aria-invalid":void 0!==s.error||void 0}),(0,t.jsxs)(i.ComboboxContent,{children:[(0,t.jsx)(i.ComboboxEmpty,{children:"No results"}),(0,t.jsx)(i.ComboboxList,{children:e=>(0,t.jsx)(i.ComboboxItem,{value:e,children:(0,t.jsxs)("div",{className:"flex items-center space-x-3 py-1",children:[(0,t.jsx)("div",{className:"w-6 h-6 flex items-center justify-center",children:(0,t.jsx)(A.Logo,{src:(e=>{if(e)return e.includes("/")||e.startsWith("data:")||e.startsWith("http")?e:`/ui/assets/logos/${e}`})(e.logo),label:e.displayName,className:"w-6 h-6 rounded-sm object-contain"})}),(0,t.jsx)("span",{className:"font-medium text-foreground",children:e.displayName})]})},e.id)})]})]}),(0,t.jsx)(r.FieldError,{errors:[s.error]})]})})},eP=(e,t,a)=>{if(!e)return a?Object.keys(a):[];let s=t.find(t=>t.id===e);return s?.dynamic_params?Object.keys(s.dynamic_params):a?Object.keys(a):[]},ez=({accessToken:e,userRole:r,userID:i,premiumUser:h})=>{let[x,g]=(0,a.useState)([]),[f,b]=(0,a.useState)(!0),[C,y]=(0,a.useState)([]),k=(0,s.useForm)({shouldUnregister:!0}),v=(0,s.useForm)({shouldUnregister:!0}),[T,w]=(0,a.useState)(null),[S,N]=(0,a.useState)(""),[A,F]=(0,a.useState)({}),[I,D]=(0,a.useState)([]),[L,z]=(0,a.useState)(!1),[M,O]=(0,a.useState)([]),[B,U]=(0,a.useState)({}),[R,Z]=(0,a.useState)([]),[H,$]=(0,a.useState)(!1),[G,q]=(0,a.useState)(null),[K,W]=(0,a.useState)(!1),[V,Q]=(0,a.useState)(null),[J,Y]=(0,a.useState)(!1),[X,ee]=(0,a.useState)(!1),[et,ea]=(0,a.useState)(!1);(0,a.useEffect)(()=>{e&&(0,j.getCallbackConfigsCall)(e).then(e=>{O(e||[])}).catch(e=>{p.toast.fromError("Failed to load callback configs: "+(0,eI.parseErrorMessage)(e))})},[e]),(0,a.useEffect)(()=>{if(H&&G){let e=Object.fromEntries(Object.entries(G.variables||{}).map(([e,t])=>[e,t??""]));v.reset({...e,callback:G.name})}},[H,G,v]);let es=e=>{I.includes(e)?D(I.filter(t=>t!==e)):D([...I,e])},er={llm_exceptions:"LLM Exceptions",llm_too_slow:"LLM Responses Too Slow",llm_requests_hanging:"LLM Requests Hanging",budget_alerts:"Budget Alerts (API Keys, Users)",db_exceptions:"Database Exceptions (Read/Write)",daily_reports:"Weekly/Monthly Spend Reports",outage_alerts:"Outage Alerts",region_outage_alerts:"Region Outage Alerts",model_deprecation_warnings:"Model Deprecation Warnings"};(0,a.useEffect)(()=>{(async()=>{if(!e||!r||!i)return b(!1);try{let t=await (0,j.getCallbacksCall)(e,i,r);g(t.callbacks),U(t.available_callbacks);let a=t.alerts;if(a&&a.length>0){let e=a[0],t=e.variables.SLACK_WEBHOOK_URL,s=e.active_alerts;D(s),N(t),F(e.alerts_to_webhook)}y(a)}finally{b(!1)}})()},[e,r,i]);let el=e=>I&&I.includes(e),en=async(t,a,s)=>{if(e){s?Y(!0):ee(!0);try{if(await (0,j.setCallbacksCall)(e,{environment_variables:t,litellm_settings:{success_callback:[a]}}),p.toast.success(s?"Callback updated successfully":`Callback ${a} added successfully`),s?($(!1),v.reset(),q(null)):(z(!1),k.reset(),w(null),Z([])),i&&r){let t=await (0,j.getCallbacksCall)(e,i,r);g(t.callbacks)}}catch(e){p.toast.fromError(e)}finally{s?Y(!1):ee(!1)}}},eo=async e=>{G&&await en(e,G.name,!0)},ec=async e=>{let t=e?.callback;t&&await en(e,t,!1)},ed=()=>{z(!1),w(null),Z([])},eu=()=>{$(!1),q(null),v.reset()},em=async()=>{if(!e)return;let t={};Object.entries(er).forEach(([e,a])=>{let s=document.querySelector(`input[name="${e}"]`),r=s?.value||"";t[e]=r});try{await (0,j.setCallbacksCall)(e,{general_settings:{alert_to_webhook_url:t,alert_types:I}})}catch(e){p.toast.fromError(e)}p.toast.success("Alerts updated successfully")},eh=async()=>{if(V&&e)try{if(ea(!0),await (0,j.deleteCallback)(e,V.name),p.toast.success(`Callback ${V.name} deleted successfully`),i&&r){let t=await (0,j.getCallbacksCall)(e,i,r);g(t.callbacks)}W(!1),Q(null)}catch(e){console.error("Failed to delete callback:",e),p.toast.fromError(e)}finally{ea(!1)}};return e?(0,t.jsxs)("div",{className:"mx-4",children:[(0,t.jsx)("div",{className:"grid grid-cols-1 gap-2 p-8 w-full mt-2",children:(0,t.jsxs)(m.Tabs,{defaultValue:"logging-callbacks",children:[(0,t.jsxs)(m.TabsList,{variant:"line",children:[(0,t.jsx)(m.TabsTrigger,{value:"logging-callbacks",children:"Logging Callbacks"}),(0,t.jsx)(m.TabsTrigger,{value:"cloudzero-cost-tracking",children:"CloudZero Cost Tracking"}),(0,t.jsx)(m.TabsTrigger,{value:"alerting-types",children:"Alerting Types"}),(0,t.jsx)(m.TabsTrigger,{value:"alerting-settings",children:"Alerting Settings"}),(0,t.jsx)(m.TabsTrigger,{value:"email-alerts",children:"Email Alerts"}),(0,t.jsx)(m.TabsTrigger,{value:"ms-teams-alerts",children:"MS Teams Alerts"})]}),(0,t.jsx)(m.TabsContent,{value:"logging-callbacks",keepMounted:!0,children:(0,t.jsx)(eF,{callbacks:x,availableCallbacks:B,isLoading:f,onAdd:()=>z(!0),onEdit:e=>{q(e),$(!0)},onDelete:e=>{Q(e),W(!0)},onTest:async t=>{try{await (0,j.serviceHealthCheck)(e,t.name),p.toast.success("Health check triggered")}catch(e){p.toast.fromError((0,eI.parseErrorMessage)(e))}}})}),(0,t.jsx)(m.TabsContent,{value:"cloudzero-cost-tracking",keepMounted:!0,children:(0,t.jsx)("div",{className:"p-8",children:(0,t.jsx)(eC,{})})}),(0,t.jsx)(m.TabsContent,{value:"alerting-types",keepMounted:!0,children:(0,t.jsxs)(n.Card,{className:"p-6",children:[(0,t.jsxs)("p",{className:"my-2",children:["Alerts are only supported for Slack Webhook URLs. Get your webhook urls from"," ",(0,t.jsx)("a",{href:"https://api.slack.com/messaging/webhooks",target:"_blank",style:{color:"blue"},children:"here"})]}),(0,t.jsxs)(u.Table,{children:[(0,t.jsx)(u.TableHeader,{children:(0,t.jsxs)(u.TableRow,{children:[(0,t.jsx)(u.TableHead,{}),(0,t.jsx)(u.TableHead,{}),(0,t.jsx)(u.TableHead,{children:"Slack Webhook URL"})]})}),(0,t.jsx)(u.TableBody,{children:Object.entries(er).map(([e,a],s)=>(0,t.jsxs)(u.TableRow,{children:[(0,t.jsx)(u.TableCell,{children:"region_outage_alerts"==e?h?(0,t.jsx)(d.Switch,{id:"switch",name:"switch",checked:el(e),onCheckedChange:()=>es(e)}):(0,t.jsx)(l.Button,{className:"flex items-center justify-center",children:(0,t.jsx)("a",{href:"https://forms.gle/W3U4PZpJGFHWtHyA9",target:"_blank",children:"✨ Enterprise Feature"})}):(0,t.jsx)(d.Switch,{id:"switch",name:"switch",checked:el(e),onCheckedChange:()=>es(e)})}),(0,t.jsx)(u.TableCell,{className:"whitespace-normal break-words",children:(0,t.jsx)("p",{children:a})}),(0,t.jsx)(u.TableCell,{children:(0,t.jsx)(c.Input,{name:e,type:"password",defaultValue:A&&A[e]?A[e]:S})})]},s))})]}),(0,t.jsx)(l.Button,{size:"xs",className:"mt-2",onClick:em,children:"Save Changes"}),(0,t.jsx)(l.Button,{onClick:async()=>{try{await (0,j.serviceHealthCheck)(e,"slack"),p.toast.success("Alert test triggered. Test request to slack made - check logs/alerts on slack to verify")}catch(e){p.toast.fromError((0,eI.parseErrorMessage)(e))}},className:"mx-2",children:"Test Alerts"})]})}),(0,t.jsx)(m.TabsContent,{value:"alerting-settings",keepMounted:!0,children:(0,t.jsx)(P,{accessToken:e,premiumUser:h})}),(0,t.jsx)(m.TabsContent,{value:"email-alerts",keepMounted:!0,children:(0,t.jsx)(_,{accessToken:e,premiumUser:h,alerts:C})}),(0,t.jsx)(m.TabsContent,{value:"ms-teams-alerts",keepMounted:!0,children:(0,t.jsx)(E,{accessToken:e,userID:i,userRole:r,alerts:C})})]})}),(0,t.jsx)(o.Dialog,{open:L,onOpenChange:e=>!e&&ed(),children:(0,t.jsxs)(o.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,t.jsx)(o.DialogHeader,{children:(0,t.jsx)(o.DialogTitle,{children:"Add Logging Callback"})}),(0,t.jsxs)("a",{href:"https://docs.litellm.ai/docs/proxy/logging",className:"mb-8 mt-4",target:"_blank",style:{color:"blue"},children:[" ","LiteLLM Docs: Logging"]}),(0,t.jsx)(s.FormProvider,{...k,children:(0,t.jsxs)("form",{onSubmit:k.handleSubmit(ec),children:[(0,t.jsx)(eL,{callbackConfigs:M,selectedCallback:T,onCallbackChange:e=>{w(e),Z(eP(e,M))}}),(0,t.jsx)(eD,{params:R,callbackConfigs:M,selectedCallback:T}),(0,t.jsxs)("div",{className:"flex justify-end space-x-3 pt-6 mt-6 border-t border-border",children:[(0,t.jsx)(l.Button,{type:"button",variant:"outline",onClick:()=>{ed(),k.reset()},disabled:X,children:"Cancel"}),(0,t.jsx)(l.Button,{type:"submit",disabled:X,children:X?"Adding...":"Add Callback"})]})]})})]})}),(0,t.jsx)(o.Dialog,{open:H,onOpenChange:e=>!e&&eu(),children:(0,t.jsxs)(o.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,t.jsx)(o.DialogHeader,{children:(0,t.jsx)(o.DialogTitle,{children:"Edit Callback Settings"})}),(0,t.jsx)(s.FormProvider,{...v,children:(0,t.jsxs)("form",{onSubmit:v.handleSubmit(eo),children:[G&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(eL,{callbackConfigs:M,selectedCallback:G.name,onCallbackChange:()=>{},disabled:!0}),(0,t.jsx)(eD,{params:eP(G.name,M,G.variables),callbackConfigs:M,selectedCallback:G.name})]}),(0,t.jsxs)("div",{className:"flex justify-end space-x-3 pt-6 mt-6 border-t border-border",children:[(0,t.jsx)(l.Button,{type:"button",variant:"outline",onClick:eu,disabled:J,children:"Cancel"}),(0,t.jsx)(l.Button,{type:"submit",disabled:J,children:J?"Saving...":"Save Changes"})]})]})})]})}),(0,t.jsx)(ei.default,{isOpen:K,title:"Delete Callback",message:"Are you sure you want to delete this callback? This action cannot be undone.",resourceInformationTitle:"Callback Information",resourceInformation:[{label:"Callback Name",value:V?.name},{label:"Mode",value:V?.mode||"success"}],onCancel:()=>{W(!1),Q(null)},onOk:eh,confirmLoading:et})]}):null};e.s(["default",0,function(){let{accessToken:e,userRole:a,userId:s,premiumUser:r}=(0,$.default)();return(0,t.jsx)(ez,{userID:s,userRole:a,accessToken:e,premiumUser:r})}],372024)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0b8dlr4_m6177.js b/litellm/proxy/_experimental/out/_next/static/chunks/0b8dlr4_m6177.js
new file mode 100644
index 00000000000..785709df2ee
--- /dev/null
+++ b/litellm/proxy/_experimental/out/_next/static/chunks/0b8dlr4_m6177.js
@@ -0,0 +1 @@
+(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,648214,e=>{"use strict";var s=e.i(843476),t=e.i(135214),r=e.i(204290),a=e.i(929592),n=e.i(519455),l=e.i(515288),i=e.i(784774),o=e.i(677572),d=e.i(952571),c=e.i(89128),u=e.i(271645),m=e.i(700514),p=e.i(417385),_=e.i(602869),g=e.i(681307),h=e.i(237016),x=e.i(707621),f=e.i(475254);let j=(0,f.default)("circle-plus",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 12h8",key:"1wcyev"}],["path",{d:"M12 8v8",key:"napkw2"}]]);var b=e.i(174886),y=e.i(465261),v=e.i(221345),S=e.i(190702),C=e.i(542450),k=e.i(182668),w=e.i(793479),N=e.i(772436),E=e.i(571303),I=e.i(991326);let T=g.z.object({key_alias:g.z.string().min(1,"Please enter a name for your token")}),A=({accessToken:e,userID:t,proxySettings:i})=>{let o=(0,I.useZodForm)(T,{defaultValues:{key_alias:""}}),[c,m]=(0,u.useState)(!1),[g,f]=(0,u.useState)(null),[A,O]=(0,u.useState)("");(0,u.useEffect)(()=>{let e="";O(e=i&&i.PROXY_BASE_URL&&void 0!==i.PROXY_BASE_URL?i.PROXY_BASE_URL:window.location.origin)},[i]);let L=`${A}/scim/v2`,M=async s=>{if(!e||!t)return void p.toast.fromError("You need to be logged in to create a SCIM token");try{m(!0);let r={key_alias:s.key_alias||"SCIM Access Token",team_id:null,models:[],allowed_routes:["/scim/*"]},a=await (0,_.keyCreateCall)(e,t,r);f(a),p.toast.success("SCIM token created successfully")}catch(e){console.error("Error creating SCIM token:",e),p.toast.fromError("Failed to create SCIM token: "+(0,S.parseErrorMessage)(e))}finally{m(!1)}};return(0,s.jsx)("div",{className:"grid grid-cols-1",children:(0,s.jsx)(l.Card,{children:(0,s.jsxs)(l.CardContent,{children:[(0,s.jsx)("div",{className:"flex items-center mb-4",children:(0,s.jsx)(l.CardTitle,{children:"SCIM Configuration"})}),(0,s.jsx)("p",{className:"text-muted-foreground",children:"System for Cross-domain Identity Management (SCIM) allows you to automatically provision and manage users and groups in LiteLLM."}),(0,s.jsx)(N.Separator,{className:"my-6"}),(0,s.jsxs)("div",{className:"space-y-8",children:[(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"flex items-center mb-2",children:[(0,s.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-full bg-info/15 text-info mr-2",children:"1"}),(0,s.jsxs)("h3",{className:"text-lg font-medium flex items-center",children:[(0,s.jsx)(v.Link,{className:"h-5 w-5 mr-2"}),"SCIM Tenant URL"]})]}),(0,s.jsx)("p",{className:"text-muted-foreground mb-3",children:"Use this URL in your identity provider SCIM integration settings."}),(0,s.jsxs)("div",{className:"flex items-center",children:[(0,s.jsx)(w.Input,{value:L,disabled:!0,readOnly:!0,className:"grow"}),(0,s.jsx)(h.CopyToClipboard,{text:L,onCopy:()=>p.toast.success("URL copied to clipboard"),children:(0,s.jsxs)(n.Button,{type:"button",className:"ml-2 flex items-center",children:[(0,s.jsx)(b.Copy,{}),"Copy"]})})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"flex items-center mb-2",children:[(0,s.jsx)("div",{className:"flex items-center justify-center w-6 h-6 rounded-full bg-info/15 text-info mr-2",children:"2"}),(0,s.jsxs)("h3",{className:"text-lg font-medium flex items-center",children:[(0,s.jsx)(y.KeyRound,{className:"h-5 w-5 mr-2"}),"Authentication Token"]})]}),(0,s.jsxs)(r.Alert,{variant:"info",className:"mb-4",children:[(0,s.jsx)(d.Info,{}),(0,s.jsx)(a.AlertTitle,{children:"Using SCIM"}),(0,s.jsx)(a.AlertDescription,{children:"You need a SCIM token to authenticate with the SCIM API. Create one below and use it in your SCIM provider configuration."})]}),g?(0,s.jsxs)(l.Card,{className:"block p-6 border border-warning/30 bg-warning/10",children:[(0,s.jsxs)("div",{className:"flex items-center mb-2 text-warning",children:[(0,s.jsx)(x.CircleAlert,{className:"h-5 w-5 mr-2"}),(0,s.jsx)("h4",{className:"text-lg font-medium text-warning",children:"Your SCIM Token"})]}),(0,s.jsx)("p",{className:"text-warning mb-4 font-medium",children:"Make sure to copy this token now. You will not be able to see it again."}),(0,s.jsxs)("div",{className:"flex items-center",children:[(0,s.jsx)(w.Input,{value:g.key,className:"grow mr-2",type:"password",disabled:!0,readOnly:!0}),(0,s.jsx)(h.CopyToClipboard,{text:g.key,onCopy:()=>p.toast.success("Token copied to clipboard"),children:(0,s.jsxs)(n.Button,{type:"button",className:"flex items-center",children:[(0,s.jsx)(b.Copy,{}),"Copy"]})})]}),(0,s.jsxs)(n.Button,{type:"button",variant:"secondary",className:"mt-4 flex items-center",onClick:()=>f(null),children:[(0,s.jsx)(j,{}),"Create Another Token"]})]}):(0,s.jsx)("div",{className:"bg-muted p-4 rounded-lg",children:(0,s.jsx)("form",{onSubmit:o.handleSubmit(M),children:(0,s.jsxs)(C.FieldGroup,{children:[(0,s.jsx)(k.FormField,{control:o.control,name:"key_alias",label:"Token Name",children:({ref:e,...t})=>(0,s.jsx)(w.Input,{...t,ref:e,placeholder:"SCIM Access Token"})}),(0,s.jsx)("div",{children:(0,s.jsxs)(n.Button,{type:"submit",disabled:c,"aria-busy":c,className:"flex items-center",children:[c?(0,s.jsx)(E.UiLoadingSpinner,{className:"size-4"}):(0,s.jsx)(y.KeyRound,{}),"Create SCIM Token"]})})]})})})]})]})]})})})};var O=e.i(153472),L=e.i(954616),M=e.i(912598);let F=async(e,s)=>{let t=(0,_.getProxyBaseUrl)(),r=t?`${t}/config/update`:"/config/update",{store_prompts_in_spend_logs:a,...n}=s,l=await fetch(r,{method:"POST",headers:{[(0,_.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({general_settings:{store_prompts_in_spend_logs:a,...n}})});if(!l.ok){let e=await l.json().catch(()=>({}));throw Error(e?.error?.message||e?.message||e?.detail||"Failed to update spend logs settings")}return await l.json()};var P=e.i(950594),D=e.i(699375),U=e.i(746798),B=e.i(302747),z=e.i(359360),R=e.i(503116),G=e.i(653145);let V="store_prompts_in_spend_logs",$=[{name:O.GeneralSettingsFieldName.MAXIMUM_SPEND_LOGS_RETENTION_PERIOD,kind:"duration",label:"Maximum Spend Logs Retention Period (Optional)",placeholder:"e.g., 7d, 30d",fallbackTooltip:"Set the maximum retention period for spend logs (e.g., '7d' for 7 days, '30d' for 30 days). Leave empty for no limit."},{name:O.GeneralSettingsFieldName.MAXIMUM_SPEND_LOGS_CLEANUP_BATCH_SIZE,kind:"count",label:"Spend Logs Cleanup Batch Size (Optional)",placeholder:"e.g., 1000",fallbackTooltip:"Rows deleted per DELETE statement during cleanup. Leave empty to use the default of 1000."},{name:O.GeneralSettingsFieldName.MAXIMUM_SPEND_LOGS_CLEANUP_MAX_BATCHES,kind:"count",label:"Spend Logs Cleanup Max Batches (Optional)",placeholder:"e.g., 500",fallbackTooltip:"Maximum number of DELETE statements run per table per cleanup run. Leave empty to use the default of 500."},{name:O.GeneralSettingsFieldName.MAXIMUM_SPEND_LOGS_CLEANUP_RUN_BUDGET,kind:"duration",label:"Spend Logs Cleanup Run Budget (Optional)",placeholder:"e.g., 5m",fallbackTooltip:"Wall-clock budget for a whole cleanup run, shared across every table it cleans (e.g., '5m'). Leave empty to use the default of 5m."},{name:O.GeneralSettingsFieldName.MAXIMUM_SPEND_LOGS_CLEANUP_BATCH_TIMEOUT,kind:"duration",label:"Spend Logs Cleanup Batch Timeout (Optional)",placeholder:"e.g., 30s",fallbackTooltip:"Postgres statement and lock timeout applied to each cleanup batch, so cleanup never monopolizes a connection (e.g., '30s'). Leave empty to use the default of 30s."}],H=e=>""===e.trim()?void 0:e,q=e=>{let s=Number(e);if(""!==e.trim()&&Number.isFinite(s))return Math.max(1,Math.round(s))},K=(e,t)=>(0,s.jsxs)(s.Fragment,{children:[e,(0,s.jsxs)(U.Tooltip,{children:[(0,s.jsx)(U.TooltipTrigger,{render:(0,s.jsx)(z.CircleHelp,{className:"size-3.5 shrink-0 cursor-help text-muted-foreground"})}),(0,s.jsx)(U.TooltipContent,{children:t})]})]}),Q=({initialValues:e,describeField:t,isSaving:r,onSubmit:a})=>{let l=(0,G.useForm)({defaultValues:e});return(0,s.jsx)(U.TooltipProvider,{children:(0,s.jsxs)("form",{onSubmit:l.handleSubmit(a),noValidate:!0,children:[(0,s.jsxs)(C.FieldGroup,{children:[(0,s.jsx)(k.FormField,{control:l.control,name:V,label:K("Store Prompts in Spend Logs",t(V,"When enabled, prompts will be stored in spend logs for tracking and analysis purposes.")),children:({id:e,value:t,onChange:r,onBlur:a})=>(0,s.jsx)(D.Switch,{id:e,checked:!!t,onCheckedChange:r,onBlur:a,className:"w-fit"})}),$.map(e=>(0,s.jsx)(k.FormField,{control:l.control,name:e.name,label:K(e.label,t(e.name,e.fallbackTooltip)),children:({ref:t,onChange:r,onBlur:a,...n})=>"duration"===e.kind?(0,s.jsxs)(P.InputGroup,{children:[(0,s.jsx)(P.InputGroupInput,{...n,ref:t,onChange:e=>r(e.target.value),onBlur:a,placeholder:e.placeholder}),(0,s.jsx)(P.InputGroupAddon,{children:(0,s.jsx)(R.Clock,{})})]}):(0,s.jsx)(w.Input,{...n,ref:t,type:"number",onChange:e=>r(e.target.value),onBlur:e=>{let s;r(void 0===(s=q(e.target.value))?"":String(s)),a()},placeholder:e.placeholder})},e.name))]}),(0,s.jsxs)(n.Button,{type:"submit",className:"mt-6",disabled:r,children:[r&&(0,s.jsx)(E.UiLoadingSpinner,{role:"img","aria-label":"loading",className:"size-4"}),r?"Saving...":"Save Settings"]})]})})},W=()=>{let{mutate:e,isPending:r}=(()=>{let{accessToken:e}=(0,t.default)(),s=(0,M.useQueryClient)();return(0,L.useMutation)({mutationFn:async s=>{if(!e)throw Error("Access token is required");return await F(e,s)},onSuccess:()=>{s.invalidateQueries({queryKey:O.proxyConfigKeys.all})}})})(),{mutate:a,isPending:n}=(0,O.useDeleteProxyConfigField)(),{data:i,isLoading:o}=(0,O.useProxyConfig)(O.ConfigType.GENERAL_SETTINGS),d=(0,u.useCallback)(e=>i?.find(s=>s.field_name===e)?.field_value,[i]),c=e=>null!=d(e),m=(0,u.useMemo)(()=>({store_prompts_in_spend_logs:d(V)??!1,...Object.fromEntries($.map(e=>{let s=d(e.name);return[e.name,null==s?"":String(s)]}))}),[d]),_=e=>new Promise(s=>{let t=!1;a({config_type:O.ConfigType.GENERAL_SETTINGS,field_name:e},{onError:()=>{t=!0},onSettled:()=>s(t?e:null)})}),g=async e=>{let s=[];for(let t of e){let e=await _(t);null!==e&&s.push(e)}return s};return(0,s.jsxs)(l.Card,{children:[(0,s.jsx)(l.CardHeader,{className:"border-b",children:(0,s.jsx)(l.CardTitle,{children:"Logging Settings"})}),(0,s.jsx)(l.CardContent,{children:(0,s.jsxs)("div",{className:"flex w-full flex-col gap-6",children:[(0,s.jsx)("p",{className:"mb-0 text-muted-foreground",children:"Proxy-wide settings that control how request and response data are written to spend logs."}),o?(0,s.jsxs)("div",{className:"flex flex-col gap-3",children:[(0,s.jsx)(B.Skeleton,{className:"h-4 w-2/5"}),(0,s.jsx)(B.Skeleton,{className:"h-4 w-full"}),(0,s.jsx)(B.Skeleton,{className:"h-4 w-full"}),(0,s.jsx)(B.Skeleton,{className:"h-4 w-full"}),(0,s.jsx)(B.Skeleton,{className:"h-4 w-3/5"})]}):(0,s.jsx)(Q,{initialValues:m,describeField:(e,s)=>i?.find(s=>s.field_name===e)?.field_description||s,isSaving:r||n,onSubmit:s=>{let t,r,a,n,l,i=(t=H(s.maximum_spend_logs_retention_period),r=q(s.maximum_spend_logs_cleanup_batch_size),a=q(s.maximum_spend_logs_cleanup_max_batches),n=H(s.maximum_spend_logs_cleanup_run_budget),l=H(s.maximum_spend_logs_cleanup_batch_timeout),{store_prompts_in_spend_logs:s.store_prompts_in_spend_logs,...void 0!==t&&{maximum_spend_logs_retention_period:t},...void 0!==r&&{maximum_spend_logs_cleanup_batch_size:r},...void 0!==a&&{maximum_spend_logs_cleanup_max_batches:a},...void 0!==n&&{maximum_spend_logs_cleanup_run_budget:n},...void 0!==l&&{maximum_spend_logs_cleanup_batch_timeout:l}}),o=()=>e(i,{onSuccess:()=>p.toast.success("Spend logs settings updated successfully"),onError:e=>p.toast.fromError("Failed to save spend logs settings: "+(0,S.parseErrorMessage)(e))}),d=$.map(e=>e.name).filter(e=>!(e in i)&&c(e));0===d.length?o():g(d).then(e=>{e.length>0?p.toast.fromError(`Failed to clear saved value for: ${e.join(", ")}`):o()})}})]})})]})};var X=e.i(688511),Y=e.i(98919),Z=e.i(727612),J=e.i(266027),ee=e.i(243652);let es=(0,ee.createQueryKeys)("sso"),et=()=>{let{accessToken:e,userId:s,userRole:r}=(0,t.default)();return(0,J.useQuery)({queryKey:es.detail("settings"),queryFn:async()=>await (0,_.getSSOSettings)(e),enabled:!!(e&&s&&r)})};var er=e.i(174553),ea=e.i(487486),en=e.i(500330),el=e.i(336712),ei=e.i(39182);let eo={google:el.default.src,microsoft:ei.default.src,okta:"https://www.okta.com/sites/default/files/Okta_Logo_BrightBlue_Medium.png",generic:"",saml:""},ed={google:"Google SSO",microsoft:"Microsoft SSO",okta:"Okta / Auth0 SSO",generic:"Generic SSO",saml:"SAML SSO"},ec={internal_user_viewer:"Internal Viewer",internal_user:"Internal User",proxy_admin_viewer:"Proxy Admin Viewer",proxy_admin:"Proxy Admin"};var eu=e.i(450240),em=e.i(257428),ep=e.i(967489),e_=e.i(624687);let eg={google:{envVarMap:{google_client_id:"GOOGLE_CLIENT_ID",google_client_secret:"GOOGLE_CLIENT_SECRET"},fields:[{label:"Google Client ID",name:"google_client_id"},{label:"Google Client Secret",name:"google_client_secret"}]},microsoft:{envVarMap:{microsoft_client_id:"MICROSOFT_CLIENT_ID",microsoft_client_secret:"MICROSOFT_CLIENT_SECRET",microsoft_tenant:"MICROSOFT_TENANT"},fields:[{label:"Microsoft Client ID",name:"microsoft_client_id"},{label:"Microsoft Client Secret",name:"microsoft_client_secret"},{label:"Microsoft Tenant",name:"microsoft_tenant"}]},okta:{envVarMap:{generic_client_id:"GENERIC_CLIENT_ID",generic_client_secret:"GENERIC_CLIENT_SECRET",generic_authorization_endpoint:"GENERIC_AUTHORIZATION_ENDPOINT",generic_token_endpoint:"GENERIC_TOKEN_ENDPOINT",generic_userinfo_endpoint:"GENERIC_USERINFO_ENDPOINT",generic_scope:"GENERIC_SCOPE"},fields:[{label:"Generic Client ID",name:"generic_client_id"},{label:"Generic Client Secret",name:"generic_client_secret"},{label:"Authorization Endpoint",name:"generic_authorization_endpoint",placeholder:"https://your-domain/authorize"},{label:"Token Endpoint",name:"generic_token_endpoint",placeholder:"https://your-domain/token"},{label:"Userinfo Endpoint",name:"generic_userinfo_endpoint",placeholder:"https://your-domain/userinfo"},{label:"Scopes",name:"generic_scope",placeholder:"openid email profile",required:!1}]},generic:{envVarMap:{generic_client_id:"GENERIC_CLIENT_ID",generic_client_secret:"GENERIC_CLIENT_SECRET",generic_authorization_endpoint:"GENERIC_AUTHORIZATION_ENDPOINT",generic_token_endpoint:"GENERIC_TOKEN_ENDPOINT",generic_userinfo_endpoint:"GENERIC_USERINFO_ENDPOINT",generic_scope:"GENERIC_SCOPE"},fields:[{label:"Generic Client ID",name:"generic_client_id"},{label:"Generic Client Secret",name:"generic_client_secret"},{label:"Authorization Endpoint",name:"generic_authorization_endpoint"},{label:"Token Endpoint",name:"generic_token_endpoint"},{label:"Userinfo Endpoint",name:"generic_userinfo_endpoint"},{label:"Scopes",name:"generic_scope",placeholder:"openid email profile",required:!1}]},saml:{envVarMap:{saml_idp_metadata_url:"SAML_IDP_METADATA_URL",saml_idp_metadata_xml:"SAML_IDP_METADATA_XML",saml_sp_entity_id:"SAML_SP_ENTITY_ID",saml_allow_unsolicited:"SAML_ALLOW_UNSOLICITED"},fields:[{label:"IdP Metadata URL",name:"saml_idp_metadata_url",required:!1,placeholder:"https://idp.example.com/metadata (use this or the metadata XML below)"},{label:"IdP Metadata XML",name:"saml_idp_metadata_xml",required:!1,type:"textarea",placeholder:"Paste the IdP metadata XML here if you do not have a metadata URL"},{label:"SP Entity ID",name:"saml_sp_entity_id",required:!1,placeholder:"Defaults to /sso/saml/metadata"},{label:"Allow IdP-initiated (unsolicited) responses",name:"saml_allow_unsolicited",required:!1,type:"checkbox"}]}},eh=["proxy_admin_teams","admin_viewer_teams","internal_user_teams","internal_viewer_teams"],ex=e=>"okta"===e||"generic"===e,ef=(e,s)=>{let t=e.sso_provider,r=ex(t),a="sso-settings"===s?!!e.use_role_mappings&&r:!!e.use_role_mappings,n="sso-settings"===s&&!!e.use_team_mappings&&r;return["sso_provider",...t?eg[t]?.fields.map(e=>e.name)??[]:[],"user_email","proxy_base_url",...r?["use_role_mappings"]:[],...a?["group_claim","default_role",...eh]:[],..."sso-settings"===s&&r?["use_team_mappings"]:[],...n?["team_ids_jwt_field"]:[]]},ej=(e,s,t)=>()=>void e.handleSubmit(e=>t(Object.fromEntries(ef(e,s).map(s=>[s,e[s]]))))(),eb={sso_provider:"Please select an SSO provider",user_email:"Please enter the email of the proxy admin",proxy_base_url:"Please enter the proxy base url",group_claim:"Please enter the group claim",team_ids_jwt_field:"Please enter the team IDs JWT field"},ey=e=>null==e||""===e,ev={sso_provider:"",google_client_id:"",google_client_secret:"",microsoft_client_id:"",microsoft_client_secret:"",microsoft_tenant:"",generic_client_id:"",generic_client_secret:"",generic_authorization_endpoint:"",generic_token_endpoint:"",generic_userinfo_endpoint:"",user_email:"",proxy_base_url:"",default_role:"internal_user"},eS=(e,s)=>(0,I.useZodForm)(g.z.custom().superRefine((s,t)=>{let r=new Set(ef(s,e)),a=e=>{r.has(e)&&ey(s[e])&&t.addIssue({code:"custom",path:[e],message:eb[e]})};a("sso_provider"),a("user_email"),a("group_claim"),a("team_ids_jwt_field");let n=s.sso_provider?eg[s.sso_provider]:void 0;n?.fields.forEach(e=>{!1===e.required||ey(s[e.name])&&t.addIssue({code:"custom",path:[e.name],message:`Please enter the ${e.label.toLowerCase()}`})});let l=s.proxy_base_url;ey(l)?t.addIssue({code:"custom",path:["proxy_base_url"],message:eb.proxy_base_url}):/^https?:\/\/.+/.test(l)?l.endsWith("/")&&t.addIssue({code:"custom",path:["proxy_base_url"],message:"URL must not end with a trailing slash"}):t.addIssue({code:"custom",path:["proxy_base_url"],message:"URL must start with http:// or https://"})}),{mode:"onChange",defaultValues:ev,...s?{values:s}:{}}),eC=({field:e})=>{let{control:t}=(0,G.useFormContext)();return"checkbox"===e.type?(0,s.jsx)(k.FormField,{control:t,name:e.name,label:e.label,orientation:"horizontal",children:({value:e,onChange:t,onBlur:r,id:a,...n})=>(0,s.jsx)(em.Checkbox,{id:a,checked:!!e,onCheckedChange:t,onBlur:r,"aria-invalid":n["aria-invalid"],"aria-describedby":n["aria-describedby"]})}):(0,s.jsx)(k.FormField,{control:t,name:e.name,label:e.label,children:({ref:t,value:r,...a})=>{let n={placeholder:e.placeholder,value:r??"",...a};return"textarea"===e.type?(0,s.jsx)(e_.Textarea,{ref:t,rows:4,...n}):"password"===e.type||e.name.includes("client")?(0,s.jsx)(eu.PasswordInput,{ref:t,...n}):(0,s.jsx)(w.Input,{ref:t,...n})}})},ek=e=>{let t=eg[e];return t?t.fields.map(e=>(0,s.jsx)(eC,{field:e},e.name)):null},ew=()=>{let{control:e}=(0,G.useFormContext)();return(0,s.jsx)(k.FormField,{control:e,name:"sso_provider",label:"SSO Provider",children:({value:e,onChange:t,onBlur:r,id:a,...n})=>(0,s.jsxs)(ep.Select,{value:e??"",onValueChange:t,children:[(0,s.jsx)(ep.SelectTrigger,{id:a,onBlur:r,"aria-invalid":n["aria-invalid"],"aria-describedby":n["aria-describedby"],className:"w-full",children:(0,s.jsx)(ep.SelectValue,{children:e=>e?eO(e):""})}),(0,s.jsx)(ep.SelectContent,{children:Object.entries(eo).map(([e,t])=>(0,s.jsx)(ep.SelectItem,{value:e,children:(0,s.jsxs)("span",{className:"flex items-center py-1",children:[t&&(0,s.jsx)(er.Logo,{src:t,label:ed[e]||e,className:"h-6 w-6 mr-3 object-contain"}),(0,s.jsx)("span",{children:eO(e)})]})},e))})]})})},eN=()=>{let{control:e}=(0,G.useFormContext)();return(0,s.jsx)(k.FormField,{control:e,name:"user_email",label:"Proxy Admin Email",children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{ref:e,value:t??"",...r})})},eE=()=>{let{control:e}=(0,G.useFormContext)();return(0,s.jsx)(k.FormField,{control:e,name:"proxy_base_url",label:"Proxy Base URL",children:({ref:e,value:t,onChange:r,...a})=>(0,s.jsx)(w.Input,{ref:e,placeholder:"https://example.com",value:t??"",onChange:e=>r(e.target.value.trim()),...a})})},eI=({name:e,label:t})=>{let{control:r}=(0,G.useFormContext)();return(0,s.jsx)(k.FormField,{control:r,name:e,label:t,orientation:"horizontal",children:({value:e,onChange:t,onBlur:r,id:a,...n})=>(0,s.jsx)(em.Checkbox,{id:a,checked:!!e,onCheckedChange:t,onBlur:r,"aria-invalid":n["aria-invalid"],"aria-describedby":n["aria-describedby"]})})},eT=()=>{let{control:e}=(0,G.useFormContext)();return(0,s.jsx)(k.FormField,{control:e,name:"group_claim",label:"Group Claim",children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{ref:e,value:t??"",...r})})},eA=[{value:"internal_user_viewer",label:"Internal Viewer"},{value:"internal_user",label:"Internal User"},{value:"proxy_admin_viewer",label:"Admin Viewer"},{value:"proxy_admin",label:"Proxy Admin"}],eO=e=>ed[e]||e.charAt(0).toUpperCase()+e.slice(1)+" SSO",eL=()=>{let{control:e}=(0,G.useFormContext)();return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(k.FormField,{control:e,name:"default_role",label:"Default Role",children:({value:e,onChange:t,onBlur:r,id:a,...n})=>(0,s.jsxs)(ep.Select,{value:e??"",onValueChange:t,children:[(0,s.jsx)(ep.SelectTrigger,{id:a,onBlur:r,"aria-invalid":n["aria-invalid"],"aria-describedby":n["aria-describedby"],className:"w-full",children:(0,s.jsx)(ep.SelectValue,{children:e=>eA.find(s=>s.value===e)?.label??e})}),(0,s.jsx)(ep.SelectContent,{children:eA.map(e=>(0,s.jsx)(ep.SelectItem,{value:e.value,children:e.label},e.value))})]})}),(0,s.jsx)(k.FormField,{control:e,name:"proxy_admin_teams",label:"Proxy Admin Teams",children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{ref:e,value:t??"",...r})}),(0,s.jsx)(k.FormField,{control:e,name:"admin_viewer_teams",label:"Admin Viewer Teams",children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{ref:e,value:t??"",...r})}),(0,s.jsx)(k.FormField,{control:e,name:"internal_user_teams",label:"Internal User Teams",children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{ref:e,value:t??"",...r})}),(0,s.jsx)(k.FormField,{control:e,name:"internal_viewer_teams",label:"Internal Viewer Teams",children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{ref:e,value:t??"",...r})})]})},eM=()=>{let{control:e}=(0,G.useFormContext)();return(0,s.jsx)(k.FormField,{control:e,name:"team_ids_jwt_field",label:"Team IDs JWT Field",children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{ref:e,value:t??"",...r})})},eF=({form:e,onFormSubmit:t})=>{let r=(0,G.useWatch)({control:e.control,name:"sso_provider"}),a=(0,G.useWatch)({control:e.control,name:"use_role_mappings"}),n=(0,G.useWatch)({control:e.control,name:"use_team_mappings"}),l=ex(r);return(0,s.jsx)("div",{children:(0,s.jsx)(G.FormProvider,{...e,children:(0,s.jsx)("form",{onSubmit:s=>{s.preventDefault(),ej(e,"sso-settings",t)()},children:(0,s.jsxs)(C.FieldGroup,{children:[(0,s.jsx)(ew,{}),r?ek(r):null,(0,s.jsx)(eN,{}),(0,s.jsx)(eE,{}),l&&(0,s.jsx)(eI,{name:"use_role_mappings",label:"Use Role Mappings"}),a&&l&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(eT,{}),(0,s.jsx)(eL,{})]}),l&&(0,s.jsx)(eI,{name:"use_team_mappings",label:"Use Team Mappings"}),n&&l&&(0,s.jsx)(eM,{})]})})})})},eP=()=>{let{accessToken:e}=(0,t.default)();return(0,L.useMutation)({mutationFn:async s=>{if(!e)throw Error("Access token is required");return await (0,_.updateSSOSettings)(e,s)}})},eD=e=>{let{proxy_admin_teams:s,admin_viewer_teams:t,internal_user_teams:r,internal_viewer_teams:a,default_role:n,group_claim:l,use_role_mappings:i,use_team_mappings:o,team_ids_jwt_field:d,...c}=e,u={...c};"boolean"==typeof u.saml_allow_unsolicited&&(u.saml_allow_unsolicited=u.saml_allow_unsolicited?"true":"false");let m=c.sso_provider;if(i&&("okta"===m||"generic"===m)){let e=e=>e&&""!==e.trim()?e.split(",").map(e=>e.trim()).filter(e=>e.length>0):[];u.role_mappings={provider:"generic",group_claim:l,default_role:({internal_user_viewer:"internal_user_viewer",internal_user:"internal_user",proxy_admin_viewer:"proxy_admin_viewer",proxy_admin:"proxy_admin"})[n]||"internal_user",roles:{proxy_admin:e(s),proxy_admin_viewer:e(t),internal_user:e(r),internal_user_viewer:e(a)}}}return o&&("okta"===m||"generic"===m)&&(u.team_mappings={team_ids_jwt_field:d}),u},eU=e=>e.google_client_id?"google":e.microsoft_client_id?"microsoft":e.generic_client_id?e.generic_authorization_endpoint?.includes("okta")||e.generic_authorization_endpoint?.includes("auth0")?"okta":"generic":e.saml_idp_metadata_url||e.saml_idp_metadata_xml?"saml":null;var eB=e.i(776639);let ez=({isVisible:e,onCancel:t,onSuccess:r})=>{let a=eS("sso-settings"),{mutateAsync:l,isPending:i}=eP(),o=async e=>{let s=eD(e);await l(s,{onSuccess:()=>{p.toast.success("SSO settings added successfully"),r()},onError:e=>{p.toast.fromError("Failed to save SSO settings: "+(0,S.parseErrorMessage)(e))}})},d=()=>{a.reset(ev),t()};return(0,s.jsx)(eB.Dialog,{open:e,onOpenChange:e=>!e&&d(),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"Add SSO"})}),(0,s.jsx)(eF,{form:a,onFormSubmit:o}),(0,s.jsx)(eB.DialogFooter,{children:(0,s.jsxs)("div",{className:"flex items-center justify-end gap-2",children:[(0,s.jsx)(n.Button,{type:"button",variant:"outline",onClick:d,disabled:i,children:"Cancel"}),(0,s.jsxs)(n.Button,{type:"button",disabled:i,onClick:ej(a,"sso-settings",o),children:[i&&(0,s.jsx)(E.UiLoadingSpinner,{className:"size-4 mr-1"}),i?"Adding...":"Add SSO"]})]})})]})})};var eR=e.i(127952);let eG=({isVisible:e,onCancel:t,onSuccess:r})=>{let{data:a}=et(),{mutateAsync:n,isPending:l}=eP(),i=async()=>{await n({google_client_id:null,google_client_secret:null,microsoft_client_id:null,microsoft_client_secret:null,microsoft_tenant:null,generic_client_id:null,generic_client_secret:null,generic_authorization_endpoint:null,generic_token_endpoint:null,generic_userinfo_endpoint:null,saml_idp_metadata_url:null,saml_idp_metadata_xml:null,saml_sp_entity_id:null,saml_allow_unsolicited:null,proxy_base_url:null,user_email:null,sso_provider:null,role_mappings:null,team_mappings:null},{onSuccess:()=>{p.toast.success("SSO settings cleared successfully"),t(),r()},onError:e=>{p.toast.fromError("Failed to clear SSO settings: "+(0,S.parseErrorMessage)(e))}})};return(0,s.jsx)(eR.default,{isOpen:e,title:"Confirm Clear SSO Settings",alertMessage:"This action cannot be undone.",message:"Are you sure you want to clear all SSO settings? Users will no longer be able to login using SSO after this change.",resourceInformationTitle:"SSO Settings",resourceInformation:[{label:"Provider",value:a?.values&&eU(a?.values)||"Generic"}],onCancel:t,onOk:i,confirmLoading:l})},eV=e=>e&&0!==e.length?e.join(", "):"",e$=({isVisible:e,onCancel:t,onSuccess:r})=>{let a=et(),{mutateAsync:l,isPending:i}=eP(),o=(0,u.useMemo)(()=>{var e;let s,t;return a.data?.values?(s=(e=a.data.values).role_mappings,t=e.team_mappings,{...ev,sso_provider:eU(e)??"",google_client_id:e.google_client_id??"",google_client_secret:e.google_client_secret??"",microsoft_client_id:e.microsoft_client_id??"",microsoft_client_secret:e.microsoft_client_secret??"",microsoft_tenant:e.microsoft_tenant??"",generic_client_id:e.generic_client_id??"",generic_client_secret:e.generic_client_secret??"",generic_authorization_endpoint:e.generic_authorization_endpoint??"",generic_token_endpoint:e.generic_token_endpoint??"",generic_userinfo_endpoint:e.generic_userinfo_endpoint??"",generic_scope:e.generic_scope??void 0,saml_idp_metadata_url:e.saml_idp_metadata_url??void 0,saml_idp_metadata_xml:e.saml_idp_metadata_xml??void 0,saml_sp_entity_id:e.saml_sp_entity_id??void 0,user_email:e.user_email??"",proxy_base_url:e.proxy_base_url??"",...null!=e.saml_allow_unsolicited?{saml_allow_unsolicited:"true"===e.saml_allow_unsolicited}:{},...s?{use_role_mappings:!0,group_claim:s.group_claim,default_role:s.default_role||"internal_user",proxy_admin_teams:eV(s.roles?.proxy_admin),admin_viewer_teams:eV(s.roles?.proxy_admin_viewer),internal_user_teams:eV(s.roles?.internal_user),internal_viewer_teams:eV(s.roles?.internal_user_viewer)}:{},...t?{use_team_mappings:!0,team_ids_jwt_field:t.team_ids_jwt_field}:{}}):ev},[a.data]),d=eS("sso-settings",o),c=async e=>{try{let s=eD(e);await l(s,{onSuccess:()=>{p.toast.success("SSO settings updated successfully"),r()},onError:e=>{p.toast.fromError("Failed to save SSO settings: "+(0,S.parseErrorMessage)(e))}})}catch(e){p.toast.fromError("Failed to process SSO settings: "+(0,S.parseErrorMessage)(e))}},m=()=>{d.reset(o),t()};return(0,s.jsx)(eB.Dialog,{open:e,onOpenChange:e=>!e&&m(),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"Edit SSO Settings"})}),(0,s.jsx)(eF,{form:d,onFormSubmit:c}),(0,s.jsx)(eB.DialogFooter,{children:(0,s.jsxs)("div",{className:"flex items-center justify-end gap-2",children:[(0,s.jsx)(n.Button,{type:"button",variant:"outline",onClick:m,disabled:i,children:"Cancel"}),(0,s.jsxs)(n.Button,{type:"button",disabled:i,onClick:ej(d,"sso-settings",c),children:[i&&(0,s.jsx)(E.UiLoadingSpinner,{className:"size-4 mr-1"}),i?"Saving...":"Save"]})]})})]})})};var eH=e.i(286536),eq=e.i(77705);function eK({defaultHidden:e=!0,value:t}){let[r,a]=(0,u.useState)(e);return(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"flex-1 font-mono text-muted-foreground",children:t?r?"•".repeat(t.length):t:(0,s.jsx)("span",{className:"text-muted-foreground italic",children:"Not configured"})}),t&&(0,s.jsx)(n.Button,{type:"button",variant:"ghost",size:"icon-sm","aria-label":r?"Show value":"Hide value",onClick:()=>a(!r),className:"text-muted-foreground",children:r?(0,s.jsx)(eH.Eye,{className:"size-4"}):(0,s.jsx)(eq.EyeOff,{className:"size-4"})})]})}e.i(707701);var eQ=e.i(807235),eW=e.i(112179),eX=e.i(761911);function eY({roleMappings:e}){if(!e)return null;let t=[{id:"role",accessorKey:"role",header:"Role",cell:({row:e})=>(0,s.jsx)("strong",{className:"font-semibold",children:ec[e.original.role]})},{id:"groups",accessorKey:"groups",header:"Mapped Groups",cell:({row:e})=>e.original.groups.length>0?(0,s.jsx)("div",{className:"flex flex-wrap gap-1",children:e.original.groups.map((e,t)=>(0,s.jsx)(eW.StatusBadge,{tone:"info",label:e},t))}):(0,s.jsx)("span",{className:"text-muted-foreground italic",children:"No groups mapped"})}];return(0,s.jsx)(l.Card,{children:(0,s.jsxs)(l.CardContent,{children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)(eX.Users,{className:"w-6 h-6 text-muted-foreground mb-2"}),(0,s.jsx)("h3",{className:"mb-2 text-2xl font-semibold text-foreground",children:"Role Mappings"})]}),(0,s.jsxs)("div",{className:"space-y-8",children:[(0,s.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("h5",{className:"mb-2 text-base font-semibold text-foreground",children:"Group Claim"}),(0,s.jsx)("div",{children:(0,s.jsx)("code",{className:"rounded-sm border border-border bg-muted px-1 py-0.5 font-mono text-xs",children:e.group_claim})})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h5",{className:"mb-2 text-base font-semibold text-foreground",children:"Default Role"}),(0,s.jsx)("div",{children:(0,s.jsx)("strong",{className:"font-semibold",children:ec[e.default_role]})})]})]}),(0,s.jsx)(N.Separator,{className:"my-6"}),(0,s.jsx)(eQ.DataTable,{columns:t,data:Object.entries(e.roles).map(([e,s])=>({role:e,groups:s})),getRowId:e=>e.role,size:"compact"})]})]})})}function eZ({onAdd:e}){return(0,s.jsxs)("div",{className:"flex w-full flex-col items-center rounded-lg border border-dashed border-border bg-card p-12 text-center",children:[(0,s.jsx)("div",{className:"mb-4 flex size-12 items-center justify-center rounded-full bg-muted",children:(0,s.jsx)(Y.Shield,{className:"size-6 text-muted-foreground"})}),(0,s.jsx)("h4",{className:"text-base font-semibold text-foreground",children:"No SSO Configuration Found"}),(0,s.jsx)("p",{className:"mx-auto mt-2 max-w-md text-sm text-muted-foreground",children:"Configure Single Sign-On (SSO) to enable seamless authentication for your team members using your identity provider."}),(0,s.jsx)(n.Button,{size:"lg",onClick:e,className:"mt-4",children:"Configure SSO"})]})}let eJ=["w-24","w-48","w-60","w-44","w-52"];function e0(){return(0,s.jsxs)(l.Card,{role:"status","aria-label":"Loading SSO configuration",children:[(0,s.jsxs)(l.CardHeader,{className:"flex flex-row items-center justify-between",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)(Y.Shield,{className:"size-6 text-muted-foreground"}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"text-lg font-semibold text-foreground",children:"SSO Configuration"}),(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:"Manage Single Sign-On authentication settings"})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)(B.Skeleton,{className:"h-8 w-40"}),(0,s.jsx)(B.Skeleton,{className:"h-8 w-48"})]})]}),(0,s.jsx)(l.CardContent,{children:(0,s.jsx)("div",{className:"divide-y divide-border overflow-hidden rounded-md border border-border",children:eJ.map(e=>(0,s.jsxs)("div",{className:"grid grid-cols-3",children:[(0,s.jsx)("div",{className:"bg-muted/50 px-4 py-3",children:(0,s.jsx)(B.Skeleton,{className:"h-4 w-20"})}),(0,s.jsx)("div",{className:"col-span-2 px-4 py-3",children:(0,s.jsx)(B.Skeleton,{className:`h-4 ${e}`})})]},e))})})]})}function e1(){return(0,s.jsx)("span",{className:"text-muted-foreground italic",children:"Not configured"})}function e2({children:e,label:t}){return(0,s.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-3",children:[(0,s.jsx)("dt",{className:"bg-muted/50 px-4 py-3 text-sm font-medium text-foreground",children:t}),(0,s.jsx)("dd",{className:"min-w-0 px-4 py-3 text-sm text-foreground sm:col-span-2",children:e})]})}function e4({value:e}){return e?(0,s.jsxs)("div",{className:"flex min-w-0 items-center gap-2",children:[(0,s.jsx)("span",{className:"truncate font-mono text-sm text-muted-foreground",children:e}),(0,s.jsx)(n.Button,{type:"button",variant:"ghost",size:"icon-sm","aria-label":"Copy value",onClick:()=>void(0,en.copyToClipboard)(e,"Copied to clipboard"),children:(0,s.jsx)(b.Copy,{className:"size-3.5"})})]}):(0,s.jsx)("span",{className:"font-mono text-muted-foreground",children:"-"})}function e3(){let{data:e,refetch:t,isLoading:r}=et(),[a,i]=(0,u.useState)(!1),[o,d]=(0,u.useState)(!1),[c,m]=(0,u.useState)(!1),p=[e?.values.google_client_id,e?.values.microsoft_client_id,e?.values.generic_client_id,e?.values.saml_idp_metadata_url,e?.values.saml_idp_metadata_xml].some(Boolean),_=e?.values?eU(e.values):null,g=!!e?.values.role_mappings,h=!!e?.values.team_mappings,x=e=>e||(0,s.jsx)(e1,{}),f=e=>e.team_mappings?.team_ids_jwt_field?(0,s.jsx)(ea.Badge,{variant:"secondary",children:e.team_mappings.team_ids_jwt_field}):(0,s.jsx)(e1,{}),j={google:{providerText:ed.google,fields:[{label:"Client ID",render:e=>(0,s.jsx)(eK,{value:e.google_client_id})},{label:"Client Secret",render:e=>(0,s.jsx)(eK,{value:e.google_client_secret})},{label:"Proxy Base URL",render:e=>x(e.proxy_base_url)}]},microsoft:{providerText:ed.microsoft,fields:[{label:"Client ID",render:e=>(0,s.jsx)(eK,{value:e.microsoft_client_id})},{label:"Client Secret",render:e=>(0,s.jsx)(eK,{value:e.microsoft_client_secret})},{label:"Tenant",render:e=>x(e.microsoft_tenant)},{label:"Proxy Base URL",render:e=>x(e.proxy_base_url)}]},okta:{providerText:ed.okta,fields:[{label:"Client ID",render:e=>(0,s.jsx)(eK,{value:e.generic_client_id})},{label:"Client Secret",render:e=>(0,s.jsx)(eK,{value:e.generic_client_secret})},{label:"Authorization Endpoint",render:e=>(0,s.jsx)(e4,{value:e.generic_authorization_endpoint})},{label:"Token Endpoint",render:e=>(0,s.jsx)(e4,{value:e.generic_token_endpoint})},{label:"User Info Endpoint",render:e=>(0,s.jsx)(e4,{value:e.generic_userinfo_endpoint})},{label:"Scopes",render:e=>x(e.generic_scope)},{label:"Proxy Base URL",render:e=>x(e.proxy_base_url)},h?{label:"Team IDs JWT Field",render:e=>f(e)}:null]},generic:{providerText:ed.generic,fields:[{label:"Client ID",render:e=>(0,s.jsx)(eK,{value:e.generic_client_id})},{label:"Client Secret",render:e=>(0,s.jsx)(eK,{value:e.generic_client_secret})},{label:"Authorization Endpoint",render:e=>(0,s.jsx)(e4,{value:e.generic_authorization_endpoint})},{label:"Token Endpoint",render:e=>(0,s.jsx)(e4,{value:e.generic_token_endpoint})},{label:"User Info Endpoint",render:e=>(0,s.jsx)(e4,{value:e.generic_userinfo_endpoint})},{label:"Scopes",render:e=>x(e.generic_scope)},{label:"Proxy Base URL",render:e=>x(e.proxy_base_url)},h?{label:"Team IDs JWT Field",render:e=>f(e)}:null]},saml:{providerText:ed.saml,fields:[{label:"IdP Metadata URL",render:e=>(0,s.jsx)(e4,{value:e.saml_idp_metadata_url})},{label:"IdP Metadata XML",render:e=>e.saml_idp_metadata_xml?(0,s.jsx)(ea.Badge,{variant:"secondary",children:"Provided"}):(0,s.jsx)(e1,{})},{label:"SP Entity ID",render:e=>(0,s.jsx)(e4,{value:e.saml_sp_entity_id})},{label:"Allow IdP-initiated (unsolicited) responses",render:e=>(0,s.jsx)(ea.Badge,{variant:"true"===e.saml_allow_unsolicited?"default":"secondary",children:"true"===e.saml_allow_unsolicited?"Enabled":"Disabled"})},{label:"Proxy Base URL",render:e=>x(e.proxy_base_url)}]}};return(0,s.jsxs)(s.Fragment,{children:[r?(0,s.jsx)(e0,{}):(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)(l.Card,{children:[(0,s.jsxs)(l.CardHeader,{children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)(Y.Shield,{className:"size-6 text-muted-foreground"}),(0,s.jsxs)("div",{children:[(0,s.jsx)(l.CardTitle,{children:(0,s.jsx)("h3",{children:"SSO Configuration"})}),(0,s.jsx)(l.CardDescription,{children:"Manage Single Sign-On authentication settings"})]})]}),p&&(0,s.jsxs)(l.CardAction,{className:"flex gap-2",children:[(0,s.jsxs)(n.Button,{type:"button",variant:"outline",onClick:()=>m(!0),children:[(0,s.jsx)(X.Edit,{}),"Edit SSO Settings"]}),(0,s.jsxs)(n.Button,{type:"button",variant:"destructive",onClick:()=>i(!0),children:[(0,s.jsx)(Z.Trash2,{}),"Delete SSO Settings"]})]})]}),(0,s.jsx)(l.CardContent,{children:p?(()=>{if(!e?.values||!_)return null;let t=j[_];return t?(0,s.jsxs)("dl",{className:"divide-y divide-border overflow-hidden rounded-md border border-border",children:[(0,s.jsx)(e2,{label:"Provider",children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[eo[_]&&(0,s.jsx)(er.Logo,{src:eo[_],label:ed[_]||_,className:"size-6 object-contain"}),(0,s.jsx)("span",{children:t.providerText})]})}),t.fields.map(t=>t&&(0,s.jsx)(e2,{label:t.label,children:t.render(e.values)},t.label))]}):null})():(0,s.jsx)(eZ,{onAdd:()=>d(!0)})})]}),g&&(0,s.jsx)(eY,{roleMappings:e?.values.role_mappings})]}),(0,s.jsx)(eG,{isVisible:a,onCancel:()=>i(!1),onSuccess:()=>t()}),(0,s.jsx)(ez,{isVisible:o,onCancel:()=>d(!1),onSuccess:()=>{d(!1),t()}}),(0,s.jsx)(e$,{isVisible:c,onCancel:()=>m(!1),onSuccess:()=>{m(!1),t()}})]})}var e5=e.i(292639);let e6=(0,ee.createQueryKeys)("uiSettings");var e7=e.i(664659),e8=e.i(111672);let e9={"api-keys":"Manage virtual keys for API access and authentication","llm-playground":"Interactive playground for testing LLM requests",models:"Configure and manage LLM models and endpoints",agents:"Create and manage AI agents",agentic:"Manage agentic resources: agents, workflow runs, and memory",workflows:"Track and inspect durable workflow run history","mcp-servers":"Configure Model Context Protocol servers",memory:"Inspect and manage agent memory entries stored under /v1/memory",guardrails:"Set up content moderation and safety guardrails",policies:"Define access control and usage policies","search-tools":"Configure RAG search and retrieval tools","tool-policies":"Configure tool use policies and permissions","vector-stores":"Manage vector databases for embeddings",new_usage:"View usage analytics and metrics","cost-optimization":"Track and configure cost-saving features: prompt compression, caching, and auto routing",logs:"Access request and response logs","guardrails-monitor":"Monitor guardrail performance and view logs",users:"Manage internal user accounts and permissions",teams:"Create and manage teams for access control",organizations:"Manage organizations and their members",projects:"Manage projects within teams","access-groups":"Manage access groups for role-based permissions",budgets:"Set and monitor spending budgets",api_ref:"Browse API documentation and endpoints","model-hub-table":"Explore available AI models and providers","learning-resources":"Access tutorials and documentation",caching:"Configure response caching and coordination Redis settings","transform-request":"Set up request transformation rules","cost-tracking":"Track and analyze API costs","ui-theme":"Customize dashboard appearance","tag-management":"Organize resources with tags",prompts:"Manage and version prompt templates",skills:"Browse and manage Claude Code skills",usage:"View legacy usage dashboard","router-settings":"Configure routing and load balancing settings","logging-and-alerts":"Set up logging and alert configurations","admin-panel":"Access admin panel and settings"};var se=e.i(708347);let ss=e=>!e||0===e.length||e.some(e=>se.internalUserRoles.includes(e));var st=e.i(204258);function sr({enabledPagesInternalUsers:e,enabledPagesPropertyDescription:t,isUpdating:r,onUpdate:a}){let l=null!=e,i=(0,u.useMemo)(()=>{let e;return e=[],e8.menuGroups.forEach(s=>{s.items.forEach(t=>{if(t.page&&"tools"!==t.page&&"experimental"!==t.page&&"settings"!==t.page&&ss(t.roles)){let r="string"==typeof t.label?t.label:t.key;e.push({page:t.page,label:r,group:s.groupLabel,description:e9[t.page]||"No description available"})}if(t.children){let r="string"==typeof t.label?t.label:t.key;t.children.forEach(t=>{if(ss(t.roles)){let a="string"==typeof t.label?t.label:t.key;e.push({page:t.page,label:a,group:`${s.groupLabel} > ${r}`,description:e9[t.page]||"No description available"})}})}})}),e},[]),o=(0,u.useMemo)(()=>{let e={};return i.forEach(s=>{e[s.group]||(e[s.group]=[]),e[s.group].push(s)}),e},[i]),[d,c]=(0,u.useState)(e||[]);return(0,u.useMemo)(()=>{c(e||[])},[e]),(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Internal User Page Visibility"}),(0,s.jsx)(ea.Badge,{variant:l?"secondary":"outline",children:l?`${d.length} page${1!==d.length?"s":""} selected`:"Not set (all pages visible)"})]}),t&&(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:t}),(0,s.jsx)("p",{className:"text-xs italic text-muted-foreground",children:"By default, all pages are visible to internal users. Select specific pages to restrict visibility."}),(0,s.jsx)("p",{className:"text-xs text-primary",children:"Note: Only pages accessible to internal user roles are shown here. Admin-only pages are excluded as they cannot be made visible to internal users regardless of this setting."})]}),(0,s.jsxs)(st.Collapsible,{className:"rounded-lg border border-border",children:[(0,s.jsxs)(st.CollapsibleTrigger,{className:"group flex w-full items-center justify-between rounded-lg px-3 py-2 text-sm font-medium hover:bg-muted",children:["Configure Page Visibility",(0,s.jsx)(e7.ChevronDown,{className:"size-4 transition-transform group-data-[panel-open]:rotate-180"})]}),(0,s.jsx)(st.CollapsibleContent,{className:"border-t border-border p-4",children:(0,s.jsxs)("div",{className:"space-y-4",children:[Object.entries(o).map(([e,t])=>(0,s.jsxs)("fieldset",{className:"space-y-2",children:[(0,s.jsx)("legend",{className:"text-xs font-semibold tracking-wide text-muted-foreground uppercase",children:e}),(0,s.jsx)("div",{className:"ml-4 space-y-2",children:t.map(e=>{let t=`page-visibility-${e.page}`;return(0,s.jsxs)("label",{htmlFor:t,className:"flex cursor-pointer items-start gap-2",children:[(0,s.jsx)(em.Checkbox,{id:t,checked:d.includes(e.page),onCheckedChange:s=>{var t,r;return t=e.page,r=!0===s,void c(e=>r?[...e,t]:e.filter(e=>e!==t))}}),(0,s.jsxs)("span",{className:"space-y-0.5",children:[(0,s.jsx)("span",{className:"block text-sm text-foreground",children:e.label}),(0,s.jsx)("span",{className:"block text-xs text-muted-foreground",children:e.description})]})]},e.page)})})]},e)),(0,s.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,s.jsx)(n.Button,{type:"button",onClick:()=>{a({enabled_ui_pages_internal_users:d.length>0?d:null})},disabled:r,children:"Save Page Visibility Settings"}),l&&(0,s.jsx)(n.Button,{type:"button",variant:"outline",onClick:()=>{c([]),a({enabled_ui_pages_internal_users:null})},disabled:r,children:"Reset to Default (All Pages)"})]})]})})]})]})}function sa({ariaLabel:e,checked:t,description:r,disabled:a,indented:n=!1,label:l,muted:i=!1,onCheckedChange:o}){return(0,s.jsxs)("div",{className:n?"ml-8 flex items-start gap-3":"flex items-start gap-3",children:[(0,s.jsx)(D.Switch,{checked:t,disabled:a,onCheckedChange:o,"aria-label":e}),(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)("p",{className:i?"text-sm font-medium text-muted-foreground":"text-sm font-medium text-foreground",children:l}),r&&(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:r})]})]})}function sn(){let e,{accessToken:n}=(0,t.default)(),{data:i,isLoading:o,isError:d,error:c}=(0,e5.useUISettings)(),{mutate:u,isPending:m,error:g}=(e=(0,M.useQueryClient)(),(0,L.useMutation)({mutationFn:async e=>{if(!n)throw Error("Access token is required");return(0,_.updateUiSettings)(n,e)},onSuccess:()=>{e.invalidateQueries({queryKey:e6.all})}})),h=i?.field_schema,x=h?.properties?.disable_model_add_for_internal_users,f=h?.properties?.disable_team_admin_delete_team_user,j=h?.properties?.require_auth_for_public_ai_hub,b=h?.properties?.forward_client_headers_to_llm_api,y=h?.properties?.forward_llm_provider_auth_headers,v=h?.properties?.enable_projects_ui,S=h?.properties?.enable_chat_ui,C=h?.properties?.enabled_ui_pages_internal_users,k=h?.properties?.disable_agents_for_internal_users,w=h?.properties?.allow_agents_for_team_admins,E=h?.properties?.disable_vector_stores_for_internal_users,I=h?.properties?.allow_vector_stores_for_team_admins,T=h?.properties?.scope_user_search_to_org,A=h?.properties?.disable_custom_api_keys,O=i?.values??{},F=!!O.disable_model_add_for_internal_users,P=!!O.disable_team_admin_delete_team_user,D=!!O.disable_agents_for_internal_users,U=!!O.disable_vector_stores_for_internal_users;return(0,s.jsxs)(l.Card,{children:[(0,s.jsx)(l.CardHeader,{children:(0,s.jsx)(l.CardTitle,{children:(0,s.jsx)("h3",{children:"UI Settings"})})}),(0,s.jsx)(l.CardContent,{children:o?(0,s.jsxs)("div",{role:"status","aria-label":"Loading UI settings",className:"space-y-3",children:[(0,s.jsx)(B.Skeleton,{className:"h-5 w-72"}),(0,s.jsx)(B.Skeleton,{className:"h-16 w-full"}),(0,s.jsx)(B.Skeleton,{className:"h-16 w-full"})]}):d?(0,s.jsxs)(r.Alert,{variant:"error",children:[(0,s.jsx)(a.AlertTitle,{children:"Could not load UI settings"}),c instanceof Error&&(0,s.jsx)(a.AlertDescription,{children:c.message})]}):(0,s.jsxs)("div",{className:"space-y-6",children:[h?.description&&(0,s.jsx)("p",{className:"text-sm text-foreground",children:h.description}),g&&(0,s.jsxs)(r.Alert,{variant:"error",children:[(0,s.jsx)(a.AlertTitle,{children:"Could not update UI settings"}),g instanceof Error&&(0,s.jsx)(a.AlertDescription,{children:g.message})]}),(0,s.jsx)(sa,{checked:F,disabled:m,onCheckedChange:e=>{u({disable_model_add_for_internal_users:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:x?.description??"Disable model add for internal users",label:"Disable model add for internal users",description:x?.description}),(0,s.jsx)(sa,{checked:P,disabled:m,onCheckedChange:e=>{u({disable_team_admin_delete_team_user:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:f?.description??"Disable team admin delete team user",label:"Disable team admin delete team user",description:f?.description}),(0,s.jsx)(sa,{checked:!!O.require_auth_for_public_ai_hub,disabled:m,onCheckedChange:e=>{u({require_auth_for_public_ai_hub:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:j?.description??"Require authentication for public AI Hub",label:"Require authentication for public AI Hub",description:j?.description}),(0,s.jsx)(sa,{checked:!!O.forward_client_headers_to_llm_api,disabled:m,onCheckedChange:e=>{u({forward_client_headers_to_llm_api:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:b?.description??"Forward client headers to LLM API",label:"Forward client headers to LLM API",description:b?.description??"Forwards client headers (Authorization, anthropic-beta, and x-* custom headers) to the upstream LLM. Enable for Claude Code with a Max subscription (forwards the OAuth token) or to pass custom/tracing headers through to the provider. Independent of the BYOK toggle — enable only the one(s) you need."}),(0,s.jsx)(sa,{checked:!!O.forward_llm_provider_auth_headers,disabled:m,onCheckedChange:e=>{u({forward_llm_provider_auth_headers:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:y?.description??"Forward LLM provider auth headers",label:"Forward LLM provider auth headers",description:y?.description??"Forwards provider auth headers (x-api-key, x-goog-api-key, api-key, ocp-apim-subscription-key) to the upstream LLM, overriding any deployment-configured key for that request. Enable for Claude Code BYOK (clients bring their own API key). Independent of the client-headers toggle — enable only the one(s) you need."}),v&&(0,s.jsx)(sa,{checked:!!O.enable_projects_ui,disabled:m,onCheckedChange:e=>{u({enable_projects_ui:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully. Refreshing page..."),setTimeout(()=>window.location.reload(),1e3)},onError:e=>{p.toast.fromError(e)}})},ariaLabel:v.description??"Enable Projects UI",label:"[BETA] Enable Projects (page will refresh)",description:v.description??"If enabled, shows the Projects feature in the UI sidebar and the project field in key management."}),(0,s.jsx)(sa,{checked:!!O.enable_chat_ui,disabled:m,onCheckedChange:e=>{u({enable_chat_ui:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully. Refreshing page..."),setTimeout(()=>window.location.reload(),1e3)},onError:e=>{p.toast.fromError(e)}})},ariaLabel:S?.description??"Enable Chat page",label:"[BETA] Enable Chat page (page will refresh)",description:S?.description??"If enabled, shows the Chat page in the UI sidebar, letting users chat with an LLM and connect their own MCP server credentials via OAuth."}),(0,s.jsx)(N.Separator,{}),(0,s.jsx)(sa,{checked:D,disabled:m,onCheckedChange:e=>{u({disable_agents_for_internal_users:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:k?.description??"Disable agents for internal users",label:"Disable agents for internal users",description:k?.description}),(0,s.jsx)(sa,{checked:!!O.allow_agents_for_team_admins,disabled:m||!D,onCheckedChange:e=>{u({allow_agents_for_team_admins:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:w?.description??"Allow agents for team admins",label:"Allow agents for team admins",description:w?.description,indented:!0,muted:!D}),(0,s.jsx)(N.Separator,{}),(0,s.jsx)(sa,{checked:U,disabled:m,onCheckedChange:e=>{u({disable_vector_stores_for_internal_users:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:E?.description??"Disable vector stores for internal users",label:"Disable vector stores for internal users",description:E?.description}),(0,s.jsx)(sa,{checked:!!O.allow_vector_stores_for_team_admins,disabled:m||!U,onCheckedChange:e=>{u({allow_vector_stores_for_team_admins:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:I?.description??"Allow vector stores for team admins",label:"Allow vector stores for team admins",description:I?.description,indented:!0,muted:!U}),(0,s.jsx)(N.Separator,{}),(0,s.jsx)(sa,{checked:!!O.scope_user_search_to_org,disabled:m,onCheckedChange:e=>{u({scope_user_search_to_org:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:T?.description??"Scope user search to organization",label:"Scope user search to organization",description:T?.description??"If enabled, the user search endpoint restricts results by organization. When off, any authenticated user can search all users."}),(0,s.jsx)(N.Separator,{}),(0,s.jsx)(sa,{checked:!!O.disable_custom_api_keys,disabled:m,onCheckedChange:e=>{u({disable_custom_api_keys:e},{onSuccess:()=>{p.toast.success("UI settings updated successfully")},onError:e=>{p.toast.fromError(e)}})},ariaLabel:A?.description??"Disable custom Virtual key values",label:"Disable custom Virtual key values",description:A?.description??"If true, users cannot specify custom key values. All keys must be auto-generated."}),(0,s.jsx)(N.Separator,{}),(0,s.jsx)(sr,{enabledPagesInternalUsers:O.enabled_ui_pages_internal_users,enabledPagesPropertyDescription:C?.description,isUpdating:m,onUpdate:e=>{u(e,{onSuccess:()=>{p.toast.success("Page visibility settings updated successfully")},onError:e=>{p.toast.fromError(e)}})}})]})})]})}var sl=e.i(66146),si=e.i(110204),so=e.i(714004);let sd={info:"Info",warning:"Warning",error:"Error"},sc=Object.keys(sd).map(e=>({value:e,label:sd[e]})),su={enabled:!1,message:"",severity:"info",revision:""};function sm(){let e,{accessToken:r}=(0,t.default)(),{data:a,isLoading:n}=(0,sl.useUserBanner)(r),{mutate:l,isPending:i}=(e=(0,M.useQueryClient)(),(0,L.useMutation)({mutationFn:async e=>{if(!r)throw Error("Access token is required");return await (0,_.updateUserBanner)(r,e)},onSuccess:()=>{e.invalidateQueries({queryKey:sl.userBannerKeys.all})}})),o=a??su;return(0,s.jsx)(sp,{persisted:o,isLoading:n,isPending:i,saveBanner:l},JSON.stringify(o))}function sp({persisted:e,isLoading:t,isPending:i,saveBanner:o}){let[d,c]=(0,u.useState)({enabled:e.enabled,message:e.message,severity:e.severity}),m=d.enabled&&""===d.message.trim();return(0,s.jsxs)(l.Card,{children:[(0,s.jsxs)(l.CardHeader,{children:[(0,s.jsx)(l.CardTitle,{children:"User Banner"}),(0,s.jsx)(l.CardDescription,{children:"Publish an announcement to all dashboard users. Markdown is supported; the banner appears below the header on every page until you unpublish it. Users can dismiss it, and it reappears whenever the content changes."})]}),(0,s.jsx)(l.CardContent,{children:t?(0,s.jsx)(B.Skeleton,{className:"h-40 w-full"}):(0,s.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)(D.Switch,{checked:d.enabled,onCheckedChange:e=>c({...d,enabled:e}),"aria-label":"Publish user banner"}),(0,s.jsx)(si.Label,{children:"Publish user banner"})]}),(0,s.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,s.jsx)(si.Label,{htmlFor:"user-banner-message",children:"Message"}),(0,s.jsx)(e_.Textarea,{id:"user-banner-message",value:d.message,maxLength:4e3,rows:3,placeholder:"**Scheduled maintenance** tonight at 10 PM UTC. See [status page](https://example.com).",onChange:e=>c({...d,message:e.target.value})}),m&&(0,s.jsx)("p",{className:"text-sm text-destructive",children:"Add a message before publishing."})]}),(0,s.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,s.jsx)(si.Label,{children:"Severity"}),(0,s.jsxs)(ep.Select,{items:sc,value:d.severity,onValueChange:e=>c({...d,severity:e??"info"}),children:[(0,s.jsx)(ep.SelectTrigger,{className:"w-48","aria-label":"Banner severity",children:(0,s.jsx)(ep.SelectValue,{placeholder:"Severity"})}),(0,s.jsx)(ep.SelectContent,{children:sc.map(e=>(0,s.jsx)(ep.SelectItem,{value:e.value,children:e.label},e.value))})]})]}),""!==d.message.trim()&&(0,s.jsxs)("div",{className:"flex flex-col gap-2",children:[(0,s.jsx)(si.Label,{children:"Preview"}),(0,s.jsxs)(r.Alert,{variant:d.severity,children:[so.SEVERITY_ICONS[d.severity],(0,s.jsx)(a.AlertDescription,{children:(0,s.jsx)(so.UserBannerMarkdown,{message:d.message})})]})]}),(0,s.jsx)("div",{children:(0,s.jsx)(n.Button,{onClick:()=>{o(d,{onSuccess:()=>{p.toast.success("User banner updated successfully")},onError:e=>{p.toast.fromError(e)}})},disabled:i||m,children:i?"Saving...":"Save banner"})})]})})]})}var s_=e.i(778917);let sg=(0,f.default)("plug-zap",[["path",{d:"M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z",key:"goz73y"}],["path",{d:"m2 22 3-3",key:"19mgm9"}],["path",{d:"M7.5 13.5 10 11",key:"7xgeeb"}],["path",{d:"M10.5 16.5 13 14",key:"10btkg"}],["path",{d:"m18 3-4 4h6l-4 4",key:"16psg9"}]]);var sh=e.i(431703);let sx=(0,sh.createApiClient)({getBaseUrl:_.getProxyBaseUrl,getAuthHeaderName:_.getGlobalLitellmHeaderName}),sf=async e=>sx.get("/config_overrides/cyberark",{accessToken:e}),sj=async(e,s)=>sx.post("/config_overrides/cyberark",{accessToken:e,body:s}),sb=async e=>sx.delete("/config_overrides/cyberark",{accessToken:e}),sy=async e=>sx.post("/config_overrides/cyberark/test_connection",{accessToken:e}),sv=(0,ee.createQueryKeys)("cyberArkConfig"),sS=()=>{let{accessToken:e}=(0,t.default)(),s={queryKey:sv.list({}),queryFn:async()=>{if(!e)throw Error("Access token is required");return sf(e)},enabled:!!e,staleTime:36e5,gcTime:36e5};return(0,J.useQuery)(s)},sC=e=>{let s=(0,M.useQueryClient)();return(0,L.useMutation)({mutationFn:async s=>{if(!e)throw Error("Access token is required");return sj(e,s)},onSuccess:()=>{s.invalidateQueries({queryKey:sv.all})}})};function sk({onAdd:e}){return(0,s.jsxs)("div",{className:"flex w-full flex-col items-center rounded-lg border border-dashed border-border bg-card p-12 text-center",children:[(0,s.jsx)("div",{className:"mb-4 flex size-12 items-center justify-center rounded-full bg-muted",children:(0,s.jsx)(y.KeyRound,{className:"size-6 text-muted-foreground"})}),(0,s.jsx)("h4",{className:"text-base font-semibold text-foreground",children:"No CyberArk Configuration Found"}),(0,s.jsx)("p",{className:"mx-auto mt-2 max-w-md text-sm text-muted-foreground",children:"Configure CyberArk Conjur to securely manage provider API keys and secrets for your LiteLLM deployment."}),(0,s.jsx)(n.Button,{size:"lg",onClick:e,className:"mt-4",children:"Configure CyberArk"})]})}let sw=new Set(["cyberark_api_key","client_key"]),sN={cyberark_api_base:"Conjur Server URL",cyberark_account:"Account",cyberark_username:"Username",cyberark_api_key:"API Key",client_cert:"Client Certificate",client_key:"Client Key",ssl_verify:"SSL Verification",refresh_interval:"Token Refresh Interval (seconds)"},sE=[{title:"Connection",fields:["cyberark_api_base","cyberark_account","cyberark_username"]},{title:"API Key Authentication",subtitle:"Use a Conjur API key to authenticate. Only one auth method is required.",fields:["cyberark_api_key"]},{title:"Certificate Authentication",subtitle:"Use a client TLS certificate and key to authenticate. Only one auth method is required.",fields:["client_cert","client_key"]},{title:"Advanced",subtitle:"Optional TLS and token caching settings.",fields:["ssl_verify","refresh_interval"]}],sI=({isVisible:e,onCancel:r,onSuccess:a})=>{let{accessToken:l}=(0,t.default)(),{data:i}=sS(),{mutate:o,isPending:d}=sC(l),c=(0,u.useMemo)(()=>i?.field_schema?.properties??{},[i]),m=(0,u.useMemo)(()=>i?.values??{},[i]),_=(0,u.useMemo)(()=>sE.flatMap(e=>e.fields).filter(e=>void 0!==c[e]),[c]),h=(0,u.useMemo)(()=>Object.fromEntries(_.map(e=>[e,sw.has(e)?"":m[e]??""])),[_,m]),x=(0,u.useMemo)(()=>g.z.object(Object.fromEntries(_.map(e=>[e,"cyberark_api_base"===e?g.z.string().refine(e=>0===e.length||/^https?:\/\/.+/.test(e),{message:"Must start with http:// or https://"}):g.z.string()]))),[_]),f=(0,I.useZodForm)(x,{values:h}),j=e=>{o(Object.fromEntries(Object.entries(e).flatMap(([e,s])=>null!=s&&""!==s?[[e,s]]:sw.has(e)?[]:[[e,""]])),{onSuccess:()=>{p.toast.success("CyberArk configuration updated successfully"),a()},onError:e=>{p.toast.fromError(e)}})},b=()=>{f.reset(h),r()},y=e=>{let t=c[e];if(!t)return null;let r=sw.has(e),a=m[e],n=r&&null!=a&&""!==a?`Leave blank to keep existing (${a})`:t?.description;return(0,s.jsx)(k.FormField,{control:f.control,name:e,label:sN[e]??e,children:({ref:e,...a})=>r?(0,s.jsx)(eu.PasswordInput,{ref:e,placeholder:n,...a}):(0,s.jsx)(w.Input,{ref:e,placeholder:t?.description,...a})},e)};return(0,s.jsx)(eB.Dialog,{open:e,onOpenChange:e=>!e&&b(),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[700px]",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"Edit CyberArk Configuration"})}),(0,s.jsx)("form",{onSubmit:f.handleSubmit(j),children:sE.map((e,t)=>(0,s.jsxs)("div",{children:[t>0&&(0,s.jsx)(N.Separator,{className:"my-6"}),(0,s.jsx)("h5",{className:"mb-1 text-base font-semibold text-foreground",children:e.title}),e.subtitle&&(0,s.jsx)("p",{className:"mb-4 text-sm text-muted-foreground",children:e.subtitle}),(0,s.jsx)(C.FieldGroup,{children:e.fields.map(y)})]},e.title))}),(0,s.jsx)(eB.DialogFooter,{children:(0,s.jsxs)("div",{className:"flex items-center justify-end gap-2",children:[(0,s.jsx)(n.Button,{type:"button",variant:"outline",onClick:b,disabled:d,children:"Cancel"}),(0,s.jsxs)(n.Button,{type:"button",disabled:d,onClick:()=>void f.handleSubmit(j)(),children:[d&&(0,s.jsx)(E.UiLoadingSpinner,{className:"size-4 mr-1"}),d?"Saving...":"Save"]})]})})]})})};function sT({children:e,label:t}){return(0,s.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-3",children:[(0,s.jsx)("dt",{className:"bg-muted/50 px-4 py-3 text-sm font-medium text-foreground",children:t}),(0,s.jsx)("dd",{className:"px-4 py-3 text-sm text-foreground sm:col-span-2",children:e})]})}function sA(){let e,{accessToken:i}=(0,t.default)(),{data:o,isLoading:c,isError:m,error:_}=sS(),{mutate:g,isPending:h}=(e=(0,M.useQueryClient)(),(0,L.useMutation)({mutationFn:async()=>{if(!i)throw Error("Access token is required");return sb(i)},onSuccess:()=>{e.invalidateQueries({queryKey:sv.all})}})),{mutate:x,isPending:f}=sC(i),[j,b]=(0,u.useState)(!1),[v,S]=(0,u.useState)(!1),[C,k]=(0,u.useState)(null),[w,N]=(0,u.useState)(!1),E=o?.values??{},I=!!E.cyberark_api_base,T=async()=>{if(i){N(!0);try{let e=await sy(i);p.toast.success(e.message||"Connection to CyberArk Conjur successful!")}catch(e){p.toast.fromError(e)}finally{N(!1)}}},A=Object.entries(E).filter(([,e])=>null!=e&&""!==e);return(0,s.jsxs)(s.Fragment,{children:[(()=>c?(0,s.jsx)(l.Card,{role:"status","aria-label":"Loading CyberArk configuration",children:(0,s.jsxs)(l.CardContent,{className:"space-y-3",children:[(0,s.jsx)(B.Skeleton,{className:"h-8 w-64"}),(0,s.jsx)(B.Skeleton,{className:"h-40 w-full"})]})}):m?(0,s.jsx)(l.Card,{children:(0,s.jsx)(l.CardContent,{children:(0,s.jsxs)(r.Alert,{variant:"error",children:[(0,s.jsx)(a.AlertTitle,{children:"Could not load CyberArk configuration"}),_ instanceof Error&&(0,s.jsx)(a.AlertDescription,{children:_.message})]})})}):(0,s.jsxs)(l.Card,{children:[(0,s.jsxs)(l.CardHeader,{children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)(y.KeyRound,{className:"size-6 text-muted-foreground"}),(0,s.jsxs)("div",{children:[(0,s.jsx)(l.CardTitle,{children:(0,s.jsx)("h3",{children:"CyberArk Conjur"})}),(0,s.jsx)(l.CardDescription,{children:"Manage secret manager configuration"})]})]}),I&&(0,s.jsxs)(l.CardAction,{className:"flex flex-wrap gap-2",children:[(0,s.jsxs)(n.Button,{type:"button",variant:"outline",disabled:w,onClick:T,children:[(0,s.jsx)(sg,{}),w?"Testing...":"Test Connection"]}),(0,s.jsxs)(n.Button,{type:"button",variant:"outline",onClick:()=>b(!0),children:[(0,s.jsx)(X.Edit,{}),"Edit Configuration"]}),(0,s.jsxs)(n.Button,{type:"button",variant:"destructive",onClick:()=>S(!0),children:[(0,s.jsx)(Z.Trash2,{}),"Delete Configuration"]})]})]}),(0,s.jsxs)(l.CardContent,{className:"space-y-6",children:[I&&(0,s.jsxs)(r.Alert,{variant:"info",children:[(0,s.jsx)(d.Info,{}),(0,s.jsx)(a.AlertTitle,{children:"Configuration changes are hot-reloaded across all proxy instances"}),(0,s.jsx)(a.AlertDescription,{children:(0,s.jsxs)("a",{href:"https://docs.litellm.ai/docs/secret_managers/cyberark",target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-1",children:["View documentation",(0,s.jsx)(s_.ExternalLink,{className:"size-3"})]})})]}),I?A.length>0&&(0,s.jsxs)("dl",{className:"divide-y divide-border overflow-hidden rounded-md border border-border",children:[(0,s.jsx)(sT,{label:"Auth Method",children:E.cyberark_api_key?"API Key":E.client_cert&&E.client_key?"TLS Certificate":"None"}),A.map(([e])=>{let t;return(0,s.jsx)(sT,{label:sN[e]??e,children:(t=E[e])?sw.has(e)?(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("span",{className:"font-mono text-muted-foreground",children:t}),(0,s.jsx)(n.Button,{type:"button",variant:"ghost",size:"icon-sm","aria-label":`Clear ${sN[e]??e}`,onClick:()=>k(e),children:(0,s.jsx)(Z.Trash2,{className:"size-3.5"})})]}):(0,s.jsx)("span",{className:"font-mono text-muted-foreground",children:t}):(0,s.jsx)("span",{className:"text-muted-foreground italic",children:"Not configured"})},e)})]}):(0,s.jsx)(sk,{onAdd:()=>b(!0)})]})]}))(),(0,s.jsx)(sI,{isVisible:j,onCancel:()=>b(!1),onSuccess:()=>b(!1)}),(0,s.jsx)(eR.default,{isOpen:v,title:"Delete CyberArk Configuration?",message:"Models using CyberArk secrets will lose access to their API keys until a new configuration is saved.",resourceInformationTitle:"CyberArk Configuration",resourceInformation:[{label:"Conjur Server URL",value:E.cyberark_api_base}],onCancel:()=>S(!1),onOk:()=>{g(void 0,{onSuccess:()=>{p.toast.success("CyberArk configuration deleted"),S(!1)},onError:e=>p.toast.fromError(e)})},confirmLoading:h}),(0,s.jsx)(eR.default,{isOpen:null!==C,title:`Clear ${C?sN[C]??C:""}?`,message:"This will remove the stored value.",resourceInformationTitle:"Field",resourceInformation:[{label:"Field",value:C?sN[C]??C:""}],onCancel:()=>k(null),onOk:()=>{C&&x({[C]:""},{onSuccess:()=>{p.toast.success(`${sN[C]??C} cleared`),k(null)},onError:e=>p.toast.fromError(e)})},confirmLoading:f})]})}let sO=async e=>{let s=(0,_.getProxyBaseUrl)(),t=s?`${s}/config_overrides/hashicorp_vault`:"/config_overrides/hashicorp_vault",r=await fetch(t,{method:"GET",headers:{[(0,_.getGlobalLitellmHeaderName)()]:`Bearer ${e}`}});if(!r.ok){let e=await r.json();throw Error((0,sh.deriveErrorMessage)(e))}return await r.json()},sL=async(e,s)=>{let t=(0,_.getProxyBaseUrl)(),r=t?`${t}/config_overrides/hashicorp_vault`:"/config_overrides/hashicorp_vault",a=await fetch(r,{method:"POST",headers:{[(0,_.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(s)});if(!a.ok){let e=await a.json();throw Error((0,sh.deriveErrorMessage)(e))}return await a.json()},sM=async e=>{let s=(0,_.getProxyBaseUrl)(),t=s?`${s}/config_overrides/hashicorp_vault`:"/config_overrides/hashicorp_vault",r=await fetch(t,{method:"DELETE",headers:{[(0,_.getGlobalLitellmHeaderName)()]:`Bearer ${e}`}});if(!r.ok){let e=await r.json();throw Error((0,sh.deriveErrorMessage)(e))}return await r.json()},sF=async e=>{let s=(0,_.getProxyBaseUrl)(),t=s?`${s}/config_overrides/hashicorp_vault/test_connection`:"/config_overrides/hashicorp_vault/test_connection",r=await fetch(t,{method:"POST",headers:{[(0,_.getGlobalLitellmHeaderName)()]:`Bearer ${e}`}});if(!r.ok){let e=await r.json();throw Error((0,sh.deriveErrorMessage)(e))}return await r.json()},sP=(0,ee.createQueryKeys)("hashicorpVaultConfig"),sD=()=>{let{accessToken:e}=(0,t.default)();return(0,J.useQuery)({queryKey:sP.list({}),queryFn:async()=>{if(!e)throw Error("Access token is required");return sO(e)},enabled:!!e,staleTime:36e5,gcTime:36e5})},sU=e=>{let s=(0,M.useQueryClient)();return(0,L.useMutation)({mutationFn:async s=>{if(!e)throw Error("Access token is required");return sL(e,s)},onSuccess:()=>{s.invalidateQueries({queryKey:sP.all})}})},sB=new Set(["vault_token","approle_secret_id","client_key"]),sz={vault_addr:"Vault Address",vault_namespace:"Namespace",vault_mount_name:"KV Mount Name",vault_path_prefix:"Path Prefix",vault_token:"Token",approle_role_id:"Role ID",approle_secret_id:"Secret ID",approle_mount_path:"Mount Path",client_cert:"Client Certificate",client_key:"Client Key",vault_cert_role:"Certificate Role"},sR=[{title:"Connection",fields:["vault_addr","vault_namespace","vault_mount_name","vault_path_prefix"]},{title:"Token Authentication",subtitle:"Use a Vault token to authenticate. Only one auth method is required.",fields:["vault_token"]},{title:"AppRole Authentication",subtitle:"Use AppRole credentials to authenticate. Only one auth method is required.",fields:["approle_role_id","approle_secret_id","approle_mount_path"]},{title:"TLS",subtitle:"Optional client certificate for mTLS.",fields:["client_cert","client_key","vault_cert_role"]}],sG=({isVisible:e,onCancel:r,onSuccess:a})=>{let{accessToken:l}=(0,t.default)(),{data:i}=sD(),{mutate:o,isPending:d}=sU(l),c=(0,u.useMemo)(()=>i?.field_schema?.properties??{},[i]),m=(0,u.useMemo)(()=>i?.values??{},[i]),_=(0,u.useMemo)(()=>sR.flatMap(e=>e.fields).filter(e=>void 0!==c[e]),[c]),h=(0,u.useMemo)(()=>Object.fromEntries(_.map(e=>[e,sB.has(e)?"":m[e]??""])),[_,m]),x=(0,u.useMemo)(()=>g.z.object(Object.fromEntries(_.map(e=>[e,"vault_addr"===e?g.z.string().refine(e=>0===e.length||/^https?:\/\/.+/.test(e),{message:"Must start with http:// or https://"}):g.z.string()]))),[_]),f=(0,I.useZodForm)(x,{values:h}),j=e=>{o(Object.fromEntries(Object.entries(e).flatMap(([e,s])=>null!=s&&""!==s?[[e,s]]:sB.has(e)?[]:[[e,""]])),{onSuccess:()=>{p.toast.success("Hashicorp Vault configuration updated successfully"),a()},onError:e=>{p.toast.fromError(e)}})},b=()=>{f.reset(h),r()},y=e=>{let t=c[e];if(!t)return null;let r=sB.has(e),a=m[e],n=r&&null!=a&&""!==a?`Leave blank to keep existing (${a})`:t?.description;return(0,s.jsx)(k.FormField,{control:f.control,name:e,label:sz[e]??e,children:({ref:e,...a})=>r?(0,s.jsx)(eu.PasswordInput,{ref:e,placeholder:n,...a}):(0,s.jsx)(w.Input,{ref:e,placeholder:t?.description,...a})},e)};return(0,s.jsx)(eB.Dialog,{open:e,onOpenChange:e=>!e&&b(),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[700px]",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"Edit Hashicorp Vault Configuration"})}),(0,s.jsx)("form",{onSubmit:f.handleSubmit(j),children:sR.map((e,t)=>(0,s.jsxs)("div",{children:[t>0&&(0,s.jsx)(N.Separator,{className:"my-6"}),(0,s.jsx)("h5",{className:"mb-1 text-base font-semibold text-foreground",children:e.title}),e.subtitle&&(0,s.jsx)("p",{className:"mb-4 text-sm text-muted-foreground",children:e.subtitle}),(0,s.jsx)(C.FieldGroup,{children:e.fields.map(y)})]},e.title))}),(0,s.jsx)(eB.DialogFooter,{children:(0,s.jsxs)("div",{className:"flex items-center justify-end gap-2",children:[(0,s.jsx)(n.Button,{type:"button",variant:"outline",onClick:b,disabled:d,children:"Cancel"}),(0,s.jsxs)(n.Button,{type:"button",disabled:d,onClick:()=>void f.handleSubmit(j)(),children:[d&&(0,s.jsx)(E.UiLoadingSpinner,{className:"size-4 mr-1"}),d?"Saving...":"Save"]})]})})]})})};function sV({onAdd:e}){return(0,s.jsxs)("div",{className:"flex w-full flex-col items-center rounded-lg border border-dashed border-border bg-card p-12 text-center",children:[(0,s.jsx)("div",{className:"mb-4 flex size-12 items-center justify-center rounded-full bg-muted",children:(0,s.jsx)(y.KeyRound,{className:"size-6 text-muted-foreground"})}),(0,s.jsx)("h4",{className:"text-base font-semibold text-foreground",children:"No Vault Configuration Found"}),(0,s.jsx)("p",{className:"mx-auto mt-2 max-w-md text-sm text-muted-foreground",children:"Configure Hashicorp Vault to securely manage provider API keys and secrets for your LiteLLM deployment."}),(0,s.jsx)(n.Button,{size:"lg",onClick:e,className:"mt-4",children:"Configure Vault"})]})}function s$({children:e,label:t}){return(0,s.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-3",children:[(0,s.jsx)("dt",{className:"bg-muted/50 px-4 py-3 text-sm font-medium text-foreground",children:t}),(0,s.jsx)("dd",{className:"px-4 py-3 text-sm text-foreground sm:col-span-2",children:e})]})}function sH(){let e,{accessToken:i}=(0,t.default)(),{data:o,isLoading:c,isError:m,error:_}=sD(),{mutate:g,isPending:h}=(e=(0,M.useQueryClient)(),(0,L.useMutation)({mutationFn:async()=>{if(!i)throw Error("Access token is required");return sM(i)},onSuccess:()=>{e.invalidateQueries({queryKey:sP.all})}})),{mutate:x,isPending:f}=sU(i),[j,b]=(0,u.useState)(!1),[v,S]=(0,u.useState)(!1),[C,k]=(0,u.useState)(null),[w,N]=(0,u.useState)(!1),E=o?.values??{},I=!!E.vault_addr,T=async()=>{if(i){N(!0);try{let e=await sF(i);p.toast.success(e.message||"Connection to Vault successful!")}catch(e){p.toast.fromError(e)}finally{N(!1)}}},A=Object.entries(E).filter(([,e])=>null!=e&&""!==e);return(0,s.jsxs)(s.Fragment,{children:[c?(0,s.jsx)(l.Card,{role:"status","aria-label":"Loading Hashicorp Vault configuration",children:(0,s.jsxs)(l.CardContent,{className:"space-y-3",children:[(0,s.jsx)(B.Skeleton,{className:"h-8 w-64"}),(0,s.jsx)(B.Skeleton,{className:"h-40 w-full"})]})}):m?(0,s.jsx)(l.Card,{children:(0,s.jsx)(l.CardContent,{children:(0,s.jsxs)(r.Alert,{variant:"error",children:[(0,s.jsx)(a.AlertTitle,{children:"Could not load Hashicorp Vault configuration"}),_ instanceof Error&&(0,s.jsx)(a.AlertDescription,{children:_.message})]})})}):(0,s.jsxs)(l.Card,{children:[(0,s.jsxs)(l.CardHeader,{children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsx)(y.KeyRound,{className:"size-6 text-muted-foreground"}),(0,s.jsxs)("div",{children:[(0,s.jsx)(l.CardTitle,{children:(0,s.jsx)("h3",{children:"Hashicorp Vault"})}),(0,s.jsx)(l.CardDescription,{children:"Manage secret manager configuration"})]})]}),I&&(0,s.jsxs)(l.CardAction,{className:"flex flex-wrap gap-2",children:[(0,s.jsxs)(n.Button,{type:"button",variant:"outline",disabled:w,onClick:T,children:[(0,s.jsx)(sg,{}),w?"Testing...":"Test Connection"]}),(0,s.jsxs)(n.Button,{type:"button",variant:"outline",onClick:()=>b(!0),children:[(0,s.jsx)(X.Edit,{}),"Edit Configuration"]}),(0,s.jsxs)(n.Button,{type:"button",variant:"destructive",onClick:()=>S(!0),children:[(0,s.jsx)(Z.Trash2,{}),"Delete Configuration"]})]})]}),(0,s.jsxs)(l.CardContent,{className:"space-y-6",children:[I&&(0,s.jsxs)(r.Alert,{variant:"info",children:[(0,s.jsx)(d.Info,{}),(0,s.jsx)(a.AlertTitle,{children:'Secrets must be stored with the field name "key"'}),(0,s.jsxs)(a.AlertDescription,{children:[(0,s.jsx)("code",{className:"block font-mono",children:"vault kv put secret/SECRET_NAME key=secret_value"}),(0,s.jsxs)("a",{href:"https://docs.litellm.ai/docs/secret_managers/hashicorp_vault",target:"_blank",rel:"noreferrer",className:"inline-flex items-center gap-1",children:["View documentation",(0,s.jsx)(s_.ExternalLink,{className:"size-3"})]})]})]}),I?A.length>0&&(0,s.jsxs)("dl",{className:"divide-y divide-border overflow-hidden rounded-md border border-border",children:[(0,s.jsx)(s$,{label:"Auth Method",children:E.approle_role_id||E.approle_secret_id?"AppRole":E.client_cert&&E.client_key?"TLS Certificate":E.vault_token?"Token":"None"}),A.map(([e])=>{let t;return(0,s.jsx)(s$,{label:sz[e]??e,children:(t=E[e])?sB.has(e)?(0,s.jsxs)("div",{className:"flex items-center justify-between gap-2",children:[(0,s.jsx)("span",{className:"font-mono text-muted-foreground",children:t}),(0,s.jsx)(n.Button,{type:"button",variant:"ghost",size:"icon-sm","aria-label":`Clear ${sz[e]??e}`,onClick:()=>k(e),children:(0,s.jsx)(Z.Trash2,{className:"size-3.5"})})]}):(0,s.jsx)("span",{className:"font-mono text-muted-foreground",children:t}):(0,s.jsx)("span",{className:"text-muted-foreground italic",children:"Not configured"})},e)})]}):(0,s.jsx)(sV,{onAdd:()=>b(!0)})]})]}),(0,s.jsx)(sG,{isVisible:j,onCancel:()=>b(!1),onSuccess:()=>b(!1)}),(0,s.jsx)(eR.default,{isOpen:v,title:"Delete Hashicorp Vault Configuration?",message:"Models using Vault secrets will lose access to their API keys until a new configuration is saved.",resourceInformationTitle:"Vault Configuration",resourceInformation:[{label:"Vault Address",value:E.vault_addr}],onCancel:()=>S(!1),onOk:()=>{g(void 0,{onSuccess:()=>{p.toast.success("Hashicorp Vault configuration deleted"),S(!1)},onError:e=>p.toast.fromError(e)})},confirmLoading:h}),(0,s.jsx)(eR.default,{isOpen:null!==C,title:`Clear ${C?sz[C]??C:""}?`,message:"This will remove the stored value.",resourceInformationTitle:"Field",resourceInformation:[{label:"Field",value:C?sz[C]??C:""}],onCancel:()=>k(null),onOk:()=>{C&&x({[C]:""},{onSuccess:()=>{p.toast.success(`${sz[C]??C} cleared`),k(null)},onError:e=>p.toast.fromError(e)})},confirmLoading:f})]})}var sq=e.i(788699),sK=e.i(107233);let sQ="(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}",sW="[a-fA-F\\d]{1,4}",sX=`(?:(?:${sW}:){7}(?:${sW}|:)|(?:${sW}:){6}(?:${sQ}|:${sW}|:)|(?:${sW}:){5}(?::${sQ}|(?::${sW}){1,2}|:)|(?:${sW}:){4}(?:(?::${sW}){0,1}:${sQ}|(?::${sW}){1,3}|:)|(?:${sW}:){3}(?:(?::${sW}){0,2}:${sQ}|(?::${sW}){1,4}|:)|(?:${sW}:){2}(?:(?::${sW}){0,3}:${sQ}|(?::${sW}){1,5}|:)|(?:${sW}:){1}(?:(?::${sW}){0,4}:${sQ}|(?::${sW}){1,6}|:)|(?::(?:(?::${sW}){0,5}:${sQ}|(?::${sW}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?`,sY=RegExp(`(?:^(?:(?:(?:[a-z]+:)?//)|www\\.)(?:\\S+(?::\\S*)?@)?(?:localhost|${sQ}|${sX}|(?:(?:[a-z\\u00a1-\\uffff0-9][-_]*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))(?::\\d{2,5})?(?:[/?#][^\\s"]*)?$)`,"i"),sZ={name:g.z.string().min(1,"Required"),display_name:g.z.string().min(1,"Required"),url:g.z.string().min(1,"Required").refine(e=>""===e||e.length<=2048&&sY.test(e),"Must be a valid URL"),plugin_key:g.z.string().optional()},sJ=g.z.object(sZ),s0="rounded-sm bg-muted px-1 py-0.5 font-mono text-xs",s1={name:"",display_name:"",url:"",plugin_key:void 0};function s2(){let{accessToken:e}=(0,t.default)(),[r,a]=(0,u.useState)([]),[o,d]=(0,u.useState)(!0),[c,m]=(0,u.useState)(!1),[p,g]=(0,u.useState)(!1),[h,x]=(0,u.useState)(null),[f,j]=(0,u.useState)(!1),b=(0,I.useZodForm)(sJ,{defaultValues:s1});(0,u.useEffect)(()=>{e&&(0,_.getConfigFieldSetting)(e,"plugins").then(e=>{let s=e?.field_value;a(Array.isArray(s)?s:[])}).catch(()=>a([])).finally(()=>d(!1))},[e]);let y=async s=>{if(e){m(!0);try{await (0,_.updateConfigFieldSetting)(e,"plugins",s),a(s)}finally{m(!1)}}},v=async e=>{let s=null!==h?r.map((s,t)=>t===h?e:s):[...r,e];await y(s),g(!1)};return(0,s.jsxs)(l.Card,{children:[(0,s.jsxs)(l.CardHeader,{children:[(0,s.jsx)("h4",{className:"text-base font-semibold text-foreground",children:"Plugins"}),(0,s.jsx)("p",{className:"text-sm text-foreground",children:"Register external services as plugins. Once added, users can toggle to the plugin from the mode switcher in the top-left of the sidebar."}),(0,s.jsxs)("p",{className:"text-xs text-muted-foreground",children:["Each plugin must expose ",(0,s.jsx)("code",{className:s0,children:"GET /api/plugin-manifest"})," returning nav items and capabilities."]})]}),(0,s.jsxs)(l.CardContent,{children:[(0,s.jsxs)(n.Button,{className:"mb-4",onClick:()=>{x(null),j(!1),b.reset(s1),g(!0)},children:[(0,s.jsx)(sK.Plus,{}),"Add Plugin"]}),(0,s.jsxs)(i.Table,{children:[(0,s.jsx)(i.TableHeader,{children:(0,s.jsxs)(i.TableRow,{children:[(0,s.jsx)(i.TableHead,{children:"Name"}),(0,s.jsx)(i.TableHead,{children:"Display Name"}),(0,s.jsx)(i.TableHead,{children:"URL"}),(0,s.jsx)(i.TableHead,{children:"Plugin Key"}),(0,s.jsx)(i.TableHead,{children:"Actions"})]})}),(0,s.jsx)(i.TableBody,{children:o?(0,s.jsx)(i.TableRow,{children:(0,s.jsx)(i.TableCell,{colSpan:5,className:"py-6 text-center",children:(0,s.jsx)(E.UiLoadingSpinner,{className:"mx-auto size-6 text-muted-foreground"})})}):0===r.length?(0,s.jsx)(i.TableRow,{children:(0,s.jsx)(i.TableCell,{colSpan:5,className:"py-6 text-center text-sm text-muted-foreground",children:"No data"})}):r.map((e,t)=>(0,s.jsxs)(i.TableRow,{children:[(0,s.jsx)(i.TableCell,{children:(0,s.jsx)("code",{className:s0,children:e.name})}),(0,s.jsx)(i.TableCell,{children:e.display_name}),(0,s.jsx)(i.TableCell,{children:(0,s.jsx)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",children:e.url})}),(0,s.jsx)(i.TableCell,{children:e.plugin_key?(0,s.jsx)("code",{className:s0,children:"•".repeat(8)}):(0,s.jsx)("span",{className:"text-muted-foreground",children:"—"})}),(0,s.jsx)(i.TableCell,{children:(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(n.Button,{variant:"outline",size:"icon-sm","aria-label":`Edit ${e.name}`,onClick:()=>{x(t),j(!1),b.reset({...r[t],plugin_key:""}),g(!0)},children:(0,s.jsx)(sq.Pencil,{})}),(0,s.jsx)(n.Button,{variant:"destructive",size:"icon-sm","aria-label":`Delete ${e.name}`,onClick:()=>{y(r.filter((e,s)=>s!==t))},children:(0,s.jsx)(Z.Trash2,{})})]})})]},e.name))})]})]}),(0,s.jsx)(eB.Dialog,{open:p,onOpenChange:e=>!e&&g(!1),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:null!==h?"Edit Plugin":"Add Plugin"})}),(0,s.jsx)("form",{onSubmit:e=>e.preventDefault(),noValidate:!0,style:{marginTop:16},children:(0,s.jsxs)(C.FieldGroup,{children:[(0,s.jsx)(k.FormField,{control:b.control,name:"name",label:"Name (identifier)",description:"Used in URLs and config. No spaces. E.g. litellm-platform-plugin",children:({ref:e,...t})=>(0,s.jsx)(w.Input,{...t,ref:e,placeholder:"litellm-platform-plugin"})}),(0,s.jsx)(k.FormField,{control:b.control,name:"display_name",label:"Display Name",children:({ref:e,...t})=>(0,s.jsx)(w.Input,{...t,ref:e,placeholder:"Agent Control Plane"})}),(0,s.jsx)(k.FormField,{control:b.control,name:"url",label:"URL",description:"Base URL of the plugin service",children:({ref:e,...t})=>(0,s.jsx)(w.Input,{...t,ref:e,placeholder:"https://your-plugin.example.com"})}),(0,s.jsx)(k.FormField,{control:b.control,name:"plugin_key",label:"Plugin Key",description:"Optional. The plugin's own credential, injected as Authorization: Bearer only when litellm reverse-proxies API calls to the plugin's backend (/plugin-proxy//*). Leave blank for plugins that use the forwarded litellm user token (e.g. iframe plugins) — that path uses the user's token, not this key.",children:({ref:e,...t})=>(0,s.jsxs)(P.InputGroup,{children:[(0,s.jsx)(P.InputGroupInput,{...t,ref:e,type:f?"text":"password",value:t.value??"",placeholder:null!==h?"Leave blank to keep current key":"sk-... (optional)"}),(0,s.jsx)(P.InputGroupAddon,{align:"inline-end",children:(0,s.jsx)(P.InputGroupButton,{size:"icon-xs",onClick:()=>j(!f),"aria-label":f?"Hide plugin key":"Show plugin key",children:f?(0,s.jsx)(eq.EyeOff,{}):(0,s.jsx)(eH.Eye,{})})})]})})]})}),(0,s.jsxs)(eB.DialogFooter,{children:[(0,s.jsx)(n.Button,{variant:"outline",onClick:()=>g(!1),children:"Cancel"}),(0,s.jsx)(n.Button,{onClick:b.handleSubmit(v),disabled:c,"aria-busy":c,children:"Save"})]})]})})]})}let s4=({isAddSSOModalVisible:e,isInstructionsModalVisible:t,handleAddSSOOk:r,handleAddSSOCancel:a,handleShowInstructions:l,handleInstructionsOk:i,handleInstructionsCancel:o,form:d,accessToken:c,ssoConfigured:m=!1})=>{let[g,h]=(0,u.useState)(!1),x=(0,G.useWatch)({control:d.control,name:"sso_provider"}),f=(0,G.useWatch)({control:d.control,name:"use_role_mappings"});(0,u.useEffect)(()=>{(async()=>{if(e&&c)try{let e=await (0,_.getSSOSettings)(c);if(e&&e.values){let s=(e=>{if(e.google_client_id)return"google";if(e.microsoft_client_id)return"microsoft";if(e.generic_client_id){let s="string"==typeof e.generic_authorization_endpoint?e.generic_authorization_endpoint:"";return s.includes("okta")||s.includes("auth0")?"okta":"generic"}return e.saml_idp_metadata_url||e.saml_idp_metadata_xml?"saml":null})(e.values),t={};if(e.values.role_mappings){let s=e.values.role_mappings,r=e=>e&&0!==e.length?e.join(", "):"";t={use_role_mappings:!0,group_claim:s.group_claim,default_role:s.default_role||"internal_user",proxy_admin_teams:r(s.roles?.proxy_admin),admin_viewer_teams:r(s.roles?.proxy_admin_viewer),internal_user_teams:r(s.roles?.internal_user),internal_viewer_teams:r(s.roles?.internal_user_viewer)}}let r={sso_provider:s??"",proxy_base_url:e.values.proxy_base_url,user_email:e.values.user_email,google_client_id:e.values.google_client_id,google_client_secret:e.values.google_client_secret,microsoft_client_id:e.values.microsoft_client_id,microsoft_client_secret:e.values.microsoft_client_secret,microsoft_tenant:e.values.microsoft_tenant,generic_client_id:e.values.generic_client_id,generic_client_secret:e.values.generic_client_secret,generic_authorization_endpoint:e.values.generic_authorization_endpoint,generic_token_endpoint:e.values.generic_token_endpoint,generic_userinfo_endpoint:e.values.generic_userinfo_endpoint,generic_scope:e.values.generic_scope,saml_idp_metadata_url:e.values.saml_idp_metadata_url,saml_idp_metadata_xml:e.values.saml_idp_metadata_xml,saml_sp_entity_id:e.values.saml_sp_entity_id,...t,saml_allow_unsolicited:"true"===e.values.saml_allow_unsolicited};d.reset({...ev,...r})}}catch(e){console.error("Failed to load SSO settings:",e)}})()},[e,c,d]);let j=async e=>{if(!c)return void p.toast.fromError("No access token available");try{let{proxy_admin_teams:s,admin_viewer_teams:t,internal_user_teams:r,internal_viewer_teams:a,default_role:n,group_claim:i,use_role_mappings:o,...d}=e,u={...d};if("boolean"==typeof u.saml_allow_unsolicited&&(u.saml_allow_unsolicited=u.saml_allow_unsolicited?"true":"false"),o){let e=e=>e&&""!==e.trim()?e.split(",").map(e=>e.trim()).filter(e=>e.length>0):[];u.role_mappings={provider:"generic",group_claim:i,default_role:(n?({internal_user_viewer:"internal_user_viewer",internal_user:"internal_user",proxy_admin_viewer:"proxy_admin_viewer",proxy_admin:"proxy_admin"})[n]:void 0)||"internal_user",roles:{proxy_admin:e(s),proxy_admin_viewer:e(t),internal_user:e(r),internal_user_viewer:e(a)}}}await (0,_.updateSSOSettings)(c,u),l(e)}catch(e){p.toast.fromError("Failed to save SSO settings: "+(0,S.parseErrorMessage)(e))}},b=async()=>{if(!c)return void p.toast.fromError("No access token available");try{await (0,_.updateSSOSettings)(c,{google_client_id:null,google_client_secret:null,microsoft_client_id:null,microsoft_client_secret:null,microsoft_tenant:null,generic_client_id:null,generic_client_secret:null,generic_authorization_endpoint:null,generic_token_endpoint:null,generic_userinfo_endpoint:null,saml_idp_metadata_url:null,saml_idp_metadata_xml:null,saml_sp_entity_id:null,saml_allow_unsolicited:null,generic_scope:null,proxy_base_url:null,user_email:null,sso_provider:null,role_mappings:null}),d.reset(ev),h(!1),r(),p.toast.success("SSO settings cleared successfully")}catch(e){console.error("Failed to clear SSO settings:",e),p.toast.fromError("Failed to clear SSO settings")}};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(eB.Dialog,{open:e,onOpenChange:e=>!e&&a(),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:m?"Edit SSO Settings":"Add SSO"})}),(0,s.jsx)(G.FormProvider,{...d,children:(0,s.jsxs)("form",{onSubmit:e=>{e.preventDefault(),ej(d,"admin-panel",j)()},children:[(0,s.jsxs)(C.FieldGroup,{children:[(0,s.jsx)(ew,{}),x?ek(x):null,(0,s.jsx)(eN,{}),(0,s.jsx)(eE,{}),("okta"===x||"generic"===x)&&(0,s.jsx)(eI,{name:"use_role_mappings",label:"Use Role Mappings"}),f&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(eT,{}),(0,s.jsx)(eL,{})]})]}),(0,s.jsxs)("div",{className:"mt-4 flex items-center justify-end gap-2",children:[m&&(0,s.jsx)(n.Button,{type:"button",variant:"secondary",onClick:()=>h(!0),children:"Clear"}),(0,s.jsx)(n.Button,{type:"submit",children:"Save"})]})]})})]})}),(0,s.jsx)(eB.Dialog,{open:g,onOpenChange:e=>!e&&h(!1),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"Confirm Clear SSO Settings"})}),(0,s.jsx)("p",{children:"Are you sure you want to clear all SSO settings? This action cannot be undone."}),(0,s.jsx)("p",{children:"Users will no longer be able to login using SSO after this change."}),(0,s.jsxs)(eB.DialogFooter,{children:[(0,s.jsx)(n.Button,{variant:"outline",onClick:()=>h(!1),children:"Cancel"}),(0,s.jsx)(n.Button,{onClick:b,variant:"destructive",children:"Yes, Clear"})]})]})}),(0,s.jsx)(eB.Dialog,{open:t,onOpenChange:e=>!e&&o(),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"SSO Setup Instructions"})}),(0,s.jsx)("p",{children:"Follow these steps to complete the SSO setup:"}),(0,s.jsx)("p",{className:"text-sm mt-2",children:"1. DO NOT Exit this TAB"}),(0,s.jsx)("p",{className:"text-sm mt-2",children:"2. Open a new tab, visit your proxy base url"}),(0,s.jsx)("p",{className:"text-sm mt-2",children:"3. Confirm your SSO is configured correctly and you can login on the new Tab"}),(0,s.jsx)("p",{className:"text-sm mt-2",children:"4. If Step 3 is successful, you can close this tab"}),(0,s.jsx)("div",{style:{textAlign:"right",marginTop:"10px"},children:(0,s.jsx)(n.Button,{type:"button",onClick:i,children:"Done"})})]})})]})},s3=g.z.object({ui_access_mode_type:g.z.string().optional(),restricted_sso_group:g.z.string().optional(),sso_group_jwt_field:g.z.string().optional()}).superRefine((e,s)=>{"restricted_sso_group"!==e.ui_access_mode_type||e.restricted_sso_group||s.addIssue({code:"custom",path:["restricted_sso_group"],message:"Please enter the restricted SSO group"})}),s5=[{value:"all_authenticated_users",label:"All Authenticated Users"},{value:"restricted_sso_group",label:"Restricted SSO Group"}],s6=e=>"object"==typeof e&&null!==e?e:null,s7=e=>"string"==typeof e?e:void 0,s8=(e,t)=>(0,s.jsxs)(s.Fragment,{children:[e,(0,s.jsxs)(U.Tooltip,{children:[(0,s.jsx)(U.TooltipTrigger,{render:(0,s.jsx)(z.CircleHelp,{className:"size-3.5 shrink-0 cursor-help text-muted-foreground"})}),(0,s.jsx)(U.TooltipContent,{children:t})]})]}),s9=({accessToken:e,onSuccess:t})=>{let r=(0,I.useZodForm)(s3,{defaultValues:{}}),[a,l]=(0,u.useState)(!1),i=(0,G.useWatch)({control:r.control,name:"ui_access_mode_type"});(0,u.useEffect)(()=>{(async()=>{if(e)try{let s=(e=>{let s=s6(s6(e)?.values);if(!s)return null;let t=s6(s.ui_access_mode);if(t)return{ui_access_mode_type:s7(t.type),restricted_sso_group:s7(t.restricted_sso_group),sso_group_jwt_field:s7(t.sso_group_jwt_field)};let r=s7(s.ui_access_mode);return void 0!==r?{ui_access_mode_type:r,restricted_sso_group:s7(s.restricted_sso_group),sso_group_jwt_field:s7(s.team_ids_jwt_field)||s7(s.sso_group_jwt_field)}:null})(await (0,_.getSSOSettings)(e));s&&(r.setValue("ui_access_mode_type",s.ui_access_mode_type),r.setValue("restricted_sso_group",s.restricted_sso_group),r.setValue("sso_group_jwt_field",s.sso_group_jwt_field))}catch(e){console.error("Failed to load UI access settings:",e)}})()},[e,r]);let o=async s=>{if(!e)return void p.toast.fromError("No access token available");l(!0);try{let r="all_authenticated_users"===s.ui_access_mode_type?{ui_access_mode:"none"}:{ui_access_mode:{type:s.ui_access_mode_type,restricted_sso_group:s.restricted_sso_group,sso_group_jwt_field:s.sso_group_jwt_field}};await (0,_.updateSSOSettings)(e,r),t()}catch(e){console.error("Failed to save UI access settings:",e),p.toast.fromError("Failed to save UI access settings")}finally{l(!1)}};return(0,s.jsx)(U.TooltipProvider,{children:(0,s.jsxs)("div",{className:"p-4",children:[(0,s.jsx)("div",{className:"mb-4",children:(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:"Configure who can access the UI interface and how group information is extracted from JWT tokens."})}),(0,s.jsxs)("form",{onSubmit:r.handleSubmit(e=>o("restricted_sso_group"===e.ui_access_mode_type?e:{...e,restricted_sso_group:void 0})),noValidate:!0,children:[(0,s.jsxs)(C.FieldGroup,{children:[(0,s.jsx)(k.FormField,{control:r.control,name:"ui_access_mode_type",label:s8("UI Access Mode","Controls who can access the UI interface"),children:({id:e,value:t,onChange:r,"aria-invalid":a,"aria-describedby":n})=>(0,s.jsxs)(ep.Select,{items:s5,value:t??null,onValueChange:e=>r(e??void 0),children:[(0,s.jsx)(ep.SelectTrigger,{id:e,className:"w-full","aria-invalid":a,"aria-describedby":n,children:(0,s.jsx)(ep.SelectValue,{placeholder:"Select access mode"})}),(0,s.jsx)(ep.SelectContent,{children:s5.map(e=>(0,s.jsx)(ep.SelectItem,{value:e.value,children:e.label},e.value))})]})}),"restricted_sso_group"===i&&(0,s.jsx)(k.FormField,{control:r.control,name:"restricted_sso_group",label:"Restricted SSO Group",children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{...r,ref:e,value:t??"",placeholder:"ui-access-group"})}),(0,s.jsx)(k.FormField,{control:r.control,name:"sso_group_jwt_field",label:s8("SSO Group JWT Field","JWT field name that contains team/group information. Use dot notation to access nested fields."),children:({ref:e,value:t,...r})=>(0,s.jsx)(w.Input,{...r,ref:e,value:t??"",placeholder:"groups"})})]}),(0,s.jsx)("div",{className:"mt-4 text-right",children:(0,s.jsxs)(n.Button,{type:"submit",disabled:a,children:[a&&(0,s.jsx)(E.UiLoadingSpinner,{className:"size-4"}),"Update UI Access Control"]})})]})]})})},te=g.z.object({ip:g.z.string().min(1,"Please enter an IP address")}),ts=({onSubmit:e})=>{let t=(0,I.useZodForm)(te,{defaultValues:{ip:""}});return(0,s.jsx)("form",{onSubmit:t.handleSubmit(e),children:(0,s.jsxs)(C.FieldGroup,{children:[(0,s.jsx)(k.FormField,{control:t.control,name:"ip",children:({ref:e,...t})=>(0,s.jsx)(w.Input,{ref:e,placeholder:"Enter IP address",...t})}),(0,s.jsx)("div",{children:(0,s.jsx)(n.Button,{type:"submit",children:"Add IP Address"})})]})})},tt=({proxySettings:e})=>{let{premiumUser:g,accessToken:h,userId:x}=(0,t.default)(),f=eS("admin-panel"),[j,b]=(0,u.useState)(!1),[y,v]=(0,u.useState)(!1),[S,C]=(0,u.useState)(!1),[k,w]=(0,u.useState)(!1),[N,E]=(0,u.useState)(!1),[I,T]=(0,u.useState)(!1),[O,L]=(0,u.useState)([]),[M,F]=(0,u.useState)(null),[P,D]=(0,u.useState)(!1),U=(0,m.useBaseUrl)(),B="All IP Addresses Allowed",z=U;z+="/fallback/login";let R=async()=>{if(h)try{let e=await (0,_.getSSOSettings)(h);if(e&&e.values){let s=e.values.google_client_id&&e.values.google_client_secret,t=e.values.microsoft_client_id&&e.values.microsoft_client_secret,r=e.values.generic_client_id&&e.values.generic_client_secret;D(s||t||r)}else D(!1)}catch(e){console.error("Error checking SSO configuration:",e),D(!1)}},G=async()=>{try{if(!0!==g)return void p.toast.fromError("This feature is only available for premium users. Please upgrade your account.");if(h){let e=await (0,_.getAllowedIPs)(h);L(e&&e.length>0?e:[B])}else L([B])}catch(e){console.error("Error fetching allowed IPs:",e),p.toast.fromError(`Failed to fetch allowed IPs ${e}`),L([B])}finally{!0===g&&C(!0)}},V=async e=>{try{if(h){await (0,_.addAllowedIP)(h,e.ip);let s=await (0,_.getAllowedIPs)(h);L(s),p.toast.success("IP address added successfully")}}catch(e){console.error("Error adding IP:",e),p.toast.fromError(`Failed to add IP address ${e}`)}finally{w(!1)}},$=async e=>{F(e),E(!0)},H=async()=>{if(M&&h)try{await (0,_.deleteAllowedIP)(h,M);let e=await (0,_.getAllowedIPs)(h);L(e.length>0?e:[B]),p.toast.success("IP address deleted successfully")}catch(e){console.error("Error deleting IP:",e),p.toast.fromError(`Failed to delete IP address ${e}`)}finally{E(!1),F(null)}};(0,u.useEffect)(()=>{R()},[h,g,R]);let q=[{key:"sso-settings",label:"SSO Settings",children:(0,s.jsx)(e3,{})},{key:"security-settings",label:"Security Settings",children:(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(l.Card,{className:"block p-6",children:[(0,s.jsx)("h3",{className:"mb-2 text-base font-semibold text-foreground",children:"✨ Security Settings"}),(0,s.jsxs)(r.Alert,{variant:"warning",children:[(0,s.jsx)(c.TriangleAlert,{}),(0,s.jsx)(a.AlertTitle,{children:"SSO Configuration Deprecated"}),(0,s.jsx)(a.AlertDescription,{children:"Editing SSO Settings on this page is deprecated and will be removed in a future version. Please use the SSO Settings tab for SSO configuration."})]}),(0,s.jsxs)("div",{style:{display:"flex",flexDirection:"column",gap:"1rem",marginTop:"1rem",marginLeft:"0.5rem"},children:[(0,s.jsx)("div",{children:(0,s.jsx)(n.Button,{style:{width:"150px"},onClick:()=>b(!0),children:P?"Edit SSO Settings":"Add SSO"})}),(0,s.jsx)("div",{children:(0,s.jsx)(n.Button,{style:{width:"150px"},onClick:G,children:"Allowed IPs"})}),(0,s.jsx)("div",{children:(0,s.jsx)(n.Button,{style:{width:"150px"},onClick:()=>!0===g?T(!0):p.toast.fromError("Only premium users can configure UI access control"),children:"UI Access Control"})})]})]}),(0,s.jsxs)("div",{className:"flex justify-start mb-4",children:[(0,s.jsx)(s4,{isAddSSOModalVisible:j,isInstructionsModalVisible:y,handleAddSSOOk:()=>{b(!1),f.reset(ev),h&&g&&R()},handleAddSSOCancel:()=>{b(!1),f.reset(ev)},handleShowInstructions:e=>{b(!1),v(!0)},handleInstructionsOk:()=>{v(!1),h&&g&&R()},handleInstructionsCancel:()=>{v(!1),h&&g&&R()},form:f,accessToken:h,ssoConfigured:P}),(0,s.jsx)(eB.Dialog,{open:S,onOpenChange:e=>!e&&C(!1),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[800px]",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"Manage Allowed IP Addresses"})}),(0,s.jsxs)(i.Table,{children:[(0,s.jsx)(i.TableHeader,{children:(0,s.jsxs)(i.TableRow,{children:[(0,s.jsx)(i.TableHead,{children:"IP Address"}),(0,s.jsx)(i.TableHead,{className:"text-right",children:"Action"})]})}),(0,s.jsx)(i.TableBody,{children:O.map((e,t)=>(0,s.jsxs)(i.TableRow,{children:[(0,s.jsx)(i.TableCell,{children:e}),(0,s.jsx)(i.TableCell,{className:"text-right",children:e!==B&&(0,s.jsx)(n.Button,{onClick:()=>$(e),variant:"destructive",size:"sm",children:"Delete"})})]},t))})]}),(0,s.jsxs)(eB.DialogFooter,{children:[(0,s.jsx)(n.Button,{className:"mx-1",onClick:()=>w(!0),children:"Add IP Address"}),(0,s.jsx)(n.Button,{onClick:()=>C(!1),children:"Close"})]})]})}),(0,s.jsx)(eB.Dialog,{open:k,onOpenChange:e=>!e&&w(!1),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"Add Allowed IP Address"})}),(0,s.jsx)(ts,{onSubmit:V})]})}),(0,s.jsx)(eB.Dialog,{open:N,onOpenChange:e=>!e&&E(!1),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"Confirm Delete"})}),(0,s.jsxs)("span",{className:"text-sm text-foreground",children:["Are you sure you want to delete the IP address: ",M,"?"]}),(0,s.jsxs)(eB.DialogFooter,{children:[(0,s.jsx)(n.Button,{className:"mx-1",onClick:()=>H(),children:"Yes"}),(0,s.jsx)(n.Button,{onClick:()=>E(!1),children:"Close"})]})]})}),(0,s.jsx)(eB.Dialog,{open:I,onOpenChange:e=>!e&&void T(!1),children:(0,s.jsxs)(eB.DialogContent,{className:"max-h-[calc(100dvh-2rem)] overflow-y-auto sm:max-w-[600px]",children:[(0,s.jsx)(eB.DialogHeader,{children:(0,s.jsx)(eB.DialogTitle,{children:"UI Access Control Settings"})}),(0,s.jsx)(s9,{accessToken:h,onSuccess:()=>{T(!1),p.toast.success("UI Access Control settings updated successfully")}})]})})]}),(0,s.jsxs)(r.Alert,{variant:"info",children:[(0,s.jsx)(d.Info,{}),(0,s.jsx)(a.AlertTitle,{children:"Login without SSO"}),(0,s.jsxs)(a.AlertDescription,{children:["If you need to login without sso, you can access"," ",(0,s.jsxs)("a",{href:z,target:"_blank",rel:"noopener noreferrer",children:[(0,s.jsx)("b",{children:z})," "]})]})]})]})},{key:"scim",label:"SCIM",children:(0,s.jsx)(A,{accessToken:h,userID:x,proxySettings:e})},{key:"ui-settings",label:"UI Settings",children:(0,s.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,s.jsx)(sn,{}),(0,s.jsx)(sm,{})]})},{key:"logging-settings",label:"Logging Settings",children:(0,s.jsx)(W,{})},{key:"hashicorp-vault",label:"Hashicorp Vault",children:(0,s.jsx)(sH,{})},{key:"cyberark",label:"CyberArk Conjur",children:(0,s.jsx)(sA,{})},{key:"plugins",label:"Plugins",children:(0,s.jsx)(s2,{})}];return(0,s.jsxs)("div",{className:"w-full m-2 mt-2 p-8",children:[(0,s.jsx)("h2",{className:"mb-2 text-base font-semibold text-foreground",children:"Admin Access"}),(0,s.jsx)("p",{className:"mb-4 text-sm text-foreground",children:"Go to 'Internal Users' page to add other admins."}),(0,s.jsxs)(o.Tabs,{defaultValue:q[0].key,children:[(0,s.jsx)(o.TabsList,{variant:"line",className:"mb-4 h-auto flex-wrap",children:q.map(e=>(0,s.jsx)(o.TabsTrigger,{value:e.key,className:"flex-none",children:e.label},e.key))}),q.map(e=>(0,s.jsx)(o.TabsContent,{value:e.key,children:e.children},e.key))]})]})};var tr=e.i(592392);e.s(["default",0,function(){let{accessToken:e}=(0,t.default)(),r=(0,tr.default)(e);return(0,s.jsx)(tt,{proxySettings:r})}],648214)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0cotqb-2hzyvs.js b/litellm/proxy/_experimental/out/_next/static/chunks/0cotqb-2hzyvs.js
deleted file mode 100644
index e0eafe3fd43..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/0cotqb-2hzyvs.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,263147,e=>{"use strict";var t=e.i(266027),r=e.i(243652),a=e.i(602869),s=e.i(431703),i=e.i(708347),l=e.i(135214);let o=(0,r.createQueryKeys)("accessGroups"),n=async e=>{let t=(0,a.getProxyBaseUrl)(),r=`${t}/v1/access_group`,i=await fetch(r,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!i.ok){let e=await i.json(),t=(0,s.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return i.json()};e.s(["accessGroupKeys",0,o,"useAccessGroups",0,()=>{let{accessToken:e,userRole:r}=(0,l.default)();return(0,t.useQuery)({queryKey:o.list({}),queryFn:async()=>n(e),enabled:!!e&&i.all_admin_roles.includes(r||"")})}])},304911,e=>{"use strict";var t=e.i(843476),r=e.i(487486);e.s(["default",0,function({userId:e}){return"default_user_id"===e?(0,t.jsx)(r.Badge,{variant:"secondary",children:"Default Proxy Admin"}):(0,t.jsx)("span",{children:e})}])},190702,e=>{"use strict";e.s(["parseErrorMessage",0,e=>{if(!e)return"An unknown error occurred";if("string"==typeof e)return e;if(e.message)try{let t=JSON.parse(e.message);if(t.error&&t.error.message)return t.error.message;return"string"==typeof t?t:JSON.stringify(t,null,2)}catch(t){return e.message}if(e.response&&e.response.data){if("string"==typeof e.response.data)return e.response.data;if(e.response.data.message)return e.response.data.message;if(e.response.data.error)return"string"==typeof e.response.data.error?e.response.data.error:e.response.data.error.message||JSON.stringify(e.response.data.error)}return String(e)}])},519380,e=>{e.q("/litellm-asset-prefix/_next/static/media/bedrock.2vhamxr8q6y4o.svg")},946013,e=>{e.q("/litellm-asset-prefix/_next/static/media/google.3y8ypywwtqob_.svg")},641266,e=>{e.q("/litellm-asset-prefix/_next/static/media/microsoft_azure.3626-7zx7wf09.svg")},956529,e=>{e.q("/litellm-asset-prefix/_next/static/media/openai_small.3rj8nedgjpevh.svg")},913383,e=>{e.q("/litellm-asset-prefix/_next/static/media/a2a_agent.14el5-6dflh1h.png")},238564,e=>{e.q("/litellm-asset-prefix/_next/static/media/ai21.0m_u-tih8nm0v.svg")},941533,e=>{e.q("/litellm-asset-prefix/_next/static/media/aiml_api.1dq6dbpwklhlg.svg")},994636,e=>{e.q("/litellm-asset-prefix/_next/static/media/anthropic.3s95kgy8jpc64.svg")},824770,e=>{e.q("/litellm-asset-prefix/_next/static/media/assemblyai_small.0w_dslsra91uw.png")},920076,e=>{e.q("/litellm-asset-prefix/_next/static/media/baseten.41k2lnwp3c5g9.svg")},96889,e=>{e.q("/litellm-asset-prefix/_next/static/media/cerebras.1ur1xyfqk9ncz.svg")},348026,e=>{e.q("/litellm-asset-prefix/_next/static/media/cloudflare.2n1spdq7u5yki.svg")},727148,e=>{e.q("/litellm-asset-prefix/_next/static/media/cohere.22i3i2e449j5i.svg")},411703,e=>{e.q("/litellm-asset-prefix/_next/static/media/cometapi.3w0xficbg3dkk.svg")},922480,e=>{e.q("/litellm-asset-prefix/_next/static/media/cursor.1q1ev-_5l7exg.svg")},769490,e=>{e.q("/litellm-asset-prefix/_next/static/media/databricks.2hiet9qlqzn-g.svg")},829789,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepgram.3-krp20p_xed3.png")},41730,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepinfra.3lr_lsr7mhui6.png")},662576,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepseek.3n4cu0x32i_7w.svg")},987202,e=>{e.q("/litellm-asset-prefix/_next/static/media/elevenlabs.2982m_dk2-h_y.png")},953265,e=>{e.q("/litellm-asset-prefix/_next/static/media/fal_ai.3rahrirki8sby.jpg")},346512,e=>{e.q("/litellm-asset-prefix/_next/static/media/featherless.3hmlef3fhc0h5.svg")},84416,e=>{e.q("/litellm-asset-prefix/_next/static/media/fireworks.3t1b6p8edeqyo.svg")},104602,e=>{e.q("/litellm-asset-prefix/_next/static/media/friendli.0ymiswh6l35bq.svg")},888193,e=>{e.q("/litellm-asset-prefix/_next/static/media/github_copilot.3k-8jyadoaq2u.svg")},447500,e=>{e.q("/litellm-asset-prefix/_next/static/media/groq.20csmqzsusp1k.svg")},270039,e=>{e.q("/litellm-asset-prefix/_next/static/media/huggingface.1-07ypt9ii_-p.svg")},227733,e=>{e.q("/litellm-asset-prefix/_next/static/media/hyperbolic.3le20v59sebn8.svg")},823929,e=>{e.q("/litellm-asset-prefix/_next/static/media/infinity.0s9s12bl4lccx.png")},333845,e=>{e.q("/litellm-asset-prefix/_next/static/media/jina.0ukab8o-3-5m_.png")},813878,e=>{e.q("/litellm-asset-prefix/_next/static/media/lambda.26_vz7cmyuodo.svg")},767788,e=>{e.q("/litellm-asset-prefix/_next/static/media/lmstudio.35s3-83mlhcms.svg")},808630,e=>{e.q("/litellm-asset-prefix/_next/static/media/meta_llama.1kxk24vwsem49.svg")},468732,e=>{e.q("/litellm-asset-prefix/_next/static/media/minimax.2mfkkqc-lnsen.svg")},610503,e=>{e.q("/litellm-asset-prefix/_next/static/media/mistral.0n8jv_67hgq4h.svg")},438969,e=>{e.q("/litellm-asset-prefix/_next/static/media/moonshot.3__i9wvf37ksm.svg")},852459,e=>{e.q("/litellm-asset-prefix/_next/static/media/morph.2av06eo-t0-ve.svg")},494696,e=>{e.q("/litellm-asset-prefix/_next/static/media/nebius.2ipf7rmjccira.svg")},148973,e=>{e.q("/litellm-asset-prefix/_next/static/media/novita.0_nzmm_rl4lrf.svg")},570036,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_nim.1fz-5ugf_um0v.svg")},151170,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_triton.1aotoxig_m2w1.png")},862330,e=>{e.q("/litellm-asset-prefix/_next/static/media/ollama.144cif369atc5.svg")},788158,e=>{e.q("/litellm-asset-prefix/_next/static/media/openrouter.1xk7748-_jixf.svg")},350567,e=>{e.q("/litellm-asset-prefix/_next/static/media/oracle.43kws59xxr8ig.svg")},822797,e=>{e.q("/litellm-asset-prefix/_next/static/media/perplexity-ai.2do8hoc8tw__0.svg")},840911,e=>{e.q("/litellm-asset-prefix/_next/static/media/qwen.0a49x9i08_0gz.png")},445735,e=>{e.q("/litellm-asset-prefix/_next/static/media/recraft.2f4cv-c9ad-mo.svg")},635202,e=>{e.q("/litellm-asset-prefix/_next/static/media/replicate.445bidyix2tyh.svg")},669161,e=>{e.q("/litellm-asset-prefix/_next/static/media/runway.2zzwye1fddnnn.png")},159508,e=>{e.q("/litellm-asset-prefix/_next/static/media/sambanova.1vcyu0faw1x8h.svg")},544025,e=>{e.q("/litellm-asset-prefix/_next/static/media/sap.1367hgge0s0xl.png")},708767,e=>{e.q("/litellm-asset-prefix/_next/static/media/scx_ai.3emo1p5delrhx.svg")},100588,e=>{e.q("/litellm-asset-prefix/_next/static/media/snowflake.2_p8qqpi0r3lr.svg")},183804,e=>{e.q("/litellm-asset-prefix/_next/static/media/soniox.3nhjmssy7ybh7.svg")},865502,e=>{e.q("/litellm-asset-prefix/_next/static/media/togetherai.1wk-mouzgw5ho.svg")},96912,e=>{e.q("/litellm-asset-prefix/_next/static/media/topaz.3rjp3zvx4eags.svg")},395073,e=>{e.q("/litellm-asset-prefix/_next/static/media/v0.15trd3tb1ulop.svg")},407829,e=>{e.q("/litellm-asset-prefix/_next/static/media/vercel.1mvnwxofolt8y.svg")},846077,e=>{e.q("/litellm-asset-prefix/_next/static/media/vllm.3_gqby46r7s3x.png")},914861,e=>{e.q("/litellm-asset-prefix/_next/static/media/volcengine.23ly9ik_qc138.png")},285328,e=>{e.q("/litellm-asset-prefix/_next/static/media/voyage.0krq6ew-yr8dk.webp")},779278,e=>{e.q("/litellm-asset-prefix/_next/static/media/watsonx.19rrg39yvhpk8.svg")},325532,e=>{e.q("/litellm-asset-prefix/_next/static/media/xai.2kc3gjiopn9om.svg")},288330,e=>{e.q("/litellm-asset-prefix/_next/static/media/xinference.063cy_ievvy5u.svg")},922158,336712,39182,980385,e=>{"use strict";let t={src:e.i(519380).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,t],922158);let r={src:e.i(946013).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,r],336712);let a={src:e.i(641266).default,width:200,height:58,blurWidth:0,blurHeight:0};e.s(["default",0,a],39182);let s={src:e.i(956529).default,width:28,height:28,blurWidth:0,blurHeight:0};e.s(["default",0,s],980385)},916925,555987,9774,247044,e=>{"use strict";var t,r=e.i(221688),a=e.i(950643);let s=/^(https?:|data:|blob:|\/\/)/i,i=e=>s.test(e),l=(e,t=r.serverRootPath)=>{let s;if(!e)return;if(i(e)||e.includes("/_next/static/"))return e;let l=(0,a.normalizeRootPath)(t);return l&&(e===l||e.startsWith(`${l}/`))?e:(s=(0,a.normalizeRootPath)(t),`${s}${e.startsWith("/")?e:`/${e}`}`)};e.s(["isExternalAssetSrc",0,i,"resolveLogoSrc",0,l],555987);let o={src:e.i(913383).default,width:661,height:768,blurWidth:7,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAwUlEQVR42h2OvQpGcByFf5dK7oBJFoooJDaDZFA+BoVkNBikGJSUJINyGeft/Q+nznDO00O6rsM0Tfi+z6JpGizLgqqqIEVR0HUdqqqCbdus930PWZZBy7IgCAKkaYpxHJEkCaIowjAMoGmaEMcx8jxHURRo2xZ1XaMsS9B5nrjvG+u6Yp5nfN+H53nwJ9JxHMiyDO/7Mtx1Xey1bRvIcRzwPI993xGGIZqmgSAIMAwDJEkSPM9jphzHsYHruhBFET+hn6S8pf6D7AAAAABJRU5ErkJggg=="},n={src:e.i(238564).default,width:103,height:24,blurWidth:0,blurHeight:0},c={src:e.i(941533).default,width:115,height:24,blurWidth:0,blurHeight:0},d={src:e.i(994636).default,width:46,height:46,blurWidth:0,blurHeight:0},u={src:e.i(824770).default,width:28,height:28,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAlElEQVR42m3OoQqDUBQGYF9mwzLbFiZsMNgwuGa4YFgYLC6PgcXuA5gFzdcgFkExGr33ogZRNIr6CAoKKgo/nAMfh/NTu3u4GWoY+0fIAsIC3C8LuIiRH9S2W5wBXsBPKaHTGGb+lZMJmCe2vPYjZe9/bMDswKMRbq9Yg9VRICcBq3p6FckINIf6o6ECwyOam/1YpwPFUFu+Lt2F2QAAAABJRU5ErkJggg=="},m={src:e.i(920076).default,width:16,height:16,blurWidth:0,blurHeight:0};var h=e.i(922158);let A={src:e.i(96889).default,width:800,height:600,blurWidth:0,blurHeight:0},g={src:e.i(348026).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,g],9774);let p={src:e.i(727148).default,width:75,height:75,blurWidth:0,blurHeight:0},f={src:e.i(411703).default,width:16,height:16,blurWidth:0,blurHeight:0},x={src:e.i(922480).default,width:16,height:16,blurWidth:0,blurHeight:0},b={src:e.i(769490).default,width:16,height:16,blurWidth:0,blurHeight:0},v={src:e.i(829789).default,width:32,height:32,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAzklEQVR42k3PPWuDcBDHccUiiikYSwqhg+IkuKUpOLqK4OYrcBZcFCcH352mgy/Ch9mxEPg2+s+Q4W65zx33kyRJQpZlFOUNTdM4HN45Hi1Op0/O56+7tAHbtqmqiqZpKIqCy+Uby/rYkABhGLKuK+M4siwLt9sv1+sPpmkKEAQBwzCQpilxHDNNE3VdYxiGALqu47oujuMQRdEOyrJEVVUBFEUhSRK6rmOeZ/q+x/f97XkBHqfIsoy2bcnzHM/z9mSP2Q62dt/0c+O1/v4BYRxu3LgaR7UAAAAASUVORK5CYII="},_={src:e.i(41730).default,width:225,height:225,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAfklEQVR42nVOvQqDMBjM+7+RpbQ0Ji2NQhwdzGIwCMZFiCAa9STqIPhxw/3A3UeW41w/AKck87w0tqvbngkFgEDCJOPoKc+fovxKzaUGiXkOk0zei1TRzDxYEbHiIw0kzD2Aji5BqHolW9Uv0+9U01AVxivr4r8CjHX7+N27K5WIrP56XsFTAAAAAElFTkSuQmCC"},w={src:e.i(662576).default,width:293,height:215,blurWidth:0,blurHeight:0},y={src:e.i(987202).default,width:1563,height:1563,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA5ElEQVR42h2PPwtBURjGj3wCk93sC1iUCYXFIlGSMjC4QiiTBSE3Ge5M3e0uPoJFBhOTP8NNukXduFL3uJ1Xzz11znCe93me38uitQSL11Pe8rAanKpycbSa5Ar9UiAmJT3QXHGwHGfvj/vJcRzOfz/7fLvsW4tuJFZLehicEIUQpOs6GYZBOIfrcZPp5f0MsXDatk2yLJOqqu6A9f2YjXk7zNCJWM45KYpCmqa5A6/P+ynNGiEGIHSiwjRNsiyLBAmxPezW6U7Gx0ALIHQiFk6I5WEl6G6BB7QAQqc0a4bgxD/uH4FYoVec8m3dAAAAAElFTkSuQmCC"},C={src:e.i(953265).default,width:400,height:400,blurWidth:8,blurHeight:8,blurDataURL:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAAIAAgDAREAAhEBAxEB/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtP9N/tL+PO/8A7ZeV/wDFUj6L917L+r3/AMj/2Q=="},k={src:e.i(346512).default,width:16,height:16,blurWidth:0,blurHeight:0},E={src:e.i(84416).default,width:16,height:16,blurWidth:0,blurHeight:0},I={src:e.i(104602).default,width:16,height:16,blurWidth:0,blurHeight:0},N={src:e.i(888193).default,width:16,height:16,blurWidth:0,blurHeight:0};var j=e.i(336712);let O={src:e.i(447500).default,width:26,height:26,blurWidth:0,blurHeight:0},L={src:e.i(270039).default,width:16,height:16,blurWidth:0,blurHeight:0},S={src:e.i(227733).default,width:16,height:16,blurWidth:0,blurHeight:0},R={src:e.i(823929).default,width:128,height:129,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAApklEQVR42oWPsQrCMBRFY51KaUuwNktBQbcgSenQ32hCTBAHXfSfulUK4g/0/7yvdO+FB5dzXhLC2FoiJE3TfZ7nYrskyzIBVpBjTdPcu677GGPGtm1fmDd1YnVd31gIYSrLUnLOjxC9tfaLfhBCXLz307xQVZUCODvnfljoceAEpskxKeUV1w0Qo1LqobV+Lk8McI5tkDiOeZIkO9SIBr0gRm71l38QASaqNz7VMwAAAABJRU5ErkJggg=="},M={src:e.i(333845).default,width:200,height:200,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAXUlEQVR42p2MoRHAMAwDQwJzCcgCwQEZIDjA03gED2BzewSPWRe2qFcB3Z+kU0o/lXNea4U/0t77OYeIACDq4FLKnSKimYmIqjKzu885U6117z3GCGitxTbg/flJF7DAEmcR3WAqAAAAAElFTkSuQmCC"},T={src:e.i(813878).default,width:16,height:16,blurWidth:0,blurHeight:0},D={src:e.i(767788).default,width:16,height:16,blurWidth:0,blurHeight:0},B={src:e.i(808630).default,width:16,height:16,blurWidth:0,blurHeight:0};var H=e.i(39182);let P={src:e.i(468732).default,width:490,height:412,blurWidth:0,blurHeight:0},U={src:e.i(610503).default,width:16,height:16,blurWidth:0,blurHeight:0},V={src:e.i(438969).default,width:16,height:16,blurWidth:0,blurHeight:0},q={src:e.i(852459).default,width:16,height:16,blurWidth:0,blurHeight:0},W={src:e.i(494696).default,width:16,height:16,blurWidth:0,blurHeight:0},z={src:e.i(148973).default,width:16,height:16,blurWidth:0,blurHeight:0},G={src:e.i(570036).default,width:16,height:16,blurWidth:0,blurHeight:0},Y={src:e.i(151170).default,width:95,height:81,blurWidth:8,blurHeight:7,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAYAAAA1WQxeAAAA0UlEQVR42kXMvWrCUBjG8VxIL6KX0IvobXQSOrQd2kLSdMzQdMmaEErPUqoIIYtKOC5iFD9BEBwiaAY/AgpH/2oUfOGFh4cfj8blNmrNKK0zmFUZzmust2nea7u9IlkNkBMPv1Xgs3JHoXRDe1o+g8Vmyl/vnf++wU/7EdF54jW8JU6K14WTPgE3fjiCZ77kPa2kdAZZlrFcLpikXYLeN6Lxxm/zhfEsRimF5roupmli2zbGh4Gu61iWlX8URWhSSsIwxPM8hBA4jpNn3/cJgoADqC23HJzwo6wAAAAASUVORK5CYII="},F={src:e.i(862330).default,width:646,height:854,blurWidth:0,blurHeight:0};var Q=e.i(980385);let K={src:e.i(788158).default,width:300,height:300,blurWidth:0,blurHeight:0},J={src:e.i(350567).default,width:231,height:30,blurWidth:0,blurHeight:0},$={src:e.i(822797).default,width:48,height:48,blurWidth:0,blurHeight:0},X={src:e.i(840911).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABE0lEQVR42gEIAff+AAAAAAAAAAAAEQwmIT8ukIAgGUpBBwYQDQQECggAAAAAAAIBBQQJBhUTFw80LUIxloZbR8+5UUS3oUA4kH0HBxEOACMUUkolFlVNCAYTERwUPzgkHFJIIhxNRCsmYVQODSAbADYffnNFKaCSDgkgHD0tjX4+MI5+CQgVEhQSLCULChgUABAKJiJTM7+vJhlYTzEkb2MxJm9iIh1NQywnZFYhH0o/AA8JIh9RMrurNiR9cQkHFhMQDSUgUkW5o1hOx60pJlxPAAcEDw4qGmJYFw80LhENKCMyKHFjUEK0nhEOJSADAwYFAAAAAAADAgcGBQMLCRUPMClCNJeEIRtLQgAAAQAAAAAAfjQxsiCQipMAAAAASUVORK5CYII="},Z={src:e.i(445735).default,width:16,height:16,blurWidth:0,blurHeight:0},ee={src:e.i(635202).default,width:16,height:16,blurWidth:0,blurHeight:0},et={src:e.i(669161).default,width:320,height:320,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7UlEQVR42lVQvc7BYBR+B/kM3w+fFm2p9m3fRhFRP7UQlTAQCVfAgE3EHZAQMTBIzBIrYbEgFhaza3ABrsF7bIYnOTl5/s5BVrvIY5MMvYTbUuy8hN8CcFIdW62CgHCKjFwie/So3PqH+b0Hc+GebkW6Lj9zUtJaHwEbFvGqWf7zOG5GJVmjcwUEAUOevQmhfKSTqJol+7f94RT+L7Yv25OV3PtsI699EByc85qpW5qcUCaMyB7orH9EgJLaTnPNgk/QfUsxKi0QtKWFzjRzA7a08IEPCivYKWkyQHAKtJUMPIVMQCAmz3FKHcELXnxEPy9E1lYCAAAAAElFTkSuQmCC"},er={src:e.i(159508).default,width:52,height:46,blurWidth:0,blurHeight:0},ea={src:e.i(544025).default,width:3300,height:2550,blurWidth:8,blurHeight:6,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAAZklEQVR42oWNTQ5AMBhE3f8mEhux4BgiIRzAwoKWplrt146fBbVhkpnNvORF+El0jvMAV4RR2qtsJZD3DyA2h6xhiMsRSTUhrRm0DYBFE4qOI285yl5CGvdW0OEYhEE/G6jgvIGv7A4KupBwIVaNAAAAAElFTkSuQmCC"},es={src:e.i(708767).default,width:760,height:277,blurWidth:0,blurHeight:0},ei={src:e.i(100588).default,width:146,height:139,blurWidth:0,blurHeight:0};e.s(["default",0,ei],247044);let el={src:e.i(183804).default,width:100,height:18,blurWidth:0,blurHeight:0},eo={src:e.i(865502).default,width:32,height:32,blurWidth:0,blurHeight:0},en={src:e.i(96912).default,width:16,height:16,blurWidth:0,blurHeight:0},ec={src:e.i(395073).default,width:16,height:16,blurWidth:0,blurHeight:0},ed={src:e.i(407829).default,width:16,height:16,blurWidth:0,blurHeight:0},eu={src:e.i(846077).default,width:64,height:64,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAo0lEQVR42lWOvQrCQBCE7718oUA6wVcQBF/AXhu1CIgcpgoi/qCNguBPwCaChYHDv9zt3e6ZeEFxq9n5GGaY/T8iq3QhWKFRkZGWzEPaaE/RDoiI5e7z0BILP7tMB2vyO3p2BJew8syvvJLGQTPEaheSVJeAQIi5F2+CWt80uHopLMEnNBpPuNc2vaXK+38A4RauTvUhbBNwDvsOlYD3DA2Se99kLK7hC5QFVQAAAABJRU5ErkJggg=="},em={src:e.i(914861).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7ElEQVR42l2LMUsCAQBG39GFFQ02ad1oq0QIRR2hER4EGdQqdBDdQZAFEudU0NZSQ0O1VUOjiuJvEBxc3BQFEVQQdFAU9OROFwf9lg/e48Hiti8vWJekBSoIODacLK04CP79IAX8815cW2X3IYL3JIhaKuKLGdNGmMUCTo+Hq1yO72yB6HDEeTrFjm8fUVwGt3uL00eD5+6AfMvixbS5bTR5/43jcm2CooT4KNf56ltUGzafA5uoZZGpdJDlABhPr7z1TJLtMbXamMT0702T//aQu0gM5GOFvRuNkKoTDuucqRpeXePoWuPg0D8BGkpJjYhKXN4AAAAASUVORK5CYII="},eh={src:e.i(285328).default,width:400,height:399,blurWidth:8,blurHeight:8,blurDataURL:"data:image/webp;base64,UklGRgwBAABXRUJQVlA4TAABAAAvB8ABEM1VICICHggIDgIAAIDzDAACD0FoAAARAAwAAAAAAAAAAAAAAACAAABAAcBCAoAWgGyoXwUAAA8E7QQCAADg/N+nrsYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4CClZXkg5AQAAAAA538LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL0HIgEAAAAAcP4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMsHA39Qutr2AtkROu8CASWZ/nMlNyzz5AdgWmkK65oUI6AlgIkY/M3zxIW3iABq15KT/Uz7BXidCOONHieAz1v6HqAC"},eA={src:e.i(779278).default,width:16,height:16,blurWidth:0,blurHeight:0},eg={src:e.i(325532).default,width:1e3,height:1e3,blurWidth:0,blurHeight:0},ep={src:e.i(288330).default,width:16,height:16,blurWidth:0,blurHeight:0};var ef=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cognition="Cognition",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="Hosted vLLM",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.NVIDIA_RIVA="Nvidia Riva",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.SCX_AI="SCX.ai",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Local vLLM",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let ex={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cognition:"cognition",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",NVIDIA_RIVA:"nvidia_riva",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",SCX_AI:"scx-ai",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},eb=new Set(["bedrock_mantle"]),ev={"A2A Agent":o.src,Ai21:n.src,"Ai21 Chat":n.src,"AI/ML API":c.src,"Aiohttp Openai":Q.default.src,Anthropic:d.src,"Anthropic Text":d.src,AssemblyAI:u.src,Azure:H.default.src,"Azure AI Foundry (Studio)":H.default.src,"Azure Text":H.default.src,Baseten:m.src,"Amazon Bedrock":h.default.src,"Amazon Bedrock Mantle":h.default.src,"AWS SageMaker":h.default.src,Cerebras:A.src,Cloudflare:g.src,Codestral:U.src,Cohere:p.src,"Cohere Chat":p.src,Cometapi:f.src,Cursor:x.src,"Databricks (Qwen API)":b.src,Dashscope:X.src,Deepseek:w.src,Deepgram:v.src,DeepInfra:_.src,ElevenLabs:y.src,"Fal AI":C.src,"Featherless Ai":k.src,"Fireworks AI":E.src,Friendliai:I.src,"Github Copilot":N.src,"Google AI Studio":j.default.src,Groq:O.src,"Hosted vLLM":eu.src,Huggingface:L.src,Hyperbolic:S.src,Infinity:R.src,"Jina AI":M.src,"Lambda Ai":T.src,"Lm Studio":D.src,"Meta Llama":B.src,MiniMax:P.src,"Mistral AI":U.src,Moonshot:V.src,Morph:q.src,Nebius:W.src,Novita:z.src,"Nvidia Nim":G.src,"Nvidia Riva":G.src,Ollama:F.src,"Ollama Chat":F.src,Oobabooga:Q.default.src,OpenAI:Q.default.src,"Openai Like":Q.default.src,"OpenAI Text Completion":Q.default.src,"OpenAI-Compatible Completions (legacy /v1/completions)":Q.default.src,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":Q.default.src,Openrouter:K.src,"Oracle Cloud Infrastructure (OCI)":J.src,Perplexity:$.src,Recraft:Z.src,Replicate:ee.src,RunwayML:et.src,Sagemaker:h.default.src,Sambanova:er.src,"SAP Generative AI Hub":ea.src,"SCX.ai":es.src,Snowflake:ei.src,Soniox:el.src,"Text-Completion-Codestral":U.src,TogetherAI:eo.src,Topaz:en.src,Triton:Y.src,V0:ec.src,"Vercel Ai Gateway":ed.src,"Vertex AI (Anthropic, Gemini, etc.)":j.default.src,"Vertex Ai Beta":j.default.src,"Local vLLM":eu.src,VolcEngine:em.src,"Voyage AI":eh.src,Watsonx:eA.src,"Watsonx Text":eA.src,xAI:eg.src,Xinference:ep.src},e_={"AI/ML API":"aiml/flux-pro/v1.1",Anthropic:"claude-3-opus",Azure:"my-deployment","Azure AI Foundry (Studio)":"azure_ai/command-r-plus","Amazon Bedrock":"claude-3-opus",Cognition:"cognition/swe-1.7",Cursor:"cursor/claude-4-sonnet",DeepInfra:"deepinfra/","Fal AI":"fal_ai/fal-ai/flux-pro/v1.1-ultra","Google AI Studio":"gemini-pro","Jina AI":"jina_ai/","Nvidia Riva":"nvidia_riva/nvidia/parakeet-ctc-1_1b-asr","Oracle Cloud Infrastructure (OCI)":"oci/xai.grok-4",RunwayML:"runwayml/gen4_turbo","AWS SageMaker":"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b","SCX.ai":"scx-ai/GLM-5.2",Snowflake:"snowflake/mistral-7b","Vertex AI (Anthropic, Gemini, etc.)":"gemini-pro",VolcEngine:"volcengine/","Voyage AI":"voyage/",Watsonx:"watsonx/ibm/granite-3-3-8b-instruct","Z.AI (Zhipu AI)":"zai/glm-4.5"};e.s(["Providers",()=>ef,"getPlaceholder",0,e=>e_[ef[e]??e]??"gpt-3.5-turbo","getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:l(ev[e])??"",displayName:e}}let t=Object.keys(ex).find(t=>ex[t].toLowerCase()===e.toLowerCase())??Object.keys(ex).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let r=ef[t];return{logo:l(ev[r])??"",displayName:r}},"getProviderModels",0,(e,t)=>{let r=ex[e],a=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let s=t.litellm_provider,i="string"==typeof s&&(s.startsWith(`${r}_`)||s.startsWith(`${r}-`));(s===r||i&&!eb.has(s))&&a.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&a.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&a.push(e)})),a},"providerLogoMap",0,ev,"provider_map",0,ex],916925)},174553,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(916925),s=e.i(555987),i=e.i(196631);let l=/(?:\/assets\/logos\/|\/_next\/static\/media\/)/,o={"baseten.svg":"invert","cursor.svg":"invert","enkrypt_ai.avif":"invert","friendli.svg":"invert","github.svg":"invert","github_copilot.svg":"invert","lago.svg":"invert","lambda.svg":"invert","langflow.svg":"invert","lmstudio.svg":"invert","moonshot.svg":"invert","nebius.svg":"invert","notion.svg":"invert","ollama.svg":"invert","openrouter.svg":"invert","promptguard.svg":"invert","recraft.svg":"invert","replicate.svg":"invert","runway.png":"invert","scx_ai.svg":"invert","secret_detect.png":"invert","topaz.svg":"invert","v0.svg":"invert","vercel.svg":"invert","watsonx.svg":"invert","aiml_api.svg":"plate","akto.svg":"plate","aws.svg":"plate","deepkeep.svg":"plate","fireworks.svg":"plate","llm_guard.png":"plate","pangea.png":"plate","repelloai.png":"plate","sambanova.svg":"plate","sentry.svg":"plate","valkey.svg":"plate"},n={invert:"dark:[filter:brightness(0)_invert(1)]",plate:"dark:bg-logo-surface dark:object-contain dark:p-0.5"};e.s(["Logo",0,({provider:e,src:c,label:d,className:u="w-4 h-4"})=>{let[m,h]=(0,r.useState)(null),A=void 0!==e?(0,a.getProviderLogoAndName)(e).logo:(0,s.resolveLogoSrc)(c)??"",g=d??e??"";if(m===A||!A)return(0,t.jsx)("div",{className:`${u} rounded-full bg-border flex items-center justify-center text-xs`,children:g.charAt(0)||"-"});let p=(e=>{let t;if(!e||(0,s.isExternalAssetSrc)(e)||!l.test(e))return;let r=e.split(/[?#]/)[0].split("/").pop()||void 0,a=void 0===r||(t=r.split(".")).length<2?void 0:`${t[0]}.${t[t.length-1]}`;return void 0===a?void 0:o[a]})(A);return(0,t.jsx)("img",{src:A,alt:`${g||"-"} logo`,className:void 0===p?u:(0,i.cn)(u,n[p]),onError:()=>{console.warn(`Logo failed to load: ${A}`),h(A)}})}],174553)},286536,e=>{"use strict";let t=(0,e.i(475254).default)("eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Eye",0,t],286536)},77705,e=>{"use strict";let t=(0,e.i(475254).default)("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["EyeOff",0,t],77705)},101048,e=>{"use strict";var t=e.i(123287);e.s(["CircleCheck",()=>t.default])},39312,e=>{"use strict";let t=(0,e.i(475254).default)("zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]);e.s(["Zap",0,t],39312)},503116,949411,e=>{"use strict";let t=(0,e.i(475254).default)("clock",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polyline",{points:"12 6 12 12 16 14",key:"68esgv"}]]);e.s(["default",0,t],949411),e.s(["Clock",0,t],503116)},973706,87316,e=>{"use strict";var t=e.i(843476);let r=(0,e.i(475254).default)("calendar",[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]]);e.s(["Calendar",0,r],87316);var a=e.i(503116),s=e.i(519455),i=e.i(196631),l=e.i(166540),o=e.i(271645);let n=[{label:"Today",shortLabel:"today",getValue:()=>({from:(0,l.default)().startOf("day").toDate(),to:(0,l.default)().endOf("day").toDate()})},{label:"Last 7 days",shortLabel:"7d",getValue:()=>({from:(0,l.default)().subtract(7,"days").startOf("day").toDate(),to:(0,l.default)().endOf("day").toDate()})},{label:"Last 30 days",shortLabel:"30d",getValue:()=>({from:(0,l.default)().subtract(30,"days").startOf("day").toDate(),to:(0,l.default)().endOf("day").toDate()})},{label:"Month to date",shortLabel:"MTD",getValue:()=>({from:(0,l.default)().startOf("month").toDate(),to:(0,l.default)().endOf("day").toDate()})},{label:"Year to date",shortLabel:"YTD",getValue:()=>({from:(0,l.default)().startOf("year").toDate(),to:(0,l.default)().endOf("day").toDate()})}];e.s(["default",0,({value:e,onValueChange:c,label:d="Select Time Range",className:u,showTimeRange:m=!0,align:h="right"})=>{let[A,g]=(0,o.useState)(!1),[p,f]=(0,o.useState)(e),[x,b]=(0,o.useState)(null),[v,_]=(0,o.useState)(""),[w,y]=(0,o.useState)(""),C=(0,o.useRef)(null),k=(0,o.useCallback)(e=>{if(!e.from||!e.to)return null;for(let t of n){let r=t.getValue(),a=(0,l.default)(e.from).isSame((0,l.default)(r.from),"day"),s=(0,l.default)(e.to).isSame((0,l.default)(r.to),"day");if(a&&s)return t.shortLabel}return null},[]);(0,o.useEffect)(()=>{b(k(e))},[e,k]);let E=(0,o.useCallback)(()=>{if(!v||!w)return{isValid:!0,error:""};let e=(0,l.default)(v,"YYYY-MM-DD"),t=(0,l.default)(w,"YYYY-MM-DD");return e.isValid()&&t.isValid()?t.isBefore(e)?{isValid:!1,error:"End date cannot be before start date"}:{isValid:!0,error:""}:{isValid:!1,error:"Invalid date format"}},[v,w])();(0,o.useEffect)(()=>{e.from&&_((0,l.default)(e.from).format("YYYY-MM-DD")),e.to&&y((0,l.default)(e.to).format("YYYY-MM-DD")),f(e)},[e]),(0,o.useEffect)(()=>{let e=e=>{C.current&&!C.current.contains(e.target)&&g(!1)};return A&&document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[A]);let I=(0,o.useCallback)((e,t)=>{if(!e||!t)return"Select date range";let r=e=>(0,l.default)(e).format("D MMM, HH:mm");return`${r(e)} - ${r(t)}`},[]),N=(0,o.useCallback)(e=>{let t;if(!e.from)return e;let r={...e},a=new Date(e.from);return t=new Date(e.to?e.to:e.from),a.toDateString()===t.toDateString(),a.setHours(0,0,0,0),t.setHours(23,59,59,999),r.from=a,r.to=t,r},[]),j=(0,o.useCallback)(()=>{try{if(v&&w&&E.isValid){let e=(0,l.default)(v,"YYYY-MM-DD").startOf("day"),t=(0,l.default)(w,"YYYY-MM-DD").endOf("day");if(e.isValid()&&t.isValid()){let r={from:e.toDate(),to:t.toDate()};f(r);let a=k(r);b(a)}}}catch(e){console.warn("Invalid date format:",e)}},[v,w,E.isValid,k]);return(0,o.useEffect)(()=>{j()},[j]),(0,t.jsxs)("div",{className:(0,i.cn)("flex items-center gap-3",u),children:[d&&(0,t.jsx)("p",{className:"text-sm font-medium text-foreground whitespace-nowrap",children:d}),(0,t.jsxs)("div",{className:"relative",ref:C,children:[(0,t.jsx)("button",{type:"button","data-slot":"advanced-date-picker-trigger","aria-expanded":A,className:"w-[300px] px-3 py-2 text-sm text-left border border-border rounded-md bg-card cursor-pointer hover:border-ring focus:border-info focus:ring-1 focus:ring-ring",onClick:()=>g(!A),children:(0,t.jsxs)("span",{className:"flex items-center justify-between",children:[(0,t.jsxs)("span",{className:"flex items-center gap-2",children:[(0,t.jsx)(a.Clock,{className:"size-4 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-foreground",children:I(e.from,e.to)})]}),(0,t.jsx)("svg",{className:`w-4 h-4 text-muted-foreground transition-transform ${A?"rotate-180":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})}),A&&(0,t.jsx)("div",{"data-slot":"advanced-date-picker-panel","data-align":h,className:(0,i.cn)("absolute top-full z-floating min-w-[600px] mt-1 bg-card border border-border rounded-lg shadow-xl","left"===h?"left-0":"right-0"),children:(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsxs)("div",{className:"w-1/2 border-r border-border",children:[(0,t.jsx)("div",{className:"p-3 border-b border-border",children:(0,t.jsx)("span",{className:"text-sm font-semibold text-foreground",children:"Relative time"})}),(0,t.jsx)("div",{className:"h-[350px] overflow-y-auto",children:n.map(e=>{let r=x===e.shortLabel;return(0,t.jsxs)("button",{type:"button","data-slot":"advanced-date-picker-preset","aria-pressed":r,className:`flex w-full items-center justify-between px-5 py-4 text-left cursor-pointer border-b border-border transition-colors ${r?"bg-info/10 hover:bg-info/15 border-info/20":"hover:bg-accent"}`,onClick:()=>(e=>{let{from:t,to:r}=e.getValue();f({from:t,to:r}),b(e.shortLabel),_((0,l.default)(t).format("YYYY-MM-DD")),y((0,l.default)(r).format("YYYY-MM-DD"))})(e),children:[(0,t.jsx)("span",{className:`text-sm ${r?"text-info font-medium":"text-foreground"}`,children:e.label}),(0,t.jsx)("span",{className:`text-xs px-2 py-1 rounded capitalize ${r?"text-info bg-info/15":"text-muted-foreground bg-muted"}`,children:e.shortLabel})]},e.label)})})]}),(0,t.jsxs)("div",{className:"w-1/2 relative",children:[(0,t.jsx)("div",{className:"p-3.5 border-b border-border",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(r,{className:"size-4 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-sm font-semibold text-foreground",children:"Start and end dates"})]})}),(0,t.jsxs)("div",{className:"p-6 space-y-6 pb-20",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"text-sm text-foreground mb-1 block",children:"Start date"}),(0,t.jsx)("input",{type:"date",value:v,onChange:e=>_(e.target.value),className:`w-65 px-3 py-2 text-sm border rounded-md cursor-pointer hover:border-ring focus:border-info focus:ring-1 focus:ring-ring ${!E.isValid?"border-destructive/30 focus:border-destructive focus:ring-red-200":"border-border"}`})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"text-sm text-foreground mb-1 block",children:"End date"}),(0,t.jsx)("input",{type:"date",value:w,onChange:e=>y(e.target.value),className:`w-65 px-3 py-2 text-sm border rounded-md cursor-pointer hover:border-ring focus:border-info focus:ring-1 focus:ring-ring ${!E.isValid?"border-destructive/30 focus:border-destructive focus:ring-red-200":"border-border"}`})]}),!E.isValid&&E.error&&(0,t.jsx)("div",{className:"bg-destructive/10 border border-destructive/20 rounded-md p-3",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("svg",{className:"w-4 h-4 text-destructive",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"})}),(0,t.jsx)("span",{className:"text-sm text-destructive font-medium",children:E.error})]})}),p.from&&p.to&&E.isValid&&(0,t.jsxs)("div",{className:"bg-info/10 p-3 rounded-md space-y-1",children:[(0,t.jsxs)("div",{className:"text-xs text-info",children:[(0,t.jsx)("span",{className:"font-medium",children:"From:"})," ",(0,l.default)(p.from).format("MMM D, YYYY [at] HH:mm:ss")]}),(0,t.jsxs)("div",{className:"text-xs text-info",children:[(0,t.jsx)("span",{className:"font-medium",children:"To:"})," ",(0,l.default)(p.to).format("MMM D, YYYY [at] HH:mm:ss")]})]})]}),(0,t.jsx)("div",{className:"absolute bottom-4 right-4",children:(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)(s.Button,{variant:"secondary",onClick:()=>{f(e),e.from&&_((0,l.default)(e.from).format("YYYY-MM-DD")),e.to&&y((0,l.default)(e.to).format("YYYY-MM-DD")),b(k(e)),g(!1)},children:"Cancel"}),(0,t.jsx)(s.Button,{onClick:()=>{p.from&&p.to&&E.isValid&&(c(p),requestIdleCallback(()=>{c(N(p))},{timeout:100}),g(!1))},disabled:!p.from||!p.to||!E.isValid,children:"Apply"})]})})]})]})})]})]})}],973706)},908990,e=>{"use strict";var t=e.i(843476),r=e.i(952571),a=e.i(515288),s=e.i(337822);let i=e=>e.toLowerCase().replace(/\s+/g,"-");e.s(["default",0,({label:e,value:l,hint:o,info:n,secondary:c})=>(0,t.jsxs)(a.Card,{"data-testid":`summary-card-${i(e)}`,children:[(0,t.jsxs)(a.CardHeader,{className:"flex flex-row items-center justify-between space-y-0",children:[(0,t.jsx)(a.CardTitle,{className:"text-sm font-medium text-muted-foreground",children:e}),n&&(0,t.jsxs)(s.Popover,{children:[(0,t.jsx)(s.PopoverTrigger,{"aria-label":`How ${e.toLowerCase()} is calculated`,"data-testid":`summary-card-info-${i(e)}`,className:"cursor-pointer text-muted-foreground hover:text-foreground",children:(0,t.jsx)(r.Info,{className:"size-3.5"})}),(0,t.jsx)(s.PopoverContent,{align:"end",className:"w-64 text-sm text-muted-foreground",children:n})]})]}),(0,t.jsx)(a.CardContent,{children:(0,t.jsxs)("div",{className:"flex items-end gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-2xl font-semibold text-foreground",children:l}),o&&(0,t.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:o})]}),c&&(0,t.jsx)("div",{className:"self-stretch border-l pl-4",children:(0,t.jsxs)("div",{className:"flex h-full flex-col justify-end",children:[(0,t.jsx)("p",{className:"text-lg font-medium text-muted-foreground",children:c.value}),(0,t.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:c.label})]})})]})})]})])},79361,e=>{"use strict";var t=e.i(500330);let r=e=>new Date(`${e}T00:00:00`).toLocaleDateString("en-US",{month:"short",day:"numeric"}),a=e=>e.compression_savings_spend??0,s=e=>e.gateway_injected_caching_savings_spend??0,i=e=>e.autorouter_savings_spend??0,l=e=>/claude|anthropic/i.test(e),o=()=>({alias:null,teamId:null,promptTokens:0,cacheReadTokens:0,cacheCreationTokens:0,realizedCachingSavings:0}),n=(e,t,r,a)=>({alias:e.alias??r,teamId:e.teamId??a,promptTokens:e.promptTokens+(t.prompt_tokens??0),cacheReadTokens:e.cacheReadTokens+(t.cache_read_input_tokens??0),cacheCreationTokens:e.cacheCreationTokens+(t.cache_creation_input_tokens??0),realizedCachingSavings:e.realizedCachingSavings+(t.prompt_caching_savings_spend??0)}),c=(e,t)=>t.reduce((e,t)=>({...e,[t]:0}),{date:e}),d=[{name:"Compression",color:"emerald",of:a},{name:"Prompt caching",color:"blue",of:s},{name:"Auto-router",color:"amber",of:i}],u=d.map(e=>e.name),m=d.map(e=>e.color);e.s(["MAX_POINTS_WITH_DOTS",0,31,"SAVINGS_COLORS",0,m,"SAVINGS_DRIVERS",0,d,"SAVINGS_SERIES",0,u,"autorouterOf",0,i,"buildDailyToolSeries",0,(e,t)=>{let r=new Set(t),a=new Map;for(let s of e){if(!r.has(s.tool_name))continue;let e=a.get(s.date)??c(s.date,t);e[s.tool_name]=(Number(e[s.tool_name])||0)+s.spend,a.set(s.date,e)}return[...a.values()].sort((e,t)=>e.date.localeCompare(t.date))},"cachingOf",0,e=>e.prompt_caching_savings_spend??0,"compressionOf",0,a,"computeCacheLeakage",0,(e,t="key",r=10)=>{let a="model"===t?(e=>{let t=new Map;for(let r of e)for(let[e,a]of Object.entries(r.breakdown?.models??{})){if(!l(e))continue;let r=t.get(e)??o();t.set(e,n(r,a.metrics,null,null))}return t})(e):(e=>{let t=new Map;for(let r of e)for(let[e,a]of Object.entries(r.breakdown?.api_keys??{})){let r=t.get(e)??o();t.set(e,n(r,a.metrics,a.metadata?.key_alias??null,a.metadata?.team_id??null))}return t})(e),s=[...a.values()].reduce((e,t)=>({cachedTokens:e.cachedTokens+t.cacheReadTokens+t.cacheCreationTokens,realizedCachingSavings:e.realizedCachingSavings+t.realizedCachingSavings}),{cachedTokens:0,realizedCachingSavings:0}),i=s.cachedTokens>0?s.realizedCachingSavings/s.cachedTokens:null,c=null!=i&&i>0?i:null;return{rows:[...a.entries()].map(([e,r])=>{let a=Math.max(0,r.promptTokens-r.cacheReadTokens-r.cacheCreationTokens);return{id:e,label:"model"===t?e:r.alias??`${e.slice(0,8)}...`,sublabel:"model"===t?null:r.teamId,uncachedPromptTokens:a,cacheHitRatio:r.promptTokens>0?r.cacheReadTokens/r.promptTokens:0,potentialSavings:null!=c?a*c:null}}).filter(e=>e.uncachedPromptTokens>0).sort((e,t)=>null!=c?(t.potentialSavings??0)-(e.potentialSavings??0):t.uncachedPromptTokens-e.uncachedPromptTokens).slice(0,r),netSavingsPerCachedToken:i}},"formatRangeLabel",0,(e,t)=>{if(!e||!t)return"";let r=e=>e.toLocaleDateString("en-US",{month:"short",day:"numeric"}),a=r(e),s=r(t);return a===s?a:`${a} – ${s}`},"gatewayAttributedCachingOf",0,s,"localIsoDay",0,e=>`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`,"pct",0,e=>`${(0,t.formatNumberWithCommas)(100*e,1)}%`,"savedTokensOf",0,e=>e.compression_saved_tokens??0,"savingsSeriesOf",0,e=>[...e].sort((e,t)=>e.date.localeCompare(t.date)).map(e=>({date:r(e.date),...Object.fromEntries(d.map(({name:t,of:r})=>[t,r(e.metrics)]))})),"shortDate",0,r,"sumOverDays",0,(e,t)=>e.reduce((e,r)=>e+t(r.metrics),0),"toCumulative",0,e=>e.reduce((e,t)=>{let r=e[e.length-1];return[...e,{date:t.date,Compression:(r?.Compression??0)+t.Compression,"Prompt caching":(r?.["Prompt caching"]??0)+t["Prompt caching"],"Auto-router":(r?.["Auto-router"]??0)+t["Auto-router"]}]},[]),"topToolsBySpend",0,(e,t=8)=>[...e].sort((e,t)=>t.spend-e.spend).slice(0,t),"usd",0,e=>{let r=Math.abs(e);return`${e<0?"-":""}$${(0,t.formatNumberWithCommas)(r,r>0&&r<1?4:2)}`},"withStartAnchor",0,(e,t)=>0===e.length?[...e]:[{date:t,Compression:0,"Prompt caching":0,"Auto-router":0},...e]])},811033,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(908990),s=e.i(79361),i=e.i(500330);e.s(["default",0,({results:e,isLoading:l})=>{let o=(0,r.useMemo)(()=>({compression:(0,s.sumOverDays)(e,s.compressionOf),caching:(0,s.sumOverDays)(e,s.cachingOf),autorouter:(0,s.sumOverDays)(e,s.autorouterOf),gatewayAttributedCaching:(0,s.sumOverDays)(e,s.gatewayAttributedCachingOf),savedTokens:(0,s.sumOverDays)(e,s.savedTokensOf),total:s.SAVINGS_DRIVERS.reduce((t,{of:r})=>t+(0,s.sumOverDays)(e,r),0)}),[e]);return(0,t.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4",children:[(0,t.jsx)(a.default,{label:"Total saved",value:(0,s.usd)(o.total),hint:l?"Loading...":"Compression + prompt caching + auto-router",info:"The sum of the three tiles beside it. Its caching term is the LiteLLM-injected share, so this total is what the gateway itself delivered; caching that clients or providers brought on their own appears only in the caching tile's Total figure."}),(0,t.jsx)(a.default,{label:"Compression savings",value:(0,s.usd)(o.compression),hint:`${(0,i.formatNumberWithCommas)(o.savedTokens)} tokens compressed`,info:"Tokens Headroom removed before the call, priced at the model's input rate."}),(0,t.jsx)(a.default,{label:"Prompt caching savings",value:(0,s.usd)(o.gatewayAttributedCaching),hint:"LiteLLM injected",secondary:{label:"Total",value:(0,s.usd)(o.caching)},info:"What caching saved against paying the input rate for every token: the discount on tokens served from cache, less the premium providers charge to write a cache entry. The headline figure is the share LiteLLM earned by inserting the breakpoints itself, through configured injection points or auto prompt caching. The total beside it also counts requests that arrived with their own cache_control and providers that cache implicitly. Either can be negative on traffic that writes more cache than it reuses, which is why the headline is not always the smaller of the two."}),(0,t.jsx)(a.default,{label:"Auto-router savings",value:(0,s.usd)(o.autorouter),hint:"vs. the priciest model it could pick",info:"What this traffic would have cost had every request gone to the most expensive model the auto-router can route to, minus what it actually cost. Switching leaves the new model with a cold cache, so it pays to write the prompt again while the baseline is priced as already warm; a route that thrashes the cache can total below zero, and a genuine first turn, where neither side had anything cached, is undercounted."})]})}])},567425,e=>{"use strict";var t=e.i(271645);let r=["total_spend","total_prompt_tokens","total_completion_tokens","total_tokens","total_api_requests","total_successful_requests","total_failed_requests","total_cache_read_input_tokens","total_cache_creation_input_tokens","total_flat_cost"],a={results:[],metadata:{total_spend:0,total_prompt_tokens:0,total_completion_tokens:0,total_tokens:0,total_api_requests:0,total_successful_requests:0,total_failed_requests:0,total_cache_read_input_tokens:0,total_cache_creation_input_tokens:0,total_pages:1,has_more:!1,page:1}},s=(e,t)=>Object.fromEntries(Array.from(new Set([...Object.keys(e),...Object.keys(t)])).map(r=>{let a=e[r],s=t[r];return"number"!=typeof a&&"number"!=typeof s?[r,a??s]:[r,("number"==typeof a?a:0)+("number"==typeof s?s:0)]})),i=(e,t,r)=>{let a=e??{},s=t??{};return Object.fromEntries(Array.from(new Set([...Object.keys(a),...Object.keys(s)])).map(e=>{let t=a[e],i=s[e];return void 0===t?[e,i]:void 0===i?[e,t]:[e,r(t,i)]}))},l=(e,t)=>({...e,metrics:s(e.metrics,t.metrics)}),o=(e,t)=>({...e,metrics:s(e.metrics,t.metrics),api_key_breakdown:i(e.api_key_breakdown,t.api_key_breakdown,l)});function n(e,t){return t.reduce((e,t)=>{let r=e.findIndex(e=>e.date===t.date);return -1===r?[...e,t]:e.map((e,a)=>{let n,c;return a===r?{...e,metrics:s(e.metrics,t.metrics),breakdown:(n=e.breakdown,c=t.breakdown,{models:i(n.models,c.models,o),model_groups:i(n.model_groups,c.model_groups,o),mcp_servers:i(n.mcp_servers,c.mcp_servers,o),providers:i(n.providers,c.providers,o),api_keys:i(n.api_keys,c.api_keys,l),entities:i(n.entities,c.entities,o),...n.endpoints||c.endpoints?{endpoints:i(n.endpoints,c.endpoints,o)}:{}})}:e})},[...e])}e.s(["usePaginatedDailyActivity",0,function({fetchFn:e,args:s,enabled:i,aggregatedFetchFn:l}){let[o,c]=(0,t.useState)(a),[d,u]=(0,t.useState)(!1),[m,h]=(0,t.useState)(!1),[A,g]=(0,t.useState)({currentPage:0,totalPages:0}),[p,f]=(0,t.useState)(!1),x=(0,t.useRef)(0),b=(0,t.useRef)(!1),v=(0,t.useRef)(null),_=(0,t.useRef)(s);_.current=s;let w=JSON.stringify(s),y=(0,t.useCallback)(()=>{b.current=!0,f(!0),h(!1),null!==v.current&&(clearTimeout(v.current),v.current=null)},[]);return(0,t.useEffect)(()=>{if(!i){c(a),u(!1),h(!1),g({currentPage:0,totalPages:0}),f(!1);return}let t=++x.current;b.current=!1,f(!1);let s=()=>x.current!==t||b.current,o=e=>new Promise(t=>{v.current=setTimeout(()=>{v.current=null,t()},e)});return(async()=>{let t=_.current;if(u(!0),h(!1),g({currentPage:1,totalPages:1}),l)try{let e=await l(...t);if(s())return;c(e),g({currentPage:1,totalPages:1}),u(!1);return}catch(e){if(s())return;console.error("Aggregated daily activity failed, falling back to pagination:",e)}try{let a=[...t.slice(0,3),1,...t.slice(3)],i=await e(...a);if(s())return;c(i);let l=i.metadata?.total_pages||1;if(g({currentPage:1,totalPages:l}),l<=1)return void u(!1);u(!1),h(!0);let d=n([],i.results),m={...i.metadata};for(let a=2;a<=l;a++){if(s()||(await o(300),s()))return;let i=[...t.slice(0,3),a,...t.slice(3)],u=await e(...i);if(s())return;d=n(d,u.results),(m=function(e,t){let a={...e};for(let s of r)a[s]=(e[s]||0)+(t[s]||0);return a}(m,u.metadata)).total_pages=l,m.has_more=a{x.current++,null!==v.current&&(clearTimeout(v.current),v.current=null)}},[i,e,l,w]),{data:o,loading:d,isFetchingMore:m,progress:A,cancelled:p,cancel:y}}])},555376,e=>{"use strict";var t=e.i(271645),r=e.i(602869),a=e.i(708347),s=e.i(567425);let i=(e,a)=>{let i=(0,t.useMemo)(()=>new Date(new Date().getTime()-2592e6),[]),l=(0,t.useMemo)(()=>new Date,[]),[o,n]=(0,t.useState)({from:i,to:l}),c=o.from??null,d=o.to??null,{userId:u,apiKey:m=null}=a,h={fetchFn:r.userDailyActivityCall,aggregatedFetchFn:r.userDailyActivityAggregatedCall,args:[e,c,d,u,!0,m],enabled:!!e&&!!c&&!!d},{data:A,loading:g,isFetchingMore:p,progress:f,cancelled:x,cancel:b}=(0,s.usePaginatedDailyActivity)(h);return{dateValue:o,onDateChange:n,results:A.results,loading:g,isFetchingMore:p,progress:f,cancelled:x,cancel:b}};e.s(["useDailyActivityRange",0,(e,t,r)=>i(e,{userId:(0,a.spendScopeUserId)(r,t)}),"useScopedDailyActivityRange",0,i])},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},871689,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeft",()=>t.default])},845150,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(131792);let s=(e,t)=>{let r=t.trim().toLowerCase();return!r||e.label.toLowerCase().includes(r)||e.value.toLowerCase().includes(r)||(e.description?.toLowerCase().includes(r)??!1)};e.s(["MultiSelect",0,function({id:e,options:i,value:l=[],onValueChange:o,placeholder:n="Select options",emptyText:c="No options found",disabled:d=!1,loading:u=!1,allowCustomValues:m=!1,className:h}){let A=(0,a.useComboboxAnchor)(),[g,p]=(0,r.useState)(""),f=i.filter(e=>null!=e&&"string"==typeof e.value&&e.value.length>0),x=l.filter(e=>"string"==typeof e&&e.length>0).map(e=>f.find(t=>t.value===e)??{label:e,value:e}),b=g.trim(),v=f.some(e=>e.value.toLowerCase()===b.toLowerCase()),_=m&&b&&!v?[...f,{label:`Create "${b}"`,value:b}]:f;return(0,t.jsxs)(a.Combobox,{multiple:!0,items:_,value:x,onValueChange:e=>{o(Array.from(new Set(m?e.flatMap(e=>l.includes(e.value)?[e.value]:e.value.split(",").map(e=>e.trim()).filter(e=>e.length>0)):e.map(e=>e.value)))),p("")},inputValue:g,onInputValueChange:p,isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:s,disabled:d||u,children:[(0,t.jsx)(a.ComboboxChips,{render:(0,t.jsx)("div",{ref:A}),className:`min-h-8 py-1 text-sm ${h??""}`,children:(0,t.jsx)(a.ComboboxValue,{children:r=>(0,t.jsxs)(t.Fragment,{children:[r.map(e=>(0,t.jsx)(a.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),(0,t.jsx)(a.ComboboxChipsInput,{id:e,placeholder:u?"Loading...":n,className:"min-w-24","aria-label":n||void 0}),r.length>0&&!d&&!u&&(0,t.jsx)(a.ComboboxClear,{className:"ml-auto self-center","aria-label":"Clear all"})]})})}),(0,t.jsxs)(a.ComboboxContent,{anchor:A,children:[(0,t.jsx)(a.ComboboxEmpty,{children:c}),(0,t.jsx)(a.ComboboxList,{children:e=>(0,t.jsx)(a.ComboboxItem,{value:e,disabled:e.disabled,children:(0,t.jsxs)("span",{className:"min-w-0",children:[(0,t.jsx)("span",{className:"block truncate",children:e.label}),e.description&&(0,t.jsx)("span",{className:"block truncate text-xs text-muted-foreground",children:e.description})]})},e.value)})]})]})}])},871943,502547,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,r],871943);let a=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"}))});e.s(["ChevronRightIcon",0,a],502547)},278587,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,r],278587)},384767,e=>{"use strict";var t=e.i(843476),r=e.i(271645);let a=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"}))});var s=e.i(487486),i=e.i(602869);let l=function({vectorStores:e,accessToken:l}){let[o,n]=(0,r.useState)([]);return(0,r.useEffect)(()=>{(async()=>{if(l&&0!==e.length)try{let e=await (0,i.vectorStoreListCall)(l);e.data&&n(e.data.map(e=>({vector_store_id:e.vector_store_id,vector_store_name:e.vector_store_name})))}catch(e){console.error("Error fetching vector stores:",e)}})()},[l,e.length]),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(a,{className:"h-4 w-4 text-info"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"Vector Stores"}),(0,t.jsx)(s.Badge,{variant:"secondary",children:e.length})]}),e.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:e.map((e,r)=>{let a;return(0,t.jsx)("div",{className:"inline-flex min-w-0 items-center px-3 py-1.5 rounded-lg bg-info/10 border border-info/20 text-info text-sm font-medium break-words",children:(a=o.find(t=>t.vector_store_id===e))?`${a.vector_store_name||a.vector_store_id} (${a.vector_store_id})`:e},r)})}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(a,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-muted-foreground text-sm",children:"No vector stores configured"})]})]})};var o=e.i(953960);let n=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"}))});var c=e.i(746798);let d=function({agents:e,agentAccessGroups:a=[],accessToken:l}){let[o,d]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{if(l&&e.length>0)try{let e=await (0,i.getAgentsList)(l);e&&e.agents&&Array.isArray(e.agents)&&d(e.agents)}catch(e){console.error("Error fetching agents:",e)}})()},[l,e.length]);let u=[...e.map(e=>({type:"agent",value:e})),...a.map(e=>({type:"accessGroup",value:e}))],m=u.length;return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-purple-600"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"Agents"}),(0,t.jsx)(s.Badge,{variant:"secondary",children:m})]}),m>0?(0,t.jsx)("div",{className:"max-h-[400px] overflow-y-auto space-y-2 pr-1",children:u.map((e,r)=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsx)("div",{className:"flex items-center gap-3 py-2 px-3 rounded-lg border border-border bg-card",children:(0,t.jsx)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:"agent"===e.type?(0,t.jsx)(c.TooltipProvider,{delay:300,children:(0,t.jsxs)(c.Tooltip,{children:[(0,t.jsxs)(c.TooltipTrigger,{render:(0,t.jsx)("div",{className:"inline-flex items-center gap-2 min-w-0"}),children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-purple-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:(e=>{let t=o.find(t=>t.agent_id===e);if(t){let r=e.length>7?`${e.slice(0,3)}...${e.slice(-4)}`:e;return`${t.agent_name} (${r})`}return e})(e.value)})]}),(0,t.jsx)(c.TooltipContent,{children:`Full ID: ${e.value}`})]})}):(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-success rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:e.value}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-success bg-success/10 border border-success/20 rounded-sm uppercase tracking-wide shrink-0",children:"Group"})]})})})},r))}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-muted-foreground text-sm",children:"No agents or access groups configured"})]})]})};e.s(["default",0,function({objectPermission:e,variant:r="card",className:a="",accessToken:s}){let i=e?.vector_stores||[],n=e?.mcp_servers||[],c=e?.mcp_access_groups||[],u=e?.mcp_tool_permissions||{},m=e?.mcp_toolsets||[],h=e?.agents||[],A=e?.agent_access_groups||[],g=e?.search_tools||[],p=(0,t.jsxs)("div",{className:"card"===r?"grid grid-cols-1 @xl:grid-cols-2 @4xl:grid-cols-3 gap-6":"space-y-4",children:[(0,t.jsx)(l,{vectorStores:i,accessToken:s}),(0,t.jsx)(o.default,{mcpServers:n,mcpAccessGroups:c,mcpToolPermissions:u,mcpToolsets:m,accessToken:s}),(0,t.jsx)(d,{agents:h,agentAccessGroups:A,accessToken:s}),(0,t.jsxs)("div",{className:"min-w-0 rounded-md border border-border p-4",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Search tools"}),0===g.length?(0,t.jsx)("p",{className:"mt-1 block text-xs text-muted-foreground",children:"No restriction — all configured search tools are allowed for this team."}):(0,t.jsx)("p",{className:"mt-1 block text-xs break-words text-foreground",children:g.join(", ")})]})]});return"card"===r?(0,t.jsxs)("div",{className:`@container bg-card border border-border rounded-lg p-6 ${a}`,children:[(0,t.jsx)("div",{className:"flex items-center gap-2 mb-6",children:(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"font-semibold text-foreground",children:"Object Permissions"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Access control for Vector Stores and MCP Servers"})]})}),p]}):(0,t.jsxs)("div",{className:`${a}`,children:[(0,t.jsx)("p",{className:"font-medium text-foreground mb-3",children:"Object Permissions"}),p]})}],384767)},422444,e=>{"use strict";var t=e.i(571353);let r=new Set(["all-proxy-models","all-team-models","no-default-models"]);e.s(["keyDetailHref",0,function(e){return`${(0,t.migratedHref)("api-keys")}?key=${encodeURIComponent(e)}`},"modelGroupHref",0,function(e){if(!r.has(e))return`${(0,t.migratedHref)("models-and-endpoints")}?model_group=${encodeURIComponent(e)}`},"orgDetailHref",0,function(e){return`${(0,t.migratedHref)("organizations")}?org=${encodeURIComponent(e)}`},"teamDetailHref",0,function(e){return`${(0,t.migratedHref)("teams")}?team=${encodeURIComponent(e)}`},"userDetailHref",0,function(e){return`${(0,t.migratedHref)("users")}?user=${encodeURIComponent(e)}`}])},556908,953960,e=>{"use strict";var t=e.i(843476),r=e.i(67488),a=e.i(487486),s=e.i(196631);let i="px-2.5 py-1 text-sm";function l({href:e,variant:o,className:n,children:c}){let d=(0,r.useEntityLinkClick)(e);return(0,t.jsx)(a.Badge,{variant:o,className:(0,s.cn)("cursor-pointer",i,n),render:(0,t.jsx)("a",{href:e,onClick:d}),children:c})}e.s(["BadgeLink",0,function({href:e,variant:r="secondary",className:o,children:n}){return e?(0,t.jsx)(l,{href:e,variant:r,className:o,children:n}):(0,t.jsx)(a.Badge,{variant:r,className:(0,s.cn)(i,o),children:n})}],556908);var o=e.i(271645);let n=o.forwardRef(function(e,t){return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"}))});var c=e.i(871943),d=e.i(502547),u=e.i(746798),m=e.i(602869),h=e.i(234713);e.s(["default",0,function({mcpServers:e,mcpAccessGroups:r=[],mcpToolPermissions:s={},mcpToolsets:i=[],accessToken:l}){let[A,g]=(0,o.useState)([]),[p,f]=(0,o.useState)([]),[x,b]=(0,o.useState)(new Set),[v,_]=(0,o.useState)(new Set);(0,o.useEffect)(()=>{(async()=>{if(l&&e.length>0)try{let e=await (0,m.fetchMCPServers)(l);e&&Array.isArray(e)?g(e):e.data&&Array.isArray(e.data)&&g(e.data)}catch(e){console.error("Error fetching MCP servers:",e)}})()},[l,e.length]),(0,o.useEffect)(()=>{(async()=>{if(l&&i.length>0)try{let e=await (0,m.fetchMCPToolsets)(l),t=Array.isArray(e)?e.filter(e=>i.includes(e.toolset_id)):[];f(t)}catch(e){console.error("Error fetching toolsets:",e)}})()},[l,i.length]);let w=e.includes(h.NO_MCP_SERVERS_SENTINEL),y=e.includes(h.ALL_PROXY_MCP_SERVERS_SENTINEL),C=[...e.filter(e=>e!==h.NO_MCP_SERVERS_SENTINEL&&e!==h.ALL_PROXY_MCP_SERVERS_SENTINEL).map(e=>({type:"server",value:e})),...r.map(e=>({type:"accessGroup",value:e}))],k=C.length+i.length;return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-info"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"MCP Servers"}),(0,t.jsx)(a.Badge,{variant:w?"destructive":"secondary",children:w?"Blocked":y?"All":k})]}),w?(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-destructive/10 border border-destructive/20",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-destructive"}),(0,t.jsx)("p",{className:"text-destructive text-sm",children:"No MCP servers — this key is blocked from all MCP servers, including its team's servers"})]}):y?(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-info/10 border border-info/20",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-info"}),(0,t.jsx)("p",{className:"text-info text-sm",children:"All Proxy MCP Servers"})]}):k>0?(0,t.jsxs)("div",{className:"max-h-[400px] overflow-y-auto space-y-2 pr-1",children:[C.map((e,r)=>{let a="server"===e.type?s[e.value]:void 0,i=a&&a.length>0,l=x.has(e.value);return(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{onClick:()=>{var t;return i&&(t=e.value,void b(e=>{let r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}))},className:`flex items-center gap-3 py-2 px-3 rounded-lg border border-border transition-all ${i?"cursor-pointer hover:bg-accent":"bg-card"}`,children:[(0,t.jsx)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:"server"===e.type?(0,t.jsxs)(u.Tooltip,{children:[(0,t.jsxs)(u.TooltipTrigger,{render:(0,t.jsx)("div",{className:"inline-flex items-center gap-2 min-w-0"}),children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-info rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:(e=>{let t=A.find(t=>t.server_id===e);if(t){let r=e.length>7?`${e.slice(0,3)}...${e.slice(-4)}`:e;return`${t.alias||t.server_name||e} (${r})`}return e})(e.value)})]}),(0,t.jsx)(u.TooltipContent,{children:`Full ID: ${e.value}`})]}):(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-success rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:e.value}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-success bg-success/10 border border-success/20 rounded-sm uppercase tracking-wide shrink-0",children:"Group"})]})}),i&&(0,t.jsxs)("div",{className:"flex items-center gap-1 shrink-0 whitespace-nowrap",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-muted-foreground",children:a.length}),(0,t.jsx)("span",{className:"text-xs text-muted-foreground",children:1===a.length?"tool":"tools"}),l?(0,t.jsx)(c.ChevronDownIcon,{className:"h-3.5 w-3.5 text-muted-foreground ml-0.5"}):(0,t.jsx)(d.ChevronRightIcon,{className:"h-3.5 w-3.5 text-muted-foreground ml-0.5"})]})]}),i&&l&&(0,t.jsx)("div",{className:"ml-4 pl-4 border-l-2 border-info/20 pb-1",children:(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:a.map((e,r)=>(0,t.jsx)("span",{className:"inline-flex items-center px-2.5 py-1 rounded-lg bg-info/10 border border-info/20 text-info text-xs font-medium",children:e},r))})})]},r)}),i.length>0&&i.map((e,r)=>{let a=p.find(t=>t.toolset_id===e),s=v.has(e),i=a?.tools.length??0;return(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{onClick:()=>i>0&&void _(t=>{let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r}),className:`flex items-center gap-3 py-2 px-3 rounded-lg border border-purple-200 transition-all ${i>0?"cursor-pointer hover:bg-purple-50 hover:border-purple-300 dark:hover:bg-purple-950 dark:hover:border-purple-700":"bg-card"}`,children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-purple-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:a?.toolset_name??e}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-purple-600 bg-purple-50 border border-purple-200 rounded-sm uppercase tracking-wide shrink-0 dark:text-purple-300 dark:bg-purple-950 dark:border-purple-800",children:"Toolset"})]}),i>0&&(0,t.jsxs)("div",{className:"flex items-center gap-1 shrink-0 whitespace-nowrap",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-muted-foreground",children:i}),(0,t.jsx)("span",{className:"text-xs text-muted-foreground",children:1===i?"tool":"tools"}),s?(0,t.jsx)(c.ChevronDownIcon,{className:"h-3.5 w-3.5 text-muted-foreground ml-0.5"}):(0,t.jsx)(d.ChevronRightIcon,{className:"h-3.5 w-3.5 text-muted-foreground ml-0.5"})]})]}),i>0&&s&&a&&(0,t.jsx)("div",{className:"ml-4 pl-4 border-l-2 border-purple-200 pb-1",children:(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:a.tools.map((e,r)=>(0,t.jsxs)("span",{className:"inline-flex items-center px-2.5 py-1 rounded-lg bg-purple-50 border border-purple-200 text-purple-800 text-xs font-medium dark:bg-purple-950 dark:border-purple-800 dark:text-purple-300",children:[(0,t.jsxs)("span",{className:"text-purple-400 mr-1 text-[10px]",children:[e.server_id.slice(0,6),"…"]}),e.tool_name]},r))})})]},`toolset-${r}`)})]}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-muted-foreground text-sm",children:"No MCP servers, access groups, or toolsets configured"})]})]})}],953960)},247482,e=>{"use strict";var t=e.i(234713);let r=e=>Array.isArray(e)?e.filter(e=>"string"==typeof e):[],a=(e,t)=>e.server_id===t||e.server_name===t||e.alias===t;e.s(["extractMcpEntitlement",0,(e,s,i=[])=>{var l;let o=e.mcp_servers_and_groups;if(null===o||"object"!=typeof o)return null;let{servers:n,accessGroups:c,toolsets:d}=o,u=r(n),m=r(c),h=r(d),A=u.includes(t.ALL_PROXY_MCP_SERVERS_SENTINEL)||h.some(e=>!i.some(t=>t.toolset_id===e)),g=new Set(i.filter(e=>h.includes(e.toolset_id)).flatMap(e=>e.tools.map(e=>e.server_id))),p=e=>u.some(t=>a(e,t))||(e.mcp_access_groups??[]).some(e=>m.includes(e))||g.has(e.server_id);return{mcp_servers:u,mcp_access_groups:m,mcp_toolsets:h,mcp_tool_permissions:Object.fromEntries(Object.entries(null===(l=e.mcp_tool_permissions)||"object"!=typeof l||Array.isArray(l)?{}:Object.fromEntries(Object.entries(l).map(([e,t])=>[e,r(t)]))).filter(([e])=>{let t;return A||0===(t=s.filter(t=>a(t,e))).length||t.some(p)}))}}])},904031,953563,e=>{"use strict";let t=e=>JSON.stringify(Object.entries(e??{}).map(([e,t])=>[e,Number(t?.budget_limit??t?.max_budget??NaN),t?.time_period??t?.budget_duration??null]).sort((e,t)=>String(e[0]).localeCompare(String(t[0]))));e.s(["modelMaxBudgetUpdate",0,(e,r)=>t(e)===t(r)?void 0:e],904031);var r=e.i(271645);e.s(["useSeededState",0,function(e,t){let[a,s]=(0,r.useState)(t),[i,l]=(0,r.useState)(e);return i!==e&&(l(e),s(t())),[a,s]}],953563)},24529,e=>{"use strict";let t=Symbol.for("constructDateFrom");function r(e,r){return"function"==typeof e?e(r):e&&"object"==typeof e&&t in e?e[t](r):e instanceof Date?new e.constructor(r):new Date(r)}function a(e,t,a){var s;let i,{years:l=0,months:o=0,weeks:n=0,days:c=0,hours:d=0,minutes:u=0,seconds:m=0}=t,h=r(a?.in||e,e),A=o||l?function(e,t){let a=r(e,e);if(isNaN(t))return r(e,NaN);if(!t)return a;let s=a.getDate(),i=r(e,a.getTime());return(i.setMonth(a.getMonth()+t+1,0),s>=i.getDate())?i:(a.setFullYear(i.getFullYear(),i.getMonth(),s),a)}(h,o+12*l):h,g=c||n?(s=c+7*n,i=r(A,A),isNaN(s)?r(A,NaN):(s&&i.setDate(i.getDate()+s),i)):A;return r(a?.in||e,+g+1e3*(m+60*(u+60*d)))}let s=/[zZ]$|[+-]\d{2}:?\d{2}$/;function i(e){return Date.parse(s.test(e)?e:`${e}Z`)}e.s(["calculateExpiryPreviewFromDuration",0,function(e){if(!e)return null;try{let t,r=parseInt(e);if(Number.isNaN(r))throw Error("Invalid duration format");let s=new Date;if(e.endsWith("mo"))t=a(s,{months:r});else if(e.endsWith("s"))t=a(s,{seconds:r});else if(e.endsWith("m"))t=a(s,{minutes:r});else if(e.endsWith("h"))t=a(s,{hours:r});else if(e.endsWith("d"))t=a(s,{days:r});else if(e.endsWith("w"))t=a(s,{weeks:r});else throw Error("Invalid duration format");return t.toLocaleString()}catch{return null}},"formatExpiresUtc",0,function(e){let t=i(e);return Number.isNaN(t)?e:new Date(t).toLocaleString()},"isKeyExpired",0,function(e){if(!e)return!1;let t=i(e);return!Number.isNaN(t)&&t{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(602869),s=e.i(845150);e.s(["default",0,({onChange:e,value:i,className:l,accessToken:o,disabled:n})=>{let[c,d]=(0,r.useState)([]),[u,m]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{(async()=>{if(o){m(!0);try{let e=await (0,a.getGuardrailsList)(o);e.guardrails&&d(e.guardrails)}catch(e){console.error("Error fetching guardrails:",e)}finally{m(!1)}}})()},[o]),(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(s.MultiSelect,{disabled:n,placeholder:n?"Setting guardrails is a premium feature.":"Select guardrails",onValueChange:t=>{e(t)},value:i,loading:u,className:l,options:c.flatMap(e=>{let t=e.guardrail_name;return null==t||""===t?[]:[{label:t,value:t}]})})})}])},921511,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(864261),s=e.i(602869),i=e.i(845150);function l(e){return e.filter(e=>(e.version_status??"draft")!=="draft").map(e=>{var t;let r=e.version_number??1,a=e.version_status??"draft";return{label:`${e.policy_name} — v${r} (${a})${e.description?` — ${e.description}`:""}`,value:"production"===a?e.policy_name:e.policy_id?(t=e.policy_id,`policy_${t}`):e.policy_name}})}e.s(["default",0,({onChange:e,value:o,className:n,accessToken:c,disabled:d,onPoliciesLoaded:u})=>{let m=(0,a.default)("viewPolicies"),[h,A]=(0,r.useState)([]),[g,p]=(0,r.useState)(!1);return((0,r.useEffect)(()=>{(async()=>{if(c&&m){p(!0);try{let e=await (0,s.getPoliciesList)(c);e.policies&&(A(e.policies),u?.(e.policies))}catch(e){console.error("Error fetching policies:",e)}finally{p(!1)}}})()},[c,m,u]),m)?(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(i.MultiSelect,{disabled:d,placeholder:d?"Setting policies is a premium feature.":"Select policies (production or published versions)",onValueChange:t=>{e(t)},value:o,loading:g,className:n,options:l(h)})}):null},"getPolicyOptionEntries",0,l])},323585,e=>{"use strict";let t=(0,e.i(475254).default)("ellipsis-vertical",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"12",cy:"5",r:"1",key:"gxeob9"}],["circle",{cx:"12",cy:"19",r:"1",key:"lyex9k"}]]);e.s(["MoreVertical",0,t],323585)},223622,e=>{"use strict";let t=(0,e.i(475254).default)("ban",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m4.9 4.9 14.2 14.2",key:"1m5liu"}]]);e.s(["Ban",0,t],223622)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0d4xeknobwogp.js b/litellm/proxy/_experimental/out/_next/static/chunks/0d4xeknobwogp.js
deleted file mode 100644
index 7cac842b8d3..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/0d4xeknobwogp.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,263147,e=>{"use strict";var t=e.i(266027),r=e.i(243652),a=e.i(602869),s=e.i(431703),i=e.i(708347),l=e.i(135214);let o=(0,r.createQueryKeys)("accessGroups"),n=async e=>{let t=(0,a.getProxyBaseUrl)(),r=`${t}/v1/access_group`,i=await fetch(r,{method:"GET",headers:{[(0,a.getGlobalLitellmHeaderName)()]:`Bearer ${e}`,"Content-Type":"application/json"}});if(!i.ok){let e=await i.json(),t=(0,s.deriveErrorMessage)(e);throw(0,a.handleError)(t),Error(t)}return i.json()};e.s(["accessGroupKeys",0,o,"useAccessGroups",0,()=>{let{accessToken:e,userRole:r}=(0,l.default)();return(0,t.useQuery)({queryKey:o.list({}),queryFn:async()=>n(e),enabled:!!e&&i.all_admin_roles.includes(r||"")})}])},304911,e=>{"use strict";var t=e.i(843476),r=e.i(487486);e.s(["default",0,function({userId:e}){return"default_user_id"===e?(0,t.jsx)(r.Badge,{variant:"secondary",children:"Default Proxy Admin"}):(0,t.jsx)("span",{children:e})}])},190702,e=>{"use strict";e.s(["parseErrorMessage",0,e=>{if(!e)return"An unknown error occurred";if("string"==typeof e)return e;if(e.message)try{let t=JSON.parse(e.message);if(t.error&&t.error.message)return t.error.message;return"string"==typeof t?t:JSON.stringify(t,null,2)}catch(t){return e.message}if(e.response&&e.response.data){if("string"==typeof e.response.data)return e.response.data;if(e.response.data.message)return e.response.data.message;if(e.response.data.error)return"string"==typeof e.response.data.error?e.response.data.error:e.response.data.error.message||JSON.stringify(e.response.data.error)}return String(e)}])},519380,e=>{e.q("/litellm-asset-prefix/_next/static/media/bedrock.2vhamxr8q6y4o.svg")},946013,e=>{e.q("/litellm-asset-prefix/_next/static/media/google.3y8ypywwtqob_.svg")},641266,e=>{e.q("/litellm-asset-prefix/_next/static/media/microsoft_azure.3626-7zx7wf09.svg")},956529,e=>{e.q("/litellm-asset-prefix/_next/static/media/openai_small.3rj8nedgjpevh.svg")},913383,e=>{e.q("/litellm-asset-prefix/_next/static/media/a2a_agent.14el5-6dflh1h.png")},238564,e=>{e.q("/litellm-asset-prefix/_next/static/media/ai21.0m_u-tih8nm0v.svg")},941533,e=>{e.q("/litellm-asset-prefix/_next/static/media/aiml_api.1dq6dbpwklhlg.svg")},994636,e=>{e.q("/litellm-asset-prefix/_next/static/media/anthropic.3s95kgy8jpc64.svg")},824770,e=>{e.q("/litellm-asset-prefix/_next/static/media/assemblyai_small.0w_dslsra91uw.png")},920076,e=>{e.q("/litellm-asset-prefix/_next/static/media/baseten.41k2lnwp3c5g9.svg")},96889,e=>{e.q("/litellm-asset-prefix/_next/static/media/cerebras.1ur1xyfqk9ncz.svg")},348026,e=>{e.q("/litellm-asset-prefix/_next/static/media/cloudflare.2n1spdq7u5yki.svg")},727148,e=>{e.q("/litellm-asset-prefix/_next/static/media/cohere.22i3i2e449j5i.svg")},411703,e=>{e.q("/litellm-asset-prefix/_next/static/media/cometapi.3w0xficbg3dkk.svg")},922480,e=>{e.q("/litellm-asset-prefix/_next/static/media/cursor.1q1ev-_5l7exg.svg")},769490,e=>{e.q("/litellm-asset-prefix/_next/static/media/databricks.2hiet9qlqzn-g.svg")},829789,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepgram.3-krp20p_xed3.png")},41730,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepinfra.3lr_lsr7mhui6.png")},662576,e=>{e.q("/litellm-asset-prefix/_next/static/media/deepseek.3n4cu0x32i_7w.svg")},987202,e=>{e.q("/litellm-asset-prefix/_next/static/media/elevenlabs.2982m_dk2-h_y.png")},953265,e=>{e.q("/litellm-asset-prefix/_next/static/media/fal_ai.3rahrirki8sby.jpg")},346512,e=>{e.q("/litellm-asset-prefix/_next/static/media/featherless.3hmlef3fhc0h5.svg")},84416,e=>{e.q("/litellm-asset-prefix/_next/static/media/fireworks.3t1b6p8edeqyo.svg")},104602,e=>{e.q("/litellm-asset-prefix/_next/static/media/friendli.0ymiswh6l35bq.svg")},888193,e=>{e.q("/litellm-asset-prefix/_next/static/media/github_copilot.3k-8jyadoaq2u.svg")},447500,e=>{e.q("/litellm-asset-prefix/_next/static/media/groq.20csmqzsusp1k.svg")},270039,e=>{e.q("/litellm-asset-prefix/_next/static/media/huggingface.1-07ypt9ii_-p.svg")},227733,e=>{e.q("/litellm-asset-prefix/_next/static/media/hyperbolic.3le20v59sebn8.svg")},823929,e=>{e.q("/litellm-asset-prefix/_next/static/media/infinity.0s9s12bl4lccx.png")},333845,e=>{e.q("/litellm-asset-prefix/_next/static/media/jina.0ukab8o-3-5m_.png")},813878,e=>{e.q("/litellm-asset-prefix/_next/static/media/lambda.26_vz7cmyuodo.svg")},767788,e=>{e.q("/litellm-asset-prefix/_next/static/media/lmstudio.35s3-83mlhcms.svg")},808630,e=>{e.q("/litellm-asset-prefix/_next/static/media/meta_llama.1kxk24vwsem49.svg")},468732,e=>{e.q("/litellm-asset-prefix/_next/static/media/minimax.2mfkkqc-lnsen.svg")},610503,e=>{e.q("/litellm-asset-prefix/_next/static/media/mistral.0n8jv_67hgq4h.svg")},438969,e=>{e.q("/litellm-asset-prefix/_next/static/media/moonshot.3__i9wvf37ksm.svg")},852459,e=>{e.q("/litellm-asset-prefix/_next/static/media/morph.2av06eo-t0-ve.svg")},494696,e=>{e.q("/litellm-asset-prefix/_next/static/media/nebius.2ipf7rmjccira.svg")},148973,e=>{e.q("/litellm-asset-prefix/_next/static/media/novita.0_nzmm_rl4lrf.svg")},570036,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_nim.1fz-5ugf_um0v.svg")},151170,e=>{e.q("/litellm-asset-prefix/_next/static/media/nvidia_triton.1aotoxig_m2w1.png")},862330,e=>{e.q("/litellm-asset-prefix/_next/static/media/ollama.144cif369atc5.svg")},788158,e=>{e.q("/litellm-asset-prefix/_next/static/media/openrouter.1xk7748-_jixf.svg")},350567,e=>{e.q("/litellm-asset-prefix/_next/static/media/oracle.43kws59xxr8ig.svg")},822797,e=>{e.q("/litellm-asset-prefix/_next/static/media/perplexity-ai.2do8hoc8tw__0.svg")},840911,e=>{e.q("/litellm-asset-prefix/_next/static/media/qwen.0a49x9i08_0gz.png")},445735,e=>{e.q("/litellm-asset-prefix/_next/static/media/recraft.2f4cv-c9ad-mo.svg")},635202,e=>{e.q("/litellm-asset-prefix/_next/static/media/replicate.445bidyix2tyh.svg")},669161,e=>{e.q("/litellm-asset-prefix/_next/static/media/runway.2zzwye1fddnnn.png")},159508,e=>{e.q("/litellm-asset-prefix/_next/static/media/sambanova.1vcyu0faw1x8h.svg")},544025,e=>{e.q("/litellm-asset-prefix/_next/static/media/sap.1367hgge0s0xl.png")},708767,e=>{e.q("/litellm-asset-prefix/_next/static/media/scx_ai.3emo1p5delrhx.svg")},100588,e=>{e.q("/litellm-asset-prefix/_next/static/media/snowflake.2_p8qqpi0r3lr.svg")},183804,e=>{e.q("/litellm-asset-prefix/_next/static/media/soniox.3nhjmssy7ybh7.svg")},865502,e=>{e.q("/litellm-asset-prefix/_next/static/media/togetherai.1wk-mouzgw5ho.svg")},96912,e=>{e.q("/litellm-asset-prefix/_next/static/media/topaz.3rjp3zvx4eags.svg")},395073,e=>{e.q("/litellm-asset-prefix/_next/static/media/v0.15trd3tb1ulop.svg")},407829,e=>{e.q("/litellm-asset-prefix/_next/static/media/vercel.1mvnwxofolt8y.svg")},846077,e=>{e.q("/litellm-asset-prefix/_next/static/media/vllm.3_gqby46r7s3x.png")},914861,e=>{e.q("/litellm-asset-prefix/_next/static/media/volcengine.23ly9ik_qc138.png")},285328,e=>{e.q("/litellm-asset-prefix/_next/static/media/voyage.0krq6ew-yr8dk.webp")},779278,e=>{e.q("/litellm-asset-prefix/_next/static/media/watsonx.19rrg39yvhpk8.svg")},325532,e=>{e.q("/litellm-asset-prefix/_next/static/media/xai.2kc3gjiopn9om.svg")},288330,e=>{e.q("/litellm-asset-prefix/_next/static/media/xinference.063cy_ievvy5u.svg")},922158,336712,39182,980385,e=>{"use strict";let t={src:e.i(519380).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,t],922158);let r={src:e.i(946013).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,r],336712);let a={src:e.i(641266).default,width:200,height:58,blurWidth:0,blurHeight:0};e.s(["default",0,a],39182);let s={src:e.i(956529).default,width:28,height:28,blurWidth:0,blurHeight:0};e.s(["default",0,s],980385)},916925,555987,9774,247044,e=>{"use strict";var t,r=e.i(221688),a=e.i(950643);let s=/^(https?:|data:|blob:|\/\/)/i,i=e=>s.test(e),l=(e,t=r.serverRootPath)=>{let s;if(!e)return;if(i(e)||e.includes("/_next/static/"))return e;let l=(0,a.normalizeRootPath)(t);return l&&(e===l||e.startsWith(`${l}/`))?e:(s=(0,a.normalizeRootPath)(t),`${s}${e.startsWith("/")?e:`/${e}`}`)};e.s(["isExternalAssetSrc",0,i,"resolveLogoSrc",0,l],555987);let o={src:e.i(913383).default,width:661,height:768,blurWidth:7,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAICAYAAAA1BOUGAAAAwUlEQVR42h2OvQpGcByFf5dK7oBJFoooJDaDZFA+BoVkNBikGJSUJINyGeft/Q+nznDO00O6rsM0Tfi+z6JpGizLgqqqIEVR0HUdqqqCbdus930PWZZBy7IgCAKkaYpxHJEkCaIowjAMoGmaEMcx8jxHURRo2xZ1XaMsS9B5nrjvG+u6Yp5nfN+H53nwJ9JxHMiyDO/7Mtx1Xey1bRvIcRzwPI993xGGIZqmgSAIMAwDJEkSPM9jphzHsYHruhBFET+hn6S8pf6D7AAAAABJRU5ErkJggg=="},n={src:e.i(238564).default,width:103,height:24,blurWidth:0,blurHeight:0},c={src:e.i(941533).default,width:115,height:24,blurWidth:0,blurHeight:0},d={src:e.i(994636).default,width:46,height:46,blurWidth:0,blurHeight:0},u={src:e.i(824770).default,width:28,height:28,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAlElEQVR42m3OoQqDUBQGYF9mwzLbFiZsMNgwuGa4YFgYLC6PgcXuA5gFzdcgFkExGr33ogZRNIr6CAoKKgo/nAMfh/NTu3u4GWoY+0fIAsIC3C8LuIiRH9S2W5wBXsBPKaHTGGb+lZMJmCe2vPYjZe9/bMDswKMRbq9Yg9VRICcBq3p6FckINIf6o6ECwyOam/1YpwPFUFu+Lt2F2QAAAABJRU5ErkJggg=="},m={src:e.i(920076).default,width:16,height:16,blurWidth:0,blurHeight:0};var h=e.i(922158);let A={src:e.i(96889).default,width:800,height:600,blurWidth:0,blurHeight:0},g={src:e.i(348026).default,width:16,height:16,blurWidth:0,blurHeight:0};e.s(["default",0,g],9774);let p={src:e.i(727148).default,width:75,height:75,blurWidth:0,blurHeight:0},f={src:e.i(411703).default,width:16,height:16,blurWidth:0,blurHeight:0},x={src:e.i(922480).default,width:16,height:16,blurWidth:0,blurHeight:0},b={src:e.i(769490).default,width:16,height:16,blurWidth:0,blurHeight:0},v={src:e.i(829789).default,width:32,height:32,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAzklEQVR42k3PPWuDcBDHccUiiikYSwqhg+IkuKUpOLqK4OYrcBZcFCcH352mgy/Ch9mxEPg2+s+Q4W65zx33kyRJQpZlFOUNTdM4HN45Hi1Op0/O56+7tAHbtqmqiqZpKIqCy+Uby/rYkABhGLKuK+M4siwLt9sv1+sPpmkKEAQBwzCQpilxHDNNE3VdYxiGALqu47oujuMQRdEOyrJEVVUBFEUhSRK6rmOeZ/q+x/f97XkBHqfIsoy2bcnzHM/z9mSP2Q62dt/0c+O1/v4BYRxu3LgaR7UAAAAASUVORK5CYII="},_={src:e.i(41730).default,width:225,height:225,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAfklEQVR42nVOvQqDMBjM+7+RpbQ0Ji2NQhwdzGIwCMZFiCAa9STqIPhxw/3A3UeW41w/AKck87w0tqvbngkFgEDCJOPoKc+fovxKzaUGiXkOk0zei1TRzDxYEbHiIw0kzD2Aji5BqHolW9Uv0+9U01AVxivr4r8CjHX7+N27K5WIrP56XsFTAAAAAElFTkSuQmCC"},w={src:e.i(662576).default,width:293,height:215,blurWidth:0,blurHeight:0},y={src:e.i(987202).default,width:1563,height:1563,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA5ElEQVR42h2PPwtBURjGj3wCk93sC1iUCYXFIlGSMjC4QiiTBSE3Ge5M3e0uPoJFBhOTP8NNukXduFL3uJ1Xzz11znCe93me38uitQSL11Pe8rAanKpycbSa5Ar9UiAmJT3QXHGwHGfvj/vJcRzOfz/7fLvsW4tuJFZLehicEIUQpOs6GYZBOIfrcZPp5f0MsXDatk2yLJOqqu6A9f2YjXk7zNCJWM45KYpCmqa5A6/P+ynNGiEGIHSiwjRNsiyLBAmxPezW6U7Gx0ALIHQiFk6I5WEl6G6BB7QAQqc0a4bgxD/uH4FYoVec8m3dAAAAAElFTkSuQmCC"},C={src:e.i(953265).default,width:400,height:400,blurWidth:8,blurHeight:8,blurDataURL:"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/wAARCAAIAAgDAREAAhEBAxEB/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtP9N/tL+PO/8A7ZeV/wDFUj6L917L+r3/AMj/2Q=="},k={src:e.i(346512).default,width:16,height:16,blurWidth:0,blurHeight:0},E={src:e.i(84416).default,width:16,height:16,blurWidth:0,blurHeight:0},I={src:e.i(104602).default,width:16,height:16,blurWidth:0,blurHeight:0},N={src:e.i(888193).default,width:16,height:16,blurWidth:0,blurHeight:0};var j=e.i(336712);let O={src:e.i(447500).default,width:26,height:26,blurWidth:0,blurHeight:0},L={src:e.i(270039).default,width:16,height:16,blurWidth:0,blurHeight:0},S={src:e.i(227733).default,width:16,height:16,blurWidth:0,blurHeight:0},R={src:e.i(823929).default,width:128,height:129,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAApklEQVR42oWPsQrCMBRFY51KaUuwNktBQbcgSenQ32hCTBAHXfSfulUK4g/0/7yvdO+FB5dzXhLC2FoiJE3TfZ7nYrskyzIBVpBjTdPcu677GGPGtm1fmDd1YnVd31gIYSrLUnLOjxC9tfaLfhBCXLz307xQVZUCODvnfljoceAEpskxKeUV1w0Qo1LqobV+Lk8McI5tkDiOeZIkO9SIBr0gRm71l38QASaqNz7VMwAAAABJRU5ErkJggg=="},M={src:e.i(333845).default,width:200,height:200,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAXUlEQVR42p2MoRHAMAwDQwJzCcgCwQEZIDjA03gED2BzewSPWRe2qFcB3Z+kU0o/lXNea4U/0t77OYeIACDq4FLKnSKimYmIqjKzu885U6117z3GCGitxTbg/flJF7DAEmcR3WAqAAAAAElFTkSuQmCC"},T={src:e.i(813878).default,width:16,height:16,blurWidth:0,blurHeight:0},D={src:e.i(767788).default,width:16,height:16,blurWidth:0,blurHeight:0},B={src:e.i(808630).default,width:16,height:16,blurWidth:0,blurHeight:0};var H=e.i(39182);let P={src:e.i(468732).default,width:490,height:412,blurWidth:0,blurHeight:0},U={src:e.i(610503).default,width:16,height:16,blurWidth:0,blurHeight:0},V={src:e.i(438969).default,width:16,height:16,blurWidth:0,blurHeight:0},q={src:e.i(852459).default,width:16,height:16,blurWidth:0,blurHeight:0},W={src:e.i(494696).default,width:16,height:16,blurWidth:0,blurHeight:0},z={src:e.i(148973).default,width:16,height:16,blurWidth:0,blurHeight:0},G={src:e.i(570036).default,width:16,height:16,blurWidth:0,blurHeight:0},Y={src:e.i(151170).default,width:95,height:81,blurWidth:8,blurHeight:7,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAYAAAA1WQxeAAAA0UlEQVR42kXMvWrCUBjG8VxIL6KX0IvobXQSOrQd2kLSdMzQdMmaEErPUqoIIYtKOC5iFD9BEBwiaAY/AgpH/2oUfOGFh4cfj8blNmrNKK0zmFUZzmust2nea7u9IlkNkBMPv1Xgs3JHoXRDe1o+g8Vmyl/vnf++wU/7EdF54jW8JU6K14WTPgE3fjiCZ77kPa2kdAZZlrFcLpikXYLeN6Lxxm/zhfEsRimF5roupmli2zbGh4Gu61iWlX8URWhSSsIwxPM8hBA4jpNn3/cJgoADqC23HJzwo6wAAAAASUVORK5CYII="},F={src:e.i(862330).default,width:646,height:854,blurWidth:0,blurHeight:0};var Q=e.i(980385);let K={src:e.i(788158).default,width:300,height:300,blurWidth:0,blurHeight:0},J={src:e.i(350567).default,width:231,height:30,blurWidth:0,blurHeight:0},$={src:e.i(822797).default,width:48,height:48,blurWidth:0,blurHeight:0},X={src:e.i(840911).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABE0lEQVR42gEIAff+AAAAAAAAAAAAEQwmIT8ukIAgGUpBBwYQDQQECggAAAAAAAIBBQQJBhUTFw80LUIxloZbR8+5UUS3oUA4kH0HBxEOACMUUkolFlVNCAYTERwUPzgkHFJIIhxNRCsmYVQODSAbADYffnNFKaCSDgkgHD0tjX4+MI5+CQgVEhQSLCULChgUABAKJiJTM7+vJhlYTzEkb2MxJm9iIh1NQywnZFYhH0o/AA8JIh9RMrurNiR9cQkHFhMQDSUgUkW5o1hOx60pJlxPAAcEDw4qGmJYFw80LhENKCMyKHFjUEK0nhEOJSADAwYFAAAAAAADAgcGBQMLCRUPMClCNJeEIRtLQgAAAQAAAAAAfjQxsiCQipMAAAAASUVORK5CYII="},Z={src:e.i(445735).default,width:16,height:16,blurWidth:0,blurHeight:0},ee={src:e.i(635202).default,width:16,height:16,blurWidth:0,blurHeight:0},et={src:e.i(669161).default,width:320,height:320,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7UlEQVR42lVQvc7BYBR+B/kM3w+fFm2p9m3fRhFRP7UQlTAQCVfAgE3EHZAQMTBIzBIrYbEgFhaza3ABrsF7bIYnOTl5/s5BVrvIY5MMvYTbUuy8hN8CcFIdW62CgHCKjFwie/So3PqH+b0Hc+GebkW6Lj9zUtJaHwEbFvGqWf7zOG5GJVmjcwUEAUOevQmhfKSTqJol+7f94RT+L7Yv25OV3PtsI699EByc85qpW5qcUCaMyB7orH9EgJLaTnPNgk/QfUsxKi0QtKWFzjRzA7a08IEPCivYKWkyQHAKtJUMPIVMQCAmz3FKHcELXnxEPy9E1lYCAAAAAElFTkSuQmCC"},er={src:e.i(159508).default,width:52,height:46,blurWidth:0,blurHeight:0},ea={src:e.i(544025).default,width:3300,height:2550,blurWidth:8,blurHeight:6,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAAZklEQVR42oWNTQ5AMBhE3f8mEhux4BgiIRzAwoKWplrt146fBbVhkpnNvORF+El0jvMAV4RR2qtsJZD3DyA2h6xhiMsRSTUhrRm0DYBFE4qOI285yl5CGvdW0OEYhEE/G6jgvIGv7A4KupBwIVaNAAAAAElFTkSuQmCC"},es={src:e.i(708767).default,width:760,height:277,blurWidth:0,blurHeight:0},ei={src:e.i(100588).default,width:146,height:139,blurWidth:0,blurHeight:0};e.s(["default",0,ei],247044);let el={src:e.i(183804).default,width:100,height:18,blurWidth:0,blurHeight:0},eo={src:e.i(865502).default,width:32,height:32,blurWidth:0,blurHeight:0},en={src:e.i(96912).default,width:16,height:16,blurWidth:0,blurHeight:0},ec={src:e.i(395073).default,width:16,height:16,blurWidth:0,blurHeight:0},ed={src:e.i(407829).default,width:16,height:16,blurWidth:0,blurHeight:0},eu={src:e.i(846077).default,width:64,height:64,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAo0lEQVR42lWOvQrCQBCE7718oUA6wVcQBF/AXhu1CIgcpgoi/qCNguBPwCaChYHDv9zt3e6ZeEFxq9n5GGaY/T8iq3QhWKFRkZGWzEPaaE/RDoiI5e7z0BILP7tMB2vyO3p2BJew8syvvJLGQTPEaheSVJeAQIi5F2+CWt80uHopLMEnNBpPuNc2vaXK+38A4RauTvUhbBNwDvsOlYD3DA2Se99kLK7hC5QFVQAAAABJRU5ErkJggg=="},em={src:e.i(914861).default,width:1024,height:1024,blurWidth:8,blurHeight:8,blurDataURL:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA7ElEQVR42l2LMUsCAQBG39GFFQ02ad1oq0QIRR2hER4EGdQqdBDdQZAFEudU0NZSQ0O1VUOjiuJvEBxc3BQFEVQQdFAU9OROFwf9lg/e48Hiti8vWJekBSoIODacLK04CP79IAX8815cW2X3IYL3JIhaKuKLGdNGmMUCTo+Hq1yO72yB6HDEeTrFjm8fUVwGt3uL00eD5+6AfMvixbS5bTR5/43jcm2CooT4KNf56ltUGzafA5uoZZGpdJDlABhPr7z1TJLtMbXamMT0702T//aQu0gM5GOFvRuNkKoTDuucqRpeXePoWuPg0D8BGkpJjYhKXN4AAAAASUVORK5CYII="},eh={src:e.i(285328).default,width:400,height:399,blurWidth:8,blurHeight:8,blurDataURL:"data:image/webp;base64,UklGRgwBAABXRUJQVlA4TAABAAAvB8ABEM1VICICHggIDgIAAIDzDAACD0FoAAARAAwAAAAAAAAAAAAAAACAAABAAcBCAoAWgGyoXwUAAA8E7QQCAADg/N+nrsYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4CClZXkg5AQAAAAA538LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL0HIgEAAAAAcP4ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMsHA39Qutr2AtkROu8CASWZ/nMlNyzz5AdgWmkK65oUI6AlgIkY/M3zxIW3iABq15KT/Uz7BXidCOONHieAz1v6HqAC"},eA={src:e.i(779278).default,width:16,height:16,blurWidth:0,blurHeight:0},eg={src:e.i(325532).default,width:1e3,height:1e3,blurWidth:0,blurHeight:0},ep={src:e.i(288330).default,width:16,height:16,blurWidth:0,blurHeight:0};var ef=((t={}).A2A_Agent="A2A Agent",t.AI21="Ai21",t.AI21_CHAT="Ai21 Chat",t.AIML="AI/ML API",t.AIOHTTP_OPENAI="Aiohttp Openai",t.Anthropic="Anthropic",t.ANTHROPIC_TEXT="Anthropic Text",t.AssemblyAI="AssemblyAI",t.AUTO_ROUTER="Auto Router",t.Bedrock="Amazon Bedrock",t.BedrockMantle="Amazon Bedrock Mantle",t.SageMaker="AWS SageMaker",t.Azure="Azure",t.Azure_AI_Studio="Azure AI Foundry (Studio)",t.AZURE_TEXT="Azure Text",t.BASETEN="Baseten",t.BYTEZ="Bytez",t.Cerebras="Cerebras",t.CLARIFAI="Clarifai",t.CLOUDFLARE="Cloudflare",t.CODESTRAL="Codestral",t.Cognition="Cognition",t.Cohere="Cohere",t.COHERE_CHAT="Cohere Chat",t.COMETAPI="Cometapi",t.COMPACTIFAI="Compactifai",t.Cursor="Cursor",t.Dashscope="Dashscope",t.Databricks="Databricks (Qwen API)",t.DATAROBOT="Datarobot",t.DeepInfra="DeepInfra",t.Deepgram="Deepgram",t.Deepseek="Deepseek",t.DOCKER_MODEL_RUNNER="Docker Model Runner",t.DOTPROMPT="Dotprompt",t.ElevenLabs="ElevenLabs",t.EMPOWER="Empower",t.FalAI="Fal AI",t.FEATHERLESS_AI="Featherless Ai",t.FireworksAI="Fireworks AI",t.FRIENDLIAI="Friendliai",t.GALADRIEL="Galadriel",t.GITHUB_COPILOT="Github Copilot",t.Google_AI_Studio="Google AI Studio",t.GradientAI="GradientAI",t.Groq="Groq",t.HEROKU="Heroku",t.Hosted_Vllm="Hosted vLLM",t.HUGGINGFACE="Huggingface",t.HYPERBOLIC="Hyperbolic",t.Infinity="Infinity",t.JinaAI="Jina AI",t.LAMBDA_AI="Lambda Ai",t.LEMONADE="Lemonade",t.LLAMAFILE="Llamafile",t.LM_STUDIO="Lm Studio",t.LLAMA="Meta Llama",t.MARITALK="Maritalk",t.MiniMax="MiniMax",t.MistralAI="Mistral AI",t.MOONSHOT="Moonshot",t.MORPH="Morph",t.NEBIUS="Nebius",t.NLP_CLOUD="Nlp Cloud",t.NOVITA="Novita",t.NSCALE="Nscale",t.NVIDIA_NIM="Nvidia Nim",t.NVIDIA_RIVA="Nvidia Riva",t.Ollama="Ollama",t.OLLAMA_CHAT="Ollama Chat",t.OOBABOOGA="Oobabooga",t.OpenAI="OpenAI",t.OPENAI_LIKE="Openai Like",t.OpenAI_Compatible="OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)",t.OpenAI_Text="OpenAI Text Completion",t.OpenAI_Text_Compatible="OpenAI-Compatible Completions (legacy /v1/completions)",t.Openrouter="Openrouter",t.Oracle="Oracle Cloud Infrastructure (OCI)",t.OVHCLOUD="Ovhcloud",t.Perplexity="Perplexity",t.PETALS="Petals",t.PG_VECTOR="Pg Vector",t.PREDIBASE="Predibase",t.RECRAFT="Recraft",t.REPLICATE="Replicate",t.RunwayML="RunwayML",t.SAGEMAKER_LEGACY="Sagemaker",t.Sambanova="Sambanova",t.SAP="SAP Generative AI Hub",t.SCX_AI="SCX.ai",t.Snowflake="Snowflake",t.Soniox="Soniox",t.TEXT_COMPLETION_CODESTRAL="Text-Completion-Codestral",t.TogetherAI="TogetherAI",t.TOPAZ="Topaz",t.Triton="Triton",t.V0="V0",t.VERCEL_AI_GATEWAY="Vercel Ai Gateway",t.Vertex_AI="Vertex AI (Anthropic, Gemini, etc.)",t.VERTEX_AI_BETA="Vertex Ai Beta",t.VLLM="Local vLLM",t.VolcEngine="VolcEngine",t.Voyage="Voyage AI",t.WANDB="Wandb",t.WATSONX="Watsonx",t.WATSONX_TEXT="Watsonx Text",t.xAI="xAI",t.XINFERENCE="Xinference",t.ZAI="Z.AI (Zhipu AI)",t);let ex={A2A_Agent:"a2a_agent",AI21:"ai21",AI21_CHAT:"ai21_chat",AIML:"aiml",AIOHTTP_OPENAI:"aiohttp_openai",Anthropic:"anthropic",ANTHROPIC_TEXT:"anthropic_text",AssemblyAI:"assemblyai",AUTO_ROUTER:"auto_router",Azure:"azure",Azure_AI_Studio:"azure_ai",AZURE_TEXT:"azure_text",BASETEN:"baseten",Bedrock:"bedrock",BedrockMantle:"bedrock_mantle",BYTEZ:"bytez",Cerebras:"cerebras",CLARIFAI:"clarifai",CLOUDFLARE:"cloudflare",CODESTRAL:"codestral",Cognition:"cognition",Cohere:"cohere",COHERE_CHAT:"cohere_chat",COMETAPI:"cometapi",COMPACTIFAI:"compactifai",Cursor:"cursor",Dashscope:"dashscope",Databricks:"databricks",DATAROBOT:"datarobot",DeepInfra:"deepinfra",Deepgram:"deepgram",Deepseek:"deepseek",DOCKER_MODEL_RUNNER:"docker_model_runner",DOTPROMPT:"dotprompt",ElevenLabs:"elevenlabs",EMPOWER:"empower",FalAI:"fal_ai",FEATHERLESS_AI:"featherless_ai",FireworksAI:"fireworks_ai",FRIENDLIAI:"friendliai",GALADRIEL:"galadriel",GITHUB_COPILOT:"github_copilot",Google_AI_Studio:"gemini",GradientAI:"gradient_ai",Groq:"groq",HEROKU:"heroku",Hosted_Vllm:"hosted_vllm",HUGGINGFACE:"huggingface",HYPERBOLIC:"hyperbolic",Infinity:"infinity",JinaAI:"jina_ai",LAMBDA_AI:"lambda_ai",LEMONADE:"lemonade",LLAMAFILE:"llamafile",LLAMA:"meta_llama",LM_STUDIO:"lm_studio",MARITALK:"maritalk",MiniMax:"minimax",MistralAI:"mistral",MOONSHOT:"moonshot",MORPH:"morph",NEBIUS:"nebius",NLP_CLOUD:"nlp_cloud",NOVITA:"novita",NSCALE:"nscale",NVIDIA_NIM:"nvidia_nim",NVIDIA_RIVA:"nvidia_riva",Ollama:"ollama",OLLAMA_CHAT:"ollama_chat",OOBABOOGA:"oobabooga",OpenAI:"openai",OPENAI_LIKE:"openai_like",OpenAI_Compatible:"openai",OpenAI_Text:"text-completion-openai",OpenAI_Text_Compatible:"text-completion-openai",Openrouter:"openrouter",Oracle:"oci",OVHCLOUD:"ovhcloud",Perplexity:"perplexity",PETALS:"petals",PG_VECTOR:"pg_vector",PREDIBASE:"predibase",RECRAFT:"recraft",REPLICATE:"replicate",RunwayML:"runwayml",SAGEMAKER_LEGACY:"sagemaker",SageMaker:"sagemaker_chat",Sambanova:"sambanova",SAP:"sap",SCX_AI:"scx-ai",Snowflake:"snowflake",Soniox:"soniox",TEXT_COMPLETION_CODESTRAL:"text-completion-codestral",TogetherAI:"together_ai",TOPAZ:"topaz",Triton:"triton",V0:"v0",VERCEL_AI_GATEWAY:"vercel_ai_gateway",Vertex_AI:"vertex_ai",VERTEX_AI_BETA:"vertex_ai_beta",VLLM:"vllm",VolcEngine:"volcengine",Voyage:"voyage",WANDB:"wandb",WATSONX:"watsonx",WATSONX_TEXT:"watsonx_text",xAI:"xai",XINFERENCE:"xinference",ZAI:"zai"},eb=new Set(["bedrock_mantle"]),ev={"A2A Agent":o.src,Ai21:n.src,"Ai21 Chat":n.src,"AI/ML API":c.src,"Aiohttp Openai":Q.default.src,Anthropic:d.src,"Anthropic Text":d.src,AssemblyAI:u.src,Azure:H.default.src,"Azure AI Foundry (Studio)":H.default.src,"Azure Text":H.default.src,Baseten:m.src,"Amazon Bedrock":h.default.src,"Amazon Bedrock Mantle":h.default.src,"AWS SageMaker":h.default.src,Cerebras:A.src,Cloudflare:g.src,Codestral:U.src,Cohere:p.src,"Cohere Chat":p.src,Cometapi:f.src,Cursor:x.src,"Databricks (Qwen API)":b.src,Dashscope:X.src,Deepseek:w.src,Deepgram:v.src,DeepInfra:_.src,ElevenLabs:y.src,"Fal AI":C.src,"Featherless Ai":k.src,"Fireworks AI":E.src,Friendliai:I.src,"Github Copilot":N.src,"Google AI Studio":j.default.src,Groq:O.src,"Hosted vLLM":eu.src,Huggingface:L.src,Hyperbolic:S.src,Infinity:R.src,"Jina AI":M.src,"Lambda Ai":T.src,"Lm Studio":D.src,"Meta Llama":B.src,MiniMax:P.src,"Mistral AI":U.src,Moonshot:V.src,Morph:q.src,Nebius:W.src,Novita:z.src,"Nvidia Nim":G.src,"Nvidia Riva":G.src,Ollama:F.src,"Ollama Chat":F.src,Oobabooga:Q.default.src,OpenAI:Q.default.src,"Openai Like":Q.default.src,"OpenAI Text Completion":Q.default.src,"OpenAI-Compatible Completions (legacy /v1/completions)":Q.default.src,"OpenAI-Compatible Chat Completions (Together AI, vLLM, etc.)":Q.default.src,Openrouter:K.src,"Oracle Cloud Infrastructure (OCI)":J.src,Perplexity:$.src,Recraft:Z.src,Replicate:ee.src,RunwayML:et.src,Sagemaker:h.default.src,Sambanova:er.src,"SAP Generative AI Hub":ea.src,"SCX.ai":es.src,Snowflake:ei.src,Soniox:el.src,"Text-Completion-Codestral":U.src,TogetherAI:eo.src,Topaz:en.src,Triton:Y.src,V0:ec.src,"Vercel Ai Gateway":ed.src,"Vertex AI (Anthropic, Gemini, etc.)":j.default.src,"Vertex Ai Beta":j.default.src,"Local vLLM":eu.src,VolcEngine:em.src,"Voyage AI":eh.src,Watsonx:eA.src,"Watsonx Text":eA.src,xAI:eg.src,Xinference:ep.src},e_={"AI/ML API":"aiml/flux-pro/v1.1",Anthropic:"claude-3-opus",Azure:"my-deployment","Azure AI Foundry (Studio)":"azure_ai/command-r-plus","Amazon Bedrock":"claude-3-opus",Cognition:"cognition/swe-1.7",Cursor:"cursor/claude-4-sonnet",DeepInfra:"deepinfra/","Fal AI":"fal_ai/fal-ai/flux-pro/v1.1-ultra","Google AI Studio":"gemini-pro","Jina AI":"jina_ai/","Nvidia Riva":"nvidia_riva/nvidia/parakeet-ctc-1_1b-asr","Oracle Cloud Infrastructure (OCI)":"oci/xai.grok-4",RunwayML:"runwayml/gen4_turbo","AWS SageMaker":"sagemaker/jumpstart-dft-meta-textgeneration-llama-2-7b","SCX.ai":"scx-ai/GLM-5.2",Snowflake:"snowflake/mistral-7b","Vertex AI (Anthropic, Gemini, etc.)":"gemini-pro",VolcEngine:"volcengine/","Voyage AI":"voyage/",Watsonx:"watsonx/ibm/granite-3-3-8b-instruct","Z.AI (Zhipu AI)":"zai/glm-4.5"};e.s(["Providers",()=>ef,"getPlaceholder",0,e=>e_[ef[e]??e]??"gpt-3.5-turbo","getProviderLogoAndName",0,e=>{if(!e)return{logo:"",displayName:"-"};if("gemini"===e.toLowerCase()){let e="Google AI Studio";return{logo:l(ev[e])??"",displayName:e}}let t=Object.keys(ex).find(t=>ex[t].toLowerCase()===e.toLowerCase())??Object.keys(ex).find(t=>t.toLowerCase()===e.toLowerCase());if(!t)return{logo:"",displayName:e};let r=ef[t];return{logo:l(ev[r])??"",displayName:r}},"getProviderModels",0,(e,t)=>{let r=ex[e],a=[];return e&&"object"==typeof t&&(Object.entries(t).forEach(([e,t])=>{if(null!==t&&"object"==typeof t&&"litellm_provider"in t){let s=t.litellm_provider,i="string"==typeof s&&(s.startsWith(`${r}_`)||s.startsWith(`${r}-`));(s===r||i&&!eb.has(s))&&a.push(e)}}),"Cohere"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"cohere_chat"===t.litellm_provider&&a.push(e)}),"AWS SageMaker"==e&&Object.entries(t).forEach(([e,t])=>{null!==t&&"object"==typeof t&&"litellm_provider"in t&&"sagemaker_chat"===t.litellm_provider&&a.push(e)})),a},"providerLogoMap",0,ev,"provider_map",0,ex],916925)},174553,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(916925),s=e.i(555987),i=e.i(196631);let l=/(?:\/assets\/logos\/|\/_next\/static\/media\/)/,o={"baseten.svg":"invert","cursor.svg":"invert","enkrypt_ai.avif":"invert","friendli.svg":"invert","github.svg":"invert","github_copilot.svg":"invert","lago.svg":"invert","lambda.svg":"invert","langflow.svg":"invert","lmstudio.svg":"invert","moonshot.svg":"invert","nebius.svg":"invert","notion.svg":"invert","ollama.svg":"invert","openrouter.svg":"invert","promptguard.svg":"invert","recraft.svg":"invert","replicate.svg":"invert","runway.png":"invert","scx_ai.svg":"invert","secret_detect.png":"invert","topaz.svg":"invert","v0.svg":"invert","vercel.svg":"invert","watsonx.svg":"invert","aiml_api.svg":"plate","akto.svg":"plate","aws.svg":"plate","deepkeep.svg":"plate","fireworks.svg":"plate","llm_guard.png":"plate","pangea.png":"plate","repelloai.png":"plate","sambanova.svg":"plate","sentry.svg":"plate","valkey.svg":"plate"},n={invert:"dark:[filter:brightness(0)_invert(1)]",plate:"dark:bg-logo-surface dark:object-contain dark:p-0.5"};e.s(["Logo",0,({provider:e,src:c,label:d,className:u="w-4 h-4"})=>{let[m,h]=(0,r.useState)(null),A=void 0!==e?(0,a.getProviderLogoAndName)(e).logo:(0,s.resolveLogoSrc)(c)??"",g=d??e??"";if(m===A||!A)return(0,t.jsx)("div",{className:`${u} rounded-full bg-border flex items-center justify-center text-xs`,children:g.charAt(0)||"-"});let p=(e=>{let t;if(!e||(0,s.isExternalAssetSrc)(e)||!l.test(e))return;let r=e.split(/[?#]/)[0].split("/").pop()||void 0,a=void 0===r||(t=r.split(".")).length<2?void 0:`${t[0]}.${t[t.length-1]}`;return void 0===a?void 0:o[a]})(A);return(0,t.jsx)("img",{src:A,alt:`${g||"-"} logo`,className:void 0===p?u:(0,i.cn)(u,n[p]),onError:()=>{console.warn(`Logo failed to load: ${A}`),h(A)}})}],174553)},286536,e=>{"use strict";let t=(0,e.i(475254).default)("eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Eye",0,t],286536)},77705,e=>{"use strict";let t=(0,e.i(475254).default)("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);e.s(["EyeOff",0,t],77705)},101048,e=>{"use strict";var t=e.i(123287);e.s(["CircleCheck",()=>t.default])},39312,e=>{"use strict";let t=(0,e.i(475254).default)("zap",[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]]);e.s(["Zap",0,t],39312)},503116,949411,e=>{"use strict";let t=(0,e.i(475254).default)("clock",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["polyline",{points:"12 6 12 12 16 14",key:"68esgv"}]]);e.s(["default",0,t],949411),e.s(["Clock",0,t],503116)},973706,87316,e=>{"use strict";var t=e.i(843476);let r=(0,e.i(475254).default)("calendar",[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]]);e.s(["Calendar",0,r],87316);var a=e.i(503116),s=e.i(519455),i=e.i(196631),l=e.i(166540),o=e.i(271645);let n=[{label:"Today",shortLabel:"today",getValue:()=>({from:(0,l.default)().startOf("day").toDate(),to:(0,l.default)().endOf("day").toDate()})},{label:"Last 7 days",shortLabel:"7d",getValue:()=>({from:(0,l.default)().subtract(7,"days").startOf("day").toDate(),to:(0,l.default)().endOf("day").toDate()})},{label:"Last 30 days",shortLabel:"30d",getValue:()=>({from:(0,l.default)().subtract(30,"days").startOf("day").toDate(),to:(0,l.default)().endOf("day").toDate()})},{label:"Month to date",shortLabel:"MTD",getValue:()=>({from:(0,l.default)().startOf("month").toDate(),to:(0,l.default)().endOf("day").toDate()})},{label:"Year to date",shortLabel:"YTD",getValue:()=>({from:(0,l.default)().startOf("year").toDate(),to:(0,l.default)().endOf("day").toDate()})}];e.s(["default",0,({value:e,onValueChange:c,label:d="Select Time Range",className:u,showTimeRange:m=!0,align:h="right"})=>{let[A,g]=(0,o.useState)(!1),[p,f]=(0,o.useState)(e),[x,b]=(0,o.useState)(null),[v,_]=(0,o.useState)(""),[w,y]=(0,o.useState)(""),C=(0,o.useRef)(null),k=(0,o.useCallback)(e=>{if(!e.from||!e.to)return null;for(let t of n){let r=t.getValue(),a=(0,l.default)(e.from).isSame((0,l.default)(r.from),"day"),s=(0,l.default)(e.to).isSame((0,l.default)(r.to),"day");if(a&&s)return t.shortLabel}return null},[]);(0,o.useEffect)(()=>{b(k(e))},[e,k]);let E=(0,o.useCallback)(()=>{if(!v||!w)return{isValid:!0,error:""};let e=(0,l.default)(v,"YYYY-MM-DD"),t=(0,l.default)(w,"YYYY-MM-DD");return e.isValid()&&t.isValid()?t.isBefore(e)?{isValid:!1,error:"End date cannot be before start date"}:{isValid:!0,error:""}:{isValid:!1,error:"Invalid date format"}},[v,w])();(0,o.useEffect)(()=>{e.from&&_((0,l.default)(e.from).format("YYYY-MM-DD")),e.to&&y((0,l.default)(e.to).format("YYYY-MM-DD")),f(e)},[e]),(0,o.useEffect)(()=>{let e=e=>{C.current&&!C.current.contains(e.target)&&g(!1)};return A&&document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[A]);let I=(0,o.useCallback)((e,t)=>{if(!e||!t)return"Select date range";let r=e=>(0,l.default)(e).format("D MMM, HH:mm");return`${r(e)} - ${r(t)}`},[]),N=(0,o.useCallback)(e=>{let t;if(!e.from)return e;let r={...e},a=new Date(e.from);return t=new Date(e.to?e.to:e.from),a.toDateString()===t.toDateString(),a.setHours(0,0,0,0),t.setHours(23,59,59,999),r.from=a,r.to=t,r},[]),j=(0,o.useCallback)(()=>{try{if(v&&w&&E.isValid){let e=(0,l.default)(v,"YYYY-MM-DD").startOf("day"),t=(0,l.default)(w,"YYYY-MM-DD").endOf("day");if(e.isValid()&&t.isValid()){let r={from:e.toDate(),to:t.toDate()};f(r);let a=k(r);b(a)}}}catch(e){console.warn("Invalid date format:",e)}},[v,w,E.isValid,k]);return(0,o.useEffect)(()=>{j()},[j]),(0,t.jsxs)("div",{className:(0,i.cn)("flex items-center gap-3",u),children:[d&&(0,t.jsx)("p",{className:"text-sm font-medium text-foreground whitespace-nowrap",children:d}),(0,t.jsxs)("div",{className:"relative",ref:C,children:[(0,t.jsx)("button",{type:"button","data-slot":"advanced-date-picker-trigger","aria-expanded":A,className:"w-[300px] px-3 py-2 text-sm text-left border border-border rounded-md bg-card cursor-pointer hover:border-ring focus:border-info focus:ring-1 focus:ring-ring",onClick:()=>g(!A),children:(0,t.jsxs)("span",{className:"flex items-center justify-between",children:[(0,t.jsxs)("span",{className:"flex items-center gap-2",children:[(0,t.jsx)(a.Clock,{className:"size-4 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-foreground",children:I(e.from,e.to)})]}),(0,t.jsx)("svg",{className:`w-4 h-4 text-muted-foreground transition-transform ${A?"rotate-180":""}`,fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})}),A&&(0,t.jsx)("div",{"data-slot":"advanced-date-picker-panel","data-align":h,className:(0,i.cn)("absolute top-full z-floating min-w-[600px] mt-1 bg-card border border-border rounded-lg shadow-xl","left"===h?"left-0":"right-0"),children:(0,t.jsxs)("div",{className:"flex",children:[(0,t.jsxs)("div",{className:"w-1/2 border-r border-border",children:[(0,t.jsx)("div",{className:"p-3 border-b border-border",children:(0,t.jsx)("span",{className:"text-sm font-semibold text-foreground",children:"Relative time"})}),(0,t.jsx)("div",{className:"h-[350px] overflow-y-auto",children:n.map(e=>{let r=x===e.shortLabel;return(0,t.jsxs)("button",{type:"button","data-slot":"advanced-date-picker-preset","aria-pressed":r,className:`flex w-full items-center justify-between px-5 py-4 text-left cursor-pointer border-b border-border transition-colors ${r?"bg-info/10 hover:bg-info/15 border-info/20":"hover:bg-accent"}`,onClick:()=>(e=>{let{from:t,to:r}=e.getValue();f({from:t,to:r}),b(e.shortLabel),_((0,l.default)(t).format("YYYY-MM-DD")),y((0,l.default)(r).format("YYYY-MM-DD"))})(e),children:[(0,t.jsx)("span",{className:`text-sm ${r?"text-info font-medium":"text-foreground"}`,children:e.label}),(0,t.jsx)("span",{className:`text-xs px-2 py-1 rounded capitalize ${r?"text-info bg-info/15":"text-muted-foreground bg-muted"}`,children:e.shortLabel})]},e.label)})})]}),(0,t.jsxs)("div",{className:"w-1/2 relative",children:[(0,t.jsx)("div",{className:"p-3.5 border-b border-border",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(r,{className:"size-4 text-muted-foreground"}),(0,t.jsx)("span",{className:"text-sm font-semibold text-foreground",children:"Start and end dates"})]})}),(0,t.jsxs)("div",{className:"p-6 space-y-6 pb-20",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"text-sm text-foreground mb-1 block",children:"Start date"}),(0,t.jsx)("input",{type:"date",value:v,onChange:e=>_(e.target.value),className:`w-65 px-3 py-2 text-sm border rounded-md cursor-pointer hover:border-ring focus:border-info focus:ring-1 focus:ring-ring ${!E.isValid?"border-destructive/30 focus:border-destructive focus:ring-red-200":"border-border"}`})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("label",{className:"text-sm text-foreground mb-1 block",children:"End date"}),(0,t.jsx)("input",{type:"date",value:w,onChange:e=>y(e.target.value),className:`w-65 px-3 py-2 text-sm border rounded-md cursor-pointer hover:border-ring focus:border-info focus:ring-1 focus:ring-ring ${!E.isValid?"border-destructive/30 focus:border-destructive focus:ring-red-200":"border-border"}`})]}),!E.isValid&&E.error&&(0,t.jsx)("div",{className:"bg-destructive/10 border border-destructive/20 rounded-md p-3",children:(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("svg",{className:"w-4 h-4 text-destructive",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,t.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z"})}),(0,t.jsx)("span",{className:"text-sm text-destructive font-medium",children:E.error})]})}),p.from&&p.to&&E.isValid&&(0,t.jsxs)("div",{className:"bg-info/10 p-3 rounded-md space-y-1",children:[(0,t.jsxs)("div",{className:"text-xs text-info",children:[(0,t.jsx)("span",{className:"font-medium",children:"From:"})," ",(0,l.default)(p.from).format("MMM D, YYYY [at] HH:mm:ss")]}),(0,t.jsxs)("div",{className:"text-xs text-info",children:[(0,t.jsx)("span",{className:"font-medium",children:"To:"})," ",(0,l.default)(p.to).format("MMM D, YYYY [at] HH:mm:ss")]})]})]}),(0,t.jsx)("div",{className:"absolute bottom-4 right-4",children:(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)(s.Button,{variant:"secondary",onClick:()=>{f(e),e.from&&_((0,l.default)(e.from).format("YYYY-MM-DD")),e.to&&y((0,l.default)(e.to).format("YYYY-MM-DD")),b(k(e)),g(!1)},children:"Cancel"}),(0,t.jsx)(s.Button,{onClick:()=>{p.from&&p.to&&E.isValid&&(c(p),requestIdleCallback(()=>{c(N(p))},{timeout:100}),g(!1))},disabled:!p.from||!p.to||!E.isValid,children:"Apply"})]})})]})]})})]})]})}],973706)},908990,e=>{"use strict";var t=e.i(843476),r=e.i(952571),a=e.i(515288),s=e.i(337822);let i=e=>e.toLowerCase().replace(/\s+/g,"-");e.s(["default",0,({label:e,value:l,hint:o,info:n,secondary:c})=>(0,t.jsxs)(a.Card,{"data-testid":`summary-card-${i(e)}`,children:[(0,t.jsxs)(a.CardHeader,{className:"flex flex-row items-center justify-between space-y-0",children:[(0,t.jsx)(a.CardTitle,{className:"text-sm font-medium text-muted-foreground",children:e}),n&&(0,t.jsxs)(s.Popover,{children:[(0,t.jsx)(s.PopoverTrigger,{"aria-label":`How ${e.toLowerCase()} is calculated`,"data-testid":`summary-card-info-${i(e)}`,className:"cursor-pointer text-muted-foreground hover:text-foreground",children:(0,t.jsx)(r.Info,{className:"size-3.5"})}),(0,t.jsx)(s.PopoverContent,{align:"end",className:"w-64 text-sm text-muted-foreground",children:n})]})]}),(0,t.jsx)(a.CardContent,{children:(0,t.jsxs)("div",{className:"flex items-end gap-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-2xl font-semibold text-foreground",children:l}),o&&(0,t.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:o})]}),c&&(0,t.jsx)("div",{className:"self-stretch border-l pl-4",children:(0,t.jsxs)("div",{className:"flex h-full flex-col justify-end",children:[(0,t.jsx)("p",{className:"text-lg font-medium text-muted-foreground",children:c.value}),(0,t.jsx)("p",{className:"mt-1 text-xs text-muted-foreground",children:c.label})]})})]})})]})])},79361,e=>{"use strict";var t=e.i(500330);let r=e=>new Date(`${e}T00:00:00`).toLocaleDateString("en-US",{month:"short",day:"numeric"}),a=e=>e.compression_savings_spend??0,s=e=>e.gateway_injected_caching_savings_spend??0,i=e=>e.autorouter_savings_spend??0,l=e=>/claude|anthropic/i.test(e),o=()=>({alias:null,teamId:null,promptTokens:0,cacheReadTokens:0,cacheCreationTokens:0,realizedCachingSavings:0}),n=(e,t,r,a)=>({alias:e.alias??r,teamId:e.teamId??a,promptTokens:e.promptTokens+(t.prompt_tokens??0),cacheReadTokens:e.cacheReadTokens+(t.cache_read_input_tokens??0),cacheCreationTokens:e.cacheCreationTokens+(t.cache_creation_input_tokens??0),realizedCachingSavings:e.realizedCachingSavings+(t.prompt_caching_savings_spend??0)}),c=(e,t)=>t.reduce((e,t)=>({...e,[t]:0}),{date:e}),d=[{name:"Compression",color:"emerald",of:a},{name:"Prompt caching",color:"blue",of:s},{name:"Auto-router",color:"amber",of:i}],u=d.map(e=>e.name),m=d.map(e=>e.color);e.s(["MAX_POINTS_WITH_DOTS",0,31,"SAVINGS_COLORS",0,m,"SAVINGS_DRIVERS",0,d,"SAVINGS_SERIES",0,u,"autorouterOf",0,i,"buildDailyToolSeries",0,(e,t)=>{let r=new Set(t),a=new Map;for(let s of e){if(!r.has(s.tool_name))continue;let e=a.get(s.date)??c(s.date,t);e[s.tool_name]=(Number(e[s.tool_name])||0)+s.spend,a.set(s.date,e)}return[...a.values()].sort((e,t)=>e.date.localeCompare(t.date))},"cachingOf",0,e=>e.prompt_caching_savings_spend??0,"compressionOf",0,a,"computeCacheLeakage",0,(e,t="key",r=10)=>{let a="model"===t?(e=>{let t=new Map;for(let r of e)for(let[e,a]of Object.entries(r.breakdown?.models??{})){if(!l(e))continue;let r=t.get(e)??o();t.set(e,n(r,a.metrics,null,null))}return t})(e):(e=>{let t=new Map;for(let r of e)for(let[e,a]of Object.entries(r.breakdown?.api_keys??{})){let r=t.get(e)??o();t.set(e,n(r,a.metrics,a.metadata?.key_alias??null,a.metadata?.team_id??null))}return t})(e),s=[...a.values()].reduce((e,t)=>({cachedTokens:e.cachedTokens+t.cacheReadTokens+t.cacheCreationTokens,realizedCachingSavings:e.realizedCachingSavings+t.realizedCachingSavings}),{cachedTokens:0,realizedCachingSavings:0}),i=s.cachedTokens>0?s.realizedCachingSavings/s.cachedTokens:null,c=null!=i&&i>0?i:null;return{rows:[...a.entries()].map(([e,r])=>{let a=Math.max(0,r.promptTokens-r.cacheReadTokens-r.cacheCreationTokens);return{id:e,label:"model"===t?e:r.alias??`${e.slice(0,8)}...`,sublabel:"model"===t?null:r.teamId,uncachedPromptTokens:a,cacheHitRatio:r.promptTokens>0?r.cacheReadTokens/r.promptTokens:0,potentialSavings:null!=c?a*c:null}}).filter(e=>e.uncachedPromptTokens>0).sort((e,t)=>null!=c?(t.potentialSavings??0)-(e.potentialSavings??0):t.uncachedPromptTokens-e.uncachedPromptTokens).slice(0,r),netSavingsPerCachedToken:i}},"formatRangeLabel",0,(e,t)=>{if(!e||!t)return"";let r=e=>e.toLocaleDateString("en-US",{month:"short",day:"numeric"}),a=r(e),s=r(t);return a===s?a:`${a} – ${s}`},"gatewayAttributedCachingOf",0,s,"localIsoDay",0,e=>`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,"0")}-${String(e.getDate()).padStart(2,"0")}`,"pct",0,e=>`${(0,t.formatNumberWithCommas)(100*e,1)}%`,"savedTokensOf",0,e=>e.compression_saved_tokens??0,"savingsSeriesOf",0,e=>[...e].sort((e,t)=>e.date.localeCompare(t.date)).map(e=>({date:r(e.date),...Object.fromEntries(d.map(({name:t,of:r})=>[t,r(e.metrics)]))})),"shortDate",0,r,"sumOverDays",0,(e,t)=>e.reduce((e,r)=>e+t(r.metrics),0),"toCumulative",0,e=>e.reduce((e,t)=>{let r=e[e.length-1];return[...e,{date:t.date,Compression:(r?.Compression??0)+t.Compression,"Prompt caching":(r?.["Prompt caching"]??0)+t["Prompt caching"],"Auto-router":(r?.["Auto-router"]??0)+t["Auto-router"]}]},[]),"topToolsBySpend",0,(e,t=8)=>[...e].sort((e,t)=>t.spend-e.spend).slice(0,t),"usd",0,e=>{let r=Math.abs(e);return`${e<0?"-":""}$${(0,t.formatNumberWithCommas)(r,r>0&&r<1?4:2)}`},"withStartAnchor",0,(e,t)=>0===e.length?[...e]:[{date:t,Compression:0,"Prompt caching":0,"Auto-router":0},...e]])},811033,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(908990),s=e.i(79361),i=e.i(500330);e.s(["default",0,({results:e,isLoading:l})=>{let o=(0,r.useMemo)(()=>({compression:(0,s.sumOverDays)(e,s.compressionOf),caching:(0,s.sumOverDays)(e,s.cachingOf),autorouter:(0,s.sumOverDays)(e,s.autorouterOf),gatewayAttributedCaching:(0,s.sumOverDays)(e,s.gatewayAttributedCachingOf),savedTokens:(0,s.sumOverDays)(e,s.savedTokensOf),total:s.SAVINGS_DRIVERS.reduce((t,{of:r})=>t+(0,s.sumOverDays)(e,r),0)}),[e]);return(0,t.jsxs)("div",{className:"grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4",children:[(0,t.jsx)(a.default,{label:"Total saved",value:(0,s.usd)(o.total),hint:l?"Loading...":"Compression + prompt caching + auto-router",info:"The sum of the three tiles beside it. Its caching term is the LiteLLM-injected share, so this total is what the gateway itself delivered; caching that clients or providers brought on their own appears only in the caching tile's Total figure."}),(0,t.jsx)(a.default,{label:"Compression savings",value:(0,s.usd)(o.compression),hint:`${(0,i.formatNumberWithCommas)(o.savedTokens)} tokens compressed`,info:"Tokens Headroom removed before the call, priced at the model's input rate."}),(0,t.jsx)(a.default,{label:"Prompt caching savings",value:(0,s.usd)(o.gatewayAttributedCaching),hint:"LiteLLM injected",secondary:{label:"Total",value:(0,s.usd)(o.caching)},info:"What caching saved against paying the input rate for every token: the discount on tokens served from cache, less the premium providers charge to write a cache entry. The headline figure is the share LiteLLM earned by inserting the breakpoints itself, through configured injection points or auto prompt caching. The total beside it also counts requests that arrived with their own cache_control and providers that cache implicitly. Either can be negative on traffic that writes more cache than it reuses, which is why the headline is not always the smaller of the two."}),(0,t.jsx)(a.default,{label:"Auto-router savings",value:(0,s.usd)(o.autorouter),hint:"vs. the priciest model it could pick",info:"What this traffic would have cost had every request gone to the most expensive model the auto-router can route to, minus what it actually cost. Switching leaves the new model with a cold cache, so it pays to write the prompt again while the baseline is priced as already warm; a route that thrashes the cache can total below zero, and a genuine first turn, where neither side had anything cached, is undercounted."})]})}])},567425,e=>{"use strict";var t=e.i(271645);let r=["total_spend","total_prompt_tokens","total_completion_tokens","total_tokens","total_api_requests","total_successful_requests","total_failed_requests","total_cache_read_input_tokens","total_cache_creation_input_tokens","total_flat_cost"],a={results:[],metadata:{total_spend:0,total_prompt_tokens:0,total_completion_tokens:0,total_tokens:0,total_api_requests:0,total_successful_requests:0,total_failed_requests:0,total_cache_read_input_tokens:0,total_cache_creation_input_tokens:0,total_pages:1,has_more:!1,page:1}},s=(e,t)=>Object.fromEntries(Array.from(new Set([...Object.keys(e),...Object.keys(t)])).map(r=>{let a=e[r],s=t[r];return"number"!=typeof a&&"number"!=typeof s?[r,a??s]:[r,("number"==typeof a?a:0)+("number"==typeof s?s:0)]})),i=(e,t,r)=>{let a=e??{},s=t??{};return Object.fromEntries(Array.from(new Set([...Object.keys(a),...Object.keys(s)])).map(e=>{let t=a[e],i=s[e];return void 0===t?[e,i]:void 0===i?[e,t]:[e,r(t,i)]}))},l=(e,t)=>({...e,metrics:s(e.metrics,t.metrics)}),o=(e,t)=>({...e,metrics:s(e.metrics,t.metrics),api_key_breakdown:i(e.api_key_breakdown,t.api_key_breakdown,l)});function n(e,t){return t.reduce((e,t)=>{let r=e.findIndex(e=>e.date===t.date);return -1===r?[...e,t]:e.map((e,a)=>{let n,c;return a===r?{...e,metrics:s(e.metrics,t.metrics),breakdown:(n=e.breakdown,c=t.breakdown,{models:i(n.models,c.models,o),model_groups:i(n.model_groups,c.model_groups,o),mcp_servers:i(n.mcp_servers,c.mcp_servers,o),providers:i(n.providers,c.providers,o),api_keys:i(n.api_keys,c.api_keys,l),entities:i(n.entities,c.entities,o),...n.endpoints||c.endpoints?{endpoints:i(n.endpoints,c.endpoints,o)}:{}})}:e})},[...e])}e.s(["usePaginatedDailyActivity",0,function({fetchFn:e,args:s,enabled:i,aggregatedFetchFn:l}){let[o,c]=(0,t.useState)(a),[d,u]=(0,t.useState)(!1),[m,h]=(0,t.useState)(!1),[A,g]=(0,t.useState)({currentPage:0,totalPages:0}),[p,f]=(0,t.useState)(!1),x=(0,t.useRef)(0),b=(0,t.useRef)(!1),v=(0,t.useRef)(null),_=(0,t.useRef)(s);_.current=s;let w=JSON.stringify(s),y=(0,t.useCallback)(()=>{b.current=!0,f(!0),h(!1),null!==v.current&&(clearTimeout(v.current),v.current=null)},[]);return(0,t.useEffect)(()=>{if(!i){c(a),u(!1),h(!1),g({currentPage:0,totalPages:0}),f(!1);return}let t=++x.current;b.current=!1,f(!1);let s=()=>x.current!==t||b.current,o=e=>new Promise(t=>{v.current=setTimeout(()=>{v.current=null,t()},e)});return(async()=>{let t=_.current;if(u(!0),h(!1),g({currentPage:1,totalPages:1}),l)try{let e=await l(...t);if(s())return;c(e),g({currentPage:1,totalPages:1}),u(!1);return}catch(e){if(s())return;console.error("Aggregated daily activity failed, falling back to pagination:",e)}try{let a=[...t.slice(0,3),1,...t.slice(3)],i=await e(...a);if(s())return;c(i);let l=i.metadata?.total_pages||1;if(g({currentPage:1,totalPages:l}),l<=1)return void u(!1);u(!1),h(!0);let d=n([],i.results),m={...i.metadata};for(let a=2;a<=l;a++){if(s()||(await o(300),s()))return;let i=[...t.slice(0,3),a,...t.slice(3)],u=await e(...i);if(s())return;d=n(d,u.results),(m=function(e,t){let a={...e};for(let s of r)a[s]=(e[s]||0)+(t[s]||0);return a}(m,u.metadata)).total_pages=l,m.has_more=a{x.current++,null!==v.current&&(clearTimeout(v.current),v.current=null)}},[i,e,l,w]),{data:o,loading:d,isFetchingMore:m,progress:A,cancelled:p,cancel:y}}])},555376,e=>{"use strict";var t=e.i(271645),r=e.i(602869),a=e.i(708347),s=e.i(567425);let i=(e,a)=>{let i=(0,t.useMemo)(()=>new Date(new Date().getTime()-2592e6),[]),l=(0,t.useMemo)(()=>new Date,[]),[o,n]=(0,t.useState)({from:i,to:l}),c=o.from??null,d=o.to??null,{userId:u,apiKey:m=null}=a,h={fetchFn:r.userDailyActivityCall,aggregatedFetchFn:r.userDailyActivityAggregatedCall,args:[e,c,d,u,!0,m],enabled:!!e&&!!c&&!!d},{data:A,loading:g,isFetchingMore:p,progress:f,cancelled:x,cancel:b}=(0,s.usePaginatedDailyActivity)(h);return{dateValue:o,onDateChange:n,results:A.results,loading:g,isFetchingMore:p,progress:f,cancelled:x,cancel:b}};e.s(["useDailyActivityRange",0,(e,t,r)=>i(e,{userId:(0,a.spendScopeUserId)(r,t)}),"useScopedDailyActivityRange",0,i])},180127,e=>{"use strict";let t=(0,e.i(475254).default)("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);e.s(["default",0,t])},871689,e=>{"use strict";var t=e.i(180127);e.s(["ArrowLeft",()=>t.default])},845150,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(131792);let s=(e,t)=>{let r=t.trim().toLowerCase();return!r||e.label.toLowerCase().includes(r)||e.value.toLowerCase().includes(r)||(e.description?.toLowerCase().includes(r)??!1)};e.s(["MultiSelect",0,function({id:e,options:i,value:l=[],onValueChange:o,placeholder:n="Select options",emptyText:c="No options found",disabled:d=!1,loading:u=!1,allowCustomValues:m=!1,className:h}){let A=(0,a.useComboboxAnchor)(),[g,p]=(0,r.useState)(""),f=i.filter(e=>null!=e&&"string"==typeof e.value&&e.value.length>0),x=l.filter(e=>"string"==typeof e&&e.length>0).map(e=>f.find(t=>t.value===e)??{label:e,value:e}),b=g.trim(),v=f.some(e=>e.value.toLowerCase()===b.toLowerCase()),_=m&&b&&!v?[...f,{label:`Create "${b}"`,value:b}]:f;return(0,t.jsxs)(a.Combobox,{multiple:!0,items:_,value:x,onValueChange:e=>{o(Array.from(new Set(m?e.flatMap(e=>l.includes(e.value)?[e.value]:e.value.split(",").map(e=>e.trim()).filter(e=>e.length>0)):e.map(e=>e.value)))),p("")},inputValue:g,onInputValueChange:p,isItemEqualToValue:(e,t)=>e.value===t.value,itemToStringLabel:e=>e.label,filter:s,disabled:d||u,children:[(0,t.jsx)(a.ComboboxChips,{render:(0,t.jsx)("div",{ref:A}),className:`min-h-8 py-1 text-sm ${h??""}`,children:(0,t.jsx)(a.ComboboxValue,{children:r=>(0,t.jsxs)(t.Fragment,{children:[r.map(e=>(0,t.jsx)(a.ComboboxChip,{"aria-label":e.label,children:e.label},e.value)),(0,t.jsx)(a.ComboboxChipsInput,{id:e,placeholder:u?"Loading...":n,className:"min-w-24","aria-label":n||void 0}),r.length>0&&!d&&!u&&(0,t.jsx)(a.ComboboxClear,{className:"ml-auto self-center","aria-label":"Clear all"})]})})}),(0,t.jsxs)(a.ComboboxContent,{anchor:A,children:[(0,t.jsx)(a.ComboboxEmpty,{children:c}),(0,t.jsx)(a.ComboboxList,{children:e=>(0,t.jsx)(a.ComboboxItem,{value:e,disabled:e.disabled,children:(0,t.jsxs)("span",{className:"min-w-0",children:[(0,t.jsx)("span",{className:"block truncate",children:e.label}),e.description&&(0,t.jsx)("span",{className:"block truncate text-xs text-muted-foreground",children:e.description})]})},e.value)})]})]})}])},871943,502547,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"}))});e.s(["ChevronDownIcon",0,r],871943);let a=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9 5l7 7-7 7"}))});e.s(["ChevronRightIcon",0,a],502547)},278587,e=>{"use strict";var t=e.i(271645);let r=t.forwardRef(function(e,r){return t.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:r},e),t.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"}))});e.s(["RefreshIcon",0,r],278587)},384767,e=>{"use strict";var t=e.i(843476),r=e.i(271645);let a=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"}))});var s=e.i(487486),i=e.i(602869);let l=function({vectorStores:e,accessToken:l}){let[o,n]=(0,r.useState)([]);return(0,r.useEffect)(()=>{(async()=>{if(l&&0!==e.length)try{let e=await (0,i.vectorStoreListCall)(l);e.data&&n(e.data.map(e=>({vector_store_id:e.vector_store_id,vector_store_name:e.vector_store_name})))}catch(e){console.error("Error fetching vector stores:",e)}})()},[l,e.length]),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(a,{className:"h-4 w-4 text-info"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"Vector Stores"}),(0,t.jsx)(s.Badge,{variant:"secondary",children:e.length})]}),e.length>0?(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:e.map((e,r)=>{let a;return(0,t.jsx)("div",{className:"inline-flex min-w-0 items-center px-3 py-1.5 rounded-lg bg-info/10 border border-info/20 text-info text-sm font-medium break-words",children:(a=o.find(t=>t.vector_store_id===e))?`${a.vector_store_name||a.vector_store_id} (${a.vector_store_id})`:e},r)})}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(a,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-muted-foreground text-sm",children:"No vector stores configured"})]})]})};var o=e.i(953960);let n=r.forwardRef(function(e,t){return r.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),r.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"}))});var c=e.i(746798);let d=function({agents:e,agentAccessGroups:a=[],accessToken:l}){let[o,d]=(0,r.useState)([]);(0,r.useEffect)(()=>{(async()=>{if(l&&e.length>0)try{let e=await (0,i.getAgentsList)(l);e&&e.agents&&Array.isArray(e.agents)&&d(e.agents)}catch(e){console.error("Error fetching agents:",e)}})()},[l,e.length]);let u=[...e.map(e=>({type:"agent",value:e})),...a.map(e=>({type:"accessGroup",value:e}))],m=u.length;return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-purple-600"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"Agents"}),(0,t.jsx)(s.Badge,{variant:"secondary",children:m})]}),m>0?(0,t.jsx)("div",{className:"max-h-[400px] overflow-y-auto space-y-2 pr-1",children:u.map((e,r)=>(0,t.jsx)("div",{className:"space-y-2",children:(0,t.jsx)("div",{className:"flex items-center gap-3 py-2 px-3 rounded-lg border border-border bg-card",children:(0,t.jsx)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:"agent"===e.type?(0,t.jsx)(c.TooltipProvider,{delay:300,children:(0,t.jsxs)(c.Tooltip,{children:[(0,t.jsxs)(c.TooltipTrigger,{render:(0,t.jsx)("div",{className:"inline-flex items-center gap-2 min-w-0"}),children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-purple-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:(e=>{let t=o.find(t=>t.agent_id===e);if(t){let r=e.length>7?`${e.slice(0,3)}...${e.slice(-4)}`:e;return`${t.agent_name} (${r})`}return e})(e.value)})]}),(0,t.jsx)(c.TooltipContent,{children:`Full ID: ${e.value}`})]})}):(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-success rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:e.value}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-success bg-success/10 border border-success/20 rounded-sm uppercase tracking-wide shrink-0",children:"Group"})]})})})},r))}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-muted-foreground text-sm",children:"No agents or access groups configured"})]})]})};e.s(["default",0,function({objectPermission:e,variant:r="card",className:a="",accessToken:s}){let i=e?.vector_stores||[],n=e?.mcp_servers||[],c=e?.mcp_access_groups||[],u=e?.mcp_tool_permissions||{},m=e?.mcp_toolsets||[],h=e?.agents||[],A=e?.agent_access_groups||[],g=e?.search_tools||[],p=(0,t.jsxs)("div",{className:"card"===r?"grid grid-cols-1 @xl:grid-cols-2 @4xl:grid-cols-3 gap-6":"space-y-4",children:[(0,t.jsx)(l,{vectorStores:i,accessToken:s}),(0,t.jsx)(o.default,{mcpServers:n,mcpAccessGroups:c,mcpToolPermissions:u,mcpToolsets:m,accessToken:s}),(0,t.jsx)(d,{agents:h,agentAccessGroups:A,accessToken:s}),(0,t.jsxs)("div",{className:"min-w-0 rounded-md border border-border p-4",children:[(0,t.jsx)("p",{className:"text-sm font-medium text-foreground",children:"Search tools"}),0===g.length?(0,t.jsx)("p",{className:"mt-1 block text-xs text-muted-foreground",children:"No restriction — all configured search tools are allowed for this team."}):(0,t.jsx)("p",{className:"mt-1 block text-xs break-words text-foreground",children:g.join(", ")})]})]});return"card"===r?(0,t.jsxs)("div",{className:`@container bg-card border border-border rounded-lg p-6 ${a}`,children:[(0,t.jsx)("div",{className:"flex items-center gap-2 mb-6",children:(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"font-semibold text-foreground",children:"Object Permissions"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Access control for Vector Stores and MCP Servers"})]})}),p]}):(0,t.jsxs)("div",{className:`${a}`,children:[(0,t.jsx)("p",{className:"font-medium text-foreground mb-3",children:"Object Permissions"}),p]})}],384767)},422444,e=>{"use strict";var t=e.i(571353);let r=new Set(["all-proxy-models","all-team-models","no-default-models"]);e.s(["keyDetailHref",0,function(e){return`${(0,t.migratedHref)("api-keys")}?key=${encodeURIComponent(e)}`},"modelGroupHref",0,function(e){if(!r.has(e))return`${(0,t.migratedHref)("models-and-endpoints")}?model_group=${encodeURIComponent(e)}`},"orgDetailHref",0,function(e){return`${(0,t.migratedHref)("organizations")}?org=${encodeURIComponent(e)}`},"teamDetailHref",0,function(e){return`${(0,t.migratedHref)("teams")}?team=${encodeURIComponent(e)}`},"userDetailHref",0,function(e){return`${(0,t.migratedHref)("users")}?user=${encodeURIComponent(e)}`}])},556908,953960,e=>{"use strict";var t=e.i(843476),r=e.i(67488),a=e.i(487486),s=e.i(196631);let i="px-2.5 py-1 text-sm";function l({href:e,variant:o,className:n,children:c}){let d=(0,r.useEntityLinkClick)(e);return(0,t.jsx)(a.Badge,{variant:o,className:(0,s.cn)("cursor-pointer",i,n),render:(0,t.jsx)("a",{href:e,onClick:d}),children:c})}e.s(["BadgeLink",0,function({href:e,variant:r="secondary",className:o,children:n}){return e?(0,t.jsx)(l,{href:e,variant:r,className:o,children:n}):(0,t.jsx)(a.Badge,{variant:r,className:(0,s.cn)(i,o),children:n})}],556908);var o=e.i(271645);let n=o.forwardRef(function(e,t){return o.createElement("svg",Object.assign({xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor","aria-hidden":"true",ref:t},e),o.createElement("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"}))});var c=e.i(871943),d=e.i(502547),u=e.i(746798),m=e.i(602869),h=e.i(234713);e.s(["default",0,function({mcpServers:e,mcpAccessGroups:r=[],mcpToolPermissions:s={},mcpToolsets:i=[],accessToken:l}){let[A,g]=(0,o.useState)([]),[p,f]=(0,o.useState)([]),[x,b]=(0,o.useState)(new Set),[v,_]=(0,o.useState)(new Set);(0,o.useEffect)(()=>{(async()=>{if(l&&e.length>0)try{let e=await (0,m.fetchMCPServers)(l);e&&Array.isArray(e)?g(e):e.data&&Array.isArray(e.data)&&g(e.data)}catch(e){console.error("Error fetching MCP servers:",e)}})()},[l,e.length]),(0,o.useEffect)(()=>{(async()=>{if(l&&i.length>0)try{let e=await (0,m.fetchMCPToolsets)(l),t=Array.isArray(e)?e.filter(e=>i.includes(e.toolset_id)):[];f(t)}catch(e){console.error("Error fetching toolsets:",e)}})()},[l,i.length]);let w=e.includes(h.NO_MCP_SERVERS_SENTINEL),y=e.includes(h.ALL_PROXY_MCP_SERVERS_SENTINEL),C=[...e.filter(e=>e!==h.NO_MCP_SERVERS_SENTINEL&&e!==h.ALL_PROXY_MCP_SERVERS_SENTINEL).map(e=>({type:"server",value:e})),...r.map(e=>({type:"accessGroup",value:e}))],k=C.length+i.length;return(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-info"}),(0,t.jsx)("p",{className:"text-sm font-semibold text-foreground",children:"MCP Servers"}),(0,t.jsx)(a.Badge,{variant:w?"destructive":"secondary",children:w?"Blocked":y?"All":k})]}),w?(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-destructive/10 border border-destructive/20",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-destructive"}),(0,t.jsx)("p",{className:"text-destructive text-sm",children:"No MCP servers — this key is blocked from all MCP servers, including its team's servers"})]}):y?(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-info/10 border border-info/20",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-info"}),(0,t.jsx)("p",{className:"text-info text-sm",children:"All Proxy MCP Servers"})]}):k>0?(0,t.jsxs)("div",{className:"max-h-[400px] overflow-y-auto space-y-2 pr-1",children:[C.map((e,r)=>{let a="server"===e.type?s[e.value]:void 0,i=a&&a.length>0,l=x.has(e.value);return(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{onClick:()=>{var t;return i&&(t=e.value,void b(e=>{let r=new Set(e);return r.has(t)?r.delete(t):r.add(t),r}))},className:`flex items-center gap-3 py-2 px-3 rounded-lg border border-border transition-all ${i?"cursor-pointer hover:bg-accent":"bg-card"}`,children:[(0,t.jsx)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:"server"===e.type?(0,t.jsxs)(u.Tooltip,{children:[(0,t.jsxs)(u.TooltipTrigger,{render:(0,t.jsx)("div",{className:"inline-flex items-center gap-2 min-w-0"}),children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-info rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:(e=>{let t=A.find(t=>t.server_id===e);if(t){let r=e.length>7?`${e.slice(0,3)}...${e.slice(-4)}`:e;return`${t.alias||t.server_name||e} (${r})`}return e})(e.value)})]}),(0,t.jsx)(u.TooltipContent,{children:`Full ID: ${e.value}`})]}):(0,t.jsxs)("div",{className:"inline-flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-success rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:e.value}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-success bg-success/10 border border-success/20 rounded-sm uppercase tracking-wide shrink-0",children:"Group"})]})}),i&&(0,t.jsxs)("div",{className:"flex items-center gap-1 shrink-0 whitespace-nowrap",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-muted-foreground",children:a.length}),(0,t.jsx)("span",{className:"text-xs text-muted-foreground",children:1===a.length?"tool":"tools"}),l?(0,t.jsx)(c.ChevronDownIcon,{className:"h-3.5 w-3.5 text-muted-foreground ml-0.5"}):(0,t.jsx)(d.ChevronRightIcon,{className:"h-3.5 w-3.5 text-muted-foreground ml-0.5"})]})]}),i&&l&&(0,t.jsx)("div",{className:"ml-4 pl-4 border-l-2 border-info/20 pb-1",children:(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:a.map((e,r)=>(0,t.jsx)("span",{className:"inline-flex items-center px-2.5 py-1 rounded-lg bg-info/10 border border-info/20 text-info text-xs font-medium",children:e},r))})})]},r)}),i.length>0&&i.map((e,r)=>{let a=p.find(t=>t.toolset_id===e),s=v.has(e),i=a?.tools.length??0;return(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{onClick:()=>i>0&&void _(t=>{let r=new Set(t);return r.has(e)?r.delete(e):r.add(e),r}),className:`flex items-center gap-3 py-2 px-3 rounded-lg border border-purple-200 transition-all ${i>0?"cursor-pointer hover:bg-purple-50 hover:border-purple-300 dark:hover:bg-purple-950 dark:hover:border-purple-700":"bg-card"}`,children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 flex-1 min-w-0",children:[(0,t.jsx)("span",{className:"inline-block w-1.5 h-1.5 bg-purple-500 rounded-full shrink-0"}),(0,t.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:a?.toolset_name??e}),(0,t.jsx)("span",{className:"ml-1 px-1.5 py-0.5 text-[9px] font-semibold text-purple-600 bg-purple-50 border border-purple-200 rounded-sm uppercase tracking-wide shrink-0 dark:text-purple-300 dark:bg-purple-950 dark:border-purple-800",children:"Toolset"})]}),i>0&&(0,t.jsxs)("div",{className:"flex items-center gap-1 shrink-0 whitespace-nowrap",children:[(0,t.jsx)("span",{className:"text-xs font-medium text-muted-foreground",children:i}),(0,t.jsx)("span",{className:"text-xs text-muted-foreground",children:1===i?"tool":"tools"}),s?(0,t.jsx)(c.ChevronDownIcon,{className:"h-3.5 w-3.5 text-muted-foreground ml-0.5"}):(0,t.jsx)(d.ChevronRightIcon,{className:"h-3.5 w-3.5 text-muted-foreground ml-0.5"})]})]}),i>0&&s&&a&&(0,t.jsx)("div",{className:"ml-4 pl-4 border-l-2 border-purple-200 pb-1",children:(0,t.jsx)("div",{className:"flex flex-wrap gap-1.5",children:a.tools.map((e,r)=>(0,t.jsxs)("span",{className:"inline-flex items-center px-2.5 py-1 rounded-lg bg-purple-50 border border-purple-200 text-purple-800 text-xs font-medium dark:bg-purple-950 dark:border-purple-800 dark:text-purple-300",children:[(0,t.jsxs)("span",{className:"text-purple-400 mr-1 text-[10px]",children:[e.server_id.slice(0,6),"…"]}),e.tool_name]},r))})})]},`toolset-${r}`)})]}):(0,t.jsxs)("div",{className:"flex items-center gap-2 px-3 py-2 rounded-lg bg-muted border border-border",children:[(0,t.jsx)(n,{className:"h-4 w-4 text-muted-foreground"}),(0,t.jsx)("p",{className:"text-muted-foreground text-sm",children:"No MCP servers, access groups, or toolsets configured"})]})]})}],953960)},247482,e=>{"use strict";var t=e.i(234713);let r=e=>Array.isArray(e)?e.filter(e=>"string"==typeof e):[],a=(e,t)=>e.server_id===t||e.server_name===t||e.alias===t;e.s(["extractMcpEntitlement",0,(e,s,i=[])=>{var l;let o=e.mcp_servers_and_groups;if(null===o||"object"!=typeof o)return null;let{servers:n,accessGroups:c,toolsets:d}=o,u=r(n),m=r(c),h=r(d),A=u.includes(t.ALL_PROXY_MCP_SERVERS_SENTINEL)||h.some(e=>!i.some(t=>t.toolset_id===e)),g=new Set(i.filter(e=>h.includes(e.toolset_id)).flatMap(e=>e.tools.map(e=>e.server_id))),p=e=>u.some(t=>a(e,t))||(e.mcp_access_groups??[]).some(e=>m.includes(e))||g.has(e.server_id);return{mcp_servers:u,mcp_access_groups:m,mcp_toolsets:h,mcp_tool_permissions:Object.fromEntries(Object.entries(null===(l=e.mcp_tool_permissions)||"object"!=typeof l||Array.isArray(l)?{}:Object.fromEntries(Object.entries(l).map(([e,t])=>[e,r(t)]))).filter(([e])=>{let t;return A||0===(t=s.filter(t=>a(t,e))).length||t.some(p)}))}}])},904031,953563,e=>{"use strict";let t=e=>JSON.stringify(Object.entries(e??{}).map(([e,t])=>[e,Number(t?.budget_limit??t?.max_budget??NaN),t?.time_period??t?.budget_duration??null]).sort((e,t)=>String(e[0]).localeCompare(String(t[0]))));e.s(["modelMaxBudgetUpdate",0,(e,r)=>t(e)===t(r)?void 0:e],904031);var r=e.i(271645);e.s(["useSeededState",0,function(e,t){let[a,s]=(0,r.useState)(t),[i,l]=(0,r.useState)(e);return i!==e&&(l(e),s(t())),[a,s]}],953563)},24529,e=>{"use strict";let t=Symbol.for("constructDateFrom");function r(e,r){return"function"==typeof e?e(r):e&&"object"==typeof e&&t in e?e[t](r):e instanceof Date?new e.constructor(r):new Date(r)}function a(e,t,a){var s;let i,{years:l=0,months:o=0,weeks:n=0,days:c=0,hours:d=0,minutes:u=0,seconds:m=0}=t,h=r(a?.in||e,e),A=o||l?function(e,t){let a=r(e,e);if(isNaN(t))return r(e,NaN);if(!t)return a;let s=a.getDate(),i=r(e,a.getTime());return(i.setMonth(a.getMonth()+t+1,0),s>=i.getDate())?i:(a.setFullYear(i.getFullYear(),i.getMonth(),s),a)}(h,o+12*l):h,g=c||n?(s=c+7*n,i=r(A,A),isNaN(s)?r(A,NaN):(s&&i.setDate(i.getDate()+s),i)):A;return r(a?.in||e,+g+1e3*(m+60*(u+60*d)))}let s=/[zZ]$|[+-]\d{2}:?\d{2}$/;function i(e){return Date.parse(s.test(e)?e:`${e}Z`)}e.s(["calculateExpiryPreviewFromDuration",0,function(e){if(!e)return null;try{let t,r=parseInt(e);if(Number.isNaN(r))throw Error("Invalid duration format");let s=new Date;if(e.endsWith("mo"))t=a(s,{months:r});else if(e.endsWith("s"))t=a(s,{seconds:r});else if(e.endsWith("m"))t=a(s,{minutes:r});else if(e.endsWith("h"))t=a(s,{hours:r});else if(e.endsWith("d"))t=a(s,{days:r});else if(e.endsWith("w"))t=a(s,{weeks:r});else throw Error("Invalid duration format");return t.toLocaleString()}catch{return null}},"formatExpiresUtc",0,function(e){let t=i(e);return Number.isNaN(t)?e:new Date(t).toLocaleString()},"isKeyExpired",0,function(e){if(!e)return!1;let t=i(e);return!Number.isNaN(t)&&t{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(602869),s=e.i(845150);e.s(["default",0,({onChange:e,value:i,className:l,accessToken:o,disabled:n})=>{let[c,d]=(0,r.useState)([]),[u,m]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{(async()=>{if(o){m(!0);try{let e=await (0,a.getGuardrailsList)(o);e.guardrails&&d(e.guardrails)}catch(e){console.error("Error fetching guardrails:",e)}finally{m(!1)}}})()},[o]),(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(s.MultiSelect,{disabled:n,placeholder:n?"Setting guardrails is a premium feature.":"Select guardrails",onValueChange:t=>{e(t)},value:i,loading:u,className:l,options:c.flatMap(e=>{let t=e.guardrail_name;return null==t||""===t?[]:[{label:t,value:t}]})})})}])},921511,e=>{"use strict";var t=e.i(843476),r=e.i(271645),a=e.i(864261),s=e.i(602869),i=e.i(845150);function l(e){return e.filter(e=>(e.version_status??"draft")!=="draft").map(e=>{var t;let r=e.version_number??1,a=e.version_status??"draft";return{label:`${e.policy_name} — v${r} (${a})${e.description?` — ${e.description}`:""}`,value:"production"===a?e.policy_name:e.policy_id?(t=e.policy_id,`policy_${t}`):e.policy_name}})}e.s(["default",0,({onChange:e,value:o,className:n,accessToken:c,disabled:d,onPoliciesLoaded:u})=>{let m=(0,a.default)("viewPolicies"),[h,A]=(0,r.useState)([]),[g,p]=(0,r.useState)(!1);return((0,r.useEffect)(()=>{(async()=>{if(c&&m){p(!0);try{let e=await (0,s.getPoliciesList)(c);e.policies&&(A(e.policies),u?.(e.policies))}catch(e){console.error("Error fetching policies:",e)}finally{p(!1)}}})()},[c,m,u]),m)?(0,t.jsx)("div",{className:"min-w-0",children:(0,t.jsx)(i.MultiSelect,{disabled:d,placeholder:d?"Setting policies is a premium feature.":"Select policies (production or published versions)",onValueChange:t=>{e(t)},value:o,loading:g,className:n,options:l(h)})}):null},"getPolicyOptionEntries",0,l])},223622,e=>{"use strict";let t=(0,e.i(475254).default)("ban",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m4.9 4.9 14.2 14.2",key:"1m5liu"}]]);e.s(["Ban",0,t],223622)},323585,e=>{"use strict";let t=(0,e.i(475254).default)("ellipsis-vertical",[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"12",cy:"5",r:"1",key:"gxeob9"}],["circle",{cx:"12",cy:"19",r:"1",key:"lyex9k"}]]);e.s(["MoreVertical",0,t],323585)}]);
\ No newline at end of file
diff --git a/litellm/proxy/_experimental/out/_next/static/chunks/0dnt68i2qq-dg.js b/litellm/proxy/_experimental/out/_next/static/chunks/0dnt68i2qq-dg.js
deleted file mode 100644
index b4cc803b17a..00000000000
--- a/litellm/proxy/_experimental/out/_next/static/chunks/0dnt68i2qq-dg.js
+++ /dev/null
@@ -1 +0,0 @@
-(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,463059,e=>{"use strict";var t=e.i(246349);e.s(["ChevronRight",()=>t.default])},302747,e=>{"use strict";var t=e.i(843476),i=e.i(196631);e.s(["Skeleton",0,function({className:e,...a}){return(0,t.jsx)("div",{"data-slot":"skeleton",className:(0,i.cn)("animate-pulse rounded-md bg-muted",e),...a})}])},559657,201634,481524,841840,e=>{"use strict";e.s([],559657),e.i(247167);var t,i=e.i(271645),a=e.i(951437),r=e.i(146376),l=e.i(667865),s=e.i(552245),n=e.i(53687),o=e.i(733332);let A=i.createContext(void 0);e.s(["TabsRootContext",0,A,"useTabsRootContext",0,function(){let e=i.useContext(A);if(void 0===e)throw Error((0,o.default)(64));return e}],201634);let u=((t={}).activationDirection="data-activation-direction",t.orientation="data-orientation",t),c={tabActivationDirection:e=>({[u.activationDirection]:e})};e.s(["tabsStateAttributesMapping",0,c],481524);var d=e.i(675606),h=e.i(56434),g=e.i(843476);let f=i.forwardRef(function(e,t){let{className:o,defaultValue:u=0,onValueChange:f,orientation:b="horizontal",render:m,value:v,style:I,...x}=e,E=void 0!==e.defaultValue,C=i.useRef([]),[R,O]=i.useState(()=>new Map),[_,w]=(0,a.useControlled)({controlled:v,default:u,name:"Tabs",state:"value"}),T=void 0!==v,[L,S]=i.useState(()=>new Map),k=i.useRef(void 0),M=i.useCallback(e=>{if(void 0===e)return null;for(let[t,i]of L.entries())if(null!=i&&e===(i.value??i.index))return t;return null},[L]),[D,B]=i.useState(()=>({previousValue:_,tabActivationDirection:"none"})),{previousValue:y,tabActivationDirection:H}=D,U=H,N=!1;y!==_&&(U=p(y,_,b,L),N=null!=y&&null!=_&&null==M(_));let W=N?y:_,P=y!==W||H!==U;(0,r.useIsoLayoutEffect)(()=>{P&&B({previousValue:W,tabActivationDirection:U})},[W,P,U]);let q=(0,l.useStableCallback)((e,t)=>{t.activationDirection=p(_,e,b,L),f?.(e,t),t.isCanceled||w(e)}),z=(0,l.useStableCallback)((e,t)=>{f?.(e,(0,d.createChangeEventDetails)(t,void 0,void 0,{activationDirection:"none"}))}),V=(0,l.useStableCallback)((e,t)=>{O(i=>{if(i.get(e)===t)return i;let a=new Map(i);return a.set(e,t),a})}),Q=(0,l.useStableCallback)((e,t)=>{O(i=>{if(!i.has(e)||i.get(e)!==t)return i;let a=new Map(i);return a.delete(e),a})}),F=i.useCallback(e=>R.get(e),[R]),G=i.useCallback(e=>{for(let t of L.values())if(e===t?.value)return t?.id},[L]),K=i.useMemo(()=>({getTabElementBySelectedValue:M,getTabIdByPanelValue:G,getTabPanelIdByValue:F,onValueChange:q,orientation:b,registerMountedTabPanel:V,setTabMap:S,unregisterMountedTabPanel:Q,tabActivationDirection:U,value:_}),[M,G,F,q,b,V,S,Q,U,_]),Y=i.useMemo(()=>{for(let e of L.values())if(null!=e&&e.value===_)return e},[L,_]),j=i.useMemo(()=>{for(let e of L.values())if(null!=e&&!e.disabled)return e.value},[L]),J=i.useRef(!E),X=i.useRef(u),Z=i.useRef(E),$=i.useRef(!1);(0,r.useIsoLayoutEffect)(()=>{if(T)return;function e(e,t){w(e),B(t=>t.previousValue===e&&"none"===t.tabActivationDirection?t:{previousValue:e,tabActivationDirection:"none"}),z(e,t),J.current=!1}if(0===L.size){$.current&&null!==_&&!k.current?.isConnected&&e(null,h.REASONS.missing);return}$.current=!0,k.current=L.keys().next().value;let t=Y?.disabled,i=null==Y&&null!==_;if(t||_!==X.current||(Z.current=!1),Z.current&&t&&_===X.current)return;let a=J.current;if(t||i){let i=j??null;if(_===i){J.current=!1;return}let r=h.REASONS.missing;a?r=h.REASONS.initial:t&&(r=h.REASONS.disabled),e(i,r);return}a&&null!=Y&&(z(_,h.REASONS.initial),J.current=!1)},[j,T,z,Y,w,L,_]);let ee={orientation:b,tabActivationDirection:U},et=(0,s.useRenderElement)("div",e,{state:ee,ref:t,props:x,stateAttributesMapping:c});return(0,g.jsx)(A.Provider,{value:K,children:(0,g.jsx)(n.CompositeList,{elementsRef:C,children:et})})});function p(e,t,i,a){if(null==e||null==t)return"none";let r=null,l=null;for(let[i,s]of a.entries()){if(null==s)continue;let a=s.value??s.index;if(e===a&&(r=i),t===a&&(l=i),null!=r&&null!=l)break}if(null==r||null==l)return r!==l&&("number"==typeof e||"string"==typeof e)&&typeof e==typeof t?"horizontal"===i?t>e?"right":"left":t>e?"down":"up":"none";let s=r.getBoundingClientRect(),n=l.getBoundingClientRect();if("horizontal"===i){if(n.left