@acarmisc/backstage-plugin-litellm 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.d.ts +0 -2
- package/dist/components/KeysTable.d.ts +0 -1
- package/dist/index.cjs.js +4 -90
- package/dist/index.cjs.js.map +2 -2
- package/dist/index.esm.js +4 -90
- package/dist/index.esm.js.map +2 -2
- package/dist/types.d.ts +0 -4
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -96,9 +96,6 @@ var init_api = __esm({
|
|
|
96
96
|
async deleteKey(keyId) {
|
|
97
97
|
return this.del(`/keys/${encodeURIComponent(keyId)}`);
|
|
98
98
|
}
|
|
99
|
-
async rotateKey(keyId) {
|
|
100
|
-
return this.post(`/keys/${encodeURIComponent(keyId)}/regenerate`, {});
|
|
101
|
-
}
|
|
102
99
|
async blockKey(keyId) {
|
|
103
100
|
await this.post(`/keys/${encodeURIComponent(keyId)}/block`, {});
|
|
104
101
|
}
|
|
@@ -316,9 +313,7 @@ var init_KeysTable = __esm({
|
|
|
316
313
|
tpm_limit: void 0,
|
|
317
314
|
rpm_limit: void 0,
|
|
318
315
|
team_id: void 0,
|
|
319
|
-
key_type: "llm_api"
|
|
320
|
-
auto_rotate: false,
|
|
321
|
-
rotation_interval_days: void 0
|
|
316
|
+
key_type: "llm_api"
|
|
322
317
|
});
|
|
323
318
|
keyToEditForm = (k) => ({
|
|
324
319
|
key_alias: k.key_alias ?? "",
|
|
@@ -334,7 +329,6 @@ var init_KeysTable = __esm({
|
|
|
334
329
|
loading,
|
|
335
330
|
onGenerateKey,
|
|
336
331
|
onUpdateKey,
|
|
337
|
-
onRotateKey,
|
|
338
332
|
onBlockKey,
|
|
339
333
|
onUnblockKey,
|
|
340
334
|
onResetKeySpend,
|
|
@@ -352,8 +346,6 @@ var init_KeysTable = __esm({
|
|
|
352
346
|
const [editingKey, setEditingKey] = useState(null);
|
|
353
347
|
const [editForm, setEditForm] = useState({});
|
|
354
348
|
const [editSubmitting, setEditSubmitting] = useState(false);
|
|
355
|
-
const [rotatingKeyId, setRotatingKeyId] = useState(null);
|
|
356
|
-
const [rotatedKeyValue, setRotatedKeyValue] = useState(null);
|
|
357
349
|
const [blockingKeyId, setBlockingKeyId] = useState(null);
|
|
358
350
|
const [deleteConfirmId, setDeleteConfirmId] = useState(null);
|
|
359
351
|
const [deleteSubmitting, setDeleteSubmitting] = useState(false);
|
|
@@ -433,17 +425,6 @@ var init_KeysTable = __esm({
|
|
|
433
425
|
setEditSubmitting(false);
|
|
434
426
|
}
|
|
435
427
|
};
|
|
436
|
-
const handleRotate = async (keyId) => {
|
|
437
|
-
setRotatingKeyId(keyId);
|
|
438
|
-
try {
|
|
439
|
-
const response = await onRotateKey(keyId);
|
|
440
|
-
setRotatedKeyValue(response.key);
|
|
441
|
-
} catch (error) {
|
|
442
|
-
console.error("Failed to rotate key:", error);
|
|
443
|
-
} finally {
|
|
444
|
-
setRotatingKeyId(null);
|
|
445
|
-
}
|
|
446
|
-
};
|
|
447
428
|
const handleToggleBlock = async (key) => {
|
|
448
429
|
const keyId = key.token ?? key.key;
|
|
449
430
|
setBlockingKeyId(keyId);
|
|
@@ -548,7 +529,6 @@ var init_KeysTable = __esm({
|
|
|
548
529
|
"Generate Your First Key"
|
|
549
530
|
)))) : filteredKeys.map((key) => {
|
|
550
531
|
const keyId = key.token ?? key.key;
|
|
551
|
-
const isRotating = rotatingKeyId === keyId;
|
|
552
532
|
const isBlocking = blockingKeyId === keyId;
|
|
553
533
|
return /* @__PURE__ */ React2.createElement(TableRow, { key: keyId, sx: key.blocked ? { bgcolor: "action.disabledBackground" } : void 0 }, /* @__PURE__ */ React2.createElement(TableCell, null, /* @__PURE__ */ React2.createElement(Box2, { display: "flex", alignItems: "center", gap: 0.5 }, key.key_alias || "-", key.blocked && /* @__PURE__ */ React2.createElement(Chip2, { label: "Blocked", color: "error", size: "small" }))), /* @__PURE__ */ React2.createElement(TableCell, null, /* @__PURE__ */ React2.createElement(Box2, { display: "flex", alignItems: "center", gap: 0.5 }, /* @__PURE__ */ React2.createElement(
|
|
554
534
|
Typography2,
|
|
@@ -567,14 +547,6 @@ var init_KeysTable = __esm({
|
|
|
567
547
|
},
|
|
568
548
|
shortKeyId(keyId)
|
|
569
549
|
), /* @__PURE__ */ React2.createElement(IconButton, { size: "small", onClick: () => copyToClipboard(keyId), title: "Copy Key ID" }, /* @__PURE__ */ React2.createElement(ContentCopy, { fontSize: "small" })))), /* @__PURE__ */ React2.createElement(TableCell, null, formatDate(key.created_at)), /* @__PURE__ */ React2.createElement(TableCell, null, /* @__PURE__ */ React2.createElement(ExpiryChip, { expiresAt: key.expires_at })), /* @__PURE__ */ React2.createElement(TableCell, null, /* @__PURE__ */ React2.createElement(BudgetCell, { spend: key.spend ?? 0, maxBudget: key.max_budget })), /* @__PURE__ */ React2.createElement(TableCell, null, /* @__PURE__ */ React2.createElement(Typography2, { variant: "body2" }, key.tpm_limit ?? "-", " / ", key.rpm_limit ?? "-")), /* @__PURE__ */ React2.createElement(TableCell, null, /* @__PURE__ */ React2.createElement(Box2, { display: "flex", gap: 0.5, flexWrap: "wrap" }, key.models?.slice(0, 2).map((model) => /* @__PURE__ */ React2.createElement(Chip2, { key: model, label: model, size: "small" })), (key.models?.length || 0) > 2 && /* @__PURE__ */ React2.createElement(Chip2, { label: `+${(key.models?.length || 0) - 2}`, size: "small", variant: "outlined" }))), /* @__PURE__ */ React2.createElement(TableCell, { align: "right" }, /* @__PURE__ */ React2.createElement(IconButton, { onClick: () => handleOpenEdit(key), title: "Edit key" }, /* @__PURE__ */ React2.createElement(Edit, { fontSize: "small" })), /* @__PURE__ */ React2.createElement(
|
|
570
|
-
IconButton,
|
|
571
|
-
{
|
|
572
|
-
onClick: () => handleRotate(keyId),
|
|
573
|
-
disabled: isRotating,
|
|
574
|
-
title: "Rotate key \u2014 generates a new secret, same settings"
|
|
575
|
-
},
|
|
576
|
-
isRotating ? /* @__PURE__ */ React2.createElement(CircularProgress, { size: 18 }) : /* @__PURE__ */ React2.createElement(Autorenew, { fontSize: "small" })
|
|
577
|
-
), /* @__PURE__ */ React2.createElement(
|
|
578
550
|
IconButton,
|
|
579
551
|
{
|
|
580
552
|
onClick: () => handleToggleBlock(key),
|
|
@@ -721,36 +693,7 @@ var init_KeysTable = __esm({
|
|
|
721
693
|
onChange: (e) => setFormData({ ...formData, rpm_limit: e.target.value ? Number(e.target.value) : void 0 }),
|
|
722
694
|
fullWidth: true
|
|
723
695
|
}
|
|
724
|
-
), /* @__PURE__ */ React2.createElement(
|
|
725
|
-
FormControlLabel,
|
|
726
|
-
{
|
|
727
|
-
control: /* @__PURE__ */ React2.createElement(
|
|
728
|
-
Checkbox,
|
|
729
|
-
{
|
|
730
|
-
checked: !!formData.auto_rotate,
|
|
731
|
-
onChange: (e) => setFormData({
|
|
732
|
-
...formData,
|
|
733
|
-
auto_rotate: e.target.checked,
|
|
734
|
-
rotation_interval_days: e.target.checked ? formData.rotation_interval_days ?? 90 : void 0
|
|
735
|
-
})
|
|
736
|
-
}
|
|
737
|
-
),
|
|
738
|
-
label: "Auto-rotate (LiteLLM rotates the secret on a schedule)"
|
|
739
|
-
}
|
|
740
|
-
), formData.auto_rotate && /* @__PURE__ */ React2.createElement(
|
|
741
|
-
TextField,
|
|
742
|
-
{
|
|
743
|
-
label: "Rotate every (days)",
|
|
744
|
-
type: "number",
|
|
745
|
-
value: formData.rotation_interval_days ?? "",
|
|
746
|
-
onChange: (e) => setFormData({
|
|
747
|
-
...formData,
|
|
748
|
-
rotation_interval_days: e.target.value ? Number(e.target.value) : void 0
|
|
749
|
-
}),
|
|
750
|
-
helperText: "LiteLLM enforces this interval server-side; the old secret stops working the moment it rotates.",
|
|
751
|
-
fullWidth: true
|
|
752
|
-
}
|
|
753
|
-
))), /* @__PURE__ */ React2.createElement(DialogActions, null, /* @__PURE__ */ React2.createElement(Button, { onClick: handleCloseModal }, newKeyValue ? "Done" : "Cancel"), !newKeyValue && /* @__PURE__ */ React2.createElement(
|
|
696
|
+
))), /* @__PURE__ */ React2.createElement(DialogActions, null, newKeyValue ? /* @__PURE__ */ React2.createElement(Button, { onClick: handleCloseModal, variant: "contained", color: "success" }, "Done") : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Button, { onClick: handleCloseModal }, "Cancel"), /* @__PURE__ */ React2.createElement(
|
|
754
697
|
Button,
|
|
755
698
|
{
|
|
756
699
|
onClick: handleGenerate,
|
|
@@ -759,7 +702,7 @@ var init_KeysTable = __esm({
|
|
|
759
702
|
disabled: !canGenerate
|
|
760
703
|
},
|
|
761
704
|
submitting ? /* @__PURE__ */ React2.createElement(CircularProgress, { size: 24 }) : "Generate"
|
|
762
|
-
)
|
|
705
|
+
)))), /* @__PURE__ */ React2.createElement(Dialog, { open: !!editingKey, onClose: handleCloseEdit, maxWidth: "sm", fullWidth: true }, /* @__PURE__ */ React2.createElement(DialogTitle, null, "Edit Key"), /* @__PURE__ */ React2.createElement(DialogContent, null, editingKey && /* @__PURE__ */ React2.createElement(Box2, { display: "flex", flexDirection: "column", gap: 2, mt: 1 }, /* @__PURE__ */ React2.createElement(Typography2, { variant: "body2", color: "text.secondary" }, /* @__PURE__ */ React2.createElement("code", { style: { fontFamily: "monospace", color: "inherit" } }, maskKey(editingKey.key))), /* @__PURE__ */ React2.createElement(
|
|
763
706
|
TextField,
|
|
764
707
|
{
|
|
765
708
|
label: "Alias",
|
|
@@ -825,26 +768,7 @@ var init_KeysTable = __esm({
|
|
|
825
768
|
onClick: handleResetSpend
|
|
826
769
|
},
|
|
827
770
|
resetSpendSubmitting ? /* @__PURE__ */ React2.createElement(CircularProgress, { size: 16 }) : "Confirm"
|
|
828
|
-
), /* @__PURE__ */ React2.createElement(Button, { size: "small", onClick: () => setResetSpendConfirm(false) }, "Cancel"))))), /* @__PURE__ */ React2.createElement(DialogActions, null, /* @__PURE__ */ React2.createElement(Button, { onClick: handleCloseEdit }, "Cancel"), /* @__PURE__ */ React2.createElement(Button, { onClick: handleUpdate, variant: "contained", color: "primary", disabled: editSubmitting }, editSubmitting ? /* @__PURE__ */ React2.createElement(CircularProgress, { size: 24 }) : "Save"))), /* @__PURE__ */ React2.createElement(Dialog, { open: !!
|
|
829
|
-
Box2,
|
|
830
|
-
{
|
|
831
|
-
display: "flex",
|
|
832
|
-
alignItems: "center",
|
|
833
|
-
gap: 1,
|
|
834
|
-
mt: 2,
|
|
835
|
-
p: 2,
|
|
836
|
-
sx: { backgroundColor: "action.hover", border: "1px solid", borderColor: "divider", borderRadius: 1 }
|
|
837
|
-
},
|
|
838
|
-
/* @__PURE__ */ React2.createElement(
|
|
839
|
-
Typography2,
|
|
840
|
-
{
|
|
841
|
-
component: "code",
|
|
842
|
-
sx: { fontFamily: "monospace", wordBreak: "break-all", flex: 1 }
|
|
843
|
-
},
|
|
844
|
-
rotatedKeyValue
|
|
845
|
-
),
|
|
846
|
-
/* @__PURE__ */ React2.createElement(IconButton, { onClick: () => copyToClipboard(rotatedKeyValue) }, /* @__PURE__ */ React2.createElement(ContentCopy, null))
|
|
847
|
-
)), /* @__PURE__ */ React2.createElement(DialogActions, null, /* @__PURE__ */ React2.createElement(Button, { onClick: () => setRotatedKeyValue(null), variant: "contained", color: "success" }, "Done"))), /* @__PURE__ */ React2.createElement(Dialog, { open: !!deleteConfirmId, onClose: () => setDeleteConfirmId(null), maxWidth: "xs", fullWidth: true }, /* @__PURE__ */ React2.createElement(DialogTitle, null, "Revoke Key?"), /* @__PURE__ */ React2.createElement(DialogContent, null, /* @__PURE__ */ React2.createElement(Typography2, null, "This will permanently revoke the key. Any integrations using it will stop working immediately.")), /* @__PURE__ */ React2.createElement(DialogActions, null, /* @__PURE__ */ React2.createElement(Button, { onClick: () => setDeleteConfirmId(null), disabled: deleteSubmitting }, "Cancel"), /* @__PURE__ */ React2.createElement(
|
|
771
|
+
), /* @__PURE__ */ React2.createElement(Button, { size: "small", onClick: () => setResetSpendConfirm(false) }, "Cancel"))))), /* @__PURE__ */ React2.createElement(DialogActions, null, /* @__PURE__ */ React2.createElement(Button, { onClick: handleCloseEdit }, "Cancel"), /* @__PURE__ */ React2.createElement(Button, { onClick: handleUpdate, variant: "contained", color: "primary", disabled: editSubmitting }, editSubmitting ? /* @__PURE__ */ React2.createElement(CircularProgress, { size: 24 }) : "Save"))), /* @__PURE__ */ React2.createElement(Dialog, { open: !!deleteConfirmId, onClose: () => setDeleteConfirmId(null), maxWidth: "xs", fullWidth: true }, /* @__PURE__ */ React2.createElement(DialogTitle, null, "Revoke Key?"), /* @__PURE__ */ React2.createElement(DialogContent, null, /* @__PURE__ */ React2.createElement(Typography2, null, "This will permanently revoke the key. Any integrations using it will stop working immediately.")), /* @__PURE__ */ React2.createElement(DialogActions, null, /* @__PURE__ */ React2.createElement(Button, { onClick: () => setDeleteConfirmId(null), disabled: deleteSubmitting }, "Cancel"), /* @__PURE__ */ React2.createElement(
|
|
848
772
|
Button,
|
|
849
773
|
{
|
|
850
774
|
onClick: handleConfirmDelete,
|
|
@@ -1584,15 +1508,6 @@ var init_LiteLLMPage = __esm({
|
|
|
1584
1508
|
},
|
|
1585
1509
|
[api, refreshKeys]
|
|
1586
1510
|
);
|
|
1587
|
-
const handleRotateKey = useCallback2(
|
|
1588
|
-
async (keyId) => {
|
|
1589
|
-
const response = await api.rotateKey(keyId);
|
|
1590
|
-
setSnackbar({ message: "Key rotated \u2014 copy the new secret now", severity: "success" });
|
|
1591
|
-
refreshKeys();
|
|
1592
|
-
return response;
|
|
1593
|
-
},
|
|
1594
|
-
[api, refreshKeys]
|
|
1595
|
-
);
|
|
1596
1511
|
const handleDeleteKey = useCallback2(
|
|
1597
1512
|
async (keyId) => {
|
|
1598
1513
|
try {
|
|
@@ -1662,7 +1577,6 @@ var init_LiteLLMPage = __esm({
|
|
|
1662
1577
|
loading: keysLoading || modelsLoading,
|
|
1663
1578
|
onGenerateKey: handleGenerateKey,
|
|
1664
1579
|
onUpdateKey: handleUpdateKey,
|
|
1665
|
-
onRotateKey: handleRotateKey,
|
|
1666
1580
|
onBlockKey: handleBlockKey,
|
|
1667
1581
|
onUnblockKey: handleUnblockKey,
|
|
1668
1582
|
onResetKeySpend: handleResetKeySpend,
|