@acarmisc/backstage-plugin-litellm 0.41.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 +32 -13
- package/dist/index.cjs.js.map +2 -2
- package/dist/index.esm.js +32 -13
- package/dist/index.esm.js.map +2 -2
- 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
|
@@ -1782,7 +1782,8 @@ var init_KeysTable = __esm({
|
|
|
1782
1782
|
onDeleteKey,
|
|
1783
1783
|
onPruneExpiredKeys,
|
|
1784
1784
|
filter,
|
|
1785
|
-
onClearFilter
|
|
1785
|
+
onClearFilter,
|
|
1786
|
+
teams
|
|
1786
1787
|
}) => {
|
|
1787
1788
|
const managePermission = (0, import_plugin_permission_react.usePermission)({ permission: import_backstage_plugin_litellm_common.litellmKeyManagePermission });
|
|
1788
1789
|
const revokePermission = (0, import_plugin_permission_react.usePermission)({ permission: import_backstage_plugin_litellm_common.litellmKeyRevokePermission });
|
|
@@ -1810,9 +1811,14 @@ var init_KeysTable = __esm({
|
|
|
1810
1811
|
setSortDirection("asc");
|
|
1811
1812
|
}
|
|
1812
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;
|
|
1813
1819
|
const teamIds = (0, import_react4.useMemo)(
|
|
1814
|
-
() => [...new Set(keys.map((k) => k.team_id).filter((t) => !!t))].sort(),
|
|
1815
|
-
[keys]
|
|
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]
|
|
1816
1822
|
);
|
|
1817
1823
|
const filteredKeys = (0, import_react4.useMemo)(() => {
|
|
1818
1824
|
let result = keys;
|
|
@@ -1936,7 +1942,7 @@ var init_KeysTable = __esm({
|
|
|
1936
1942
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_Typography5.default, { variant: "body2", children: key.key_alias || "\u2014" }),
|
|
1937
1943
|
key.blocked && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(StatusPill, { label: "Blocked", tone: "danger" })
|
|
1938
1944
|
] }) }),
|
|
1939
|
-
/* @__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
|
|
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" }) }),
|
|
1940
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: [
|
|
1941
1947
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1942
1948
|
import_Typography5.default,
|
|
@@ -2057,7 +2063,7 @@ var init_KeysTable = __esm({
|
|
|
2057
2063
|
sx: { minWidth: 160 },
|
|
2058
2064
|
children: [
|
|
2059
2065
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_MenuItem.default, { value: "", children: "All teams" }),
|
|
2060
|
-
teamIds.map((id) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_MenuItem.default, { value: id, children: id }, id))
|
|
2066
|
+
teamIds.map((id) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_MenuItem.default, { value: id, children: teamLabel(id) }, id))
|
|
2061
2067
|
]
|
|
2062
2068
|
}
|
|
2063
2069
|
),
|
|
@@ -5105,7 +5111,7 @@ var init_TeamUsage = __esm({
|
|
|
5105
5111
|
}) })
|
|
5106
5112
|
] }) });
|
|
5107
5113
|
};
|
|
5108
|
-
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 }) => {
|
|
5109
5115
|
const [expanded, setExpanded] = (0, import_react10.useState)(false);
|
|
5110
5116
|
const chart = useChartTheme();
|
|
5111
5117
|
const handleExpandChange = (newExpanded) => {
|
|
@@ -5172,6 +5178,10 @@ var init_TeamUsage = __esm({
|
|
|
5172
5178
|
children: label
|
|
5173
5179
|
}
|
|
5174
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
|
+
] });
|
|
5175
5185
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Paper8.default, { variant: "outlined", sx: { borderRadius: 2, p: 2.5 }, children: [
|
|
5176
5186
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { display: "flex", alignItems: "center", gap: 1.5, children: [
|
|
5177
5187
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
@@ -5297,6 +5307,8 @@ var init_TeamUsage = __esm({
|
|
|
5297
5307
|
sectionLabel("Models"),
|
|
5298
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" })
|
|
5299
5309
|
] }),
|
|
5310
|
+
renderNamedTags("Knowledge bases", team.object_permission?.vector_stores, vectorStores),
|
|
5311
|
+
renderNamedTags("MCP servers", team.object_permission?.mcp_servers, mcpServers),
|
|
5300
5312
|
renderDailySpendSection(),
|
|
5301
5313
|
(memberUsageLoading || memberUsage) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
|
|
5302
5314
|
sectionLabel("Usage by member"),
|
|
@@ -5365,7 +5377,9 @@ var init_TeamUsage = __esm({
|
|
|
5365
5377
|
onTeamExpand,
|
|
5366
5378
|
canManageMembers,
|
|
5367
5379
|
onManageMembers,
|
|
5368
|
-
readOnly
|
|
5380
|
+
readOnly,
|
|
5381
|
+
vectorStores,
|
|
5382
|
+
mcpServers
|
|
5369
5383
|
}) => {
|
|
5370
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)(
|
|
5371
5385
|
import_Box14.default,
|
|
@@ -5423,7 +5437,9 @@ var init_TeamUsage = __esm({
|
|
|
5423
5437
|
onEditTeam,
|
|
5424
5438
|
canManageMembers: canManageMembers?.(team),
|
|
5425
5439
|
onManageMembers,
|
|
5426
|
-
onExpand: onTeamExpand
|
|
5440
|
+
onExpand: onTeamExpand,
|
|
5441
|
+
vectorStores,
|
|
5442
|
+
mcpServers
|
|
5427
5443
|
},
|
|
5428
5444
|
team.team_id
|
|
5429
5445
|
)) })
|
|
@@ -6392,12 +6408,12 @@ var init_LiteLLMPage = __esm({
|
|
|
6392
6408
|
const teamMgmtEnabled = liteLlmConfig?.teamManagement?.enabled ?? false;
|
|
6393
6409
|
const objectPermsEnabled = liteLlmConfig?.teamManagement?.objectPermissionsEnabled ?? false;
|
|
6394
6410
|
const { value: vectorStores } = (0, import_react_use2.useAsync)(
|
|
6395
|
-
|
|
6396
|
-
[api
|
|
6411
|
+
() => api.getVectorStores().catch(() => []),
|
|
6412
|
+
[api]
|
|
6397
6413
|
);
|
|
6398
6414
|
const { value: mcpServers } = (0, import_react_use2.useAsync)(
|
|
6399
|
-
|
|
6400
|
-
[api
|
|
6415
|
+
() => api.getMcpServers().catch(() => []),
|
|
6416
|
+
[api]
|
|
6401
6417
|
);
|
|
6402
6418
|
const teams = (0, import_react13.useMemo)(() => {
|
|
6403
6419
|
if (!allTeams?.length) return [];
|
|
@@ -6723,7 +6739,8 @@ var init_LiteLLMPage = __esm({
|
|
|
6723
6739
|
onDeleteKey: handleDeleteKey,
|
|
6724
6740
|
onPruneExpiredKeys: handlePruneExpiredKeys,
|
|
6725
6741
|
filter,
|
|
6726
|
-
onClearFilter: clearFilter
|
|
6742
|
+
onClearFilter: clearFilter,
|
|
6743
|
+
teams: allTeams ?? []
|
|
6727
6744
|
}
|
|
6728
6745
|
);
|
|
6729
6746
|
})(),
|
|
@@ -6754,6 +6771,8 @@ var init_LiteLLMPage = __esm({
|
|
|
6754
6771
|
onEditTeam: (t) => setManageTeam({ mode: "edit", team: t }),
|
|
6755
6772
|
canCreate: teamMgmtEnabled && canCreateTeam && !readOnly,
|
|
6756
6773
|
onCreateTeam: () => setManageTeam({ mode: "create" }),
|
|
6774
|
+
vectorStores: vectorStores ?? [],
|
|
6775
|
+
mcpServers: mcpServers ?? [],
|
|
6757
6776
|
canManageMembers: (t) => teamMgmtEnabled && canManageMembers && isTeamMemberManager(t, userInfo?.user_id, memberManagerRoles, readOnly),
|
|
6758
6777
|
onManageMembers: (t) => setManageTeam({ mode: "members", team: t }),
|
|
6759
6778
|
readOnly,
|