@acarmisc/backstage-plugin-litellm 0.29.0 → 0.31.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/components/LiteLLMBudgetGauges.d.ts +26 -14
- package/dist/homeWidgetHelpers.d.ts +13 -0
- package/dist/index.cjs.js +338 -174
- package/dist/index.cjs.js.map +3 -3
- package/dist/index.esm.js +341 -176
- package/dist/index.esm.js.map +3 -3
- package/dist/keyLabels.d.ts +15 -0
- package/package.json +3 -2
package/dist/index.esm.js
CHANGED
|
@@ -1038,16 +1038,21 @@ var init_Gauge = __esm({
|
|
|
1038
1038
|
fontSize: size <= 64 ? 15 : 18,
|
|
1039
1039
|
fontWeight: 700,
|
|
1040
1040
|
fontVariantNumeric: "tabular-nums",
|
|
1041
|
-
color: "text.primary"
|
|
1041
|
+
color: isOverCap ? "currentColor" : "text.primary"
|
|
1042
1042
|
},
|
|
1043
|
-
children:
|
|
1043
|
+
children: label ?? `${Math.round(value)}%`
|
|
1044
1044
|
}
|
|
1045
1045
|
),
|
|
1046
1046
|
caption && /* @__PURE__ */ jsx5(
|
|
1047
1047
|
Typography3,
|
|
1048
1048
|
{
|
|
1049
1049
|
variant: "caption",
|
|
1050
|
-
sx: {
|
|
1050
|
+
sx: {
|
|
1051
|
+
fontSize: 9.5,
|
|
1052
|
+
color: "text.secondary",
|
|
1053
|
+
mt: 0.25,
|
|
1054
|
+
whiteSpace: "nowrap"
|
|
1055
|
+
},
|
|
1051
1056
|
children: caption
|
|
1052
1057
|
}
|
|
1053
1058
|
)
|
|
@@ -1500,6 +1505,18 @@ function pruneCopy(n) {
|
|
|
1500
1505
|
}
|
|
1501
1506
|
return `Remove ${n} expired keys from the list. They already don't work.`;
|
|
1502
1507
|
}
|
|
1508
|
+
function blockButtonState(blocked, manage, unblock) {
|
|
1509
|
+
if (blocked) {
|
|
1510
|
+
return {
|
|
1511
|
+
label: unblock.denied ? "No permission to unblock keys" : "Unblock key",
|
|
1512
|
+
disabled: !unblock.allowed
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
return {
|
|
1516
|
+
label: manage.denied ? "No permission to block keys" : "Block key \u2014 suspends without revoking",
|
|
1517
|
+
disabled: !manage.allowed
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1503
1520
|
var init_keyLabels = __esm({
|
|
1504
1521
|
"src/keyLabels.ts"() {
|
|
1505
1522
|
"use strict";
|
|
@@ -1603,7 +1620,8 @@ import { ContentCopy, Delete, Edit, Autorenew, Search, Lock, LockOpen, Check, Cl
|
|
|
1603
1620
|
import { usePermission } from "@backstage/plugin-permission-react";
|
|
1604
1621
|
import {
|
|
1605
1622
|
litellmKeyManagePermission,
|
|
1606
|
-
litellmKeyRevokePermission
|
|
1623
|
+
litellmKeyRevokePermission,
|
|
1624
|
+
litellmKeyUnblockPermission
|
|
1607
1625
|
} from "@acarmisc/backstage-plugin-litellm-common";
|
|
1608
1626
|
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1609
1627
|
function expiryChipLabel(status, expiresAt) {
|
|
@@ -1717,10 +1735,13 @@ var init_KeysTable = __esm({
|
|
|
1717
1735
|
}) => {
|
|
1718
1736
|
const managePermission = usePermission({ permission: litellmKeyManagePermission });
|
|
1719
1737
|
const revokePermission = usePermission({ permission: litellmKeyRevokePermission });
|
|
1738
|
+
const unblockPermission = usePermission({ permission: litellmKeyUnblockPermission });
|
|
1720
1739
|
const canManageKeys = !managePermission.loading && managePermission.allowed;
|
|
1721
1740
|
const canRevokeKeys = !revokePermission.loading && revokePermission.allowed;
|
|
1722
1741
|
const manageDenied = !managePermission.loading && !managePermission.allowed;
|
|
1723
1742
|
const revokeDenied = !revokePermission.loading && !revokePermission.allowed;
|
|
1743
|
+
const canUnblockKeys = !unblockPermission.loading && unblockPermission.allowed;
|
|
1744
|
+
const unblockDenied = !unblockPermission.loading && !unblockPermission.allowed;
|
|
1724
1745
|
const [blockConfirmKey, setBlockConfirmKey] = useState3(null);
|
|
1725
1746
|
const [blockSubmitting, setBlockSubmitting] = useState3(false);
|
|
1726
1747
|
const [deleteConfirmKey, setDeleteConfirmKey] = useState3(null);
|
|
@@ -1839,6 +1860,11 @@ var init_KeysTable = __esm({
|
|
|
1839
1860
|
return filteredKeys.map((key) => {
|
|
1840
1861
|
const keyId = key.token ?? key.key;
|
|
1841
1862
|
const keyModels = key.models ?? [];
|
|
1863
|
+
const blockState = blockButtonState(
|
|
1864
|
+
key.blocked,
|
|
1865
|
+
{ allowed: canManageKeys, denied: manageDenied },
|
|
1866
|
+
{ allowed: canUnblockKeys, denied: unblockDenied }
|
|
1867
|
+
);
|
|
1842
1868
|
return /* @__PURE__ */ jsxs7(
|
|
1843
1869
|
TableRow,
|
|
1844
1870
|
{
|
|
@@ -1910,19 +1936,13 @@ var init_KeysTable = __esm({
|
|
|
1910
1936
|
children: /* @__PURE__ */ jsx8(Edit, { fontSize: "small" })
|
|
1911
1937
|
}
|
|
1912
1938
|
) }) }),
|
|
1913
|
-
/* @__PURE__ */ jsx8(Tooltip, { describeChild: true, title: (
|
|
1914
|
-
if (manageDenied) return "No permission to block keys";
|
|
1915
|
-
return key.blocked ? "Unblock key" : "Block key \u2014 suspends without revoking";
|
|
1916
|
-
})(), placement: "top", children: /* @__PURE__ */ jsx8("span", { children: /* @__PURE__ */ jsx8(
|
|
1939
|
+
/* @__PURE__ */ jsx8(Tooltip, { describeChild: true, title: blockState.label, placement: "top", children: /* @__PURE__ */ jsx8("span", { children: /* @__PURE__ */ jsx8(
|
|
1917
1940
|
IconButton,
|
|
1918
1941
|
{
|
|
1919
1942
|
size: "small",
|
|
1920
1943
|
onClick: () => handleToggleBlock(key),
|
|
1921
|
-
disabled: blockSubmitting ||
|
|
1922
|
-
"aria-label":
|
|
1923
|
-
if (manageDenied) return "No permission to block keys";
|
|
1924
|
-
return key.blocked ? "Unblock key" : "Block key \u2014 suspends without revoking";
|
|
1925
|
-
})(),
|
|
1944
|
+
disabled: blockSubmitting || blockState.disabled,
|
|
1945
|
+
"aria-label": blockState.label,
|
|
1926
1946
|
sx: quietIconButtonSx("warning"),
|
|
1927
1947
|
children: keyBlockIcon(blockSubmitting, key.blocked)
|
|
1928
1948
|
}
|
|
@@ -5750,7 +5770,7 @@ import {
|
|
|
5750
5770
|
litellmKeyRevokePermission as litellmKeyRevokePermission2,
|
|
5751
5771
|
litellmKeyManagePermission as litellmKeyManagePermission2,
|
|
5752
5772
|
litellmKeyResetSpendPermission as litellmKeyResetSpendPermission2,
|
|
5753
|
-
litellmKeyUnblockPermission,
|
|
5773
|
+
litellmKeyUnblockPermission as litellmKeyUnblockPermission2,
|
|
5754
5774
|
litellmAuditReadPermission,
|
|
5755
5775
|
litellmTeamCreatePermission,
|
|
5756
5776
|
litellmTeamManagePermission,
|
|
@@ -6558,6 +6578,7 @@ import { Link as Link3 } from "@backstage/core-components";
|
|
|
6558
6578
|
// src/homeWidgetHelpers.ts
|
|
6559
6579
|
init_format();
|
|
6560
6580
|
init_tokens();
|
|
6581
|
+
init_dates();
|
|
6561
6582
|
function rangeCaption(startDay, endDay) {
|
|
6562
6583
|
return `${fmtDateShort(startDay)} \u2013 ${fmtDateShort(endDay)}`;
|
|
6563
6584
|
}
|
|
@@ -6582,6 +6603,10 @@ function sparklineAriaLabel(points) {
|
|
|
6582
6603
|
const peakDate = fmtDateShort(maxPoint.date);
|
|
6583
6604
|
return `Daily spend over ${dayCount} day${dayCount === 1 ? "" : "s"}, total ${fmtUsd(total)}, peak ${fmtUsd(maxPoint.spend)} on ${peakDate}`;
|
|
6584
6605
|
}
|
|
6606
|
+
function spendOnDay(points, now = /* @__PURE__ */ new Date()) {
|
|
6607
|
+
const day = toLocalDay(now);
|
|
6608
|
+
return points.find((p) => p.date === day)?.spend ?? 0;
|
|
6609
|
+
}
|
|
6585
6610
|
function usageSummary(usage) {
|
|
6586
6611
|
if (!usage) {
|
|
6587
6612
|
return "$0.00 spent \xB7 0 in \xB7 0 out";
|
|
@@ -6810,7 +6835,76 @@ function resetLabel(limit) {
|
|
|
6810
6835
|
const window2 = fmtBudgetDuration(limit.budgetDuration);
|
|
6811
6836
|
return window2 ? `resets ${window2}` : "never resets";
|
|
6812
6837
|
}
|
|
6813
|
-
var
|
|
6838
|
+
var Tag = ({ children, tone, title }) => /* @__PURE__ */ jsx21(
|
|
6839
|
+
Typography17,
|
|
6840
|
+
{
|
|
6841
|
+
title,
|
|
6842
|
+
sx: (theme) => ({
|
|
6843
|
+
fontSize: 10.5,
|
|
6844
|
+
fontWeight: 700,
|
|
6845
|
+
letterSpacing: "0.08em",
|
|
6846
|
+
textTransform: "uppercase",
|
|
6847
|
+
lineHeight: 1.3,
|
|
6848
|
+
color: tone ? toneColor(theme, tone) : theme.palette.text.secondary,
|
|
6849
|
+
whiteSpace: "nowrap",
|
|
6850
|
+
overflow: "hidden",
|
|
6851
|
+
textOverflow: "ellipsis"
|
|
6852
|
+
}),
|
|
6853
|
+
children
|
|
6854
|
+
}
|
|
6855
|
+
);
|
|
6856
|
+
var InlineStat = ({ label, value, hint, tone = "accent", title }) => /* @__PURE__ */ jsxs19(Box19, { sx: { minWidth: 0, flex: 1 }, children: [
|
|
6857
|
+
/* @__PURE__ */ jsxs19(Box19, { sx: { display: "flex", alignItems: "center", gap: 0.625, minWidth: 0 }, children: [
|
|
6858
|
+
/* @__PURE__ */ jsx21(
|
|
6859
|
+
Box19,
|
|
6860
|
+
{
|
|
6861
|
+
sx: (theme) => ({
|
|
6862
|
+
width: 6,
|
|
6863
|
+
height: 6,
|
|
6864
|
+
borderRadius: "50%",
|
|
6865
|
+
bgcolor: toneColor(theme, tone),
|
|
6866
|
+
flexShrink: 0
|
|
6867
|
+
})
|
|
6868
|
+
}
|
|
6869
|
+
),
|
|
6870
|
+
/* @__PURE__ */ jsx21(Tag, { children: label })
|
|
6871
|
+
] }),
|
|
6872
|
+
/* @__PURE__ */ jsx21(
|
|
6873
|
+
Typography17,
|
|
6874
|
+
{
|
|
6875
|
+
title,
|
|
6876
|
+
sx: {
|
|
6877
|
+
fontSize: 19,
|
|
6878
|
+
fontWeight: 700,
|
|
6879
|
+
lineHeight: 1.15,
|
|
6880
|
+
mt: 0.25,
|
|
6881
|
+
fontVariantNumeric: "tabular-nums",
|
|
6882
|
+
whiteSpace: "nowrap",
|
|
6883
|
+
overflow: "hidden",
|
|
6884
|
+
textOverflow: "ellipsis"
|
|
6885
|
+
},
|
|
6886
|
+
children: value
|
|
6887
|
+
}
|
|
6888
|
+
),
|
|
6889
|
+
/* @__PURE__ */ jsx21(
|
|
6890
|
+
Typography17,
|
|
6891
|
+
{
|
|
6892
|
+
variant: "caption",
|
|
6893
|
+
color: "text.secondary",
|
|
6894
|
+
sx: {
|
|
6895
|
+
display: "block",
|
|
6896
|
+
mt: 0.25,
|
|
6897
|
+
fontSize: 10.5,
|
|
6898
|
+
minHeight: 14,
|
|
6899
|
+
whiteSpace: "nowrap",
|
|
6900
|
+
overflow: "hidden",
|
|
6901
|
+
textOverflow: "ellipsis"
|
|
6902
|
+
},
|
|
6903
|
+
children: hint ?? ""
|
|
6904
|
+
}
|
|
6905
|
+
)
|
|
6906
|
+
] });
|
|
6907
|
+
var LevelRow = ({
|
|
6814
6908
|
gauge,
|
|
6815
6909
|
size,
|
|
6816
6910
|
keysHref
|
|
@@ -6819,14 +6913,42 @@ var LevelGauge = ({
|
|
|
6819
6913
|
const limit = gauge.limit;
|
|
6820
6914
|
const tone = limit ? budgetTone2(limit.pct) : "neutral";
|
|
6821
6915
|
const extra = gauge.kind === "key" ? Math.max(0, gauge.count - 1) : 0;
|
|
6916
|
+
const overCap = Boolean(limit && limit.pct > 100);
|
|
6917
|
+
const subNote = () => {
|
|
6918
|
+
if (overCap) return "Over cap";
|
|
6919
|
+
if (extra > 0 && keysHref) {
|
|
6920
|
+
return /* @__PURE__ */ jsxs19(
|
|
6921
|
+
Typography17,
|
|
6922
|
+
{
|
|
6923
|
+
component: Link4,
|
|
6924
|
+
to: keysHref,
|
|
6925
|
+
variant: "caption",
|
|
6926
|
+
sx: {
|
|
6927
|
+
fontSize: 10.5,
|
|
6928
|
+
color: "primary.main",
|
|
6929
|
+
textDecoration: "none",
|
|
6930
|
+
"&:hover": { textDecoration: "underline" }
|
|
6931
|
+
},
|
|
6932
|
+
children: [
|
|
6933
|
+
"+",
|
|
6934
|
+
extra,
|
|
6935
|
+
" more"
|
|
6936
|
+
]
|
|
6937
|
+
}
|
|
6938
|
+
);
|
|
6939
|
+
}
|
|
6940
|
+
return limit?.sublabel ?? null;
|
|
6941
|
+
};
|
|
6822
6942
|
const gaugeAriaLabel = limit ? `${name} budget used: ${Math.round(limit.pct)}%` : `${name} \u2014 no cap`;
|
|
6823
6943
|
return /* @__PURE__ */ jsxs19(
|
|
6824
6944
|
Box19,
|
|
6825
6945
|
{
|
|
6826
6946
|
sx: {
|
|
6827
|
-
display: "
|
|
6828
|
-
|
|
6947
|
+
display: "grid",
|
|
6948
|
+
gridTemplateColumns: "auto minmax(0, 1fr) auto",
|
|
6829
6949
|
alignItems: "center",
|
|
6950
|
+
gap: 1.25,
|
|
6951
|
+
py: 0.75,
|
|
6830
6952
|
minWidth: 0
|
|
6831
6953
|
},
|
|
6832
6954
|
children: [
|
|
@@ -6840,84 +6962,109 @@ var LevelGauge = ({
|
|
|
6840
6962
|
ariaLabel: gaugeAriaLabel
|
|
6841
6963
|
}
|
|
6842
6964
|
),
|
|
6843
|
-
/* @__PURE__ */
|
|
6844
|
-
|
|
6845
|
-
{
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6965
|
+
/* @__PURE__ */ jsxs19(Box19, { sx: { minWidth: 0 }, children: [
|
|
6966
|
+
/* @__PURE__ */ jsx21(Tag, { tone: tone === "warning" || tone === "danger" ? tone : void 0, children: name }),
|
|
6967
|
+
limit ? /* @__PURE__ */ jsxs19(Fragment11, { children: [
|
|
6968
|
+
/* @__PURE__ */ jsx21(
|
|
6969
|
+
Typography17,
|
|
6970
|
+
{
|
|
6971
|
+
variant: "caption",
|
|
6972
|
+
title: limit.sublabel ? `${limit.label} \xB7 ${limit.sublabel}` : limit.label,
|
|
6973
|
+
sx: {
|
|
6974
|
+
display: "block",
|
|
6975
|
+
fontSize: 11.5,
|
|
6976
|
+
fontWeight: 600,
|
|
6977
|
+
lineHeight: 1.35,
|
|
6978
|
+
overflow: "hidden",
|
|
6979
|
+
textOverflow: "ellipsis",
|
|
6980
|
+
whiteSpace: "nowrap"
|
|
6981
|
+
},
|
|
6982
|
+
children: limit.label
|
|
6983
|
+
}
|
|
6984
|
+
),
|
|
6985
|
+
/* @__PURE__ */ jsx21(
|
|
6986
|
+
Typography17,
|
|
6987
|
+
{
|
|
6988
|
+
variant: "caption",
|
|
6989
|
+
color: overCap ? "error" : "text.secondary",
|
|
6990
|
+
sx: {
|
|
6991
|
+
display: "block",
|
|
6992
|
+
fontSize: 10.5,
|
|
6993
|
+
fontWeight: overCap ? 700 : void 0,
|
|
6994
|
+
lineHeight: 1.35,
|
|
6995
|
+
overflow: "hidden",
|
|
6996
|
+
textOverflow: "ellipsis",
|
|
6997
|
+
whiteSpace: "nowrap"
|
|
6998
|
+
},
|
|
6999
|
+
children: subNote()
|
|
7000
|
+
}
|
|
7001
|
+
)
|
|
7002
|
+
] }) : /* @__PURE__ */ jsx21(
|
|
6859
7003
|
Typography17,
|
|
6860
7004
|
{
|
|
6861
7005
|
variant: "caption",
|
|
6862
|
-
|
|
7006
|
+
color: "text.secondary",
|
|
6863
7007
|
sx: {
|
|
6864
|
-
|
|
6865
|
-
fontSize:
|
|
6866
|
-
|
|
6867
|
-
maxWidth: "100%",
|
|
7008
|
+
display: "block",
|
|
7009
|
+
fontSize: 10.5,
|
|
7010
|
+
lineHeight: 1.35,
|
|
6868
7011
|
overflow: "hidden",
|
|
6869
7012
|
textOverflow: "ellipsis",
|
|
6870
7013
|
whiteSpace: "nowrap"
|
|
6871
7014
|
},
|
|
6872
|
-
children:
|
|
7015
|
+
children: none
|
|
6873
7016
|
}
|
|
6874
|
-
)
|
|
7017
|
+
)
|
|
7018
|
+
] }),
|
|
7019
|
+
/* @__PURE__ */ jsxs19(Box19, { sx: { minWidth: 0, textAlign: "right" }, children: [
|
|
6875
7020
|
/* @__PURE__ */ jsx21(
|
|
6876
7021
|
Typography17,
|
|
6877
7022
|
{
|
|
6878
|
-
|
|
6879
|
-
color: "text.secondary",
|
|
7023
|
+
title: limit ? `${fmtUsd(limit.spend)} of ${fmtUsd(limit.budget)}` : void 0,
|
|
6880
7024
|
sx: {
|
|
6881
|
-
|
|
7025
|
+
display: "block",
|
|
7026
|
+
fontSize: 12.5,
|
|
7027
|
+
fontWeight: 600,
|
|
7028
|
+
lineHeight: 1.35,
|
|
6882
7029
|
fontVariantNumeric: "tabular-nums",
|
|
6883
|
-
|
|
7030
|
+
whiteSpace: "nowrap",
|
|
7031
|
+
overflow: "hidden",
|
|
7032
|
+
textOverflow: "ellipsis",
|
|
7033
|
+
color: limit ? void 0 : "text.secondary"
|
|
6884
7034
|
},
|
|
6885
|
-
children:
|
|
7035
|
+
children: amountCaption(limit)
|
|
6886
7036
|
}
|
|
6887
7037
|
),
|
|
6888
|
-
|
|
7038
|
+
/* @__PURE__ */ jsx21(
|
|
6889
7039
|
Typography17,
|
|
6890
7040
|
{
|
|
6891
|
-
component: Link4,
|
|
6892
|
-
to: keysHref,
|
|
6893
7041
|
variant: "caption",
|
|
7042
|
+
color: "text.secondary",
|
|
6894
7043
|
sx: {
|
|
7044
|
+
display: "block",
|
|
6895
7045
|
fontSize: 10.5,
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
7046
|
+
lineHeight: 1.35,
|
|
7047
|
+
whiteSpace: "nowrap",
|
|
7048
|
+
overflow: "hidden",
|
|
7049
|
+
textOverflow: "ellipsis"
|
|
6899
7050
|
},
|
|
6900
|
-
children:
|
|
6901
|
-
"+",
|
|
6902
|
-
extra,
|
|
6903
|
-
" more"
|
|
6904
|
-
]
|
|
7051
|
+
children: amountNote(limit)
|
|
6905
7052
|
}
|
|
6906
|
-
)
|
|
6907
|
-
] })
|
|
6908
|
-
Typography17,
|
|
6909
|
-
{
|
|
6910
|
-
variant: "caption",
|
|
6911
|
-
color: "text.secondary",
|
|
6912
|
-
sx: { mt: 0.25, fontSize: 10.5, textAlign: "center" },
|
|
6913
|
-
children: none
|
|
6914
|
-
}
|
|
6915
|
-
)
|
|
7053
|
+
)
|
|
7054
|
+
] })
|
|
6916
7055
|
]
|
|
6917
7056
|
}
|
|
6918
7057
|
);
|
|
6919
7058
|
};
|
|
6920
|
-
|
|
7059
|
+
function amountCaption(limit) {
|
|
7060
|
+
if (!limit) return "";
|
|
7061
|
+
return limit.hidden ? `${Math.round(limit.pct)}%` : spendCaption(limit);
|
|
7062
|
+
}
|
|
7063
|
+
function amountNote(limit) {
|
|
7064
|
+
if (!limit) return "";
|
|
7065
|
+
return limit.hidden ? "hidden by admin" : resetLabel(limit);
|
|
7066
|
+
}
|
|
7067
|
+
var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, maxBudget }) => {
|
|
6921
7068
|
const renderPlot = () => {
|
|
6922
7069
|
if (loading) {
|
|
6923
7070
|
return /* @__PURE__ */ jsx21(Skeleton8, { variant: "rectangular", width: "100%", height: "100%" });
|
|
@@ -6963,99 +7110,70 @@ var UsageMiniChart = ({ data, totalSpend, loading, height, usageUnavailable = fa
|
|
|
6963
7110
|
)
|
|
6964
7111
|
] }) });
|
|
6965
7112
|
};
|
|
6966
|
-
const
|
|
6967
|
-
if (loading)
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
|
|
6976
|
-
|
|
6977
|
-
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
|
|
6999
|
-
|
|
7000
|
-
|
|
7001
|
-
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
Box19,
|
|
7016
|
-
{
|
|
7017
|
-
sx: {
|
|
7018
|
-
display: "flex",
|
|
7019
|
-
flexDirection: "column",
|
|
7020
|
-
alignItems: "center",
|
|
7021
|
-
minWidth: 0
|
|
7022
|
-
},
|
|
7023
|
-
role: "img",
|
|
7024
|
-
"aria-label": sparklineAriaLabel(data),
|
|
7025
|
-
children: [
|
|
7026
|
-
/* @__PURE__ */ jsx21(Box19, { sx: { height, width: "100%" }, children: renderPlot() }),
|
|
7027
|
-
/* @__PURE__ */ jsx21(
|
|
7028
|
-
Typography17,
|
|
7029
|
-
{
|
|
7030
|
-
sx: (theme) => ({
|
|
7031
|
-
mt: 0.75,
|
|
7032
|
-
fontSize: 10.5,
|
|
7033
|
-
fontWeight: 700,
|
|
7034
|
-
letterSpacing: "0.08em",
|
|
7035
|
-
textTransform: "uppercase",
|
|
7036
|
-
color: theme.palette.text.secondary
|
|
7037
|
-
}),
|
|
7038
|
-
children: "Spend (MTD)"
|
|
7039
|
-
}
|
|
7040
|
-
),
|
|
7041
|
-
/* @__PURE__ */ jsx21(
|
|
7042
|
-
Typography17,
|
|
7043
|
-
{
|
|
7044
|
-
variant: "caption",
|
|
7045
|
-
color: "text.secondary",
|
|
7046
|
-
sx: { mt: 0.25, fontSize: 10.5 },
|
|
7047
|
-
children: mtdCaption()
|
|
7048
|
-
}
|
|
7049
|
-
),
|
|
7050
|
-
renderCaption()
|
|
7051
|
-
]
|
|
7052
|
-
}
|
|
7053
|
-
);
|
|
7113
|
+
const caption = (() => {
|
|
7114
|
+
if (loading) return "\u2026";
|
|
7115
|
+
if (usageUnavailable) return USAGE_UNAVAILABLE_MSG;
|
|
7116
|
+
if (data.length === 0) return "No spend this month";
|
|
7117
|
+
return mtdCaption();
|
|
7118
|
+
})();
|
|
7119
|
+
return /* @__PURE__ */ jsxs19(Box19, { role: "img", "aria-label": sparklineAriaLabel(data), sx: { minWidth: 0 }, children: [
|
|
7120
|
+
/* @__PURE__ */ jsx21(Box19, { sx: { height, width: "100%" }, children: renderPlot() }),
|
|
7121
|
+
/* @__PURE__ */ jsxs19(
|
|
7122
|
+
Box19,
|
|
7123
|
+
{
|
|
7124
|
+
sx: {
|
|
7125
|
+
display: "flex",
|
|
7126
|
+
alignItems: "baseline",
|
|
7127
|
+
justifyContent: "space-between",
|
|
7128
|
+
gap: 1,
|
|
7129
|
+
mt: 0.5,
|
|
7130
|
+
minWidth: 0
|
|
7131
|
+
},
|
|
7132
|
+
children: [
|
|
7133
|
+
/* @__PURE__ */ jsxs19(Box19, { sx: { display: "flex", alignItems: "baseline", gap: 0.75, minWidth: 0 }, children: [
|
|
7134
|
+
/* @__PURE__ */ jsx21(Tag, { children: "Spent (mtd)" }),
|
|
7135
|
+
/* @__PURE__ */ jsx21(
|
|
7136
|
+
Typography17,
|
|
7137
|
+
{
|
|
7138
|
+
variant: "caption",
|
|
7139
|
+
color: "text.secondary",
|
|
7140
|
+
sx: { fontSize: 10.5, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
|
|
7141
|
+
children: caption
|
|
7142
|
+
}
|
|
7143
|
+
)
|
|
7144
|
+
] }),
|
|
7145
|
+
/* @__PURE__ */ jsx21(
|
|
7146
|
+
Typography17,
|
|
7147
|
+
{
|
|
7148
|
+
title: loading || usageUnavailable ? void 0 : `${fmtUsd(mtdSpend)} spent month to date`,
|
|
7149
|
+
sx: {
|
|
7150
|
+
fontSize: 12.5,
|
|
7151
|
+
fontWeight: 700,
|
|
7152
|
+
fontVariantNumeric: "tabular-nums",
|
|
7153
|
+
whiteSpace: "nowrap"
|
|
7154
|
+
},
|
|
7155
|
+
children: loading || usageUnavailable ? "\u2014" : fmtUsd(mtdSpend)
|
|
7156
|
+
}
|
|
7157
|
+
)
|
|
7158
|
+
]
|
|
7159
|
+
}
|
|
7160
|
+
)
|
|
7161
|
+
] });
|
|
7054
7162
|
};
|
|
7163
|
+
function statValue(loading, unavailable, value) {
|
|
7164
|
+
if (loading) return "\u2026";
|
|
7165
|
+
if (unavailable) return "\u2014";
|
|
7166
|
+
return value;
|
|
7167
|
+
}
|
|
7168
|
+
function statHint(loading, unavailable, hint) {
|
|
7169
|
+
if (loading) return void 0;
|
|
7170
|
+
if (unavailable) return USAGE_UNAVAILABLE_MSG;
|
|
7171
|
+
return hint;
|
|
7172
|
+
}
|
|
7055
7173
|
var LiteLLMBudgetGauges = ({
|
|
7056
7174
|
title = "Budget",
|
|
7057
7175
|
bare = false,
|
|
7058
|
-
size =
|
|
7176
|
+
size = 56,
|
|
7059
7177
|
keysHref,
|
|
7060
7178
|
moduleHref: propModuleHref,
|
|
7061
7179
|
onCreateKey,
|
|
@@ -7072,7 +7190,7 @@ var LiteLLMBudgetGauges = ({
|
|
|
7072
7190
|
const api = useApi6(liteLlmApiRef);
|
|
7073
7191
|
const theme = useTheme4();
|
|
7074
7192
|
const isSmallScreen = useMediaQuery(theme.breakpoints.down("sm"));
|
|
7075
|
-
const gaugeSize = isSmallScreen ?
|
|
7193
|
+
const gaugeSize = isSmallScreen ? Math.min(48, size) : size;
|
|
7076
7194
|
const expandedRegionId = useId2();
|
|
7077
7195
|
const moduleRouteRef = useRouteRef3(rootRouteRef);
|
|
7078
7196
|
const moduleHref = propModuleHref ?? moduleRouteRef?.();
|
|
@@ -7147,6 +7265,12 @@ var LiteLLMBudgetGauges = ({
|
|
|
7147
7265
|
}),
|
|
7148
7266
|
[loading, profileError, user, usageError, keys]
|
|
7149
7267
|
);
|
|
7268
|
+
const today = /* @__PURE__ */ new Date();
|
|
7269
|
+
const todaySpend = spendOnDay(dailySpend, today);
|
|
7270
|
+
const yesterday = new Date(today);
|
|
7271
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
7272
|
+
const yesterdaySpend = dailySpend.some((d) => d.date === toLocalDay(yesterday)) ? spendOnDay(dailySpend, yesterday) : null;
|
|
7273
|
+
const todayHint = yesterdaySpend === null ? void 0 : `vs ${fmtUsd(yesterdaySpend)} yesterday`;
|
|
7150
7274
|
const summaryText = headline.count === 0 ? "no limits apply" : `${headline.count} limit${headline.count === 1 ? "" : "s"}`;
|
|
7151
7275
|
const resolvedCtas = useMemo11(() => {
|
|
7152
7276
|
return resolveCtas({
|
|
@@ -7207,29 +7331,70 @@ var LiteLLMBudgetGauges = ({
|
|
|
7207
7331
|
}
|
|
7208
7332
|
)
|
|
7209
7333
|
] }),
|
|
7210
|
-
viewState.kind === "loading" && /* @__PURE__ */ jsx21(Box19, { sx: { display: "flex",
|
|
7211
|
-
/* @__PURE__ */ jsx21(Skeleton8, { variant: "circular", width: size, height: size
|
|
7212
|
-
/* @__PURE__ */
|
|
7213
|
-
|
|
7214
|
-
|
|
7334
|
+
viewState.kind === "loading" && /* @__PURE__ */ jsx21(Box19, { sx: { display: "flex", flexDirection: "column", gap: 1.25, minHeight: size }, children: [0, 1, 2].map((i) => /* @__PURE__ */ jsxs19(Box19, { sx: { display: "flex", alignItems: "center", gap: 1.25 }, children: [
|
|
7335
|
+
/* @__PURE__ */ jsx21(Skeleton8, { variant: "circular", width: size, height: size }),
|
|
7336
|
+
/* @__PURE__ */ jsxs19(Box19, { sx: { flex: 1 }, children: [
|
|
7337
|
+
/* @__PURE__ */ jsx21(Skeleton8, { variant: "text", width: "70%", height: 12, sx: { mb: 0.25 } }),
|
|
7338
|
+
/* @__PURE__ */ jsx21(Skeleton8, { variant: "text", width: "45%", height: 11 })
|
|
7339
|
+
] }),
|
|
7340
|
+
/* @__PURE__ */ jsx21(Skeleton8, { variant: "text", width: 64, height: 12 })
|
|
7215
7341
|
] }, i)) }),
|
|
7216
7342
|
viewState.kind === "error" && /* @__PURE__ */ jsx21(Typography17, { variant: "body2", color: "text.secondary", sx: { mt: 0.5 }, children: viewState.message }),
|
|
7217
7343
|
viewState.kind === "unprovisioned" && /* @__PURE__ */ jsx21(Typography17, { variant: "body2", color: "text.secondary", sx: { mt: 0.5 }, children: UNPROVISIONED_MSG }),
|
|
7218
7344
|
viewState.kind === "ready" && /* @__PURE__ */ jsxs19(Fragment11, { children: [
|
|
7219
|
-
/* @__PURE__ */ jsxs19(
|
|
7220
|
-
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
|
|
7232
|
-
|
|
7345
|
+
/* @__PURE__ */ jsxs19(
|
|
7346
|
+
Box19,
|
|
7347
|
+
{
|
|
7348
|
+
sx: {
|
|
7349
|
+
display: "flex",
|
|
7350
|
+
alignItems: "stretch",
|
|
7351
|
+
gap: 2,
|
|
7352
|
+
mb: 1.25,
|
|
7353
|
+
minWidth: 0
|
|
7354
|
+
},
|
|
7355
|
+
children: [
|
|
7356
|
+
/* @__PURE__ */ jsx21(
|
|
7357
|
+
InlineStat,
|
|
7358
|
+
{
|
|
7359
|
+
label: "Today spent",
|
|
7360
|
+
tone: "accent",
|
|
7361
|
+
value: statValue(usageLoading, viewState.usageUnavailable, fmtUsd(todaySpend)),
|
|
7362
|
+
hint: statHint(usageLoading, viewState.usageUnavailable, todayHint),
|
|
7363
|
+
title: usageLoading || viewState.usageUnavailable ? void 0 : "Spend since local midnight"
|
|
7364
|
+
}
|
|
7365
|
+
),
|
|
7366
|
+
/* @__PURE__ */ jsx21(Box19, { sx: { width: "1px", bgcolor: "divider", flexShrink: 0 } }),
|
|
7367
|
+
/* @__PURE__ */ jsx21(
|
|
7368
|
+
InlineStat,
|
|
7369
|
+
{
|
|
7370
|
+
label: "Month to date",
|
|
7371
|
+
value: statValue(usageLoading, viewState.usageUnavailable, fmtUsd(mtdSpend)),
|
|
7372
|
+
hint: statHint(usageLoading, viewState.usageUnavailable, mtdCaption()),
|
|
7373
|
+
title: usageLoading || viewState.usageUnavailable ? void 0 : "Spend from the 1st of this month"
|
|
7374
|
+
}
|
|
7375
|
+
)
|
|
7376
|
+
]
|
|
7377
|
+
}
|
|
7378
|
+
),
|
|
7379
|
+
/* @__PURE__ */ jsx21(Box19, { sx: { borderTop: "1px solid", borderColor: "divider" }, children: gauges.map((gauge, i) => /* @__PURE__ */ jsx21(
|
|
7380
|
+
Box19,
|
|
7381
|
+
{
|
|
7382
|
+
sx: i === 0 ? void 0 : { borderTop: "1px solid", borderColor: "divider" },
|
|
7383
|
+
children: /* @__PURE__ */ jsx21(LevelRow, { gauge, size: gaugeSize, keysHref: keysTabHref })
|
|
7384
|
+
},
|
|
7385
|
+
gauge.kind
|
|
7386
|
+
)) }),
|
|
7387
|
+
/* @__PURE__ */ jsx21(Box19, { sx: { mt: 1.25 }, children: /* @__PURE__ */ jsx21(
|
|
7388
|
+
SpendStrip,
|
|
7389
|
+
{
|
|
7390
|
+
data: dailySpend,
|
|
7391
|
+
mtdSpend,
|
|
7392
|
+
loading: usageLoading,
|
|
7393
|
+
height: gaugeSize,
|
|
7394
|
+
usageUnavailable: viewState.usageUnavailable,
|
|
7395
|
+
maxBudget: user?.max_budget ?? void 0
|
|
7396
|
+
}
|
|
7397
|
+
) }),
|
|
7233
7398
|
/* @__PURE__ */ jsx21(Collapse4, { in: isExpanded, unmountOnExit: true, children: /* @__PURE__ */ jsx21(
|
|
7234
7399
|
Box19,
|
|
7235
7400
|
{
|