@acarmisc/backstage-plugin-litellm 0.44.0 → 0.45.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.
@@ -0,0 +1,21 @@
1
+ import { FC } from 'react';
2
+ import { GenerateKeyRequest, GenerateKeyResponse, LiteLlmConfig, ModelInfo, TeamInfo, VirtualKey } from '../types';
3
+ /**
4
+ * @deprecated Use {@link KeyFormDialog} with `mode="create"` instead — this
5
+ * wrapper only forwards props for backwards compatibility with the public
6
+ * entrypoint and will be removed in a future release.
7
+ */
8
+ export declare const GenerateKeyDialog: FC<{
9
+ open: boolean;
10
+ onClose: () => void;
11
+ keys: VirtualKey[];
12
+ models: ModelInfo[];
13
+ teams: TeamInfo[];
14
+ username?: string;
15
+ keyGenerationSettings?: {
16
+ allowUnlimitedBudget: boolean;
17
+ teamRequired: boolean;
18
+ };
19
+ onGenerateKey: (request: GenerateKeyRequest) => Promise<GenerateKeyResponse>;
20
+ onGetConfig: () => Promise<LiteLlmConfig>;
21
+ }>;
@@ -25,6 +25,9 @@ interface TeamUsageProps {
25
25
  /** Per-key usage for a team; null hides the section. */
26
26
  getTeamKeyUsage?: (teamId: string) => TeamKeyUsage | null;
27
27
  getTeamKeyUsageLoading?: (teamId: string) => boolean;
28
+ /** True when the breakdown failed for a reason other than refusal: shows a caption. */
29
+ getTeamMemberUsageFailed?: (teamId: string) => boolean;
30
+ getTeamKeyUsageFailed?: (teamId: string) => boolean;
28
31
  canManage?: boolean;
29
32
  onEditTeam?: (team: TeamInfo) => void;
30
33
  /** When true (with `onCreateTeam`), a "Create Team" action renders in the section header. */
package/dist/index.cjs.js CHANGED
@@ -5163,7 +5163,7 @@ var init_TeamUsage = __esm({
5163
5163
  }) })
5164
5164
  ] }) });
5165
5165
  };
