@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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type FetchApi, type DiscoveryApi } from '@backstage/frontend-plugin-api';
2
- import { UserInfo, VirtualKey, ModelInfo, UsageMetrics, TeamMemberUsage, TeamInfo, GenerateKeyRequest, GenerateKeyResponse, UpdateKeyRequest, AuditLogsParams, PaginatedAuditLogs, SpendLogsParams, PaginatedSpendLogs, LiteLlmConfig, QualityResponse, VectorStoreInfo, McpServerInfo, CreateTeamRequest, CreateTeamResponse, UpdateTeamRequest } from './types';
2
+ import { UserInfo, VirtualKey, ModelInfo, UsageMetrics, TeamMemberUsage, TeamKeyUsage, TeamInfo, GenerateKeyRequest, GenerateKeyResponse, UpdateKeyRequest, AuditLogsParams, PaginatedAuditLogs, SpendLogsParams, PaginatedSpendLogs, LiteLlmConfig, QualityResponse, VectorStoreInfo, McpServerInfo, CreateTeamRequest, CreateTeamResponse, UpdateTeamRequest } from './types';
3
3
  export declare class ApiError extends Error {
4
4
  body: unknown;
5
5
  status: number;
@@ -37,6 +37,11 @@ export interface LiteLlmApiInterface {
37
37
  }): Promise<TeamInfo>;
38
38
  removeTeamMember(teamId: string, userEntityRef: string): Promise<TeamInfo>;
39
39
  getVectorStores(): Promise<VectorStoreInfo[]>;
40
+ /** Id → name for every KB and MCP server, for labels only (not allowlist-filtered). */
41
+ getObjectNames(): Promise<{
42
+ vector_stores: VectorStoreInfo[];
43
+ mcp_servers: McpServerInfo[];
44
+ }>;
40
45
  setTeamKnowledgeBases(teamId: string, vectorStores: string[]): Promise<TeamInfo>;
41
46
  getMcpServers(): Promise<McpServerInfo[]>;
42
47
  setTeamMcpServers(teamId: string, mcpServers: string[]): Promise<TeamInfo>;
@@ -44,6 +49,8 @@ export interface LiteLlmApiInterface {
44
49
  getTeamUsage(teamId: string, startDate: string, endDate: string): Promise<UsageMetrics>;
45
50
  /** Per-member breakdown; rejects (403/404) when the caller may not see it. */
46
51
  getTeamMemberUsage(teamId: string, startDate: string, endDate: string): Promise<TeamMemberUsage>;
52
+ /** A team's keys with per-key usage; same access rules as the per-member breakdown. */
53
+ getTeamKeyUsage(teamId: string, startDate: string, endDate: string): Promise<TeamKeyUsage>;
47
54
  getAuditLogs(params: AuditLogsParams): Promise<PaginatedAuditLogs>;
48
55
  getSpendLogs(params: SpendLogsParams): Promise<PaginatedSpendLogs>;
49
56
  /** Langfuse quality summary; `{configured:false}` when Langfuse is off. */
@@ -105,12 +112,17 @@ export declare class LiteLlmApi implements LiteLlmApiInterface {
105
112
  }): Promise<TeamInfo>;
106
113
  removeTeamMember(teamId: string, userEntityRef: string): Promise<TeamInfo>;
107
114
  getVectorStores(): Promise<VectorStoreInfo[]>;
115
+ getObjectNames(): Promise<{
116
+ vector_stores: VectorStoreInfo[];
117
+ mcp_servers: McpServerInfo[];
118
+ }>;
108
119
  setTeamKnowledgeBases(teamId: string, vectorStores: string[]): Promise<TeamInfo>;
109
120
  getMcpServers(): Promise<McpServerInfo[]>;
110
121
  setTeamMcpServers(teamId: string, mcpServers: string[]): Promise<TeamInfo>;
111
122
  getUsage(startDate: string, endDate: string): Promise<UsageMetrics>;
