@acarmisc/backstage-plugin-litellm-backend 0.19.0 → 0.20.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/config.d.ts CHANGED
@@ -171,6 +171,16 @@ export interface Config {
171
171
  */
172
172
  allowedDurations?: string[];
173
173
 
174
+ /**
175
+ * Allowed `budget_duration` values for new keys (how often a key's
176
+ * spend resets, e.g. "30d" or "1mo"). Requests with a value not in this
177
+ * list are rejected with a 400 error. An empty array allows any value
178
+ * matching /^\d+(s|m|h|d|mo)$/. Omitting the field keeps today's
179
+ * behaviour: the key's budget never resets.
180
+ * @default ["1d", "7d", "30d", "1mo"]
181
+ */
182
+ allowedBudgetDurations?: string[];
183
+
174
184
  /**
175
185
  * When true, key owners can reset their key's spend counter via the
176
186
  * "Reset Spend" button in the frontend, subject to the
@@ -397,6 +407,37 @@ export interface Config {
397
407
  hideTeamBudgetForManagers?: boolean;
398
408
  };
399
409
 
410
+ /**
411
+ * Team usage views beyond the team totals shown to every member.
412
+ */
413
+ teamUsage?: {
414
+ /**
415
+ * Per-member usage breakdown (GET /teams/:teamId/usage/members and the
416
+ * "Usage by member" table on the Teams tab). Per-person spend is
417
+ * sensitive, so the breakdown is off by default and, when on, only
418
+ * reaches:
419
+ * - managers of the team (members of its metadata.owning_group, with
420
+ * team management enabled);
421
+ * - members of the team holding one of `viewerRoles` in it;
422
+ * - members of the team granted `litellm.team.usage.read` (only
423
+ * consulted when permission.enabled is true).
424
+ */
425
+ memberBreakdown?: {
426
+ /**
427
+ * When false, the route returns 404 and the UI hides the table.
428
+ * @default false
429
+ */
430
+ enabled?: boolean;
431
+
432
+ /**
433
+ * LiteLLM team roles (e.g. ["admin"]) whose holders may view their
434
+ * own team's breakdown.
435
+ * @default []
436
+ */
437
+ viewerRoles?: string[];
438
+ };
439
+ };
440
+
400
441
  bridge?: {
401
442
  /**
402
443
  * When true, mount the /bridge/keys, /bridge/keys (POST), /bridge/models
package/dist/client.d.ts CHANGED
@@ -60,6 +60,11 @@ export declare class LiteLLMClient {
60
60
  * `expires` instead of `expires_at`).
61
61
  */
62
62
  listKeys(userId?: string): Promise<VirtualKey[]>;
63
+ /**
64
+ * Lists every key bound to a team (any owner), following `/key/list`
65
+ * pagination. Stops after 50 pages of 100 keys.
66
+ */
67
+ listTeamKeys(teamId: string): Promise<VirtualKey[]>;
63
68
  private toVirtualKey;
64
69
  /**
65
70
  * Creates a new virtual key on the LiteLLM proxy.
package/dist/client.js CHANGED
@@ -198,6 +198,27 @@ class LiteLLMClient {
198
198
  throw err;
199
199
  }
200
200
  }
201
+ /**
202
+ * Lists every key bound to a team (any owner), following `/key/list`
203
+ * pagination. Stops after 50 pages of 100 keys.
204
+ */
205
+ async listTeamKeys(teamId) {
206
+ const keys = [];
207
+ for (let page = 1; page <= 50; page++) {
208
+ const params = new URLSearchParams({
209
+ team_id: teamId,
210
+ return_full_object: 'true',
211
+ page: String(page),
212
+ size: '100',
213
+ });
214
+ const response = await this.request(`/key/list?${params.toString()}`);
215
+ const rawKeys = (response.keys ?? []).filter((k) => typeof k === 'object' && k !== null);
216
+ keys.push(...rawKeys.map(this.toVirtualKey));
217
+ if (rawKeys.length === 0 || page >= (response.total_pages ?? 1))
218
+ break;
219
+ }
220
+ return keys;
221
+ }
201
222
  toVirtualKey(k) {
202
223
  return {
203
224
  key: k.key_name ?? k.token,