@acarmisc/backstage-plugin-litellm 0.24.0 → 0.26.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/README.md +3 -2
- package/dist/SearchInput.d.ts +1 -0
- package/dist/budget.d.ts +8 -0
- package/dist/components/BudgetLimitList.d.ts +41 -0
- package/dist/components/GenerateKeyDialog.d.ts +8 -7
- package/dist/components/KeyFormDialog.d.ts +42 -0
- package/dist/components/KeysTable.d.ts +4 -5
- package/dist/components/LiteLLMBudgetGauges.d.ts +34 -2
- package/dist/components/SearchInput.d.ts +9 -0
- package/dist/index.cjs.js +708 -548
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +649 -489
- package/dist/index.esm.js.map +4 -4
- package/dist/types.d.ts +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,11 +86,12 @@ The **Models** tab lists every model the LiteLLM proxy exposes, with per-model i
|
|
|
86
86
|
- `litellmPlugin` — the frontend plugin instance
|
|
87
87
|
- `LiteLLMPage` — main plugin page (keys, usage, team context)
|
|
88
88
|
- `LiteLLMHomeWidget` — homepage usage summary card
|
|
89
|
-
- `
|
|
89
|
+
- `KeyFormDialog` — shared key form for both generating and editing a key (surfaces failures inline, warns on duplicate aliases, team-scoped model picker, unlimited-budget toggle when gated on)
|
|
90
|
+
- `GenerateKeyDialog` — deprecated wrapper around `KeyFormDialog` with `mode="create"`
|
|
90
91
|
- `DashboardHeader`, `KeysTable`, `UsageStats`, `TeamUsage` — individual page sections, exported for composition
|
|
91
92
|
- `LiteLlmApi`, `liteLlmApiRef` — API client and its Backstage API ref
|
|
92
93
|
|
|
93
|
-
Note: `DashboardHeader` and `KeysTable` are composition pieces driven by `LiteLLMPage` and their props differ from older versions. `LiteLLMPage` is the supported entry point; composing the sections directly means keeping them in sync with the page's data wiring (keys, models, teams, and the `onGenerateKeyClick`
|
|
94
|
+
Note: `DashboardHeader` and `KeysTable` are composition pieces driven by `LiteLLMPage` and their props differ from older versions. `LiteLLMPage` is the supported entry point; composing the sections directly means keeping them in sync with the page's data wiring (keys, models, teams, and the `onGenerateKeyClick`/`onEditKey` callbacks).
|
|
94
95
|
|
|
95
96
|
## License
|
|
96
97
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/budget.d.ts
CHANGED
|
@@ -45,6 +45,14 @@ export interface BudgetSummary {
|
|
|
45
45
|
* team falls back to the owner's personal budget.
|
|
46
46
|
*/
|
|
47
47
|
export declare function buildBudgetSummary(user: UserInfo | null, teams: TeamInfo[], keys: VirtualKey[], maxKeys?: number): BudgetSummary;
|
|
48
|
+
/**
|
|
49
|
+
* Every concrete limit across all levels, keys first then personal then
|
|
50
|
+
* teams. The per-level slices are already sorted by proximity to the cap, so
|
|
51
|
+
* each level's limits stay ordered; this is the flat list for a "show all
|
|
52
|
+
* limits" view. Keys beyond a display `maxKeys` are not included — build the
|
|
53
|
+
* summary with a large `maxKeys` when the full list is needed.
|
|
54
|
+
*/
|
|
55
|
+
export declare function allBudgetLimits(summary: BudgetSummary): BudgetLimit[];
|
|
48
56
|
/** One gauge in the condensed homepage card — a single enforcement level. */
|
|
49
57
|
export interface BudgetGauge {
|
|
50
58
|
kind: 'key' | 'user' | 'team';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared budget-limit presentation used by both budget cards: the
|
|
3
|
+
* `LiteLLMBudgetWidget` (full/compact meter list) and the condensed
|
|
4
|
+
* `LiteLLMBudgetGauges` (expanded "all limits" view). Keeping the card in one
|
|
5
|
+
* place means a limit reads identically wherever it is shown.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import type { Theme } from '@mui/material/styles';
|
|
9
|
+
import { BudgetLimit } from '../budget';
|
|
10
|
+
import { Tone } from './ui';
|
|
11
|
+
/** Semantic colour for a tone, from the host theme. */
|
|
12
|
+
export declare function levelToneColor(tone: Tone | undefined, theme: Theme): string;
|
|
13
|
+
/** Spend-vs-cap meter card for a single limit. */
|
|
14
|
+
export declare const LimitCard: React.FC<{
|
|
15
|
+
limit: BudgetLimit;
|
|
16
|
+
}>;
|
|
17
|
+
/** A LimitCard prefixed with a small KEY / USER / TEAM tag. */
|
|
18
|
+
export declare const TaggedLimit: React.FC<{
|
|
19
|
+
limit: BudgetLimit;
|
|
20
|
+
}>;
|
|
21
|
+
/** A key-budget note under a limit list — plain text when no href is given. */
|
|
22
|
+
export declare const MoreKeysNote: React.FC<{
|
|
23
|
+
count: number;
|
|
24
|
+
href?: string;
|
|
25
|
+
label?: string;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Flat list of concrete limits across every level, as tagged meter cards.
|
|
29
|
+
* Used by the condensed gauges card's expanded view; the full widget renders
|
|
30
|
+
* its own grouped-by-level rail instead.
|
|
31
|
+
*/
|
|
32
|
+
export declare const BudgetLimitList: React.FC<{
|
|
33
|
+
limits: BudgetLimit[];
|
|
34
|
+
/** Keys beyond the supplied limits — rendered as a trailing note. */
|
|
35
|
+
hiddenKeyCount?: number;
|
|
36
|
+
keysHref?: string;
|
|
37
|
+
}>;
|
|
38
|
+
/** Inset panel used to hold a nested list of limits inside a card. */
|
|
39
|
+
export declare const LimitListPanel: React.FC<{
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
}>;
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { GenerateKeyRequest, GenerateKeyResponse, LiteLlmConfig, ModelInfo, TeamInfo, VirtualKey } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use {@link KeyFormDialog} with `mode="create"` instead — this
|
|
5
|
+
* wrapper only forwards props for backwards compatibility with the public
|
|
6
|
+
* entrypoint and will be removed in a future release.
|
|
7
|
+
*/
|
|
8
|
+
export declare const GenerateKeyDialog: React.FC<{
|
|
4
9
|
open: boolean;
|
|
5
10
|
onClose: () => void;
|
|
6
11
|
keys: VirtualKey[];
|
|
7
12
|
models: ModelInfo[];
|
|
8
13
|
teams: TeamInfo[];
|
|
9
|
-
/** Current user's LiteLLM user id, used to pre-fill a default key alias. */
|
|
10
14
|
username?: string;
|
|
11
|
-
/** Controls for the "Generate New Key" form; see litellm.keyGeneration in app-config.yaml. */
|
|
12
15
|
keyGenerationSettings?: {
|
|
13
16
|
allowUnlimitedBudget: boolean;
|
|
14
17
|
teamRequired: boolean;
|
|
15
18
|
};
|
|
16
19
|
onGenerateKey: (request: GenerateKeyRequest) => Promise<GenerateKeyResponse>;
|
|
17
20
|
onGetConfig: () => Promise<LiteLlmConfig>;
|
|
18
|
-
}
|
|
19
|
-
export declare const GenerateKeyDialog: React.FC<GenerateKeyDialogProps>;
|
|
20
|
-
export {};
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { VirtualKey, ModelInfo, TeamInfo, GenerateKeyRequest, GenerateKeyResponse, UpdateKeyRequest, LiteLlmConfig } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Single form dialog for both key creation (`mode="create"`) and key editing
|
|
5
|
+
* (`mode="edit"`).
|
|
6
|
+
*
|
|
7
|
+
* Create mode: alias (pre-filled), team, models, duration, budget (+unlimited
|
|
8
|
+
* when gated on), TPM/RPM in the Advanced accordion, and the post-generation
|
|
9
|
+
* screen with copyable key + starter snippets.
|
|
10
|
+
*
|
|
11
|
+
* Edit mode: the same shared fields but no duration (expiry is immutable after
|
|
12
|
+
* creation) and no team switch (LiteLLM /key/update semantics); adds a masked
|
|
13
|
+
* key header and the Danger Zone (reset spend). Budget validation, the
|
|
14
|
+
* unlimited toggle and the team-scoped model filtering behave exactly as they
|
|
15
|
+
* do at creation time.
|
|
16
|
+
*/
|
|
17
|
+
export type KeyFormDialogMode = 'create' | 'edit';
|
|
18
|
+
export interface KeyFormDialogProps {
|
|
19
|
+
open: boolean;
|
|
20
|
+
onClose: () => void;
|
|
21
|
+
/** `create` generates a new key; `edit` updates an existing one. */
|
|
22
|
+
mode: KeyFormDialogMode;
|
|
23
|
+
/** Key being edited (edit mode only). */
|
|
24
|
+
keyToEdit?: VirtualKey | null;
|
|
25
|
+
keys: VirtualKey[];
|
|
26
|
+
models: ModelInfo[];
|
|
27
|
+
teams: TeamInfo[];
|
|
28
|
+
/** Current user's LiteLLM user id, used to pre-fill a default key alias. */
|
|
29
|
+
username?: string;
|
|
30
|
+
/** Controls for the key form; see litellm.keyGeneration in app-config.yaml. */
|
|
31
|
+
keyGenerationSettings?: {
|
|
32
|
+
allowUnlimitedBudget: boolean;
|
|
33
|
+
teamRequired: boolean;
|
|
34
|
+
};
|
|
35
|
+
onCreateKey: (request: GenerateKeyRequest) => Promise<GenerateKeyResponse>;
|
|
36
|
+
onUpdateKey: (keyId: string, request: UpdateKeyRequest) => Promise<void>;
|
|
37
|
+
onResetKeySpend?: (keyId: string) => Promise<void>;
|
|
38
|
+
onGetConfig: () => Promise<LiteLlmConfig>;
|
|
39
|
+
}
|
|
40
|
+
export declare const KeyFormDialog: React.FC<KeyFormDialogProps>;
|
|
41
|
+
export declare function fmtCost(perToken?: number): string | null;
|
|
42
|
+
export declare function formatContextWindow(maxInput?: number, maxOutput?: number): string | null;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { VirtualKey
|
|
2
|
+
import { VirtualKey } from '../types';
|
|
3
3
|
interface KeysTableProps {
|
|
4
4
|
keys: VirtualKey[];
|
|
5
|
-
|
|
6
|
-
/** Opens the shared "Generate New Key" dialog (rendered at page level). */
|
|
5
|
+
/** Opens the shared key form dialog in create mode (rendered at page level). */
|
|
7
6
|
onGenerateKeyClick: () => void;
|
|
7
|
+
/** Opens the shared key form dialog in edit mode for the given key. */
|
|
8
|
+
onEditKey: (key: VirtualKey) => void;
|
|
8
9
|
loading: boolean;
|
|
9
|
-
onUpdateKey: (keyId: string, request: UpdateKeyRequest) => Promise<void>;
|
|
10
10
|
onBlockKey: (keyId: string) => Promise<void>;
|
|
11
11
|
onUnblockKey: (keyId: string) => Promise<void>;
|
|
12
|
-
onResetKeySpend: (keyId: string) => Promise<void>;
|
|
13
12
|
onDeleteKey: (keyId: string) => Promise<void>;
|
|
14
13
|
onPruneExpiredKeys: () => Promise<{
|
|
15
14
|
pruned: number;
|
|
@@ -9,8 +9,22 @@
|
|
|
9
9
|
* user has no cap at that level, so the card keeps a stable shape as data
|
|
10
10
|
* loads and across users. When a level holds several limits, the ring shows
|
|
11
11
|
* the one closest to its cap and a "+N more" link counts the rest.
|
|
12
|
+
*
|
|
13
|
+
* The bottom action bar is composable: pass any subset of `ctas` — mint a new
|
|
14
|
+
* key, open the LiteLLM module, or expand the full per-limit list in place —
|
|
15
|
+
* in the order you want. `action` remains an escape hatch for a fully custom
|
|
16
|
+
* node; when either is present it renders below a divider.
|
|
12
17
|
*/
|
|
13
18
|
import React from 'react';
|
|
19
|
+
/** Preset action-bar buttons. `label` overrides the default copy. */
|
|
20
|
+
export type BudgetCtaKind = 'new-key' | 'module' | 'all-limits';
|
|
21
|
+
export interface BudgetCtaSpec {
|
|
22
|
+
kind: BudgetCtaKind;
|
|
23
|
+
/** Override the default label. */
|
|
24
|
+
label?: string;
|
|
25
|
+
}
|
|
26
|
+
/** Either a bare kind (`'module'`) or a spec object (`{ kind: 'module' }`). */
|
|
27
|
+
export type BudgetCta = BudgetCtaKind | BudgetCtaSpec;
|
|
14
28
|
export interface LiteLLMBudgetGaugesProps {
|
|
15
29
|
/** Optional title override. Defaults to 'Budget'. */
|
|
16
30
|
title?: string;
|
|
@@ -18,10 +32,28 @@ export interface LiteLLMBudgetGaugesProps {
|
|
|
18
32
|
size?: number;
|
|
19
33
|
/** Where the "+N more" key link points. Defaults to the Keys tab. */
|
|
20
34
|
keysHref?: string;
|
|
35
|
+
/** Where the module CTA points. Defaults to the LiteLLM page. */
|
|
36
|
+
moduleHref?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Called when the "new key" CTA is used. When omitted, the CTA deep-links
|
|
39
|
+
* to the module with `?generate=1`, which opens the generate-key dialog.
|
|
40
|
+
*/
|
|
41
|
+
onCreateKey?: () => void;
|
|
21
42
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
43
|
+
* Action-bar buttons to render, in order. Defaults to
|
|
44
|
+
* `['new-key', 'module', 'all-limits']`. Pass `[]` to hide the bar; the
|
|
45
|
+
* `all-limits` entry is dropped automatically when the user has no limits.
|
|
24
46
|
*/
|
|
47
|
+
ctas?: BudgetCta[];
|
|
48
|
+
/** Max key limits listed in the expanded view. Defaults to 8. */
|
|
49
|
+
maxExpandedKeys?: number;
|
|
50
|
+
/** Controlled expanded state for the all-limits view. */
|
|
51
|
+
expanded?: boolean;
|
|
52
|
+
/** Initial expanded state when uncontrolled. Defaults to false. */
|
|
53
|
+
defaultExpanded?: boolean;
|
|
54
|
+
/** Notified whenever the expanded state changes. */
|
|
55
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
56
|
+
/** Fully custom node pinned below the CTAs, below a divider. */
|
|
25
57
|
action?: React.ReactNode;
|
|
26
58
|
}
|
|
27
59
|
export declare const LiteLLMBudgetGauges: React.FC<LiteLLMBudgetGaugesProps>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface SearchInputProps {
|
|
3
|
+
label?: string;
|
|
4
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
5
|
+
value: string;
|
|
6
|
+
onInputChange?: (value: string) => void;
|
|
7
|
+
}
|
|
8
|
+
declare const SearchInput: React.FC<SearchInputProps>;
|
|
9
|
+
export default SearchInput;
|