@acarmisc/backstage-plugin-litellm 0.5.0 → 0.6.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.esm.js CHANGED
@@ -1121,7 +1121,7 @@ __export(LiteLLMPage_exports, {
1121
1121
  LiteLLMPage: () => LiteLLMPage
1122
1122
  });
1123
1123
  import React6, { useState as useState5, useCallback as useCallback2, useMemo as useMemo3 } from "react";
1124
- import { Grid as Grid2, Box as Box6, Snackbar, Alert as Alert2, CircularProgress as CircularProgress4, Typography as Typography6, Paper as Paper6, Tabs as Tabs2, Tab as Tab2 } from "@mui/material";
1124
+ import { Box as Box6, Snackbar, Alert as Alert2, CircularProgress as CircularProgress4, Typography as Typography6, Paper as Paper6, Tabs as Tabs2, Tab as Tab2 } from "@mui/material";
1125
1125
  import { useAsync as useAsync2, useAsyncRetry } from "react-use";
1126
1126
  import { useApi } from "@backstage/core-plugin-api";
1127
1127
  function initDateRange() {
@@ -1321,7 +1321,7 @@ var init_LiteLLMPage = __esm({
1321
1321
  const hint = userError?.body?.hint;
1322
1322
  return /* @__PURE__ */ React6.createElement(Box6, { p: 3 }, /* @__PURE__ */ React6.createElement(Paper6, { sx: { p: 3 } }, /* @__PURE__ */ React6.createElement(Typography6, { variant: "h6", gutterBottom: true }, "Account not provisioned"), /* @__PURE__ */ React6.createElement(Typography6, { color: "text.secondary", paragraph: true }, "Your Backstage account is not linked to a LiteLLM user."), hint ? /* @__PURE__ */ React6.createElement(Typography6, { variant: "body2", color: "text.secondary" }, hint) : /* @__PURE__ */ React6.createElement(Typography6, { variant: "body2", color: "text.secondary" }, isProvisioningEnabled ? "Auto-provisioning is enabled but failed. Check the backend logs." : "Set litellm.provisioning.enabled: true in app-config.yaml to enable auto-provisioning, or ask your administrator to create the account manually.")));
1323
1323
  }
1324
- return /* @__PURE__ */ React6.createElement(Box6, { p: 3 }, userInfo.can_view_audit && /* @__PURE__ */ React6.createElement(
1324
+ return /* @__PURE__ */ React6.createElement(Box6, { p: 3 }, /* @__PURE__ */ React6.createElement(Box6, { mb: 2 }, /* @__PURE__ */ React6.createElement(DashboardHeader, { userInfo, teams: teams ?? [], loading: userLoading || teamsLoading })), /* @__PURE__ */ React6.createElement(
1325
1325
  Tabs2,
1326
1326
  {
1327
1327
  value: activeTab,
@@ -1329,20 +1329,10 @@ var init_LiteLLMPage = __esm({
1329
1329
  sx: { mb: 2, borderBottom: 1, borderColor: "divider" }
1330
1330
  },
1331
1331
  /* @__PURE__ */ React6.createElement(Tab2, { label: "Overview", value: "overview" }),
1332
- /* @__PURE__ */ React6.createElement(Tab2, { label: "Audit Log", value: "audit" })
1333
- ), activeTab === "audit" ? /* @__PURE__ */ React6.createElement(AuditLog, { api }) : /* @__PURE__ */ React6.createElement(Grid2, { container: true, spacing: 2 }, /* @__PURE__ */ React6.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React6.createElement(DashboardHeader, { userInfo, teams: teams ?? [], loading: userLoading || teamsLoading })), /* @__PURE__ */ React6.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React6.createElement(
1334
- TeamUsage,
1335
- {
1336
- teams: teams ?? [],
1337
- loading: teamsLoading,
1338
- dateRange,
1339
- getTeamUsage: (teamId) => {
1340
- if (teamUsageCache[teamId] === void 0) loadTeamUsage(teamId);
1341
- return teamUsageCache[teamId] ?? null;
1342
- },
1343
- getTeamUsageLoading: (teamId) => teamUsageLoading[teamId] ?? false
1344
- }
1345
- )), /* @__PURE__ */ React6.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React6.createElement(
1332
+ /* @__PURE__ */ React6.createElement(Tab2, { label: "Keys", value: "keys" }),
1333
+ /* @__PURE__ */ React6.createElement(Tab2, { label: "Teams", value: "teams" }),
1334
+ userInfo.can_view_audit && /* @__PURE__ */ React6.createElement(Tab2, { label: "Audit Log", value: "audit" })
1335
+ ), activeTab === "overview" && /* @__PURE__ */ React6.createElement(
1346
1336
  UsageStats,
1347
1337
  {
1348
1338
  usage: usage ?? null,
@@ -1352,7 +1342,7 @@ var init_LiteLLMPage = __esm({
1352
1342
  loading: usageLoading,
1353
1343
  userInfo
1354
1344
  }
1355
- )), /* @__PURE__ */ React6.createElement(Grid2, { item: true, xs: 12 }, /* @__PURE__ */ React6.createElement(
1345
+ ), activeTab === "keys" && /* @__PURE__ */ React6.createElement(
1356
1346
  KeysTable,
1357
1347
  {
1358
1348
  keys: keys ?? [],
@@ -1367,7 +1357,19 @@ var init_LiteLLMPage = __esm({
1367
1357
  onResetKeySpend: handleResetKeySpend,
1368
1358
  onDeleteKey: handleDeleteKey
1369
1359
  }
1370
- ))), /* @__PURE__ */ React6.createElement(
1360
+ ), activeTab === "teams" && /* @__PURE__ */ React6.createElement(
1361
+ TeamUsage,
1362
+ {
1363
+ teams: teams ?? [],
1364
+ loading: teamsLoading,
1365
+ dateRange,
1366
+ getTeamUsage: (teamId) => {
1367
+ if (teamUsageCache[teamId] === void 0) loadTeamUsage(teamId);
1368
+ return teamUsageCache[teamId] ?? null;
1369
+ },
1370
+ getTeamUsageLoading: (teamId) => teamUsageLoading[teamId] ?? false
1371
+ }
1372
+ ), activeTab === "audit" && userInfo.can_view_audit && /* @__PURE__ */ React6.createElement(AuditLog, { api }), /* @__PURE__ */ React6.createElement(
1371
1373
  Snackbar,
1372
1374
  {
1373
1375
  open: !!snackbar,
@@ -1431,7 +1433,7 @@ import {
1431
1433
  FormControl as FormControl2,
1432
1434
  Select as Select2,
1433
1435
  MenuItem as MenuItem4,
1434
- Grid as Grid3,
1436
+ Grid as Grid2,
1435
1437
  CircularProgress as CircularProgress5,
1436
1438
  Alert as Alert3
1437
1439
  } from "@mui/material";
@@ -1500,7 +1502,7 @@ var LiteLLMHomeWidget = ({
1500
1502
  /* @__PURE__ */ React8.createElement(MenuItem4, { value: "today" }, "Today"),
1501
1503
  /* @__PURE__ */ React8.createElement(MenuItem4, { value: "7d" }, "7d"),
1502
1504
  /* @__PURE__ */ React8.createElement(MenuItem4, { value: "30d" }, "30d")
1503
- ))), loading && /* @__PURE__ */ React8.createElement(Box7, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: 120 }, /* @__PURE__ */ React8.createElement(CircularProgress5, { size: 32 })), !loading && error && /* @__PURE__ */ React8.createElement(Alert3, { severity: "error", sx: { mt: 1 } }, error), !loading && !error && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Grid3, { container: true, spacing: 2, sx: { mb: hasSparkline ? 1.5 : 0 } }, /* @__PURE__ */ React8.createElement(Grid3, { item: true, xs: 6 }, /* @__PURE__ */ React8.createElement(Kpi, { label: "USD Spent", value: fmtUsd2(usage?.total_spend ?? 0) })), /* @__PURE__ */ React8.createElement(Grid3, { item: true, xs: 6 }, /* @__PURE__ */ React8.createElement(Kpi, { label: "Tokens In", value: fmtInt2(usage?.prompt_tokens ?? 0) })), /* @__PURE__ */ React8.createElement(Grid3, { item: true, xs: 6 }, /* @__PURE__ */ React8.createElement(Kpi, { label: "Tokens Out", value: fmtInt2(usage?.completion_tokens ?? 0) })), /* @__PURE__ */ React8.createElement(Grid3, { item: true, xs: 6 }, /* @__PURE__ */ React8.createElement(Kpi, { label: "Keys", value: fmtInt2(keys.length) }))), hasSparkline && /* @__PURE__ */ React8.createElement(Box7, { height: 120 }, /* @__PURE__ */ React8.createElement(ResponsiveContainer3, { width: "100%", height: "100%" }, /* @__PURE__ */ React8.createElement(AreaChart3, { data: dailyData, margin: { top: 4, right: 0, bottom: 0, left: 0 } }, /* @__PURE__ */ React8.createElement(
1505
+ ))), loading && /* @__PURE__ */ React8.createElement(Box7, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: 120 }, /* @__PURE__ */ React8.createElement(CircularProgress5, { size: 32 })), !loading && error && /* @__PURE__ */ React8.createElement(Alert3, { severity: "error", sx: { mt: 1 } }, error), !loading && !error && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Grid2, { container: true, spacing: 2, sx: { mb: hasSparkline ? 1.5 : 0 } }, /* @__PURE__ */ React8.createElement(Grid2, { item: true, xs: 6 }, /* @__PURE__ */ React8.createElement(Kpi, { label: "USD Spent", value: fmtUsd2(usage?.total_spend ?? 0) })), /* @__PURE__ */ React8.createElement(Grid2, { item: true, xs: 6 }, /* @__PURE__ */ React8.createElement(Kpi, { label: "Tokens In", value: fmtInt2(usage?.prompt_tokens ?? 0) })), /* @__PURE__ */ React8.createElement(Grid2, { item: true, xs: 6 }, /* @__PURE__ */ React8.createElement(Kpi, { label: "Tokens Out", value: fmtInt2(usage?.completion_tokens ?? 0) })), /* @__PURE__ */ React8.createElement(Grid2, { item: true, xs: 6 }, /* @__PURE__ */ React8.createElement(Kpi, { label: "Keys", value: fmtInt2(keys.length) }))), hasSparkline && /* @__PURE__ */ React8.createElement(Box7, { height: 120 }, /* @__PURE__ */ React8.createElement(ResponsiveContainer3, { width: "100%", height: "100%" }, /* @__PURE__ */ React8.createElement(AreaChart3, { data: dailyData, margin: { top: 4, right: 0, bottom: 0, left: 0 } }, /* @__PURE__ */ React8.createElement(
1504
1506
  Area3,
1505
1507
  {
1506
1508
  type: "monotone",