@acarmisc/backstage-plugin-litellm 0.32.0 → 0.34.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 CHANGED
@@ -1,97 +1,86 @@
1
1
  # @acarmisc/backstage-plugin-litellm
2
2
 
3
- Frontend for the **Backstage LiteLLM Governance Plugin** — lets developers manage LiteLLM virtual API keys and monitor AI model usage directly from Backstage.
3
+ Frontend for the **Backstage LiteLLM Governance Plugin** — lets developers manage
4
+ their LiteLLM virtual keys and follow their AI usage and budgets from Backstage.
4
5
 
5
- Built with the [New Frontend System](https://backstage.io/docs/frontend-system/) (`@backstage/frontend-plugin-api`) and Material-UI.
6
+ Built for the [New Frontend System](https://backstage.io/docs/frontend-system/)
7
+ (`@backstage/frontend-plugin-api`). It needs the backend,
8
+ [`@acarmisc/backstage-plugin-litellm-backend`](https://www.npmjs.com/package/@acarmisc/backstage-plugin-litellm-backend),
9
+ which talks to LiteLLM and enforces every rule.
6
10
 
7
- Pair this package with the backend, [`@acarmisc/backstage-plugin-litellm-backend`](https://www.npmjs.com/package/@acarmisc/backstage-plugin-litellm-backend), which proxies requests to your LiteLLM instance and resolves Backstage identity.
8
-
9
- Full setup docs, configuration reference, and architecture notes live in the [project README](https://github.com/acarmisc/backstage-plugin-litellm-govai#readme).
10
-
11
- ## Screenshots
12
-
13
- | View | Preview |
14
- |------|---------|
15
- | Home widget — `LiteLLMHomeWidget` | ![Home widget](../../docs/screenshots/home-widget.png) |
16
- | Overview / Usage Analytics | ![Usage analytics](../../docs/screenshots/usage-analytics.png) |
17
- | Keys tab — virtual key inventory | ![Keys tab](../../docs/screenshots/keys-tab.png) |
18
- | Generate New Key dialog | ![Generate New Key dialog](../../docs/screenshots/generate-key-dialog.png) |
19
- | Models tab | ![Models tab](../../docs/screenshots/models-tab.png) |
20
- | Compact "Create Key" card | ![Create Key card](../../docs/screenshots/key-card.png) |
11
+ Full documentation — adoption guide, configuration, permissions, security model
12
+ and architecture — starts at the
13
+ [project README](https://github.com/acarmisc/backstage-plugin-litellm-govai#readme).
21
14
 
22
15
  ## Installation
23
16
 
24
- This plugin is designed to be used **within a Backstage monorepo**.
25
-
26
17
  ```bash
27
- yarn add --cwd packages/app @acarmisc/backstage-plugin-litellm
18
+ yarn --cwd packages/app add @acarmisc/backstage-plugin-litellm
28
19
  ```
29
20
 
30
- You'll also need the backend package installed and configured — see its [README](https://www.npmjs.com/package/@acarmisc/backstage-plugin-litellm-backend) for `app-config.yaml` setup.
31
-
32
- ## Usage
33
-
34
- ### Full page
35
-
36
- The `LiteLLMPage` component renders the four-tab governance view: **Overview** (usage KPIs + charts), **Keys** (virtual key inventory), **Teams** (team-scoped usage), and **Models** (proxy model catalog).
21
+ If your app discovers features from its dependencies (`app.packages: all`),
22
+ the plugin is picked up automatically. Otherwise register it:
37
23
 
38
24
  ```tsx
39
- import { litellmPlugin, LiteLLMPage } from '@acarmisc/backstage-plugin-litellm';
40
-
41
25
  // packages/app/src/App.tsx
42
- <Route path="/litellm" element={<LiteLLMPage />} />
43
- ```
44
-
45
- ![Usage Analytics full page](../../docs/screenshots/usage-analytics-overview.png)
26
+ import { createApp } from '@backstage/frontend-defaults';
27
+ import litellmPlugin from '@acarmisc/backstage-plugin-litellm';
46
28
 
47
- ### Home page widget
48
-
49
- `LiteLLMHomeWidget` is a compact card for the Backstage homepage. It shows the signed-in user's own usage — identity is resolved server-side from the Backstage token, so no `userId` prop is required. The header includes a `Today` / `7d` / `30d` period selector and a daily-spend sparkline.
50
-
51
- ```tsx
52
- import { LiteLLMHomeWidget } from '@acarmisc/backstage-plugin-litellm';
53
-
54
- <LiteLLMHomeWidget defaultPeriod="7d" />
29
+ const app = createApp({
30
+ features: [litellmPlugin],
31
+ });
55
32
  ```
56
33
 
57
- | Prop | Type | Default | Description |
58
- |------|------|---------|-------------|
59
- | `defaultPeriod` | `'today' \| '7d' \| '30d'` | `'7d'` | Period shown on first render |
60
- | `title` | `string` | `'LiteLLM Usage'` | Card title override |
34
+ This adds the `/litellm` page and the `liteLlmApiRef` API used by every
35
+ component below.
61
36
 
62
- A slimmer **Create Key** card variant is available for surfaces that only need a one-click shortcut into the key-mint flow:
37
+ ## The `/litellm` page
63
38
 
64
- ![Create Key card](../../docs/screenshots/key-card.png)
39
+ Tabs: **Overview** (usage KPIs and charts), **Keys** (your virtual keys: edit,
40
+ block / unblock, reset spend, delete), **Teams** (team usage, and team
41
+ management for admins), **Models** (the proxy's model catalogue) and **Audit
42
+ Log** (members of `litellm.audit.group` only). `?tab=<name>` opens a tab and
43
+ `?generate=1` opens the Generate New Key dialog.
65
44
 
66
- ### Keys tab
45
+ ![The /litellm page](https://raw.githubusercontent.com/acarmisc/backstage-plugin-litellm-govai/main/docs/images/overview.png)
67
46
 
68
- The **Keys** tab lists every virtual key you own with its alias, key ID, creation and expiry dates, budget bar (`$spent / $limit`), TPM/RPM, and model scope. Each row exposes inline actions: edit, block/unblock, reset spend, and delete.
47
+ ## Homepage components
69
48
 
70
- ![Keys tab](../../docs/screenshots/keys-tab.png)
49
+ | Component | What it shows |
50
+ |---|---|
51
+ | `LiteLLMHomeWidget` | Spend and tokens for `Today` / `7d` / `30d` with a daily sparkline |
52
+ | `LiteLLMBudgetWidget` | The budget hierarchy (key → personal → team → global) with a meter per limit |
53
+ | `LiteLLMBudgetGauges` | A condensed budget card: one ring per level and a month-to-date chart |
54
+ | `GenerateKeyButton` | The shared "Generate New Key" button (`onClick`, or `to="/litellm?generate=1"`) |
71
55
 
72
- ### Generate New Key dialog
73
-
74
- The dialog walks the user through aliasing the key, picking a duration, binding a team, restricting model access, setting a max budget, and configuring per-key TPM/RPM caps. Failures (e.g. duplicate alias) surface inline with the upstream error code preserved.
75
-
76
- ![Generate New Key dialog](../../docs/screenshots/generate-key-dialog.png)
56
+ ```tsx
57
+ import {
58
+ LiteLLMHomeWidget,
59
+ LiteLLMBudgetGauges,
60
+ } from '@acarmisc/backstage-plugin-litellm';
77
61
 
78
- ### Models tab
62
+ <LiteLLMHomeWidget defaultPeriod="7d" />
63
+ <LiteLLMBudgetGauges />
64
+ ```
79
65
 
80
- The **Models** tab lists every model the LiteLLM proxy exposes, with per-model input/output cost, max input/output token limits, and capabilities. The team selector scopes the list to the models the bound team is allowed to call.
66
+ Props for each component are documented in
67
+ [docs/frontend.md](https://github.com/acarmisc/backstage-plugin-litellm-govai/blob/main/docs/frontend.md).
81
68
 
82
- ![Models tab](../../docs/screenshots/models-tab.png)
69
+ ![LiteLLMBudgetGauges](https://raw.githubusercontent.com/acarmisc/backstage-plugin-litellm-govai/main/docs/images/budget-gauges.png)
83
70
 
84
- ## Exports
71
+ To try it without a backend, run `npm start` in this package: it serves the
72
+ plugin with mock data at `http://localhost:3000/litellm` (see
73
+ [CONTRIBUTING.md](https://github.com/acarmisc/backstage-plugin-litellm-govai/blob/main/CONTRIBUTING.md#run-the-frontend-with-mock-data)).
85
74
 
86
- - `litellmPlugin` — the frontend plugin instance
87
- - `LiteLLMPage` — main plugin page (keys, usage, team context)
88
- - `LiteLLMHomeWidget` — homepage usage summary card
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"`
91
- - `DashboardHeader`, `KeysTable`, `UsageStats`, `TeamUsage` — individual page sections, exported for composition
92
- - `LiteLlmApi`, `liteLlmApiRef` — API client and its Backstage API ref
75
+ ## Other exports
93
76
 
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).
77
+ - `litellmPlugin` (also the default export)
78
+ - `LiteLLMPage`, and the building blocks it uses: `DashboardHeader`,
79
+ `KeysTable`, `UsageStats`, `TeamUsage`, `KeyFormDialog`, `ManageTeamDialog`.
80
+ Prefer `LiteLLMPage`; composing the pieces yourself means wiring their data
81
+ and callbacks the way the page does.
82
+ - `LiteLlmApi`, `liteLlmApiRef`, the shared API types, and the
83
+ `litellmTeam*Permission` definitions.
95
84
 
96
85
  ## License
97
86
 
@@ -26,5 +26,3 @@ export interface KeyFormDialogProps {
26
26
  onGetConfig: () => Promise<LiteLlmConfig>;
27
27
  }
28
28
  export declare const KeyFormDialog: FC<KeyFormDialogProps>;
29
- export declare function fmtCost(perToken?: number): string | null;
30
- export declare function formatContextWindow(maxInput?: number, maxOutput?: number): string | null;
@@ -82,5 +82,4 @@ export interface LiteLLMBudgetGaugesProps {
82
82
  teams?: TeamInfo[];
83
83
  keys?: VirtualKey[];
84
84
  }
85
- export { monthToDateRange } from '../dates';
86
85
  export declare const LiteLLMBudgetGauges: FC<LiteLLMBudgetGaugesProps>;
@@ -1,5 +1,10 @@
1
1
  import { FC } from 'react';
2
2
  import { TeamInfo, ModelInfo, LiteLlmConfig, CreateTeamRequest, UpdateTeamRequest, VectorStoreInfo, McpServerInfo } from '../types';
3
+ /** A catalog User entity flattened into what the member picker needs. */
4
+ export interface InitialMember {
5
+ userEntityRef: string;
6
+ maxBudgetInTeam?: number;
7
+ }
3
8
  interface ManageTeamDialogProps {
4
9
  open: boolean;
5
10
  onClose: () => void;
@@ -7,7 +12,11 @@ interface ManageTeamDialogProps {
7
12
  team?: TeamInfo;
8
13
  allModels: ModelInfo[];
9
14
  config?: LiteLlmConfig;
10
- onSubmit: (payload: CreateTeamRequest | UpdateTeamRequest) => Promise<void>;
15
+ /**
16
+ * Saves the team. In create mode, `initialMembers` lists the members picked
17
+ * in the dialog; the parent adds them once the team exists.
18
+ */
19
+ onSubmit: (payload: CreateTeamRequest | UpdateTeamRequest, initialMembers?: InitialMember[]) => Promise<void>;
11
20
  /** When true, the Members section (edit mode only) exposes add/remove controls. */
12
21
  canManageMembers?: boolean;
13
22
  /** Called to add a member; the parent is expected to refresh `team` on success. */
@@ -1,5 +1,4 @@
1
1
  import { VirtualKey, ModelInfo, GenerateKeyRequest, UpdateKeyRequest } from '../types';
2
- export declare const generateDefaultAlias: (username?: string) => string;
3
2
  export declare const createForm: (username?: string) => GenerateKeyRequest;
4
3
  export declare const editForm: (k: VirtualKey) => UpdateKeyRequest;
5
4
  export declare function isModelAllowedByTeam(model: ModelInfo, teamModels?: string[]): boolean;
@@ -2,11 +2,6 @@
2
2
  * Pure helper: determine if the Clipboard API is available.
3
3
  */
4
4
  export declare function isClipboardApiAvailable(): boolean;
5
- /**
6
- * Pure helper: fallback copy via textarea and document.execCommand.
7
- * Returns true if successful, false otherwise.
8
- */
9
- export declare function fallbackCopyToClipboard(text: string): boolean;
10
5
  /**
11
6
  * Pure helper: create a timer for the copied state.
12
7
  * Returns the timer ID so the caller can manage cleanup.