@retrivora-ai/rag-engine 2.0.6 → 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 +863 -94
- package/dist/handlers/index.mjs +863 -94
- package/dist/index.js +84 -26
- package/dist/index.mjs +84 -26
- package/dist/server.js +863 -94
- package/dist/server.mjs +863 -94
- package/package.json +1 -1
- package/src/core/Pipeline.ts +67 -47
- package/src/core/QueryProcessor.ts +3 -3
- package/src/llm/providers/UniversalLLMAdapter.ts +86 -26
- package/src/rag/Reranker.ts +2 -2
- package/src/rendering/IntentClassifier.ts +1 -1
- package/src/rendering/RendererRegistry.ts +1 -1
- package/src/utils/ProductExtractor.ts +1 -1
- package/src/utils/UITransformer.ts +66 -22
package/dist/handlers/index.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({
|
|
@@ -3876,6 +4479,17 @@ var LLM_PROFILES = {
|
|
|
3876
4479
|
};
|
|
3877
4480
|
|
|
3878
4481
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4482
|
+
function extractContent(obj) {
|
|
4483
|
+
var _a2, _b, _c;
|
|
4484
|
+
if (!obj || typeof obj !== "object") return void 0;
|
|
4485
|
+
const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
|
|
4486
|
+
if (!choice) return void 0;
|
|
4487
|
+
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4488
|
+
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
4489
|
+
if (typeof choice.text === "string") return choice.text;
|
|
4490
|
+
if (typeof choice.content === "string") return choice.content;
|
|
4491
|
+
return void 0;
|
|
4492
|
+
}
|
|
3879
4493
|
var UniversalLLMAdapter = class {
|
|
3880
4494
|
constructor(config) {
|
|
3881
4495
|
var _a2, _b, _c, _d, _e, _f, _g2, _h;
|
|
@@ -3907,7 +4521,7 @@ var UniversalLLMAdapter = class {
|
|
|
3907
4521
|
});
|
|
3908
4522
|
}
|
|
3909
4523
|
async chat(messages, context) {
|
|
3910
|
-
var _a2, _b, _c
|
|
4524
|
+
var _a2, _b, _c;
|
|
3911
4525
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3912
4526
|
const formattedMessages = [
|
|
3913
4527
|
{ role: "system", content: `${this.systemPrompt}
|
|
@@ -3934,25 +4548,42 @@ ${context != null ? context : "None"}` },
|
|
|
3934
4548
|
}
|
|
3935
4549
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3936
4550
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
4551
|
+
const _g2 = globalThis;
|
|
4552
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4553
|
+
if (typeof dispatch !== "function") {
|
|
4554
|
+
try {
|
|
4555
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4556
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4557
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4558
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4559
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4560
|
+
}
|
|
4561
|
+
} catch (e) {
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
if (typeof dispatch === "function") {
|
|
4565
|
+
try {
|
|
4566
|
+
const res = await dispatch({
|
|
3941
4567
|
model: this.model,
|
|
3942
4568
|
messages: formattedMessages,
|
|
3943
4569
|
max_tokens: this.maxTokens,
|
|
3944
4570
|
temperature: this.temperature
|
|
3945
4571
|
}, this.apiKey);
|
|
3946
|
-
|
|
3947
|
-
|
|
4572
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4573
|
+
if (content !== void 0) {
|
|
4574
|
+
return content;
|
|
3948
4575
|
}
|
|
4576
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
|
|
4577
|
+
} catch (dispatchErr) {
|
|
4578
|
+
throw dispatchErr;
|
|
3949
4579
|
}
|
|
3950
|
-
}
|
|
4580
|
+
} else {
|
|
4581
|
+
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.`);
|
|
3951
4582
|
}
|
|
3952
4583
|
}
|
|
3953
4584
|
const { data } = await this.http.post(path2, payload);
|
|
3954
|
-
const extractPath = (
|
|
3955
|
-
const result = resolvePath(data, extractPath);
|
|
4585
|
+
const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
|
|
4586
|
+
const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
|
|
3956
4587
|
if (result === void 0) {
|
|
3957
4588
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
3958
4589
|
}
|
|
@@ -3965,7 +4596,7 @@ ${context != null ? context : "None"}` },
|
|
|
3965
4596
|
*/
|
|
3966
4597
|
chatStream(messages, context) {
|
|
3967
4598
|
return __asyncGenerator(this, null, function* () {
|
|
3968
|
-
var _a2, _b, _c, _d, _e
|
|
4599
|
+
var _a2, _b, _c, _d, _e;
|
|
3969
4600
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3970
4601
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
3971
4602
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
@@ -3999,10 +4630,22 @@ ${context != null ? context : "None"}` },
|
|
|
3999
4630
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4000
4631
|
let streamBody = null;
|
|
4001
4632
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4633
|
+
const _g2 = globalThis;
|
|
4634
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4635
|
+
if (typeof dispatch !== "function") {
|
|
4636
|
+
try {
|
|
4637
|
+
const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
|
|
4638
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4639
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4640
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4641
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4642
|
+
}
|
|
4643
|
+
} catch (e) {
|
|
4644
|
+
}
|
|
4645
|
+
}
|
|
4646
|
+
if (typeof dispatch === "function") {
|
|
4647
|
+
try {
|
|
4648
|
+
const res = yield new __await(dispatch({
|
|
4006
4649
|
model: this.model,
|
|
4007
4650
|
messages: formattedMessages,
|
|
4008
4651
|
max_tokens: this.maxTokens,
|
|
@@ -4011,12 +4654,19 @@ ${context != null ? context : "None"}` },
|
|
|
4011
4654
|
}, this.apiKey));
|
|
4012
4655
|
if (res == null ? void 0 : res.stream) {
|
|
4013
4656
|
streamBody = res.stream;
|
|
4014
|
-
} else
|
|
4015
|
-
|
|
4016
|
-
|
|
4657
|
+
} else {
|
|
4658
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4659
|
+
if (content !== void 0) {
|
|
4660
|
+
yield content;
|
|
4661
|
+
return;
|
|
4662
|
+
}
|
|
4663
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
|
|
4017
4664
|
}
|
|
4665
|
+
} catch (dispatchErr) {
|
|
4666
|
+
throw dispatchErr;
|
|
4018
4667
|
}
|
|
4019
|
-
}
|
|
4668
|
+
} else {
|
|
4669
|
+
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.`);
|
|
4020
4670
|
}
|
|
4021
4671
|
}
|
|
4022
4672
|
if (!streamBody) {
|
|
@@ -4043,14 +4693,14 @@ ${context != null ? context : "None"}` },
|
|
|
4043
4693
|
if (done) break;
|
|
4044
4694
|
buffer += decoder.decode(value, { stream: true });
|
|
4045
4695
|
const lines = buffer.split("\n");
|
|
4046
|
-
buffer = (
|
|
4696
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4047
4697
|
for (const line of lines) {
|
|
4048
4698
|
const trimmed = line.trim();
|
|
4049
4699
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4050
4700
|
if (!trimmed.startsWith("data:")) continue;
|
|
4051
4701
|
try {
|
|
4052
4702
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4053
|
-
const text = resolvePath(json, extractPath);
|
|
4703
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4054
4704
|
if (text && typeof text === "string") yield text;
|
|
4055
4705
|
} catch (e) {
|
|
4056
4706
|
}
|
|
@@ -4060,7 +4710,7 @@ ${context != null ? context : "None"}` },
|
|
|
4060
4710
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4061
4711
|
try {
|
|
4062
4712
|
const json = JSON.parse(jsonStr);
|
|
4063
|
-
const text = resolvePath(json, extractPath);
|
|
4713
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4064
4714
|
if (text && typeof text === "string") yield text;
|
|
4065
4715
|
} catch (e) {
|
|
4066
4716
|
}
|
|
@@ -4087,18 +4737,34 @@ ${context != null ? context : "None"}` },
|
|
|
4087
4737
|
}
|
|
4088
4738
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4089
4739
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4740
|
+
const _g2 = globalThis;
|
|
4741
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4742
|
+
if (typeof dispatch !== "function") {
|
|
4743
|
+
try {
|
|
4744
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4745
|
+
if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
|
|
4746
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4747
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4748
|
+
dispatch = gateway.dispatchEmbedding;
|
|
4749
|
+
}
|
|
4750
|
+
} catch (e) {
|
|
4751
|
+
}
|
|
4752
|
+
}
|
|
4753
|
+
if (typeof dispatch === "function") {
|
|
4754
|
+
try {
|
|
4755
|
+
const res = await dispatch({
|
|
4094
4756
|
model: this.model,
|
|
4095
4757
|
input: text
|
|
4096
4758
|
}, this.apiKey);
|
|
4097
4759
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4098
4760
|
return res.data[0].embedding;
|
|
4099
4761
|
}
|
|
4762
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4763
|
+
} catch (dispatchErr) {
|
|
4764
|
+
throw dispatchErr;
|
|
4100
4765
|
}
|
|
4101
|
-
}
|
|
4766
|
+
} else {
|
|
4767
|
+
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.`);
|
|
4102
4768
|
}
|
|
4103
4769
|
}
|
|
4104
4770
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -4691,7 +5357,8 @@ var Reranker = class {
|
|
|
4691
5357
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
4692
5358
|
}
|
|
4693
5359
|
const scoredMatches = matches.map((match) => {
|
|
4694
|
-
|
|
5360
|
+
var _a2;
|
|
5361
|
+
const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
|
|
4695
5362
|
let keywordScore = 0;
|
|
4696
5363
|
keywords.forEach((keyword) => {
|
|
4697
5364
|
if (contentLower.includes(keyword)) {
|
|
@@ -4712,7 +5379,10 @@ var Reranker = class {
|
|
|
4712
5379
|
[{ role: "user", content: `Query: "${query}"
|
|
4713
5380
|
|
|
4714
5381
|
Documents:
|
|
4715
|
-
${topN.map((m, i) =>
|
|
5382
|
+
${topN.map((m, i) => {
|
|
5383
|
+
var _a2;
|
|
5384
|
+
return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
|
|
5385
|
+
}).join("\n")}` }],
|
|
4716
5386
|
"",
|
|
4717
5387
|
{
|
|
4718
5388
|
systemPrompt: 'You are a relevance ranking expert. Given the user query and a list of retrieved document chunks, rank the chunks by relevance to the query. Return the result as a comma-separated list of document indices in order of relevance, from most relevant to least relevant. Use the indices provided in brackets like [0], [1], etc. Only return the indices (e.g., "2,0,1"), nothing else. Do not include brackets in the output.',
|
|
@@ -5877,10 +6547,10 @@ Return ONLY 'vector', 'graph', or 'both'. No explanation.`;
|
|
|
5877
6547
|
"",
|
|
5878
6548
|
{ temperature: 0, maxTokens: 10 }
|
|
5879
6549
|
);
|
|
5880
|
-
const cleanResponse = response.trim().toLowerCase();
|
|
5881
|
-
if (cleanResponse.includes("vector")) return "vector";
|
|
5882
|
-
if (cleanResponse.includes("graph")) return "graph";
|
|
6550
|
+
const cleanResponse = (response != null ? response : "").trim().toLowerCase();
|
|
5883
6551
|
if (cleanResponse.includes("both")) return "both";
|
|
6552
|
+
if (cleanResponse.includes("graph")) return "graph";
|
|
6553
|
+
if (cleanResponse.includes("vector")) return "vector";
|
|
5884
6554
|
} catch (error) {
|
|
5885
6555
|
console.warn("[QueryProcessor] LLM strategy classification failed, falling back to keywords:", error);
|
|
5886
6556
|
}
|
|
@@ -6054,7 +6724,10 @@ var IntentClassifier = class {
|
|
|
6054
6724
|
hasCategoricalFields = catKeys.size > 0;
|
|
6055
6725
|
numericFieldCount = numericKeys.size;
|
|
6056
6726
|
categoricalFieldCount = catKeys.size;
|
|
6057
|
-
if (productKeyMatches >= 2 || docs.some((d) =>
|
|
6727
|
+
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6728
|
+
var _a2, _b;
|
|
6729
|
+
return ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").toLowerCase().includes("price") || ((_b = d == null ? void 0 : d.content) != null ? _b : "").toLowerCase().includes("brand");
|
|
6730
|
+
})) {
|
|
6058
6731
|
isProductLike = true;
|
|
6059
6732
|
}
|
|
6060
6733
|
}
|
|
@@ -6334,7 +7007,10 @@ var TextRendererStrategy = class {
|
|
|
6334
7007
|
return { type: "text", title, data: { content: data } };
|
|
6335
7008
|
}
|
|
6336
7009
|
const docs = Array.isArray(data) ? data : [];
|
|
6337
|
-
const text = docs.map((d) =>
|
|
7010
|
+
const text = docs.map((d) => {
|
|
7011
|
+
var _a2;
|
|
7012
|
+
return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
|
|
7013
|
+
}).join("\n\n");
|
|
6338
7014
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6339
7015
|
}
|
|
6340
7016
|
};
|
|
@@ -6583,6 +7259,19 @@ var UITransformer = class _UITransformer {
|
|
|
6583
7259
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6584
7260
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6585
7261
|
}
|
|
7262
|
+
console.log("[UITransformer.transform] Processing retrievedData:", {
|
|
7263
|
+
userQuery,
|
|
7264
|
+
retrievedCount: retrievedData.length,
|
|
7265
|
+
sample: retrievedData.slice(0, 2).map((item) => {
|
|
7266
|
+
var _a3;
|
|
7267
|
+
return {
|
|
7268
|
+
id: item == null ? void 0 : item.id,
|
|
7269
|
+
contentType: typeof (item == null ? void 0 : item.content),
|
|
7270
|
+
contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
|
|
7271
|
+
metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
|
|
7272
|
+
};
|
|
7273
|
+
})
|
|
7274
|
+
});
|
|
6586
7275
|
const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
|
|
6587
7276
|
const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
|
|
6588
7277
|
const profile = this.profileData(filteredData);
|
|
@@ -6923,7 +7612,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
6923
7612
|
}
|
|
6924
7613
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
6925
7614
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
6926
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null)
|
|
7615
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
6927
7616
|
return {
|
|
6928
7617
|
type: "product_carousel",
|
|
6929
7618
|
title: "Recommended Products",
|
|
@@ -7072,7 +7761,10 @@ ${schemaProfileText}` : ""}`;
|
|
|
7072
7761
|
type: "radar_chart",
|
|
7073
7762
|
title: "Product Comparison",
|
|
7074
7763
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7075
|
-
data: radarData.length > 0 ? radarData : data.map((d) =>
|
|
7764
|
+
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7765
|
+
var _a2;
|
|
7766
|
+
return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
|
|
7767
|
+
})
|
|
7076
7768
|
};
|
|
7077
7769
|
}
|
|
7078
7770
|
static transformToTable(data, query = "") {
|
|
@@ -7089,7 +7781,10 @@ ${schemaProfileText}` : ""}`;
|
|
|
7089
7781
|
static transformToText(data) {
|
|
7090
7782
|
return this.createTextResponse(
|
|
7091
7783
|
"Retrieved Context",
|
|
7092
|
-
data.map((item) =>
|
|
7784
|
+
data.map((item) => {
|
|
7785
|
+
var _a2;
|
|
7786
|
+
return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
|
|
7787
|
+
}).join("\n\n"),
|
|
7093
7788
|
`Found ${data.length} relevant results`
|
|
7094
7789
|
);
|
|
7095
7790
|
}
|
|
@@ -7250,6 +7945,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7250
7945
|
return productTerms && productAction && !nonProductEntityTerms;
|
|
7251
7946
|
}
|
|
7252
7947
|
static isProductData(item) {
|
|
7948
|
+
if (!item) return false;
|
|
7253
7949
|
const content = (item.content || "").toLowerCase();
|
|
7254
7950
|
const productKeywords = [
|
|
7255
7951
|
"product",
|
|
@@ -7296,7 +7992,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7296
7992
|
return fieldCount.size > 2;
|
|
7297
7993
|
}
|
|
7298
7994
|
static profileData(data) {
|
|
7299
|
-
const records = data.map((item) => {
|
|
7995
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7996
|
+
var _a2, _b;
|
|
7300
7997
|
const fields2 = {};
|
|
7301
7998
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7302
7999
|
const primitive = this.toPrimitive(value);
|
|
@@ -7305,8 +8002,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7305
8002
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7306
8003
|
return {
|
|
7307
8004
|
id: item.id,
|
|
7308
|
-
content: item.content,
|
|
7309
|
-
score: item.score,
|
|
8005
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
8006
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7310
8007
|
fields: fields2,
|
|
7311
8008
|
source: item
|
|
7312
8009
|
};
|
|
@@ -7508,12 +8205,12 @@ ${schemaProfileText}` : ""}`;
|
|
|
7508
8205
|
}
|
|
7509
8206
|
static extractTimeSeriesData(data) {
|
|
7510
8207
|
return data.map((item) => {
|
|
7511
|
-
var _a2, _b, _c, _d, _e;
|
|
8208
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
7512
8209
|
const meta = item.metadata || {};
|
|
7513
8210
|
return {
|
|
7514
8211
|
timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7515
8212
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7516
|
-
label: (
|
|
8213
|
+
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7517
8214
|
};
|
|
7518
8215
|
});
|
|
7519
8216
|
}
|
|
@@ -7627,7 +8324,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7627
8324
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7628
8325
|
}
|
|
7629
8326
|
static resolveTableCellValue(item, column) {
|
|
7630
|
-
|
|
8327
|
+
var _a2, _b, _c;
|
|
8328
|
+
if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
|
|
7631
8329
|
const meta = item.metadata || {};
|
|
7632
8330
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7633
8331
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -7638,9 +8336,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7638
8336
|
}
|
|
7639
8337
|
const aliasValue = this.resolveAliasedTableCell(meta, column);
|
|
7640
8338
|
if (aliasValue !== void 0) return this.toDisplayValue(aliasValue);
|
|
7641
|
-
const contentValue = this.extractContentFieldValue(item.content, column);
|
|
8339
|
+
const contentValue = this.extractContentFieldValue((_b = item == null ? void 0 : item.content) != null ? _b : "", column);
|
|
7642
8340
|
if (contentValue !== null) return contentValue;
|
|
7643
|
-
const aliasContentValue = this.extractAliasedContentFieldValue(item.content, column);
|
|
8341
|
+
const aliasContentValue = this.extractAliasedContentFieldValue((_c = item == null ? void 0 : item.content) != null ? _c : "", column);
|
|
7644
8342
|
return aliasContentValue != null ? aliasContentValue : "";
|
|
7645
8343
|
}
|
|
7646
8344
|
static resolveAliasedTableCell(meta, column) {
|
|
@@ -7690,6 +8388,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7690
8388
|
return { inStockCount: inStock, outOfStockCount: outOfStock };
|
|
7691
8389
|
}
|
|
7692
8390
|
static determineStockStatus(item) {
|
|
8391
|
+
if (!item) return true;
|
|
7693
8392
|
const meta = item.metadata || {};
|
|
7694
8393
|
const stockValue = resolveMetadataValue(meta, "stock");
|
|
7695
8394
|
if (stockValue !== void 0) {
|
|
@@ -7735,35 +8434,64 @@ ${schemaProfileText}` : ""}`;
|
|
|
7735
8434
|
return resolveMetadataValue(meta, uiKey);
|
|
7736
8435
|
}
|
|
7737
8436
|
static extractProductInfo(item, config, trainedSchema) {
|
|
7738
|
-
var _a2;
|
|
8437
|
+
var _a2, _b;
|
|
8438
|
+
if (!item) return null;
|
|
7739
8439
|
const meta = item.metadata || {};
|
|
8440
|
+
const content = item.content || "";
|
|
7740
8441
|
const name = this.getDynamicVal(meta, "name", config, trainedSchema);
|
|
7741
8442
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
7742
8443
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
7743
8444
|
const description = this.cleanProductDescription(
|
|
7744
|
-
(_a2 = this.extractProductDescriptionFromContent(
|
|
8445
|
+
(_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
7745
8446
|
);
|
|
7746
8447
|
if (name || this.isProductData(item)) {
|
|
7747
8448
|
let finalName = name ? String(name) : void 0;
|
|
8449
|
+
if (!finalName && content) {
|
|
8450
|
+
const nameMatch = content.match(/(?:Product|Item|Name):\s*([^\n]+)/i);
|
|
8451
|
+
finalName = nameMatch ? nameMatch[1].trim() : (_b = content.split("\n")[0]) == null ? void 0 : _b.substring(0, 60);
|
|
8452
|
+
}
|
|
7748
8453
|
if (!finalName) {
|
|
7749
|
-
|
|
7750
|
-
|
|
8454
|
+
console.warn(
|
|
8455
|
+
`[UITransformer] Unable to read product name from metadata or content for item ${item.id}. Defaulting to 'Unnamed Product'.`,
|
|
8456
|
+
{ metadataKeys: Object.keys(meta), contentLength: content.length }
|
|
8457
|
+
);
|
|
7751
8458
|
}
|
|
7752
8459
|
let finalPrice = typeof price === "number" || typeof price === "string" ? price : void 0;
|
|
7753
|
-
if (!finalPrice) {
|
|
7754
|
-
const priceMatch =
|
|
8460
|
+
if (!finalPrice && content) {
|
|
8461
|
+
const priceMatch = content.match(/(?:Price|Cost):\s*\$?([\d,.]+)/i) || content.match(/\$\s*([\d,.]+)/);
|
|
7755
8462
|
if (priceMatch) finalPrice = priceMatch[1].replace(/,/g, "");
|
|
7756
8463
|
}
|
|
8464
|
+
if (finalPrice === void 0) {
|
|
8465
|
+
console.warn(
|
|
8466
|
+
`[UITransformer] Unable to read product price from metadata or content for item ${item.id}.`,
|
|
8467
|
+
{ metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
|
|
8468
|
+
);
|
|
8469
|
+
}
|
|
7757
8470
|
const imageValue = this.getDynamicVal(meta, "image", config, trainedSchema);
|
|
8471
|
+
if (!imageValue) {
|
|
8472
|
+
console.debug(
|
|
8473
|
+
`[UITransformer] Unable to read product image URL from metadata for item ${item.id}.`
|
|
8474
|
+
);
|
|
8475
|
+
}
|
|
8476
|
+
if (!description) {
|
|
8477
|
+
console.debug(
|
|
8478
|
+
`[UITransformer] Unable to read product description from metadata or content for item ${item.id}.`
|
|
8479
|
+
);
|
|
8480
|
+
}
|
|
7758
8481
|
return {
|
|
7759
8482
|
id: item.id,
|
|
7760
|
-
name: finalName,
|
|
8483
|
+
name: finalName || "Unnamed Product",
|
|
7761
8484
|
price: finalPrice,
|
|
7762
8485
|
image: typeof imageValue === "string" ? imageValue : void 0,
|
|
7763
8486
|
brand: brand ? String(brand) : void 0,
|
|
7764
8487
|
description,
|
|
7765
8488
|
inStock: this.determineStockStatus(item)
|
|
7766
8489
|
};
|
|
8490
|
+
} else {
|
|
8491
|
+
console.warn(
|
|
8492
|
+
`[UITransformer] Item ${item.id} skipped: unable to read name or identify as product data from metadata/content.`,
|
|
8493
|
+
{ metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
|
|
8494
|
+
);
|
|
7767
8495
|
}
|
|
7768
8496
|
return null;
|
|
7769
8497
|
}
|
|
@@ -7848,13 +8576,13 @@ RULES:
|
|
|
7848
8576
|
5. If no relevant data is found, return text: "I cannot answer this question based on the available information."`;
|
|
7849
8577
|
}
|
|
7850
8578
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
7851
|
-
const items = sources.map((s, i) => {
|
|
8579
|
+
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
7852
8580
|
var _a2, _b, _c, _d;
|
|
7853
8581
|
return {
|
|
7854
8582
|
index: i + 1,
|
|
7855
|
-
content: (_b = (_a2 = s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
|
|
7856
|
-
metadata: (_c = s.metadata) != null ? _c : {},
|
|
7857
|
-
score: (_d = s.score) != null ? _d : 0
|
|
8583
|
+
content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
|
|
8584
|
+
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8585
|
+
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
7858
8586
|
};
|
|
7859
8587
|
});
|
|
7860
8588
|
const full = JSON.stringify(items, null, 2);
|
|
@@ -8378,7 +9106,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8378
9106
|
*/
|
|
8379
9107
|
askStreamInternal(_0) {
|
|
8380
9108
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8381
|
-
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
|
|
9109
|
+
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;
|
|
8382
9110
|
yield new __await(this.initialize());
|
|
8383
9111
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8384
9112
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8421,40 +9149,65 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8421
9149
|
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;
|
|
8422
9150
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8423
9151
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8424
|
-
const wantsExhaustiveList =
|
|
8425
|
-
const retrievalLimit =
|
|
8426
|
-
const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
|
|
9152
|
+
const wantsExhaustiveList = true;
|
|
9153
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
9154
|
+
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"));
|
|
9155
|
+
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
9156
|
+
rawCount: rawSources.length,
|
|
9157
|
+
sample: rawSources.slice(0, 2).map((s) => {
|
|
9158
|
+
var _a3;
|
|
9159
|
+
return {
|
|
9160
|
+
id: s == null ? void 0 : s.id,
|
|
9161
|
+
score: s == null ? void 0 : s.score,
|
|
9162
|
+
contentType: typeof (s == null ? void 0 : s.content),
|
|
9163
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9164
|
+
metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
|
|
9165
|
+
};
|
|
9166
|
+
})
|
|
9167
|
+
});
|
|
8427
9168
|
const retrieveEnd = performance.now();
|
|
8428
9169
|
const embedMs = retrieveEnd - embedStart;
|
|
8429
9170
|
const retrieveMs = retrieveEnd - embedStart;
|
|
8430
9171
|
const rerankStart = performance.now();
|
|
8431
|
-
const structuredSources = this.applyStructuredFilters(rawSources, filter);
|
|
8432
|
-
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) =>
|
|
8433
|
-
|
|
9172
|
+
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
9173
|
+
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
9174
|
+
var _a3;
|
|
9175
|
+
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
9176
|
+
});
|
|
9177
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8434
9178
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8435
9179
|
if (!hasNumericPredicates && useReranking) {
|
|
8436
|
-
fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
|
|
8437
|
-
} else if (!wantsExhaustiveList) {
|
|
8438
|
-
fullSources = fullSources.slice(0, topK);
|
|
9180
|
+
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8439
9181
|
}
|
|
8440
9182
|
const rerankMs = performance.now() - rerankStart;
|
|
8441
|
-
|
|
9183
|
+
const totalCount = fullSources.length;
|
|
9184
|
+
const promptSources = fullSources.slice(0, 15);
|
|
9185
|
+
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]
|
|
9186
|
+
|
|
9187
|
+
` + promptSources.map((m, i) => {
|
|
8442
9188
|
var _a3;
|
|
8443
9189
|
return `[Source ${i + 1}]
|
|
8444
9190
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8445
9191
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
}
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
9192
|
+
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
9193
|
+
var _a3, _b2;
|
|
9194
|
+
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
9195
|
+
});
|
|
9196
|
+
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
9197
|
+
count: sources.length,
|
|
9198
|
+
totalRawCount: rawSources.length,
|
|
9199
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
9200
|
+
var _a3;
|
|
9201
|
+
return {
|
|
9202
|
+
rank: idx + 1,
|
|
9203
|
+
id: s == null ? void 0 : s.id,
|
|
9204
|
+
score: s == null ? void 0 : s.score,
|
|
9205
|
+
contentType: typeof (s == null ? void 0 : s.content),
|
|
9206
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9207
|
+
metadata: s == null ? void 0 : s.metadata
|
|
9208
|
+
};
|
|
9209
|
+
})
|
|
9210
|
+
});
|
|
8458
9211
|
if (graphData && graphData.nodes.length > 0) {
|
|
8459
9212
|
const graphContext = graphData.nodes.map(
|
|
8460
9213
|
(n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
|
|
@@ -8480,18 +9233,18 @@ ${context}`;
|
|
|
8480
9233
|
}
|
|
8481
9234
|
yield {
|
|
8482
9235
|
reply: "",
|
|
8483
|
-
sources: sources.map((s) => {
|
|
8484
|
-
var _a3;
|
|
9236
|
+
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
9237
|
+
var _a3, _b2, _c2;
|
|
8485
9238
|
return {
|
|
8486
9239
|
id: s.id,
|
|
8487
|
-
score: s.score,
|
|
8488
|
-
content: s.content,
|
|
8489
|
-
metadata: (
|
|
9240
|
+
score: (_a3 = s.score) != null ? _a3 : 0,
|
|
9241
|
+
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
9242
|
+
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8490
9243
|
namespace: ns
|
|
8491
9244
|
};
|
|
8492
9245
|
})
|
|
8493
9246
|
};
|
|
8494
|
-
const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
|
|
9247
|
+
const allMetadataKeys = Array.from(new Set(sources.filter(Boolean).flatMap((s) => Object.keys((s == null ? void 0 : s.metadata) || {}))));
|
|
8495
9248
|
const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
|
|
8496
9249
|
if (allMetadataKeys.length > 0 && !cachedSchema) {
|
|
8497
9250
|
SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => {
|
|
@@ -8643,7 +9396,7 @@ ${context}`;
|
|
|
8643
9396
|
}
|
|
8644
9397
|
yield fullReply;
|
|
8645
9398
|
}
|
|
8646
|
-
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true
|
|
9399
|
+
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
|
|
8647
9400
|
if (runHallucination) {
|
|
8648
9401
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8649
9402
|
}
|
|
@@ -8652,7 +9405,7 @@ ${context}`;
|
|
|
8652
9405
|
const latency = {
|
|
8653
9406
|
embedMs: Math.round(embedMs),
|
|
8654
9407
|
retrieveMs: Math.round(retrieveMs),
|
|
8655
|
-
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((
|
|
9408
|
+
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
|
|
8656
9409
|
generateMs: Math.round(generateMs),
|
|
8657
9410
|
totalMs: Math.round(totalMs)
|
|
8658
9411
|
};
|
|
@@ -8665,7 +9418,7 @@ ${context}`;
|
|
|
8665
9418
|
totalTokens: promptTokens + completionTokens,
|
|
8666
9419
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8667
9420
|
};
|
|
8668
|
-
const awaitHallucination = ((
|
|
9421
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8669
9422
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8670
9423
|
uiTransformationPromise,
|
|
8671
9424
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8694,10 +9447,10 @@ ${context}`;
|
|
|
8694
9447
|
hallucinationReason: hScore.reason
|
|
8695
9448
|
} : {});
|
|
8696
9449
|
const trace = buildTrace(hallucinationResult);
|
|
8697
|
-
const isTelemetryActive = (
|
|
9450
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8698
9451
|
if (isTelemetryActive) {
|
|
8699
9452
|
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";
|
|
8700
|
-
const telemetryUrl = ((
|
|
9453
|
+
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
8701
9454
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8702
9455
|
(async () => {
|
|
8703
9456
|
try {
|
|
@@ -8756,9 +9509,8 @@ ${context}`;
|
|
|
8756
9509
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8757
9510
|
);
|
|
8758
9511
|
}
|
|
8759
|
-
const
|
|
8760
|
-
|
|
8761
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9512
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9513
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8762
9514
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8763
9515
|
}
|
|
8764
9516
|
try {
|
|
@@ -8783,6 +9535,8 @@ ${context}`;
|
|
|
8783
9535
|
});
|
|
8784
9536
|
}
|
|
8785
9537
|
resolveNumericPredicateValue(source, predicate) {
|
|
9538
|
+
var _a2;
|
|
9539
|
+
if (!source) return null;
|
|
8786
9540
|
const meta = source.metadata || {};
|
|
8787
9541
|
const field = predicate.field;
|
|
8788
9542
|
const entries = Object.entries(meta).filter(([, value]) => value !== null && value !== void 0 && typeof value !== "object");
|
|
@@ -8794,7 +9548,7 @@ ${context}`;
|
|
|
8794
9548
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
8795
9549
|
if (value !== null) return value;
|
|
8796
9550
|
}
|
|
8797
|
-
const contentValue = this.extractNumericValueFromContent(source.content, field);
|
|
9551
|
+
const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
|
|
8798
9552
|
if (contentValue !== null) return contentValue;
|
|
8799
9553
|
}
|
|
8800
9554
|
for (const [key, value] of entries) {
|
|
@@ -8805,6 +9559,7 @@ ${context}`;
|
|
|
8805
9559
|
return null;
|
|
8806
9560
|
}
|
|
8807
9561
|
extractNumericValueFromContent(content, field) {
|
|
9562
|
+
if (!content || typeof content !== "string") return null;
|
|
8808
9563
|
const escapedWords = field.split(/\s+|_+|-+/).filter(Boolean).map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
8809
9564
|
if (escapedWords.length === 0) return null;
|
|
8810
9565
|
const pattern = new RegExp(`(?:${escapedWords.join("[\\\\s_:-]*")})\\s*[:\\-\u2013]?\\s*([\\d,]+(?:\\.\\d+)?)`, "i");
|
|
@@ -8890,6 +9645,20 @@ ${context}`;
|
|
|
8890
9645
|
resolvedSources.push(source);
|
|
8891
9646
|
}
|
|
8892
9647
|
}
|
|
9648
|
+
console.log("[Pipeline] retrieve() response:", {
|
|
9649
|
+
query,
|
|
9650
|
+
namespace: ns,
|
|
9651
|
+
count: resolvedSources.length,
|
|
9652
|
+
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9653
|
+
var _a3;
|
|
9654
|
+
return {
|
|
9655
|
+
id: s == null ? void 0 : s.id,
|
|
9656
|
+
score: s == null ? void 0 : s.score,
|
|
9657
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9658
|
+
metadata: s == null ? void 0 : s.metadata
|
|
9659
|
+
};
|
|
9660
|
+
})
|
|
9661
|
+
});
|
|
8893
9662
|
return { sources: resolvedSources, graphData };
|
|
8894
9663
|
}
|
|
8895
9664
|
/** Rewrite the user query for better retrieval performance. */
|