@acarmisc/backstage-plugin-litellm 0.40.0 → 0.42.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/components/KeysTable.d.ts +3 -1
- package/dist/components/TeamUsage.d.ts +5 -1
- package/dist/index.cjs.js +77 -32
- package/dist/index.cjs.js.map +3 -3
- package/dist/index.esm.js +72 -27
- package/dist/index.esm.js.map +3 -3
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { type KeyFilterType } from '../keyFilter';
|
|
3
|
-
import { VirtualKey } from '../types';
|
|
3
|
+
import { TeamInfo, VirtualKey } from '../types';
|
|
4
4
|
interface KeysTableProps {
|
|
5
5
|
keys: VirtualKey[];
|
|
6
6
|
/** Opens the shared key form dialog in create mode (rendered at page level). */
|
|
@@ -16,6 +16,8 @@ interface KeysTableProps {
|
|
|
16
16
|
}>;
|
|
17
17
|
filter?: KeyFilterType;
|
|
18
18
|
onClearFilter?: () => void;
|
|
19
|
+
/** Used to show team names instead of raw team ids. */
|
|
20
|
+
teams?: TeamInfo[];
|
|
19
21
|
}
|
|
20
22
|
export declare const KeysTable: FC<KeysTableProps>;
|
|
21
23
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
|
-
import { TeamInfo, TeamMemberUsage, UsageMetrics } from '../types';
|
|
2
|
+
import { McpServerInfo, TeamInfo, TeamMemberUsage, UsageMetrics, VectorStoreInfo } from '../types';
|
|
3
3
|
/**
|
|
4
4
|
* Per-member usage for the period, sorted by spend. Dollars are replaced by
|
|
5
5
|
* the share of team spend when the backend hides them.
|
|
@@ -27,6 +27,10 @@ interface TeamUsageProps {
|
|
|
27
27
|
onManageMembers?: (team: TeamInfo) => void;
|
|
28
28
|
/** Teams are synced from an identity provider: show a badge, no write controls. */
|
|
29
29
|
readOnly?: boolean;
|
|
30
|
+
/** Used to show knowledge base names instead of raw ids. */
|
|
31
|
+
vectorStores?: VectorStoreInfo[];
|
|
32
|
+
/** Used to show MCP server names instead of raw ids. */
|
|
33
|
+
mcpServers?: McpServerInfo[];
|
|
30
34
|
}
|
|
31
35
|
export declare const TeamUsage: FC<TeamUsageProps>;
|
|
32
36
|
export {};
|
package/dist/index.cjs.js
CHANGED
|
@@ -1721,7 +1721,7 @@ function compareKeys(a, b, sortKey) {
|
|
|
1721
1721
|
return 0;
|
|
1722
1722
|
}
|
|
1723
1723
|
}
|
|
1724
|
-
var import_react4, import_Table, import_TableBody, import_TableCell, import_TableContainer, import_TableHead, import_TableRow, import_TableSortLabel, import_Button2, import_IconButton, import_Box7, import_Typography5, import_Dialog, import_DialogTitle, import_DialogContent, import_DialogActions, import_TextField, import_CircularProgress, import_Skeleton2, import_InputAdornment, import_Tooltip, import_Chip, import_styles7, import_icons_material2, import_plugin_permission_react, import_backstage_plugin_litellm_common, import_jsx_runtime8, shortKeyId, formatDate, KeysTable;
|
|
1724
|
+
var import_react4, import_Table, import_TableBody, import_TableCell, import_TableContainer, import_TableHead, import_TableRow, import_TableSortLabel, import_Button2, import_IconButton, import_Box7, import_Typography5, import_Dialog, import_DialogTitle, import_DialogContent, import_DialogActions, import_TextField, import_MenuItem, import_CircularProgress, import_Skeleton2, import_InputAdornment, import_Tooltip, import_Chip, import_styles7, import_icons_material2, import_plugin_permission_react, import_backstage_plugin_litellm_common, import_jsx_runtime8, shortKeyId, formatDate, KeysTable;
|
|
1725
1725
|
var init_KeysTable = __esm({
|
|
1726
1726
|
"src/components/KeysTable.tsx"() {
|
|
1727
1727
|
"use strict";
|
|
@@ -1742,6 +1742,7 @@ var init_KeysTable = __esm({
|
|
|
1742
1742
|
import_DialogContent = __toESM(require("@mui/material/DialogContent"));
|
|
1743
1743
|
import_DialogActions = __toESM(require("@mui/material/DialogActions"));
|
|
1744
1744
|
import_TextField = __toESM(require("@mui/material/TextField"));
|
|
1745
|
+
import_MenuItem = __toESM(require("@mui/material/MenuItem"));
|
|
1745
1746
|
import_CircularProgress = __toESM(require("@mui/material/CircularProgress"));
|
|
1746
1747
|
import_Skeleton2 = __toESM(require("@mui/material/Skeleton"));
|
|
1747
1748
|
import_InputAdornment = __toESM(require("@mui/material/InputAdornment"));
|
|
@@ -1781,7 +1782,8 @@ var init_KeysTable = __esm({
|
|
|
1781
1782
|
onDeleteKey,
|
|
1782
1783
|
onPruneExpiredKeys,
|
|
1783
1784
|
filter,
|
|
1784
|
-
onClearFilter
|
|
1785
|
+
onClearFilter,
|
|
1786
|
+
teams
|
|
1785
1787
|
}) => {
|
|
1786
1788
|
const managePermission = (0, import_plugin_permission_react.usePermission)({ permission: import_backstage_plugin_litellm_common.litellmKeyManagePermission });
|
|
1787
1789
|
const revokePermission = (0, import_plugin_permission_react.usePermission)({ permission: import_backstage_plugin_litellm_common.litellmKeyRevokePermission });
|
|
@@ -1798,6 +1800,7 @@ var init_KeysTable = __esm({
|
|
|
1798
1800
|
const [deleteSubmitting, setDeleteSubmitting] = (0, import_react4.useState)(false);
|
|
1799
1801
|
const clipboard = useCopyToClipboard();
|
|
1800
1802
|
const [filterText, setFilterText] = (0, import_react4.useState)("");
|
|
1803
|
+
const [teamFilter, setTeamFilter] = (0, import_react4.useState)("");
|
|
1801
1804
|
const [sortKey, setSortKey] = (0, import_react4.useState)("created");
|
|
1802
1805
|
const [sortDirection, setSortDirection] = (0, import_react4.useState)("desc");
|
|
1803
1806
|
const handleSort = (nextSortKey) => {
|
|
@@ -1808,9 +1811,21 @@ var init_KeysTable = __esm({
|
|
|
1808
1811
|
setSortDirection("asc");
|
|
1809
1812
|
}
|
|
1810
1813
|
};
|
|
1814
|
+
const teamNames = (0, import_react4.useMemo)(
|
|
1815
|
+
() => new Map((teams ?? []).map((t) => [t.team_id, t.team_alias || t.team_id])),
|
|
1816
|
+
[teams]
|
|
1817
|
+
);
|
|
1818
|
+
const teamLabel = (id) => teamNames.get(id) ?? id;
|
|
1819
|
+
const teamIds = (0, import_react4.useMemo)(
|
|
1820
|
+
() => [...new Set(keys.map((k) => k.team_id).filter((t) => !!t))].sort((a, b) => (teamNames.get(a) ?? a).localeCompare(teamNames.get(b) ?? b)),
|
|
1821
|
+
[keys, teamNames]
|
|
1822
|
+
);
|
|
1811
1823
|
const filteredKeys = (0, import_react4.useMemo)(() => {
|
|
1812
1824
|
let result = keys;
|
|
1813
1825
|
result = filterKeysByStatus(result, filter);
|
|
1826
|
+
if (teamFilter) {
|
|
1827
|
+
result = result.filter((k) => k.team_id === teamFilter);
|
|
1828
|
+
}
|
|
1814
1829
|
if (filterText.trim()) {
|
|
1815
1830
|
const q = filterText.toLowerCase();
|
|
1816
1831
|
result = result.filter(
|
|
@@ -1821,7 +1836,7 @@ var init_KeysTable = __esm({
|
|
|
1821
1836
|
const comparison = compareKeys(a, b, sortKey);
|
|
1822
1837
|
return sortDirection === "asc" ? comparison : -comparison;
|
|
1823
1838
|
});
|
|
1824
|
-
}, [keys, filterText, sortKey, sortDirection, filter]);
|
|
1839
|
+
}, [keys, filterText, teamFilter, sortKey, sortDirection, filter]);
|
|
1825
1840
|
const handleOpenEdit = (k) => {
|
|
1826
1841
|
onEditKey(k);
|
|
1827
1842
|
};
|
|
@@ -1880,10 +1895,10 @@ var init_KeysTable = __esm({
|
|
|
1880
1895
|
};
|
|
1881
1896
|
const renderTableBody = () => {
|
|
1882
1897
|
if (loading) {
|
|
1883
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableRow.default, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { colSpan:
|
|
1898
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableRow.default, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { colSpan: 9, sx: { py: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Skeleton2.default, { variant: "rounded", height: 140 }) }) });
|
|
1884
1899
|
}
|
|
1885
1900
|
if (filteredKeys.length === 0) {
|
|
1886
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableRow.default, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { colSpan:
|
|
1901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableRow.default, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { colSpan: 9, children: filterText || teamFilter ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1887
1902
|
EmptyState,
|
|
1888
1903
|
{
|
|
1889
1904
|
message: "No keys match that filter",
|
|
@@ -1927,6 +1942,7 @@ var init_KeysTable = __esm({
|
|
|
1927
1942
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Typography5.default, { variant: "body2", children: key.key_alias || "\u2014" }),
|
|
1928
1943
|
key.blocked && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StatusPill, { label: "Blocked", tone: "danger" })
|
|
1929
1944
|
] }) }),
|
|
1945
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Typography5.default, { variant: "body2", color: "text.secondary", children: key.team_id ? teamLabel(key.team_id) : "\u2014" }) }),
|
|
1930
1946
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_Box7.default, { display: "flex", alignItems: "center", gap: 0.5, children: [
|
|
1931
1947
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1932
1948
|
import_Typography5.default,
|
|
@@ -2019,7 +2035,7 @@ var init_KeysTable = __esm({
|
|
|
2019
2035
|
SectionCard,
|
|
2020
2036
|
{
|
|
2021
2037
|
title: "Virtual Keys",
|
|
2022
|
-
subtitle: loading ? "Loading\u2026" : `${filteredKeys.length}${filterText ? ` of ${keys.length}` : ""} key${filteredKeys.length === 1 ? "" : "s"}`,
|
|
2038
|
+
subtitle: loading ? "Loading\u2026" : `${filteredKeys.length}${filterText || teamFilter ? ` of ${keys.length}` : ""} key${filteredKeys.length === 1 ? "" : "s"}`,
|
|
2023
2039
|
flush: true,
|
|
2024
2040
|
actions: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
2025
2041
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
@@ -2036,6 +2052,21 @@ var init_KeysTable = __esm({
|
|
|
2036
2052
|
}
|
|
2037
2053
|
}
|
|
2038
2054
|
),
|
|
2055
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2056
|
+
import_TextField.default,
|
|
2057
|
+
{
|
|
2058
|
+
select: true,
|
|
2059
|
+
size: "small",
|
|
2060
|
+
label: "Team",
|
|
2061
|
+
value: teamFilter,
|
|
2062
|
+
onChange: (e) => setTeamFilter(e.target.value),
|
|
2063
|
+
sx: { minWidth: 160 },
|
|
2064
|
+
children: [
|
|
2065
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_MenuItem.default, { value: "", children: "All teams" }),
|
|
2066
|
+
teamIds.map((id) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_MenuItem.default, { value: id, children: teamLabel(id) }, id))
|
|
2067
|
+
]
|
|
2068
|
+
}
|
|
2069
|
+
),
|
|
2039
2070
|
expiredKeys.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2040
2071
|
import_Button2.default,
|
|
2041
2072
|
{
|
|
@@ -2074,6 +2105,7 @@ var init_KeysTable = __esm({
|
|
|
2074
2105
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableContainer.default, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_Table.default, { size: "small", sx: dataTableSx, children: [
|
|
2075
2106
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableHead.default, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_TableRow.default, { children: [
|
|
2076
2107
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { sortDirection: sortKey === "alias" ? sortDirection : false, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableSortLabel.default, { active: sortKey === "alias", direction: sortKey === "alias" ? sortDirection : "asc", onClick: () => handleSort("alias"), children: "Alias" }) }),
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { children: "Team" }),
|
|
2077
2109
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { children: "Key ID" }),
|
|
2078
2110
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { sortDirection: sortKey === "created" ? sortDirection : false, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableSortLabel.default, { active: sortKey === "created", direction: sortKey === "created" ? sortDirection : "asc", onClick: () => handleSort("created"), children: "Created" }) }),
|
|
2079
2111
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableCell.default, { sortDirection: sortKey === "expires" ? sortDirection : false, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_TableSortLabel.default, { active: sortKey === "expires", direction: sortKey === "expires" ? sortDirection : "asc", onClick: () => handleSort("expires"), children: "Expires" }) }),
|
|
@@ -2504,7 +2536,7 @@ function formatContextWindow(maxInput, maxOutput) {
|
|
|
2504
2536
|
if (outPart) return `ctx ${outPart} out`;
|
|
2505
2537
|
return null;
|
|
2506
2538
|
}
|
|
2507
|
-
var import_react6, import_Box9, import_Typography7, import_Dialog2, import_DialogTitle2, import_DialogContent2, import_DialogActions2, import_TextField2,
|
|
2539
|
+
var import_react6, import_Box9, import_Typography7, import_Dialog2, import_DialogTitle2, import_DialogContent2, import_DialogActions2, import_TextField2, import_MenuItem2, import_Button3, import_IconButton3, import_CircularProgress2, import_Autocomplete, import_Checkbox, import_FormControlLabel, import_Alert, import_Accordion, import_AccordionSummary, import_AccordionDetails, import_Tooltip3, import_InputAdornment2, import_Chip2, import_icons_material4, import_plugin_permission_react2, import_backstage_plugin_litellm_common3, import_jsx_runtime10, KeyFormDialog;
|
|
2508
2540
|
var init_KeyFormDialog = __esm({
|
|
2509
2541
|
"src/components/KeyFormDialog.tsx"() {
|
|
2510
2542
|
"use strict";
|
|
@@ -2516,7 +2548,7 @@ var init_KeyFormDialog = __esm({
|
|
|
2516
2548
|
import_DialogContent2 = __toESM(require("@mui/material/DialogContent"));
|
|
2517
2549
|
import_DialogActions2 = __toESM(require("@mui/material/DialogActions"));
|
|
2518
2550
|
import_TextField2 = __toESM(require("@mui/material/TextField"));
|
|
2519
|
-
|
|
2551
|
+
import_MenuItem2 = __toESM(require("@mui/material/MenuItem"));
|
|
2520
2552
|
import_Button3 = __toESM(require("@mui/material/Button"));
|
|
2521
2553
|
import_IconButton3 = __toESM(require("@mui/material/IconButton"));
|
|
2522
2554
|
import_CircularProgress2 = __toESM(require("@mui/material/CircularProgress"));
|
|
@@ -3066,7 +3098,7 @@ var init_KeyFormDialog = __esm({
|
|
|
3066
3098
|
value: generateForm.duration || "30d",
|
|
3067
3099
|
onChange: (e) => setFormData({ duration: e.target.value }),
|
|
3068
3100
|
fullWidth: true,
|
|
3069
|
-
children: import_backstage_plugin_litellm_common3.DEFAULT_KEY_DURATIONS.map((duration) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3101
|
+
children: import_backstage_plugin_litellm_common3.DEFAULT_KEY_DURATIONS.map((duration) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_MenuItem2.default, { value: duration, children: (0, import_backstage_plugin_litellm_common3.formatDurationLabel)(duration) }, duration))
|
|
3070
3102
|
}
|
|
3071
3103
|
),
|
|
3072
3104
|
generateForm.duration && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_Typography7.default, { variant: "caption", color: "text.secondary", children: expiryPreview(generateForm.duration) })
|
|
@@ -3156,7 +3188,7 @@ var init_KeyFormDialog = __esm({
|
|
|
3156
3188
|
});
|
|
3157
3189
|
|
|
3158
3190
|
// src/components/ManageTeamDialog.tsx
|
|
3159
|
-
var import_react7, import_Dialog3, import_DialogTitle3, import_DialogContent3, import_DialogActions3, import_TextField3, import_Button4, import_Alert2, import_Checkbox2, import_FormControlLabel2, import_Autocomplete2, import_CircularProgress3,
|
|
3191
|
+
var import_react7, import_Dialog3, import_DialogTitle3, import_DialogContent3, import_DialogActions3, import_TextField3, import_Button4, import_Alert2, import_Checkbox2, import_FormControlLabel2, import_Autocomplete2, import_CircularProgress3, import_MenuItem3, import_Box10, import_Divider2, import_Typography8, import_IconButton4, import_Tooltip4, import_Paper4, import_Table2, import_TableBody2, import_TableCell2, import_TableContainer2, import_TableHead2, import_TableRow2, import_icons_material5, import_core_plugin_api4, import_plugin_catalog_react, import_catalog_model, import_jsx_runtime11, BUDGET_DURATION_OPTIONS, DEFAULT_BUDGET_DURATION, FALLBACK_BUDGET_CEILING, ManageTeamDialog;
|
|
3160
3192
|
var init_ManageTeamDialog = __esm({
|
|
3161
3193
|
"src/components/ManageTeamDialog.tsx"() {
|
|
3162
3194
|
"use strict";
|
|
@@ -3172,7 +3204,7 @@ var init_ManageTeamDialog = __esm({
|
|
|
3172
3204
|
import_FormControlLabel2 = __toESM(require("@mui/material/FormControlLabel"));
|
|
3173
3205
|
import_Autocomplete2 = __toESM(require("@mui/material/Autocomplete"));
|
|
3174
3206
|
import_CircularProgress3 = __toESM(require("@mui/material/CircularProgress"));
|
|
3175
|
-
|
|
3207
|
+
import_MenuItem3 = __toESM(require("@mui/material/MenuItem"));
|
|
3176
3208
|
import_Box10 = __toESM(require("@mui/material/Box"));
|
|
3177
3209
|
import_Divider2 = __toESM(require("@mui/material/Divider"));
|
|
3178
3210
|
import_Typography8 = __toESM(require("@mui/material/Typography"));
|
|
@@ -3590,7 +3622,7 @@ var init_ManageTeamDialog = __esm({
|
|
|
3590
3622
|
disabled: submitting || unlimited,
|
|
3591
3623
|
helperText: "Spend-reset period for the team budget",
|
|
3592
3624
|
fullWidth: true,
|
|
3593
|
-
children: durationOptions.map((o) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3625
|
+
children: durationOptions.map((o) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_MenuItem3.default, { value: o.value, children: o.label }, o.value))
|
|
3594
3626
|
}
|
|
3595
3627
|
)
|
|
3596
3628
|
]
|
|
@@ -3970,7 +4002,7 @@ function rateTone(rate) {
|
|
|
3970
4002
|
if (rate >= 0.9) return "warning";
|
|
3971
4003
|
return "danger";
|
|
3972
4004
|
}
|
|
3973
|
-
var import_react8, import_Paper5, import_Box11, import_Typography9, import_TextField4,
|
|
4005
|
+
var import_react8, import_Paper5, import_Box11, import_Typography9, import_TextField4, import_MenuItem4, import_Grid, import_Alert3, import_Button5, import_Table3, import_TableBody3, import_TableCell3, import_TableContainer3, import_TableHead3, import_TableRow3, import_Skeleton3, import_recharts, import_jsx_runtime12, TOP_N_MODELS, PERIOD_LS_KEY, PRESET_LABELS, fmtPct, ChartSkeleton, ChartOrFallback, SuccessRateCell, UsageStats;
|
|
3974
4006
|
var init_UsageStats = __esm({
|
|
3975
4007
|
"src/components/UsageStats.tsx"() {
|
|
3976
4008
|
"use strict";
|
|
@@ -3979,7 +4011,7 @@ var init_UsageStats = __esm({
|
|
|
3979
4011
|
import_Box11 = __toESM(require("@mui/material/Box"));
|
|
3980
4012
|
import_Typography9 = __toESM(require("@mui/material/Typography"));
|
|
3981
4013
|
import_TextField4 = __toESM(require("@mui/material/TextField"));
|
|
3982
|
-
|
|
4014
|
+
import_MenuItem4 = __toESM(require("@mui/material/MenuItem"));
|
|
3983
4015
|
import_Grid = __toESM(require("@mui/material/Grid"));
|
|
3984
4016
|
import_Alert3 = __toESM(require("@mui/material/Alert"));
|
|
3985
4017
|
import_Button5 = __toESM(require("@mui/material/Button"));
|
|
@@ -4237,7 +4269,7 @@ var init_UsageStats = __esm({
|
|
|
4237
4269
|
value: currentPreset,
|
|
4238
4270
|
onChange: (e) => handlePresetChange(e.target.value),
|
|
4239
4271
|
sx: { minWidth: 160 },
|
|
4240
|
-
children: Object.keys(PRESET_LABELS).map((p) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4272
|
+
children: Object.keys(PRESET_LABELS).map((p) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_MenuItem4.default, { value: p, children: PRESET_LABELS[p] }, p))
|
|
4241
4273
|
}
|
|
4242
4274
|
);
|
|
4243
4275
|
if (usageError) {
|
|
@@ -4298,8 +4330,8 @@ var init_UsageStats = __esm({
|
|
|
4298
4330
|
onChange: (e) => setSelectedModel(e.target.value),
|
|
4299
4331
|
sx: { minWidth: 220 },
|
|
4300
4332
|
children: [
|
|
4301
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4302
|
-
models.filter((m) => modelsInPeriod.includes(m.model_name)).map((m) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4333
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_MenuItem4.default, { value: "all", children: "All models" }),
|
|
4334
|
+
models.filter((m) => modelsInPeriod.includes(m.model_name)).map((m) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_MenuItem4.default, { value: m.model_name, children: m.model_name }, m.model_name))
|
|
4303
4335
|
]
|
|
4304
4336
|
}
|
|
4305
4337
|
)
|
|
@@ -5079,7 +5111,7 @@ var init_TeamUsage = __esm({
|
|
|
5079
5111
|
}) })
|
|
5080
5112
|
] }) });
|
|
5081
5113
|
};
|
|
5082
|
-
TeamCard = ({ team, usage, usageLoading, memberUsage, memberUsageLoading, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand }) => {
|
|
5114
|
+
TeamCard = ({ team, usage, usageLoading, memberUsage, memberUsageLoading, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand, vectorStores, mcpServers }) => {
|
|
5083
5115
|
const [expanded, setExpanded] = (0, import_react10.useState)(false);
|
|
5084
5116
|
const chart = useChartTheme();
|
|
5085
5117
|
const handleExpandChange = (newExpanded) => {
|
|
@@ -5146,6 +5178,10 @@ var init_TeamUsage = __esm({
|
|
|
5146
5178
|
children: label
|
|
5147
5179
|
}
|
|
5148
5180
|
);
|
|
5181
|
+
const renderNamedTags = (label, ids, items) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
|
|
5182
|
+
sectionLabel(label),
|
|
5183
|
+
ids?.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Box14.default, { display: "flex", gap: 0.5, flexWrap: "wrap", children: ids.map((id) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TagChip, { label: items?.find((i) => i.id === id)?.name ?? id, title: id }, id)) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "body2", color: "text.secondary", children: "None configured" })
|
|
5184
|
+
] });
|
|
5149
5185
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Paper8.default, { variant: "outlined", sx: { borderRadius: 2, p: 2.5 }, children: [
|
|
5150
5186
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { display: "flex", alignItems: "center", gap: 1.5, children: [
|
|
5151
5187
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
@@ -5271,6 +5307,8 @@ var init_TeamUsage = __esm({
|
|
|
5271
5307
|
sectionLabel("Models"),
|
|
5272
5308
|
team.models?.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Box14.default, { display: "flex", gap: 0.5, flexWrap: "wrap", children: team.models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TagChip, { label: m, title: m }, m)) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "body2", color: "text.secondary", children: "All models allowed" })
|
|
5273
5309
|
] }),
|
|
5310
|
+
renderNamedTags("Knowledge bases", team.object_permission?.vector_stores, vectorStores),
|
|
5311
|
+
renderNamedTags("MCP servers", team.object_permission?.mcp_servers, mcpServers),
|
|
5274
5312
|
renderDailySpendSection(),
|
|
5275
5313
|
(memberUsageLoading || memberUsage) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
|
|
5276
5314
|
sectionLabel("Usage by member"),
|
|
@@ -5339,7 +5377,9 @@ var init_TeamUsage = __esm({
|
|
|
5339
5377
|
onTeamExpand,
|
|
5340
5378
|
canManageMembers,
|
|
5341
5379
|
onManageMembers,
|
|
5342
|
-
readOnly
|
|
5380
|
+
readOnly,
|
|
5381
|
+
vectorStores,
|
|
5382
|
+
mcpServers
|
|
5343
5383
|
}) => {
|
|
5344
5384
|
const readOnlyBadge = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Tooltip5.default, { title: "Teams and memberships are managed in your identity provider. Changes made here would be overwritten, so editing is disabled.", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5345
5385
|
import_Box14.default,
|
|
@@ -5397,7 +5437,9 @@ var init_TeamUsage = __esm({
|
|
|
5397
5437
|
onEditTeam,
|
|
5398
5438
|
canManageMembers: canManageMembers?.(team),
|
|
5399
5439
|
onManageMembers,
|
|
5400
|
-
onExpand: onTeamExpand
|
|
5440
|
+
onExpand: onTeamExpand,
|
|
5441
|
+
vectorStores,
|
|
5442
|
+
mcpServers
|
|
5401
5443
|
},
|
|
5402
5444
|
team.team_id
|
|
5403
5445
|
)) })
|
|
@@ -5425,7 +5467,7 @@ function fmtTokens(n) {
|
|
|
5425
5467
|
if (n >= 1e3) return `${(n / 1e3).toFixed(0)}K`;
|
|
5426
5468
|
return String(n);
|
|
5427
5469
|
}
|
|
5428
|
-
var import_react11, import_Box15, import_Table5, import_TableBody5, import_TableCell5, import_TableContainer5, import_TableHead5, import_TableRow5, import_TableSortLabel2, import_Typography13,
|
|
5470
|
+
var import_react11, import_Box15, import_Table5, import_TableBody5, import_TableCell5, import_TableContainer5, import_TableHead5, import_TableRow5, import_TableSortLabel2, import_Typography13, import_MenuItem5, import_Select, import_FormControl, import_InputLabel, import_TextField5, import_InputAdornment3, import_icons_material8, import_ContentCopy, import_Tooltip6, import_Snackbar, import_Alert4, import_styles11, import_jsx_runtime16, ALL_PROXY_MODELS, ModelsTable;
|
|
5429
5471
|
var init_ModelsTable = __esm({
|
|
5430
5472
|
"src/components/ModelsTable.tsx"() {
|
|
5431
5473
|
"use strict";
|
|
@@ -5439,7 +5481,7 @@ var init_ModelsTable = __esm({
|
|
|
5439
5481
|
import_TableRow5 = __toESM(require("@mui/material/TableRow"));
|
|
5440
5482
|
import_TableSortLabel2 = __toESM(require("@mui/material/TableSortLabel"));
|
|
5441
5483
|
import_Typography13 = __toESM(require("@mui/material/Typography"));
|
|
5442
|
-
|
|
5484
|
+
import_MenuItem5 = __toESM(require("@mui/material/MenuItem"));
|
|
5443
5485
|
import_Select = __toESM(require("@mui/material/Select"));
|
|
5444
5486
|
import_FormControl = __toESM(require("@mui/material/FormControl"));
|
|
5445
5487
|
import_InputLabel = __toESM(require("@mui/material/InputLabel"));
|
|
@@ -5557,7 +5599,7 @@ var init_ModelsTable = __esm({
|
|
|
5557
5599
|
value: selectedTeamId,
|
|
5558
5600
|
label: "Team",
|
|
5559
5601
|
onChange: (e) => setSelectedTeamId(e.target.value),
|
|
5560
|
-
children: teams.map((t) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5602
|
+
children: teams.map((t) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_MenuItem5.default, { value: t.team_id, children: t.team_alias ?? t.team_id }, t.team_id))
|
|
5561
5603
|
}
|
|
5562
5604
|
)
|
|
5563
5605
|
] }),
|
|
@@ -6366,12 +6408,12 @@ var init_LiteLLMPage = __esm({
|
|
|
6366
6408
|
const teamMgmtEnabled = liteLlmConfig?.teamManagement?.enabled ?? false;
|
|
6367
6409
|
const objectPermsEnabled = liteLlmConfig?.teamManagement?.objectPermissionsEnabled ?? false;
|
|
6368
6410
|
const { value: vectorStores } = (0, import_react_use2.useAsync)(
|
|
6369
|
-
|
|
6370
|
-
[api
|
|
6411
|
+
() => api.getVectorStores().catch(() => []),
|
|
6412
|
+
[api]
|
|
6371
6413
|
);
|
|
6372
6414
|
const { value: mcpServers } = (0, import_react_use2.useAsync)(
|
|
6373
|
-
|
|
6374
|
-
[api
|
|
6415
|
+
() => api.getMcpServers().catch(() => []),
|
|
6416
|
+
[api]
|
|
6375
6417
|
);
|
|
6376
6418
|
const teams = (0, import_react13.useMemo)(() => {
|
|
6377
6419
|
if (!allTeams?.length) return [];
|
|
@@ -6697,7 +6739,8 @@ var init_LiteLLMPage = __esm({
|
|
|
6697
6739
|
onDeleteKey: handleDeleteKey,
|
|
6698
6740
|
onPruneExpiredKeys: handlePruneExpiredKeys,
|
|
6699
6741
|
filter,
|
|
6700
|
-
onClearFilter: clearFilter
|
|
6742
|
+
onClearFilter: clearFilter,
|
|
6743
|
+
teams: allTeams ?? []
|
|
6701
6744
|
}
|
|
6702
6745
|
);
|
|
6703
6746
|
})(),
|
|
@@ -6728,6 +6771,8 @@ var init_LiteLLMPage = __esm({
|
|
|
6728
6771
|
onEditTeam: (t) => setManageTeam({ mode: "edit", team: t }),
|
|
6729
6772
|
canCreate: teamMgmtEnabled && canCreateTeam && !readOnly,
|
|
6730
6773
|
onCreateTeam: () => setManageTeam({ mode: "create" }),
|
|
6774
|
+
vectorStores: vectorStores ?? [],
|
|
6775
|
+
mcpServers: mcpServers ?? [],
|
|
6731
6776
|
canManageMembers: (t) => teamMgmtEnabled && canManageMembers && isTeamMemberManager(t, userInfo?.user_id, memberManagerRoles, readOnly),
|
|
6732
6777
|
onManageMembers: (t) => setManageTeam({ mode: "members", team: t }),
|
|
6733
6778
|
readOnly,
|
|
@@ -7113,7 +7158,7 @@ var import_Box19 = __toESM(require("@mui/material/Box"));
|
|
|
7113
7158
|
var import_Typography17 = __toESM(require("@mui/material/Typography"));
|
|
7114
7159
|
var import_FormControl2 = __toESM(require("@mui/material/FormControl"));
|
|
7115
7160
|
var import_Select2 = __toESM(require("@mui/material/Select"));
|
|
7116
|
-
var
|
|
7161
|
+
var import_MenuItem6 = __toESM(require("@mui/material/MenuItem"));
|
|
7117
7162
|
var import_Skeleton7 = __toESM(require("@mui/material/Skeleton"));
|
|
7118
7163
|
var import_recharts3 = require("recharts");
|
|
7119
7164
|
var import_core_plugin_api7 = require("@backstage/core-plugin-api");
|
|
@@ -7250,9 +7295,9 @@ var LiteLLMHomeWidget = ({
|
|
|
7250
7295
|
displayEmpty: true,
|
|
7251
7296
|
inputProps: { "aria-label": "Usage period" },
|
|
7252
7297
|
children: [
|
|
7253
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7254
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7255
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7298
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_MenuItem6.default, { value: "today", children: "Today" }),
|
|
7299
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_MenuItem6.default, { value: "7d", children: "7d" }),
|
|
7300
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_MenuItem6.default, { value: "30d", children: "30d" })
|
|
7256
7301
|
]
|
|
7257
7302
|
}
|
|
7258
7303
|
) })
|