@acarmisc/backstage-plugin-litellm 0.45.0 → 0.46.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
@@ -5084,47 +5084,70 @@ function budgetStatValue(hidden, budget) {
5084
5084
  if (budget > 0) return fmtUsd2(budget);
5085
5085
  return "Unlimited";
5086
5086
  }
5087
- var fmtUsd2, monoSx, MemberUsageTable, TeamKeyUsageTable, TeamCard, TeamUsage;
5087
+ var fmtUsd2, monoSx, fmtShare, MemberUsageCards, TeamKeyUsageTable, TeamCard, TeamUsage;
5088
5088
  var init_TeamUsage = __esm({
5089
5089
  "src/components/TeamUsage.tsx"() {
5090
5090
  "use strict";
5091
5091
  init_ui();
5092
5092
  fmtUsd2 = (n) => `$${(n ?? 0).toFixed(2)}`;
5093
5093
  monoSx = { fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace", fontSize: 11 };
5094
- MemberUsageTable = ({ usage }) => {
5094
+ fmtShare = (pct) => `${pct.toFixed(pct > 0 && pct < 1 ? 1 : 0)}%`;
5095
+ MemberUsageCards = ({ usage }) => {
5095
5096
  const hidden = usage.budget_hidden === true;
5096
5097
  if (!usage.members.length) {
5097
5098
  return /* @__PURE__ */ jsx15(Typography12, { variant: "body2", color: "text.secondary", children: "No members or activity in this period." });
5098
5099
  }
5099
- return /* @__PURE__ */ jsx15(TableContainer4, { component: Paper8, variant: "outlined", sx: { borderRadius: 1.5 }, children: /* @__PURE__ */ jsxs14(Table4, { size: "small", sx: dataTableSx, "aria-label": "Usage by member", children: [
5100
- /* @__PURE__ */ jsx15(TableHead4, { children: /* @__PURE__ */ jsxs14(TableRow4, { children: [
5101
- /* @__PURE__ */ jsx15(TableCell4, { children: "Member" }),
5102
- !hidden && /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Spend" }),
5103
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Share" }),
5104
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Tokens" }),
5105
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Requests" }),
5106
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Success" }),
5107
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: "Keys" })
5108
- ] }) }),
5109
- /* @__PURE__ */ jsx15(TableBody4, { children: usage.members.map((m) => {
5110
- const name = m.display_name ?? m.user_email ?? m.user_id;
5111
- let sub = null;
5112
- if (m.display_name) sub = m.user_email ?? m.user_id;
5113
- else if (m.user_email && m.user_id !== m.user_email) sub = m.user_id;
5114
- return /* @__PURE__ */ jsxs14(TableRow4, { children: [
5115
- /* @__PURE__ */ jsx15(TableCell4, { children: m.user_id === null ? /* @__PURE__ */ jsx15(MuiTooltip, { title: "Activity of keys that were deleted or have no owner", children: /* @__PURE__ */ jsx15(Typography12, { variant: "body2", color: "text.secondary", sx: { fontStyle: "italic" }, children: "Unattributed" }) }) : /* @__PURE__ */ jsxs14(Fragment8, { children: [
5116
- /* @__PURE__ */ jsx15(Typography12, { variant: "body2", children: name }),
5117
- sub && /* @__PURE__ */ jsx15(Typography12, { variant: "caption", color: "text.secondary", sx: monoSx, children: sub })
5118
- ] }) }),
5119
- !hidden && /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: fmtUsd2(m.spend) }),
5120
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: `${m.spend_share_pct.toFixed(m.spend_share_pct > 0 && m.spend_share_pct < 1 ? 1 : 0)}%` }),
5121
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: fmtCompact(m.total_tokens) }),
5122
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: m.api_requests.toLocaleString() }),
5123
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: m.success_rate === null ? "\u2014" : `${m.success_rate.toFixed(0)}%` }),
5124
- /* @__PURE__ */ jsx15(TableCell4, { align: "right", children: m.user_id === null ? "\u2014" : m.key_count })
5125
- ] }, m.user_id ?? "__unattributed");
5126
- }) })
5127
- ] }) });
5100
+ const people = usage.members.filter((m) => m.user_id !== null).length;
5101
+ return /* @__PURE__ */ jsxs14(Box14, { children: [
5102
+ !hidden && people > 0 && /* @__PURE__ */ jsx15(Typography12, { variant: "caption", color: "text.secondary", sx: { display: "block", mb: 1 }, children: `Team spend ${fmtUsd2(usage.total_spend)} \xB7 avg ${fmtUsd2(usage.total_spend / people)} per member` }),
5103
+ /* @__PURE__ */ jsx15(
5104
+ Box14,
5105
+ {
5106
+ role: "list",
5107
+ "aria-label": "Usage by member",
5108
+ sx: { display: "grid", gap: 1.5, gridTemplateColumns: "repeat(auto-fill, minmax(230px, 1fr))" },
5109
+ children: usage.members.map((m) => {
5110
+ const name = m.display_name ?? m.user_email ?? m.user_id;
5111
+ let sub = null;
5112
+ if (m.display_name) sub = m.user_email ?? m.user_id;
5113
+ else if (m.user_email && m.user_id !== m.user_email) sub = m.user_id;
5114
+ const stats = [
5115
+ ["Tokens", fmtCompact(m.total_tokens)],
5116
+ ["Requests", m.api_requests.toLocaleString()],
5117
+ ["Success", m.success_rate === null ? "\u2014" : `${m.success_rate.toFixed(0)}%`],
5118
+ ["Keys", m.user_id === null ? "\u2014" : String(m.key_count)]
5119
+ ];
5120
+ return /* @__PURE__ */ jsxs14(
5121
+ Paper8,
5122
+ {
5123
+ role: "listitem",
5124
+ variant: "outlined",
5125
+ sx: { borderRadius: 1.5, p: 1.5, minWidth: 0 },
5126
+ children: [
5127
+ /* @__PURE__ */ jsxs14(Box14, { display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 1, children: [
5128
+ /* @__PURE__ */ jsx15(Box14, { minWidth: 0, children: m.user_id === null ? /* @__PURE__ */ jsx15(MuiTooltip, { title: "Activity of keys that were deleted or have no owner", children: /* @__PURE__ */ jsx15(Typography12, { variant: "body2", color: "text.secondary", sx: { fontStyle: "italic" }, children: "Unattributed" }) }) : /* @__PURE__ */ jsxs14(Fragment8, { children: [
5129
+ /* @__PURE__ */ jsx15(Typography12, { variant: "body2", fontWeight: 600, noWrap: true, children: name }),
5130
+ sub && /* @__PURE__ */ jsx15(Typography12, { variant: "caption", color: "text.secondary", noWrap: true, sx: { ...monoSx, display: "block" }, children: sub })
5131
+ ] }) }),
5132
+ m.role && /* @__PURE__ */ jsx15(StatusPill, { label: m.role, tone: m.role === "admin" ? "accent" : "neutral", dot: false })
5133
+ ] }),
5134
+ /* @__PURE__ */ jsxs14(Box14, { mt: 1.5, display: "flex", alignItems: "baseline", justifyContent: "space-between", children: [
5135
+ /* @__PURE__ */ jsx15(Typography12, { variant: "h6", component: "span", sx: { lineHeight: 1.2 }, children: hidden ? fmtShare(m.spend_share_pct) : fmtUsd2(m.spend) }),
5136
+ /* @__PURE__ */ jsx15(Typography12, { variant: "caption", color: "text.secondary", children: hidden ? "of team usage" : `${fmtShare(m.spend_share_pct)} of team` })
5137
+ ] }),
5138
+ /* @__PURE__ */ jsx15(Box14, { mt: 0.75, children: /* @__PURE__ */ jsx15(Meter, { value: m.spend_share_pct, ariaLabel: `${name ?? "Unattributed"} share of team spend` }) }),
5139
+ /* @__PURE__ */ jsx15(Box14, { mt: 1.5, display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 0.5, children: stats.map(([label, value]) => /* @__PURE__ */ jsxs14(Box14, { children: [
5140
+ /* @__PURE__ */ jsx15(Typography12, { variant: "caption", color: "text.secondary", display: "block", children: label }),
5141
+ /* @__PURE__ */ jsx15(Typography12, { variant: "body2", children: value })
5142
+ ] }, label)) })
5143
+ ]
5144
+ },
5145
+ m.user_id ?? "__unattributed"
5146
+ );
5147
+ })
5148
+ }
5149
+ )
5150
+ ] });
5128
5151
  };