112
123
  getTeamUsage(teamId: string, startDate: string, endDate: string): Promise<UsageMetrics>;
113
124
  getTeamMemberUsage(teamId: string, startDate: string, endDate: string): Promise<TeamMemberUsage>;
125
+ getTeamKeyUsage(teamId: string, startDate: string, endDate: string): Promise<TeamKeyUsage>;
114
126
  getSpendLogs(params: SpendLogsParams): Promise<PaginatedSpendLogs>;
115
127
  getQuality(params: SpendLogsParams): Promise<QualityResponse>;
116
128
  getConfig(): Promise<LiteLlmConfig>;
@@ -27,12 +27,16 @@ interface ManageTeamDialogProps {
27
27
  canManageKnowledgeBases?: boolean;
28
28
  /** Vector stores the caller may attach (already allowlist-filtered server-side). */
29
29
  vectorStores?: VectorStoreInfo[];
30
+ /** Names for labelling attached stores; may include stores not offered in the picker. */
31
+ vectorStoreNames?: VectorStoreInfo[];
30
32
  /** Called to replace the team's attached knowledge bases; parent refreshes `team`. */
31
33
  onSaveKnowledgeBases?: (vectorStoreIds: string[]) => Promise<void>;
32
34
  /** When true, the MCP Servers section (edit mode only) is shown. */
33
35
  canManageMcpServers?: boolean;
34
36
  /** MCP servers the caller may attach (already allowlist-filtered server-side). */
35
37
  mcpServers?: McpServerInfo[];
38
+ /** Names for labelling attached servers; may include servers not offered in the picker. */
39
+ mcpServerNames?: McpServerInfo[];
36
40
  /** Called to replace the team's attached MCP servers; parent refreshes `team`. */
37
41
  onSaveMcpServers?: (mcpServerIds: string[]) => Promise<void>;
38
42
  /** When true, only members section is shown (not budget/models/KB/MCP); title changes; Save becomes Done. */
@@ -1,5 +1,5 @@
1
1
  import { FC } from 'react';
2
- import { McpServerInfo, TeamInfo, TeamMemberUsage, UsageMetrics, VectorStoreInfo } from '../types';
2
+ import { McpServerInfo, TeamInfo, TeamKeyUsage, 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.
@@ -7,6 +7,13 @@ import { McpServerInfo, TeamInfo, TeamMemberUsage, UsageMetrics, VectorStoreInfo
7
7
  export declare const MemberUsageTable: FC<{
8
8
  usage: TeamMemberUsage;
9
9
  }>;
10
+ /**
11
+ * A team's keys with the period's usage, for team leads. The backend never
12
+ * sends secrets; dollars are dropped when it hides them.
13
+ */
14
+ export declare const TeamKeyUsageTable: FC<{
15
+ usage: TeamKeyUsage;
16
+ }>;
10
17
  interface TeamUsageProps {
11
18
  teams: TeamInfo[];
12
19
  loading: boolean;
@@ -15,6 +22,9 @@ interface TeamUsageProps {
15
22
  /** Per-member breakdown for a team; null hides the section. */
16
23
  getTeamMemberUsage?: (teamId: string) => TeamMemberUsage | null;
17
24
  getTeamMemberUsageLoading?: (teamId: string) => boolean;
25
+ /** Per-key usage for a team; null hides the section. */
26
+ getTeamKeyUsage?: (teamId: string) => TeamKeyUsage | null;
27
+ getTeamKeyUsageLoading?: (teamId: string) => boolean;
18
28
  canManage?: boolean;
19
29
  onEditTeam?: (team: TeamInfo) => void;
20
30
  /** When true (with `onCreateTeam`), a "Create Team" action renders in the section header. */
package/dist/index.cjs.js CHANGED
@@ -287,6 +287,10 @@ var init_api = __esm({
287
287
  async getVectorStores() {
288
288
  return this.get("/vector-stores");
289
289
  }
290
+ // Names only, readable by any signed-in user; never used for the picker.
291
+ async getObjectNames() {
292
+ return this.get("/object-names");
293
+ }
290
294
  async setTeamKnowledgeBases(teamId, vectorStores) {
291
295
  return this.put(
292
296
  `/teams/${encodeURIComponent(teamId)}/knowledge-bases`,
@@ -317,6 +321,12 @@ var init_api = __esm({
317
321
  end_date: endDate
318
322
  });
319
323
  }
324
+ async getTeamKeyUsage(teamId, startDate, endDate) {
325
+ return this.get(`/teams/${encodeURIComponent(teamId)}/usage/keys`, {
326
+ start_date: startDate,
327
+ end_date: endDate
328
+ });
329
+ }
320
330
  async getSpendLogs(params) {
321
331
  const strParams = {
322
332
  start_date: params.startDate,
@@ -3245,9 +3255,11 @@ var init_ManageTeamDialog = __esm({
3245
3255
  onRemoveMember,
3246
3256
  canManageKnowledgeBases,
3247
3257
  vectorStores,
3258
+ vectorStoreNames,
3248
3259
  onSaveKnowledgeBases,
3249
3260
  canManageMcpServers,
3250
3261
  mcpServers,
3262
+ mcpServerNames,
3251
3263
  onSaveMcpServers,
3252
3264
  membersOnly,
3253
3265
  currentUserId,
@@ -3516,10 +3528,10 @@ var init_ManageTeamDialog = __esm({
3516
3528
  const durationOptions = BUDGET_DURATION_OPTIONS.some((o) => o.value === budgetDuration) ? BUDGET_DURATION_OPTIONS : [...BUDGET_DURATION_OPTIONS, { value: budgetDuration, label: budgetDuration }];
3517
3529
  const showKnowledgeBases = mode === "edit" && !!canManageKnowledgeBases;
3518
3530
  const kbOptions = (vectorStores ?? []).map((v) => v.id);
3519
- const kbLabel = (id) => (vectorStores ?? []).find((v) => v.id === id)?.name ?? id;
3531
+ const kbLabel = (id) => (vectorStoreNames ?? []).find((v) => v.id === id)?.name ?? id;
3520
3532
  const showMcpServers = mode === "edit" && !!canManageMcpServers;
3521
3533
  const mcpOptions = (mcpServers ?? []).map((s) => s.id);
3522
- const mcpLabel = (id) => (mcpServers ?? []).find((s) => s.id === id)?.name ?? id;
3534
+ const mcpLabel = (id) => (mcpServerNames ?? []).find((s) => s.id === id)?.name ?? id;
3523
3535
  const isRemovalDisabled = (memberUserId, memberRole) => {
3524
3536
  if (!membersOnly) return { disabled: false };
3525
3537
  if (memberUserId === currentUserId) {
@@ -5048,7 +5060,7 @@ function budgetStatValue(hidden, budget) {
5048
5060
  if (budget > 0) return fmtUsd2(budget);
5049
5061
  return "Unlimited";
5050
5062
  }
5051
- var import_react10, import_Paper8, import_Box14, import_Typography12, import_Skeleton5, import_Divider3, import_Table4, import_TableBody4, import_TableCell4, import_TableHead4, import_TableRow4, import_TableContainer4, import_Collapse2, import_IconButton6, import_Button6, import_CircularProgress4, import_styles10, import_Tooltip5, import_icons_material7, import_recharts2, import_jsx_runtime15, fmtUsd2, monoSx, MemberUsageTable, TeamCard, TeamUsage;
5063
+ var import_react10, import_Paper8, import_Box14, import_Typography12, import_Skeleton5, import_Divider3, import_Table4, import_TableBody4, import_TableCell4, import_TableHead4, import_TableRow4, import_TableContainer4, import_Collapse2, import_IconButton6, import_Button6, import_CircularProgress4, import_styles10, import_Tooltip5, import_icons_material7, import_recharts2, import_jsx_runtime15, fmtUsd2, monoSx, MemberUsageTable, TeamKeyUsageTable, TeamCard, TeamUsage;
5052
5064
  var init_TeamUsage = __esm({
5053
5065
  "src/components/TeamUsage.tsx"() {
5054
5066
  "use strict";
@@ -5111,7 +5123,47 @@ var init_TeamUsage = __esm({
5111
5123
  }) })
5112
5124
  ] }) });
5113
5125
  };
5114
- TeamCard = ({ team, usage, usageLoading, memberUsage, memberUsageLoading, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand, vectorStores, mcpServers }) => {
5126
+ TeamKeyUsageTable = ({ usage }) => {
5127
+ const hidden = usage.budget_hidden === true;
5128
+ if (!usage.keys.length) {
5129
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "body2", color: "text.secondary", children: "This team has no keys." });
5130
+ }
5131
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableContainer4.default, { component: import_Paper8.default, variant: "outlined", sx: { borderRadius: 1.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Table4.default, { size: "small", sx: dataTableSx, "aria-label": "Keys by member", children: [
5132
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableHead4.default, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_TableRow4.default, { children: [
5133
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: "Key" }),
5134
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: "Owner" }),
5135
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: "Created" }),
5136
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: "Status" }),
5137
+ !hidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Spend" }),
5138
+ !hidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Budget" }),
5139
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Tokens" }),
5140
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Requests" })
5141
+ ] }) }),
5142
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableBody4.default, { children: usage.keys.map((k) => {
5143
+ const owner = k.display_name ?? k.user_email ?? k.user_id;
5144
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_TableRow4.default, { children: [
5145
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_TableCell4.default, { children: [
5146
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "body2", children: k.key_alias ?? k.key }),
5147
+ k.key_alias && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "caption", color: "text.secondary", sx: monoSx, children: k.key })
5148
+ ] }),
5149
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: owner ?? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "body2", color: "text.secondary", children: "\u2014" }) }),
5150
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: fmtDateShort(k.created_at) }),
5151
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5152
+ StatusPill,
5153
+ {
5154
+ label: k.blocked ? "Blocked" : "Active",
5155
+ tone: k.blocked ? "danger" : "success"
5156
+ }
5157
+ ) }),
5158
+ !hidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: fmtUsd2(k.spend) }),
5159
+ !hidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: k.max_budget === void 0 ? "Unlimited" : fmtUsd2(k.max_budget) }),
5160
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: fmtCompact(k.total_tokens) }),
5161
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: k.api_requests.toLocaleString() })
5162
+ ] }, k.key);
5163
+ }) })
5164
+ ] }) });
5165
+ };
5166
+ TeamCard = ({ team, usage, usageLoading, memberUsage, memberUsageLoading, keyUsage, keyUsageLoading, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand, vectorStores, mcpServers }) => {
5115
5167
  const [expanded, setExpanded] = (0, import_react10.useState)(false);
5116
5168
  const chart = useChartTheme();
5117
5169
  const handleExpandChange = (newExpanded) => {
@@ -5314,6 +5366,10 @@ var init_TeamUsage = __esm({
5314
5366
  sectionLabel("Usage by member"),
5315
5367
  memberUsage ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MemberUsageTable, { usage: memberUsage }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Box14.default, { display: "flex", justifyContent: "center", py: 2, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_CircularProgress4.default, { size: 22 }) })
5316
5368
  ] }),
