@acarmisc/backstage-plugin-litellm 0.34.0 → 0.36.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.cjs.js CHANGED
@@ -257,6 +257,10 @@ var init_api = __esm({
257
257
  async listModels() {
258
258
  return this.get("/models");
259
259
  }
260
+ /** Mints (or rotates) the caller's connect-flow key, optionally bound to one of their teams. */
261
+ async connectLocalClient(redirectUri, team) {
262
+ return this.post("/opencode/connect", { redirect_uri: redirectUri, team });
263
+ }
260
264
  async getTeams() {
261
265
  return this.get("/teams");
262
266
  }
@@ -307,6 +311,12 @@ var init_api = __esm({
307
311
  end_date: endDate
308
312
  });
309
313
  }
314
+ async getTeamMemberUsage(teamId, startDate, endDate) {
315
+ return this.get(`/teams/${encodeURIComponent(teamId)}/usage/members`, {
316
+ start_date: startDate,
317
+ end_date: endDate
318
+ });
319
+ }
310
320
  async getConfig() {
311
321
  return this.get("/config");
312
322
  }
@@ -4986,7 +4996,7 @@ function budgetStatValue(hidden, budget) {
4986
4996
  if (budget > 0) return fmtUsd2(budget);
4987
4997
  return "Unlimited";
4988
4998
  }
4989
- 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, TeamCard, TeamUsage;
4999
+ 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;
4990
5000
  var init_TeamUsage = __esm({
4991
5001
  "src/components/TeamUsage.tsx"() {
4992
5002
  "use strict";
@@ -5013,7 +5023,43 @@ var init_TeamUsage = __esm({
5013
5023
  init_ui();
5014
5024
  import_jsx_runtime15 = require("react/jsx-runtime");
5015
5025
  fmtUsd2 = (n) => `$${(n ?? 0).toFixed(2)}`;
5016
- TeamCard = ({ team, usage, usageLoading, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand }) => {
5026
+ monoSx = { fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fontSize: 11 };
5027
+ MemberUsageTable = ({ usage }) => {
5028
+ const hidden = usage.budget_hidden === true;
5029
+ if (!usage.members.length) {
5030
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "body2", color: "text.secondary", children: "No members or activity in this period." });
5031
+ }
5032
+ 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": "Usage by member", children: [
5033
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableHead4.default, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_TableRow4.default, { children: [
5034
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: "Member" }),
5035
+ !hidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Spend" }),
5036
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Share" }),
5037
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Tokens" }),
5038
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Requests" }),
5039
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Success" }),
5040
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: "Keys" })
5041
+ ] }) }),
5042
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableBody4.default, { children: usage.members.map((m) => {
5043
+ const name = m.display_name ?? m.user_email ?? m.user_id;
5044
+ let sub = null;
5045
+ if (m.display_name) sub = m.user_email ?? m.user_id;
5046
+ else if (m.user_email && m.user_id !== m.user_email) sub = m.user_id;
5047
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_TableRow4.default, { children: [
5048
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { children: m.user_id === null ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Tooltip5.default, { title: "Activity of keys that were deleted or have no owner", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "body2", color: "text.secondary", sx: { fontStyle: "italic" }, children: "Unattributed" }) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
5049
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "body2", children: name }),
5050
+ sub && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_Typography12.default, { variant: "caption", color: "text.secondary", sx: monoSx, children: sub })
5051
+ ] }) }),
5052
+ !hidden && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: fmtUsd2(m.spend) }),
5053
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: `${m.spend_share_pct.toFixed(m.spend_share_pct > 0 && m.spend_share_pct < 1 ? 1 : 0)}%` }),
5054
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: fmtCompact(m.total_tokens) }),
5055
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: m.api_requests.toLocaleString() }),
5056
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: m.success_rate === null ? "\u2014" : `${m.success_rate.toFixed(0)}%` }),
5057
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_TableCell4.default, { align: "right", children: m.user_id === null ? "\u2014" : m.key_count })
5058
+ ] }, m.user_id ?? "__unattributed");
5059
+ }) })
5060
+ ] }) });
5061
+ };
5062
+ TeamCard = ({ team, usage, usageLoading, memberUsage, memberUsageLoading, canManage, onEditTeam, canManageMembers, onManageMembers, onExpand }) => {
5017
5063
  const [expanded, setExpanded] = (0, import_react10.useState)(false);
5018
5064
  const chart = useChartTheme();
5019
5065
  const handleExpandChange = (newExpanded) => {
@@ -5206,6 +5252,10 @@ var init_TeamUsage = __esm({
5206
5252
  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" })
5207
5253
  ] }),
5208
5254
  renderDailySpendSection(),
5255
+ (memberUsageLoading || memberUsage) && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { mb: 2.5, children: [
5256
+ sectionLabel("Usage by member"),
5257
+ 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 }) })
5258
+ ] }),
5209
5259
  /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_Box14.default, { children: [
5210
5260
  sectionLabel("Members"),
5211
5261
  team.members_with_roles?.length ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -5260,6 +5310,8 @@ var init_TeamUsage = __esm({
5260
5310
  loading,
5261
5311
  getTeamUsage,
5262
5312
  getTeamUsageLoading,
5313
+ getTeamMemberUsage,
5314
+ getTeamMemberUsageLoading,
5263
5315
  canManage,
5264
5316
  onEditTeam,
5265
5317
  canCreate,
@@ -5319,6 +5371,8 @@ var init_TeamUsage = __esm({
5319
5371
  team,
5320
5372
  usage: getTeamUsage(team.team_id),
5321
5373
  usageLoading: getTeamUsageLoading(team.team_id),
5374
+ memberUsage: getTeamMemberUsage?.(team.team_id) ?? null,
5375
+ memberUsageLoading: getTeamMemberUsageLoading?.(team.team_id) ?? false,
5322
5376
  canManage,
5323
5377
  onEditTeam,
5324
5378
  canManageMembers: canManageMembers?.(team),
@@ -6125,6 +6179,8 @@ var init_LiteLLMPage = __esm({
6125
6179
  const keyFormOpen = generateDialogOpen || !!keyToEdit;
6126
6180
  const [teamUsageCache, setTeamUsageCache] = (0, import_react13.useState)({});
6127
6181
  const [teamUsageLoading, setTeamUsageLoading] = (0, import_react13.useState)({});
6182
+ const [memberUsageCache, setMemberUsageCache] = (0, import_react13.useState)({});
6183
+ const [memberUsageLoading, setMemberUsageLoading] = (0, import_react13.useState)({});
6128
6184
  const { value: userInfo, loading: userLoading, error: userError } = (0, import_react_use2.useAsync)(
6129
6185
  () => api.getUserInfo(),
6130
6186
  [api]
@@ -6185,6 +6241,8 @@ var init_LiteLLMPage = __esm({
6185
6241
  }
6186
6242
  setTeamUsageCache({});
6187
6243
  setTeamUsageLoading({});
6244
+ setMemberUsageCache({});
6245
+ setMemberUsageLoading({});
6188
6246
  }, [setDateRange, setCurrentPreset]);
6189
6247
  const loadTeamUsage = (0, import_react13.useCallback)(async (teamId) => {
6190
6248
  if (teamUsageCache[teamId] !== void 0 || teamUsageLoading[teamId]) return;
@@ -6200,6 +6258,20 @@ var init_LiteLLMPage = __esm({
6200
6258
  setTeamUsageLoading((prev) => ({ ...prev, [teamId]: false }));
6201
6259
  }
6202
6260
  }, [api, dateRange, teamUsageCache, teamUsageLoading]);
6261
+ const loadMemberUsage = (0, import_react13.useCallback)(async (teamId) => {
6262
+ if (memberUsageCache[teamId] !== void 0 || memberUsageLoading[teamId]) return;
6263
+ setMemberUsageLoading((prev) => ({ ...prev, [teamId]: true }));
6264
+ try {
6265
+ const startDate = toLocalDay(dateRange.start);
6266
+ const endDate = toLocalDay(dateRange.end);
6267
+ const data = await api.getTeamMemberUsage(teamId, startDate, endDate);
6268
+ setMemberUsageCache((prev) => ({ ...prev, [teamId]: data }));
6269
+ } catch {
6270
+ setMemberUsageCache((prev) => ({ ...prev, [teamId]: null }));
6271
+ } finally {
6272
+ setMemberUsageLoading((prev) => ({ ...prev, [teamId]: false }));
6273
+ }
6274
+ }, [api, dateRange, memberUsageCache, memberUsageLoading]);
6203
6275
  const allowedModels = (0, import_react13.useMemo)(() => {
6204
6276
  if (!allModels?.length) return [];
6205
6277
  const userModels = userInfo?.models;
@@ -6494,6 +6566,8 @@ var init_LiteLLMPage = __esm({
6494
6566
  loading: teamsLoading,
6495
6567
  getTeamUsage: (teamId) => teamUsageCache[teamId] ?? null,
6496
6568
  getTeamUsageLoading: (teamId) => teamUsageLoading[teamId] ?? false,
6569
+ getTeamMemberUsage: (teamId) => memberUsageCache[teamId] ?? null,
6570
+ getTeamMemberUsageLoading: (teamId) => memberUsageLoading[teamId] ?? false,
6497
6571
  canManage: teamMgmtEnabled && canManageTeam && !readOnly,
6498
6572
  onEditTeam: (t) => setManageTeam({ mode: "edit", team: t }),
6499
6573
  canCreate: teamMgmtEnabled && canCreateTeam && !readOnly,
@@ -6501,7 +6575,10 @@ var init_LiteLLMPage = __esm({
6501
6575
  canManageMembers: (t) => teamMgmtEnabled && canManageMembers && isTeamMemberManager(t, userInfo?.user_id, memberManagerRoles, readOnly),
6502
6576
  onManageMembers: (t) => setManageTeam({ mode: "members", team: t }),
6503
6577
  readOnly,
6504
- onTeamExpand: (team) => loadTeamUsage(team.team_id)
6578
+ onTeamExpand: (team) => {
6579
+ loadTeamUsage(team.team_id);
6580
+ if (liteLlmConfig?.teamUsage?.memberBreakdown) loadMemberUsage(team.team_id);
6581
+ }
6505
6582
  }
6506
6583
  );
6507
6584
  })(),
@@ -6657,6 +6734,131 @@ var init_LiteLLMPage = __esm({
6657
6734
  }
6658
6735
  });
6659
6736
 
6737
+ // src/connect.ts
6738
+ function isLoopbackCallback(uri) {
6739
+ if (!uri) return false;
6740
+ try {
6741
+ const url = new URL(uri);
6742
+ return url.protocol === "http:" && (url.hostname === "localhost" || url.hostname === "127.0.0.1") && url.pathname === "/callback" && url.search === "" && url.hash === "";
6743
+ } catch {
6744
+ return false;
6745
+ }
6746
+ }
6747
+ function postToLoopback(redirectUri, fields) {
6748
+ const form = document.createElement("form");
6749
+ form.method = "POST";
6750
+ form.action = redirectUri;
6751
+ for (const [name, value] of fields) {
6752
+ const input = document.createElement("input");
6753
+ input.type = "hidden";
6754
+ input.name = name;
6755
+ input.value = value;
6756
+ form.appendChild(input);
6757
+ }
6758
+ document.body.appendChild(form);
6759
+ form.submit();
6760
+ }
6761
+ var init_connect = __esm({
6762
+ "src/connect.ts"() {
6763
+ "use strict";
6764
+ }
6765
+ });
6766
+
6767
+ // src/components/ConnectPage.tsx
6768
+ var ConnectPage_exports = {};
6769
+ __export(ConnectPage_exports, {
6770
+ ConnectPage: () => ConnectPage
6771
+ });
6772
+ var import_react14, import_Alert7, import_Box18, import_Button8, import_Checkbox3, import_FormControlLabel3, import_FormGroup, import_Paper9, import_Typography16, import_react_router_dom2, import_react_use3, import_core_plugin_api6, import_core_components4, import_jsx_runtime19, ConnectPage;
6773
+ var init_ConnectPage = __esm({
6774
+ "src/components/ConnectPage.tsx"() {
6775
+ "use strict";
6776
+ import_react14 = require("react");
6777
+ import_Alert7 = __toESM(require("@mui/material/Alert"));
6778
+ import_Box18 = __toESM(require("@mui/material/Box"));
6779
+ import_Button8 = __toESM(require("@mui/material/Button"));
6780
+ import_Checkbox3 = __toESM(require("@mui/material/Checkbox"));
6781
+ import_FormControlLabel3 = __toESM(require("@mui/material/FormControlLabel"));
6782
+ import_FormGroup = __toESM(require("@mui/material/FormGroup"));
6783
+ import_Paper9 = __toESM(require("@mui/material/Paper"));
6784
+ import_Typography16 = __toESM(require("@mui/material/Typography"));
6785
+ import_react_router_dom2 = require("react-router-dom");
6786
+ import_react_use3 = require("react-use");
6787
+ import_core_plugin_api6 = require("@backstage/core-plugin-api");
6788
+ import_core_components4 = require("@backstage/core-components");
6789
+ init_api();
6790
+ init_connect();
6791
+ import_jsx_runtime19 = require("react/jsx-runtime");
6792
+ ConnectPage = () => {
6793
+ const api = (0, import_core_plugin_api6.useApi)(liteLlmApiRef);
6794
+ const [params] = (0, import_react_router_dom2.useSearchParams)();
6795
+ const redirectUri = params.get("redirect_uri");
6796
+ const state = params.get("state") ?? "";
6797
+ const client = params.get("client") || "a local application";
6798
+ const teams = (0, import_react_use3.useAsync)(() => api.getTeams(), [api]);
6799
+ const [selected, setSelected] = (0, import_react14.useState)();
6800
+ const [busy, setBusy] = (0, import_react14.useState)(false);
6801
+ const [error, setError] = (0, import_react14.useState)();
6802
+ if (!isLoopbackCallback(redirectUri)) {
6803
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_core_components4.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_Alert7.default, { severity: "error", children: "Invalid connection link: redirect_uri must be http://localhost:<port>/callback." }) });
6804
+ }
6805
+ if (teams.loading) return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_core_components4.Progress, {});
6806
+ const all = teams.value ?? [];
6807
+ const chosen = selected ?? new Set(all.map((t) => t.team_id));
6808
+ const toggle = (id) => {
6809
+ const next = new Set(chosen);
6810
+ if (!next.delete(id)) next.add(id);
6811
+ setSelected(next);
6812
+ };
6813
+ const connect = async () => {
6814
+ setBusy(true);
6815
+ setError(void 0);
6816
+ try {
6817
+ const ids = all.length ? all.filter((t) => chosen.has(t.team_id)).map((t) => t.team_id) : [void 0];
6818
+ const keys = [];
6819
+ for (const id of ids) keys.push(["key", (await api.connectLocalClient(redirectUri, id)).key]);
6820
+ postToLoopback(redirectUri, [["state", state], ...keys]);
6821
+ } catch (e) {
6822
+ setError(e instanceof Error ? e.message : String(e));
6823
+ setBusy(false);
6824
+ }
6825
+ };
6826
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_core_components4.Content, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_Box18.default, { maxWidth: 520, mx: "auto", mt: 4, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_Paper9.default, { sx: { p: 3 }, children: [
6827
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_Typography16.default, { variant: "h5", gutterBottom: true, children: [
6828
+ "Connect ",
6829
+ client
6830
+ ] }),
6831
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_Typography16.default, { variant: "body2", color: "text.secondary", paragraph: true, children: [
6832
+ client,
6833
+ " will receive an API key for each selected team. Connecting again replaces the keys created by a previous connection."
6834
+ ] }),
6835
+ teams.error && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_Alert7.default, { severity: "error", children: [
6836
+ "Could not load your teams: ",
6837
+ teams.error.message
6838
+ ] }),
6839
+ all.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_FormGroup.default, { sx: { mb: 2 }, children: all.map((t) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
6840
+ import_FormControlLabel3.default,
6841
+ {
6842
+ control: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_Checkbox3.default, { checked: chosen.has(t.team_id), onChange: () => toggle(t.team_id) }),
6843
+ label: t.team_alias ?? t.team_id
6844
+ },
6845
+ t.team_id
6846
+ )) }),
6847
+ error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_Alert7.default, { severity: "error", sx: { mb: 2 }, children: error }),
6848
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
6849
+ import_Button8.default,
6850
+ {
6851
+ variant: "contained",
6852
+ onClick: connect,
6853
+ disabled: busy || !!teams.error || all.length > 0 && chosen.size === 0,
6854
+ children: busy ? "Connecting\u2026" : "Connect"
6855
+ }
6856
+ )
6857
+ ] }) }) });
6858
+ };
6859
+ }
6860
+ });
6861
+
6660
6862
  // src/index.ts
