@happyvertical/ai 0.79.0 → 0.80.1

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.
Files changed (63) hide show
  1. package/AGENT.md +1 -1
  2. package/dist/chunks/anthropic-DA8sdt12.js +438 -0
  3. package/dist/chunks/anthropic-DA8sdt12.js.map +1 -0
  4. package/dist/chunks/bedrock-DDiYFUw0.js +699 -0
  5. package/dist/chunks/bedrock-DDiYFUw0.js.map +1 -0
  6. package/dist/chunks/bifrost-fM9FpW_w.js +198 -0
  7. package/dist/chunks/bifrost-fM9FpW_w.js.map +1 -0
  8. package/dist/chunks/claude-cli-CnJh5KQT.js +498 -0
  9. package/dist/chunks/claude-cli-CnJh5KQT.js.map +1 -0
  10. package/dist/chunks/gateway-admin-CiKvHst7.js +283 -0
  11. package/dist/chunks/gateway-admin-CiKvHst7.js.map +1 -0
  12. package/dist/chunks/gemini-Bu7Fke7c.js +593 -0
  13. package/dist/chunks/gemini-Bu7Fke7c.js.map +1 -0
  14. package/dist/chunks/huggingface-B07_6wHW.js +295 -0
  15. package/dist/chunks/huggingface-B07_6wHW.js.map +1 -0
  16. package/dist/chunks/litellm-D_Oo9OQ_.js +185 -0
  17. package/dist/chunks/litellm-D_Oo9OQ_.js.map +1 -0
  18. package/dist/chunks/ollama-D4ksOTO8.js +626 -0
  19. package/dist/chunks/ollama-D4ksOTO8.js.map +1 -0
  20. package/dist/chunks/openai--F38QHiJ.js +691 -0
  21. package/dist/chunks/openai--F38QHiJ.js.map +1 -0
  22. package/dist/chunks/qwen-tts-DRRbOrhA.js +333 -0
  23. package/dist/chunks/qwen-tts-DRRbOrhA.js.map +1 -0
  24. package/dist/chunks/rate-limit-BwyPGXFW.js +199 -0
  25. package/dist/chunks/rate-limit-BwyPGXFW.js.map +1 -0
  26. package/dist/chunks/safety-CEnoJS6X.js +260 -0
  27. package/dist/chunks/safety-CEnoJS6X.js.map +1 -0
  28. package/dist/chunks/types-FHs-KbGL.js +117 -0
  29. package/dist/chunks/types-FHs-KbGL.js.map +1 -0
  30. package/dist/chunks/usage-C1Y1Nlg4.js +35 -0
  31. package/dist/chunks/usage-C1Y1Nlg4.js.map +1 -0
  32. package/dist/cli/claude-context.js +17 -17
  33. package/dist/cli/claude-context.js.map +1 -1
  34. package/dist/index.js +717 -23
  35. package/dist/index.js.map +1 -1
  36. package/metadata.json +1 -1
  37. package/package.json +5 -5
  38. package/dist/chunks/anthropic-2z-82zgr.js +0 -530
  39. package/dist/chunks/anthropic-2z-82zgr.js.map +0 -1
  40. package/dist/chunks/bedrock-Dc2eVPUD.js +0 -920
  41. package/dist/chunks/bedrock-Dc2eVPUD.js.map +0 -1
  42. package/dist/chunks/bifrost-CEnCsciy.js +0 -258
  43. package/dist/chunks/bifrost-CEnCsciy.js.map +0 -1
  44. package/dist/chunks/claude-cli-X1ONjE8K.js +0 -603
  45. package/dist/chunks/claude-cli-X1ONjE8K.js.map +0 -1
  46. package/dist/chunks/gateway-admin-BUhBzXZb.js +0 -359
  47. package/dist/chunks/gateway-admin-BUhBzXZb.js.map +0 -1
  48. package/dist/chunks/gemini-CS56gY0D.js +0 -768
  49. package/dist/chunks/gemini-CS56gY0D.js.map +0 -1
  50. package/dist/chunks/huggingface-wQSfO5xA.js +0 -411
  51. package/dist/chunks/huggingface-wQSfO5xA.js.map +0 -1
  52. package/dist/chunks/index-DCXO0nZA.js +0 -1293
  53. package/dist/chunks/index-DCXO0nZA.js.map +0 -1
  54. package/dist/chunks/litellm-BMFTYbWc.js +0 -245
  55. package/dist/chunks/litellm-BMFTYbWc.js.map +0 -1
  56. package/dist/chunks/ollama-DsGDrA-c.js +0 -962
  57. package/dist/chunks/ollama-DsGDrA-c.js.map +0 -1
  58. package/dist/chunks/openai-CJEo69jb.js +0 -882
  59. package/dist/chunks/openai-CJEo69jb.js.map +0 -1
  60. package/dist/chunks/qwen-tts-BLYZ6d9s.js +0 -365
  61. package/dist/chunks/qwen-tts-BLYZ6d9s.js.map +0 -1
  62. package/dist/chunks/usage-DMWiJ2oB.js +0 -21
  63. package/dist/chunks/usage-DMWiJ2oB.js.map +0 -1