5166
- TeamCard = ({ team, usage, usageLoading, memberUsage, memberUsageLoading, keyUsage, keyUsageLoading, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand, vectorStores, mcpServers }) => {
5166
+ TeamCard = ({ team, usage, usageLoading, memberUsage, memberUsageLoading, memberUsageFailed, keyUsage, keyUsageLoading, keyUsageFailed, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand, vectorStores, mcpServers }) => {
5167
5167
  const [expanded, setExpanded] = (0, import_react10.useState)(false);
5168
5168
  const chart = useChartTheme();
5169
5169
  const handleExpandChange = (newExpanded) => {
@@ -5362,13 +5362,17 @@ var init_TeamUsage = __esm({
5362
5362
  renderNamedTags("Knowledge bases", team.object_permission?.vector_stores, vectorStores),
5363
5363
  renderNamedTags("MCP servers", team.object_permission?.mcp_servers, mcpServers),
5364
5364
  renderDailySpendSection(),
5365
- (memberUsageLoading || memberUsage) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
5365
+ (memberUsageLoading || memberUsage || memberUsageFailed) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
5366
5366
  sectionLabel("Usage by member"),
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 }) })
5367
+ memberUsage && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MemberUsageTable, { usage: memberUsage }),
5368
+ !memberUsage && memberUsageFailed && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "caption", color: "text.secondary", children: "Could not load per-member usage" }),
5369
+ !memberUsage && !memberUsageFailed && /* @__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 }) })
5368
5370
  ] }),
5369
- (keyUsageLoading || keyUsage) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
5371
+ (keyUsageLoading || keyUsage || keyUsageFailed) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
5370
5372
  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 }) })
5373
+ keyUsage && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TeamKeyUsageTable, { usage: keyUsage }),
5374
+ !keyUsage && keyUsageFailed && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "caption", color: "text.secondary", children: "Could not load per-key usage" }),
5375
+ !keyUsage && !keyUsageFailed && /* @__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
5376
  ] }),
5373
5377
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { children: [
5374
5378
  sectionLabel("Members"),
@@ -5428,6 +5432,8 @@ var init_TeamUsage = __esm({
5428
5432
  getTeamMemberUsageLoading,
5429
5433
  getTeamKeyUsage,
5430
5434
  getTeamKeyUsageLoading,
5435
+ getTeamMemberUsageFailed,
5436
+ getTeamKeyUsageFailed,
5431
5437
  canManage,
5432
5438
  onEditTeam,
5433
5439
  canCreate,
@@ -5493,6 +5499,8 @@ var init_TeamUsage = __esm({
5493
5499
  memberUsageLoading: getTeamMemberUsageLoading?.(team.team_id) ?? false,
5494
5500
  keyUsage: getTeamKeyUsage?.(team.team_id) ?? null,
5495
5501
  keyUsageLoading: getTeamKeyUsageLoading?.(team.team_id) ?? false,
5502
+ memberUsageFailed: getTeamMemberUsageFailed?.(team.team_id) ?? false,
5503
+ keyUsageFailed: getTeamKeyUsageFailed?.(team.team_id) ?? false,
5496
5504
  canManage,
5497
5505
  onEditTeam,
5498
5506
  canManageMembers: canManageMembers?.(team),
@@ -6316,7 +6324,7 @@ function initDateRange() {
6316
6324
  else start.setDate(start.getDate() - 7);
6317
6325
  return { start, end };
6318
6326
  }
6319
- var import_react13, import_Box17, import_Alert6, import_Button8, import_Typography15, import_Tabs2, import_Tab2, import_Grid3, import_Accordion2, import_AccordionSummary2, import_AccordionDetails2, import_ExpandMore, import_react_router_dom, import_react_use2, import_core_plugin_api5, import_core_components3, import_plugin_permission_react3, import_backstage_plugin_litellm_common5, import_jsx_runtime18, PERIOD_LS_KEY2, PAGE_TABS, isPageTab, LiteLLMPage;
6327
+ var import_react13, import_Box17, import_Alert6, import_Button8, import_Typography15, import_Tabs2, import_Tab2, import_Grid3, import_Accordion2, import_AccordionSummary2, import_AccordionDetails2, import_ExpandMore, import_react_router_dom, import_react_use2, import_core_plugin_api5, import_core_components3, import_plugin_permission_react3, import_backstage_plugin_litellm_common5, import_jsx_runtime18, PERIOD_LS_KEY2, PAGE_TABS, isPageTab, isRefusal, LiteLLMPage;
6320
6328
  var init_LiteLLMPage = __esm({
6321
6329
  "src/components/LiteLLMPage.tsx"() {
6322
6330
  "use strict";
@@ -6356,6 +6364,7 @@ var init_LiteLLMPage = __esm({
6356
6364
  PERIOD_LS_KEY2 = "litellm_usage_period";
6357
6365
  PAGE_TABS = ["overview", "keys", "teams", "models", "insights"];
6358
6366
  isPageTab = (v) => !!v && PAGE_TABS.includes(v);
6367
+ isRefusal = (err) => err instanceof ApiError && (err.status === 403 || err.status === 404);
6359
6368
  LiteLLMPage = () => {
6360
6369
  const api = (0, import_core_plugin_api5.useApi)(liteLlmApiRef);
6361
6370
  const alertApi = (0, import_core_plugin_api5.useApi)(import_core_plugin_api5.alertApiRef);
@@ -6441,6 +6450,8 @@ var init_LiteLLMPage = __esm({
6441
6450
  const [memberUsageLoading, setMemberUsageLoading] = (0, import_react13.useState)({});
6442
6451
  const [keyUsageCache, setKeyUsageCache] = (0, import_react13.useState)({});
6443
6452
  const [keyUsageLoading, setKeyUsageLoading] = (0, import_react13.useState)({});
6453
+ const [memberUsageFailed, setMemberUsageFailed] = (0, import_react13.useState)({});
6454
+ const [keyUsageFailed, setKeyUsageFailed] = (0, import_react13.useState)({});
6444
6455
  const { value: userInfo, loading: userLoading, error: userError } = (0, import_react_use2.useAsync)(
6445
6456
  () => api.getUserInfo(),
6446
6457
  [api]
@@ -6509,6 +6520,8 @@ var init_LiteLLMPage = __esm({
6509
6520
  setMemberUsageLoading({});
6510
6521
  setKeyUsageCache({});
6511
6522
  setKeyUsageLoading({});
6523
+ setMemberUsageFailed({});
6524
+ setKeyUsageFailed({});
6512
6525
  }, [setDateRange, setCurrentPreset]);
6513
6526
  const loadTeamUsage = (0, import_react13.useCallback)(async (teamId) => {
6514
6527
  if (teamUsageCache[teamId] !== void 0 || teamUsageLoading[teamId]) return;
@@ -6532,8 +6545,9 @@ var init_LiteLLMPage = __esm({
6532
6545
  const endDate = toLocalDay(dateRange.end);
6533
6546
  const data = await api.getTeamMemberUsage(teamId, startDate, endDate);
6534
6547
  setMemberUsageCache((prev) => ({ ...prev, [teamId]: data }));
6535
- } catch {
6548
+ } catch (err) {
6536
6549
  setMemberUsageCache((prev) => ({ ...prev, [teamId]: null }));
6550
+ setMemberUsageFailed((prev) => ({ ...prev, [teamId]: !isRefusal(err) }));
6537
6551
  } finally {
6538
6552
  setMemberUsageLoading((prev) => ({ ...prev, [teamId]: false }));
6539
6553
  }
@@ -6546,8 +6560,9 @@ var init_LiteLLMPage = __esm({
6546
6560
  const endDate = toLocalDay(dateRange.end);
6547
6561
  const data = await api.getTeamKeyUsage(teamId, startDate, endDate);
6548
6562
  setKeyUsageCache((prev) => ({ ...prev, [teamId]: data }));
6549
- } catch {
6563
+ } catch (err) {
6550
6564
  setKeyUsageCache((prev) => ({ ...prev, [teamId]: null }));
6565
+ setKeyUsageFailed((prev) => ({ ...prev, [teamId]: !isRefusal(err) }));
6551
6566
  } finally {
6552
6567
  setKeyUsageLoading((prev) => ({ ...prev, [teamId]: false }));
6553
6568
  }
@@ -6851,6 +6866,8 @@ var init_LiteLLMPage = __esm({
6851
6866
  getTeamMemberUsageLoading: (teamId) => memberUsageLoading[teamId] ?? false,
6852
6867
  getTeamKeyUsage: (teamId) => keyUsageCache[teamId] ?? null,
6853
6868
  getTeamKeyUsageLoading: (teamId) => keyUsageLoading[teamId] ?? false,
6869
+ getTeamMemberUsageFailed: (teamId) => memberUsageFailed[teamId] ?? false,
6870
+ getTeamKeyUsageFailed: (teamId) => keyUsageFailed[teamId] ?? false,
6854
6871
  canManage: teamMgmtEnabled && canManageTeam && !readOnly,
6855
6872
  onEditTeam: (t) => setManageTeam({ mode: "edit", team: t }),
6856
6873
  canCreate: teamMgmtEnabled && canCreateTeam && !readOnly,