@acarmisc/backstage-plugin-litellm 0.21.0 → 0.21.1

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/budget.d.ts CHANGED
@@ -41,12 +41,13 @@ export interface BudgetSummary {
41
41
  export declare function buildBudgetSummary(user: UserInfo | null, teams: TeamInfo[], keys: VirtualKey[], maxKeys?: number): BudgetSummary;
42
42
  /**
43
43
  * One-line summary of a `BudgetSummary`, for a collapsed/compact header:
44
- * how many concrete limits the user is subject to, and how close the
45
- * closest one is to its cap. `closestPct` is null when there are no limits.
44
+ * how many concrete limits the user is subject to, and the one closest to
45
+ * its cap — kept as the whole `BudgetLimit` so the caller can name its
46
+ * level (key / personal / team). `closest` is null when there are no limits.
46
47
  */
47
48
  export declare function budgetHeadline(summary: BudgetSummary): {
48
49
  count: number;
49
- closestPct: number | null;
50
+ closest: BudgetLimit | null;
50
51
  };
51
52
  /** "30d" → "every 30 days"; "1d" → "daily". Returns null when duration is unset. */
52
53
  export declare function fmtBudgetDuration(duration?: string): string | null;
package/dist/index.cjs.js CHANGED
@@ -2809,16 +2809,14 @@ function buildBudgetSummary(user, teams, keys, maxKeys = 3) {
2809
2809
  };
2810
2810
  }
2811
2811
  function budgetHeadline(summary) {
2812
- const pcts = [
2813
- ...summary.keys.map((k) => k.pct),
2814
- ...summary.user ? [summary.user.pct] : [],
2815
- ...summary.teams.map((t) => t.pct)
2812
+ const all = [
2813
+ ...summary.keys,
2814
+ ...summary.user ? [summary.user] : [],
2815
+ ...summary.teams
2816
2816
  ];
2817
2817
  const count = summary.keys.length + summary.hiddenBudgetedKeys + (summary.user ? 1 : 0) + summary.teams.length;
2818
- return {
2819
- count,
2820
- closestPct: pcts.length ? Math.max(...pcts) : null
2821
- };
2818
+ const closest = all.length ? all.reduce((a, b) => b.pct > a.pct ? b : a) : null;
2819
+ return { count, closest };
2822
2820
  }
2823
2821
  function fmtBudgetDuration(duration) {
2824
2822
  if (!duration) return null;
@@ -2857,7 +2855,7 @@ function levelToneColor(tone, theme) {
2857
2855
  return theme.palette.primary.main;
2858
2856
  }
2859
2857
  }
2860
- var import_react7, import_Paper5, import_Box7, import_Typography7, import_CircularProgress4, import_Alert3, import_Collapse, import_IconButton4, import_icons_material5, import_styles4, import_core_plugin_api3, LevelFrame, EmptyLimitCard, LimitCard, TaggedLimit, FullBody, CompactBody, LiteLLMBudgetWidget;
2858
+ var import_react7, import_Paper5, import_Box7, import_Typography7, import_CircularProgress4, import_Alert3, import_Collapse, import_IconButton4, import_icons_material5, import_styles4, import_core_plugin_api3, LevelFrame, EmptyLimitCard, LimitCard, CLOSEST_LEVEL_LABEL, TaggedLimit, FullBody, CompactBody, LiteLLMBudgetWidget;
2861
2859
  var init_LiteLLMBudgetWidget = __esm({
2862
2860
  "src/components/LiteLLMBudgetWidget.tsx"() {
2863
2861
  "use strict";
@@ -2980,6 +2978,11 @@ var init_LiteLLMBudgetWidget = __esm({
2980
2978
  /* @__PURE__ */ import_react7.default.createElement(import_Typography7.default, { variant: "caption", color: "text.secondary" }, fmtBudgetDuration(limit.budgetDuration) ? `resets ${fmtBudgetDuration(limit.budgetDuration)}` : "never resets")
2981
2979
  ));
2982
2980
  };
2981
+ CLOSEST_LEVEL_LABEL = {
2982
+ key: "key",
2983
+ user: "personal",
2984
+ team: "team"
2985
+ };
2983
2986
  TaggedLimit = ({ limit }) => {
2984
2987
  const tone = budgetTone2(limit.pct);
2985
2988
  return /* @__PURE__ */ import_react7.default.createElement(import_Box7.default, null, /* @__PURE__ */ import_react7.default.createElement(
@@ -3086,7 +3089,9 @@ var init_LiteLLMBudgetWidget = __esm({
3086
3089
  );
3087
3090
  const headline = (0, import_react7.useMemo)(() => budgetHeadline(summary), [summary]);
3088
3091
  const limitsWord = `${headline.count} limit${headline.count === 1 ? "" : "s"}`;
3089
- const closestWord = headline.closestPct === null ? "" : ` \xB7 closest ${Math.round(headline.closestPct)}%`;
3092
+ const closestWord = headline.closest === null ? "" : ` \xB7 closest: ${CLOSEST_LEVEL_LABEL[headline.closest.kind]} ${Math.round(
3093
+ headline.closest.pct
3094
+ )}%`;
3090
3095
  const summaryText = headline.count === 0 ? "no limits apply" : `${limitsWord}${closestWord}`;
3091
3096
  const body = /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, loading && /* @__PURE__ */ import_react7.default.createElement(import_Box7.default, { display: "flex", justifyContent: "center", alignItems: "center", minHeight: 140 }, /* @__PURE__ */ import_react7.default.createElement(import_CircularProgress4.default, { size: 32 })), !loading && error && /* @__PURE__ */ import_react7.default.createElement(import_Alert3.default, { severity: "error", sx: { mt: 0.5 } }, error), !loading && !error && (compact ? /* @__PURE__ */ import_react7.default.createElement(CompactBody, { summary }) : /* @__PURE__ */ import_react7.default.createElement(FullBody, { summary })));
3092
3097
  return /* @__PURE__ */ import_react7.default.createElement(import_Paper5.default, { sx: { p: 2 } }, collapsible ? /* @__PURE__ */ import_react7.default.createElement(
@@ -3102,7 +3107,13 @@ var init_LiteLLMBudgetWidget = __esm({
3102
3107
  mb: expanded ? 1.5 : 0
3103
3108
  }
3104
3109
  },
3105
- /* @__PURE__ */ import_react7.default.createElement(import_Box7.default, { sx: { minWidth: 0, flex: 1, display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" } }, /* @__PURE__ */ import_react7.default.createElement(import_Typography7.default, { variant: "h6", lineHeight: 1.2 }, title), !loading && !error && /* @__PURE__ */ import_react7.default.createElement(StatusPill, { label: summaryText, tone: budgetTone2(headline.closestPct ?? 0) })),
3110
+ /* @__PURE__ */ import_react7.default.createElement(import_Box7.default, { sx: { minWidth: 0, flex: 1 } }, /* @__PURE__ */ import_react7.default.createElement(import_Typography7.default, { variant: "h6", lineHeight: 1.2 }, title), !loading && !error && /* @__PURE__ */ import_react7.default.createElement(import_Box7.default, { sx: { mt: 0.5 } }, /* @__PURE__ */ import_react7.default.createElement(
3111
+ StatusPill,
3112
+ {
3113
+ label: summaryText,
3114
+ tone: budgetTone2(headline.closest?.pct ?? 0)
3115
+ }
3116
+ ))),
3106
3117
  /* @__PURE__ */ import_react7.default.createElement(
3107
3118
  import_IconButton4.default,
3108
3119
  {