6661
6863
  var index_exports = {};
6662
6864
  __export(index_exports, {
@@ -6688,7 +6890,7 @@ var import_icons_material10 = require("@mui/icons-material");
6688
6890
  var import_frontend_plugin_api4 = require("@backstage/frontend-plugin-api");
6689
6891
  init_api();
6690
6892
  init_routes();
6691
- var import_jsx_runtime19 = require("react/jsx-runtime");
6893
+ var import_jsx_runtime20 = require("react/jsx-runtime");
6692
6894
  var liteLlmApi = import_frontend_plugin_api4.ApiBlueprint.make({
6693
6895
  params: (defineParams) => defineParams({
6694
6896
  api: liteLlmApiRef,
@@ -6700,11 +6902,21 @@ var liteLlmPage = import_frontend_plugin_api4.PageBlueprint.make({
6700
6902
  params: {
6701
6903
  path: "/litellm",
6702
6904
  title: "LiteLLM",
6703
- icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_icons_material10.TrendingUp, {}),
6905
+ icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons_material10.TrendingUp, {}),
6704
6906
  routeRef: rootRouteRef,
6705
6907
  loader: async () => {
6706
6908
  const { LiteLLMPage: LiteLLMPage2 } = await Promise.resolve().then(() => (init_LiteLLMPage(), LiteLLMPage_exports));
6707
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LiteLLMPage2, {});
6909
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LiteLLMPage2, {});
6910
+ }
6911
+ }
6912
+ });
6913
+ var liteLlmConnectPage = import_frontend_plugin_api4.PageBlueprint.make({
6914
+ name: "connect",
6915
+ params: {
6916
+ path: "/litellm/connect",
6917
+ loader: async () => {
6918
+ const { ConnectPage: ConnectPage2 } = await Promise.resolve().then(() => (init_ConnectPage(), ConnectPage_exports));
6919
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ConnectPage2, {});
6708
6920
  }
6709
6921
  }
6710
6922
  });
@@ -6713,7 +6925,7 @@ var litellmPlugin = (0, import_frontend_plugin_api4.createFrontendPlugin)({
6713
6925
  routes: {
6714
6926
  root: rootRouteRef
6715
6927
  },
6716
- extensions: [liteLlmApi, liteLlmPage]
6928
+ extensions: [liteLlmApi, liteLlmPage, liteLlmConnectPage]
6717
6929
  });
6718
6930
 
6719
6931
  // src/index.ts
@@ -6724,18 +6936,18 @@ init_UsageStats();
6724
6936
  init_TeamUsage();
6725
6937
 
6726
6938
  // src/components/LiteLLMHomeWidget.tsx
6727
- var import_react14 = require("react");
6728
- var import_Paper9 = __toESM(require("@mui/material/Paper"));
6729
- var import_Box18 = __toESM(require("@mui/material/Box"));
6730
- var import_Typography16 = __toESM(require("@mui/material/Typography"));
6939
+ var import_react15 = require("react");
6940
+ var import_Paper10 = __toESM(require("@mui/material/Paper"));
6941
+ var import_Box19 = __toESM(require("@mui/material/Box"));
6942
+ var import_Typography17 = __toESM(require("@mui/material/Typography"));
6731
6943
  var import_FormControl2 = __toESM(require("@mui/material/FormControl"));
6732
6944
  var import_Select2 = __toESM(require("@mui/material/Select"));
6733
6945
  var import_MenuItem6 = __toESM(require("@mui/material/MenuItem"));
6734
6946
  var import_Skeleton7 = __toESM(require("@mui/material/Skeleton"));
6735
6947
  var import_recharts3 = require("recharts");
6736
- var import_core_plugin_api6 = require("@backstage/core-plugin-api");
6948
+ var import_core_plugin_api7 = require("@backstage/core-plugin-api");
6737
6949
  var import_frontend_plugin_api5 = require("@backstage/frontend-plugin-api");
6738
- var import_core_components4 = require("@backstage/core-components");
6950
+ var import_core_components5 = require("@backstage/core-components");
6739
6951
  init_useLiteLLMProfile();
6740
6952
  init_api();
6741
6953
  init_routes();
@@ -6787,7 +6999,7 @@ function usageSummary(usage) {
6787
6999
  }
6788
7000
 
6789
7001
  // src/components/LiteLLMHomeWidget.tsx
6790
- var import_jsx_runtime20 = require("react/jsx-runtime");
7002
+ var import_jsx_runtime21 = require("react/jsx-runtime");
6791
7003
  function presetToDateRange(preset) {
6792
7004
  const end = /* @__PURE__ */ new Date();
6793
7005
  const start = /* @__PURE__ */ new Date();
@@ -6805,14 +7017,14 @@ var LiteLLMHomeWidget = ({
6805
7017
  title = "LiteLLM Usage",
6806
7018
  bare = false
6807
7019
  }) => {
6808
- const api = (0, import_core_plugin_api6.useApi)(liteLlmApiRef);
7020
+ const api = (0, import_core_plugin_api7.useApi)(liteLlmApiRef);
6809
7021
  const moduleRouteRef = (0, import_frontend_plugin_api5.useRouteRef)(rootRouteRef);
6810
7022
  const { userInfo, keys, loading: profileLoading, error: profileError } = useLiteLLMProfile();
6811
- const [period, setPeriod] = (0, import_react14.useState)(defaultPeriod);
6812
- const [usageLoading, setUsageLoading] = (0, import_react14.useState)(true);
6813
- const [usageError, setUsageError] = (0, import_react14.useState)(null);
6814
- const [usage, setUsage] = (0, import_react14.useState)(null);
6815
- (0, import_react14.useEffect)(() => {
7023
+ const [period, setPeriod] = (0, import_react15.useState)(defaultPeriod);
7024
+ const [usageLoading, setUsageLoading] = (0, import_react15.useState)(true);
7025
+ const [usageError, setUsageError] = (0, import_react15.useState)(null);
7026
+ const [usage, setUsage] = (0, import_react15.useState)(null);
7027
+ (0, import_react15.useEffect)(() => {
6816
7028
  let cancelled = false;
6817
7029
  setUsageLoading(true);
6818
7030
  setUsageError(null);
@@ -6834,7 +7046,7 @@ var LiteLLMHomeWidget = ({
6834
7046
  cancelled = true;
6835
7047
  };
6836
7048
  }, [api, period]);
6837
- const viewState = (0, import_react14.useMemo)(
7049
+ const viewState = (0, import_react15.useMemo)(
6838
7050
  () => widgetViewState({
6839
7051
  loading: profileLoading || usageLoading,
6840
7052
  error: profileError,
@@ -6844,7 +7056,7 @@ var LiteLLMHomeWidget = ({
6844
7056
  }),
6845
7057
  [profileLoading, usageLoading, profileError, userInfo, usageError, keys]
6846
7058
  );
6847
- const Wrapper = bare ? import_Box18.default : import_Paper9.default;
7059
+ const Wrapper = bare ? import_Box19.default : import_Paper10.default;
6848
7060
  const partialFailure = !usageLoading && usageError && usage;
6849
7061
  const dailyData = (usage?.daily_usage ?? []).map((d) => ({
6850
7062
  date: d.date,
@@ -6856,10 +7068,10 @@ var LiteLLMHomeWidget = ({
6856
7068
  const endDate = toLocalDay(end);
6857
7069
  const dateRangeCaption = rangeCaption(startDate, endDate);
6858
7070
  const sparklineAriaLabelText = sparklineAriaLabel(dailyData);
6859
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Wrapper, { sx: bare ? { height: "100%" } : { p: 2, height: "100%" }, children: [
6860
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_Box18.default, { display: "flex", justifyContent: bare ? "flex-end" : "space-between", alignItems: "center", mb: 1.5, children: [
6861
- !bare && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Typography16.default, { variant: "h6", children: title }),
6862
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_FormControl2.default, { size: "small", sx: { minWidth: 90 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
7071
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Wrapper, { sx: bare ? { height: "100%" } : { p: 2, height: "100%" }, children: [
7072
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { display: "flex", justifyContent: bare ? "flex-end" : "space-between", alignItems: "center", mb: 1.5, children: [
7073
+ !bare && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Typography17.default, { variant: "h6", children: title }),
7074
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_FormControl2.default, { size: "small", sx: { minWidth: 90 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
6863
7075
  import_Select2.default,
6864
7076
  {
6865
7077
  value: period,
@@ -6867,23 +7079,23 @@ var LiteLLMHomeWidget = ({
6867
7079
  displayEmpty: true,
6868
7080
  inputProps: { "aria-label": "Usage period" },
6869
7081
  children: [
6870
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_MenuItem6.default, { value: "today", children: "Today" }),
6871
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_MenuItem6.default, { value: "7d", children: "7d" }),
6872
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_MenuItem6.default, { value: "30d", children: "30d" })
7082
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_MenuItem6.default, { value: "today", children: "Today" }),
7083
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_MenuItem6.default, { value: "7d", children: "7d" }),
7084
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_MenuItem6.default, { value: "30d", children: "30d" })
6873
7085
  ]
6874
7086
  }
6875
7087
  ) })
6876
7088
  ] }),
6877
- viewState.kind === "loading" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_Box18.default, { sx: { minHeight: 120 }, children: [
6878
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Skeleton7.default, { variant: "text", width: "60%", height: 20, sx: { mb: 1 } }),
6879
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Skeleton7.default, { variant: "rectangular", width: "100%", height: 100 })
7089
+ viewState.kind === "loading" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { minHeight: 120 }, children: [
7090
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Skeleton7.default, { variant: "text", width: "60%", height: 20, sx: { mb: 1 } }),
7091
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Skeleton7.default, { variant: "rectangular", width: "100%", height: 100 })
6880
7092
  ] }),
6881
- viewState.kind === "error" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Typography16.default, { variant: "body2", color: "text.secondary", sx: { mt: 1 }, children: viewState.message }),
6882
- viewState.kind === "unprovisioned" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Typography16.default, { variant: "body2", color: "text.secondary", sx: { mt: 1 }, children: UNPROVISIONED_MSG }),
6883
- viewState.kind === "ready" && partialFailure && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Box18.default, { sx: { mt: 1, mb: 1, p: 1, backgroundColor: "action.hover", borderRadius: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Typography16.default, { variant: "body2", color: "text.secondary", children: USAGE_UNAVAILABLE_MSG }) }),
6884
- viewState.kind === "ready" && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
6885
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6886
- import_Typography16.default,
7093
+ viewState.kind === "error" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Typography17.default, { variant: "body2", color: "text.secondary", sx: { mt: 1 }, children: viewState.message }),
7094
+ viewState.kind === "unprovisioned" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Typography17.default, { variant: "body2", color: "text.secondary", sx: { mt: 1 }, children: UNPROVISIONED_MSG }),
7095
+ viewState.kind === "ready" && partialFailure && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Box19.default, { sx: { mt: 1, mb: 1, p: 1, backgroundColor: "action.hover", borderRadius: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Typography17.default, { variant: "body2", color: "text.secondary", children: USAGE_UNAVAILABLE_MSG }) }),
7096
+ viewState.kind === "ready" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
7097
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7098
+ import_Typography17.default,
6887
7099
  {
6888
7100
  variant: "body2",
6889
7101
  sx: {
@@ -6894,18 +7106,18 @@ var LiteLLMHomeWidget = ({
6894
7106
  children: viewState.usageUnavailable ? USAGE_UNAVAILABLE_MSG : usageSummary(usage)
6895
7107
  }
6896
7108
  ),
6897
- hasSparkline && !viewState.usageUnavailable && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
6898
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6899
- import_Box18.default,
7109
+ hasSparkline && !viewState.usageUnavailable && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
7110
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7111
+ import_Box19.default,
6900
7112
  {
6901
7113
  height: 80,
6902
7114
  role: "img",
6903
7115
  "aria-label": sparklineAriaLabelText,
6904
7116
  sx: { mb: 0.5 },
6905
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_recharts3.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_recharts3.AreaChart, { data: dailyData, margin: { top: 4, right: 0, bottom: 0, left: 0 }, children: [
6906
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_recharts3.XAxis, { dataKey: "date", hide: true }),
6907
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_recharts3.Tooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChartTooltip, { valueFormatter: fmtUsd }) }),
6908
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
7117
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_recharts3.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_recharts3.AreaChart, { data: dailyData, margin: { top: 4, right: 0, bottom: 0, left: 0 }, children: [
7118
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_recharts3.XAxis, { dataKey: "date", hide: true }),
7119
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_recharts3.Tooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ChartTooltip, { valueFormatter: fmtUsd }) }),
7120
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6909
7121
  import_recharts3.Area,
6910
7122
  {
6911
7123
  type: "monotone",
@@ -6921,13 +7133,13 @@ var LiteLLMHomeWidget = ({
6921
7133
  ] }) })
6922
7134
  }
