@acarmisc/backstage-plugin-litellm 0.35.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/api.d.ts +9 -0
- package/dist/components/ConnectPage.d.ts +7 -0
- package/dist/connect.d.ts +8 -0
- package/dist/index.cjs.js +289 -150
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.esm.js +274 -135
- package/dist/index.esm.js.map +4 -4
- package/dist/plugin.d.ts +40 -0
- package/package.json +1 -1
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
|
}
|
|
@@ -6730,6 +6734,131 @@ var init_LiteLLMPage = __esm({
|
|
|
6730
6734
|
}
|
|
6731
6735
|
});
|
|
6732
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
|
+
|
|
6733
6862
|
// src/index.ts
|
|
6734
6863
|
var index_exports = {};
|
|
6735
6864
|
__export(index_exports, {
|
|
@@ -6761,7 +6890,7 @@ var import_icons_material10 = require("@mui/icons-material");
|
|
|
6761
6890
|
var import_frontend_plugin_api4 = require("@backstage/frontend-plugin-api");
|
|
6762
6891
|
init_api();
|
|
6763
6892
|
init_routes();
|
|
6764
|
-
var
|
|
6893
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
6765
6894
|
var liteLlmApi = import_frontend_plugin_api4.ApiBlueprint.make({
|
|
6766
6895
|
params: (defineParams) => defineParams({
|
|
6767
6896
|
api: liteLlmApiRef,
|
|
@@ -6773,11 +6902,21 @@ var liteLlmPage = import_frontend_plugin_api4.PageBlueprint.make({
|
|
|
6773
6902
|
params: {
|
|
6774
6903
|
path: "/litellm",
|
|
6775
6904
|
title: "LiteLLM",
|
|
6776
|
-
icon: /* @__PURE__ */ (0,
|
|
6905
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons_material10.TrendingUp, {}),
|
|
6777
6906
|
routeRef: rootRouteRef,
|
|
6778
6907
|
loader: async () => {
|
|
6779
6908
|
const { LiteLLMPage: LiteLLMPage2 } = await Promise.resolve().then(() => (init_LiteLLMPage(), LiteLLMPage_exports));
|
|
6780
|
-
return /* @__PURE__ */ (0,
|
|
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, {});
|
|
6781
6920
|
}
|
|
6782
6921
|
}
|
|
6783
6922
|
});
|
|
@@ -6786,7 +6925,7 @@ var litellmPlugin = (0, import_frontend_plugin_api4.createFrontendPlugin)({
|
|
|
6786
6925
|
routes: {
|
|
6787
6926
|
root: rootRouteRef
|
|
6788
6927
|
},
|
|
6789
|
-
extensions: [liteLlmApi, liteLlmPage]
|
|
6928
|
+
extensions: [liteLlmApi, liteLlmPage, liteLlmConnectPage]
|
|
6790
6929
|
});
|
|
6791
6930
|
|
|
6792
6931
|
// src/index.ts
|
|
@@ -6797,18 +6936,18 @@ init_UsageStats();
|
|
|
6797
6936
|
init_TeamUsage();
|
|
6798
6937
|
|
|
6799
6938
|
// src/components/LiteLLMHomeWidget.tsx
|
|
6800
|
-
var
|
|
6801
|
-
var
|
|
6802
|
-
var
|
|
6803
|
-
var
|
|
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"));
|
|
6804
6943
|
var import_FormControl2 = __toESM(require("@mui/material/FormControl"));
|
|
6805
6944
|
var import_Select2 = __toESM(require("@mui/material/Select"));
|
|
6806
6945
|
var import_MenuItem6 = __toESM(require("@mui/material/MenuItem"));
|
|
6807
6946
|
var import_Skeleton7 = __toESM(require("@mui/material/Skeleton"));
|
|
6808
6947
|
var import_recharts3 = require("recharts");
|
|
6809
|
-
var
|
|
6948
|
+
var import_core_plugin_api7 = require("@backstage/core-plugin-api");
|
|
6810
6949
|
var import_frontend_plugin_api5 = require("@backstage/frontend-plugin-api");
|
|
6811
|
-
var
|
|
6950
|
+
var import_core_components5 = require("@backstage/core-components");
|
|
6812
6951
|
init_useLiteLLMProfile();
|
|
6813
6952
|
init_api();
|
|
6814
6953
|
init_routes();
|
|
@@ -6860,7 +6999,7 @@ function usageSummary(usage) {
|
|
|
6860
6999
|
}
|
|
6861
7000
|
|
|
6862
7001
|
// src/components/LiteLLMHomeWidget.tsx
|
|
6863
|
-
var
|
|
7002
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6864
7003
|
function presetToDateRange(preset) {
|
|
6865
7004
|
const end = /* @__PURE__ */ new Date();
|
|
6866
7005
|
const start = /* @__PURE__ */ new Date();
|
|
@@ -6878,14 +7017,14 @@ var LiteLLMHomeWidget = ({
|
|
|
6878
7017
|
title = "LiteLLM Usage",
|
|
6879
7018
|
bare = false
|
|
6880
7019
|
}) => {
|
|
6881
|
-
const api = (0,
|
|
7020
|
+
const api = (0, import_core_plugin_api7.useApi)(liteLlmApiRef);
|
|
6882
7021
|
const moduleRouteRef = (0, import_frontend_plugin_api5.useRouteRef)(rootRouteRef);
|
|
6883
7022
|
const { userInfo, keys, loading: profileLoading, error: profileError } = useLiteLLMProfile();
|
|
6884
|
-
const [period, setPeriod] = (0,
|
|
6885
|
-
const [usageLoading, setUsageLoading] = (0,
|
|
6886
|
-
const [usageError, setUsageError] = (0,
|
|
6887
|
-
const [usage, setUsage] = (0,
|
|
6888
|
-
(0,
|
|
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)(() => {
|
|
6889
7028
|
let cancelled = false;
|
|
6890
7029
|
setUsageLoading(true);
|
|
6891
7030
|
setUsageError(null);
|
|
@@ -6907,7 +7046,7 @@ var LiteLLMHomeWidget = ({
|
|
|
6907
7046
|
cancelled = true;
|
|
6908
7047
|
};
|
|
6909
7048
|
}, [api, period]);
|
|
6910
|
-
const viewState = (0,
|
|
7049
|
+
const viewState = (0, import_react15.useMemo)(
|
|
6911
7050
|
() => widgetViewState({
|
|
6912
7051
|
loading: profileLoading || usageLoading,
|
|
6913
7052
|
error: profileError,
|
|
@@ -6917,7 +7056,7 @@ var LiteLLMHomeWidget = ({
|
|
|
6917
7056
|
}),
|
|
6918
7057
|
[profileLoading, usageLoading, profileError, userInfo, usageError, keys]
|
|
6919
7058
|
);
|
|
6920
|
-
const Wrapper = bare ?
|
|
7059
|
+
const Wrapper = bare ? import_Box19.default : import_Paper10.default;
|
|
6921
7060
|
const partialFailure = !usageLoading && usageError && usage;
|
|
6922
7061
|
const dailyData = (usage?.daily_usage ?? []).map((d) => ({
|
|
6923
7062
|
date: d.date,
|
|
@@ -6929,10 +7068,10 @@ var LiteLLMHomeWidget = ({
|
|
|
6929
7068
|
const endDate = toLocalDay(end);
|
|
6930
7069
|
const dateRangeCaption = rangeCaption(startDate, endDate);
|
|
6931
7070
|
const sparklineAriaLabelText = sparklineAriaLabel(dailyData);
|
|
6932
|
-
return /* @__PURE__ */ (0,
|
|
6933
|
-
/* @__PURE__ */ (0,
|
|
6934
|
-
!bare && /* @__PURE__ */ (0,
|
|
6935
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
6936
7075
|
import_Select2.default,
|
|
6937
7076
|
{
|
|
6938
7077
|
value: period,
|
|
@@ -6940,23 +7079,23 @@ var LiteLLMHomeWidget = ({
|
|
|
6940
7079
|
displayEmpty: true,
|
|
6941
7080
|
inputProps: { "aria-label": "Usage period" },
|
|
6942
7081
|
children: [
|
|
6943
|
-
/* @__PURE__ */ (0,
|
|
6944
|
-
/* @__PURE__ */ (0,
|
|
6945
|
-
/* @__PURE__ */ (0,
|
|
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" })
|
|
6946
7085
|
]
|
|
6947
7086
|
}
|
|
6948
7087
|
) })
|
|
6949
7088
|
] }),
|
|
6950
|
-
viewState.kind === "loading" && /* @__PURE__ */ (0,
|
|
6951
|
-
/* @__PURE__ */ (0,
|
|
6952
|
-
/* @__PURE__ */ (0,
|
|
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 })
|
|
6953
7092
|
] }),
|
|
6954
|
-
viewState.kind === "error" && /* @__PURE__ */ (0,
|
|
6955
|
-
viewState.kind === "unprovisioned" && /* @__PURE__ */ (0,
|
|
6956
|
-
viewState.kind === "ready" && partialFailure && /* @__PURE__ */ (0,
|
|
6957
|
-
viewState.kind === "ready" && /* @__PURE__ */ (0,
|
|
6958
|
-
/* @__PURE__ */ (0,
|
|
6959
|
-
|
|
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,
|
|
6960
7099
|
{
|
|
6961
7100
|
variant: "body2",
|
|
6962
7101
|
sx: {
|
|
@@ -6967,18 +7106,18 @@ var LiteLLMHomeWidget = ({
|
|
|
6967
7106
|
children: viewState.usageUnavailable ? USAGE_UNAVAILABLE_MSG : usageSummary(usage)
|
|
6968
7107
|
}
|
|
6969
7108
|
),
|
|
6970
|
-
hasSparkline && !viewState.usageUnavailable && /* @__PURE__ */ (0,
|
|
6971
|
-
/* @__PURE__ */ (0,
|
|
6972
|
-
|
|
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,
|
|
6973
7112
|
{
|
|
6974
7113
|
height: 80,
|
|
6975
7114
|
role: "img",
|
|
6976
7115
|
"aria-label": sparklineAriaLabelText,
|
|
6977
7116
|
sx: { mb: 0.5 },
|
|
6978
|
-
children: /* @__PURE__ */ (0,
|
|
6979
|
-
/* @__PURE__ */ (0,
|
|
6980
|
-
/* @__PURE__ */ (0,
|
|
6981
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
6982
7121
|
import_recharts3.Area,
|
|
6983
7122
|
{
|
|
6984
7123
|
type: "monotone",
|
|
@@ -6994,13 +7133,13 @@ var LiteLLMHomeWidget = ({
|
|
|
6994
7133
|
] }) })
|
|
6995
7134
|
}
|
|
6996
7135
|
),
|
|
6997
|
-
/* @__PURE__ */ (0,
|
|
7136
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_Typography17.default, { variant: "caption", color: "text.secondary", sx: { display: "block", mb: 1 }, children: [
|
|
6998
7137
|
"daily spend (",
|
|
6999
7138
|
dateRangeCaption,
|
|
7000
7139
|
")"
|
|
7001
7140
|
] })
|
|
7002
7141
|
] }),
|
|
7003
|
-
moduleRouteRef?.() && /* @__PURE__ */ (0,
|
|
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" }) })
|
|
7004
7143
|
] })
|
|
7005
7144
|
] });
|
|
7006
7145
|
};
|
|
@@ -7009,20 +7148,20 @@ var LiteLLMHomeWidget = ({
|
|
|
7009
7148
|
init_LiteLLMBudgetWidget();
|
|
7010
7149
|
|
|
7011
7150
|
// src/components/LiteLLMBudgetGauges.tsx
|
|
7012
|
-
var
|
|
7151
|
+
var import_react16 = require("react");
|
|
7013
7152
|
var import_frontend_plugin_api6 = require("@backstage/frontend-plugin-api");
|
|
7014
|
-
var
|
|
7015
|
-
var
|
|
7016
|
-
var
|
|
7017
|
-
var
|
|
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"));
|
|
7018
7157
|
var import_Skeleton8 = __toESM(require("@mui/material/Skeleton"));
|
|
7019
7158
|
var import_Collapse4 = __toESM(require("@mui/material/Collapse"));
|
|
7020
7159
|
var import_styles13 = require("@mui/material/styles");
|
|
7021
7160
|
var import_useMediaQuery = __toESM(require("@mui/material/useMediaQuery"));
|
|
7022
7161
|
var import_icons_material11 = require("@mui/icons-material");
|
|
7023
7162
|
var import_recharts4 = require("recharts");
|
|
7024
|
-
var
|
|
7025
|
-
var
|
|
7163
|
+
var import_core_plugin_api8 = require("@backstage/core-plugin-api");
|
|
7164
|
+
var import_core_components6 = require("@backstage/core-components");
|
|
7026
7165
|
init_useLiteLLMProfile();
|
|
7027
7166
|
init_api();
|
|
7028
7167
|
init_format();
|
|
@@ -7053,7 +7192,7 @@ init_GenerateKeyButton();
|
|
|
7053
7192
|
init_BudgetLimitList();
|
|
7054
7193
|
init_budget();
|
|
7055
7194
|
init_routes();
|
|
7056
|
-
var
|
|
7195
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
7057
7196
|
var LEVEL = {
|
|
7058
7197
|
key: { name: "Key", none: "No cap (unlimited)" },
|
|
7059
7198
|
user: { name: "User", none: "No personal budget" },
|
|
@@ -7077,8 +7216,8 @@ function resetLabel(limit) {
|
|
|
7077
7216
|
const window2 = fmtBudgetDuration(limit.budgetDuration);
|
|
7078
7217
|
return window2 ? `resets ${window2}` : "never resets";
|
|
7079
7218
|
}
|
|
7080
|
-
var Tag = ({ children, tone, title }) => /* @__PURE__ */ (0,
|
|
7081
|
-
|
|
7219
|
+
var Tag = ({ children, tone, title }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7220
|
+
import_Typography18.default,
|
|
7082
7221
|
{
|
|
7083
7222
|
title,
|
|
7084
7223
|
sx: (theme) => ({
|
|
@@ -7095,10 +7234,10 @@ var Tag = ({ children, tone, title }) => /* @__PURE__ */ (0, import_jsx_runtime2
|
|
|
7095
7234
|
children
|
|
7096
7235
|
}
|
|
7097
7236
|
);
|
|
7098
|
-
var InlineStat = ({ label, value, hint, tone = "accent", title }) => /* @__PURE__ */ (0,
|
|
7099
|
-
/* @__PURE__ */ (0,
|
|
7100
|
-
/* @__PURE__ */ (0,
|
|
7101
|
-
|
|
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,
|
|
7102
7241
|
{
|
|
7103
7242
|
sx: (theme) => ({
|
|
7104
7243
|
width: 6,
|
|
@@ -7109,10 +7248,10 @@ var InlineStat = ({ label, value, hint, tone = "accent", title }) => /* @__PURE_
|
|
|
7109
7248
|
})
|
|
7110
7249
|
}
|
|
7111
7250
|
),
|
|
7112
|
-
/* @__PURE__ */ (0,
|
|
7251
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Tag, { children: label })
|
|
7113
7252
|
] }),
|
|
7114
|
-
/* @__PURE__ */ (0,
|
|
7115
|
-
|
|
7253
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7254
|
+
import_Typography18.default,
|
|
7116
7255
|
{
|
|
7117
7256
|
title,
|
|
7118
7257
|
sx: {
|
|
@@ -7128,8 +7267,8 @@ var InlineStat = ({ label, value, hint, tone = "accent", title }) => /* @__PURE_
|
|
|
7128
7267
|
children: value
|
|
7129
7268
|
}
|
|
7130
7269
|
),
|
|
7131
|
-
/* @__PURE__ */ (0,
|
|
7132
|
-
|
|
7270
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7271
|
+
import_Typography18.default,
|
|
7133
7272
|
{
|
|
7134
7273
|
variant: "caption",
|
|
7135
7274
|
color: "text.secondary",
|
|
@@ -7159,10 +7298,10 @@ var LevelRow = ({
|
|
|
7159
7298
|
const subNote = () => {
|
|
7160
7299
|
if (overCap) return "Over cap";
|
|
7161
7300
|
if (extra > 0 && keysHref) {
|
|
7162
|
-
return /* @__PURE__ */ (0,
|
|
7163
|
-
|
|
7301
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
7302
|
+
import_Typography18.default,
|
|
7164
7303
|
{
|
|
7165
|
-
component:
|
|
7304
|
+
component: import_core_components6.Link,
|
|
7166
7305
|
to: keysHref,
|
|
7167
7306
|
variant: "caption",
|
|
7168
7307
|
sx: {
|
|
@@ -7182,8 +7321,8 @@ var LevelRow = ({
|
|
|
7182
7321
|
return limit?.sublabel ?? null;
|
|
7183
7322
|
};
|
|
7184
7323
|
const gaugeAriaLabel = limit ? `${name} budget used: ${Math.round(limit.pct)}%` : `${name} \u2014 no cap`;
|
|
7185
|
-
return /* @__PURE__ */ (0,
|
|
7186
|
-
|
|
7324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
7325
|
+
import_Box20.default,
|
|
7187
7326
|
{
|
|
7188
7327
|
sx: {
|
|
7189
7328
|
display: "grid",
|
|
@@ -7194,7 +7333,7 @@ var LevelRow = ({
|
|
|
7194
7333
|
minWidth: 0
|
|
7195
7334
|
},
|
|
7196
7335
|
children: [
|
|
7197
|
-
/* @__PURE__ */ (0,
|
|
7336
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7198
7337
|
Gauge,
|
|
7199
7338
|
{
|
|
7200
7339
|
value: limit?.pct ?? 0,
|
|
@@ -7204,11 +7343,11 @@ var LevelRow = ({
|
|
|
7204
7343
|
ariaLabel: gaugeAriaLabel
|
|
7205
7344
|
}
|
|
7206
7345
|
),
|
|
7207
|
-
/* @__PURE__ */ (0,
|
|
7208
|
-
/* @__PURE__ */ (0,
|
|
7209
|
-
limit ? /* @__PURE__ */ (0,
|
|
7210
|
-
/* @__PURE__ */ (0,
|
|
7211
|
-
|
|
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,
|
|
7212
7351
|
{
|
|
7213
7352
|
variant: "caption",
|
|
7214
7353
|
title: limit.sublabel ? `${limit.label} \xB7 ${limit.sublabel}` : limit.label,
|
|
@@ -7224,8 +7363,8 @@ var LevelRow = ({
|
|
|
7224
7363
|
children: limit.label
|
|
7225
7364
|
}
|
|
7226
7365
|
),
|
|
7227
|
-
/* @__PURE__ */ (0,
|
|
7228
|
-
|
|
7366
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7367
|
+
import_Typography18.default,
|
|
7229
7368
|
{
|
|
7230
7369
|
variant: "caption",
|
|
7231
7370
|
color: overCap ? "error" : "text.secondary",
|
|
@@ -7241,8 +7380,8 @@ var LevelRow = ({
|
|
|
7241
7380
|
children: subNote()
|
|
7242
7381
|
}
|
|
7243
7382
|
)
|
|
7244
|
-
] }) : /* @__PURE__ */ (0,
|
|
7245
|
-
|
|
7383
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7384
|
+
import_Typography18.default,
|
|
7246
7385
|
{
|
|
7247
7386
|
variant: "caption",
|
|
7248
7387
|
color: "text.secondary",
|
|
@@ -7258,9 +7397,9 @@ var LevelRow = ({
|
|
|
7258
7397
|
}
|
|
7259
7398
|
)
|
|
7260
7399
|
] }),
|
|
7261
|
-
/* @__PURE__ */ (0,
|
|
7262
|
-
/* @__PURE__ */ (0,
|
|
7263
|
-
|
|
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,
|
|
7264
7403
|
{
|
|
7265
7404
|
title: limit ? `${fmtUsd(limit.spend)} of ${fmtUsd(limit.budget)}` : void 0,
|
|
7266
7405
|
sx: {
|
|
@@ -7277,8 +7416,8 @@ var LevelRow = ({
|
|
|
7277
7416
|
children: amountCaption(limit)
|
|
7278
7417
|
}
|
|
7279
7418
|
),
|
|
7280
|
-
/* @__PURE__ */ (0,
|
|
7281
|
-
|
|
7419
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7420
|
+
import_Typography18.default,
|
|
7282
7421
|
{
|
|
7283
7422
|
variant: "caption",
|
|
7284
7423
|
color: "text.secondary",
|
|
@@ -7309,11 +7448,11 @@ function amountNote(limit) {
|
|
|
7309
7448
|
var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, maxBudget }) => {
|
|
7310
7449
|
const renderPlot = () => {
|
|
7311
7450
|
if (loading) {
|
|
7312
|
-
return /* @__PURE__ */ (0,
|
|
7451
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Skeleton8.default, { variant: "rectangular", width: "100%", height: "100%" });
|
|
7313
7452
|
}
|
|
7314
7453
|
if (data.length === 0) {
|
|
7315
|
-
return /* @__PURE__ */ (0,
|
|
7316
|
-
|
|
7454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7455
|
+
import_Box20.default,
|
|
7317
7456
|
{
|
|
7318
7457
|
display: "flex",
|
|
7319
7458
|
justifyContent: "center",
|
|
@@ -7324,10 +7463,10 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
|
|
|
7324
7463
|
}
|
|
7325
7464
|
);
|
|
7326
7465
|
}
|
|
7327
|
-
return /* @__PURE__ */ (0,
|
|
7328
|
-
/* @__PURE__ */ (0,
|
|
7329
|
-
/* @__PURE__ */ (0,
|
|
7330
|
-
maxBudget !== void 0 && /* @__PURE__ */ (0,
|
|
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)(
|
|
7331
7470
|
import_recharts4.ReferenceLine,
|
|
7332
7471
|
{
|
|
7333
7472
|
y: maxBudget,
|
|
@@ -7336,7 +7475,7 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
|
|
|
7336
7475
|
strokeWidth: 1
|
|
7337
7476
|
}
|
|
7338
7477
|
),
|
|
7339
|
-
/* @__PURE__ */ (0,
|
|
7478
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7340
7479
|
import_recharts4.Area,
|
|
7341
7480
|
{
|
|
7342
7481
|
type: "monotone",
|
|
@@ -7358,10 +7497,10 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
|
|
|
7358
7497
|
if (data.length === 0) return "No spend this month";
|
|
7359
7498
|
return mtdCaption();
|
|
7360
7499
|
})();
|
|
7361
|
-
return /* @__PURE__ */ (0,
|
|
7362
|
-
/* @__PURE__ */ (0,
|
|
7363
|
-
/* @__PURE__ */ (0,
|
|
7364
|
-
|
|
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,
|
|
7365
7504
|
{
|
|
7366
7505
|
sx: {
|
|
7367
7506
|
display: "flex",
|
|
@@ -7372,10 +7511,10 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
|
|
|
7372
7511
|
minWidth: 0
|
|
7373
7512
|
},
|
|
7374
7513
|
children: [
|
|
7375
|
-
/* @__PURE__ */ (0,
|
|
7376
|
-
/* @__PURE__ */ (0,
|
|
7377
|
-
/* @__PURE__ */ (0,
|
|
7378
|
-
|
|
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,
|
|
7379
7518
|
{
|
|
7380
7519
|
variant: "caption",
|
|
7381
7520
|
color: "text.secondary",
|
|
@@ -7384,8 +7523,8 @@ var SpendStrip = ({ data, mtdSpend, loading, height, usageUnavailable = false, m
|
|
|
7384
7523
|
}
|
|
7385
7524
|
)
|
|
7386
7525
|
] }),
|
|
7387
|
-
/* @__PURE__ */ (0,
|
|
7388
|
-
|
|
7526
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7527
|
+
import_Typography18.default,
|
|
7389
7528
|
{
|
|
7390
7529
|
title: loading || usageUnavailable ? void 0 : `${fmtUsd(mtdSpend)} spent month to date`,
|
|
7391
7530
|
sx: {
|
|
@@ -7429,33 +7568,33 @@ var LiteLLMBudgetGauges = ({
|
|
|
7429
7568
|
teams: propTeams,
|
|
7430
7569
|
keys: propKeys
|
|
7431
7570
|
}) => {
|
|
7432
|
-
const api = (0,
|
|
7571
|
+
const api = (0, import_core_plugin_api8.useApi)(liteLlmApiRef);
|
|
7433
7572
|
const theme = (0, import_styles13.useTheme)();
|
|
7434
7573
|
const isSmallScreen = (0, import_useMediaQuery.default)(theme.breakpoints.down("sm"));
|
|
7435
7574
|
const gaugeSize = isSmallScreen ? Math.min(48, size) : size;
|
|
7436
|
-
const expandedRegionId = (0,
|
|
7575
|
+
const expandedRegionId = (0, import_react16.useId)();
|
|
7437
7576
|
const moduleRouteRef = (0, import_frontend_plugin_api6.useRouteRef)(rootRouteRef);
|
|
7438
7577
|
const moduleHref = propModuleHref ?? moduleRouteRef?.();
|
|
7439
7578
|
const { userInfo: hookUserInfo, teams: hookTeams, keys: hookKeys, loading: profileLoading, error: profileError } = useLiteLLMProfile();
|
|
7440
|
-
const [usageLoading, setUsageLoading] = (0,
|
|
7441
|
-
const [usageError, setUsageError] = (0,
|
|
7442
|
-
const [dailySpend, setDailySpend] = (0,
|
|
7443
|
-
const [mtdSpend, setMtdSpend] = (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);
|
|
7444
7583
|
const user = propUserInfo !== void 0 ? propUserInfo : hookUserInfo;
|
|
7445
7584
|
const teams = propTeams !== void 0 ? propTeams : hookTeams;
|
|
7446
7585
|
const keys = propKeys !== void 0 ? propKeys : hookKeys;
|
|
7447
7586
|
const loading = propUserInfo === void 0 ? profileLoading : usageLoading;
|
|
7448
7587
|
const error = propUserInfo === void 0 ? profileError : usageError;
|
|
7449
7588
|
const isControlled = expanded !== void 0;
|
|
7450
|
-
const [uncontrolledExpanded, setUncontrolledExpanded] = (0,
|
|
7589
|
+
const [uncontrolledExpanded, setUncontrolledExpanded] = (0, import_react16.useState)(defaultExpanded);
|
|
7451
7590
|
const isExpanded = isControlled ? expanded : uncontrolledExpanded;
|
|
7452
|
-
const toggleExpanded = (0,
|
|
7591
|
+
const toggleExpanded = (0, import_react16.useCallback)(() => {
|
|
7453
7592
|
const next = !isExpanded;
|
|
7454
7593
|
if (!isControlled) setUncontrolledExpanded(next);
|
|
7455
7594
|
onExpandedChange?.(next);
|
|
7456
7595
|
}, [isControlled, isExpanded, onExpandedChange]);
|
|
7457
7596
|
const keysTabHref = keysHref ?? (moduleHref ? `${moduleHref}?tab=keys` : void 0);
|
|
7458
|
-
(0,
|
|
7597
|
+
(0, import_react16.useEffect)(() => {
|
|
7459
7598
|
let cancelled = false;
|
|
7460
7599
|
setUsageLoading(true);
|
|
7461
7600
|
setUsageError(null);
|
|
@@ -7483,21 +7622,21 @@ var LiteLLMBudgetGauges = ({
|
|
|
7483
7622
|
cancelled = true;
|
|
7484
7623
|
};
|
|
7485
7624
|
}, [api]);
|
|
7486
|
-
const summary = (0,
|
|
7625
|
+
const summary = (0, import_react16.useMemo)(
|
|
7487
7626
|
() => buildBudgetSummary(user, teams, keys, keys.length),
|
|
7488
7627
|
[user, teams, keys]
|
|
7489
7628
|
);
|
|
7490
|
-
const gauges = (0,
|
|
7491
|
-
const headline = (0,
|
|
7492
|
-
const expandedSummary = (0,
|
|
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)(
|
|
7493
7632
|
() => buildBudgetSummary(user, teams, keys, maxExpandedKeys),
|
|
7494
7633
|
[user, teams, keys, maxExpandedKeys]
|
|
7495
7634
|
);
|
|
7496
|
-
const expandedLimits = (0,
|
|
7635
|
+
const expandedLimits = (0, import_react16.useMemo)(
|
|
7497
7636
|
() => allBudgetLimits(expandedSummary),
|
|
7498
7637
|
[expandedSummary]
|
|
7499
7638
|
);
|
|
7500
|
-
const viewState = (0,
|
|
7639
|
+
const viewState = (0, import_react16.useMemo)(
|
|
7501
7640
|
() => widgetViewState({
|
|
7502
7641
|
loading,
|
|
7503
7642
|
error: profileError,
|
|
@@ -7514,7 +7653,7 @@ var LiteLLMBudgetGauges = ({
|
|
|
7514
7653
|
const yesterdaySpend = dailySpend.some((d) => d.date === toLocalDay(yesterday)) ? spendOnDay(dailySpend, yesterday) : null;
|
|
7515
7654
|
const todayHint = yesterdaySpend === null ? void 0 : `vs ${fmtUsd(yesterdaySpend)} yesterday`;
|
|
7516
7655
|
const summaryText = headline.count === 0 ? "no limits apply" : `${headline.count} limit${headline.count === 1 ? "" : "s"}`;
|
|
7517
|
-
const resolvedCtas = (0,
|
|
7656
|
+
const resolvedCtas = (0, import_react16.useMemo)(() => {
|
|
7518
7657
|
return resolveCtas({
|
|
7519
7658
|
ctas,
|
|
7520
7659
|
hasKeys: (keys?.length ?? 0) > 0,
|
|
@@ -7528,20 +7667,20 @@ var LiteLLMBudgetGauges = ({
|
|
|
7528
7667
|
switch (cta.kind) {
|
|
7529
7668
|
case "new-key":
|
|
7530
7669
|
if (!onCreateKey && !moduleHref) return null;
|
|
7531
|
-
return onCreateKey ? /* @__PURE__ */ (0,
|
|
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);
|
|
7532
7671
|
case "module":
|
|
7533
7672
|
if (!moduleHref) return null;
|
|
7534
|
-
return /* @__PURE__ */ (0,
|
|
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);
|
|
7535
7674
|
case "all-limits":
|
|
7536
|
-
return /* @__PURE__ */ (0,
|
|
7537
|
-
|
|
7675
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7676
|
+
import_Button9.default,
|
|
7538
7677
|
{
|
|
7539
7678
|
size: "small",
|
|
7540
7679
|
variant: "text",
|
|
7541
7680
|
onClick: toggleExpanded,
|
|
7542
7681
|
"aria-expanded": isExpanded,
|
|
7543
7682
|
"aria-controls": expandedRegionId,
|
|
7544
|
-
endIcon: /* @__PURE__ */ (0,
|
|
7683
|
+
endIcon: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7545
7684
|
import_icons_material11.ExpandMore,
|
|
7546
7685
|
{
|
|
7547
7686
|
sx: (muiTheme) => ({
|
|
@@ -7560,11 +7699,11 @@ var LiteLLMBudgetGauges = ({
|
|
|
7560
7699
|
}
|
|
7561
7700
|
};
|
|
7562
7701
|
const hasFooter = resolvedCtas.length > 0 || !!action;
|
|
7563
|
-
const Wrapper = bare ?
|
|
7564
|
-
return /* @__PURE__ */ (0,
|
|
7565
|
-
/* @__PURE__ */ (0,
|
|
7566
|
-
!bare && /* @__PURE__ */ (0,
|
|
7567
|
-
!loading && !error && /* @__PURE__ */ (0,
|
|
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)(
|
|
7568
7707
|
StatusPill,
|
|
7569
7708
|
{
|
|
7570
7709
|
label: summaryText,
|
|
@@ -7573,19 +7712,19 @@ var LiteLLMBudgetGauges = ({
|
|
|
7573
7712
|
}
|
|
7574
7713
|
)
|
|
7575
7714
|
] }),
|
|
7576
|
-
viewState.kind === "loading" && /* @__PURE__ */ (0,
|
|
7577
|
-
/* @__PURE__ */ (0,
|
|
7578
|
-
/* @__PURE__ */ (0,
|
|
7579
|
-
/* @__PURE__ */ (0,
|
|
7580
|
-
/* @__PURE__ */ (0,
|
|
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 })
|
|
7581
7720
|
] }),
|
|
7582
|
-
/* @__PURE__ */ (0,
|
|
7721
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Skeleton8.default, { variant: "text", width: 64, height: 12 })
|
|
7583
7722
|
] }, i)) }),
|
|
7584
|
-
viewState.kind === "error" && /* @__PURE__ */ (0,
|
|
7585
|
-
viewState.kind === "unprovisioned" && /* @__PURE__ */ (0,
|
|
7586
|
-
viewState.kind === "ready" && /* @__PURE__ */ (0,
|
|
7587
|
-
/* @__PURE__ */ (0,
|
|
7588
|
-
|
|
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,
|
|
7589
7728
|
{
|
|
7590
7729
|
sx: {
|
|
7591
7730
|
display: "flex",
|
|
@@ -7595,7 +7734,7 @@ var LiteLLMBudgetGauges = ({
|
|
|
7595
7734
|
minWidth: 0
|
|
7596
7735
|
},
|
|
7597
7736
|
children: [
|
|
7598
|
-
/* @__PURE__ */ (0,
|
|
7737
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7599
7738
|
InlineStat,
|
|
7600
7739
|
{
|
|
7601
7740
|
label: "Today spent",
|
|
@@ -7605,8 +7744,8 @@ var LiteLLMBudgetGauges = ({
|
|
|
7605
7744
|
title: usageLoading || viewState.usageUnavailable ? void 0 : "Spend since local midnight"
|
|
7606
7745
|
}
|
|
7607
7746
|
),
|
|
7608
|
-
/* @__PURE__ */ (0,
|
|
7609
|
-
/* @__PURE__ */ (0,
|
|
7747
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Box20.default, { sx: { width: "1px", bgcolor: "divider", flexShrink: 0 } }),
|
|
7748
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7610
7749
|
InlineStat,
|
|
7611
7750
|
{
|
|
7612
7751
|
label: "Month to date",
|
|
@@ -7618,15 +7757,15 @@ var LiteLLMBudgetGauges = ({
|
|
|
7618
7757
|
]
|
|
7619
7758
|
}
|
|
7620
7759
|
),
|
|
7621
|
-
/* @__PURE__ */ (0,
|
|
7622
|
-
|
|
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,
|
|
7623
7762
|
{
|
|
7624
7763
|
sx: i === 0 ? void 0 : { borderTop: "1px solid", borderColor: "divider" },
|
|
7625
|
-
children: /* @__PURE__ */ (0,
|
|
7764
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LevelRow, { gauge, size: gaugeSize, keysHref: keysTabHref })
|
|
7626
7765
|
},
|
|
7627
7766
|
gauge.kind
|
|
7628
7767
|
)) }),
|
|
7629
|
-
/* @__PURE__ */ (0,
|
|
7768
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_Box20.default, { sx: { mt: 1.25 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7630
7769
|
SpendStrip,
|
|
7631
7770
|
{
|
|
7632
7771
|
data: dailySpend,
|
|
@@ -7637,8 +7776,8 @@ var LiteLLMBudgetGauges = ({
|
|
|
7637
7776
|
maxBudget: user?.max_budget ?? void 0
|
|
7638
7777
|
}
|
|
7639
7778
|
) }),
|
|
7640
|
-
/* @__PURE__ */ (0,
|
|
7641
|
-
|
|
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,
|
|
7642
7781
|
{
|
|
7643
7782
|
id: expandedRegionId,
|
|
7644
7783
|
sx: {
|
|
@@ -7648,7 +7787,7 @@ var LiteLLMBudgetGauges = ({
|
|
|
7648
7787
|
maxHeight: 300,
|
|
7649
7788
|
overflowY: "auto"
|
|
7650
7789
|
},
|
|
7651
|
-
children: /* @__PURE__ */ (0,
|
|
7790
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LimitListPanel, { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7652
7791
|
BudgetLimitList,
|
|
7653
7792
|
{
|
|
7654
7793
|
limits: expandedLimits,
|
|
@@ -7659,8 +7798,8 @@ var LiteLLMBudgetGauges = ({
|
|
|
7659
7798
|
}
|
|
7660
7799
|
) })
|
|
7661
7800
|
] }),
|
|
7662
|
-
hasFooter && /* @__PURE__ */ (0,
|
|
7663
|
-
|
|
7801
|
+
hasFooter && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
7802
|
+
import_Box20.default,
|
|
7664
7803
|
{
|
|
7665
7804
|
sx: (muiTheme) => ({
|
|
7666
7805
|
mt: 2,
|