@acarmisc/backstage-plugin-litellm 0.21.2 → 0.22.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 +60 -9
- package/dist/index.cjs.js.map +3 -3
- package/dist/index.esm.js +73 -22
- package/dist/index.esm.js.map +3 -3
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -3393,6 +3393,7 @@ import TableCell5 from "@mui/material/TableCell";
|
|
|
3393
3393
|
import TableContainer5 from "@mui/material/TableContainer";
|
|
3394
3394
|
import TableHead5 from "@mui/material/TableHead";
|
|
3395
3395
|
import TableRow5 from "@mui/material/TableRow";
|
|
3396
|
+
import TableSortLabel2 from "@mui/material/TableSortLabel";
|
|
3396
3397
|
import Typography9 from "@mui/material/Typography";
|
|
3397
3398
|
import MenuItem4 from "@mui/material/MenuItem";
|
|
3398
3399
|
import Select from "@mui/material/Select";
|
|
@@ -3434,6 +3435,8 @@ var init_ModelsTable = __esm({
|
|
|
3434
3435
|
const [selectedTeamId, setSelectedTeamId] = useState7("");
|
|
3435
3436
|
const [filterText, setFilterText] = useState7("");
|
|
3436
3437
|
const [copiedSnackbar, setCopiedSnackbar] = useState7(false);
|
|
3438
|
+
const [sortKey, setSortKey] = useState7("model_name");
|
|
3439
|
+
const [sortDirection, setSortDirection] = useState7("asc");
|
|
3437
3440
|
const selectedTeam = useMemo7(
|
|
3438
3441
|
() => teams.find((t) => t.team_id === selectedTeamId) ?? null,
|
|
3439
3442
|
[teams, selectedTeamId]
|
|
@@ -3444,14 +3447,62 @@ var init_ModelsTable = __esm({
|
|
|
3444
3447
|
}, [allModels, selectedTeam]);
|
|
3445
3448
|
const filteredModels = useMemo7(() => {
|
|
3446
3449
|
const q = filterText.trim().toLowerCase();
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3450
|
+
let models = teamModels;
|
|
3451
|
+
if (q) {
|
|
3452
|
+
models = teamModels.filter(
|
|
3453
|
+
(model) => model.model_name.toLowerCase().includes(q) || (model.access_groups || []).some((group) => group.toLowerCase().includes(q))
|
|
3454
|
+
);
|
|
3455
|
+
}
|
|
3456
|
+
return [...models].sort((a, b) => {
|
|
3457
|
+
let aVal;
|
|
3458
|
+
let bVal;
|
|
3459
|
+
switch (sortKey) {
|
|
3460
|
+
case "model_name":
|
|
3461
|
+
aVal = a.model_name;
|
|
3462
|
+
bVal = b.model_name;
|
|
3463
|
+
break;
|
|
3464
|
+
case "mode":
|
|
3465
|
+
aVal = a.mode;
|
|
3466
|
+
bVal = b.mode;
|
|
3467
|
+
break;
|
|
3468
|
+
case "input_cost_per_token":
|
|
3469
|
+
aVal = a.input_cost_per_token ?? 0;
|
|
3470
|
+
bVal = b.input_cost_per_token ?? 0;
|
|
3471
|
+
break;
|
|
3472
|
+
case "output_cost_per_token":
|
|
3473
|
+
aVal = a.output_cost_per_token ?? 0;
|
|
3474
|
+
bVal = b.output_cost_per_token ?? 0;
|
|
3475
|
+
break;
|
|
3476
|
+
case "max_input_tokens":
|
|
3477
|
+
aVal = a.max_input_tokens ?? 0;
|
|
3478
|
+
bVal = b.max_input_tokens ?? 0;
|
|
3479
|
+
break;
|
|
3480
|
+
case "max_output_tokens":
|
|
3481
|
+
aVal = a.max_output_tokens ?? 0;
|
|
3482
|
+
bVal = b.max_output_tokens ?? 0;
|
|
3483
|
+
break;
|
|
3484
|
+
default:
|
|
3485
|
+
return 0;
|
|
3486
|
+
}
|
|
3487
|
+
if (aVal === void 0 || aVal === null) aVal = "";
|
|
3488
|
+
if (bVal === void 0 || bVal === null) bVal = "";
|
|
3489
|
+
if (typeof aVal === "string" && typeof bVal === "string") {
|
|
3490
|
+
return sortDirection === "asc" ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
|
|
3491
|
+
}
|
|
3492
|
+
return sortDirection === "asc" ? aVal - bVal : bVal - aVal;
|
|
3493
|
+
});
|
|
3494
|
+
}, [teamModels, filterText, sortKey, sortDirection]);
|
|
3452
3495
|
const handleCopyModelId = useCallback((modelId) => {
|
|
3453
3496
|
navigator.clipboard.writeText(modelId).then(() => setCopiedSnackbar(true));
|
|
3454
3497
|
}, []);
|
|
3498
|
+
const handleSort = useCallback((key) => {
|
|
3499
|
+
if (sortKey === key) {
|
|
3500
|
+
setSortDirection((prev) => prev === "asc" ? "desc" : "asc");
|
|
3501
|
+
} else {
|
|
3502
|
+
setSortKey(key);
|
|
3503
|
+
setSortDirection("asc");
|
|
3504
|
+
}
|
|
3505
|
+
}, [sortKey]);
|
|
3455
3506
|
const modeColor = (mode) => {
|
|
3456
3507
|
switch (mode) {
|
|
3457
3508
|
case "chat":
|
|
@@ -3517,7 +3568,7 @@ var init_ModelsTable = __esm({
|
|
|
3517
3568
|
hint: "Try a different search term"
|
|
3518
3569
|
}
|
|
3519
3570
|
),
|
|
3520
|
-
!loading && filteredModels.length > 0 && /* @__PURE__ */ React9.createElement(TableContainer5, null, /* @__PURE__ */ React9.createElement(Table5, { size: "small", sx: dataTableSx }, /* @__PURE__ */ React9.createElement(TableHead5, null, /* @__PURE__ */ React9.createElement(TableRow5, null, /* @__PURE__ */ React9.createElement(TableCell5,
|
|
3571
|
+
!loading && filteredModels.length > 0 && /* @__PURE__ */ React9.createElement(TableContainer5, null, /* @__PURE__ */ React9.createElement(Table5, { size: "small", sx: dataTableSx }, /* @__PURE__ */ React9.createElement(TableHead5, null, /* @__PURE__ */ React9.createElement(TableRow5, null, /* @__PURE__ */ React9.createElement(TableCell5, { sortDirection: sortKey === "model_name" ? sortDirection : false }, /* @__PURE__ */ React9.createElement(TableSortLabel2, { active: sortKey === "model_name", direction: sortKey === "model_name" ? sortDirection : "asc", onClick: () => handleSort("model_name") }, "Model ID")), /* @__PURE__ */ React9.createElement(TableCell5, { sortDirection: sortKey === "mode" ? sortDirection : false }, /* @__PURE__ */ React9.createElement(TableSortLabel2, { active: sortKey === "mode", direction: sortKey === "mode" ? sortDirection : "asc", onClick: () => handleSort("mode") }, "Mode")), /* @__PURE__ */ React9.createElement(TableCell5, { align: "right", sortDirection: sortKey === "input_cost_per_token" ? sortDirection : false }, /* @__PURE__ */ React9.createElement(TableSortLabel2, { active: sortKey === "input_cost_per_token", direction: sortKey === "input_cost_per_token" ? sortDirection : "asc", onClick: () => handleSort("input_cost_per_token") }, "Input Cost")), /* @__PURE__ */ React9.createElement(TableCell5, { align: "right", sortDirection: sortKey === "output_cost_per_token" ? sortDirection : false }, /* @__PURE__ */ React9.createElement(TableSortLabel2, { active: sortKey === "output_cost_per_token", direction: sortKey === "output_cost_per_token" ? sortDirection : "asc", onClick: () => handleSort("output_cost_per_token") }, "Output Cost")), /* @__PURE__ */ React9.createElement(TableCell5, { align: "right", sortDirection: sortKey === "max_input_tokens" ? sortDirection : false }, /* @__PURE__ */ React9.createElement(TableSortLabel2, { active: sortKey === "max_input_tokens", direction: sortKey === "max_input_tokens" ? sortDirection : "asc", onClick: () => handleSort("max_input_tokens") }, "Max Input")), /* @__PURE__ */ React9.createElement(TableCell5, { align: "right", sortDirection: sortKey === "max_output_tokens" ? sortDirection : false }, /* @__PURE__ */ React9.createElement(TableSortLabel2, { active: sortKey === "max_output_tokens", direction: sortKey === "max_output_tokens" ? sortDirection : "asc", onClick: () => handleSort("max_output_tokens") }, "Max Output")), /* @__PURE__ */ React9.createElement(TableCell5, null, "Capabilities"))), /* @__PURE__ */ React9.createElement(TableBody5, null, filteredModels.map((m) => /* @__PURE__ */ React9.createElement(TableRow5, { key: m.model_name, hover: true }, /* @__PURE__ */ React9.createElement(TableCell5, null, /* @__PURE__ */ React9.createElement(Box9, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React9.createElement(Tooltip3, { title: m.model_name, placement: "top" }, /* @__PURE__ */ React9.createElement(
|
|
3521
3572
|
"span",
|
|
3522
3573
|
{
|
|
3523
3574
|
role: "button",
|
|
@@ -3574,7 +3625,7 @@ var init_ModelsTable = __esm({
|
|
|
3574
3625
|
});
|
|
3575
3626
|
|
|
3576
3627
|
// src/components/AuditLog.tsx
|
|
3577
|
-
import React10, { useState as useState8,
|
|
3628
|
+
import React10, { useState as useState8, useMemo as useMemo8 } from "react";
|
|
3578
3629
|
import Box10 from "@mui/material/Box";
|
|
3579
3630
|
import Typography10 from "@mui/material/Typography";
|
|
3580
3631
|
import Table6 from "@mui/material/Table";
|
|
@@ -3713,10 +3764,10 @@ var init_AuditLog = __esm({
|
|
|
3713
3764
|
const [page, setPage] = useState8(0);
|
|
3714
3765
|
const [pageSize, setPageSize] = useState8(25);
|
|
3715
3766
|
const [filters, setFilters] = useState8({});
|
|
3716
|
-
const fetchParams =
|
|
3767
|
+
const fetchParams = useMemo8(
|
|
3717
3768
|
() => ({ page: page + 1, page_size: pageSize, ...filters }),
|
|
3718
3769
|
[page, pageSize, filters]
|
|
3719
|
-
)
|
|
3770
|
+
);
|
|
3720
3771
|
const { value, loading, error } = useAsync2(
|
|
3721
3772
|
() => api.getAuditLogs(fetchParams),
|
|
3722
3773
|
[api, fetchParams]
|
|
@@ -3837,7 +3888,7 @@ var LiteLLMPage_exports = {};
|
|
|
3837
3888
|
__export(LiteLLMPage_exports, {
|
|
3838
3889
|
LiteLLMPage: () => LiteLLMPage
|
|
3839
3890
|
});
|
|
3840
|
-
import React11, { useState as useState9, useCallback as
|
|
3891
|
+
import React11, { useState as useState9, useCallback as useCallback2, useMemo as useMemo9 } from "react";
|
|
3841
3892
|
import Box11 from "@mui/material/Box";
|
|
3842
3893
|
import Snackbar2 from "@mui/material/Snackbar";
|
|
3843
3894
|
import Alert6 from "@mui/material/Alert";
|
|
@@ -3898,7 +3949,7 @@ var init_LiteLLMPage = __esm({
|
|
|
3898
3949
|
const t = searchParams.get("tab");
|
|
3899
3950
|
return isPageTab(t) ? t : "overview";
|
|
3900
3951
|
});
|
|
3901
|
-
const selectTab =
|
|
3952
|
+
const selectTab = useCallback2(
|
|
3902
3953
|
(tab) => {
|
|
3903
3954
|
setActiveTab(tab);
|
|
3904
3955
|
setSearchParams(
|
|
@@ -3960,7 +4011,7 @@ var init_LiteLLMPage = __esm({
|
|
|
3960
4011
|
async () => objectPermsEnabled ? api.getMcpServers().catch(() => []) : [],
|
|
3961
4012
|
[api, objectPermsEnabled]
|
|
3962
4013
|
);
|
|
3963
|
-
const teams =
|
|
4014
|
+
const teams = useMemo9(() => {
|
|
3964
4015
|
if (!allTeams?.length) return [];
|
|
3965
4016
|
if (!userInfo) return allTeams;
|
|
3966
4017
|
const userId = userInfo.user_id;
|
|
@@ -3977,7 +4028,7 @@ var init_LiteLLMPage = __esm({
|
|
|
3977
4028
|
const endDate = dateRange.end.toISOString().split("T")[0];
|
|
3978
4029
|
return api.getUsage(startDate, endDate);
|
|
3979
4030
|
}, [api, dateRange]);
|
|
3980
|
-
const handleDateRangeChange =
|
|
4031
|
+
const handleDateRangeChange = useCallback2((range, preset) => {
|
|
3981
4032
|
setDateRange(range);
|
|
3982
4033
|
if (preset) {
|
|
3983
4034
|
setCurrentPreset(preset);
|
|
@@ -3985,7 +4036,7 @@ var init_LiteLLMPage = __esm({
|
|
|
3985
4036
|
setTeamUsageCache({});
|
|
3986
4037
|
setTeamUsageLoading({});
|
|
3987
4038
|
}, [setDateRange, setCurrentPreset]);
|
|
3988
|
-
const loadTeamUsage =
|
|
4039
|
+
const loadTeamUsage = useCallback2(async (teamId) => {
|
|
3989
4040
|
if (teamUsageCache[teamId] !== void 0 || teamUsageLoading[teamId]) return;
|
|
3990
4041
|
setTeamUsageLoading((prev) => ({ ...prev, [teamId]: true }));
|
|
3991
4042
|
try {
|
|
@@ -3999,7 +4050,7 @@ var init_LiteLLMPage = __esm({
|
|
|
3999
4050
|
setTeamUsageLoading((prev) => ({ ...prev, [teamId]: false }));
|
|
4000
4051
|
}
|
|
4001
4052
|
}, [api, dateRange, teamUsageCache, teamUsageLoading]);
|
|
4002
|
-
const allowedModels =
|
|
4053
|
+
const allowedModels = useMemo9(() => {
|
|
4003
4054
|
if (!allModels?.length) return [];
|
|
4004
4055
|
const userModels = userInfo?.models;
|
|
4005
4056
|
const teamModels = teams?.flatMap((t) => t.models ?? []);
|
|
@@ -4012,7 +4063,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4012
4063
|
]);
|
|
4013
4064
|
return allModels.filter((m) => allowed.has(m.model_name));
|
|
4014
4065
|
}, [allModels, userInfo, teams]);
|
|
4015
|
-
const handleGenerateKey =
|
|
4066
|
+
const handleGenerateKey = useCallback2(
|
|
4016
4067
|
async (request) => {
|
|
4017
4068
|
try {
|
|
4018
4069
|
const response = await api.generateKey(request);
|
|
@@ -4026,7 +4077,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4026
4077
|
},
|
|
4027
4078
|
[api, refreshKeys]
|
|
4028
4079
|
);
|
|
4029
|
-
const handleUpdateKey =
|
|
4080
|
+
const handleUpdateKey = useCallback2(
|
|
4030
4081
|
async (keyId, request) => {
|
|
4031
4082
|
try {
|
|
4032
4083
|
await api.updateKey(keyId, request);
|
|
@@ -4039,7 +4090,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4039
4090
|
},
|
|
4040
4091
|
[api, refreshKeys]
|
|
4041
4092
|
);
|
|
4042
|
-
const handleBlockKey =
|
|
4093
|
+
const handleBlockKey = useCallback2(
|
|
4043
4094
|
async (keyId) => {
|
|
4044
4095
|
try {
|
|
4045
4096
|
await api.blockKey(keyId);
|
|
@@ -4051,7 +4102,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4051
4102
|
},
|
|
4052
4103
|
[api, refreshKeys]
|
|
4053
4104
|
);
|
|
4054
|
-
const handleUnblockKey =
|
|
4105
|
+
const handleUnblockKey = useCallback2(
|
|
4055
4106
|
async (keyId) => {
|
|
4056
4107
|
try {
|
|
4057
4108
|
await api.unblockKey(keyId);
|
|
@@ -4063,7 +4114,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4063
4114
|
},
|
|
4064
4115
|
[api, refreshKeys]
|
|
4065
4116
|
);
|
|
4066
|
-
const handleResetKeySpend =
|
|
4117
|
+
const handleResetKeySpend = useCallback2(
|
|
4067
4118
|
async (keyId) => {
|
|
4068
4119
|
try {
|
|
4069
4120
|
await api.resetKeySpend(keyId);
|
|
@@ -4075,7 +4126,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4075
4126
|
},
|
|
4076
4127
|
[api, refreshKeys]
|
|
4077
4128
|
);
|
|
4078
|
-
const handleDeleteKey =
|
|
4129
|
+
const handleDeleteKey = useCallback2(
|
|
4079
4130
|
async (keyId) => {
|
|
4080
4131
|
try {
|
|
4081
4132
|
await api.deleteKey(keyId);
|
|
@@ -4092,7 +4143,7 @@ var init_LiteLLMPage = __esm({
|
|
|
4092
4143
|
},
|
|
4093
4144
|
[api, refreshKeys]
|
|
4094
4145
|
);
|
|
4095
|
-
const handlePruneExpiredKeys =
|
|
4146
|
+
const handlePruneExpiredKeys = useCallback2(
|
|
4096
4147
|
async () => {
|
|
4097
4148
|
try {
|
|
4098
4149
|
const result = await api.pruneExpiredKeys();
|