@acarmisc/backstage-plugin-litellm 0.18.0 → 0.19.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 +58 -16
- package/dist/index.cjs.js.map +3 -3
- package/dist/index.esm.js +52 -10
- package/dist/index.esm.js.map +3 -3
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -3004,6 +3004,9 @@ import MenuItem4 from "@mui/material/MenuItem";
|
|
|
3004
3004
|
import Select from "@mui/material/Select";
|
|
3005
3005
|
import FormControl from "@mui/material/FormControl";
|
|
3006
3006
|
import InputLabel from "@mui/material/InputLabel";
|
|
3007
|
+
import TextField5 from "@mui/material/TextField";
|
|
3008
|
+
import InputAdornment2 from "@mui/material/InputAdornment";
|
|
3009
|
+
import { Search as Search2 } from "@mui/icons-material";
|
|
3007
3010
|
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
|
3008
3011
|
import Tooltip3 from "@mui/material/Tooltip";
|
|
3009
3012
|
import Snackbar from "@mui/material/Snackbar";
|
|
@@ -3035,15 +3038,23 @@ var init_ModelsTable = __esm({
|
|
|
3035
3038
|
ModelsTable = ({ allModels, teams, loading }) => {
|
|
3036
3039
|
const theme = useTheme2();
|
|
3037
3040
|
const [selectedTeamId, setSelectedTeamId] = useState6("");
|
|
3041
|
+
const [filterText, setFilterText] = useState6("");
|
|
3038
3042
|
const [copiedSnackbar, setCopiedSnackbar] = useState6(false);
|
|
3039
3043
|
const selectedTeam = useMemo6(
|
|
3040
3044
|
() => teams.find((t) => t.team_id === selectedTeamId) ?? null,
|
|
3041
3045
|
[teams, selectedTeamId]
|
|
3042
3046
|
);
|
|
3043
|
-
const
|
|
3047
|
+
const teamModels = useMemo6(() => {
|
|
3044
3048
|
if (!selectedTeam) return [];
|
|
3045
3049
|
return allModels.filter((model) => isModelAllowedByTeam2(model, selectedTeam.models));
|
|
3046
3050
|
}, [allModels, selectedTeam]);
|
|
3051
|
+
const filteredModels = useMemo6(() => {
|
|
3052
|
+
const q = filterText.trim().toLowerCase();
|
|
3053
|
+
if (!q) return teamModels;
|
|
3054
|
+
return teamModels.filter(
|
|
3055
|
+
(model) => model.model_name.toLowerCase().includes(q) || (model.access_groups || []).some((group) => group.toLowerCase().includes(q))
|
|
3056
|
+
);
|
|
3057
|
+
}, [teamModels, filterText]);
|
|
3047
3058
|
const handleCopyModelId = useCallback((modelId) => {
|
|
3048
3059
|
navigator.clipboard.writeText(modelId).then(() => setCopiedSnackbar(true));
|
|
3049
3060
|
}, []);
|
|
@@ -3065,9 +3076,9 @@ var init_ModelsTable = __esm({
|
|
|
3065
3076
|
SectionCard,
|
|
3066
3077
|
{
|
|
3067
3078
|
title: "Available Models",
|
|
3068
|
-
subtitle: selectedTeam ? `${filteredModels.length} model${filteredModels.length
|
|
3079
|
+
subtitle: selectedTeam ? `${filteredModels.length}${filterText.trim() ? ` of ${teamModels.length}` : ""} model${filteredModels.length === 1 ? "" : "s"}` : "Select a team to view its models"
|
|
3069
3080
|
},
|
|
3070
|
-
/* @__PURE__ */ React8.createElement(Box8, { sx: { px: 2.5, pb: 2.5, pt: 1 } }, /* @__PURE__ */ React8.createElement(FormControl, { size: "small", sx: { minWidth: 240, mb: 2 } }, /* @__PURE__ */ React8.createElement(InputLabel, { id: "team-select-label" }, "Team"), /* @__PURE__ */ React8.createElement(
|
|
3081
|
+
/* @__PURE__ */ React8.createElement(Box8, { sx: { px: 2.5, pb: 2.5, pt: 1, display: "flex", gap: 2, flexWrap: "wrap" } }, /* @__PURE__ */ React8.createElement(FormControl, { size: "small", sx: { minWidth: 240, mb: 2 } }, /* @__PURE__ */ React8.createElement(InputLabel, { id: "team-select-label" }, "Team"), /* @__PURE__ */ React8.createElement(
|
|
3071
3082
|
Select,
|
|
3072
3083
|
{
|
|
3073
3084
|
labelId: "team-select-label",
|
|
@@ -3076,7 +3087,20 @@ var init_ModelsTable = __esm({
|
|
|
3076
3087
|
onChange: (e) => setSelectedTeamId(e.target.value)
|
|
3077
3088
|
},
|
|
3078
3089
|
teams.map((t) => /* @__PURE__ */ React8.createElement(MenuItem4, { key: t.team_id, value: t.team_id }, t.team_alias ?? t.team_id))
|
|
3079
|
-
))
|
|
3090
|
+
)), /* @__PURE__ */ React8.createElement(
|
|
3091
|
+
TextField5,
|
|
3092
|
+
{
|
|
3093
|
+
label: "Filter Models",
|
|
3094
|
+
size: "small",
|
|
3095
|
+
value: filterText,
|
|
3096
|
+
onChange: (e) => setFilterText(e.target.value),
|
|
3097
|
+
disabled: !selectedTeamId,
|
|
3098
|
+
sx: { minWidth: 240, mb: 2 },
|
|
3099
|
+
InputProps: {
|
|
3100
|
+
startAdornment: /* @__PURE__ */ React8.createElement(InputAdornment2, { position: "start" }, /* @__PURE__ */ React8.createElement(Search2, { fontSize: "small" }))
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
)),
|
|
3080
3104
|
loading && /* @__PURE__ */ React8.createElement(EmptyState, { message: "Loading models\u2026" }),
|
|
3081
3105
|
!loading && !selectedTeamId && /* @__PURE__ */ React8.createElement(
|
|
3082
3106
|
EmptyState,
|
|
@@ -3085,14 +3109,32 @@ var init_ModelsTable = __esm({
|
|
|
3085
3109
|
hint: "Each team may have a different set of models assigned"
|
|
3086
3110
|
}
|
|
3087
3111
|
),
|
|
3088
|
-
!loading && selectedTeamId &&
|
|
3112
|
+
!loading && selectedTeamId && teamModels.length === 0 && /* @__PURE__ */ React8.createElement(
|
|
3089
3113
|
EmptyState,
|
|
3090
3114
|
{
|
|
3091
3115
|
message: "No models available for this team",
|
|
3092
3116
|
hint: allModels.length === 0 ? "No models are configured in the system" : "None of the team's assigned models were found in the catalog"
|
|
3093
3117
|
}
|
|
3094
3118
|
),
|
|
3095
|
-
!loading &&
|
|
3119
|
+
!loading && selectedTeamId && teamModels.length > 0 && filteredModels.length === 0 && /* @__PURE__ */ React8.createElement(
|
|
3120
|
+
EmptyState,
|
|
3121
|
+
{
|
|
3122
|
+
message: "No models match your search",
|
|
3123
|
+
hint: "Try a different search term"
|
|
3124
|
+
}
|
|
3125
|
+
),
|
|
3126
|
+
!loading && filteredModels.length > 0 && /* @__PURE__ */ React8.createElement(TableContainer5, null, /* @__PURE__ */ React8.createElement(Table5, { size: "small", sx: dataTableSx }, /* @__PURE__ */ React8.createElement(TableHead5, null, /* @__PURE__ */ React8.createElement(TableRow5, null, /* @__PURE__ */ React8.createElement(TableCell5, null, "Model ID"), /* @__PURE__ */ React8.createElement(TableCell5, null, "Mode"), /* @__PURE__ */ React8.createElement(TableCell5, { align: "right" }, "Input Cost"), /* @__PURE__ */ React8.createElement(TableCell5, { align: "right" }, "Output Cost"), /* @__PURE__ */ React8.createElement(TableCell5, { align: "right" }, "Max Input"), /* @__PURE__ */ React8.createElement(TableCell5, { align: "right" }, "Max Output"), /* @__PURE__ */ React8.createElement(TableCell5, null, "Capabilities"))), /* @__PURE__ */ React8.createElement(TableBody5, null, filteredModels.map((m) => /* @__PURE__ */ React8.createElement(TableRow5, { key: m.model_name, hover: true }, /* @__PURE__ */ React8.createElement(TableCell5, null, /* @__PURE__ */ React8.createElement(Box8, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React8.createElement(Tooltip3, { title: m.model_name, placement: "top" }, /* @__PURE__ */ React8.createElement(
|
|
3127
|
+
"span",
|
|
3128
|
+
{
|
|
3129
|
+
role: "button",
|
|
3130
|
+
tabIndex: 0,
|
|
3131
|
+
"aria-label": "Copy model ID",
|
|
3132
|
+
onClick: () => handleCopyModelId(m.model_name),
|
|
3133
|
+
onKeyDown: (e) => e.key === "Enter" && handleCopyModelId(m.model_name),
|
|
3134
|
+
style: { cursor: "pointer", display: "inline-flex" }
|
|
3135
|
+
},
|
|
3136
|
+
/* @__PURE__ */ React8.createElement(TagChip, { label: m.model_name, title: "Copy model ID" })
|
|
3137
|
+
)), /* @__PURE__ */ React8.createElement(Tooltip3, { title: "Copy model ID" }, /* @__PURE__ */ React8.createElement(
|
|
3096
3138
|
Box8,
|
|
3097
3139
|
{
|
|
3098
3140
|
component: "span",
|
|
@@ -3148,7 +3190,7 @@ import TableContainer6 from "@mui/material/TableContainer";
|
|
|
3148
3190
|
import TableHead6 from "@mui/material/TableHead";
|
|
3149
3191
|
import TableRow6 from "@mui/material/TableRow";
|
|
3150
3192
|
import TablePagination from "@mui/material/TablePagination";
|
|
3151
|
-
import
|
|
3193
|
+
import TextField6 from "@mui/material/TextField";
|
|
3152
3194
|
import MenuItem5 from "@mui/material/MenuItem";
|
|
3153
3195
|
import Skeleton5 from "@mui/material/Skeleton";
|
|
3154
3196
|
import Collapse2 from "@mui/material/Collapse";
|
|
@@ -3294,7 +3336,7 @@ var init_AuditLog = __esm({
|
|
|
3294
3336
|
subtitle: loading ? "Loading\u2026" : `${total.toLocaleString()} event${total === 1 ? "" : "s"}`,
|
|
3295
3337
|
flush: true,
|
|
3296
3338
|
actions: /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement(
|
|
3297
|
-
|
|
3339
|
+
TextField6,
|
|
3298
3340
|
{
|
|
3299
3341
|
size: "small",
|
|
3300
3342
|
label: "Action",
|
|
@@ -3312,7 +3354,7 @@ var init_AuditLog = __esm({
|
|
|
3312
3354
|
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "deleted" }, "Deleted"),
|
|
3313
3355
|
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "blocked" }, "Blocked")
|
|
3314
3356
|
), /* @__PURE__ */ React9.createElement(
|
|
3315
|
-
|
|
3357
|
+
TextField6,
|
|
3316
3358
|
{
|
|
3317
3359
|
size: "small",
|
|
3318
3360
|
label: "Table",
|
|
@@ -3331,7 +3373,7 @@ var init_AuditLog = __esm({
|
|
|
3331
3373
|
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "LiteLLM_ObjectPermissionTable" }, "Team access (KB / MCP)"),
|
|
3332
3374
|
/* @__PURE__ */ React9.createElement(MenuItem5, { value: "LiteLLM_UserTable" }, "User")
|
|
3333
3375
|
), /* @__PURE__ */ React9.createElement(
|
|
3334
|
-
|
|
3376
|
+
TextField6,
|
|
3335
3377
|
{
|
|
3336
3378
|
size: "small",
|
|
3337
3379
|
label: "Changed by",
|