mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-25 05:54:53 +00:00
Merge 108c22115e into 6762d65eb8
This commit is contained in:
commit
762dd7b766
3 changed files with 70 additions and 0 deletions
|
|
@ -46,4 +46,54 @@ describe("MyUserTab", () => {
|
|||
expect(screen.getByText("model-one")).toBeInTheDocument();
|
||||
expect(screen.getByText("TPM: 1,000")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe("temporary budget increase", () => {
|
||||
const renderWithTempBudget = (temp: {
|
||||
temp_budget_increase?: number | null;
|
||||
temp_budget_expiry?: string | null;
|
||||
}) => {
|
||||
vi.mocked(useMyTeamMember).mockReturnValue({
|
||||
data: {
|
||||
user_id: "user-1",
|
||||
team_id: "team-1",
|
||||
role: "user",
|
||||
spend: 12.5,
|
||||
total_spend: 30,
|
||||
litellm_budget_table: { max_budget: 100, ...temp },
|
||||
},
|
||||
isLoading: false,
|
||||
error: null,
|
||||
} as ReturnType<typeof useMyTeamMember>);
|
||||
|
||||
renderWithProviders(<MyUserTab teamId="team-1" />);
|
||||
};
|
||||
|
||||
it("shows an active increase and its expiry date under the budget", () => {
|
||||
renderWithTempBudget({ temp_budget_increase: 150, temp_budget_expiry: "2099-11-01T12:00:00Z" });
|
||||
|
||||
expect(screen.getByTestId("my-temp-budget")).toHaveTextContent("+ $150.00 temporary increase until Nov 1, 2099");
|
||||
});
|
||||
|
||||
it("treats an expiry without a timezone as UTC, as the API returns it", () => {
|
||||
renderWithTempBudget({ temp_budget_increase: 150, temp_budget_expiry: "2099-11-01T12:00:00" });
|
||||
|
||||
expect(screen.getByTestId("my-temp-budget")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows nothing once the increase has expired", () => {
|
||||
renderWithTempBudget({ temp_budget_increase: 150, temp_budget_expiry: "2020-01-11T00:00:00Z" });
|
||||
|
||||
expect(screen.queryByTestId("my-temp-budget")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows nothing without an increase, with a 0 increase, or without an expiry", () => {
|
||||
renderWithTempBudget({ temp_budget_increase: 0, temp_budget_expiry: "2099-11-01T12:00:00Z" });
|
||||
expect(screen.queryByTestId("my-temp-budget")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows nothing when the expiry is missing", () => {
|
||||
renderWithTempBudget({ temp_budget_increase: 150, temp_budget_expiry: null });
|
||||
expect(screen.queryByTestId("my-temp-budget")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { formatBudgetReset } from "@/utils/budgetUtils";
|
||||
import { formatNumberWithCommas } from "@/utils/dataUtils";
|
||||
import { tempBudgetExpiryMs } from "@/components/shared/InheritedBudgetHint";
|
||||
import { SimpleTooltip } from "@/components/ui/tooltip";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Card, CardContent } from "@/components/ui/card";
|
||||
|
|
@ -30,6 +31,17 @@ const formatRateLimit = (value: number | null | undefined): string => {
|
|||
return formatNumberWithCommas(value, 0);
|
||||
};
|
||||
|
||||
// The member's temporary increase while it is still in effect, with its expiry formatted for display.
|
||||
const activeTempBudget = (
|
||||
budgetTable: Parameters<typeof tempBudgetExpiryMs>[0],
|
||||
now: Date = new Date(),
|
||||
): { amount: number; expiry: string | null } | null => {
|
||||
const amount = budgetTable?.temp_budget_increase ?? 0;
|
||||
const expiryMs = tempBudgetExpiryMs(budgetTable);
|
||||
if (amount <= 0 || expiryMs === null || expiryMs <= now.getTime()) return null;
|
||||
return { amount, expiry: formatBudgetReset(new Date(expiryMs).toISOString()) };
|
||||
};
|
||||
|
||||
export default function MyUserTab({ teamId }: MyUserTabProps) {
|
||||
const { data, isLoading, error } = useMyTeamMember(teamId);
|
||||
|
||||
|
|
@ -69,6 +81,7 @@ export default function MyUserTab({ teamId }: MyUserTabProps) {
|
|||
const rpmLimit = budgetTable?.rpm_limit ?? null;
|
||||
const budgetReset = formatBudgetReset(budgetTable?.budget_reset_at);
|
||||
const allowedModels = budgetTable?.allowed_models ?? null;
|
||||
const tempBudget = activeTempBudget(budgetTable);
|
||||
|
||||
return (
|
||||
<div className="flex w-full flex-col gap-4">
|
||||
|
|
@ -103,6 +116,11 @@ export default function MyUserTab({ teamId }: MyUserTabProps) {
|
|||
of {maxBudget === null ? "Unlimited" : `$${formatNumber(maxBudget, 4)}`}
|
||||
</span>
|
||||
</div>
|
||||
{tempBudget && (
|
||||
<div className="mt-1 text-muted-foreground" data-testid="my-temp-budget">
|
||||
+ ${formatNumber(tempBudget.amount, 2)} temporary increase until {tempBudget.expiry}
|
||||
</div>
|
||||
)}
|
||||
{budgetReset && <div className="mt-1 text-muted-foreground">Resets {budgetReset}</div>}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ export interface TeamMemberInfo {
|
|||
budget_duration?: string | null;
|
||||
budget_reset_at?: string | null;
|
||||
allowed_models?: string[] | null;
|
||||
temp_budget_increase?: number | null;
|
||||
temp_budget_expiry?: string | null;
|
||||
} | null;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue