@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/api.d.ts +13 -1
- package/dist/components/ConnectPage.d.ts +7 -0
- package/dist/components/TeamUsage.d.ts +11 -1
- package/dist/connect.d.ts +8 -0
- package/dist/index.cjs.js +365 -153
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.esm.js +350 -138
- package/dist/index.esm.js.map +4 -4
- package/dist/plugin.d.ts +40 -0
- package/dist/types.d.ts +6 -1
- package/package.json +2 -2
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
|
-
|
|
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) =>
|
|
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
|
|
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,
|
|
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,
|
|
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
|
|
6728
|
-
var
|
|
6729
|
-
var
|
|
6730
|
-
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"));
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
6812
|
-
const [usageLoading, setUsageLoading] = (0,
|
|
6813
|
-
const [usageError, setUsageError] = (0,
|
|
6814
|
-
const [usage, setUsage] = (0,
|
|
6815
|
-
(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)(() => {
|
|
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,
|
|
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 ?
|
|
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,
|
|
6860
|
-
/* @__PURE__ */ (0,
|
|
6861
|
-
!bare && /* @__PURE__ */ (0,
|
|
6862
|
-
/* @__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)(
|
|
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,
|
|
6871
|
-
/* @__PURE__ */ (0,
|
|
6872
|
-
/* @__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" })
|
|
6873
7085
|
]
|
|
6874
7086
|
}
|
|
6875
7087
|
) })
|
|
6876
7088
|
] }),
|
|
6877
|
-
viewState.kind === "loading" && /* @__PURE__ */ (0,
|
|
6878
|
-
/* @__PURE__ */ (0,
|
|
6879
|
-
/* @__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 })
|
|
6880
7092
|
] }),
|
|
6881
|
-
viewState.kind === "error" && /* @__PURE__ */ (0,
|
|
6882
|
-
viewState.kind === "unprovisioned" && /* @__PURE__ */ (0,
|
|
6883
|
-
viewState.kind === "ready" && partialFailure && /* @__PURE__ */ (0,
|
|
6884
|
-
viewState.kind === "ready" && /* @__PURE__ */ (0,
|
|
6885
|
-
/* @__PURE__ */ (0,
|
|
6886
|
-
|
|
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,
|
|
6898
|
-
/* @__PURE__ */ (0,
|
|
6899
|
-
|
|
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,
|
|
6906
|
-
/* @__PURE__ */ (0,
|
|
6907
|
-
/* @__PURE__ */ (0,
|
|
6908
|
-
/* @__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)(
|
|
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,
|
|
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,
|
|
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
|
|
7151
|
+
var import_react16 = require("react");
|
|
6940
7152
|
var import_frontend_plugin_api6 = require("@backstage/frontend-plugin-api");
|
|
6941
|
-
var
|
|
6942
|
-
var
|
|
6943
|
-
var
|
|
6944
|
-
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"));
|
|
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
|
|
6952
|
-
var
|
|
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
|
|
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,
|
|
7008
|
-
|
|
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,
|
|
7026
|
-
/* @__PURE__ */ (0,
|
|
7027
|
-
/* @__PURE__ */ (0,
|
|
7028
|
-
|
|
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,
|
|
7251
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Tag, { children: label })
|
|
7040
7252
|
] }),
|
|
7041
|
-
/* @__PURE__ */ (0,
|
|
7042
|
-
|
|
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,
|
|
7059
|
-
|
|
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,
|
|
7090
|
-
|
|
7301
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
7302
|
+
import_Typography18.default,
|
|
7091
7303
|
{
|
|
7092
|
-
component:
|
|
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,
|
|
7113
|
-
|
|
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,
|
|
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,
|
|
7135
|
-
/* @__PURE__ */ (0,
|
|
7136
|
-
limit ? /* @__PURE__ */ (0,
|
|
7137
|
-
/* @__PURE__ */ (0,
|
|
7138
|
-
|
|
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,
|
|
7155
|
-
|
|
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,
|
|
7172
|
-
|
|
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,
|
|
7189
|
-
/* @__PURE__ */ (0,
|
|
7190
|
-
|
|
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,
|
|
7208
|
-
|
|
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,
|
|
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,
|
|
7243
|
-
|
|
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,
|
|
7255
|
-
/* @__PURE__ */ (0,
|
|
7256
|
-
/* @__PURE__ */ (0,
|
|
7257
|
-
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)(
|
|
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,
|
|
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,
|
|
7289
|
-
/* @__PURE__ */ (0,
|
|
7290
|
-
/* @__PURE__ */ (0,
|
|
7291
|
-
|
|
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,
|
|
7303
|
-
/* @__PURE__ */ (0,
|
|
7304
|
-
/* @__PURE__ */ (0,
|
|
7305
|
-
|
|
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,
|
|
7315
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
7368
|
-
const [usageError, setUsageError] = (0,
|
|
7369
|
-
const [dailySpend, setDailySpend] = (0,
|
|
7370
|
-
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);
|
|
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,
|
|
7589
|
+
const [uncontrolledExpanded, setUncontrolledExpanded] = (0, import_react16.useState)(defaultExpanded);
|
|
7378
7590
|
const isExpanded = isControlled ? expanded : uncontrolledExpanded;
|
|
7379
|
-
const toggleExpanded = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
7418
|
-
const headline = (0,
|
|
7419
|
-
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)(
|
|
7420
7632
|
() => buildBudgetSummary(user, teams, keys, maxExpandedKeys),
|
|
7421
7633
|
[user, teams, keys, maxExpandedKeys]
|
|
7422
7634
|
);
|
|
7423
|
-
const expandedLimits = (0,
|
|
7635
|
+
const expandedLimits = (0, import_react16.useMemo)(
|
|
7424
7636
|
() => allBudgetLimits(expandedSummary),
|
|
7425
7637
|
[expandedSummary]
|
|
7426
7638
|
);
|
|
7427
|
-
const viewState = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
7464
|
-
|
|
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,
|
|
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 ?
|
|
7491
|
-
return /* @__PURE__ */ (0,
|
|
7492
|
-
/* @__PURE__ */ (0,
|
|
7493
|
-
!bare && /* @__PURE__ */ (0,
|
|
7494
|
-
!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)(
|
|
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,
|
|
7504
|
-
/* @__PURE__ */ (0,
|
|
7505
|
-
/* @__PURE__ */ (0,
|
|
7506
|
-
/* @__PURE__ */ (0,
|
|
7507
|
-
/* @__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 })
|
|
7508
7720
|
] }),
|
|
7509
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
7512
|
-
viewState.kind === "unprovisioned" && /* @__PURE__ */ (0,
|
|
7513
|
-
viewState.kind === "ready" && /* @__PURE__ */ (0,
|
|
7514
|
-
/* @__PURE__ */ (0,
|
|
7515
|
-
|
|
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,
|
|
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,
|
|
7536
|
-
/* @__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)(
|
|
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,
|
|
7549
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
7568
|
-
|
|
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,
|
|
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,
|
|
7590
|
-
|
|
7801
|
+
hasFooter && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
7802
|
+
import_Box20.default,
|
|
7591
7803
|
{
|
|
7592
7804
|
sx: (muiTheme) => ({
|
|
7593
7805
|
mt: 2,
|