5129
5152
  TeamKeyUsageTable = ({ usage }) => {
5130
5153
  const hidden = usage.budget_hidden === true;
@@ -5367,7 +5390,7 @@ var init_TeamUsage = __esm({
5367
5390
  renderDailySpendSection(),
5368
5391
  (memberUsageLoading || memberUsage || memberUsageFailed) && /* @__PURE__ */ jsxs14(Box14, { mb: 2.5, children: [
5369
5392
  sectionLabel("Usage by member"),
5370
- memberUsage && /* @__PURE__ */ jsx15(MemberUsageTable, { usage: memberUsage }),
5393
+ memberUsage && /* @__PURE__ */ jsx15(MemberUsageCards, { usage: memberUsage }),
5371
5394
  !memberUsage && memberUsageFailed && /* @__PURE__ */ jsx15(Typography12, { variant: "caption", color: "text.secondary", children: "Could not load per-member usage" }),
5372
5395
  !memberUsage && !memberUsageFailed && /* @__PURE__ */ jsx15(Box14, { display: "flex", justifyContent: "center", py: 2, children: /* @__PURE__ */ jsx15(CircularProgress4, { size: 22 }) })
5373
5396
  ] }),
@@ -5377,7 +5400,7 @@ var init_TeamUsage = __esm({
5377
5400
  !keyUsage && keyUsageFailed && /* @__PURE__ */ jsx15(Typography12, { variant: "caption", color: "text.secondary", children: "Could not load per-key usage" }),
5378
5401
  !keyUsage && !keyUsageFailed && /* @__PURE__ */ jsx15(Box14, { display: "flex", justifyContent: "center", py: 2, children: /* @__PURE__ */ jsx15(CircularProgress4, { size: 22 }) })
5379
5402
  ] }),
5380
- /* @__PURE__ */ jsxs14(Box14, { children: [
5403
+ !memberUsage && /* @__PURE__ */ jsxs14(Box14, { children: [
5381
5404
  sectionLabel("Members"),
5382
5405
  team.members_with_roles?.length ? /* @__PURE__ */ jsx15(
5383
5406
  TableContainer4,