@retrivora-ai/rag-engine 2.0.7 → 2.0.8
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/handlers/index.js +706 -54
- package/dist/handlers/index.mjs +706 -54
- package/dist/index.js +5 -4
- package/dist/index.mjs +5 -4
- package/dist/server.js +706 -54
- package/dist/server.mjs +706 -54
- package/package.json +1 -1
- package/src/core/Pipeline.ts +19 -37
- package/src/llm/providers/UniversalLLMAdapter.ts +74 -16
- package/src/utils/UITransformer.ts +4 -5
package/dist/server.js
CHANGED
|
@@ -121,6 +121,609 @@ var init_templateUtils = __esm({
|
|
|
121
121
|
}
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
+
// ../../services/llm-gateway/providers/groq.ts
|
|
125
|
+
async function handleGroqRequest(req, apiKeyOverride) {
|
|
126
|
+
const apiKey = apiKeyOverride || process.env.GROQ_API_KEY;
|
|
127
|
+
if (!apiKey) {
|
|
128
|
+
throw new Error("Groq API Key missing. Please set GROQ_API_KEY in environment variables.");
|
|
129
|
+
}
|
|
130
|
+
const modelName = req.model.replace(/^groq\//i, "");
|
|
131
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
132
|
+
model: modelName
|
|
133
|
+
});
|
|
134
|
+
const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
|
|
135
|
+
method: "POST",
|
|
136
|
+
headers: {
|
|
137
|
+
"Content-Type": "application/json",
|
|
138
|
+
"Authorization": `Bearer ${apiKey}`
|
|
139
|
+
},
|
|
140
|
+
body: JSON.stringify(payload)
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
const errorText = await response.text();
|
|
144
|
+
throw new Error(`Groq API Error (${response.status}): ${errorText}`);
|
|
145
|
+
}
|
|
146
|
+
if (req.stream && response.body) {
|
|
147
|
+
return { stream: response.body };
|
|
148
|
+
}
|
|
149
|
+
const json = await response.json();
|
|
150
|
+
return { response: json };
|
|
151
|
+
}
|
|
152
|
+
var init_groq = __esm({
|
|
153
|
+
"../../services/llm-gateway/providers/groq.ts"() {
|
|
154
|
+
"use strict";
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// ../../services/llm-gateway/providers/openai.ts
|
|
159
|
+
async function handleOpenAIRequest(req, apiKeyOverride) {
|
|
160
|
+
const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
|
|
161
|
+
if (!apiKey) {
|
|
162
|
+
throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
|
|
163
|
+
}
|
|
164
|
+
const modelName = req.model.replace(/^(openai|gpt)\//i, "");
|
|
165
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
166
|
+
model: modelName
|
|
167
|
+
});
|
|
168
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
169
|
+
method: "POST",
|
|
170
|
+
headers: {
|
|
171
|
+
"Content-Type": "application/json",
|
|
172
|
+
"Authorization": `Bearer ${apiKey}`
|
|
173
|
+
},
|
|
174
|
+
body: JSON.stringify(payload)
|
|
175
|
+
});
|
|
176
|
+
if (!response.ok) {
|
|
177
|
+
const errorText = await response.text();
|
|
178
|
+
throw new Error(`OpenAI API Error (${response.status}): ${errorText}`);
|
|
179
|
+
}
|
|
180
|
+
if (req.stream && response.body) {
|
|
181
|
+
return { stream: response.body };
|
|
182
|
+
}
|
|
183
|
+
const json = await response.json();
|
|
184
|
+
return { response: json };
|
|
185
|
+
}
|
|
186
|
+
async function handleOpenAIEmbedding(req, apiKeyOverride) {
|
|
187
|
+
const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
|
|
188
|
+
if (!apiKey) {
|
|
189
|
+
throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
|
|
190
|
+
}
|
|
191
|
+
const modelName = req.model.replace(/^(openai)\//i, "");
|
|
192
|
+
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
193
|
+
method: "POST",
|
|
194
|
+
headers: {
|
|
195
|
+
"Content-Type": "application/json",
|
|
196
|
+
"Authorization": `Bearer ${apiKey}`
|
|
197
|
+
},
|
|
198
|
+
body: JSON.stringify({
|
|
199
|
+
model: modelName,
|
|
200
|
+
input: req.input
|
|
201
|
+
})
|
|
202
|
+
});
|
|
203
|
+
if (!response.ok) {
|
|
204
|
+
const errorText = await response.text();
|
|
205
|
+
throw new Error(`OpenAI Embedding API Error (${response.status}): ${errorText}`);
|
|
206
|
+
}
|
|
207
|
+
return await response.json();
|
|
208
|
+
}
|
|
209
|
+
var init_openai = __esm({
|
|
210
|
+
"../../services/llm-gateway/providers/openai.ts"() {
|
|
211
|
+
"use strict";
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// ../../services/llm-gateway/providers/gemini.ts
|
|
216
|
+
async function handleGeminiRequest(req, apiKeyOverride) {
|
|
217
|
+
const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
|
|
218
|
+
if (!apiKey) {
|
|
219
|
+
throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
|
|
220
|
+
}
|
|
221
|
+
let modelName = req.model.replace(/^(google|gemini)\//i, "");
|
|
222
|
+
if (!modelName.startsWith("gemini-")) {
|
|
223
|
+
modelName = `gemini-${modelName}`;
|
|
224
|
+
}
|
|
225
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
226
|
+
model: modelName
|
|
227
|
+
});
|
|
228
|
+
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", {
|
|
229
|
+
method: "POST",
|
|
230
|
+
headers: {
|
|
231
|
+
"Content-Type": "application/json",
|
|
232
|
+
"Authorization": `Bearer ${apiKey}`
|
|
233
|
+
},
|
|
234
|
+
body: JSON.stringify(payload)
|
|
235
|
+
});
|
|
236
|
+
if (!response.ok) {
|
|
237
|
+
const errorText = await response.text();
|
|
238
|
+
throw new Error(`Google Gemini API Error (${response.status}): ${errorText}`);
|
|
239
|
+
}
|
|
240
|
+
if (req.stream && response.body) {
|
|
241
|
+
return { stream: response.body };
|
|
242
|
+
}
|
|
243
|
+
const json = await response.json();
|
|
244
|
+
return { response: json };
|
|
245
|
+
}
|
|
246
|
+
async function handleGeminiEmbedding(req, apiKeyOverride) {
|
|
247
|
+
const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
|
|
248
|
+
if (!apiKey) {
|
|
249
|
+
throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
|
|
250
|
+
}
|
|
251
|
+
let modelName = req.model.replace(/^(google|gemini)\//i, "");
|
|
252
|
+
if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.startsWith("text-embedding-00") && !modelName.startsWith("embedding-00")) {
|
|
253
|
+
modelName = "text-embedding-004";
|
|
254
|
+
}
|
|
255
|
+
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/embeddings", {
|
|
256
|
+
method: "POST",
|
|
257
|
+
headers: {
|
|
258
|
+
"Content-Type": "application/json",
|
|
259
|
+
"Authorization": `Bearer ${apiKey}`
|
|
260
|
+
},
|
|
261
|
+
body: JSON.stringify({
|
|
262
|
+
model: modelName,
|
|
263
|
+
input: req.input
|
|
264
|
+
})
|
|
265
|
+
});
|
|
266
|
+
if (!response.ok) {
|
|
267
|
+
const errorText = await response.text();
|
|
268
|
+
throw new Error(`Google Gemini Embedding API Error (${response.status}): ${errorText}`);
|
|
269
|
+
}
|
|
270
|
+
return await response.json();
|
|
271
|
+
}
|
|
272
|
+
var init_gemini = __esm({
|
|
273
|
+
"../../services/llm-gateway/providers/gemini.ts"() {
|
|
274
|
+
"use strict";
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// ../../services/llm-gateway/providers/huggingface.ts
|
|
279
|
+
async function handleHuggingFaceChatRequest(req, apiKeyOverride) {
|
|
280
|
+
var _a2, _b;
|
|
281
|
+
const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
|
|
282
|
+
if (!apiKey) {
|
|
283
|
+
throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
|
|
284
|
+
}
|
|
285
|
+
let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
|
|
286
|
+
if (!modelName || modelName === "default" || modelName.toLowerCase() === "qwen" || modelName.toLowerCase() === "qwen-coder") {
|
|
287
|
+
modelName = "Qwen/Qwen2.5-Coder-32B-Instruct";
|
|
288
|
+
}
|
|
289
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
290
|
+
model: modelName
|
|
291
|
+
});
|
|
292
|
+
try {
|
|
293
|
+
const response = await fetch("https://router.huggingface.co/v1/chat/completions", {
|
|
294
|
+
method: "POST",
|
|
295
|
+
headers: {
|
|
296
|
+
"Content-Type": "application/json",
|
|
297
|
+
"Authorization": `Bearer ${apiKey}`
|
|
298
|
+
},
|
|
299
|
+
body: JSON.stringify(payload)
|
|
300
|
+
});
|
|
301
|
+
if (response.ok) {
|
|
302
|
+
if (req.stream && response.body) {
|
|
303
|
+
return { stream: response.body };
|
|
304
|
+
}
|
|
305
|
+
const json = await response.json();
|
|
306
|
+
return { response: json };
|
|
307
|
+
}
|
|
308
|
+
} catch (e) {
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
const response = await fetch("https://router.huggingface.co/hf-inference/v1/chat/completions", {
|
|
312
|
+
method: "POST",
|
|
313
|
+
headers: {
|
|
314
|
+
"Content-Type": "application/json",
|
|
315
|
+
"Authorization": `Bearer ${apiKey}`
|
|
316
|
+
},
|
|
317
|
+
body: JSON.stringify(payload)
|
|
318
|
+
});
|
|
319
|
+
if (response.ok) {
|
|
320
|
+
if (req.stream && response.body) {
|
|
321
|
+
return { stream: response.body };
|
|
322
|
+
}
|
|
323
|
+
const json = await response.json();
|
|
324
|
+
return { response: json };
|
|
325
|
+
}
|
|
326
|
+
} catch (e) {
|
|
327
|
+
}
|
|
328
|
+
const lastUserMsg = ((_a2 = req.messages.filter((m) => m.role === "user").pop()) == null ? void 0 : _a2.content) || "Hello";
|
|
329
|
+
const pipelineRes = await fetch(`https://router.huggingface.co/hf-inference/models/${modelName}`, {
|
|
330
|
+
method: "POST",
|
|
331
|
+
headers: {
|
|
332
|
+
"Content-Type": "application/json",
|
|
333
|
+
"Authorization": `Bearer ${apiKey}`
|
|
334
|
+
},
|
|
335
|
+
body: JSON.stringify({
|
|
336
|
+
inputs: lastUserMsg,
|
|
337
|
+
parameters: { max_new_tokens: req.max_tokens || 256, temperature: req.temperature || 0.7 },
|
|
338
|
+
options: { wait_for_model: true }
|
|
339
|
+
})
|
|
340
|
+
});
|
|
341
|
+
if (!pipelineRes.ok) {
|
|
342
|
+
const errorText = await pipelineRes.text();
|
|
343
|
+
throw new Error(`HuggingFace API Error (${pipelineRes.status}): ${errorText}`);
|
|
344
|
+
}
|
|
345
|
+
const raw = await pipelineRes.json();
|
|
346
|
+
const textOutput = Array.isArray(raw) ? ((_b = raw[0]) == null ? void 0 : _b.generated_text) || JSON.stringify(raw) : JSON.stringify(raw);
|
|
347
|
+
const formattedResponse = {
|
|
348
|
+
id: `hf-${Date.now()}`,
|
|
349
|
+
object: "chat.completion",
|
|
350
|
+
created: Math.floor(Date.now() / 1e3),
|
|
351
|
+
model: modelName,
|
|
352
|
+
choices: [
|
|
353
|
+
{
|
|
354
|
+
index: 0,
|
|
355
|
+
message: {
|
|
356
|
+
role: "assistant",
|
|
357
|
+
content: textOutput
|
|
358
|
+
},
|
|
359
|
+
finish_reason: "stop"
|
|
360
|
+
}
|
|
361
|
+
],
|
|
362
|
+
usage: {
|
|
363
|
+
prompt_tokens: lastUserMsg.length,
|
|
364
|
+
completion_tokens: textOutput.length,
|
|
365
|
+
total_tokens: lastUserMsg.length + textOutput.length
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
return { response: formattedResponse };
|
|
369
|
+
}
|
|
370
|
+
async function handleHuggingFaceEmbedding(req, apiKeyOverride) {
|
|
371
|
+
const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
|
|
372
|
+
if (!apiKey) {
|
|
373
|
+
throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
|
|
374
|
+
}
|
|
375
|
+
let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
|
|
376
|
+
if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.includes("/") && !modelName.includes("bge") && !modelName.includes("sentence-transformers")) {
|
|
377
|
+
modelName = "BAAI/bge-base-en-v1.5";
|
|
378
|
+
}
|
|
379
|
+
const inputs = Array.isArray(req.input) ? req.input : [req.input];
|
|
380
|
+
const fetchEmbeddingFromModel = async (targetModel) => {
|
|
381
|
+
try {
|
|
382
|
+
const routerRes = await fetch("https://router.huggingface.co/hf-inference/v1/embeddings", {
|
|
383
|
+
method: "POST",
|
|
384
|
+
headers: {
|
|
385
|
+
"Content-Type": "application/json",
|
|
386
|
+
"Authorization": `Bearer ${apiKey}`
|
|
387
|
+
},
|
|
388
|
+
body: JSON.stringify({
|
|
389
|
+
model: targetModel,
|
|
390
|
+
input: inputs
|
|
391
|
+
})
|
|
392
|
+
});
|
|
393
|
+
if (routerRes.ok) {
|
|
394
|
+
const json = await routerRes.json();
|
|
395
|
+
if (json && json.data) return json;
|
|
396
|
+
}
|
|
397
|
+
} catch (e) {
|
|
398
|
+
}
|
|
399
|
+
const response = await fetch(`https://router.huggingface.co/hf-inference/models/${targetModel}`, {
|
|
400
|
+
method: "POST",
|
|
401
|
+
headers: {
|
|
402
|
+
"Content-Type": "application/json",
|
|
403
|
+
"Authorization": `Bearer ${apiKey}`
|
|
404
|
+
},
|
|
405
|
+
body: JSON.stringify({
|
|
406
|
+
inputs,
|
|
407
|
+
options: { wait_for_model: true }
|
|
408
|
+
})
|
|
409
|
+
});
|
|
410
|
+
if (!response.ok) {
|
|
411
|
+
const errorText = await response.text();
|
|
412
|
+
throw new Error(`HuggingFace API Error (${response.status}): ${errorText}`);
|
|
413
|
+
}
|
|
414
|
+
const rawData = await response.json();
|
|
415
|
+
const embeddings = Array.isArray(rawData[0]) ? typeof rawData[0][0] === "number" ? rawData : rawData.map((arr) => arr[0]) : [rawData];
|
|
416
|
+
return {
|
|
417
|
+
object: "list",
|
|
418
|
+
data: embeddings.map((vec, idx) => ({
|
|
419
|
+
object: "embedding",
|
|
420
|
+
embedding: vec,
|
|
421
|
+
index: idx
|
|
422
|
+
})),
|
|
423
|
+
model: targetModel,
|
|
424
|
+
usage: {
|
|
425
|
+
prompt_tokens: inputs.reduce((acc, str) => acc + str.length, 0),
|
|
426
|
+
completion_tokens: 0,
|
|
427
|
+
total_tokens: inputs.reduce((acc, str) => acc + str.length, 0)
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
try {
|
|
432
|
+
return await fetchEmbeddingFromModel(modelName);
|
|
433
|
+
} catch (err) {
|
|
434
|
+
if (modelName !== "BAAI/bge-base-en-v1.5") {
|
|
435
|
+
console.warn(`[LLM Gateway] HuggingFace model ${modelName} failed. Falling back to BAAI/bge-base-en-v1.5...`, err);
|
|
436
|
+
return await fetchEmbeddingFromModel("BAAI/bge-base-en-v1.5");
|
|
437
|
+
}
|
|
438
|
+
throw err;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
var init_huggingface = __esm({
|
|
442
|
+
"../../services/llm-gateway/providers/huggingface.ts"() {
|
|
443
|
+
"use strict";
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
// ../../services/llm-gateway/providers/anthropic.ts
|
|
448
|
+
async function handleAnthropicRequest(req, apiKeyOverride) {
|
|
449
|
+
var _a2, _b;
|
|
450
|
+
const apiKey = apiKeyOverride || process.env.ANTHROPIC_API_KEY;
|
|
451
|
+
if (!apiKey) {
|
|
452
|
+
throw new Error("Anthropic API Key missing. Please set ANTHROPIC_API_KEY in environment variables.");
|
|
453
|
+
}
|
|
454
|
+
const modelName = req.model.replace(/^(anthropic|claude)\//i, "");
|
|
455
|
+
let systemPrompt = void 0;
|
|
456
|
+
const anthropicMessages = [];
|
|
457
|
+
for (const msg of req.messages) {
|
|
458
|
+
if (msg.role === "system") {
|
|
459
|
+
systemPrompt = systemPrompt ? `${systemPrompt}
|
|
460
|
+
${msg.content}` : msg.content;
|
|
461
|
+
} else {
|
|
462
|
+
anthropicMessages.push({
|
|
463
|
+
role: msg.role === "assistant" ? "assistant" : "user",
|
|
464
|
+
content: msg.content
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (anthropicMessages.length === 0) {
|
|
469
|
+
anthropicMessages.push({ role: "user", content: "Hello" });
|
|
470
|
+
}
|
|
471
|
+
const payload = {
|
|
472
|
+
model: modelName,
|
|
473
|
+
messages: anthropicMessages,
|
|
474
|
+
max_tokens: req.max_tokens || req.max_completion_tokens || 1024,
|
|
475
|
+
stream: req.stream || false
|
|
476
|
+
};
|
|
477
|
+
if (systemPrompt) {
|
|
478
|
+
payload.system = systemPrompt;
|
|
479
|
+
}
|
|
480
|
+
if (req.temperature !== void 0) {
|
|
481
|
+
payload.temperature = req.temperature;
|
|
482
|
+
}
|
|
483
|
+
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
|
484
|
+
method: "POST",
|
|
485
|
+
headers: {
|
|
486
|
+
"Content-Type": "application/json",
|
|
487
|
+
"x-api-key": apiKey,
|
|
488
|
+
"anthropic-version": "2023-06-01"
|
|
489
|
+
},
|
|
490
|
+
body: JSON.stringify(payload)
|
|
491
|
+
});
|
|
492
|
+
if (!response.ok) {
|
|
493
|
+
const errorText = await response.text();
|
|
494
|
+
throw new Error(`Anthropic API Error (${response.status}): ${errorText}`);
|
|
495
|
+
}
|
|
496
|
+
if (req.stream && response.body) {
|
|
497
|
+
return { stream: response.body };
|
|
498
|
+
}
|
|
499
|
+
const json = await response.json();
|
|
500
|
+
const textContent = ((_b = (_a2 = json.content) == null ? void 0 : _a2[0]) == null ? void 0 : _b.text) || "";
|
|
501
|
+
const openAIResponse = {
|
|
502
|
+
id: json.id || `chatcmpl-${Date.now()}`,
|
|
503
|
+
object: "chat.completion",
|
|
504
|
+
created: Math.floor(Date.now() / 1e3),
|
|
505
|
+
model: json.model || modelName,
|
|
506
|
+
choices: [
|
|
507
|
+
{
|
|
508
|
+
index: 0,
|
|
509
|
+
message: {
|
|
510
|
+
role: "assistant",
|
|
511
|
+
content: textContent
|
|
512
|
+
},
|
|
513
|
+
finish_reason: json.stop_reason === "end_turn" ? "stop" : json.stop_reason || "stop"
|
|
514
|
+
}
|
|
515
|
+
],
|
|
516
|
+
usage: json.usage ? {
|
|
517
|
+
prompt_tokens: json.usage.input_tokens,
|
|
518
|
+
completion_tokens: json.usage.output_tokens,
|
|
519
|
+
total_tokens: json.usage.input_tokens + json.usage.output_tokens
|
|
520
|
+
} : void 0
|
|
521
|
+
};
|
|
522
|
+
return { response: openAIResponse };
|
|
523
|
+
}
|
|
524
|
+
var init_anthropic = __esm({
|
|
525
|
+
"../../services/llm-gateway/providers/anthropic.ts"() {
|
|
526
|
+
"use strict";
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// ../../services/llm-gateway/providers/ollama.ts
|
|
531
|
+
async function handleOllamaRequest(req, baseUrlOverride) {
|
|
532
|
+
const baseUrl = (baseUrlOverride || process.env.OLLAMA_BASE_URL || "http://localhost:11434/v1").replace(/\/+$/, "");
|
|
533
|
+
const modelName = req.model.replace(/^ollama\//i, "");
|
|
534
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
535
|
+
model: modelName
|
|
536
|
+
});
|
|
537
|
+
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
538
|
+
method: "POST",
|
|
539
|
+
headers: {
|
|
540
|
+
"Content-Type": "application/json"
|
|
541
|
+
},
|
|
542
|
+
body: JSON.stringify(payload)
|
|
543
|
+
});
|
|
544
|
+
if (!response.ok) {
|
|
545
|
+
const errorText = await response.text();
|
|
546
|
+
throw new Error(`Ollama API Error (${response.status}): ${errorText}`);
|
|
547
|
+
}
|
|
548
|
+
if (req.stream && response.body) {
|
|
549
|
+
return { stream: response.body };
|
|
550
|
+
}
|
|
551
|
+
const json = await response.json();
|
|
552
|
+
return { response: json };
|
|
553
|
+
}
|
|
554
|
+
var init_ollama = __esm({
|
|
555
|
+
"../../services/llm-gateway/providers/ollama.ts"() {
|
|
556
|
+
"use strict";
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// ../../services/llm-gateway/router.ts
|
|
561
|
+
var router_exports = {};
|
|
562
|
+
__export(router_exports, {
|
|
563
|
+
SUPPORTED_MODELS: () => SUPPORTED_MODELS,
|
|
564
|
+
dispatchChatCompletion: () => dispatchChatCompletion,
|
|
565
|
+
dispatchEmbedding: () => dispatchEmbedding,
|
|
566
|
+
resolveProvider: () => resolveProvider
|
|
567
|
+
});
|
|
568
|
+
function resolveProvider(model) {
|
|
569
|
+
const lower = model.toLowerCase();
|
|
570
|
+
if (lower.startsWith("huggingface/") || lower.startsWith("hf/")) {
|
|
571
|
+
return "huggingface";
|
|
572
|
+
}
|
|
573
|
+
if (lower.startsWith("ollama/")) {
|
|
574
|
+
return "ollama";
|
|
575
|
+
}
|
|
576
|
+
if (lower.startsWith("groq/") || lower.includes("llama") || lower.includes("qwen") || lower.includes("mixtral")) {
|
|
577
|
+
return "groq";
|
|
578
|
+
}
|
|
579
|
+
if (process.env.GROQ_API_KEY) return "groq";
|
|
580
|
+
if (process.env.OPENAI_API_KEY) return "openai";
|
|
581
|
+
if (process.env.GEMINI_API_KEY) return "gemini";
|
|
582
|
+
if (process.env.ANTHROPIC_API_KEY) return "anthropic";
|
|
583
|
+
if (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY) return "huggingface";
|
|
584
|
+
return "groq";
|
|
585
|
+
}
|
|
586
|
+
function cleanApiKeyOverride(apiKeyOverride) {
|
|
587
|
+
if (!apiKeyOverride) return void 0;
|
|
588
|
+
const key = apiKeyOverride.trim();
|
|
589
|
+
if (key === process.env.LITELLM_API_KEY || key === process.env.LITELLM_MASTER_KEY || key.startsWith("sk-retrivora") || !key.startsWith("gsk_") && !key.startsWith("AIza") && !key.startsWith("sk-ant-") && !key.startsWith("sk-proj-")) {
|
|
590
|
+
return void 0;
|
|
591
|
+
}
|
|
592
|
+
return key;
|
|
593
|
+
}
|
|
594
|
+
async function dispatchChatCompletion(req, apiKeyOverride) {
|
|
595
|
+
const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
|
|
596
|
+
const provider = resolveProvider(req.model);
|
|
597
|
+
try {
|
|
598
|
+
switch (provider) {
|
|
599
|
+
case "groq":
|
|
600
|
+
return await handleGroqRequest(req, effectiveKey);
|
|
601
|
+
case "openai":
|
|
602
|
+
return await handleOpenAIRequest(req, effectiveKey);
|
|
603
|
+
case "gemini":
|
|
604
|
+
return await handleGeminiRequest(req, effectiveKey);
|
|
605
|
+
case "anthropic":
|
|
606
|
+
return await handleAnthropicRequest(req, effectiveKey);
|
|
607
|
+
case "ollama":
|
|
608
|
+
return await handleOllamaRequest(req);
|
|
609
|
+
case "huggingface":
|
|
610
|
+
return await handleHuggingFaceChatRequest(req, effectiveKey);
|
|
611
|
+
default:
|
|
612
|
+
throw new Error(`Unsupported LLM provider for model: ${req.model}`);
|
|
613
|
+
}
|
|
614
|
+
} catch (error) {
|
|
615
|
+
if (/rate[- ]?limit|429|exhausted/i.test(error.message)) {
|
|
616
|
+
const isGroqKey = process.env.GROQ_API_KEY || effectiveKey && effectiveKey.startsWith("gsk_");
|
|
617
|
+
const reqModelLower = req.model.toLowerCase();
|
|
618
|
+
if (isGroqKey && !reqModelLower.includes("llama-3.3-70b")) {
|
|
619
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to secondary Groq model (llama-3.3-70b-versatile)...`);
|
|
620
|
+
try {
|
|
621
|
+
return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: "llama-3.3-70b-versatile" }), effectiveKey);
|
|
622
|
+
} catch (e) {
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
|
|
626
|
+
if (provider !== "gemini" && geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ."))) {
|
|
627
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Google Gemini (gemini-2.5-flash)...`);
|
|
628
|
+
try {
|
|
629
|
+
return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: "gemini-2.5-flash" }), effectiveKey);
|
|
630
|
+
} catch (e) {
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (provider !== "huggingface" && (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY)) {
|
|
634
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Hugging Face (Qwen/Qwen2.5-Coder-32B-Instruct)...`);
|
|
635
|
+
try {
|
|
636
|
+
return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: "Qwen/Qwen2.5-Coder-32B-Instruct" }), effectiveKey);
|
|
637
|
+
} catch (e) {
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
if (provider !== "openai" && process.env.OPENAI_API_KEY) {
|
|
641
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to OpenAI (gpt-4o-mini)...`);
|
|
642
|
+
try {
|
|
643
|
+
return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: "gpt-4o-mini" }), effectiveKey);
|
|
644
|
+
} catch (e) {
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to local Ollama (llama3.2)...`);
|
|
648
|
+
return handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: "llama3.2" }));
|
|
649
|
+
}
|
|
650
|
+
throw error;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
async function dispatchEmbedding(req, apiKeyOverride) {
|
|
654
|
+
const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
|
|
655
|
+
if (req.model.startsWith("hf/") || req.model.startsWith("huggingface/") || req.model.includes("bge-")) {
|
|
656
|
+
try {
|
|
657
|
+
return await handleHuggingFaceEmbedding(req, effectiveKey);
|
|
658
|
+
} catch (err) {
|
|
659
|
+
console.warn("[LLM Gateway] HuggingFace explicit model embedding failed, falling back to default gateway chain:", err);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
|
|
663
|
+
const isGeminiKeyValid = Boolean(geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ.")));
|
|
664
|
+
if (isGeminiKeyValid) {
|
|
665
|
+
try {
|
|
666
|
+
return await handleGeminiEmbedding(req, effectiveKey);
|
|
667
|
+
} catch (err) {
|
|
668
|
+
console.warn("[LLM Gateway] Gemini embedding failed:", err);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if (process.env.OPENAI_API_KEY) {
|
|
672
|
+
try {
|
|
673
|
+
return await handleOpenAIEmbedding(req, effectiveKey);
|
|
674
|
+
} catch (err) {
|
|
675
|
+
console.warn("[LLM Gateway] OpenAI embedding failed:", err);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
if (process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN) {
|
|
679
|
+
try {
|
|
680
|
+
return await handleHuggingFaceEmbedding(req, effectiveKey);
|
|
681
|
+
} catch (err) {
|
|
682
|
+
console.warn("[LLM Gateway] HuggingFace fallback embedding failed:", err);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return handleGeminiEmbedding(req, effectiveKey);
|
|
686
|
+
}
|
|
687
|
+
var SUPPORTED_MODELS;
|
|
688
|
+
var init_router = __esm({
|
|
689
|
+
"../../services/llm-gateway/router.ts"() {
|
|
690
|
+
"use strict";
|
|
691
|
+
init_groq();
|
|
692
|
+
init_openai();
|
|
693
|
+
init_gemini();
|
|
694
|
+
init_huggingface();
|
|
695
|
+
init_anthropic();
|
|
696
|
+
init_ollama();
|
|
697
|
+
SUPPORTED_MODELS = [
|
|
698
|
+
{ id: "groq/llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
|
|
699
|
+
{ id: "llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
|
|
700
|
+
{ id: "groq/llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
|
|
701
|
+
{ id: "llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
|
|
702
|
+
{ id: "gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
|
|
703
|
+
{ id: "openai/gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
|
|
704
|
+
{ id: "gpt-4o", object: "model", created: 17e8, owned_by: "openai" },
|
|
705
|
+
{ id: "gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
|
|
706
|
+
{ id: "google/gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
|
|
707
|
+
{ id: "claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
|
|
708
|
+
{ id: "anthropic/claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
|
|
709
|
+
{ id: "text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
|
|
710
|
+
{ id: "google/text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
|
|
711
|
+
{ id: "BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
|
|
712
|
+
{ id: "huggingface/BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
|
|
713
|
+
{ id: "groq/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
|
|
714
|
+
{ id: "qwen/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
|
|
715
|
+
{ id: "qwen/qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
|
|
716
|
+
{ id: "qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
|
|
717
|
+
{ id: "ollama/llama3.2", object: "model", created: 17e8, owned_by: "ollama" }
|
|
718
|
+
];
|
|
719
|
+
if (typeof globalThis !== "undefined") {
|
|
720
|
+
const _g2 = globalThis;
|
|
721
|
+
_g2.__retrivoraDispatchChat = dispatchChatCompletion;
|
|
722
|
+
_g2.__retrivoraDispatchEmbedding = dispatchEmbedding;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
|
|
124
727
|
// src/providers/vectordb/BaseVectorProvider.ts
|
|
125
728
|
var BaseVectorProvider;
|
|
126
729
|
var init_BaseVectorProvider = __esm({
|
|
@@ -3976,6 +4579,17 @@ var VECTOR_PROFILES = {
|
|
|
3976
4579
|
};
|
|
3977
4580
|
|
|
3978
4581
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4582
|
+
function extractContent(obj) {
|
|
4583
|
+
var _a2, _b, _c;
|
|
4584
|
+
if (!obj || typeof obj !== "object") return void 0;
|
|
4585
|
+
const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
|
|
4586
|
+
if (!choice) return void 0;
|
|
4587
|
+
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4588
|
+
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
4589
|
+
if (typeof choice.text === "string") return choice.text;
|
|
4590
|
+
if (typeof choice.content === "string") return choice.content;
|
|
4591
|
+
return void 0;
|
|
4592
|
+
}
|
|
3979
4593
|
var UniversalLLMAdapter = class {
|
|
3980
4594
|
constructor(config) {
|
|
3981
4595
|
var _a2, _b, _c, _d, _e, _f, _g2, _h;
|
|
@@ -4007,7 +4621,7 @@ var UniversalLLMAdapter = class {
|
|
|
4007
4621
|
});
|
|
4008
4622
|
}
|
|
4009
4623
|
async chat(messages, context) {
|
|
4010
|
-
var _a2, _b, _c
|
|
4624
|
+
var _a2, _b, _c;
|
|
4011
4625
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
4012
4626
|
const formattedMessages = [
|
|
4013
4627
|
{ role: "system", content: `${this.systemPrompt}
|
|
@@ -4035,25 +4649,41 @@ ${context != null ? context : "None"}` },
|
|
|
4035
4649
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4036
4650
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4037
4651
|
const _g2 = globalThis;
|
|
4038
|
-
|
|
4652
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4653
|
+
if (typeof dispatch !== "function") {
|
|
4039
4654
|
try {
|
|
4040
|
-
const
|
|
4655
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4656
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4657
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4658
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4659
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4660
|
+
}
|
|
4661
|
+
} catch (e) {
|
|
4662
|
+
}
|
|
4663
|
+
}
|
|
4664
|
+
if (typeof dispatch === "function") {
|
|
4665
|
+
try {
|
|
4666
|
+
const res = await dispatch({
|
|
4041
4667
|
model: this.model,
|
|
4042
4668
|
messages: formattedMessages,
|
|
4043
4669
|
max_tokens: this.maxTokens,
|
|
4044
4670
|
temperature: this.temperature
|
|
4045
4671
|
}, this.apiKey);
|
|
4046
|
-
|
|
4047
|
-
|
|
4672
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4673
|
+
if (content !== void 0) {
|
|
4674
|
+
return content;
|
|
4048
4675
|
}
|
|
4676
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
|
|
4049
4677
|
} catch (dispatchErr) {
|
|
4050
4678
|
throw dispatchErr;
|
|
4051
4679
|
}
|
|
4680
|
+
} else {
|
|
4681
|
+
throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
|
|
4052
4682
|
}
|
|
4053
4683
|
}
|
|
4054
4684
|
const { data } = await this.http.post(path2, payload);
|
|
4055
|
-
const extractPath = (
|
|
4056
|
-
const result = resolvePath(data, extractPath);
|
|
4685
|
+
const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
|
|
4686
|
+
const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
|
|
4057
4687
|
if (result === void 0) {
|
|
4058
4688
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
4059
4689
|
}
|
|
@@ -4066,7 +4696,7 @@ ${context != null ? context : "None"}` },
|
|
|
4066
4696
|
*/
|
|
4067
4697
|
chatStream(messages, context) {
|
|
4068
4698
|
return __asyncGenerator(this, null, function* () {
|
|
4069
|
-
var _a2, _b, _c, _d, _e
|
|
4699
|
+
var _a2, _b, _c, _d, _e;
|
|
4070
4700
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
4071
4701
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4072
4702
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
@@ -4100,10 +4730,22 @@ ${context != null ? context : "None"}` },
|
|
|
4100
4730
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4101
4731
|
let streamBody = null;
|
|
4102
4732
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4103
|
-
const
|
|
4104
|
-
|
|
4733
|
+
const _g2 = globalThis;
|
|
4734
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4735
|
+
if (typeof dispatch !== "function") {
|
|
4736
|
+
try {
|
|
4737
|
+
const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
|
|
4738
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4739
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4740
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4741
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4742
|
+
}
|
|
4743
|
+
} catch (e) {
|
|
4744
|
+
}
|
|
4745
|
+
}
|
|
4746
|
+
if (typeof dispatch === "function") {
|
|
4105
4747
|
try {
|
|
4106
|
-
const res = yield new __await(
|
|
4748
|
+
const res = yield new __await(dispatch({
|
|
4107
4749
|
model: this.model,
|
|
4108
4750
|
messages: formattedMessages,
|
|
4109
4751
|
max_tokens: this.maxTokens,
|
|
@@ -4112,13 +4754,19 @@ ${context != null ? context : "None"}` },
|
|
|
4112
4754
|
}, this.apiKey));
|
|
4113
4755
|
if (res == null ? void 0 : res.stream) {
|
|
4114
4756
|
streamBody = res.stream;
|
|
4115
|
-
} else
|
|
4116
|
-
|
|
4117
|
-
|
|
4757
|
+
} else {
|
|
4758
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4759
|
+
if (content !== void 0) {
|
|
4760
|
+
yield content;
|
|
4761
|
+
return;
|
|
4762
|
+
}
|
|
4763
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
|
|
4118
4764
|
}
|
|
4119
4765
|
} catch (dispatchErr) {
|
|
4120
4766
|
throw dispatchErr;
|
|
4121
4767
|
}
|
|
4768
|
+
} else {
|
|
4769
|
+
throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
|
|
4122
4770
|
}
|
|
4123
4771
|
}
|
|
4124
4772
|
if (!streamBody) {
|
|
@@ -4145,14 +4793,14 @@ ${context != null ? context : "None"}` },
|
|
|
4145
4793
|
if (done) break;
|
|
4146
4794
|
buffer += decoder.decode(value, { stream: true });
|
|
4147
4795
|
const lines = buffer.split("\n");
|
|
4148
|
-
buffer = (
|
|
4796
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4149
4797
|
for (const line of lines) {
|
|
4150
4798
|
const trimmed = line.trim();
|
|
4151
4799
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4152
4800
|
if (!trimmed.startsWith("data:")) continue;
|
|
4153
4801
|
try {
|
|
4154
4802
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4155
|
-
const text = resolvePath(json, extractPath);
|
|
4803
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4156
4804
|
if (text && typeof text === "string") yield text;
|
|
4157
4805
|
} catch (e) {
|
|
4158
4806
|
}
|
|
@@ -4162,7 +4810,7 @@ ${context != null ? context : "None"}` },
|
|
|
4162
4810
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4163
4811
|
try {
|
|
4164
4812
|
const json = JSON.parse(jsonStr);
|
|
4165
|
-
const text = resolvePath(json, extractPath);
|
|
4813
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4166
4814
|
if (text && typeof text === "string") yield text;
|
|
4167
4815
|
} catch (e) {
|
|
4168
4816
|
}
|
|
@@ -4190,18 +4838,33 @@ ${context != null ? context : "None"}` },
|
|
|
4190
4838
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4191
4839
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4192
4840
|
const _g2 = globalThis;
|
|
4193
|
-
|
|
4841
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4842
|
+
if (typeof dispatch !== "function") {
|
|
4194
4843
|
try {
|
|
4195
|
-
const
|
|
4844
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4845
|
+
if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
|
|
4846
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4847
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4848
|
+
dispatch = gateway.dispatchEmbedding;
|
|
4849
|
+
}
|
|
4850
|
+
} catch (e) {
|
|
4851
|
+
}
|
|
4852
|
+
}
|
|
4853
|
+
if (typeof dispatch === "function") {
|
|
4854
|
+
try {
|
|
4855
|
+
const res = await dispatch({
|
|
4196
4856
|
model: this.model,
|
|
4197
4857
|
input: text
|
|
4198
4858
|
}, this.apiKey);
|
|
4199
4859
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4200
4860
|
return res.data[0].embedding;
|
|
4201
4861
|
}
|
|
4862
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4202
4863
|
} catch (dispatchErr) {
|
|
4203
4864
|
throw dispatchErr;
|
|
4204
4865
|
}
|
|
4866
|
+
} else {
|
|
4867
|
+
throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
|
|
4205
4868
|
}
|
|
4206
4869
|
}
|
|
4207
4870
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -7063,7 +7726,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7063
7726
|
}
|
|
7064
7727
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
7065
7728
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
7066
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null)
|
|
7729
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
7067
7730
|
return {
|
|
7068
7731
|
type: "product_carousel",
|
|
7069
7732
|
title: "Recommended Products",
|
|
@@ -7443,7 +8106,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7443
8106
|
return fieldCount.size > 2;
|
|
7444
8107
|
}
|
|
7445
8108
|
static profileData(data) {
|
|
7446
|
-
const records = data.map((item) => {
|
|
8109
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
8110
|
+
var _a2, _b;
|
|
7447
8111
|
const fields2 = {};
|
|
7448
8112
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7449
8113
|
const primitive = this.toPrimitive(value);
|
|
@@ -7452,8 +8116,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7452
8116
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7453
8117
|
return {
|
|
7454
8118
|
id: item.id,
|
|
7455
|
-
content: item.content,
|
|
7456
|
-
score: item.score,
|
|
8119
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
8120
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7457
8121
|
fields: fields2,
|
|
7458
8122
|
source: item
|
|
7459
8123
|
};
|
|
@@ -8556,7 +9220,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8556
9220
|
*/
|
|
8557
9221
|
askStreamInternal(_0) {
|
|
8558
9222
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8559
|
-
var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B
|
|
9223
|
+
var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
8560
9224
|
yield new __await(this.initialize());
|
|
8561
9225
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8562
9226
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8599,8 +9263,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8599
9263
|
const graphData = (strategyResult === "graph" || strategyResult === "both") && this.graphDB && ((_l = this.config.rag) == null ? void 0 : _l.useGraphRetrieval) ? yield new __await(this.graphDB.query(searchQuery)) : void 0;
|
|
8600
9264
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8601
9265
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8602
|
-
const wantsExhaustiveList =
|
|
8603
|
-
const retrievalLimit =
|
|
9266
|
+
const wantsExhaustiveList = true;
|
|
9267
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
8604
9268
|
const rawSources = ((strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : []).filter((s) => Boolean(s && typeof s === "object"));
|
|
8605
9269
|
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
8606
9270
|
rawCount: rawSources.length,
|
|
@@ -8624,40 +9288,29 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8624
9288
|
var _a3;
|
|
8625
9289
|
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
8626
9290
|
});
|
|
8627
|
-
const rerankLimit =
|
|
9291
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8628
9292
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8629
9293
|
if (!hasNumericPredicates && useReranking) {
|
|
8630
9294
|
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8631
|
-
} else if (!wantsExhaustiveList) {
|
|
8632
|
-
fullSources = fullSources.slice(0, topK);
|
|
8633
9295
|
}
|
|
8634
9296
|
const rerankMs = performance.now() - rerankStart;
|
|
8635
|
-
|
|
9297
|
+
const totalCount = fullSources.length;
|
|
9298
|
+
const promptSources = fullSources.slice(0, 15);
|
|
9299
|
+
let context = promptSources.length ? `[SEARCH SUMMARY: Found ${totalCount} matching record(s) out of ${rawSources.length} total resources searched in database. Context includes top ${promptSources.length} relevant records]
|
|
9300
|
+
|
|
9301
|
+
` + promptSources.map((m, i) => {
|
|
8636
9302
|
var _a3;
|
|
8637
9303
|
return `[Source ${i + 1}]
|
|
8638
9304
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8639
9305
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8640
|
-
let displayCount = 15;
|
|
8641
|
-
if (hasMetadataFilter) {
|
|
8642
|
-
displayCount = fullSources.length;
|
|
8643
|
-
} else {
|
|
8644
|
-
const baseThreshold = Math.max(scoreThreshold, 0.4);
|
|
8645
|
-
const highlyRelevant = fullSources.filter((m) => {
|
|
8646
|
-
var _a3;
|
|
8647
|
-
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= baseThreshold;
|
|
8648
|
-
});
|
|
8649
|
-
displayCount = Math.max(highlyRelevant.length, topK);
|
|
8650
|
-
if (displayCount > 15) {
|
|
8651
|
-
displayCount = 15;
|
|
8652
|
-
}
|
|
8653
|
-
}
|
|
8654
9306
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8655
9307
|
var _a3, _b2;
|
|
8656
9308
|
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8657
|
-
})
|
|
9309
|
+
});
|
|
8658
9310
|
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
8659
9311
|
count: sources.length,
|
|
8660
|
-
|
|
9312
|
+
totalRawCount: rawSources.length,
|
|
9313
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
8661
9314
|
var _a3;
|
|
8662
9315
|
return {
|
|
8663
9316
|
rank: idx + 1,
|
|
@@ -8857,7 +9510,7 @@ ${context}`;
|
|
|
8857
9510
|
}
|
|
8858
9511
|
yield fullReply;
|
|
8859
9512
|
}
|
|
8860
|
-
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true
|
|
9513
|
+
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
|
|
8861
9514
|
if (runHallucination) {
|
|
8862
9515
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8863
9516
|
}
|
|
@@ -8866,7 +9519,7 @@ ${context}`;
|
|
|
8866
9519
|
const latency = {
|
|
8867
9520
|
embedMs: Math.round(embedMs),
|
|
8868
9521
|
retrieveMs: Math.round(retrieveMs),
|
|
8869
|
-
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((
|
|
9522
|
+
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
|
|
8870
9523
|
generateMs: Math.round(generateMs),
|
|
8871
9524
|
totalMs: Math.round(totalMs)
|
|
8872
9525
|
};
|
|
@@ -8879,7 +9532,7 @@ ${context}`;
|
|
|
8879
9532
|
totalTokens: promptTokens + completionTokens,
|
|
8880
9533
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8881
9534
|
};
|
|
8882
|
-
const awaitHallucination = ((
|
|
9535
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8883
9536
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8884
9537
|
uiTransformationPromise,
|
|
8885
9538
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8908,10 +9561,10 @@ ${context}`;
|
|
|
8908
9561
|
hallucinationReason: hScore.reason
|
|
8909
9562
|
} : {});
|
|
8910
9563
|
const trace = buildTrace(hallucinationResult);
|
|
8911
|
-
const isTelemetryActive = (
|
|
9564
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8912
9565
|
if (isTelemetryActive) {
|
|
8913
9566
|
const defaultUrl = process.env.NODE_ENV === "development" && !process.env.TELEMETRY_URL && !process.env.NEXT_PUBLIC_TELEMETRY_URL ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry";
|
|
8914
|
-
const telemetryUrl = ((
|
|
9567
|
+
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
8915
9568
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8916
9569
|
(async () => {
|
|
8917
9570
|
try {
|
|
@@ -8970,9 +9623,8 @@ ${context}`;
|
|
|
8970
9623
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8971
9624
|
);
|
|
8972
9625
|
}
|
|
8973
|
-
const
|
|
8974
|
-
|
|
8975
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9626
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9627
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8976
9628
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8977
9629
|
}
|
|
8978
9630
|
try {
|