@acarmisc/backstage-plugin-litellm-backend 0.1.2 → 0.1.7

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
@@ -1,6 +1,101 @@
1
1
  export interface Config {
2
2
  litellm: {
3
+ /**
4
+ * Base URL of the LiteLLM proxy instance.
5
+ * @visibility backend
6
+ */
3
7
  baseUrl: string;
8
+
9
+ /**
10
+ * LiteLLM master key for admin operations. Never exposed to the frontend.
11
+ * @visibility secret
12
+ */
4
13
  masterKey: string;
14
+
15
+ /**
16
+ * Email domain appended to the Backstage user entity name to form the
17
+ * LiteLLM user_id. When set, a user named "john.doe" maps to
18
+ * "john.doe@<userIdDomain>" in LiteLLM. Omit to use the bare entity name.
19
+ * @visibility backend
20
+ */
21
+ userIdDomain?: string;
22
+
23
+ provisioning?: {
24
+ /**
25
+ * When true the backend automatically creates a LiteLLM user on first
26
+ * access if the Backstage user is not yet known to LiteLLM.
27
+ * Disabled by default — enable explicitly when you are ready.
28
+ * @default false
29
+ */
30
+ enabled?: boolean;
31
+
32
+ defaults?: {
33
+ /**
34
+ * Max lifetime spend in USD before the account is blocked.
35
+ * Set a conservative value; null means no hard cap.
36
+ * @default 10
37
+ */
38
+ maxBudget?: number;
39
+
40
+ /**
41
+ * Spend-reset period for maxBudget (e.g. "30d", "7d", "1h").
42
+ * After this period the spend counter resets.
43
+ * @default "30d"
44
+ */
45
+ budgetDuration?: string;
46
+
47
+ /**
48
+ * LiteLLM model IDs the new user is allowed to call.
49
+ * Empty array means all models configured in the proxy are allowed.
50
+ * @default []
51
+ */
52
+ models?: string[];
53
+
54
+ /**
55
+ * LiteLLM team IDs to add the new user to automatically.
56
+ * The user inherits team-level model and budget restrictions.
57
+ * @default []
58
+ */
59
+ teams?: string[];
60
+
61
+ /**
62
+ * Tokens per minute hard cap across all models.
63
+ * Omit for no limit (team or global limits still apply).
64
+ */
65
+ tpmLimit?: number;
66
+
67
+ /**
68
+ * Requests per minute hard cap across all models.
69
+ * Omit for no limit.
70
+ */
71
+ rpmLimit?: number;
72
+
73
+ /**
74
+ * Arbitrary key-value metadata stored on the LiteLLM user record.
75
+ * Useful for tracking source, cost centre, department, etc.
76
+ */
77
+ metadata?: Record<string, string>;
78
+ };
79
+
80
+ /**
81
+ * Role-based provisioning overrides. Evaluated in order — first match wins.
82
+ * When a Backstage user belongs to the listed group, these settings override
83
+ * the defaults above. Fields omitted here fall back to defaults.
84
+ */
85
+ roles?: Array<{
86
+ /**
87
+ * Backstage group entity ref, e.g. "group:default/ai-power-users".
88
+ * Matched against the user's memberOf relations in the catalog.
89
+ */
90
+ group: string;
91
+ maxBudget?: number;
92
+ budgetDuration?: string;
93
+ models?: string[];
94
+ teams?: string[];
95
+ tpmLimit?: number;
96
+ rpmLimit?: number;
97
+ metadata?: Record<string, string>;
98
+ }>;
99
+ };
5
100
  };
6
- }
101
+ }
package/dist/client.d.ts CHANGED
@@ -1,11 +1,16 @@
1
- import { LiteLLMConfig, UserInfo, VirtualKey, ModelInfo, UsageMetrics, TeamInfo, GenerateKeyRequest, GenerateKeyResponse, DeleteKeyRequest } from './types';
1
+ import { LiteLLMConfig, UserInfo, VirtualKey, ModelInfo, UsageMetrics, TeamInfo, GenerateKeyRequest, GenerateKeyResponse, DeleteKeyRequest, CreateUserRequest, CreateUserResponse } from './types';
2
2
  export declare class LiteLLMClient {
3
3
  private baseUrl;
4
4
  private masterKey;
5
5
  private timeout;
6
6
  constructor(config: LiteLLMConfig, timeout?: number);
7
7
  private request;
8
- getUserInfo(userId?: string): Promise<UserInfo>;
8
+ /**
9
+ * Returns null when the user is not found in LiteLLM (404).
10
+ * Throws on all other errors so callers know something went wrong.
11
+ */
12
+ getUserInfo(userId?: string): Promise<UserInfo | null>;
13
+ createUser(payload: CreateUserRequest): Promise<CreateUserResponse>;
9
14
  listKeys(userId?: string): Promise<VirtualKey[]>;
10
15
  generateKey(request: GenerateKeyRequest): Promise<GenerateKeyResponse>;
11
16
  deleteKeys(request: DeleteKeyRequest): Promise<{
package/dist/client.js CHANGED
@@ -23,7 +23,9 @@ class LiteLLMClient {
23
23
  });
24
24
  if (!response.ok) {
25
25
  const errorBody = await response.text();
26
- throw new Error(`LiteLLM API error: ${response.status} ${response.statusText} - ${errorBody}`);
26
+ const err = new Error(`LiteLLM API error: ${response.status} ${response.statusText} - ${errorBody}`);
27
+ err.status = response.status;
28
+ throw err;
27
29
  }
28
30
  return response.json();
29
31
  }
@@ -31,9 +33,26 @@ class LiteLLMClient {
31
33
  clearTimeout(timeoutId);
32
34
  }
33
35
  }
36
+ /**
37
+ * Returns null when the user is not found in LiteLLM (404).
38
+ * Throws on all other errors so callers know something went wrong.
39
+ */
34
40
  async getUserInfo(userId) {
35
41
  const query = userId ? `?user_id=${encodeURIComponent(userId)}` : '';
36
- return this.request(`/user/info${query}`);
42
+ try {
43
+ return await this.request(`/user/info${query}`);
44
+ }
45
+ catch (err) {
46
+ if (err.status === 404)
47
+ return null;
48
+ throw err;
49
+ }
50
+ }
51
+ async createUser(payload) {
52
+ return this.request('/user/new', {
53
+ method: 'POST',
54
+ body: JSON.stringify(payload),
55
+ });
37
56
  }
38
57
  async listKeys(userId) {
39
58
  const query = userId ? `?user_id=${encodeURIComponent(userId)}` : '';