6923
7135
  ),
6924
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_Typography16.default, { variant: "caption", color: "text.secondary", sx: { display: "block", mb: 1 }, children: [
7136
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Typography17.default, { variant: "caption", color: "text.secondary", sx: { display: "block", mb: 1 }, children: [
6925
7137
  "daily spend (",
6926
7138
  dateRangeCaption,
6927
7139
  ")"
6928
7140
  ] })
6929
7141
  ] }),
6930
- moduleRouteRef?.() && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Typography16.default, { variant: "caption", sx: { mt: 1, display: "block" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_core_components4.Link, { to: moduleRouteRef(), color: "primary", children: "Open LiteLLM \u2192" }) })
7142
+ moduleRouteRef?.() && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Typography17.default, { variant: "caption", sx: { mt: 1, display: "block" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_core_components5.Link, { to: moduleRouteRef(), color: "primary", children: "Open LiteLLM \u2192" }) })
6931
7143
  ] })
6932
7144
  ] });
6933
7145
  };
@@ -6936,20 +7148,20 @@ var LiteLLMHomeWidget = ({
6936
7148
  init_LiteLLMBudgetWidget();
6937
7149
 
6938
7150
  // src/components/LiteLLMBudgetGauges.tsx
6939
- var import_react15 = require("react");
7151
+ var import_react16 = require("react");
6940
7152
  var import_frontend_plugin_api6 = require("@backstage/frontend-plugin-api");
6941
- var import_Paper10 = __toESM(require("@mui/material/Paper"));
6942
- var import_Box19 = __toESM(require("@mui/material/Box"));
6943
- var import_Button8 = __toESM(require("@mui/material/Button"));
6944
- var import_Typography17 = __toESM(require("@mui/material/Typography"));
7153
+ var import_Paper11 = __toESM(require("@mui/material/Paper"));
7154
+ var import_Box20 = __toESM(require("@mui/material/Box"));
7155
+ var import_Button9 = __toESM(require("@mui/material/Button"));
7156
+ var import_Typography18 = __toESM(require("@mui/material/Typography"));
6945
7157
  var import_Skeleton8 = __toESM(require("@mui/material/Skeleton"));
6946
7158
  var import_Collapse4 = __toESM(require("@mui/material/Collapse"));
6947
7159
  var import_styles13 = require("@mui/material/styles");
6948
7160
  var import_useMediaQuery = __toESM(require("@mui/material/useMediaQuery"));
6949
7161
  var import_icons_material11 = require("@mui/icons-material");
6950
7162
  var import_recharts4 = require("recharts");
6951
- var import_core_plugin_api7 = require("@backstage/core-plugin-api");
6952
- var import_core_components5 = require("@backstage/core-components");
7163
+ var import_core_plugin_api8 = require("@backstage/core-plugin-api");
7164
+ var import_core_components6 = require("@backstage/core-components");
6953
7165
  init_useLiteLLMProfile();
6954
7166
  init_api();
6955
7167
  init_format();
@@ -6980,7 +7192,7 @@ init_GenerateKeyButton();
6980
7192
  init_BudgetLimitList();
6981
7193
  init_budget();
6982
7194
  init_routes();
6983
- var import_jsx_runtime21 = require("react/jsx-runtime");
7195
+ var import_jsx_runtime22 = require("react/jsx-runtime");
6984
7196
  var LEVEL = {
6985
7197
  key: { name: "Key", none: "No cap (unlimited)" },
6986
7198
  user: { name: "User", none: "No personal budget" },
@@ -7004,8 +7216,8 @@ function resetLabel(limit) {
7004
7216
  const window2 = fmtBudgetDuration(limit.budgetDuration);
7005
7217
  return window2 ? `resets ${window2}` : "never resets";
7006
7218
  }
7007
- var Tag = ({ children, tone, title }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7008
- import_Typography17.default,
7219
+ var Tag = ({ children, tone, title }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7220
+ import_Typography18.default,
7009
7221
  {
7010
7222
  title,
7011
7223
  sx: (theme) => ({
@@ -7022,10 +7234,10 @@ var Tag = ({ children, tone, title }) => /* @__PURE__ */ (0, import_jsx_runtime2
7022
7234
  children
7023
7235
  }
7024
7236
  );
7025
- var InlineStat = ({ label, value, hint, tone = "accent", title }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { minWidth: 0, flex: 1 }, children: [
7026
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { display: "flex", alignItems: "center", gap: 0.625, minWidth: 0 }, children: [
7027
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7028
- import_Box19.default,
7237
+ var InlineStat = ({ label, value, hint, tone = "accent", title }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { sx: { minWidth: 0, flex: 1 }, children: [
7238
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { sx: { display: "flex", alignItems: "center", gap: 0.625, minWidth: 0 }, children: [
7239
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7240
+ import_Box20.default,
7029
7241
  {
7030
7242
  sx: (theme) => ({
7031
7243
  width: 6,
@@ -7036,10 +7248,10 @@ var InlineStat = ({ label, value, hint, tone = "accent", title }) => /* @__PURE_
7036
7248
  })
7037
7249
  }
7038
7250
  ),
7039
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Tag, { children: label })
7251
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Tag, { children: label })
7040
7252
  ] }),
7041
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7042
- import_Typography17.default,
7253
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7254
+ import_Typography18.default,
7043
7255
  {
7044
7256
  title,
7045
7257
  sx: {
@@ -7055,8 +7267,8 @@ var InlineStat = ({ label, value, hint, tone = "accent", title }) => /* @__PURE_
7055
7267
  children: value
7056
7268
  }
7057
7269
  ),
7058
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7059
- import_Typography17.default,
7270
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7271
+ import_Typography18.default,
7060
7272
  {
7061
7273
  variant: "caption",
7062
7274
  color: "text.secondary",
@@ -7086,10 +7298,10 @@ var LevelRow = ({
7086
7298
  const subNote = () => {
7087
7299
  if (overCap) return "Over cap";
7088
7300
  if (extra > 0 && keysHref) {
7089
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7090
- import_Typography17.default,
7301
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
7302
+ import_Typography18.default,
7091
7303
  {
7092
- component: import_core_components5.Link,
7304
+ component: import_core_components6.Link,
7093
7305
  to: keysHref,
7094
7306
  variant: "caption",
7095
7307
  sx: {
@@ -7109,8 +7321,8 @@ var LevelRow = ({
7109
7321
  return limit?.sublabel ?? null;
7110
7322
  };
7111
7323
  const gaugeAriaLabel = limit ? `${name} budget used: ${Math.round(limit.pct)}%` : `${name} \u2014 no cap`;
7112
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7113
- import_Box19.default,
7324
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
7325
+ import_Box20.default,
7114
7326
  {
7115
7327
  sx: {
7116
7328
  display: "grid",
@@ -7121,7 +7333,7 @@ var LevelRow = ({
7121
7333
  minWidth: 0
7122
7334
  },
7123
7335
  children: [
7124
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7336
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7125
7337
  Gauge,
7126
7338
  {
7127
7339
  value: limit?.pct ?? 0,
@@ -7131,11 +7343,11 @@ var LevelRow = ({
7131
7343
  ariaLabel: gaugeAriaLabel
7132
7344
  }
7133
7345
  ),
7134
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { minWidth: 0 }, children: [
7135
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Tag, { tone: tone === "warning" || tone === "danger" ? tone : void 0, children: name }),
7136
- limit ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
7137
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7138
- import_Typography17.default,
7346
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { sx: { minWidth: 0 }, children: [
7347
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Tag, { tone: tone === "warning" || tone === "danger" ? tone : void 0, children: name }),
7348
+ limit ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
7349
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7350
+ import_Typography18.default,
7139
7351
  {
7140
7352
  variant: "caption",
7141
7353
  title: limit.sublabel ? `${limit.label} \xB7 ${limit.sublabel}` : limit.label,
@@ -7151,8 +7363,8 @@ var LevelRow = ({
7151
7363
  children: limit.label
7152
7364
  }
7153
7365
  ),
7154
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7155
- import_Typography17.default,
7366
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7367
+ import_Typography18.default,
7156
7368
  {
7157
7369
  variant: "caption",
7158
7370
  color: overCap ? "error" : "text.secondary",
@@ -7168,8 +7380,8 @@ var LevelRow = ({
7168
7380
  children: subNote()
7169
7381
  }
7170
7382
  )
7171
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7172
- import_Typography17.default,
7383
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7384
+ import_Typography18.default,
7173
7385
  {
7174
7386
  variant: "caption",
7175
7387
  color: "text.secondary",
@@ -7185,9 +7397,9 @@ var LevelRow = ({
7185
7397
  }
7186
7398
  )
7187
7399
  ] }),
7188
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { minWidth: 0, textAlign: "right" }, children: [
7189
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7190
- import_Typography17.default,
7400
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { sx: { minWidth: 0, textAlign: "right" }, children: [
7401
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7402
+ import_Typography18.default,
7191
7403
  {
7192
7404
  title: limit ? `${fmtUsd(limit.spend)} of ${fmtUsd(limit.budget)}` : void 0,
7193
7405
  sx: {
@@ -7204,8 +7416,8 @@ var LevelRow = ({
7204
7416
  children: amountCaption(limit)
7205
7417
  }
7206
7418
  ),
7207
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7208
- import_Typography17.default,
7419
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7420
+ import_Typography18.default,
7209
7421
  {
7210
7422
  variant: "caption",
7211
7423
  color: "text.secondary",
@@ -7236,11 +7448,11 @@ function amountNote(limit) {
7236
7448
  var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, maxBudget }) => {
7237
7449
  const renderPlot = () => {
7238
7450
  if (loading) {
7239
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Skeleton8.default, { variant: "rectangular", width: "100%", height: "100%" });
7451
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Skeleton8.default, { variant: "rectangular", width: "100%", height: "100%" });
7240
7452
  }
7241
7453
  if (data.length === 0) {
7242
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7243
- import_Box19.default,
7454
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7455
+ import_Box20.default,
7244
7456
  {
7245
7457
  display: "flex",
7246
7458
  justifyContent: "center",
@@ -7251,10 +7463,10 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
7251
7463
  }
7252
7464
  );
7253
7465
  }
7254
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_recharts4.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_recharts4.AreaChart, { data, margin: { top: 4, right: 0, bottom: 0, left: 0 }, children: [
7255
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_recharts4.XAxis, { dataKey: "date", hide: true }),
7256
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_recharts4.Tooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ChartTooltip, { valueFormatter: fmtUsd }) }),
7257
- maxBudget !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7466
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_recharts4.ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_recharts4.AreaChart, { data, margin: { top: 4, right: 0, bottom: 0, left: 0 }, children: [
7467
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_recharts4.XAxis, { dataKey: "date", hide: true }),
7468
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_recharts4.Tooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ChartTooltip, { valueFormatter: fmtUsd }) }),
7469
+ maxBudget !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7258
7470
  import_recharts4.ReferenceLine,
7259
7471
  {
7260
7472
  y: maxBudget,
@@ -7263,7 +7475,7 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
7263
7475
  strokeWidth: 1
7264
7476
  }
7265
7477
  ),
7266
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7478
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7267
7479
  import_recharts4.Area,
7268
7480
  {
7269
7481
  type: "monotone",
@@ -7285,10 +7497,10 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
7285
7497
  if (data.length === 0) return "No spend this month";
7286
7498
  return mtdCaption();
7287
7499
  })();
7288
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { role: "img", "aria-label": sparklineAriaLabel(data), sx: { minWidth: 0 }, children: [
7289
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Box19.default, { sx: { height, width: "100%" }, children: renderPlot() }),
7290
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7291
- import_Box19.default,
7500
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { role: "img", "aria-label": sparklineAriaLabel(data), sx: { minWidth: 0 }, children: [
7501
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Box20.default, { sx: { height, width: "100%" }, children: renderPlot() }),
7502
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
7503
+ import_Box20.default,
7292
7504
  {
7293
7505
  sx: {
7294
7506
  display: "flex",
@@ -7299,10 +7511,10 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
7299
7511
  minWidth: 0
7300
7512
  },
7301
7513
  children: [
7302
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { display: "flex", alignItems: "baseline", gap: 0.75, minWidth: 0 }, children: [
7303
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Tag, { children: "Spent (mtd)" }),
7304
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7305
- import_Typography17.default,
7514
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { sx: { display: "flex", alignItems: "baseline", gap: 0.75, minWidth: 0 }, children: [
7515
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Tag, { children: "Spent (mtd)" }),
7516
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7517
+ import_Typography18.default,
7306
7518
  {
7307
7519
  variant: "caption",
7308
7520
  color: "text.secondary",
@@ -7311,8 +7523,8 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
7311
7523
  }
7312
7524
  )
7313
7525
  ] }),
7314
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7315
- import_Typography17.default,
7526
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7527
+ import_Typography18.default,
7316
7528
  {
7317
7529
  title: loading || usageUnavailable ? void 0 : `${fmtUsd(mtdSpend)} spent month to date`,
7318
7530
  sx: {
@@ -7356,33 +7568,33 @@ var LiteLLMBudgetGauges = ({
7356
7568
  teams: propTeams,
7357
7569
  keys: propKeys
7358
7570
  }) => {
7359
- const api = (0, import_core_plugin_api7.useApi)(liteLlmApiRef);
7571
+ const api = (0, import_core_plugin_api8.useApi)(liteLlmApiRef);
7360
7572
  const theme = (0, import_styles13.useTheme)();
7361
7573
  const isSmallScreen = (0, import_useMediaQuery.default)(theme.breakpoints.down("sm"));
7362
7574
  const gaugeSize = isSmallScreen ? Math.min(48, size) : size;
7363
- const expandedRegionId = (0, import_react15.useId)();
7575
+ const expandedRegionId = (0, import_react16.useId)();
7364
7576
  const moduleRouteRef = (0, import_frontend_plugin_api6.useRouteRef)(rootRouteRef);
7365
7577
  const moduleHref = propModuleHref ?? moduleRouteRef?.();
7366
7578
  const { userInfo: hookUserInfo, teams: hookTeams, keys: hookKeys, loading: profileLoading, error: profileError } = useLiteLLMProfile();
7367
- const [usageLoading, setUsageLoading] = (0, import_react15.useState)(true);
7368
- const [usageError, setUsageError] = (0, import_react15.useState)(null);
7369
- const [dailySpend, setDailySpend] = (0, import_react15.useState)([]);
7370
- const [mtdSpend, setMtdSpend] = (0, import_react15.useState)(0);
7579
+ const [usageLoading, setUsageLoading] = (0, import_react16.useState)(true);
7580
+ const [usageError, setUsageError] = (0, import_react16.useState)(null);
7581
+ const [dailySpend, setDailySpend] = (0, import_react16.useState)([]);
7582
+ const [mtdSpend, setMtdSpend] = (0, import_react16.useState)(0);
7371
7583
  const user = propUserInfo !== void 0 ? propUserInfo : hookUserInfo;
7372
7584
  const teams = propTeams !== void 0 ? propTeams : hookTeams;
7373
7585
  const keys = propKeys !== void 0 ? propKeys : hookKeys;
7374
7586
  const loading = propUserInfo === void 0 ? profileLoading : usageLoading;
7375
7587
  const error = propUserInfo === void 0 ? profileError : usageError;
7376
7588
  const isControlled = expanded !== void 0;
7377
- const [uncontrolledExpanded, setUncontrolledExpanded] = (0, import_react15.useState)(defaultExpanded);
7589
+ const [uncontrolledExpanded, setUncontrolledExpanded] = (0, import_react16.useState)(defaultExpanded);
7378
7590
  const isExpanded = isControlled ? expanded : uncontrolledExpanded;
7379
- const toggleExpanded = (0, import_react15.useCallback)(() => {
7591
+ const toggleExpanded = (0, import_react16.useCallback)(() => {
7380
7592
  const next = !isExpanded;
7381
7593
  if (!isControlled) setUncontrolledExpanded(next);
7382
7594
  onExpandedChange?.(next);
7383
7595
  }, [isControlled, isExpanded, onExpandedChange]);
7384
7596
  const keysTabHref = keysHref ?? (moduleHref ? `${moduleHref}?tab=keys` : void 0);
7385
- (0, import_react15.useEffect)(() => {
7597
+ (0, import_react16.useEffect)(() => {
7386
7598
  let cancelled = false;
7387
7599
  setUsageLoading(true);
7388
7600
  setUsageError(null);
@@ -7410,21 +7622,21 @@ var LiteLLMBudgetGauges = ({
7410
7622
  cancelled = true;
7411
7623
  };
7412
7624
  }, [api]);
7413
- const summary = (0, import_react15.useMemo)(
7625
+ const summary = (0, import_react16.useMemo)(
7414
7626
  () => buildBudgetSummary(user, teams, keys, keys.length),
7415
7627
  [user, teams, keys]
7416
7628
  );
7417
- const gauges = (0, import_react15.useMemo)(() => buildBudgetGauges(summary), [summary]);
7418
- const headline = (0, import_react15.useMemo)(() => budgetHeadline(summary), [summary]);
7419
- const expandedSummary = (0, import_react15.useMemo)(
7629
+ const gauges = (0, import_react16.useMemo)(() => buildBudgetGauges(summary), [summary]);
7630
+ const headline = (0, import_react16.useMemo)(() => budgetHeadline(summary), [summary]);
7631
+ const expandedSummary = (0, import_react16.useMemo)(
7420
7632
  () => buildBudgetSummary(user, teams, keys, maxExpandedKeys),
7421
7633
  [user, teams, keys, maxExpandedKeys]
7422
7634
  );
7423
- const expandedLimits = (0, import_react15.useMemo)(
7635
+ const expandedLimits = (0, import_react16.useMemo)(
7424
7636
  () => allBudgetLimits(expandedSummary),
7425
7637
  [expandedSummary]
7426
7638
  );
7427
- const viewState = (0, import_react15.useMemo)(
7639
+ const viewState = (0, import_react16.useMemo)(
7428
7640
  () => widgetViewState({
7429
7641
  loading,
7430
7642
  error: profileError,
@@ -7441,7 +7653,7 @@ var LiteLLMBudgetGauges = ({
7441
7653
  const yesterdaySpend = dailySpend.some((d) => d.date === toLocalDay(yesterday)) ? spendOnDay(dailySpend, yesterday) : null;
7442
7654
  const todayHint = yesterdaySpend === null ? void 0 : `vs ${fmtUsd(yesterdaySpend)} yesterday`;
7443
7655
  const summaryText = headline.count === 0 ? "no limits apply" : `${headline.count} limit${headline.count === 1 ? "" : "s"}`;
7444
- const resolvedCtas = (0, import_react15.useMemo)(() => {
7656
+ const resolvedCtas = (0, import_react16.useMemo)(() => {
7445
7657
  return resolveCtas({
7446
7658
  ctas,
7447
7659
  hasKeys: (keys?.length ?? 0) > 0,
@@ -7455,20 +7667,20 @@ var LiteLLMBudgetGauges = ({
7455
7667
  switch (cta.kind) {
7456
7668
  case "new-key":
7457
7669
  if (!onCreateKey && !moduleHref) return null;
7458
- return onCreateKey ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(GenerateKeyButton, { size: "small", label, onClick: onCreateKey }, key) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(GenerateKeyButton, { size: "small", label, to: `${moduleHref}?generate=1` }, key);
7670
+ return onCreateKey ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GenerateKeyButton, { size: "small", label, onClick: onCreateKey }, key) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GenerateKeyButton, { size: "small", label, to: `${moduleHref}?generate=1` }, key);
7459
7671
  case "module":
7460
7672
  if (!moduleHref) return null;
7461
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Button8.default, { size: "small", variant: "text", component: import_core_components5.Link, to: moduleHref, children: label }, key);
7673
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Button9.default, { size: "small", variant: "text", component: import_core_components6.Link, to: moduleHref, children: label }, key);
7462
7674
  case "all-limits":
7463
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7464
- import_Button8.default,
7675
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7676
+ import_Button9.default,
7465
7677
  {
7466
7678
  size: "small",
7467
7679
  variant: "text",
7468
7680
  onClick: toggleExpanded,
7469
7681
  "aria-expanded": isExpanded,
7470
7682
  "aria-controls": expandedRegionId,
7471
- endIcon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7683
+ endIcon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7472
7684
  import_icons_material11.ExpandMore,
7473
7685
  {
7474
7686
  sx: (muiTheme) => ({
@@ -7487,11 +7699,11 @@ var LiteLLMBudgetGauges = ({
7487
7699
  }
7488
7700
  };
7489
7701
  const hasFooter = resolvedCtas.length > 0 || !!action;
7490
- const Wrapper = bare ? import_Box19.default : import_Paper10.default;
7491
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Wrapper, { sx: bare ? { height: "100%" } : { p: 2, height: "100%" }, children: [
7492
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1.5, minWidth: 0, justifyContent: bare ? "flex-end" : void 0 }, children: [
7493
- !bare && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Typography17.default, { variant: "h6", lineHeight: 1.2, sx: { minWidth: 0, flex: 1 }, children: title }),
7494
- !loading && !error && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7702
+ const Wrapper = bare ? import_Box20.default : import_Paper11.default;
7703
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Wrapper, { sx: bare ? { height: "100%" } : { p: 2, height: "100%" }, children: [
7704
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 1.5, minWidth: 0, justifyContent: bare ? "flex-end" : void 0 }, children: [
7705
+ !bare && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Typography18.default, { variant: "h6", lineHeight: 1.2, sx: { minWidth: 0, flex: 1 }, children: title }),
7706
+ !loading && !error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7495
7707
  StatusPill,
7496
7708
  {
7497
7709
  label: summaryText,
@@ -7500,19 +7712,19 @@ var LiteLLMBudgetGauges = ({
7500
7712
  }
7501
7713
  )
7502
7714
  ] }),
7503
- viewState.kind === "loading" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Box19.default, { sx: { display: "flex", flexDirection: "column", gap: 1.25, minHeight: size }, children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { display: "flex", alignItems: "center", gap: 1.25 }, children: [
7504
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Skeleton8.default, { variant: "circular", width: size, height: size }),
7505
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Box19.default, { sx: { flex: 1 }, children: [
7506
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Skeleton8.default, { variant: "text", width: "70%", height: 12, sx: { mb: 0.25 } }),
7507
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Skeleton8.default, { variant: "text", width: "45%", height: 11 })
7715
+ viewState.kind === "loading" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Box20.default, { sx: { display: "flex", flexDirection: "column", gap: 1.25, minHeight: size }, children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { sx: { display: "flex", alignItems: "center", gap: 1.25 }, children: [
7716
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Skeleton8.default, { variant: "circular", width: size, height: size }),
7717
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_Box20.default, { sx: { flex: 1 }, children: [
7718
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Skeleton8.default, { variant: "text", width: "70%", height: 12, sx: { mb: 0.25 } }),
7719
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Skeleton8.default, { variant: "text", width: "45%", height: 11 })
7508
7720
  ] }),
7509
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Skeleton8.default, { variant: "text", width: 64, height: 12 })
7721
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Skeleton8.default, { variant: "text", width: 64, height: 12 })
7510
7722
  ] }, i)) }),
7511
- viewState.kind === "error" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Typography17.default, { variant: "body2", color: "text.secondary", sx: { mt: 0.5 }, children: viewState.message }),
7512
- viewState.kind === "unprovisioned" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Typography17.default, { variant: "body2", color: "text.secondary", sx: { mt: 0.5 }, children: UNPROVISIONED_MSG }),
7513
- viewState.kind === "ready" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
7514
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7515
- import_Box19.default,
7723
+ viewState.kind === "error" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Typography18.default, { variant: "body2", color: "text.secondary", sx: { mt: 0.5 }, children: viewState.message }),
7724
+ viewState.kind === "unprovisioned" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Typography18.default, { variant: "body2", color: "text.secondary", sx: { mt: 0.5 }, children: UNPROVISIONED_MSG }),
7725
+ viewState.kind === "ready" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
7726
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
7727
+ import_Box20.default,
7516
7728
  {
7517
7729
  sx: {
7518
7730
  display: "flex",
@@ -7522,7 +7734,7 @@ var LiteLLMBudgetGauges = ({
7522
7734
  minWidth: 0
7523
7735
  },
7524
7736
  children: [
7525
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7737
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7526
7738
  InlineStat,
7527
7739
  {
7528
7740
  label: "Today spent",
@@ -7532,8 +7744,8 @@ var LiteLLMBudgetGauges = ({
7532
7744
  title: usageLoading || viewState.usageUnavailable ? void 0 : "Spend since local midnight"
7533
7745
  }
7534
7746
  ),
7535
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Box19.default, { sx: { width: "1px", bgcolor: "divider", flexShrink: 0 } }),
7536
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7747
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Box20.default, { sx: { width: "1px", bgcolor: "divider", flexShrink: 0 } }),
7748
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7537
7749
  InlineStat,
7538
7750
  {
7539
7751
  label: "Month to date",
@@ -7545,15 +7757,15 @@ var LiteLLMBudgetGauges = ({
7545
7757
  ]
7546
7758
  }
7547
7759
  ),
7548
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Box19.default, { sx: { borderTop: "1px solid", borderColor: "divider" }, children: gauges.map((gauge, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7549
- import_Box19.default,
7760
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Box20.default, { sx: { borderTop: "1px solid", borderColor: "divider" }, children: gauges.map((gauge, i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7761
+ import_Box20.default,
7550
7762
  {
7551
7763
  sx: i === 0 ? void 0 : { borderTop: "1px solid", borderColor: "divider" },
7552
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LevelRow, { gauge, size: gaugeSize, keysHref: keysTabHref })
7764
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LevelRow, { gauge, size: gaugeSize, keysHref: keysTabHref })
7553
7765
  },
7554
7766
  gauge.kind
7555
7767
  )) }),
7556
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Box19.default, { sx: { mt: 1.25 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7768
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Box20.default, { sx: { mt: 1.25 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7557
7769
  SpendStrip,
7558
7770
  {
7559
7771
  data: dailySpend,
@@ -7564,8 +7776,8 @@ var LiteLLMBudgetGauges = ({
7564
7776
  maxBudget: user?.max_budget ?? void 0
7565
7777
  }
7566
7778
  ) }),
7567
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Collapse4.default, { in: isExpanded, unmountOnExit: true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7568
- import_Box19.default,
7779
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Collapse4.default, { in: isExpanded, unmountOnExit: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7780
+ import_Box20.default,
7569
7781
  {
7570
7782
  id: expandedRegionId,
7571
7783
  sx: {
@@ -7575,7 +7787,7 @@ var LiteLLMBudgetGauges = ({
7575
7787
  maxHeight: 300,
7576
7788
  overflowY: "auto"
7577
7789
  },
7578
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LimitListPanel, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7790
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LimitListPanel, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
7579
7791
  BudgetLimitList,
7580
7792
  {
7581
7793
  limits: expandedLimits,
@@ -7586,8 +7798,8 @@ var LiteLLMBudgetGauges = ({
7586
7798
  }
7587
7799
  ) })
7588
7800
  ] }),
7589
- hasFooter && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7590
- import_Box19.default,
7801
+ hasFooter && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
7802
+ import_Box20.default,
7591
7803
  {
7592
7804
  sx: (muiTheme) => ({
7593
7805
  mt: 2,