@acarmisc/backstage-plugin-litellm 0.16.0 → 0.17.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/index.cjs.js +53 -37
- package/dist/index.cjs.js.map +3 -3
- package/dist/index.esm.js +50 -34
- package/dist/index.esm.js.map +3 -3
- package/dist/types.d.ts +3 -2
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1931,6 +1931,7 @@ import Alert2 from "@mui/material/Alert";
|
|
|
1931
1931
|
import Checkbox2 from "@mui/material/Checkbox";
|
|
1932
1932
|
import FormControlLabel2 from "@mui/material/FormControlLabel";
|
|
1933
1933
|
import Autocomplete3 from "@mui/material/Autocomplete";
|
|
1934
|
+
import MenuItem2 from "@mui/material/MenuItem";
|
|
1934
1935
|
import Box5 from "@mui/material/Box";
|
|
1935
1936
|
import Divider2 from "@mui/material/Divider";
|
|
1936
1937
|
import Typography5 from "@mui/material/Typography";
|
|
@@ -1939,10 +1940,19 @@ import List from "@mui/material/List";
|
|
|
1939
1940
|
import ListItem from "@mui/material/ListItem";
|
|
1940
1941
|
import ListItemText from "@mui/material/ListItemText";
|
|
1941
1942
|
import { Delete as DeleteIcon } from "@mui/icons-material";
|
|
1942
|
-
var ManageTeamDialog;
|
|
1943
|
+
var BUDGET_DURATION_OPTIONS, DEFAULT_BUDGET_DURATION, FALLBACK_BUDGET_CEILING, ManageTeamDialog;
|
|
1943
1944
|
var init_ManageTeamDialog = __esm({
|
|
1944
1945
|
"src/components/ManageTeamDialog.tsx"() {
|
|
1945
1946
|
"use strict";
|
|
1947
|
+
BUDGET_DURATION_OPTIONS = [
|
|
1948
|
+
{ value: "1d", label: "Daily (1d)" },
|
|
1949
|
+
{ value: "7d", label: "Weekly (7d)" },
|
|
1950
|
+
{ value: "30d", label: "Monthly (30d)" },
|
|
1951
|
+
{ value: "90d", label: "Quarterly (90d)" },
|
|
1952
|
+
{ value: "365d", label: "Yearly (365d)" }
|
|
1953
|
+
];
|
|
1954
|
+
DEFAULT_BUDGET_DURATION = "30d";
|
|
1955
|
+
FALLBACK_BUDGET_CEILING = 1e3;
|
|
1946
1956
|
ManageTeamDialog = ({
|
|
1947
1957
|
open,
|
|
1948
1958
|
onClose,
|
|
@@ -1979,21 +1989,23 @@ var init_ManageTeamDialog = __esm({
|
|
|
1979
1989
|
const [mcpBusy, setMcpBusy] = useState3(false);
|
|
1980
1990
|
const [mcpError, setMcpError] = useState3(null);
|
|
1981
1991
|
const allowUnlimitedBudget = config?.teamManagement?.allowUnlimitedBudget ?? false;
|
|
1982
|
-
const maxBudgetCeiling = config?.teamManagement?.maxBudgetCeiling;
|
|
1992
|
+
const maxBudgetCeiling = config?.teamManagement?.maxBudgetCeiling ?? FALLBACK_BUDGET_CEILING;
|
|
1983
1993
|
useEffect2(() => {
|
|
1984
1994
|
if (open) {
|
|
1985
1995
|
if (mode === "edit" && team) {
|
|
1986
1996
|
setAlias(team.team_alias ?? "");
|
|
1987
1997
|
setModels(team.models ?? []);
|
|
1988
|
-
setMaxBudget(
|
|
1998
|
+
setMaxBudget(
|
|
1999
|
+
team.max_budget ? String(team.max_budget) : String(maxBudgetCeiling)
|
|
2000
|
+
);
|
|
1989
2001
|
setUnlimited(allowUnlimitedBudget && !team.max_budget);
|
|
1990
|
-
setBudgetDuration(
|
|
2002
|
+
setBudgetDuration(team.budget_duration ?? DEFAULT_BUDGET_DURATION);
|
|
1991
2003
|
} else {
|
|
1992
2004
|
setAlias("");
|
|
1993
2005
|
setModels([]);
|
|
1994
|
-
setMaxBudget(
|
|
2006
|
+
setMaxBudget(String(maxBudgetCeiling));
|
|
1995
2007
|
setUnlimited(allowUnlimitedBudget);
|
|
1996
|
-
setBudgetDuration(
|
|
2008
|
+
setBudgetDuration(DEFAULT_BUDGET_DURATION);
|
|
1997
2009
|
}
|
|
1998
2010
|
setError(null);
|
|
1999
2011
|
setMemberRef("");
|
|
@@ -2004,7 +2016,7 @@ var init_ManageTeamDialog = __esm({
|
|
|
2004
2016
|
setMcpIds(team?.object_permission?.mcp_servers ?? []);
|
|
2005
2017
|
setMcpError(null);
|
|
2006
2018
|
}
|
|
2007
|
-
}, [open, mode, team, allowUnlimitedBudget]);
|
|
2019
|
+
}, [open, mode, team, allowUnlimitedBudget, maxBudgetCeiling]);
|
|
2008
2020
|
const handleSubmit = async () => {
|
|
2009
2021
|
setError(null);
|
|
2010
2022
|
if (!alias.trim()) {
|
|
@@ -2025,7 +2037,7 @@ var init_ManageTeamDialog = __esm({
|
|
|
2025
2037
|
setError("Budget must be a positive number");
|
|
2026
2038
|
return;
|
|
2027
2039
|
}
|
|
2028
|
-
if (
|
|
2040
|
+
if (budget > maxBudgetCeiling) {
|
|
2029
2041
|
setError(`Budget cannot exceed $${maxBudgetCeiling}`);
|
|
2030
2042
|
return;
|
|
2031
2043
|
}
|
|
@@ -2112,6 +2124,7 @@ var init_ManageTeamDialog = __esm({
|
|
|
2112
2124
|
}
|
|
2113
2125
|
};
|
|
2114
2126
|
const modelNames = allModels.map((m) => m.model_name);
|
|
2127
|
+
const durationOptions = BUDGET_DURATION_OPTIONS.some((o) => o.value === budgetDuration) ? BUDGET_DURATION_OPTIONS : [...BUDGET_DURATION_OPTIONS, { value: budgetDuration, label: budgetDuration }];
|
|
2115
2128
|
const members = team?.members_with_roles ?? [];
|
|
2116
2129
|
const showMembers = mode === "edit" && !!canManageMembers;
|
|
2117
2130
|
const showKnowledgeBases = mode === "edit" && !!canManageKnowledgeBases;
|
|
@@ -2147,7 +2160,8 @@ var init_ManageTeamDialog = __esm({
|
|
|
2147
2160
|
value: maxBudget,
|
|
2148
2161
|
onChange: (e) => setMaxBudget(e.target.value),
|
|
2149
2162
|
disabled: submitting || unlimited,
|
|
2150
|
-
|
|
2163
|
+
inputProps: { min: 0, max: maxBudgetCeiling },
|
|
2164
|
+
helperText: `Maximum: $${maxBudgetCeiling}`,
|
|
2151
2165
|
fullWidth: true
|
|
2152
2166
|
}
|
|
2153
2167
|
), allowUnlimitedBudget && /* @__PURE__ */ React5.createElement(
|
|
@@ -2159,13 +2173,15 @@ var init_ManageTeamDialog = __esm({
|
|
|
2159
2173
|
), /* @__PURE__ */ React5.createElement(
|
|
2160
2174
|
TextField3,
|
|
2161
2175
|
{
|
|
2176
|
+
select: true,
|
|
2162
2177
|
label: "Budget Duration",
|
|
2163
2178
|
value: budgetDuration,
|
|
2164
2179
|
onChange: (e) => setBudgetDuration(e.target.value),
|
|
2165
|
-
|
|
2166
|
-
|
|
2180
|
+
disabled: submitting || unlimited,
|
|
2181
|
+
helperText: "Spend-reset period for the team budget",
|
|
2167
2182
|
fullWidth: true
|
|
2168
|
-
}
|
|
2183
|
+
},
|
|
2184
|
+
durationOptions.map((o) => /* @__PURE__ */ React5.createElement(MenuItem2, { key: o.value, value: o.value }, o.label))
|
|
2169
2185
|
), showMembers && /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Divider2, { sx: { my: 1 } }), /* @__PURE__ */ React5.createElement(Typography5, { variant: "subtitle2", sx: { mb: 1 } }, "Members"), memberError && /* @__PURE__ */ React5.createElement(Alert2, { severity: "error", sx: { mb: 1 }, onClose: () => setMemberError(null) }, memberError), members.length === 0 ? /* @__PURE__ */ React5.createElement(Typography5, { variant: "body2", color: "text.secondary" }, "No members yet.") : /* @__PURE__ */ React5.createElement(List, { dense: true, disablePadding: true }, members.map((m) => /* @__PURE__ */ React5.createElement(
|
|
2170
2186
|
ListItem,
|
|
2171
2187
|
{
|
|
@@ -2264,7 +2280,7 @@ import Paper3 from "@mui/material/Paper";
|
|
|
2264
2280
|
import Box6 from "@mui/material/Box";
|
|
2265
2281
|
import Typography6 from "@mui/material/Typography";
|
|
2266
2282
|
import TextField4 from "@mui/material/TextField";
|
|
2267
|
-
import
|
|
2283
|
+
import MenuItem3 from "@mui/material/MenuItem";
|
|
2268
2284
|
import Grid from "@mui/material/Grid";
|
|
2269
2285
|
import Table2 from "@mui/material/Table";
|
|
2270
2286
|
import TableBody2 from "@mui/material/TableBody";
|
|
@@ -2493,7 +2509,7 @@ var init_UsageStats = __esm({
|
|
|
2493
2509
|
onChange: (e) => handlePresetChange(e.target.value),
|
|
2494
2510
|
sx: { minWidth: 160 }
|
|
2495
2511
|
},
|
|
2496
|
-
Object.keys(PRESET_LABELS).map((p) => /* @__PURE__ */ React6.createElement(
|
|
2512
|
+
Object.keys(PRESET_LABELS).map((p) => /* @__PURE__ */ React6.createElement(MenuItem3, { key: p, value: p }, PRESET_LABELS[p]))
|
|
2497
2513
|
);
|
|
2498
2514
|
return /* @__PURE__ */ React6.createElement(
|
|
2499
2515
|
SectionCard,
|
|
@@ -2538,8 +2554,8 @@ var init_UsageStats = __esm({
|
|
|
2538
2554
|
onChange: (e) => setSelectedModel(e.target.value),
|
|
2539
2555
|
sx: { minWidth: 220 }
|
|
2540
2556
|
},
|
|
2541
|
-
/* @__PURE__ */ React6.createElement(
|
|
2542
|
-
models.map((m) => /* @__PURE__ */ React6.createElement(
|
|
2557
|
+
/* @__PURE__ */ React6.createElement(MenuItem3, { value: "all" }, "All models"),
|
|
2558
|
+
models.map((m) => /* @__PURE__ */ React6.createElement(MenuItem3, { key: m.model_name, value: m.model_name }, m.model_name))
|
|
2543
2559
|
)
|
|
2544
2560
|
),
|
|
2545
2561
|
tab === "costs" && /* @__PURE__ */ React6.createElement(Grid, { container: true, spacing: 2 }, /* @__PURE__ */ React6.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React6.createElement(ChartCard, { title: "Daily spend by model", height: 260 }, /* @__PURE__ */ React6.createElement(ChartOrFallback, { loading, empty: modelSpendByDate.length === 0, height: 260 }, /* @__PURE__ */ React6.createElement(ResponsiveContainer, { width: "100%", height: "100%" }, /* @__PURE__ */ React6.createElement(AreaChart, { data: modelSpendByDate, margin: { top: 4, right: 8, left: 0, bottom: 0 } }, /* @__PURE__ */ React6.createElement(CartesianGrid, { ...chart.grid }), /* @__PURE__ */ React6.createElement(XAxis, { dataKey: "date", tickFormatter: fmtDateShort, ...chart.axis }), /* @__PURE__ */ React6.createElement(YAxis, { tickFormatter: fmtUsdCompact, width: 56, ...chart.axis }), /* @__PURE__ */ React6.createElement(
|
|
@@ -2879,7 +2895,7 @@ import TableContainer4 from "@mui/material/TableContainer";
|
|
|
2879
2895
|
import TableHead4 from "@mui/material/TableHead";
|
|
2880
2896
|
import TableRow4 from "@mui/material/TableRow";
|
|
2881
2897
|
import Typography8 from "@mui/material/Typography";
|
|
2882
|
-
import
|
|
2898
|
+
import MenuItem4 from "@mui/material/MenuItem";
|
|
2883
2899
|
import Select from "@mui/material/Select";
|
|
2884
2900
|
import FormControl from "@mui/material/FormControl";
|
|
2885
2901
|
import InputLabel from "@mui/material/InputLabel";
|
|
@@ -2954,7 +2970,7 @@ var init_ModelsTable = __esm({
|
|
|
2954
2970
|
label: "Team",
|
|
2955
2971
|
onChange: (e) => setSelectedTeamId(e.target.value)
|
|
2956
2972
|
},
|
|
2957
|
-
teams.map((t) => /* @__PURE__ */ React8.createElement(
|
|
2973
|
+
teams.map((t) => /* @__PURE__ */ React8.createElement(MenuItem4, { key: t.team_id, value: t.team_id }, t.team_alias ?? t.team_id))
|
|
2958
2974
|
))),
|
|
2959
2975
|
loading && /* @__PURE__ */ React8.createElement(EmptyState, { message: "Loading models\u2026" }),
|
|
2960
2976
|
!loading && !selectedTeamId && /* @__PURE__ */ React8.createElement(
|
|
@@ -3028,7 +3044,7 @@ import TableHead5 from "@mui/material/TableHead";
|
|
|
3028
3044
|
import TableRow5 from "@mui/material/TableRow";
|
|
3029
3045
|
import TablePagination from "@mui/material/TablePagination";
|
|
3030
3046
|
import TextField5 from "@mui/material/TextField";
|
|
3031
|
-
import
|
|
3047
|
+
import MenuItem5 from "@mui/material/MenuItem";
|
|
3032
3048
|
import Skeleton5 from "@mui/material/Skeleton";
|
|
3033
3049
|
import Collapse2 from "@mui/material/Collapse";
|
|
3034
3050
|
import IconButton5 from "@mui/material/IconButton";
|
|
@@ -3185,11 +3201,11 @@ var init_AuditLog = __esm({
|
|
|
3185
3201
|
},
|
|
3186
3202
|
sx: { minWidth: 150 }
|
|
3187
3203
|
},
|
|
3188
|
-
/* @__PURE__ */ React9.createElement(
|
|
3189
|
-
/* @__PURE__ */ React9.createElement(
|
|
3190
|
-
/* @__PURE__ */ React9.createElement(
|
|
3191
|
-
/* @__PURE__ */ React9.createElement(
|
|
3192
|
-
/* @__PURE__ */ React9.createElement(
|
|
3204
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "" }, "All actions"),
|
|
3205
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "created" }, "Created"),
|
|
3206
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "updated" }, "Updated"),
|
|
3207
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "deleted" }, "Deleted"),
|
|
3208
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "blocked" }, "Blocked")
|
|
3193
3209
|
), /* @__PURE__ */ React9.createElement(
|
|
3194
3210
|
TextField5,
|
|
3195
3211
|
{
|
|
@@ -3203,12 +3219,12 @@ var init_AuditLog = __esm({
|
|
|
3203
3219
|
},
|
|
3204
3220
|
sx: { minWidth: 150 }
|
|
3205
3221
|
},
|
|
3206
|
-
/* @__PURE__ */ React9.createElement(
|
|
3207
|
-
/* @__PURE__ */ React9.createElement(
|
|
3208
|
-
/* @__PURE__ */ React9.createElement(
|
|
3209
|
-
/* @__PURE__ */ React9.createElement(
|
|
3210
|
-
/* @__PURE__ */ React9.createElement(
|
|
3211
|
-
/* @__PURE__ */ React9.createElement(
|
|
3222
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "" }, "All tables"),
|
|
3223
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "LiteLLM_VerificationToken" }, "Key"),
|
|
3224
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "LiteLLM_TeamTable" }, "Team"),
|
|
3225
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "LiteLLM_TeamMembership" }, "Team member"),
|
|
3226
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "LiteLLM_ObjectPermissionTable" }, "Team access (KB / MCP)"),
|
|
3227
|
+
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "LiteLLM_UserTable" }, "User")
|
|
3212
3228
|
), /* @__PURE__ */ React9.createElement(
|
|
3213
3229
|
TextField5,
|
|
3214
3230
|
{
|
|
@@ -3760,7 +3776,7 @@ import Box11 from "@mui/material/Box";
|
|
|
3760
3776
|
import Typography11 from "@mui/material/Typography";
|
|
3761
3777
|
import FormControl2 from "@mui/material/FormControl";
|
|
3762
3778
|
import Select2 from "@mui/material/Select";
|
|
3763
|
-
import
|
|
3779
|
+
import MenuItem6 from "@mui/material/MenuItem";
|
|
3764
3780
|
import Grid2 from "@mui/material/Grid";
|
|
3765
3781
|
import CircularProgress5 from "@mui/material/CircularProgress";
|
|
3766
3782
|
import Alert6 from "@mui/material/Alert";
|
|
@@ -3834,9 +3850,9 @@ var LiteLLMHomeWidget = ({
|
|
|
3834
3850
|
onChange: (e) => setPeriod(e.target.value),
|
|
3835
3851
|
displayEmpty: true
|
|
3836
3852
|
},
|
|
3837
|
-
/* @__PURE__ */ React12.createElement(
|
|
3838
|
-
/* @__PURE__ */ React12.createElement(
|
|
3839
|
-
/* @__PURE__ */ React12.createElement(
|
|
3853
|
+
/* @__PURE__ */ React12.createElement(MenuItem6, { value: "today" }, "Today"),
|
|
3854
|
+
/* @__PURE__ */ React12.createElement(MenuItem6, { value: "7d" }, "7d"),
|
|
3855
|
+
/* @__PURE__ */ React12.createElement(MenuItem6, { value: "30d" }, "30d")
|
|
3840
3856
|
))), loading && /* @__PURE__ */ React12.createElement(Box11, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: 120 }, /* @__PURE__ */ React12.createElement(CircularProgress5, { size: 32 })), !loading && totalFailure && /* @__PURE__ */ React12.createElement(Alert6, { severity: "error", sx: { mt: 1 } }, usageError ?? "Failed to load usage data"), !loading && !totalFailure && /* @__PURE__ */ React12.createElement(React12.Fragment, null, partialFailure && /* @__PURE__ */ React12.createElement(Alert6, { severity: "warning", sx: { mt: 1, mb: 1 } }, usageError ? `Usage data unavailable (${usageError}).` : "", keysError ? ` Key list unavailable (${keysError}).` : "", " Showing what loaded."), /* @__PURE__ */ React12.createElement(Grid2, { container: true, spacing: 2, sx: { mb: hasSparkline ? 1.5 : 0 } }, /* @__PURE__ */ React12.createElement(Grid2, { item: true, xs: 6 }, /* @__PURE__ */ React12.createElement(Kpi, { label: "USD Spent", value: fmtUsd(usage?.total_spend ?? 0) })), /* @__PURE__ */ React12.createElement(Grid2, { item: true, xs: 6 }, /* @__PURE__ */ React12.createElement(Kpi, { label: "Tokens In", value: fmtInt(usage?.prompt_tokens ?? 0) })), /* @__PURE__ */ React12.createElement(Grid2, { item: true, xs: 6 }, /* @__PURE__ */ React12.createElement(Kpi, { label: "Tokens Out", value: fmtInt(usage?.completion_tokens ?? 0) })), /* @__PURE__ */ React12.createElement(Grid2, { item: true, xs: 6 }, /* @__PURE__ */ React12.createElement(Kpi, { label: "Keys", value: fmtInt(keys.length) }))), hasSparkline && /* @__PURE__ */ React12.createElement(Box11, { height: 120 }, /* @__PURE__ */ React12.createElement(ResponsiveContainer3, { width: "100%", height: "100%" }, /* @__PURE__ */ React12.createElement(AreaChart3, { data: dailyData, margin: { top: 4, right: 0, bottom: 0, left: 0 } }, /* @__PURE__ */ React12.createElement(
|
|
3841
3857
|
Area3,
|
|
3842
3858
|
{
|