@happyvertical/ai 0.80.0 → 0.80.2
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/dist/chunks/anthropic-DA8sdt12.js +438 -0
- package/dist/chunks/anthropic-DA8sdt12.js.map +1 -0
- package/dist/chunks/bedrock-DDiYFUw0.js +699 -0
- package/dist/chunks/bedrock-DDiYFUw0.js.map +1 -0
- package/dist/chunks/bifrost-fM9FpW_w.js +198 -0
- package/dist/chunks/bifrost-fM9FpW_w.js.map +1 -0
- package/dist/chunks/claude-cli-CnJh5KQT.js +498 -0
- package/dist/chunks/claude-cli-CnJh5KQT.js.map +1 -0
- package/dist/chunks/gateway-admin-CiKvHst7.js +283 -0
- package/dist/chunks/gateway-admin-CiKvHst7.js.map +1 -0
- package/dist/chunks/gemini-Bu7Fke7c.js +593 -0
- package/dist/chunks/gemini-Bu7Fke7c.js.map +1 -0
- package/dist/chunks/huggingface-B07_6wHW.js +295 -0
- package/dist/chunks/huggingface-B07_6wHW.js.map +1 -0
- package/dist/chunks/litellm-D_Oo9OQ_.js +185 -0
- package/dist/chunks/litellm-D_Oo9OQ_.js.map +1 -0
- package/dist/chunks/ollama-D4ksOTO8.js +626 -0
- package/dist/chunks/ollama-D4ksOTO8.js.map +1 -0
- package/dist/chunks/openai--F38QHiJ.js +691 -0
- package/dist/chunks/openai--F38QHiJ.js.map +1 -0
- package/dist/chunks/qwen-tts-DRRbOrhA.js +333 -0
- package/dist/chunks/qwen-tts-DRRbOrhA.js.map +1 -0
- package/dist/chunks/rate-limit-BwyPGXFW.js +199 -0
- package/dist/chunks/rate-limit-BwyPGXFW.js.map +1 -0
- package/dist/chunks/safety-CEnoJS6X.js +260 -0
- package/dist/chunks/safety-CEnoJS6X.js.map +1 -0
- package/dist/chunks/types-FHs-KbGL.js +117 -0
- package/dist/chunks/types-FHs-KbGL.js.map +1 -0
- package/dist/chunks/usage-C1Y1Nlg4.js +35 -0
- package/dist/chunks/usage-C1Y1Nlg4.js.map +1 -0
- package/dist/cli/claude-context.js +17 -17
- package/dist/cli/claude-context.js.map +1 -1
- package/dist/index.js +717 -23
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/chunks/anthropic-2z-82zgr.js +0 -530
- package/dist/chunks/anthropic-2z-82zgr.js.map +0 -1
- package/dist/chunks/bedrock-Dc2eVPUD.js +0 -920
- package/dist/chunks/bedrock-Dc2eVPUD.js.map +0 -1
- package/dist/chunks/bifrost-CEnCsciy.js +0 -258
- package/dist/chunks/bifrost-CEnCsciy.js.map +0 -1
- package/dist/chunks/claude-cli-X1ONjE8K.js +0 -603
- package/dist/chunks/claude-cli-X1ONjE8K.js.map +0 -1
- package/dist/chunks/gateway-admin-BUhBzXZb.js +0 -359
- package/dist/chunks/gateway-admin-BUhBzXZb.js.map +0 -1
- package/dist/chunks/gemini-CS56gY0D.js +0 -768
- package/dist/chunks/gemini-CS56gY0D.js.map +0 -1
- package/dist/chunks/huggingface-wQSfO5xA.js +0 -411
- package/dist/chunks/huggingface-wQSfO5xA.js.map +0 -1
- package/dist/chunks/index-DCXO0nZA.js +0 -1293
- package/dist/chunks/index-DCXO0nZA.js.map +0 -1
- package/dist/chunks/litellm-BMFTYbWc.js +0 -245
- package/dist/chunks/litellm-BMFTYbWc.js.map +0 -1
- package/dist/chunks/ollama-DsGDrA-c.js +0 -962
- package/dist/chunks/ollama-DsGDrA-c.js.map +0 -1
- package/dist/chunks/openai-CJEo69jb.js +0 -882
- package/dist/chunks/openai-CJEo69jb.js.map +0 -1
- package/dist/chunks/qwen-tts-BLYZ6d9s.js +0 -365
- package/dist/chunks/qwen-tts-BLYZ6d9s.js.map +0 -1
- package/dist/chunks/usage-DMWiJ2oB.js +0 -21
- package/dist/chunks/usage-DMWiJ2oB.js.map +0 -1
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { a as ContextLengthError, c as extractTextContent, o as ModelNotFoundError, r as AuthenticationError, s as RateLimitError, t as AIError } from "./types-FHs-KbGL.js";
|
|
2
|
+
import { a as normalizeBaseAIOptions, c as prepareRequestControls, o as normalizeChatOptions } from "./safety-CEnoJS6X.js";
|
|
3
|
+
import { t as emitUsage } from "./usage-C1Y1Nlg4.js";
|
|
4
|
+
//#region src/shared/providers/huggingface.ts
|
|
5
|
+
/**
|
|
6
|
+
* Hugging Face provider implementation
|
|
7
|
+
*/
|
|
8
|
+
var HuggingFaceProvider = class {
|
|
9
|
+
options;
|
|
10
|
+
baseUrl;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.options = normalizeBaseAIOptions({
|
|
13
|
+
defaultModel: "microsoft/DialoGPT-medium",
|
|
14
|
+
useCache: true,
|
|
15
|
+
waitForModel: true,
|
|
16
|
+
...options
|
|
17
|
+
});
|
|
18
|
+
this.baseUrl = this.options.endpoint || "https://api-inference.huggingface.co";
|
|
19
|
+
}
|
|
20
|
+
async chat(messages, options = {}) {
|
|
21
|
+
const startTime = Date.now();
|
|
22
|
+
let controls;
|
|
23
|
+
try {
|
|
24
|
+
const prompt = this.messagesToPrompt(messages);
|
|
25
|
+
const model = options.model || this.options.model || this.options.defaultModel;
|
|
26
|
+
options = normalizeChatOptions(this.options, options, "huggingface", model);
|
|
27
|
+
controls = prepareRequestControls(this.options, options);
|
|
28
|
+
const response = await this.makeRequest(`/models/${model}`, {
|
|
29
|
+
inputs: prompt,
|
|
30
|
+
parameters: {
|
|
31
|
+
max_new_tokens: options.maxTokens,
|
|
32
|
+
temperature: options.temperature ?? 1,
|
|
33
|
+
top_p: options.topP ?? 1,
|
|
34
|
+
do_sample: options.temperature && options.temperature > 0 || false,
|
|
35
|
+
stop_sequences: Array.isArray(options.stop) ? options.stop : options.stop ? [options.stop] : void 0
|
|
36
|
+
},
|
|
37
|
+
options: {
|
|
38
|
+
use_cache: this.options.useCache,
|
|
39
|
+
wait_for_model: this.options.waitForModel
|
|
40
|
+
}
|
|
41
|
+
}, controls.signal);
|
|
42
|
+
if (Array.isArray(response) && response[0]?.generated_text) {
|
|
43
|
+
const content = response[0].generated_text.replace(prompt, "").trim();
|
|
44
|
+
emitUsage(this.options, "huggingface", "chat", model, void 0, startTime, options.usageTags);
|
|
45
|
+
return {
|
|
46
|
+
content,
|
|
47
|
+
model,
|
|
48
|
+
finishReason: "stop"
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
throw new AIError("Invalid response format from Hugging Face", "INVALID_RESPONSE", "huggingface");
|
|
52
|
+
} catch (error) {
|
|
53
|
+
if (controls?.didTimeout()) throw new AIError(`AI request timed out after ${controls.timeout}ms`, "AI_TIMEOUT", "huggingface", options.model);
|
|
54
|
+
if (options.signal?.aborted) throw new AIError("AI request aborted by caller", "AI_ABORTED", "huggingface", options.model);
|
|
55
|
+
throw this.mapError(error);
|
|
56
|
+
} finally {
|
|
57
|
+
controls?.cleanup();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async complete(prompt, options = {}) {
|
|
61
|
+
return this.chat([{
|
|
62
|
+
role: "user",
|
|
63
|
+
content: prompt
|
|
64
|
+
}], {
|
|
65
|
+
model: options.model,
|
|
66
|
+
maxTokens: options.maxTokens,
|
|
67
|
+
temperature: options.temperature,
|
|
68
|
+
topP: options.topP,
|
|
69
|
+
n: options.n,
|
|
70
|
+
stop: options.stop,
|
|
71
|
+
stream: options.stream,
|
|
72
|
+
onProgress: options.onProgress,
|
|
73
|
+
signal: options.signal,
|
|
74
|
+
timeout: options.timeout,
|
|
75
|
+
reasoning: options.reasoning,
|
|
76
|
+
usageTags: options.usageTags
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Simple message interface for single-turn interactions with optional history
|
|
81
|
+
*
|
|
82
|
+
* @param text - The message text to send
|
|
83
|
+
* @param options - Configuration options including history, model, etc.
|
|
84
|
+
* @returns Promise resolving to the response content string
|
|
85
|
+
*/
|
|
86
|
+
async message(text, options = {}) {
|
|
87
|
+
const messages = [...options.history || [], {
|
|
88
|
+
role: options.role || "user",
|
|
89
|
+
content: text
|
|
90
|
+
}];
|
|
91
|
+
return (await this.chat(messages, {
|
|
92
|
+
model: options.model,
|
|
93
|
+
maxTokens: options.maxTokens,
|
|
94
|
+
temperature: options.temperature,
|
|
95
|
+
topP: options.topP,
|
|
96
|
+
stop: options.stop,
|
|
97
|
+
stream: options.stream,
|
|
98
|
+
frequencyPenalty: options.frequencyPenalty,
|
|
99
|
+
presencePenalty: options.presencePenalty,
|
|
100
|
+
responseFormat: options.responseFormat,
|
|
101
|
+
seed: options.seed,
|
|
102
|
+
tools: options.tools,
|
|
103
|
+
toolChoice: options.toolChoice,
|
|
104
|
+
onProgress: options.onProgress,
|
|
105
|
+
signal: options.signal,
|
|
106
|
+
timeout: options.timeout,
|
|
107
|
+
reasoning: options.reasoning,
|
|
108
|
+
usageTags: options.usageTags
|
|
109
|
+
})).content;
|
|
110
|
+
}
|
|
111
|
+
async embed(text, options = {}) {
|
|
112
|
+
const startTime = Date.now();
|
|
113
|
+
try {
|
|
114
|
+
const input = Array.isArray(text) ? text : [text];
|
|
115
|
+
const model = options.model || "sentence-transformers/all-MiniLM-L6-v2";
|
|
116
|
+
const response = await this.makeRequest(`/models/${model}`, {
|
|
117
|
+
inputs: input,
|
|
118
|
+
options: {
|
|
119
|
+
use_cache: this.options.useCache,
|
|
120
|
+
wait_for_model: this.options.waitForModel
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
let embeddings;
|
|
124
|
+
if (Array.isArray(response) && Array.isArray(response[0])) embeddings = Array.isArray(text) ? response : [response[0]];
|
|
125
|
+
else if (response && typeof response === "object" && response.embeddings) embeddings = response.embeddings;
|
|
126
|
+
else throw new AIError("Invalid embedding response format", "INVALID_RESPONSE", "huggingface");
|
|
127
|
+
emitUsage(this.options, "huggingface", "embed", model, void 0, startTime, options.usageTags);
|
|
128
|
+
return {
|
|
129
|
+
embeddings,
|
|
130
|
+
model
|
|
131
|
+
};
|
|
132
|
+
} catch (error) {
|
|
133
|
+
throw this.mapError(error);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async embedImage(_image, _options = {}) {
|
|
137
|
+
throw new AIError("Hugging Face image embeddings not implemented. Use OpenAI or Gemini.", "NOT_IMPLEMENTED", "huggingface");
|
|
138
|
+
}
|
|
139
|
+
async describeImage(_image, _prompt, _options = {}) {
|
|
140
|
+
throw new AIError("Image description is not implemented for Hugging Face. Use OpenAI or Gemini.", "NOT_IMPLEMENTED", "huggingface");
|
|
141
|
+
}
|
|
142
|
+
async generateImage(_prompt, _options = {}) {
|
|
143
|
+
throw new AIError("Image generation is not implemented for Hugging Face. Use OpenAI or Gemini.", "NOT_IMPLEMENTED", "huggingface");
|
|
144
|
+
}
|
|
145
|
+
async *stream(messages, options = {}) {
|
|
146
|
+
const startTime = Date.now();
|
|
147
|
+
const content = (await this.chat(messages, {
|
|
148
|
+
...options,
|
|
149
|
+
_skipUsage: true
|
|
150
|
+
})).content;
|
|
151
|
+
const chunkSize = 10;
|
|
152
|
+
for (let i = 0; i < content.length; i += chunkSize) {
|
|
153
|
+
if (options.signal?.aborted) throw new AIError("AI request aborted by caller", "AI_ABORTED", "huggingface", options.model);
|
|
154
|
+
const chunk = content.slice(i, i + chunkSize);
|
|
155
|
+
if (options.onProgress) options.onProgress(chunk);
|
|
156
|
+
yield chunk;
|
|
157
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
158
|
+
}
|
|
159
|
+
const model = options.model || this.options.defaultModel || "gpt2";
|
|
160
|
+
emitUsage(this.options, "huggingface", "stream", model, void 0, startTime, options.usageTags);
|
|
161
|
+
}
|
|
162
|
+
async countTokens(text) {
|
|
163
|
+
return Math.ceil(text.length / 4);
|
|
164
|
+
}
|
|
165
|
+
async getModels() {
|
|
166
|
+
return [
|
|
167
|
+
{
|
|
168
|
+
id: "microsoft/DialoGPT-medium",
|
|
169
|
+
name: "DialoGPT Medium",
|
|
170
|
+
description: "Conversational AI model by Microsoft",
|
|
171
|
+
contextLength: 1024,
|
|
172
|
+
capabilities: ["text", "chat"],
|
|
173
|
+
supportsFunctions: false,
|
|
174
|
+
supportsVision: false
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: "microsoft/DialoGPT-large",
|
|
178
|
+
name: "DialoGPT Large",
|
|
179
|
+
description: "Large conversational AI model by Microsoft",
|
|
180
|
+
contextLength: 1024,
|
|
181
|
+
capabilities: ["text", "chat"],
|
|
182
|
+
supportsFunctions: false,
|
|
183
|
+
supportsVision: false
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
id: "facebook/blenderbot-400M-distill",
|
|
187
|
+
name: "BlenderBot 400M",
|
|
188
|
+
description: "Conversational AI model by Meta",
|
|
189
|
+
contextLength: 512,
|
|
190
|
+
capabilities: ["text", "chat"],
|
|
191
|
+
supportsFunctions: false,
|
|
192
|
+
supportsVision: false
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
id: "gpt2",
|
|
196
|
+
name: "GPT-2",
|
|
197
|
+
description: "OpenAI GPT-2 model",
|
|
198
|
+
contextLength: 1024,
|
|
199
|
+
capabilities: ["text", "completion"],
|
|
200
|
+
supportsFunctions: false,
|
|
201
|
+
supportsVision: false
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: "sentence-transformers/all-MiniLM-L6-v2",
|
|
205
|
+
name: "All-MiniLM-L6-v2",
|
|
206
|
+
description: "Sentence embedding model",
|
|
207
|
+
contextLength: 512,
|
|
208
|
+
capabilities: ["embeddings"],
|
|
209
|
+
supportsFunctions: false,
|
|
210
|
+
supportsVision: false
|
|
211
|
+
}
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
async getCapabilities() {
|
|
215
|
+
return {
|
|
216
|
+
chat: true,
|
|
217
|
+
completion: true,
|
|
218
|
+
embeddings: true,
|
|
219
|
+
streaming: true,
|
|
220
|
+
functions: false,
|
|
221
|
+
vision: false,
|
|
222
|
+
fineTuning: true,
|
|
223
|
+
imageEmbeddings: false,
|
|
224
|
+
imageGeneration: false,
|
|
225
|
+
tts: false,
|
|
226
|
+
voiceCloning: false,
|
|
227
|
+
voiceDesign: false,
|
|
228
|
+
maxContextLength: 2048,
|
|
229
|
+
supportedOperations: [
|
|
230
|
+
"chat",
|
|
231
|
+
"completion",
|
|
232
|
+
"embedding",
|
|
233
|
+
"streaming"
|
|
234
|
+
]
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
async synthesizeSpeech(_text, _options) {
|
|
238
|
+
throw new AIError("TTS is not supported by HuggingFace provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "huggingface");
|
|
239
|
+
}
|
|
240
|
+
streamSpeech(_text, _options) {
|
|
241
|
+
const error = new AIError("TTS streaming is not supported by HuggingFace provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "huggingface");
|
|
242
|
+
return { [Symbol.asyncIterator]: () => ({ next: () => Promise.reject(error) }) };
|
|
243
|
+
}
|
|
244
|
+
async cloneVoice(_options) {
|
|
245
|
+
throw new AIError("Voice cloning is not supported by HuggingFace provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "huggingface");
|
|
246
|
+
}
|
|
247
|
+
async designVoice(_options) {
|
|
248
|
+
throw new AIError("Voice design is not supported by HuggingFace provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "huggingface");
|
|
249
|
+
}
|
|
250
|
+
async getVoices(_options) {
|
|
251
|
+
throw new AIError("Voice listing is not supported by HuggingFace provider. Use Qwen3-TTS provider.", "NOT_IMPLEMENTED", "huggingface");
|
|
252
|
+
}
|
|
253
|
+
messagesToPrompt(messages) {
|
|
254
|
+
return `${messages.map((message) => {
|
|
255
|
+
const textContent = extractTextContent(message.content);
|
|
256
|
+
switch (message.role) {
|
|
257
|
+
case "system": return `System: ${textContent}`;
|
|
258
|
+
case "user": return `Human: ${textContent}`;
|
|
259
|
+
case "assistant": return `Assistant: ${textContent}`;
|
|
260
|
+
default: return textContent;
|
|
261
|
+
}
|
|
262
|
+
}).join("\n")}\nAssistant:`;
|
|
263
|
+
}
|
|
264
|
+
async makeRequest(endpoint, data, signal) {
|
|
265
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
266
|
+
const response = await fetch(url, {
|
|
267
|
+
method: "POST",
|
|
268
|
+
headers: {
|
|
269
|
+
Authorization: `Bearer ${this.options.apiToken}`,
|
|
270
|
+
"Content-Type": "application/json",
|
|
271
|
+
...this.options.headers
|
|
272
|
+
},
|
|
273
|
+
body: JSON.stringify(data),
|
|
274
|
+
signal
|
|
275
|
+
});
|
|
276
|
+
if (!response.ok) {
|
|
277
|
+
const errorText = await response.text();
|
|
278
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
279
|
+
}
|
|
280
|
+
return response.json();
|
|
281
|
+
}
|
|
282
|
+
mapError(error) {
|
|
283
|
+
if (error instanceof AIError) return error;
|
|
284
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
285
|
+
if (message.includes("401") || message.includes("Unauthorized")) return new AuthenticationError("huggingface");
|
|
286
|
+
if (message.includes("429") || message.includes("rate limit")) return new RateLimitError("huggingface");
|
|
287
|
+
if (message.includes("404") || message.includes("not found")) return new ModelNotFoundError(message, "huggingface");
|
|
288
|
+
if (message.includes("413") || message.includes("too large")) return new ContextLengthError("huggingface");
|
|
289
|
+
return new AIError(message, "UNKNOWN_ERROR", "huggingface");
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
//#endregion
|
|
293
|
+
export { HuggingFaceProvider };
|
|
294
|
+
|
|
295
|
+
//# sourceMappingURL=huggingface-B07_6wHW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"huggingface-B07_6wHW.js","names":[],"sources":["../../src/shared/providers/huggingface.ts"],"sourcesContent":["/**\n * Hugging Face provider implementation\n */\n\nimport {\n normalizeBaseAIOptions,\n normalizeChatOptions,\n type PreparedRequestControls,\n prepareRequestControls,\n} from '../safety';\nimport type {\n AICapabilities,\n AIInterface,\n AIMessage,\n AIModel,\n AIResponse,\n ChatOptions,\n CompletionOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n HuggingFaceOptions,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n MessageOptions,\n TokenUsage,\n TTSOptions,\n TTSResponse,\n Voice,\n VoiceCloneOptions,\n VoiceDesignOptions,\n VoiceListOptions,\n} from '../types';\nimport {\n AIError,\n AuthenticationError,\n ContextLengthError,\n extractTextContent,\n ModelNotFoundError,\n RateLimitError,\n} from '../types';\nimport { emitUsage } from './usage';\n\nexport class HuggingFaceProvider implements AIInterface {\n private options: HuggingFaceOptions;\n private baseUrl: string;\n\n constructor(options: HuggingFaceOptions) {\n this.options = normalizeBaseAIOptions({\n defaultModel: 'microsoft/DialoGPT-medium',\n useCache: true,\n waitForModel: true,\n ...options,\n });\n\n this.baseUrl =\n this.options.endpoint || 'https://api-inference.huggingface.co';\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const startTime = Date.now();\n let controls: PreparedRequestControls | undefined;\n try {\n // Convert messages to a single prompt for text generation models\n const prompt = this.messagesToPrompt(messages);\n const model =\n options.model || this.options.model || this.options.defaultModel;\n options = normalizeChatOptions(\n this.options,\n options,\n 'huggingface',\n model,\n );\n controls = prepareRequestControls(this.options, options);\n\n const response = await this.makeRequest(\n `/models/${model}`,\n {\n inputs: prompt,\n parameters: {\n max_new_tokens: options.maxTokens,\n temperature: options.temperature ?? 1.0,\n top_p: options.topP ?? 1.0,\n do_sample:\n (options.temperature && options.temperature > 0) || false,\n stop_sequences: Array.isArray(options.stop)\n ? options.stop\n : options.stop\n ? [options.stop]\n : undefined,\n },\n options: {\n use_cache: this.options.useCache,\n wait_for_model: this.options.waitForModel,\n },\n },\n controls.signal,\n );\n\n if (Array.isArray(response) && response[0]?.generated_text) {\n const generatedText = response[0].generated_text;\n // Remove the input prompt from the response\n const content = generatedText.replace(prompt, '').trim();\n\n emitUsage(\n this.options,\n 'huggingface',\n 'chat',\n model!,\n undefined,\n startTime,\n options.usageTags,\n );\n\n return {\n content,\n model,\n finishReason: 'stop',\n };\n }\n\n throw new AIError(\n 'Invalid response format from Hugging Face',\n 'INVALID_RESPONSE',\n 'huggingface',\n );\n } catch (error) {\n if (controls?.didTimeout()) {\n throw new AIError(\n `AI request timed out after ${controls.timeout}ms`,\n 'AI_TIMEOUT',\n 'huggingface',\n options.model,\n );\n }\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'huggingface',\n options.model,\n );\n }\n throw this.mapError(error);\n } finally {\n controls?.cleanup();\n }\n }\n\n async complete(\n prompt: string,\n options: CompletionOptions = {},\n ): Promise<AIResponse> {\n return this.chat([{ role: 'user', content: prompt }], {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n n: options.n,\n stop: options.stop,\n stream: options.stream,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n });\n }\n\n /**\n * Simple message interface for single-turn interactions with optional history\n *\n * @param text - The message text to send\n * @param options - Configuration options including history, model, etc.\n * @returns Promise resolving to the response content string\n */\n async message(text: string, options: MessageOptions = {}): Promise<string> {\n // Build messages array from history + current message\n const messages: AIMessage[] = [\n ...(options.history || []),\n { role: options.role || 'user', content: text },\n ];\n\n const response = await this.chat(messages, {\n model: options.model,\n maxTokens: options.maxTokens,\n temperature: options.temperature,\n topP: options.topP,\n stop: options.stop,\n stream: options.stream,\n frequencyPenalty: options.frequencyPenalty,\n presencePenalty: options.presencePenalty,\n responseFormat: options.responseFormat,\n seed: options.seed,\n tools: options.tools,\n toolChoice: options.toolChoice,\n onProgress: options.onProgress,\n signal: options.signal,\n timeout: options.timeout,\n reasoning: options.reasoning,\n usageTags: options.usageTags,\n });\n\n return response.content;\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n const startTime = Date.now();\n try {\n const input = Array.isArray(text) ? text : [text];\n const model = options.model || 'sentence-transformers/all-MiniLM-L6-v2';\n\n const response = await this.makeRequest(`/models/${model}`, {\n inputs: input,\n options: {\n use_cache: this.options.useCache,\n wait_for_model: this.options.waitForModel,\n },\n });\n\n // Handle different response formats from different embedding models\n let embeddings: number[][];\n if (Array.isArray(response) && Array.isArray(response[0])) {\n // Direct array of embeddings\n embeddings = Array.isArray(text) ? response : [response[0]];\n } else if (\n response &&\n typeof response === 'object' &&\n response.embeddings\n ) {\n // Response with embeddings property\n embeddings = response.embeddings;\n } else {\n throw new AIError(\n 'Invalid embedding response format',\n 'INVALID_RESPONSE',\n 'huggingface',\n );\n }\n\n emitUsage(\n this.options,\n 'huggingface',\n 'embed',\n model,\n undefined,\n startTime,\n options.usageTags,\n );\n\n return {\n embeddings,\n model,\n };\n } catch (error) {\n throw this.mapError(error);\n }\n }\n\n async embedImage(\n _image: string | Buffer,\n _options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n throw new AIError(\n 'Hugging Face image embeddings not implemented. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async describeImage(\n _image: string | Buffer,\n _prompt?: string,\n _options: ImageDescriptionOptions = {},\n ): Promise<string> {\n throw new AIError(\n 'Image description is not implemented for Hugging Face. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async generateImage(\n _prompt: string,\n _options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n // Note: Hugging Face has image generation models (Stable Diffusion), but we're keeping this as a stub\n throw new AIError(\n 'Image generation is not implemented for Hugging Face. Use OpenAI or Gemini.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n // Hugging Face Inference API doesn't support streaming for most models\n // Fall back to regular completion and yield the result\n const startTime = Date.now();\n const response = await this.chat(messages, {\n ...options,\n _skipUsage: true,\n } as any);\n\n // Simulate streaming by yielding chunks\n const content = response.content;\n const chunkSize = 10;\n\n for (let i = 0; i < content.length; i += chunkSize) {\n if (options.signal?.aborted) {\n throw new AIError(\n 'AI request aborted by caller',\n 'AI_ABORTED',\n 'huggingface',\n options.model,\n );\n }\n const chunk = content.slice(i, i + chunkSize);\n if (options.onProgress) {\n options.onProgress(chunk);\n }\n yield chunk;\n\n // Add small delay to simulate streaming\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n\n const model = options.model || this.options.defaultModel || 'gpt2';\n emitUsage(\n this.options,\n 'huggingface',\n 'stream',\n model,\n undefined,\n startTime,\n options.usageTags,\n );\n }\n\n async countTokens(text: string): Promise<number> {\n // Approximation - Hugging Face models use different tokenizers\n return Math.ceil(text.length / 4);\n }\n\n async getModels(): Promise<AIModel[]> {\n // Return some popular text generation models available on Hugging Face\n return [\n {\n id: 'microsoft/DialoGPT-medium',\n name: 'DialoGPT Medium',\n description: 'Conversational AI model by Microsoft',\n contextLength: 1024,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'microsoft/DialoGPT-large',\n name: 'DialoGPT Large',\n description: 'Large conversational AI model by Microsoft',\n contextLength: 1024,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'facebook/blenderbot-400M-distill',\n name: 'BlenderBot 400M',\n description: 'Conversational AI model by Meta',\n contextLength: 512,\n capabilities: ['text', 'chat'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'gpt2',\n name: 'GPT-2',\n description: 'OpenAI GPT-2 model',\n contextLength: 1024,\n capabilities: ['text', 'completion'],\n supportsFunctions: false,\n supportsVision: false,\n },\n {\n id: 'sentence-transformers/all-MiniLM-L6-v2',\n name: 'All-MiniLM-L6-v2',\n description: 'Sentence embedding model',\n contextLength: 512,\n capabilities: ['embeddings'],\n supportsFunctions: false,\n supportsVision: false,\n },\n ];\n }\n\n async getCapabilities(): Promise<AICapabilities> {\n return {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: false, // Most HF models don't support function calling\n vision: false, // Limited vision model support\n fineTuning: true, // Via Hugging Face training API\n imageEmbeddings: false,\n imageGeneration: false, // Stable Diffusion exists but not implemented\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 2048,\n supportedOperations: ['chat', 'completion', 'embedding', 'streaming'],\n };\n }\n\n // ============================================================================\n // TTS Methods (Not supported - use Qwen3-TTS provider)\n // ============================================================================\n\n async synthesizeSpeech(\n _text: string,\n _options?: TTSOptions,\n ): Promise<TTSResponse> {\n throw new AIError(\n 'TTS is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n streamSpeech(_text: string, _options?: TTSOptions): AsyncIterable<Buffer> {\n const error = new AIError(\n 'TTS streaming is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n return {\n [Symbol.asyncIterator]: () => ({\n next: () => Promise.reject(error),\n }),\n };\n }\n\n async cloneVoice(_options: VoiceCloneOptions): Promise<Voice> {\n throw new AIError(\n 'Voice cloning is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async designVoice(_options: VoiceDesignOptions): Promise<Voice> {\n throw new AIError(\n 'Voice design is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n async getVoices(_options?: VoiceListOptions): Promise<Voice[]> {\n throw new AIError(\n 'Voice listing is not supported by HuggingFace provider. Use Qwen3-TTS provider.',\n 'NOT_IMPLEMENTED',\n 'huggingface',\n );\n }\n\n private messagesToPrompt(messages: AIMessage[]): string {\n // Convert chat messages to a single prompt format\n return `${messages\n .map((message) => {\n const textContent = extractTextContent(message.content);\n switch (message.role) {\n case 'system':\n return `System: ${textContent}`;\n case 'user':\n return `Human: ${textContent}`;\n case 'assistant':\n return `Assistant: ${textContent}`;\n default:\n return textContent;\n }\n })\n .join('\\n')}\\nAssistant:`;\n }\n\n private async makeRequest(\n endpoint: string,\n data: any,\n signal?: AbortSignal,\n ): Promise<any> {\n const url = `${this.baseUrl}${endpoint}`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.options.apiToken}`,\n 'Content-Type': 'application/json',\n ...this.options.headers,\n },\n body: JSON.stringify(data),\n signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`HTTP ${response.status}: ${errorText}`);\n }\n\n return response.json();\n }\n\n private mapError(error: unknown): AIError {\n if (error instanceof AIError) {\n return error;\n }\n\n const message = error instanceof Error ? error.message : 'Unknown error';\n\n // Map common HTTP status codes\n if (message.includes('401') || message.includes('Unauthorized')) {\n return new AuthenticationError('huggingface');\n }\n\n if (message.includes('429') || message.includes('rate limit')) {\n return new RateLimitError('huggingface');\n }\n\n if (message.includes('404') || message.includes('not found')) {\n return new ModelNotFoundError(message, 'huggingface');\n }\n\n if (message.includes('413') || message.includes('too large')) {\n return new ContextLengthError('huggingface');\n }\n\n return new AIError(message, 'UNKNOWN_ERROR', 'huggingface');\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { o as normalizeChatOptions, s as normalizeImageGenerationOptions } from "./safety-CEnoJS6X.js";
|
|
2
|
+
import { i as resolveGatewayAdminBaseUrl, n as LiteLLMAdmin } from "./gateway-admin-CiKvHst7.js";
|
|
3
|
+
import { OpenAIProvider } from "./openai--F38QHiJ.js";
|
|
4
|
+
import { ValidationError } from "@happyvertical/utils";
|
|
5
|
+
//#region src/shared/providers/litellm.ts
|
|
6
|
+
var LITELLM_CAPABILITIES = {
|
|
7
|
+
chat: true,
|
|
8
|
+
completion: true,
|
|
9
|
+
embeddings: true,
|
|
10
|
+
streaming: true,
|
|
11
|
+
functions: true,
|
|
12
|
+
vision: true,
|
|
13
|
+
fineTuning: false,
|
|
14
|
+
imageEmbeddings: true,
|
|
15
|
+
imageGeneration: true,
|
|
16
|
+
tts: false,
|
|
17
|
+
voiceCloning: false,
|
|
18
|
+
voiceDesign: false,
|
|
19
|
+
maxContextLength: 128e3,
|
|
20
|
+
supportedOperations: [
|
|
21
|
+
"chat",
|
|
22
|
+
"completion",
|
|
23
|
+
"embedding",
|
|
24
|
+
"streaming",
|
|
25
|
+
"functions",
|
|
26
|
+
"vision",
|
|
27
|
+
"image_embedding",
|
|
28
|
+
"image_generation"
|
|
29
|
+
]
|
|
30
|
+
};
|
|
31
|
+
function isEmbeddingModel(modelId) {
|
|
32
|
+
return /embed/i.test(modelId);
|
|
33
|
+
}
|
|
34
|
+
function isImageEmbeddingModel(modelId) {
|
|
35
|
+
return /titan-embed-image|multimodalembedding|image[-_]?embed|clip/i.test(modelId);
|
|
36
|
+
}
|
|
37
|
+
function isImageGenerationModel(modelId) {
|
|
38
|
+
return /gpt-image|dall-e|imagen|stable[-_ ]diffusion|sdxl|flux|titan-image|image-generator/i.test(modelId);
|
|
39
|
+
}
|
|
40
|
+
function isFilteredLiteLLMModel(modelId) {
|
|
41
|
+
return /moderation|transcrib|whisper|speech|tts|rerank/i.test(modelId);
|
|
42
|
+
}
|
|
43
|
+
function inferLiteLLMContextLength(modelId) {
|
|
44
|
+
if (isEmbeddingModel(modelId)) return 8192;
|
|
45
|
+
if (/gemini-1\.5|gemini-2\.0|gemini-2\.5|gemini-3/i.test(modelId)) return 1e6;
|
|
46
|
+
if (/claude/i.test(modelId)) return 2e5;
|
|
47
|
+
if (/gpt-4o|gpt-4\.1|o1|o3|o4|llama|mistral|qwen|deepseek/i.test(modelId)) return 128e3;
|
|
48
|
+
return 32768;
|
|
49
|
+
}
|
|
50
|
+
function inferLiteLLMFunctions(modelId) {
|
|
51
|
+
if (isEmbeddingModel(modelId)) return false;
|
|
52
|
+
return /gpt|claude|gemini|command|llama|mistral|qwen|deepseek|o1|o3|o4/i.test(modelId);
|
|
53
|
+
}
|
|
54
|
+
function inferLiteLLMVision(modelId) {
|
|
55
|
+
return /gpt-4o|gpt-4\.1|vision|claude-3|gemini|pixtral|llava|qwen.*vl|vl-/i.test(modelId);
|
|
56
|
+
}
|
|
57
|
+
function inferLiteLLMCapabilities(modelId) {
|
|
58
|
+
if (isImageGenerationModel(modelId)) return ["image_generation"];
|
|
59
|
+
if (isImageEmbeddingModel(modelId)) return ["embeddings", "image_embedding"];
|
|
60
|
+
if (isEmbeddingModel(modelId)) return ["embeddings"];
|
|
61
|
+
const capabilities = ["text", "chat"];
|
|
62
|
+
if (inferLiteLLMFunctions(modelId)) capabilities.push("functions");
|
|
63
|
+
if (inferLiteLLMVision(modelId)) capabilities.push("vision");
|
|
64
|
+
return capabilities;
|
|
65
|
+
}
|
|
66
|
+
function normalizeBaseUrl(baseUrl) {
|
|
67
|
+
return baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
68
|
+
}
|
|
69
|
+
function ensureLiteLLMOptions(options) {
|
|
70
|
+
if (!options.baseUrl?.trim()) throw new ValidationError("LiteLLM baseUrl is required", {
|
|
71
|
+
provider: "litellm",
|
|
72
|
+
hint: "Pass baseUrl like https://llm.happyvertical.com/v1 or set HAVE_AI_BASE_URL / LITELLM_BASE_URL"
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
...options,
|
|
76
|
+
baseUrl: normalizeBaseUrl(options.baseUrl.trim())
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
var LITELLM_PROFILE = {
|
|
80
|
+
providerLabel: "LiteLLM",
|
|
81
|
+
providerName: "litellm",
|
|
82
|
+
defaultModel: "gpt-4",
|
|
83
|
+
capabilities: LITELLM_CAPABILITIES,
|
|
84
|
+
describeModel: (modelId) => `LiteLLM model: ${modelId}`,
|
|
85
|
+
getContextLength: inferLiteLLMContextLength,
|
|
86
|
+
getModelCapabilities: inferLiteLLMCapabilities,
|
|
87
|
+
shouldIncludeModel: (modelId) => !isFilteredLiteLLMModel(modelId),
|
|
88
|
+
supportsFunctions: inferLiteLLMFunctions,
|
|
89
|
+
supportsVision: inferLiteLLMVision
|
|
90
|
+
};
|
|
91
|
+
function supportsCapability(model, capability) {
|
|
92
|
+
if (capability === "vision") return model.capabilities.includes("vision") || model.supportsVision === true;
|
|
93
|
+
if (capability === "embeddings") return model.capabilities.includes("embeddings");
|
|
94
|
+
if (capability === "image_generation") return model.capabilities.includes("image_generation");
|
|
95
|
+
return model.capabilities.includes("chat");
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* LiteLLM provider implementation.
|
|
99
|
+
*
|
|
100
|
+
* LiteLLM exposes an OpenAI-compatible API surface, so this provider reuses the
|
|
101
|
+
* OpenAI transport while customizing provider identity, model discovery, and
|
|
102
|
+
* capability heuristics for gateway-backed deployments.
|
|
103
|
+
*/
|
|
104
|
+
var LiteLLMProvider = class extends OpenAIProvider {
|
|
105
|
+
admin;
|
|
106
|
+
configuredDefaultModel;
|
|
107
|
+
resolvedModelCache = /* @__PURE__ */ new Map();
|
|
108
|
+
constructor(options) {
|
|
109
|
+
const normalized = ensureLiteLLMOptions(options);
|
|
110
|
+
super(normalized, LITELLM_PROFILE);
|
|
111
|
+
this.admin = new LiteLLMAdmin({
|
|
112
|
+
provider: "litellm",
|
|
113
|
+
baseUrl: resolveGatewayAdminBaseUrl(normalized.baseUrl, normalized.adminUrl || normalized.adminBaseUrl, "litellm"),
|
|
114
|
+
apiKey: normalized.adminApiKey || normalized.apiKey,
|
|
115
|
+
headers: normalized.adminHeaders,
|
|
116
|
+
timeout: normalized.timeout
|
|
117
|
+
});
|
|
118
|
+
this.configuredDefaultModel = normalized.defaultModel;
|
|
119
|
+
}
|
|
120
|
+
async resolveModel(capability, explicitModel) {
|
|
121
|
+
if (explicitModel) return explicitModel;
|
|
122
|
+
if (this.configuredDefaultModel && (capability === "chat" || capability === "vision")) return this.configuredDefaultModel;
|
|
123
|
+
const cached = this.resolvedModelCache.get(capability);
|
|
124
|
+
if (cached) return cached;
|
|
125
|
+
const pending = this.selectModel(capability).catch((error) => {
|
|
126
|
+
this.resolvedModelCache.delete(capability);
|
|
127
|
+
throw error;
|
|
128
|
+
});
|
|
129
|
+
this.resolvedModelCache.set(capability, pending);
|
|
130
|
+
return pending;
|
|
131
|
+
}
|
|
132
|
+
async selectModel(capability) {
|
|
133
|
+
const model = (await super.getModels()).find((candidate) => supportsCapability(candidate, capability));
|
|
134
|
+
if (!model) throw new ValidationError(`No ${capability} model is available from the LiteLLM gateway`, {
|
|
135
|
+
provider: "litellm",
|
|
136
|
+
capability,
|
|
137
|
+
hint: "Pass defaultModel explicitly or ensure /models returns a compatible model for this key"
|
|
138
|
+
});
|
|
139
|
+
return model.id;
|
|
140
|
+
}
|
|
141
|
+
async chat(messages, options = {}) {
|
|
142
|
+
const safe = normalizeChatOptions(this.options, options, "litellm", options.model || this.options.defaultModel);
|
|
143
|
+
return super.chat(messages, {
|
|
144
|
+
...safe,
|
|
145
|
+
model: await this.resolveModel("chat", safe.model)
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async *stream(messages, options = {}) {
|
|
149
|
+
const safe = normalizeChatOptions(this.options, options, "litellm", options.model || this.options.defaultModel);
|
|
150
|
+
yield* super.stream(messages, {
|
|
151
|
+
...safe,
|
|
152
|
+
model: await this.resolveModel("chat", safe.model)
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async describeImage(image, prompt, options = {}) {
|
|
156
|
+
const safe = normalizeChatOptions(this.options, options, "litellm", options.model || this.options.defaultModel);
|
|
157
|
+
return super.describeImage(image, prompt, {
|
|
158
|
+
...safe,
|
|
159
|
+
model: await this.resolveModel("vision", safe.model)
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async embed(text, options = {}) {
|
|
163
|
+
return super.embed(text, {
|
|
164
|
+
...options,
|
|
165
|
+
model: await this.resolveModel("embeddings", options.model)
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
async embedImage(image, options = {}) {
|
|
169
|
+
return super.embedImage(image, {
|
|
170
|
+
...options,
|
|
171
|
+
model: await this.resolveModel("embeddings", options.model)
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async generateImage(prompt, options = {}) {
|
|
175
|
+
const safe = normalizeImageGenerationOptions(this.options, options, "litellm", options.model);
|
|
176
|
+
return super.generateImage(prompt, {
|
|
177
|
+
...safe,
|
|
178
|
+
model: await this.resolveModel("image_generation", safe.model)
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
//#endregion
|
|
183
|
+
export { LiteLLMProvider };
|
|
184
|
+
|
|
185
|
+
//# sourceMappingURL=litellm-D_Oo9OQ_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"litellm-D_Oo9OQ_.js","names":[],"sources":["../../src/shared/providers/litellm.ts"],"sourcesContent":["import { ValidationError } from '@happyvertical/utils';\n\nimport {\n normalizeChatOptions,\n normalizeImageGenerationOptions,\n} from '../safety';\nimport type {\n AICapabilities,\n AIMessage,\n AIModel,\n AIResponse,\n ChatOptions,\n EmbeddingOptions,\n EmbeddingResponse,\n ImageDescriptionOptions,\n ImageEmbeddingOptions,\n ImageGenerationOptions,\n ImageGenerationResponse,\n LiteLLMOptions,\n} from '../types';\nimport { LiteLLMAdmin, resolveGatewayAdminBaseUrl } from './gateway-admin';\nimport { type OpenAICompatibleProfile, OpenAIProvider } from './openai';\n\nconst LITELLM_CAPABILITIES: AICapabilities = {\n chat: true,\n completion: true,\n embeddings: true,\n streaming: true,\n functions: true,\n vision: true,\n fineTuning: false,\n imageEmbeddings: true,\n imageGeneration: true,\n tts: false,\n voiceCloning: false,\n voiceDesign: false,\n maxContextLength: 128000,\n supportedOperations: [\n 'chat',\n 'completion',\n 'embedding',\n 'streaming',\n 'functions',\n 'vision',\n 'image_embedding',\n 'image_generation',\n ],\n};\n\nfunction isEmbeddingModel(modelId: string): boolean {\n return /embed/i.test(modelId);\n}\n\nfunction isImageEmbeddingModel(modelId: string): boolean {\n return /titan-embed-image|multimodalembedding|image[-_]?embed|clip/i.test(\n modelId,\n );\n}\n\nfunction isImageGenerationModel(modelId: string): boolean {\n return /gpt-image|dall-e|imagen|stable[-_ ]diffusion|sdxl|flux|titan-image|image-generator/i.test(\n modelId,\n );\n}\n\nfunction isFilteredLiteLLMModel(modelId: string): boolean {\n return /moderation|transcrib|whisper|speech|tts|rerank/i.test(modelId);\n}\n\nfunction inferLiteLLMContextLength(modelId: string): number {\n if (isEmbeddingModel(modelId)) return 8192;\n if (/gemini-1\\.5|gemini-2\\.0|gemini-2\\.5|gemini-3/i.test(modelId)) {\n return 1000000;\n }\n if (/claude/i.test(modelId)) return 200000;\n if (/gpt-4o|gpt-4\\.1|o1|o3|o4|llama|mistral|qwen|deepseek/i.test(modelId)) {\n return 128000;\n }\n return 32768;\n}\n\nfunction inferLiteLLMFunctions(modelId: string): boolean {\n if (isEmbeddingModel(modelId)) return false;\n return /gpt|claude|gemini|command|llama|mistral|qwen|deepseek|o1|o3|o4/i.test(\n modelId,\n );\n}\n\nfunction inferLiteLLMVision(modelId: string): boolean {\n return /gpt-4o|gpt-4\\.1|vision|claude-3|gemini|pixtral|llava|qwen.*vl|vl-/i.test(\n modelId,\n );\n}\n\nfunction inferLiteLLMCapabilities(modelId: string): string[] {\n if (isImageGenerationModel(modelId)) {\n return ['image_generation'];\n }\n\n if (isImageEmbeddingModel(modelId)) {\n return ['embeddings', 'image_embedding'];\n }\n\n if (isEmbeddingModel(modelId)) {\n return ['embeddings'];\n }\n\n const capabilities = ['text', 'chat'];\n\n if (inferLiteLLMFunctions(modelId)) {\n capabilities.push('functions');\n }\n\n if (inferLiteLLMVision(modelId)) {\n capabilities.push('vision');\n }\n\n return capabilities;\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n}\n\nfunction ensureLiteLLMOptions(options: LiteLLMOptions): LiteLLMOptions {\n if (!options.baseUrl?.trim()) {\n throw new ValidationError('LiteLLM baseUrl is required', {\n provider: 'litellm',\n hint: 'Pass baseUrl like https://llm.happyvertical.com/v1 or set HAVE_AI_BASE_URL / LITELLM_BASE_URL',\n });\n }\n\n return {\n ...options,\n baseUrl: normalizeBaseUrl(options.baseUrl.trim()),\n };\n}\n\nconst LITELLM_PROFILE: OpenAICompatibleProfile = {\n providerLabel: 'LiteLLM',\n providerName: 'litellm',\n defaultModel: 'gpt-4',\n capabilities: LITELLM_CAPABILITIES,\n describeModel: (modelId) => `LiteLLM model: ${modelId}`,\n getContextLength: inferLiteLLMContextLength,\n getModelCapabilities: inferLiteLLMCapabilities,\n shouldIncludeModel: (modelId) => !isFilteredLiteLLMModel(modelId),\n supportsFunctions: inferLiteLLMFunctions,\n supportsVision: inferLiteLLMVision,\n};\n\ntype LiteLLMResolvedCapability =\n | 'chat'\n | 'vision'\n | 'embeddings'\n | 'image_generation';\n\nfunction supportsCapability(\n model: AIModel,\n capability: LiteLLMResolvedCapability,\n): boolean {\n if (capability === 'vision') {\n return (\n model.capabilities.includes('vision') || model.supportsVision === true\n );\n }\n\n if (capability === 'embeddings') {\n return model.capabilities.includes('embeddings');\n }\n\n if (capability === 'image_generation') {\n return model.capabilities.includes('image_generation');\n }\n\n return model.capabilities.includes('chat');\n}\n\n/**\n * LiteLLM provider implementation.\n *\n * LiteLLM exposes an OpenAI-compatible API surface, so this provider reuses the\n * OpenAI transport while customizing provider identity, model discovery, and\n * capability heuristics for gateway-backed deployments.\n */\nexport class LiteLLMProvider extends OpenAIProvider {\n readonly admin: LiteLLMAdmin;\n private readonly configuredDefaultModel?: string;\n private readonly resolvedModelCache = new Map<\n LiteLLMResolvedCapability,\n Promise<string>\n >();\n\n constructor(options: LiteLLMOptions) {\n const normalized = ensureLiteLLMOptions(options);\n super(normalized, LITELLM_PROFILE);\n this.admin = new LiteLLMAdmin({\n provider: 'litellm',\n baseUrl: resolveGatewayAdminBaseUrl(\n normalized.baseUrl,\n normalized.adminUrl || normalized.adminBaseUrl,\n 'litellm',\n ),\n apiKey: normalized.adminApiKey || normalized.apiKey,\n headers: normalized.adminHeaders,\n timeout: normalized.timeout,\n });\n this.configuredDefaultModel = normalized.defaultModel;\n }\n\n private async resolveModel(\n capability: LiteLLMResolvedCapability,\n explicitModel?: string,\n ): Promise<string> {\n if (explicitModel) {\n return explicitModel;\n }\n\n if (\n this.configuredDefaultModel &&\n (capability === 'chat' || capability === 'vision')\n ) {\n return this.configuredDefaultModel;\n }\n\n const cached = this.resolvedModelCache.get(capability);\n if (cached) {\n return cached;\n }\n\n const pending = this.selectModel(capability).catch((error) => {\n this.resolvedModelCache.delete(capability);\n throw error;\n });\n this.resolvedModelCache.set(capability, pending);\n return pending;\n }\n\n private async selectModel(\n capability: LiteLLMResolvedCapability,\n ): Promise<string> {\n const models = await super.getModels();\n const model = models.find((candidate) =>\n supportsCapability(candidate, capability),\n );\n\n if (!model) {\n throw new ValidationError(\n `No ${capability} model is available from the LiteLLM gateway`,\n {\n provider: 'litellm',\n capability,\n hint: 'Pass defaultModel explicitly or ensure /models returns a compatible model for this key',\n },\n );\n }\n\n return model.id;\n }\n\n async chat(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): Promise<AIResponse> {\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n return super.chat(messages, {\n ...safe,\n model: await this.resolveModel('chat', safe.model),\n });\n }\n\n async *stream(\n messages: AIMessage[],\n options: ChatOptions = {},\n ): AsyncIterable<string> {\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n yield* super.stream(messages, {\n ...safe,\n model: await this.resolveModel('chat', safe.model),\n });\n }\n\n async describeImage(\n image: string | Buffer,\n prompt?: string,\n options: ImageDescriptionOptions = {},\n ): Promise<string> {\n const safe = normalizeChatOptions(\n this.options,\n options,\n 'litellm',\n options.model || this.options.defaultModel,\n );\n return super.describeImage(image, prompt, {\n ...safe,\n model: await this.resolveModel('vision', safe.model),\n });\n }\n\n async embed(\n text: string | string[],\n options: EmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n return super.embed(text, {\n ...options,\n model: await this.resolveModel('embeddings', options.model),\n });\n }\n\n async embedImage(\n image: string | Buffer,\n options: ImageEmbeddingOptions = {},\n ): Promise<EmbeddingResponse> {\n return super.embedImage(image, {\n ...options,\n model: await this.resolveModel('embeddings', options.model),\n });\n }\n\n async generateImage(\n prompt: string,\n options: ImageGenerationOptions = {},\n ): Promise<ImageGenerationResponse> {\n const safe = normalizeImageGenerationOptions(\n this.options,\n options,\n 'litellm',\n options.model,\n );\n return super.generateImage(prompt, {\n ...safe,\n model: await this.resolveModel('image_generation', safe.model),\n });\n }\n}\n"],"mappings":"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"}
|