5369
+ (keyUsageLoading || keyUsage) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
5370
+ sectionLabel("Keys by member"),
5371
+ keyUsage ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TeamKeyUsageTable, { usage: keyUsage }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Box14.default, { display: "flex", justifyContent: "center", py: 2, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_CircularProgress4.default, { size: 22 }) })
5372
+ ] }),
5317
5373
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { children: [
5318
5374
  sectionLabel("Members"),
5319
5375
  team.members_with_roles?.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -5370,6 +5426,8 @@ var init_TeamUsage = __esm({
5370
5426
  getTeamUsageLoading,
5371
5427
  getTeamMemberUsage,
5372
5428
  getTeamMemberUsageLoading,
5429
+ getTeamKeyUsage,
5430
+ getTeamKeyUsageLoading,
5373
5431
  canManage,
5374
5432
  onEditTeam,
5375
5433
  canCreate,
@@ -5433,6 +5491,8 @@ var init_TeamUsage = __esm({
5433
5491
  usageLoading: getTeamUsageLoading(team.team_id),
5434
5492
  memberUsage: getTeamMemberUsage?.(team.team_id) ?? null,
5435
5493
  memberUsageLoading: getTeamMemberUsageLoading?.(team.team_id) ?? false,
5494
+ keyUsage: getTeamKeyUsage?.(team.team_id) ?? null,
5495
+ keyUsageLoading: getTeamKeyUsageLoading?.(team.team_id) ?? false,
5436
5496
  canManage,
5437
5497
  onEditTeam,
5438
5498
  canManageMembers: canManageMembers?.(team),
@@ -6379,6 +6439,8 @@ var init_LiteLLMPage = __esm({
6379
6439
  const [teamUsageLoading, setTeamUsageLoading] = (0, import_react13.useState)({});
6380
6440
  const [memberUsageCache, setMemberUsageCache] = (0, import_react13.useState)({});
6381
6441
  const [memberUsageLoading, setMemberUsageLoading] = (0, import_react13.useState)({});
6442
+ const [keyUsageCache, setKeyUsageCache] = (0, import_react13.useState)({});
6443
+ const [keyUsageLoading, setKeyUsageLoading] = (0, import_react13.useState)({});
6382
6444
  const { value: userInfo, loading: userLoading, error: userError } = (0, import_react_use2.useAsync)(
6383
6445
  () => api.getUserInfo(),
6384
6446
  [api]
@@ -6415,6 +6477,10 @@ var init_LiteLLMPage = __esm({
6415
6477
  () => api.getMcpServers().catch(() => []),
6416
6478
  [api]
6417
6479
  );
6480
+ const { value: objectNames } = (0, import_react_use2.useAsync)(
6481
+ () => api.getObjectNames().catch(() => ({ vector_stores: [], mcp_servers: [] })),
6482
+ [api]
6483
+ );
6418
6484
  const teams = (0, import_react13.useMemo)(() => {
6419
6485
  if (!allTeams?.length) return [];
6420
6486
  if (!userInfo) return allTeams;
@@ -6441,6 +6507,8 @@ var init_LiteLLMPage = __esm({
6441
6507
  setTeamUsageLoading({});
6442
6508
  setMemberUsageCache({});
6443
6509
  setMemberUsageLoading({});
6510
+ setKeyUsageCache({});
6511
+ setKeyUsageLoading({});
6444
6512
  }, [setDateRange, setCurrentPreset]);
6445
6513
  const loadTeamUsage = (0, import_react13.useCallback)(async (teamId) => {
6446
6514
  if (teamUsageCache[teamId] !== void 0 || teamUsageLoading[teamId]) return;
@@ -6470,6 +6538,20 @@ var init_LiteLLMPage = __esm({
6470
6538
  setMemberUsageLoading((prev) => ({ ...prev, [teamId]: false }));
6471
6539
  }
6472
6540
  }, [api, dateRange, memberUsageCache, memberUsageLoading]);
6541
+ const loadKeyUsage = (0, import_react13.useCallback)(async (teamId) => {
6542
+ if (keyUsageCache[teamId] !== void 0 || keyUsageLoading[teamId]) return;
6543
+ setKeyUsageLoading((prev) => ({ ...prev, [teamId]: true }));
6544
+ try {
6545
+ const startDate = toLocalDay(dateRange.start);
6546
+ const endDate = toLocalDay(dateRange.end);
6547
+ const data = await api.getTeamKeyUsage(teamId, startDate, endDate);
6548
+ setKeyUsageCache((prev) => ({ ...prev, [teamId]: data }));
6549
+ } catch {
6550
+ setKeyUsageCache((prev) => ({ ...prev, [teamId]: null }));
6551
+ } finally {
6552
+ setKeyUsageLoading((prev) => ({ ...prev, [teamId]: false }));
6553
+ }
6554
+ }, [api, dateRange, keyUsageCache, keyUsageLoading]);
6473
6555
  const allowedModels = (0, import_react13.useMemo)(() => {
6474
6556
  if (!allModels?.length) return [];
6475
6557
  const userModels = userInfo?.models;
@@ -6767,18 +6849,23 @@ var init_LiteLLMPage = __esm({
6767
6849
  getTeamUsageLoading: (teamId) => teamUsageLoading[teamId] ?? false,
6768
6850
  getTeamMemberUsage: (teamId) => memberUsageCache[teamId] ?? null,
6769
6851
  getTeamMemberUsageLoading: (teamId) => memberUsageLoading[teamId] ?? false,
6852
+ getTeamKeyUsage: (teamId) => keyUsageCache[teamId] ?? null,
6853
+ getTeamKeyUsageLoading: (teamId) => keyUsageLoading[teamId] ?? false,
6770
6854
  canManage: teamMgmtEnabled && canManageTeam && !readOnly,
6771
6855
  onEditTeam: (t) => setManageTeam({ mode: "edit", team: t }),
6772
6856
  canCreate: teamMgmtEnabled && canCreateTeam && !readOnly,
6773
6857
  onCreateTeam: () => setManageTeam({ mode: "create" }),
6774
- vectorStores: vectorStores ?? [],
6775
- mcpServers: mcpServers ?? [],
6858
+ vectorStores: objectNames?.vector_stores ?? [],
6859
+ mcpServers: objectNames?.mcp_servers ?? [],
6776
6860
  canManageMembers: (t) => teamMgmtEnabled && canManageMembers && isTeamMemberManager(t, userInfo?.user_id, memberManagerRoles, readOnly),
6777
6861
  onManageMembers: (t) => setManageTeam({ mode: "members", team: t }),
6778
6862
  readOnly,
6779
6863
  onTeamExpand: (team) => {
6780
6864
  loadTeamUsage(team.team_id);
6781
- if (liteLlmConfig?.teamUsage?.memberBreakdown) loadMemberUsage(team.team_id);
6865
+ if (liteLlmConfig?.teamUsage?.memberBreakdown) {
6866
+ loadMemberUsage(team.team_id);
6867
+ loadKeyUsage(team.team_id);
6868
+ }
6782
6869
  }
6783
6870
  }
6784
6871
  );
@@ -6904,6 +6991,7 @@ var init_LiteLLMPage = __esm({
6904
6991
  },
6905
6992
  canManageKnowledgeBases: teamMgmtEnabled && objectPermsEnabled && canManageKnowledgeBases,
6906
6993
  vectorStores: vectorStores ?? [],
6994
+ vectorStoreNames: objectNames?.vector_stores ?? [],
6907
6995
  onSaveKnowledgeBases: async (vectorStoreIds) => {
6908
6996
  if (!manageTeam?.team) return;
6909
6997
  try {
@@ -6922,6 +7010,7 @@ var init_LiteLLMPage = __esm({
6922
7010
  },
6923
7011
  canManageMcpServers: teamMgmtEnabled && objectPermsEnabled && canManageMcpServers,
6924
7012
  mcpServers: mcpServers ?? [],
7013
+ mcpServerNames: objectNames?.mcp_servers ?? [],
6925
7014
  onSaveMcpServers: async (mcpServerIds) => {
6926
7015
  if (!manageTeam?.team) return;
6927
7016
  try {