@@ -0,0 +1,283 @@
1
+ import { t as AIError } from "./types-FHs-KbGL.js";
2
+ //#region src/shared/providers/gateway-admin.ts
3
+ function stripTrailingSlash(value) {
4
+ return value.endsWith("/") ? value.slice(0, -1) : value;
5
+ }
6
+ function normalizeGatewayBaseUrl(baseUrl) {
7
+ return stripTrailingSlash(baseUrl.trim());
8
+ }
9
+ /**
10
+ * Derive the gateway root URL for admin APIs from an OpenAI-compatible base URL.
11
+ *
12
+ * Strips known inference path suffixes iteratively so that a baseUrl such as
13
+ * `http://host/openai/v1` collapses to the gateway root rather than to the
14
+ * partial `http://host/openai`.
15
+ */
16
+ function deriveGatewayAdminBaseUrl(baseUrl) {
17
+ let normalized = normalizeGatewayBaseUrl(baseUrl);
18
+ const suffixes = [
19
+ "/pydanticai/v1",
20
+ "/openai",
21
+ "/v1"
22
+ ];
23
+ let stripped = true;
24
+ while (stripped) {
25
+ stripped = false;
26
+ for (const suffix of suffixes) if (normalized.endsWith(suffix)) {
27
+ normalized = normalized.slice(0, -suffix.length);
28
+ stripped = true;
29
+ break;
30
+ }
31
+ }
32
+ return normalized || normalizeGatewayBaseUrl(baseUrl);
33
+ }
34
+ function resolveGatewayAdminBaseUrl(baseUrl, adminBaseUrl, provider) {
35
+ const configuredBaseUrl = adminBaseUrl || baseUrl;
36
+ if (!configuredBaseUrl?.trim()) throw new AIError(`${provider} baseUrl is required for admin operations`, "ADMIN_BASE_URL_REQUIRED", provider);
37
+ return adminBaseUrl ? normalizeGatewayBaseUrl(adminBaseUrl) : deriveGatewayAdminBaseUrl(configuredBaseUrl);
38
+ }
39
+ function slugifyProjectId(name, tenantId) {
40
+ return [tenantId, name].filter(Boolean).join("-").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "ai-project";
41
+ }
42
+ function toJsonRecord(value) {
43
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
44
+ }
45
+ function stringValue(value) {
46
+ return typeof value === "string" && value.length > 0 ? value : void 0;
47
+ }
48
+ function encodeBasicCredentials(username, password) {
49
+ const value = `${username}:${password}`;
50
+ if (typeof btoa === "function") return btoa(value);
51
+ return Buffer.from(value, "utf8").toString("base64");
52
+ }
53
+ function removeUndefinedValues(value) {
54
+ for (const key of Object.keys(value)) if (value[key] === void 0) delete value[key];
55
+ return value;
56
+ }
57
+ function createMetadata(options, tenantField = "tenant_id") {
58
+ const metadata = { ...options.metadata };
59
+ if (options.tenantId) metadata[tenantField] = options.tenantId;
60
+ if (options.description) metadata.description = options.description;
61
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
62
+ }
63
+ function responseMessage(body, fallback) {
64
+ const record = toJsonRecord(body);
65
+ return stringValue(toJsonRecord(record.error).message) || stringValue(record.message) || stringValue(record.detail) || fallback;
66
+ }
67
+ var GatewayAdminTransport = class {
68
+ baseUrl;
69
+ provider;
70
+ apiKey;
71
+ username;
72
+ password;
73
+ headers;
74
+ timeout;
75
+ constructor(options) {
76
+ this.provider = options.provider;
77
+ this.baseUrl = normalizeGatewayBaseUrl(options.baseUrl);
78
+ this.apiKey = options.apiKey;
79
+ this.username = options.username;
80
+ this.password = options.password;
81
+ this.headers = options.headers;
82
+ this.timeout = options.timeout;
83
+ }
84
+ async request(method, path, body, query) {
85
+ const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`);
86
+ if (query) {
87
+ for (const [key, value] of Object.entries(query)) if (value !== void 0) url.searchParams.set(key, value);
88
+ }
89
+ const controller = typeof AbortController === "undefined" ? void 0 : new AbortController();
90
+ const timeoutHandle = controller && this.timeout ? setTimeout(() => controller.abort(), this.timeout) : void 0;
91
+ try {
92
+ const response = await fetch(url, {
93
+ method,
94
+ headers: {
95
+ Accept: "application/json",
96
+ ...body !== void 0 ? { "Content-Type": "application/json" } : {},
97
+ ...this.headers,
98
+ ...this.createAuthHeaders()
99
+ },
100
+ body: body === void 0 ? void 0 : JSON.stringify(body),
101
+ signal: controller?.signal
102
+ });
103
+ const text = await response.text();
104
+ const parsed = text ? this.parseJson(text) : void 0;
105
+ if (!response.ok) throw this.mapResponseError(response, parsed);
106
+ return parsed;
107
+ } catch (error) {
108
+ if (error instanceof AIError) throw error;
109
+ throw new AIError(`${this.provider} admin request failed: ${error instanceof Error ? error.message : String(error)}`, "ADMIN_REQUEST_FAILED", this.provider);
110
+ } finally {
111
+ if (timeoutHandle) clearTimeout(timeoutHandle);
112
+ }
113
+ }
114
+ createAuthHeaders() {
115
+ if (this.username && this.password) return { Authorization: `Basic ${encodeBasicCredentials(this.username, this.password)}` };
116
+ return this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {};
117
+ }
118
+ parseJson(text) {
119
+ try {
120
+ return JSON.parse(text);
121
+ } catch (_error) {
122
+ return { message: text };
123
+ }
124
+ }
125
+ mapResponseError(response, body) {
126
+ const message = responseMessage(body, `${this.provider} admin request failed with ${response.status}`);
127
+ if (response.status === 401 || response.status === 403) return new AIError(message, "AUTH_ERROR", this.provider);
128
+ if (response.status === 429) return new AIError(message, "RATE_LIMIT", this.provider, void 0, true);
129
+ return new AIError(message, `ADMIN_HTTP_${response.status}`, this.provider, void 0, response.status >= 500);
130
+ }
131
+ };
132
+ function mapBifrostBudget(budget) {
133
+ if (!budget) return void 0;
134
+ return removeUndefinedValues({
135
+ max_limit: budget.maxLimit,
136
+ reset_duration: budget.resetDuration,
137
+ calendar_aligned: budget.calendarAligned
138
+ });
139
+ }
140
+ function mapBifrostRateLimit(rateLimit) {
141
+ if (!rateLimit) return void 0;
142
+ return removeUndefinedValues({
143
+ token_max_limit: rateLimit.tokenMaxLimit ?? rateLimit.tpmLimit,
144
+ token_reset_duration: rateLimit.tokenResetDuration,
145
+ request_max_limit: rateLimit.requestMaxLimit ?? rateLimit.rpmLimit,
146
+ request_reset_duration: rateLimit.requestResetDuration
147
+ });
148
+ }
149
+ function mapBifrostProviderConfigs(configs) {
150
+ if (!configs) return void 0;
151
+ return configs.map((config) => removeUndefinedValues({
152
+ provider: config.provider,
153
+ weight: config.weight,
154
+ allowed_models: config.allowedModels,
155
+ key_ids: config.keyIds
156
+ }));
157
+ }
158
+ function mapLiteLLMBudget(budget) {
159
+ return removeUndefinedValues({
160
+ max_budget: budget?.maxLimit,
161
+ budget_duration: budget?.resetDuration
162
+ });
163
+ }
164
+ function mapLiteLLMRateLimit(rateLimit) {
165
+ return removeUndefinedValues({
166
+ tpm_limit: rateLimit?.tpmLimit ?? rateLimit?.tokenMaxLimit,
167
+ rpm_limit: rateLimit?.rpmLimit ?? rateLimit?.requestMaxLimit
168
+ });
169
+ }
170
+ var BifrostAdmin = class {
171
+ transport;
172
+ constructor(options) {
173
+ this.transport = new GatewayAdminTransport(options);
174
+ }
175
+ async createProject(options) {
176
+ const body = removeUndefinedValues({
177
+ name: options.name,
178
+ customer_id: options.tenantId,
179
+ budget: mapBifrostBudget(options.budget),
180
+ ...options.raw
181
+ });
182
+ const response = await this.transport.request("POST", "/api/governance/teams", body);
183
+ const team = toJsonRecord(response.team ?? response);
184
+ const id = stringValue(team.id) || stringValue(team.team_id);
185
+ if (!id) throw new AIError("Bifrost did not return a project id", "ADMIN_INVALID_RESPONSE", "bifrost");
186
+ return {
187
+ id,
188
+ name: stringValue(team.name) || stringValue(team.team_alias) || options.name,
189
+ tenantId: stringValue(team.customer_id) || options.tenantId,
190
+ budgetId: stringValue(team.budget_id),
191
+ provider: "bifrost",
192
+ raw: response
193
+ };
194
+ }
195
+ async createVirtualKey(options) {
196
+ const body = removeUndefinedValues({
197
+ name: options.name,
198
+ description: options.description,
199
+ provider_configs: mapBifrostProviderConfigs(options.providerConfigs),
200
+ team_id: options.projectId,
201
+ customer_id: options.projectId ? void 0 : options.tenantId,
202
+ budget: mapBifrostBudget(options.budget),
203
+ rate_limit: mapBifrostRateLimit(options.rateLimit),
204
+ key_ids: options.keyIds,
205
+ is_active: options.isActive ?? true,
206
+ ...options.raw
207
+ });
208
+ const response = await this.transport.request("POST", "/api/governance/virtual-keys", body);
209
+ const virtualKey = toJsonRecord(response.virtual_key ?? response.virtualKey ?? response);
210
+ return {
211
+ id: stringValue(virtualKey.id) || stringValue(virtualKey.key_id),
212
+ name: stringValue(virtualKey.name) || options.name,
213
+ key: stringValue(virtualKey.value) || stringValue(virtualKey.key),
214
+ maskedKey: stringValue(virtualKey.key_name) || stringValue(virtualKey.masked_key),
215
+ projectId: stringValue(virtualKey.team_id) || options.projectId,
216
+ tenantId: stringValue(virtualKey.customer_id) || options.tenantId,
217
+ expiresAt: stringValue(virtualKey.expires) || stringValue(virtualKey.expires_at),
218
+ provider: "bifrost",
219
+ raw: response
220
+ };
221
+ }
222
+ };
223
+ var LiteLLMAdmin = class {
224
+ transport;
225
+ constructor(options) {
226
+ this.transport = new GatewayAdminTransport(options);
227
+ }
228
+ async createProject(options) {
229
+ const projectId = options.id || slugifyProjectId(options.name, options.tenantId);
230
+ const body = removeUndefinedValues({
231
+ team_id: projectId,
232
+ team_alias: options.name,
233
+ models: options.models,
234
+ ...mapLiteLLMBudget(options.budget),
235
+ ...mapLiteLLMRateLimit(options.rateLimit),
236
+ metadata: createMetadata(options),
237
+ blocked: options.isBlocked,
238
+ ...options.raw
239
+ });
240
+ const response = await this.transport.request("POST", "/team/new", body);
241
+ const team = toJsonRecord(response.team ?? response);
242
+ return {
243
+ id: stringValue(team.team_id) || projectId,
244
+ name: stringValue(team.team_alias) || stringValue(team.name) || options.name,
245
+ tenantId: options.tenantId,
246
+ provider: "litellm",
247
+ raw: response
248
+ };
249
+ }
250
+ async createVirtualKey(options) {
251
+ const body = removeUndefinedValues({
252
+ key_alias: options.name,
253
+ team_id: options.projectId,
254
+ user_id: options.userId,
255
+ models: options.models,
256
+ duration: options.duration,
257
+ ...mapLiteLLMBudget(options.budget),
258
+ ...mapLiteLLMRateLimit(options.rateLimit),
259
+ metadata: createMetadata(options),
260
+ aliases: options.aliases,
261
+ config: options.config,
262
+ permissions: options.permissions,
263
+ blocked: options.isActive === void 0 ? void 0 : !options.isActive,
264
+ ...options.raw
265
+ });
266
+ const response = await this.transport.request("POST", "/key/generate", body);
267
+ return {
268
+ id: stringValue(response.token_id) || stringValue(response.key_id),
269
+ name: stringValue(response.key_alias) || stringValue(response.key_name) || options.name,
270
+ key: stringValue(response.key),
271
+ maskedKey: stringValue(response.key_name),
272
+ projectId: stringValue(response.team_id) || options.projectId,
273
+ tenantId: options.tenantId,
274
+ expiresAt: stringValue(response.expires),
275
+ provider: "litellm",
276
+ raw: response
277
+ };
278
+ }
279
+ };
280
+ //#endregion
281
+ export { resolveGatewayAdminBaseUrl as i, LiteLLMAdmin as n, normalizeGatewayBaseUrl as r, BifrostAdmin as t };
282
+
283
+ //# sourceMappingURL=gateway-admin-CiKvHst7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-admin-CiKvHst7.js","names":[],"sources":["../../src/shared/providers/gateway-admin.ts"],"sourcesContent":["import type {\n AIAdminBudget,\n AIAdminInterface,\n AIAdminProject,\n AIAdminProviderConfig,\n AIAdminRateLimit,\n AIVirtualKey,\n CreateAIProjectOptions,\n CreateAIVirtualKeyOptions,\n} from '../types';\nimport { AIError } from '../types';\n\ninterface GatewayAdminTransportOptions {\n provider: string;\n baseUrl: string;\n apiKey?: string;\n username?: string;\n password?: string;\n headers?: Record<string, string>;\n timeout?: number;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nfunction stripTrailingSlash(value: string): string {\n return value.endsWith('/') ? value.slice(0, -1) : value;\n}\n\nexport function normalizeGatewayBaseUrl(baseUrl: string): string {\n return stripTrailingSlash(baseUrl.trim());\n}\n\n/**\n * Derive the gateway root URL for admin APIs from an OpenAI-compatible base URL.\n *\n * Strips known inference path suffixes iteratively so that a baseUrl such as\n * `http://host/openai/v1` collapses to the gateway root rather than to the\n * partial `http://host/openai`.\n */\nexport function deriveGatewayAdminBaseUrl(baseUrl: string): string {\n let normalized = normalizeGatewayBaseUrl(baseUrl);\n const suffixes = ['/pydanticai/v1', '/openai', '/v1'];\n let stripped = true;\n\n while (stripped) {\n stripped = false;\n for (const suffix of suffixes) {\n if (normalized.endsWith(suffix)) {\n normalized = normalized.slice(0, -suffix.length);\n stripped = true;\n break;\n }\n }\n }\n\n return normalized || normalizeGatewayBaseUrl(baseUrl);\n}\n\nexport function resolveGatewayAdminBaseUrl(\n baseUrl: string | undefined,\n adminBaseUrl: string | undefined,\n provider: string,\n): string {\n const configuredBaseUrl = adminBaseUrl || baseUrl;\n if (!configuredBaseUrl?.trim()) {\n throw new AIError(\n `${provider} baseUrl is required for admin operations`,\n 'ADMIN_BASE_URL_REQUIRED',\n provider,\n );\n }\n\n return adminBaseUrl\n ? normalizeGatewayBaseUrl(adminBaseUrl)\n : deriveGatewayAdminBaseUrl(configuredBaseUrl);\n}\n\nexport function slugifyProjectId(name: string, tenantId?: string): string {\n const value = [tenantId, name].filter(Boolean).join('-');\n const slug = value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n return slug || 'ai-project';\n}\n\nfunction toJsonRecord(value: unknown): JsonRecord {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as JsonRecord)\n : {};\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction encodeBasicCredentials(username: string, password: string): string {\n const value = `${username}:${password}`;\n\n if (typeof btoa === 'function') {\n return btoa(value);\n }\n\n return Buffer.from(value, 'utf8').toString('base64');\n}\n\nfunction removeUndefinedValues<T extends JsonRecord>(value: T): T {\n for (const key of Object.keys(value)) {\n if (value[key] === undefined) {\n delete value[key];\n }\n }\n\n return value;\n}\n\nfunction createMetadata(\n options: {\n tenantId?: string;\n description?: string;\n metadata?: Record<string, unknown>;\n },\n tenantField = 'tenant_id',\n): Record<string, unknown> | undefined {\n const metadata = {\n ...options.metadata,\n };\n\n if (options.tenantId) {\n metadata[tenantField] = options.tenantId;\n }\n\n if (options.description) {\n metadata.description = options.description;\n }\n\n return Object.keys(metadata).length > 0 ? metadata : undefined;\n}\n\nfunction responseMessage(body: unknown, fallback: string): string {\n const record = toJsonRecord(body);\n const error = toJsonRecord(record.error);\n\n return (\n stringValue(error.message) ||\n stringValue(record.message) ||\n stringValue(record.detail) ||\n fallback\n );\n}\n\nclass GatewayAdminTransport {\n private readonly baseUrl: string;\n private readonly provider: string;\n private readonly apiKey?: string;\n private readonly username?: string;\n private readonly password?: string;\n private readonly headers?: Record<string, string>;\n private readonly timeout?: number;\n\n constructor(options: GatewayAdminTransportOptions) {\n this.provider = options.provider;\n this.baseUrl = normalizeGatewayBaseUrl(options.baseUrl);\n this.apiKey = options.apiKey;\n this.username = options.username;\n this.password = options.password;\n this.headers = options.headers;\n this.timeout = options.timeout;\n }\n\n async request<T>(\n method: string,\n path: string,\n body?: unknown,\n query?: Record<string, string | undefined>,\n ): Promise<T> {\n const url = new URL(\n `${this.baseUrl}${path.startsWith('/') ? path : `/${path}`}`,\n );\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) {\n url.searchParams.set(key, value);\n }\n }\n }\n\n const controller =\n typeof AbortController === 'undefined'\n ? undefined\n : new AbortController();\n const timeoutHandle =\n controller && this.timeout\n ? setTimeout(() => controller.abort(), this.timeout)\n : undefined;\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n Accept: 'application/json',\n ...(body !== undefined ? { 'Content-Type': 'application/json' } : {}),\n ...this.headers,\n ...this.createAuthHeaders(),\n },\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller?.signal,\n });\n\n const text = await response.text();\n const parsed = text ? this.parseJson(text) : undefined;\n\n if (!response.ok) {\n throw this.mapResponseError(response, parsed);\n }\n\n return parsed as T;\n } catch (error) {\n if (error instanceof AIError) {\n throw error;\n }\n\n throw new AIError(\n `${this.provider} admin request failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n 'ADMIN_REQUEST_FAILED',\n this.provider,\n );\n } finally {\n if (timeoutHandle) {\n clearTimeout(timeoutHandle);\n }\n }\n }\n\n private createAuthHeaders(): Record<string, string> {\n if (this.username && this.password) {\n return {\n Authorization: `Basic ${encodeBasicCredentials(\n this.username,\n this.password,\n )}`,\n };\n }\n\n return this.apiKey ? { Authorization: `Bearer ${this.apiKey}` } : {};\n }\n\n private parseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch (_error) {\n return { message: text };\n }\n }\n\n private mapResponseError(response: Response, body: unknown): AIError {\n const message = responseMessage(\n body,\n `${this.provider} admin request failed with ${response.status}`,\n );\n\n if (response.status === 401 || response.status === 403) {\n return new AIError(message, 'AUTH_ERROR', this.provider);\n }\n\n if (response.status === 429) {\n return new AIError(message, 'RATE_LIMIT', this.provider, undefined, true);\n }\n\n return new AIError(\n message,\n `ADMIN_HTTP_${response.status}`,\n this.provider,\n undefined,\n response.status >= 500,\n );\n }\n}\n\nfunction mapBifrostBudget(budget?: AIAdminBudget): JsonRecord | undefined {\n if (!budget) return undefined;\n\n return removeUndefinedValues({\n max_limit: budget.maxLimit,\n reset_duration: budget.resetDuration,\n calendar_aligned: budget.calendarAligned,\n });\n}\n\nfunction mapBifrostRateLimit(\n rateLimit?: AIAdminRateLimit,\n): JsonRecord | undefined {\n if (!rateLimit) return undefined;\n\n return removeUndefinedValues({\n token_max_limit: rateLimit.tokenMaxLimit ?? rateLimit.tpmLimit,\n token_reset_duration: rateLimit.tokenResetDuration,\n request_max_limit: rateLimit.requestMaxLimit ?? rateLimit.rpmLimit,\n request_reset_duration: rateLimit.requestResetDuration,\n });\n}\n\nfunction mapBifrostProviderConfigs(\n configs?: AIAdminProviderConfig[],\n): JsonRecord[] | undefined {\n if (!configs) return undefined;\n\n return configs.map((config) =>\n removeUndefinedValues({\n provider: config.provider,\n weight: config.weight,\n allowed_models: config.allowedModels,\n key_ids: config.keyIds,\n }),\n );\n}\n\nfunction mapLiteLLMBudget(\n budget?: AIAdminBudget,\n): Pick<JsonRecord, 'max_budget' | 'budget_duration'> {\n return removeUndefinedValues({\n max_budget: budget?.maxLimit,\n budget_duration: budget?.resetDuration,\n });\n}\n\nfunction mapLiteLLMRateLimit(\n rateLimit?: AIAdminRateLimit,\n): Pick<JsonRecord, 'tpm_limit' | 'rpm_limit'> {\n return removeUndefinedValues({\n tpm_limit: rateLimit?.tpmLimit ?? rateLimit?.tokenMaxLimit,\n rpm_limit: rateLimit?.rpmLimit ?? rateLimit?.requestMaxLimit,\n });\n}\n\nexport class BifrostAdmin implements AIAdminInterface {\n private readonly transport: GatewayAdminTransport;\n\n constructor(options: GatewayAdminTransportOptions) {\n this.transport = new GatewayAdminTransport(options);\n }\n\n async createProject(\n options: CreateAIProjectOptions,\n ): Promise<AIAdminProject> {\n const body = removeUndefinedValues({\n name: options.name,\n customer_id: options.tenantId,\n budget: mapBifrostBudget(options.budget),\n ...options.raw,\n });\n\n const response = await this.transport.request<JsonRecord>(\n 'POST',\n '/api/governance/teams',\n body,\n );\n const team = toJsonRecord(response.team ?? response);\n const id = stringValue(team.id) || stringValue(team.team_id);\n\n if (!id) {\n throw new AIError(\n 'Bifrost did not return a project id',\n 'ADMIN_INVALID_RESPONSE',\n 'bifrost',\n );\n }\n\n return {\n id,\n name:\n stringValue(team.name) || stringValue(team.team_alias) || options.name,\n tenantId: stringValue(team.customer_id) || options.tenantId,\n budgetId: stringValue(team.budget_id),\n provider: 'bifrost',\n raw: response,\n };\n }\n\n async createVirtualKey(\n options: CreateAIVirtualKeyOptions,\n ): Promise<AIVirtualKey> {\n const body = removeUndefinedValues({\n name: options.name,\n description: options.description,\n provider_configs: mapBifrostProviderConfigs(options.providerConfigs),\n team_id: options.projectId,\n customer_id: options.projectId ? undefined : options.tenantId,\n budget: mapBifrostBudget(options.budget),\n rate_limit: mapBifrostRateLimit(options.rateLimit),\n key_ids: options.keyIds,\n is_active: options.isActive ?? true,\n ...options.raw,\n });\n\n const response = await this.transport.request<JsonRecord>(\n 'POST',\n '/api/governance/virtual-keys',\n body,\n );\n const virtualKey = toJsonRecord(\n response.virtual_key ?? response.virtualKey ?? response,\n );\n\n return {\n id: stringValue(virtualKey.id) || stringValue(virtualKey.key_id),\n name: stringValue(virtualKey.name) || options.name,\n key: stringValue(virtualKey.value) || stringValue(virtualKey.key),\n maskedKey:\n stringValue(virtualKey.key_name) || stringValue(virtualKey.masked_key),\n projectId: stringValue(virtualKey.team_id) || options.projectId,\n tenantId: stringValue(virtualKey.customer_id) || options.tenantId,\n expiresAt:\n stringValue(virtualKey.expires) || stringValue(virtualKey.expires_at),\n provider: 'bifrost',\n raw: response,\n };\n }\n}\n\nexport class LiteLLMAdmin implements AIAdminInterface {\n private readonly transport: GatewayAdminTransport;\n\n constructor(options: GatewayAdminTransportOptions) {\n this.transport = new GatewayAdminTransport(options);\n }\n\n async createProject(\n options: CreateAIProjectOptions,\n ): Promise<AIAdminProject> {\n const projectId =\n options.id || slugifyProjectId(options.name, options.tenantId);\n const body = removeUndefinedValues({\n team_id: projectId,\n team_alias: options.name,\n models: options.models,\n ...mapLiteLLMBudget(options.budget),\n ...mapLiteLLMRateLimit(options.rateLimit),\n metadata: createMetadata(options),\n blocked: options.isBlocked,\n ...options.raw,\n });\n\n const response = await this.transport.request<JsonRecord>(\n 'POST',\n '/team/new',\n body,\n );\n const team = toJsonRecord(response.team ?? response);\n\n return {\n id: stringValue(team.team_id) || projectId,\n name:\n stringValue(team.team_alias) || stringValue(team.name) || options.name,\n tenantId: options.tenantId,\n provider: 'litellm',\n raw: response,\n };\n }\n\n async createVirtualKey(\n options: CreateAIVirtualKeyOptions,\n ): Promise<AIVirtualKey> {\n const body = removeUndefinedValues({\n key_alias: options.name,\n team_id: options.projectId,\n user_id: options.userId,\n models: options.models,\n duration: options.duration,\n ...mapLiteLLMBudget(options.budget),\n ...mapLiteLLMRateLimit(options.rateLimit),\n metadata: createMetadata(options),\n aliases: options.aliases,\n config: options.config,\n permissions: options.permissions,\n blocked: options.isActive === undefined ? undefined : !options.isActive,\n ...options.raw,\n });\n\n const response = await this.transport.request<JsonRecord>(\n 'POST',\n '/key/generate',\n body,\n );\n\n return {\n id: stringValue(response.token_id) || stringValue(response.key_id),\n name:\n stringValue(response.key_alias) ||\n stringValue(response.key_name) ||\n options.name,\n key: stringValue(response.key),\n maskedKey: stringValue(response.key_name),\n projectId: stringValue(response.team_id) || options.projectId,\n tenantId: options.tenantId,\n expiresAt: stringValue(response.expires),\n provider: 'litellm',\n raw: response,\n };\n }\n}\n"],"mappings":"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"}