@acarmisc/backstage-plugin-litellm 0.42.0 → 0.44.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/api.d.ts +13 -1
- package/dist/components/ManageTeamDialog.d.ts +4 -0
- package/dist/components/TeamUsage.d.ts +11 -1
- package/dist/index.cjs.js +96 -7
- package/dist/index.cjs.js.map +2 -2
- package/dist/index.esm.js +96 -7
- package/dist/index.esm.js.map +2 -2
- package/dist/types.d.ts +1 -1
- package/package.json +2 -2
package/dist/index.esm.js
CHANGED
|
@@ -265,6 +265,10 @@ var init_api = __esm({
|
|
|
265
265
|
async getVectorStores() {
|
|
266
266
|
return this.get("/vector-stores");
|
|
267
267
|
}
|
|
268
|
+
// Names only, readable by any signed-in user; never used for the picker.
|
|
269
|
+
async getObjectNames() {
|
|
270
|
+
return this.get("/object-names");
|
|
271
|
+
}
|
|
268
272
|
async setTeamKnowledgeBases(teamId, vectorStores) {
|
|
269
273
|
return this.put(
|
|
270
274
|
`/teams/${encodeURIComponent(teamId)}/knowledge-bases`,
|
|
@@ -295,6 +299,12 @@ var init_api = __esm({
|
|
|
295
299
|
end_date: endDate
|
|
296
300
|
});
|
|
297
301
|
}
|
|
302
|
+
async getTeamKeyUsage(teamId, startDate, endDate) {
|
|
303
|
+
return this.get(`/teams/${encodeURIComponent(teamId)}/usage/keys`, {
|
|
304
|
+
start_date: startDate,
|
|
305
|
+
end_date: endDate
|
|
306
|
+
});
|
|
307
|
+
}
|
|
298
308
|
async getSpendLogs(params) {
|
|
299
309
|
const strParams = {
|
|
300
310
|
start_date: params.startDate,
|
|
@@ -3225,9 +3235,11 @@ var init_ManageTeamDialog = __esm({
|
|
|
3225
3235
|
onRemoveMember,
|
|
3226
3236
|
canManageKnowledgeBases,
|
|
3227
3237
|
vectorStores,
|
|
3238
|
+
vectorStoreNames,
|
|
3228
3239
|
onSaveKnowledgeBases,
|
|
3229
3240
|
canManageMcpServers,
|
|
3230
3241
|
mcpServers,
|
|
3242
|
+
mcpServerNames,
|
|
3231
3243
|
onSaveMcpServers,
|
|
3232
3244
|
membersOnly,
|
|
3233
3245
|
currentUserId,
|
|
@@ -3496,10 +3508,10 @@ var init_ManageTeamDialog = __esm({
|
|
|
3496
3508
|
const durationOptions = BUDGET_DURATION_OPTIONS.some((o) => o.value === budgetDuration) ? BUDGET_DURATION_OPTIONS : [...BUDGET_DURATION_OPTIONS, { value: budgetDuration, label: budgetDuration }];
|
|
3497
3509
|
const showKnowledgeBases = mode === "edit" && !!canManageKnowledgeBases;
|
|
3498
3510
|
const kbOptions = (vectorStores ?? []).map((v) => v.id);
|
|
3499
|
-
const kbLabel = (id) => (
|
|
3511
|
+
const kbLabel = (id) => (vectorStoreNames ?? []).find((v) => v.id === id)?.name ?? id;
|
|
3500
3512
|
const showMcpServers = mode === "edit" && !!canManageMcpServers;
|
|
3501
3513
|
const mcpOptions = (mcpServers ?? []).map((s) => s.id);
|
|
3502
|
-
const mcpLabel = (id) => (
|
|
3514
|
+
const mcpLabel = (id) => (mcpServerNames ?? []).find((s) => s.id === id)?.name ?? id;
|
|
3503
3515
|
const isRemovalDisabled = (memberUserId, memberRole) => {
|
|
3504
3516
|
if (!membersOnly) return { disabled: false };
|
|
3505
3517
|
if (memberUserId === currentUserId) {
|
|
@@ -5072,7 +5084,7 @@ function budgetStatValue(hidden, budget) {
|
|
|
5072
5084
|
if (budget > 0) return fmtUsd2(budget);
|
|
5073
5085
|
return "Unlimited";
|
|
5074
5086
|
}
|
|
5075
|
-
var fmtUsd2, monoSx, MemberUsageTable, TeamCard, TeamUsage;
|
|
5087
|
+
var fmtUsd2, monoSx, MemberUsageTable, TeamKeyUsageTable, TeamCard, TeamUsage;
|
|
5076
5088
|
var init_TeamUsage = __esm({
|
|
5077
5089
|
"src/components/TeamUsage.tsx"() {
|
|
5078
5090
|
"use strict";
|
|
@@ -5114,7 +5126,47 @@ var init_TeamUsage = __esm({
|
|
|
5114
5126
|
}) })
|
|
5115
5127
|
] }) });
|
|
5116
5128
|
};
|
|
5117
|
-
|
|
5129
|
+
TeamKeyUsageTable = ({ usage }) => {
|
|
5130
|
+
const hidden = usage.budget_hidden === true;
|
|
5131
|
+
if (!usage.keys.length) {
|
|
5132
|
+
return /* @__PURE__ */ jsx15(Typography12, { variant: "body2", color: "text.secondary", children: "This team has no keys." });
|
|
5133
|
+
}
|
|
5134
|
+
return /* @__PURE__ */ jsx15(TableContainer4, { component: Paper8, variant: "outlined", sx: { borderRadius: 1.5 }, children: /* @__PURE__ */ jsxs14(Table4, { size: "small", sx: dataTableSx, "aria-label": "Keys by member", children: [
|
|
5135
|
+
/* @__PURE__ */ jsx15(TableHead4, { children: /* @__PURE__ */ jsxs14(TableRow4, { children: [
|
|
5136
|
+
/* @__PURE__ */ jsx15(TableCell4, { children: "Key" }),
|
|
5137
|
+
/* @__PURE__ */ jsx15(TableCell4, { children: "Owner" }),
|
|
5138
|
+
/* @__PURE__ */ jsx15(TableCell4, { children: "Created" }),
|
|
5139
|
+
/* @__PURE__ */ jsx15(TableCell4, { children: "Status" }),
|
|
5140
|
+
!hidden && /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Spend" }),
|
|
5141
|
+
!hidden && /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Budget" }),
|
|
5142
|
+
/* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Tokens" }),
|
|
5143
|
+
/* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Requests" })
|
|
5144
|
+
] }) }),
|
|
5145
|
+
/* @__PURE__ */ jsx15(TableBody4, { children: usage.keys.map((k) => {
|
|
5146
|
+
const owner = k.display_name ?? k.user_email ?? k.user_id;
|
|
5147
|
+
return /* @__PURE__ */ jsxs14(TableRow4, { children: [
|
|
5148
|
+
/* @__PURE__ */ jsxs14(TableCell4, { children: [
|
|
5149
|
+
/* @__PURE__ */ jsx15(Typography12, { variant: "body2", children: k.key_alias ?? k.key }),
|
|
5150
|
+
k.key_alias && /* @__PURE__ */ jsx15(Typography12, { variant: "caption", color: "text.secondary", sx: monoSx, children: k.key })
|
|
5151
|
+
] }),
|
|
5152
|
+
/* @__PURE__ */ jsx15(TableCell4, { children: owner ?? /* @__PURE__ */ jsx15(Typography12, { variant: "body2", color: "text.secondary", children: "\u2014" }) }),
|
|
5153
|
+
/* @__PURE__ */ jsx15(TableCell4, { children: fmtDateShort(k.created_at) }),
|
|
5154
|
+
/* @__PURE__ */ jsx15(TableCell4, { children: /* @__PURE__ */ jsx15(
|
|
5155
|
+
StatusPill,
|
|
5156
|
+
{
|
|
5157
|
+
label: k.blocked ? "Blocked" : "Active",
|
|
5158
|
+
tone: k.blocked ? "danger" : "success"
|
|
5159
|
+
}
|
|
5160
|
+
) }),
|
|
5161
|
+
!hidden && /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: fmtUsd2(k.spend) }),
|
|
5162
|
+
!hidden && /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: k.max_budget === void 0 ? "Unlimited" : fmtUsd2(k.max_budget) }),
|
|
5163
|
+
/* @__PURE__ */ jsx15(TableCell4, { align: "right", children: fmtCompact(k.total_tokens) }),
|
|
5164
|
+
/* @__PURE__ */ jsx15(TableCell4, { align: "right", children: k.api_requests.toLocaleString() })
|
|
5165
|
+
] }, k.key);
|
|
5166
|
+
}) })
|
|
5167
|
+
] }) });
|
|
5168
|
+
};
|
|
5169
|
+
TeamCard = ({ team, usage, usageLoading, memberUsage, memberUsageLoading, keyUsage, keyUsageLoading, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand, vectorStores, mcpServers }) => {
|
|
5118
5170
|
const [expanded, setExpanded] = useState9(false);
|
|
5119
5171
|
const chart = useChartTheme();
|
|
5120
5172
|
const handleExpandChange = (newExpanded) => {
|
|
@@ -5317,6 +5369,10 @@ var init_TeamUsage = __esm({
|
|
|
5317
5369
|
sectionLabel("Usage by member"),
|
|
5318
5370
|
memberUsage ? /* @__PURE__ */ jsx15(MemberUsageTable, { usage: memberUsage }) : /* @__PURE__ */ jsx15(Box14, { display: "flex", justifyContent: "center", py: 2, children: /* @__PURE__ */ jsx15(CircularProgress4, { size: 22 }) })
|
|
5319
5371
|
] }),
|
|
5372
|
+
(keyUsageLoading || keyUsage) && /* @__PURE__ */ jsxs14(Box14, { mb: 2.5, children: [
|
|
5373
|
+
sectionLabel("Keys by member"),
|
|
5374
|
+
keyUsage ? /* @__PURE__ */ jsx15(TeamKeyUsageTable, { usage: keyUsage }) : /* @__PURE__ */ jsx15(Box14, { display: "flex", justifyContent: "center", py: 2, children: /* @__PURE__ */ jsx15(CircularProgress4, { size: 22 }) })
|
|
5375
|
+
] }),
|
|
5320
5376
|
/* @__PURE__ */ jsxs14(Box14, { children: [
|
|
5321
5377
|
sectionLabel("Members"),
|
|
5322
5378
|
team.members_with_roles?.length ? /* @__PURE__ */ jsx15(
|
|
@@ -5373,6 +5429,8 @@ var init_TeamUsage = __esm({
|
|
|
5373
5429
|
getTeamUsageLoading,
|
|
5374
5430
|
getTeamMemberUsage,
|
|
5375
5431
|
getTeamMemberUsageLoading,
|
|
5432
|
+
getTeamKeyUsage,
|
|
5433
|
+
getTeamKeyUsageLoading,
|
|
5376
5434
|
canManage,
|
|
5377
5435
|
onEditTeam,
|
|
5378
5436
|
canCreate,
|
|
@@ -5436,6 +5494,8 @@ var init_TeamUsage = __esm({
|
|
|
5436
5494
|
usageLoading: getTeamUsageLoading(team.team_id),
|
|
5437
5495
|
memberUsage: getTeamMemberUsage?.(team.team_id) ?? null,
|
|
5438
5496
|
memberUsageLoading: getTeamMemberUsageLoading?.(team.team_id) ?? false,
|
|
5497
|
+
keyUsage: getTeamKeyUsage?.(team.team_id) ?? null,
|
|
5498
|
+
keyUsageLoading: getTeamKeyUsageLoading?.(team.team_id) ?? false,
|
|
5439
5499
|
canManage,
|
|
5440
5500
|
onEditTeam,
|
|
5441
5501
|
canManageMembers: canManageMembers?.(team),
|
|
@@ -6388,6 +6448,8 @@ var init_LiteLLMPage = __esm({
|
|
|
6388
6448
|
const [teamUsageLoading, setTeamUsageLoading] = useState11({});
|
|
6389
6449
|
const [memberUsageCache, setMemberUsageCache] = useState11({});
|
|
6390
6450
|
const [memberUsageLoading, setMemberUsageLoading] = useState11({});
|
|
6451
|
+
const [keyUsageCache, setKeyUsageCache] = useState11({});
|
|
6452
|
+
const [keyUsageLoading, setKeyUsageLoading] = useState11({});
|
|
6391
6453
|
const { value: userInfo, loading: userLoading, error: userError } = useAsync(
|
|
6392
6454
|
() => api.getUserInfo(),
|
|
6393
6455
|
[api]
|
|
@@ -6424,6 +6486,10 @@ var init_LiteLLMPage = __esm({
|
|
|
6424
6486
|
() => api.getMcpServers().catch(() => []),
|
|
6425
6487
|
[api]
|
|
6426
6488
|
);
|
|
6489
|
+
const { value: objectNames } = useAsync(
|
|
6490
|
+
() => api.getObjectNames().catch(() => ({ vector_stores: [], mcp_servers: [] })),
|
|
6491
|
+
[api]
|
|
6492
|
+
);
|
|
6427
6493
|
const teams = useMemo9(() => {
|
|
6428
6494
|
if (!allTeams?.length) return [];
|
|
6429
6495
|
if (!userInfo) return allTeams;
|
|
@@ -6450,6 +6516,8 @@ var init_LiteLLMPage = __esm({
|
|
|
6450
6516
|
setTeamUsageLoading({});
|
|
6451
6517
|
setMemberUsageCache({});
|
|
6452
6518
|
setMemberUsageLoading({});
|
|
6519
|
+
setKeyUsageCache({});
|
|
6520
|
+
setKeyUsageLoading({});
|
|
6453
6521
|
}, [setDateRange, setCurrentPreset]);
|
|
6454
6522
|
const loadTeamUsage = useCallback4(async (teamId) => {
|
|
6455
6523
|
if (teamUsageCache[teamId] !== void 0 || teamUsageLoading[teamId]) return;
|
|
@@ -6479,6 +6547,20 @@ var init_LiteLLMPage = __esm({
|
|
|
6479
6547
|
setMemberUsageLoading((prev) => ({ ...prev, [teamId]: false }));
|
|
6480
6548
|
}
|
|
6481
6549
|
}, [api, dateRange, memberUsageCache, memberUsageLoading]);
|
|
6550
|
+
const loadKeyUsage = useCallback4(async (teamId) => {
|
|
6551
|
+
if (keyUsageCache[teamId] !== void 0 || keyUsageLoading[teamId]) return;
|
|
6552
|
+
setKeyUsageLoading((prev) => ({ ...prev, [teamId]: true }));
|
|
6553
|
+
try {
|
|
6554
|
+
const startDate = toLocalDay(dateRange.start);
|
|
6555
|
+
const endDate = toLocalDay(dateRange.end);
|
|
6556
|
+
const data = await api.getTeamKeyUsage(teamId, startDate, endDate);
|
|
6557
|
+
setKeyUsageCache((prev) => ({ ...prev, [teamId]: data }));
|
|
6558
|
+
} catch {
|
|
6559
|
+
setKeyUsageCache((prev) => ({ ...prev, [teamId]: null }));
|
|
6560
|
+
} finally {
|
|
6561
|
+
setKeyUsageLoading((prev) => ({ ...prev, [teamId]: false }));
|
|
6562
|
+
}
|
|
6563
|
+
}, [api, dateRange, keyUsageCache, keyUsageLoading]);
|
|
6482
6564
|
const allowedModels = useMemo9(() => {
|
|
6483
6565
|
if (!allModels?.length) return [];
|
|
6484
6566
|
const userModels = userInfo?.models;
|
|
@@ -6776,18 +6858,23 @@ var init_LiteLLMPage = __esm({
|
|
|
6776
6858
|
getTeamUsageLoading: (teamId) => teamUsageLoading[teamId] ?? false,
|
|
6777
6859
|
getTeamMemberUsage: (teamId) => memberUsageCache[teamId] ?? null,
|
|
6778
6860
|
getTeamMemberUsageLoading: (teamId) => memberUsageLoading[teamId] ?? false,
|
|
6861
|
+
getTeamKeyUsage: (teamId) => keyUsageCache[teamId] ?? null,
|
|
6862
|
+
getTeamKeyUsageLoading: (teamId) => keyUsageLoading[teamId] ?? false,
|
|
6779
6863
|
canManage: teamMgmtEnabled && canManageTeam && !readOnly,
|
|
6780
6864
|
onEditTeam: (t) => setManageTeam({ mode: "edit", team: t }),
|
|
6781
6865
|
canCreate: teamMgmtEnabled && canCreateTeam && !readOnly,
|
|
6782
6866
|
onCreateTeam: () => setManageTeam({ mode: "create" }),
|
|
6783
|
-
vectorStores:
|
|
6784
|
-
mcpServers:
|
|
6867
|
+
vectorStores: objectNames?.vector_stores ?? [],
|
|
6868
|
+
mcpServers: objectNames?.mcp_servers ?? [],
|
|
6785
6869
|
canManageMembers: (t) => teamMgmtEnabled && canManageMembers && isTeamMemberManager(t, userInfo?.user_id, memberManagerRoles, readOnly),
|
|
6786
6870
|
onManageMembers: (t) => setManageTeam({ mode: "members", team: t }),
|
|
6787
6871
|
readOnly,
|
|
6788
6872
|
onTeamExpand: (team) => {
|
|
6789
6873
|
loadTeamUsage(team.team_id);
|
|
6790
|
-
if (liteLlmConfig?.teamUsage?.memberBreakdown)
|
|
6874
|
+
if (liteLlmConfig?.teamUsage?.memberBreakdown) {
|
|
6875
|
+
loadMemberUsage(team.team_id);
|
|
6876
|
+
loadKeyUsage(team.team_id);
|
|
6877
|
+
}
|
|
6791
6878
|
}
|
|
6792
6879
|
}
|
|
6793
6880
|
);
|
|
@@ -6913,6 +7000,7 @@ var init_LiteLLMPage = __esm({
|
|
|
6913
7000
|
},
|
|
6914
7001
|
canManageKnowledgeBases: teamMgmtEnabled && objectPermsEnabled && canManageKnowledgeBases,
|
|
6915
7002
|
vectorStores: vectorStores ?? [],
|
|
7003
|
+
vectorStoreNames: objectNames?.vector_stores ?? [],
|
|
6916
7004
|
onSaveKnowledgeBases: async (vectorStoreIds) => {
|
|
6917
7005
|
if (!manageTeam?.team) return;
|
|
6918
7006
|
try {
|
|
@@ -6931,6 +7019,7 @@ var init_LiteLLMPage = __esm({
|
|
|
6931
7019
|
},
|
|
6932
7020
|
canManageMcpServers: teamMgmtEnabled && objectPermsEnabled && canManageMcpServers,
|
|
6933
7021
|
mcpServers: mcpServers ?? [],
|
|
7022
|
+
mcpServerNames: objectNames?.mcp_servers ?? [],
|
|
6934
7023
|
onSaveMcpServers: async (mcpServerIds) => {
|
|
6935
7024
|
if (!manageTeam?.team) return;
|
|
6936
7025
|
try {
|