@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 +96 -1
- package/dist/client.d.ts +7 -2
- package/dist/client.js +21 -2
- package/dist/index.cjs.js +5725 -27
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.esm.js +81 -8
- package/dist/index.esm.js.map +2 -2
- package/dist/router.js +85 -15
- package/dist/types.cjs.js.map +1 -1
- package/dist/types.d.ts +27 -0
- package/package.json +3 -1
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)}` : '';
|