@acarmisc/backstage-plugin-litellm 0.21.3 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/budget.d.ts +6 -0
- package/dist/index.cjs.js +70 -32
- package/dist/index.cjs.js.map +2 -2
- package/dist/index.esm.js +84 -46
- package/dist/index.esm.js.map +3 -3
- package/dist/types.d.ts +13 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -2001,6 +2001,8 @@ var init_ManageTeamDialog = __esm({
|
|
|
2001
2001
|
const [mcpError, setMcpError] = useState3(null);
|
|
2002
2002
|
const allowUnlimitedBudget = config?.teamManagement?.allowUnlimitedBudget ?? false;
|
|
2003
2003
|
const maxBudgetCeiling = config?.teamManagement?.maxBudgetCeiling ?? FALLBACK_BUDGET_CEILING;
|
|
2004
|
+
const hideBudgetForManagers = config?.display?.hideTeamBudgetForManagers ?? false;
|
|
2005
|
+
const budgetWriteOnly = hideBudgetForManagers && mode === "edit";
|
|
2004
2006
|
const members = useMemo4(() => team?.members_with_roles ?? [], [team]);
|
|
2005
2007
|
const showMembers = mode === "edit" && !!canManageMembers;
|
|
2006
2008
|
const catalogApi = useApi(catalogApiRef);
|
|
@@ -2036,9 +2038,13 @@ var init_ManageTeamDialog = __esm({
|
|
|
2036
2038
|
if (mode === "edit" && team) {
|
|
2037
2039
|
setAlias(team.team_alias ?? "");
|
|
2038
2040
|
setModels(team.models ?? []);
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2041
|
+
if (hideBudgetForManagers) {
|
|
2042
|
+
setMaxBudget("");
|
|
2043
|
+
} else {
|
|
2044
|
+
setMaxBudget(
|
|
2045
|
+
team.max_budget ? String(team.max_budget) : String(maxBudgetCeiling)
|
|
2046
|
+
);
|
|
2047
|
+
}
|
|
2042
2048
|
setUnlimited(allowUnlimitedBudget && !team.max_budget);
|
|
2043
2049
|
setBudgetDuration(team.budget_duration ?? DEFAULT_BUDGET_DURATION);
|
|
2044
2050
|
} else {
|
|
@@ -2058,7 +2064,7 @@ var init_ManageTeamDialog = __esm({
|
|
|
2058
2064
|
setMcpIds(team?.object_permission?.mcp_servers ?? []);
|
|
2059
2065
|
setMcpError(null);
|
|
2060
2066
|
}
|
|
2061
|
-
}, [open, mode, team, allowUnlimitedBudget, maxBudgetCeiling]);
|
|
2067
|
+
}, [open, mode, team, allowUnlimitedBudget, maxBudgetCeiling, hideBudgetForManagers]);
|
|
2062
2068
|
const handleSubmit = async () => {
|
|
2063
2069
|
setError(null);
|
|
2064
2070
|
if (!alias.trim()) {
|
|
@@ -2070,18 +2076,21 @@ var init_ManageTeamDialog = __esm({
|
|
|
2070
2076
|
return;
|
|
2071
2077
|
}
|
|
2072
2078
|
if (!unlimited) {
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2079
|
+
const budgetLeftBlank = budgetWriteOnly && !maxBudget.trim();
|
|
2080
|
+
if (!budgetLeftBlank) {
|
|
2081
|
+
if (!maxBudget) {
|
|
2082
|
+
setError("Budget is required when unlimited budgets are disabled");
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
const budget = parseFloat(maxBudget);
|
|
2086
|
+
if (isNaN(budget) || budget <= 0) {
|
|
2087
|
+
setError("Budget must be a positive number");
|
|
2088
|
+
return;
|
|
2089
|
+
}
|
|
2090
|
+
if (budget > maxBudgetCeiling) {
|
|
2091
|
+
setError(`Budget cannot exceed $${maxBudgetCeiling}`);
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2085
2094
|
}
|
|
2086
2095
|
}
|
|
2087
2096
|
try {
|
|
@@ -2095,10 +2104,16 @@ var init_ManageTeamDialog = __esm({
|
|
|
2095
2104
|
...budgetDuration && { budget_duration: budgetDuration }
|
|
2096
2105
|
};
|
|
2097
2106
|
} else {
|
|
2107
|
+
let budgetField = {};
|
|
2108
|
+
if (unlimited) {
|
|
2109
|
+
budgetField = { max_budget: null };
|
|
2110
|
+
} else if (maxBudget.trim()) {
|
|
2111
|
+
budgetField = { max_budget: parseFloat(maxBudget) };
|
|
2112
|
+
}
|
|
2098
2113
|
payload = {
|
|
2099
2114
|
team_alias: alias.trim(),
|
|
2100
2115
|
models,
|
|
2101
|
-
...
|
|
2116
|
+
...budgetField,
|
|
2102
2117
|
...budgetDuration && { budget_duration: budgetDuration }
|
|
2103
2118
|
};
|
|
2104
2119
|
}
|
|
@@ -2204,13 +2219,13 @@ var init_ManageTeamDialog = __esm({
|
|
|
2204
2219
|
), /* @__PURE__ */ React5.createElement(
|
|
2205
2220
|
TextField3,
|
|
2206
2221
|
{
|
|
2207
|
-
label: "Max Budget ($)",
|
|
2222
|
+
label: budgetWriteOnly ? "New Max Budget ($)" : "Max Budget ($)",
|
|
2208
2223
|
type: "number",
|
|
2209
2224
|
value: maxBudget,
|
|
2210
2225
|
onChange: (e) => setMaxBudget(e.target.value),
|
|
2211
2226
|
disabled: submitting || unlimited,
|
|
2212
2227
|
inputProps: { min: 0, max: maxBudgetCeiling },
|
|
2213
|
-
helperText: `Maximum: $${maxBudgetCeiling}`,
|
|
2228
|
+
helperText: budgetWriteOnly ? "Current budget is hidden \u2014 leave blank to keep it, or enter a new value" : `Maximum: $${maxBudgetCeiling}`,
|
|
2214
2229
|
fullWidth: true
|
|
2215
2230
|
}
|
|
2216
2231
|
), allowUnlimitedBudget && /* @__PURE__ */ React5.createElement(
|
|
@@ -2781,7 +2796,19 @@ function buildBudgetSummary(user, teams, keys, maxKeys = 3) {
|
|
|
2781
2796
|
pct: limitPct(spend, budget)
|
|
2782
2797
|
};
|
|
2783
2798
|
})() : void 0;
|
|
2784
|
-
const teamLimits = teams.filter((t) => (t.max_budget ?? 0) > 0).map((t) => {
|
|
2799
|
+
const teamLimits = teams.filter((t) => (t.max_budget ?? 0) > 0 || t.budget_hidden === true).map((t) => {
|
|
2800
|
+
if (t.budget_hidden === true) {
|
|
2801
|
+
return {
|
|
2802
|
+
kind: "team",
|
|
2803
|
+
label: t.team_alias || "Untitled team",
|
|
2804
|
+
sublabel: t.team_id,
|
|
2805
|
+
budget: 0,
|
|
2806
|
+
spend: 0,
|
|
2807
|
+
budgetDuration: t.budget_duration,
|
|
2808
|
+
pct: Math.min(100, Math.max(0, t.budget_pct ?? 0)),
|
|
2809
|
+
hidden: true
|
|
2810
|
+
};
|
|
2811
|
+
}
|
|
2785
2812
|
const spend = t.spend ?? 0;
|
|
2786
2813
|
return {
|
|
2787
2814
|
kind: "team",
|
|
@@ -2957,7 +2984,7 @@ var init_LiteLLMBudgetWidget = __esm({
|
|
|
2957
2984
|
}
|
|
2958
2985
|
},
|
|
2959
2986
|
limit.sublabel
|
|
2960
|
-
)), /* @__PURE__ */ React7.createElement(Typography7, { variant: "body2", sx: { fontWeight: 600, fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap" } }, fmtUsd(limit.spend), /* @__PURE__ */ React7.createElement(Box7, { component: "span", color: "text.secondary", sx: { fontWeight: 400 } }, " / ", fmtUsd(limit.budget)))), /* @__PURE__ */ React7.createElement(Box7, { sx: { mt: 1 } }, /* @__PURE__ */ React7.createElement(Meter, { value: limit.pct, tone, height: 6 })), /* @__PURE__ */ React7.createElement(
|
|
2987
|
+
)), limit.hidden ? /* @__PURE__ */ React7.createElement(Typography7, { variant: "body2", sx: { fontWeight: 600, fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap" } }, pct, "% used") : /* @__PURE__ */ React7.createElement(Typography7, { variant: "body2", sx: { fontWeight: 600, fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap" } }, fmtUsd(limit.spend), /* @__PURE__ */ React7.createElement(Box7, { component: "span", color: "text.secondary", sx: { fontWeight: 400 } }, " / ", fmtUsd(limit.budget)))), /* @__PURE__ */ React7.createElement(Box7, { sx: { mt: 1 } }, /* @__PURE__ */ React7.createElement(Meter, { value: limit.pct, tone, height: 6 })), /* @__PURE__ */ React7.createElement(
|
|
2961
2988
|
Box7,
|
|
2962
2989
|
{
|
|
2963
2990
|
sx: {
|
|
@@ -2968,7 +2995,7 @@ var init_LiteLLMBudgetWidget = __esm({
|
|
|
2968
2995
|
mt: 0.75
|
|
2969
2996
|
}
|
|
2970
2997
|
},
|
|
2971
|
-
/* @__PURE__ */ React7.createElement(Typography7, { variant: "caption", color: "text.secondary", sx: { fontVariantNumeric: "tabular-nums" } }, pct, "% of budget", closeTo && ` \xB7 soft-limit warning`),
|
|
2998
|
+
/* @__PURE__ */ React7.createElement(Typography7, { variant: "caption", color: "text.secondary", sx: { fontVariantNumeric: "tabular-nums" } }, limit.hidden ? /* @__PURE__ */ React7.createElement(React7.Fragment, null, "Hidden by admin") : /* @__PURE__ */ React7.createElement(React7.Fragment, null, pct, "% of budget", closeTo && ` \xB7 soft-limit warning`)),
|
|
2972
2999
|
/* @__PURE__ */ React7.createElement(Typography7, { variant: "caption", color: "text.secondary" }, fmtBudgetDuration(limit.budgetDuration) ? `resets ${fmtBudgetDuration(limit.budgetDuration)}` : "never resets")
|
|
2973
3000
|
));
|
|
2974
3001
|
};
|
|
@@ -3176,6 +3203,15 @@ function budgetTone3(isOver, isNear) {
|
|
|
3176
3203
|
if (isNear) return "warning";
|
|
3177
3204
|
return "accent";
|
|
3178
3205
|
}
|
|
3206
|
+
function visibleBudgetPct(spend, budget) {
|
|
3207
|
+
if (budget <= 0) return 0;
|
|
3208
|
+
return Math.min(spend / budget * 100, 100);
|
|
3209
|
+
}
|
|
3210
|
+
function budgetStatValue(hidden, budget) {
|
|
3211
|
+
if (hidden) return "Hidden";
|
|
3212
|
+
if (budget > 0) return fmtUsd2(budget);
|
|
3213
|
+
return "Unlimited";
|
|
3214
|
+
}
|
|
3179
3215
|
var fmtUsd2, TeamCard, TeamUsage;
|
|
3180
3216
|
var init_TeamUsage = __esm({
|
|
3181
3217
|
"src/components/TeamUsage.tsx"() {
|
|
@@ -3185,13 +3221,15 @@ var init_TeamUsage = __esm({
|
|
|
3185
3221
|
TeamCard = ({ team, usage, usageLoading, canManage, onEditTeam }) => {
|
|
3186
3222
|
const [expanded, setExpanded] = useState6(false);
|
|
3187
3223
|
const chart = useChartTheme();
|
|
3188
|
-
const
|
|
3189
|
-
const
|
|
3190
|
-
const
|
|
3191
|
-
const
|
|
3192
|
-
const
|
|
3224
|
+
const hidden = team.budget_hidden === true;
|
|
3225
|
+
const budget = hidden ? 0 : team.max_budget ?? 0;
|
|
3226
|
+
const spend = hidden ? 0 : team.spend ?? 0;
|
|
3227
|
+
const budgetPct = hidden ? Math.min(100, Math.max(0, team.budget_pct ?? 0)) : visibleBudgetPct(spend, budget);
|
|
3228
|
+
const isOver = hidden ? team.budget_status === "over" : budget > 0 && spend >= budget;
|
|
3229
|
+
const isNear = hidden ? team.budget_status === "near" : budget > 0 && spend >= budget * 0.8 && !isOver;
|
|
3193
3230
|
const dailyData = usage?.daily_usage?.map((d) => ({ date: d.date, spend: d.spend })) ?? [];
|
|
3194
3231
|
const renderDailySpendSection = () => {
|
|
3232
|
+
if (hidden) return null;
|
|
3195
3233
|
if (usageLoading) {
|
|
3196
3234
|
return /* @__PURE__ */ React8.createElement(Box8, { display: "flex", justifyContent: "center", py: 3 }, /* @__PURE__ */ React8.createElement(CircularProgress5, { size: 22 }));
|
|
3197
3235
|
}
|
|
@@ -3292,11 +3330,11 @@ var init_TeamUsage = __esm({
|
|
|
3292
3330
|
},
|
|
3293
3331
|
/* @__PURE__ */ React8.createElement(Stat, { label: "Members", value: team.members_with_roles?.length ?? "\u2014" }),
|
|
3294
3332
|
/* @__PURE__ */ React8.createElement(Stat, { label: "Models", value: team.models?.length ? team.models.length : "All" }),
|
|
3295
|
-
/* @__PURE__ */ React8.createElement(Stat, { label: "Budget", value:
|
|
3296
|
-
/* @__PURE__ */ React8.createElement(Stat, { label: "Spend", value: fmtUsd2(spend) }),
|
|
3333
|
+
/* @__PURE__ */ React8.createElement(Stat, { label: "Budget", value: budgetStatValue(hidden, budget) }),
|
|
3334
|
+
/* @__PURE__ */ React8.createElement(Stat, { label: "Spend", value: hidden ? "\u2014" : fmtUsd2(spend) }),
|
|
3297
3335
|
/* @__PURE__ */ React8.createElement(Stat, { label: "TPM", value: team.tpm_limit && team.tpm_limit > 0 ? team.tpm_limit.toLocaleString() : "\u2014" }),
|
|
3298
3336
|
/* @__PURE__ */ React8.createElement(Stat, { label: "RPM", value: team.rpm_limit && team.rpm_limit > 0 ? team.rpm_limit.toLocaleString() : "\u2014" })
|
|
3299
|
-
), budget > 0 && /* @__PURE__ */ React8.createElement(Box8, { mt: 2, maxWidth: 640 }, /* @__PURE__ */ React8.createElement(Box8, { display: "flex", justifyContent: "space-between", alignItems: "baseline", mb: 0.75 }, /* @__PURE__ */ React8.createElement(Typography8, { variant: "caption", color: "text.secondary", sx: { fontVariantNumeric: "tabular-nums" } }, fmtUsd2(spend), " of ", fmtUsd2(budget)), /* @__PURE__ */ React8.createElement(Typography8, { variant: "caption", color: "text.secondary", sx: { fontVariantNumeric: "tabular-nums" } }, budgetPct.toFixed(0), "%")), /* @__PURE__ */ React8.createElement(Meter, { value: budgetPct, tone: budgetTone3(isOver, isNear), height: 5 })), /* @__PURE__ */ React8.createElement(Collapse2, { in: expanded, unmountOnExit: true }, /* @__PURE__ */ React8.createElement(Divider3, { sx: { my: 2.5 } }), /* @__PURE__ */ React8.createElement(Box8, { mb: 2.5 }, sectionLabel("Models"), team.models?.length ? /* @__PURE__ */ React8.createElement(Box8, { display: "flex", gap: 0.5, flexWrap: "wrap" }, team.models.map((m) => /* @__PURE__ */ React8.createElement(TagChip, { key: m, label: m, title: m }))) : /* @__PURE__ */ React8.createElement(Typography8, { variant: "body2", color: "text.secondary" }, "All models allowed")), renderDailySpendSection(), /* @__PURE__ */ React8.createElement(Box8, null, sectionLabel("Members"), team.members_with_roles?.length ? /* @__PURE__ */ React8.createElement(
|
|
3337
|
+
), hidden && /* @__PURE__ */ React8.createElement(Box8, { mt: 2, maxWidth: 640 }, /* @__PURE__ */ React8.createElement(Box8, { display: "flex", justifyContent: "space-between", alignItems: "baseline", mb: 0.75 }, /* @__PURE__ */ React8.createElement(Typography8, { variant: "caption", color: "text.secondary", sx: { fontVariantNumeric: "tabular-nums" } }, budgetPct.toFixed(0), "% used"), /* @__PURE__ */ React8.createElement(Typography8, { variant: "caption", color: "text.secondary" }, "Hidden by admin")), /* @__PURE__ */ React8.createElement(Meter, { value: budgetPct, tone: budgetTone3(isOver, isNear), height: 5 }), /* @__PURE__ */ React8.createElement(Typography8, { variant: "caption", color: "text.secondary", sx: { display: "block", mt: 0.75 } }, "Team budget is hidden \u2014 showing usage level only", team.budget_duration ? ` \xB7 resets every ${team.budget_duration}` : "", ".")), !hidden && budget > 0 && /* @__PURE__ */ React8.createElement(Box8, { mt: 2, maxWidth: 640 }, /* @__PURE__ */ React8.createElement(Box8, { display: "flex", justifyContent: "space-between", alignItems: "baseline", mb: 0.75 }, /* @__PURE__ */ React8.createElement(Typography8, { variant: "caption", color: "text.secondary", sx: { fontVariantNumeric: "tabular-nums" } }, fmtUsd2(spend), " of ", fmtUsd2(budget)), /* @__PURE__ */ React8.createElement(Typography8, { variant: "caption", color: "text.secondary", sx: { fontVariantNumeric: "tabular-nums" } }, budgetPct.toFixed(0), "%")), /* @__PURE__ */ React8.createElement(Meter, { value: budgetPct, tone: budgetTone3(isOver, isNear), height: 5 })), /* @__PURE__ */ React8.createElement(Collapse2, { in: expanded, unmountOnExit: true }, /* @__PURE__ */ React8.createElement(Divider3, { sx: { my: 2.5 } }), /* @__PURE__ */ React8.createElement(Box8, { mb: 2.5 }, sectionLabel("Models"), team.models?.length ? /* @__PURE__ */ React8.createElement(Box8, { display: "flex", gap: 0.5, flexWrap: "wrap" }, team.models.map((m) => /* @__PURE__ */ React8.createElement(TagChip, { key: m, label: m, title: m }))) : /* @__PURE__ */ React8.createElement(Typography8, { variant: "body2", color: "text.secondary" }, "All models allowed")), renderDailySpendSection(), /* @__PURE__ */ React8.createElement(Box8, null, sectionLabel("Members"), team.members_with_roles?.length ? /* @__PURE__ */ React8.createElement(
|
|
3300
3338
|
TableContainer4,
|
|
3301
3339
|
{
|
|
3302
3340
|
component: Paper6,
|
|
@@ -3625,7 +3663,7 @@ var init_ModelsTable = __esm({
|
|
|
3625
3663
|
});
|
|
3626
3664
|
|
|
3627
3665
|
// src/components/AuditLog.tsx
|
|
3628
|
-
import React10, { useState as useState8,
|
|
3666
|
+
import React10, { useState as useState8, useMemo as useMemo8 } from "react";
|
|
3629
3667
|
import Box10 from "@mui/material/Box";
|
|
3630
3668
|
import Typography10 from "@mui/material/Typography";
|
|
3631
3669
|
import Table6 from "@mui/material/Table";
|
|
@@ -3764,10 +3802,10 @@ var init_AuditLog = __esm({
|
|
|
3764
3802
|
const [page, setPage] = useState8(0);
|
|
3765
3803
|
const [pageSize, setPageSize] = useState8(25);
|
|
3766
3804
|
const [filters, setFilters] = useState8({});
|
|
3767
|
-
const fetchParams =
|
|
3805
|
+
const fetchParams = useMemo8(
|
|
3768
3806
|
() => ({ page: page + 1, page_size: pageSize, ...filters }),
|
|
3769
3807
|
[page, pageSize, filters]
|
|
3770
|
-
)
|
|
3808
|
+
);
|
|
3771
3809
|
const { value, loading, error } = useAsync2(
|
|
3772
3810
|
() => api.getAuditLogs(fetchParams),
|
|
3773
3811
|
[api, fetchParams]
|
|
@@ -3888,7 +3926,7 @@ var LiteLLMPage_exports = {};
|
|
|
3888
3926
|
__export(LiteLLMPage_exports, {
|
|
3889
3927
|
LiteLLMPage: () => LiteLLMPage
|
|
3890
3928
|
});
|
|
3891
|
-
import React11, { useState as useState9, useCallback as
|
|
3929
|
+
import React11, { useState as useState9, useCallback as useCallback2, useMemo as useMemo9 } from "react";
|
|
3892
3930
|
import Box11 from "@mui/material/Box";
|
|
3893
3931
|
import Snackbar2 from "@mui/material/Snackbar";
|
|
3894
3932
|
import Alert6 from "@mui/material/Alert";
|
|
@@ -3949,7 +3987,7 @@ var init_LiteLLMPage = __esm({
|
|
|
3949
3987
|
const t = searchParams.get("tab");
|
|
3950
3988
|
return isPageTab(t) ? t : "overview";
|
|
3951
3989
|
});
|
|
3952
|
-
const selectTab =
|
|
3990
|
+
const selectTab = useCallback2(
|
|
3953
3991
|
(tab) => {
|
|
3954
3992
|
setActiveTab(tab);
|
|
3955
3993
|
setSearchParams(
|
|
@@ -4011,7 +4049,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4011
4049
|
async () => objectPermsEnabled ? api.getMcpServers().catch(() => []) : [],
|
|
4012
4050
|
[api, objectPermsEnabled]
|
|
4013
4051
|
);
|
|
4014
|
-
const teams =
|
|
4052
|
+
const teams = useMemo9(() => {
|
|
4015
4053
|
if (!allTeams?.length) return [];
|
|
4016
4054
|
if (!userInfo) return allTeams;
|
|
4017
4055
|
const userId = userInfo.user_id;
|
|
@@ -4028,7 +4066,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4028
4066
|
const endDate = dateRange.end.toISOString().split("T")[0];
|
|
4029
4067
|
return api.getUsage(startDate, endDate);
|
|
4030
4068
|
}, [api, dateRange]);
|
|
4031
|
-
const handleDateRangeChange =
|
|
4069
|
+
const handleDateRangeChange = useCallback2((range, preset) => {
|
|
4032
4070
|
setDateRange(range);
|
|
4033
4071
|
if (preset) {
|
|
4034
4072
|
setCurrentPreset(preset);
|
|
@@ -4036,7 +4074,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4036
4074
|
setTeamUsageCache({});
|
|
4037
4075
|
setTeamUsageLoading({});
|
|
4038
4076
|
}, [setDateRange, setCurrentPreset]);
|
|
4039
|
-
const loadTeamUsage =
|
|
4077
|
+
const loadTeamUsage = useCallback2(async (teamId) => {
|
|
4040
4078
|
if (teamUsageCache[teamId] !== void 0 || teamUsageLoading[teamId]) return;
|
|
4041
4079
|
setTeamUsageLoading((prev) => ({ ...prev, [teamId]: true }));
|
|
4042
4080
|
try {
|
|
@@ -4050,7 +4088,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4050
4088
|
setTeamUsageLoading((prev) => ({ ...prev, [teamId]: false }));
|
|
4051
4089
|
}
|
|
4052
4090
|
}, [api, dateRange, teamUsageCache, teamUsageLoading]);
|
|
4053
|
-
const allowedModels =
|
|
4091
|
+
const allowedModels = useMemo9(() => {
|
|
4054
4092
|
if (!allModels?.length) return [];
|
|
4055
4093
|
const userModels = userInfo?.models;
|
|
4056
4094
|
const teamModels = teams?.flatMap((t) => t.models ?? []);
|
|
@@ -4063,7 +4101,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4063
4101
|
]);
|
|
4064
4102
|
return allModels.filter((m) => allowed.has(m.model_name));
|
|
4065
4103
|
}, [allModels, userInfo, teams]);
|
|
4066
|
-
const handleGenerateKey =
|
|
4104
|
+
const handleGenerateKey = useCallback2(
|
|
4067
4105
|
async (request) => {
|
|
4068
4106
|
try {
|
|
4069
4107
|
const response = await api.generateKey(request);
|
|
@@ -4077,7 +4115,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4077
4115
|
},
|
|
4078
4116
|
[api, refreshKeys]
|
|
4079
4117
|
);
|
|
4080
|
-
const handleUpdateKey =
|
|
4118
|
+
const handleUpdateKey = useCallback2(
|
|
4081
4119
|
async (keyId, request) => {
|
|
4082
4120
|
try {
|
|
4083
4121
|
await api.updateKey(keyId, request);
|
|
@@ -4090,7 +4128,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4090
4128
|
},
|
|
4091
4129
|
[api, refreshKeys]
|
|
4092
4130
|
);
|
|
4093
|
-
const handleBlockKey =
|
|
4131
|
+
const handleBlockKey = useCallback2(
|
|
4094
4132
|
async (keyId) => {
|
|
4095
4133
|
try {
|
|
4096
4134
|
await api.blockKey(keyId);
|
|
@@ -4102,7 +4140,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4102
4140
|
},
|
|
4103
4141
|
[api, refreshKeys]
|
|
4104
4142
|
);
|
|
4105
|
-
const handleUnblockKey =
|
|
4143
|
+
const handleUnblockKey = useCallback2(
|
|
4106
4144
|
async (keyId) => {
|
|
4107
4145
|
try {
|
|
4108
4146
|
await api.unblockKey(keyId);
|
|
@@ -4114,7 +4152,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4114
4152
|
},
|
|
4115
4153
|
[api, refreshKeys]
|
|
4116
4154
|
);
|
|
4117
|
-
const handleResetKeySpend =
|
|
4155
|
+
const handleResetKeySpend = useCallback2(
|
|
4118
4156
|
async (keyId) => {
|
|
4119
4157
|
try {
|
|
4120
4158
|
await api.resetKeySpend(keyId);
|
|
@@ -4126,7 +4164,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4126
4164
|
},
|
|
4127
4165
|
[api, refreshKeys]
|
|
4128
4166
|
);
|
|
4129
|
-
const handleDeleteKey =
|
|
4167
|
+
const handleDeleteKey = useCallback2(
|
|
4130
4168
|
async (keyId) => {
|
|
4131
4169
|
try {
|
|
4132
4170
|
await api.deleteKey(keyId);
|
|
@@ -4143,7 +4181,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4143
4181
|
},
|
|
4144
4182
|
[api, refreshKeys]
|
|
4145
4183
|
);
|
|
4146
|
-
const handlePruneExpiredKeys =
|
|
4184
|
+
const handlePruneExpiredKeys = useCallback2(
|
|
4147
4185
|
async () => {
|
|
4148
4186
|
try {
|
|
4149
4187
|
const result = await api.pruneExpiredKeys();
|