@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/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}
|
|
@@ -4034,25 +4648,42 @@ ${context != null ? context : "None"}` },
|
|
|
4034
4648
|
}
|
|
4035
4649
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4036
4650
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4651
|
+
const _g2 = globalThis;
|
|
4652
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4653
|
+
if (typeof dispatch !== "function") {
|
|
4654
|
+
try {
|
|
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}`);
|
|
4677
|
+
} catch (dispatchErr) {
|
|
4678
|
+
throw dispatchErr;
|
|
4049
4679
|
}
|
|
4050
|
-
}
|
|
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.`);
|
|
4051
4682
|
}
|
|
4052
4683
|
}
|
|
4053
4684
|
const { data } = await this.http.post(path2, payload);
|
|
4054
|
-
const extractPath = (
|
|
4055
|
-
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);
|
|
4056
4687
|
if (result === void 0) {
|
|
4057
4688
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
4058
4689
|
}
|
|
@@ -4065,7 +4696,7 @@ ${context != null ? context : "None"}` },
|
|
|
4065
4696
|
*/
|
|
4066
4697
|
chatStream(messages, context) {
|
|
4067
4698
|
return __asyncGenerator(this, null, function* () {
|
|
4068
|
-
var _a2, _b, _c, _d, _e
|
|
4699
|
+
var _a2, _b, _c, _d, _e;
|
|
4069
4700
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
4070
4701
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4071
4702
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
@@ -4099,10 +4730,22 @@ ${context != null ? context : "None"}` },
|
|
|
4099
4730
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4100
4731
|
let streamBody = null;
|
|
4101
4732
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
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") {
|
|
4747
|
+
try {
|
|
4748
|
+
const res = yield new __await(dispatch({
|
|
4106
4749
|
model: this.model,
|
|
4107
4750
|
messages: formattedMessages,
|
|
4108
4751
|
max_tokens: this.maxTokens,
|
|
@@ -4111,12 +4754,19 @@ ${context != null ? context : "None"}` },
|
|
|
4111
4754
|
}, this.apiKey));
|
|
4112
4755
|
if (res == null ? void 0 : res.stream) {
|
|
4113
4756
|
streamBody = res.stream;
|
|
4114
|
-
} else
|
|
4115
|
-
|
|
4116
|
-
|
|
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}`);
|
|
4117
4764
|
}
|
|
4765
|
+
} catch (dispatchErr) {
|
|
4766
|
+
throw dispatchErr;
|
|
4118
4767
|
}
|
|
4119
|
-
}
|
|
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.`);
|
|
4120
4770
|
}
|
|
4121
4771
|
}
|
|
4122
4772
|
if (!streamBody) {
|
|
@@ -4143,14 +4793,14 @@ ${context != null ? context : "None"}` },
|
|
|
4143
4793
|
if (done) break;
|
|
4144
4794
|
buffer += decoder.decode(value, { stream: true });
|
|
4145
4795
|
const lines = buffer.split("\n");
|
|
4146
|
-
buffer = (
|
|
4796
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4147
4797
|
for (const line of lines) {
|
|
4148
4798
|
const trimmed = line.trim();
|
|
4149
4799
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4150
4800
|
if (!trimmed.startsWith("data:")) continue;
|
|
4151
4801
|
try {
|
|
4152
4802
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4153
|
-
const text = resolvePath(json, extractPath);
|
|
4803
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4154
4804
|
if (text && typeof text === "string") yield text;
|
|
4155
4805
|
} catch (e) {
|
|
4156
4806
|
}
|
|
@@ -4160,7 +4810,7 @@ ${context != null ? context : "None"}` },
|
|
|
4160
4810
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4161
4811
|
try {
|
|
4162
4812
|
const json = JSON.parse(jsonStr);
|
|
4163
|
-
const text = resolvePath(json, extractPath);
|
|
4813
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4164
4814
|
if (text && typeof text === "string") yield text;
|
|
4165
4815
|
} catch (e) {
|
|
4166
4816
|
}
|
|
@@ -4187,18 +4837,34 @@ ${context != null ? context : "None"}` },
|
|
|
4187
4837
|
}
|
|
4188
4838
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4189
4839
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4840
|
+
const _g2 = globalThis;
|
|
4841
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4842
|
+
if (typeof dispatch !== "function") {
|
|
4843
|
+
try {
|
|
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({
|
|
4194
4856
|
model: this.model,
|
|
4195
4857
|
input: text
|
|
4196
4858
|
}, this.apiKey);
|
|
4197
4859
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4198
4860
|
return res.data[0].embedding;
|
|
4199
4861
|
}
|
|
4862
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4863
|
+
} catch (dispatchErr) {
|
|
4864
|
+
throw dispatchErr;
|
|
4200
4865
|
}
|
|
4201
|
-
}
|
|
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.`);
|
|
4202
4868
|
}
|
|
4203
4869
|
}
|
|
4204
4870
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -4791,7 +5457,8 @@ var Reranker = class {
|
|
|
4791
5457
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
4792
5458
|
}
|
|
4793
5459
|
const scoredMatches = matches.map((match) => {
|
|
4794
|
-
|
|
5460
|
+
var _a2;
|
|
5461
|
+
const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
|
|
4795
5462
|
let keywordScore = 0;
|
|
4796
5463
|
keywords.forEach((keyword) => {
|
|
4797
5464
|
if (contentLower.includes(keyword)) {
|
|
@@ -4812,7 +5479,10 @@ var Reranker = class {
|
|
|
4812
5479
|
[{ role: "user", content: `Query: "${query}"
|
|
4813
5480
|
|
|
4814
5481
|
Documents:
|
|
4815
|
-
${topN.map((m, i) =>
|
|
5482
|
+
${topN.map((m, i) => {
|
|
5483
|
+
var _a2;
|
|
5484
|
+
return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
|
|
5485
|
+
}).join("\n")}` }],
|
|
4816
5486
|
"",
|
|
4817
5487
|
{
|
|
4818
5488
|
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.',
|
|
@@ -5983,10 +6653,10 @@ Return ONLY 'vector', 'graph', or 'both'. No explanation.`;
|
|
|
5983
6653
|
"",
|
|
5984
6654
|
{ temperature: 0, maxTokens: 10 }
|
|
5985
6655
|
);
|
|
5986
|
-
const cleanResponse = response.trim().toLowerCase();
|
|
5987
|
-
if (cleanResponse.includes("vector")) return "vector";
|
|
5988
|
-
if (cleanResponse.includes("graph")) return "graph";
|
|
6656
|
+
const cleanResponse = (response != null ? response : "").trim().toLowerCase();
|
|
5989
6657
|
if (cleanResponse.includes("both")) return "both";
|
|
6658
|
+
if (cleanResponse.includes("graph")) return "graph";
|
|
6659
|
+
if (cleanResponse.includes("vector")) return "vector";
|
|
5990
6660
|
} catch (error) {
|
|
5991
6661
|
console.warn("[QueryProcessor] LLM strategy classification failed, falling back to keywords:", error);
|
|
5992
6662
|
}
|
|
@@ -6160,7 +6830,10 @@ var IntentClassifier = class {
|
|
|
6160
6830
|
hasCategoricalFields = catKeys.size > 0;
|
|
6161
6831
|
numericFieldCount = numericKeys.size;
|
|
6162
6832
|
categoricalFieldCount = catKeys.size;
|
|
6163
|
-
if (productKeyMatches >= 2 || docs.some((d) =>
|
|
6833
|
+
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6834
|
+
var _a2, _b;
|
|
6835
|
+
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");
|
|
6836
|
+
})) {
|
|
6164
6837
|
isProductLike = true;
|
|
6165
6838
|
}
|
|
6166
6839
|
}
|
|
@@ -6440,7 +7113,10 @@ var TextRendererStrategy = class {
|
|
|
6440
7113
|
return { type: "text", title, data: { content: data } };
|
|
6441
7114
|
}
|
|
6442
7115
|
const docs = Array.isArray(data) ? data : [];
|
|
6443
|
-
const text = docs.map((d) =>
|
|
7116
|
+
const text = docs.map((d) => {
|
|
7117
|
+
var _a2;
|
|
7118
|
+
return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
|
|
7119
|
+
}).join("\n\n");
|
|
6444
7120
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6445
7121
|
}
|
|
6446
7122
|
};
|
|
@@ -6697,6 +7373,19 @@ var UITransformer = class _UITransformer {
|
|
|
6697
7373
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6698
7374
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6699
7375
|
}
|
|
7376
|
+
console.log("[UITransformer.transform] Processing retrievedData:", {
|
|
7377
|
+
userQuery,
|
|
7378
|
+
retrievedCount: retrievedData.length,
|
|
7379
|
+
sample: retrievedData.slice(0, 2).map((item) => {
|
|
7380
|
+
var _a3;
|
|
7381
|
+
return {
|
|
7382
|
+
id: item == null ? void 0 : item.id,
|
|
7383
|
+
contentType: typeof (item == null ? void 0 : item.content),
|
|
7384
|
+
contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
|
|
7385
|
+
metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
|
|
7386
|
+
};
|
|
7387
|
+
})
|
|
7388
|
+
});
|
|
6700
7389
|
const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
|
|
6701
7390
|
const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
|
|
6702
7391
|
const profile = this.profileData(filteredData);
|
|
@@ -7037,7 +7726,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7037
7726
|
}
|
|
7038
7727
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
7039
7728
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
7040
|
-
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);
|
|
7041
7730
|
return {
|
|
7042
7731
|
type: "product_carousel",
|
|
7043
7732
|
title: "Recommended Products",
|
|
@@ -7186,7 +7875,10 @@ ${schemaProfileText}` : ""}`;
|
|
|
7186
7875
|
type: "radar_chart",
|
|
7187
7876
|
title: "Product Comparison",
|
|
7188
7877
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7189
|
-
data: radarData.length > 0 ? radarData : data.map((d) =>
|
|
7878
|
+
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7879
|
+
var _a2;
|
|
7880
|
+
return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
|
|
7881
|
+
})
|
|
7190
7882
|
};
|
|
7191
7883
|
}
|
|
7192
7884
|
static transformToTable(data, query = "") {
|
|
@@ -7203,7 +7895,10 @@ ${schemaProfileText}` : ""}`;
|
|
|
7203
7895
|
static transformToText(data) {
|
|
7204
7896
|
return this.createTextResponse(
|
|
7205
7897
|
"Retrieved Context",
|
|
7206
|
-
data.map((item) =>
|
|
7898
|
+
data.map((item) => {
|
|
7899
|
+
var _a2;
|
|
7900
|
+
return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
|
|
7901
|
+
}).join("\n\n"),
|
|
7207
7902
|
`Found ${data.length} relevant results`
|
|
7208
7903
|
);
|
|
7209
7904
|
}
|
|
@@ -7364,6 +8059,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7364
8059
|
return productTerms && productAction && !nonProductEntityTerms;
|
|
7365
8060
|
}
|
|
7366
8061
|
static isProductData(item) {
|
|
8062
|
+
if (!item) return false;
|
|
7367
8063
|
const content = (item.content || "").toLowerCase();
|
|
7368
8064
|
const productKeywords = [
|
|
7369
8065
|
"product",
|
|
@@ -7410,7 +8106,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7410
8106
|
return fieldCount.size > 2;
|
|
7411
8107
|
}
|
|
7412
8108
|
static profileData(data) {
|
|
7413
|
-
const records = data.map((item) => {
|
|
8109
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
8110
|
+
var _a2, _b;
|
|
7414
8111
|
const fields2 = {};
|
|
7415
8112
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7416
8113
|
const primitive = this.toPrimitive(value);
|
|
@@ -7419,8 +8116,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7419
8116
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7420
8117
|
return {
|
|
7421
8118
|
id: item.id,
|
|
7422
|
-
content: item.content,
|
|
7423
|
-
score: item.score,
|
|
8119
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
8120
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7424
8121
|
fields: fields2,
|
|
7425
8122
|
source: item
|
|
7426
8123
|
};
|
|
@@ -7622,12 +8319,12 @@ ${schemaProfileText}` : ""}`;
|
|
|
7622
8319
|
}
|
|
7623
8320
|
static extractTimeSeriesData(data) {
|
|
7624
8321
|
return data.map((item) => {
|
|
7625
|
-
var _a2, _b, _c, _d, _e;
|
|
8322
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
7626
8323
|
const meta = item.metadata || {};
|
|
7627
8324
|
return {
|
|
7628
8325
|
timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7629
8326
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7630
|
-
label: (
|
|
8327
|
+
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7631
8328
|
};
|
|
7632
8329
|
});
|
|
7633
8330
|
}
|
|
@@ -7741,7 +8438,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7741
8438
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7742
8439
|
}
|
|
7743
8440
|
static resolveTableCellValue(item, column) {
|
|
7744
|
-
|
|
8441
|
+
var _a2, _b, _c;
|
|
8442
|
+
if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
|
|
7745
8443
|
const meta = item.metadata || {};
|
|
7746
8444
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7747
8445
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -7752,9 +8450,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7752
8450
|
}
|
|
7753
8451
|
const aliasValue = this.resolveAliasedTableCell(meta, column);
|
|
7754
8452
|
if (aliasValue !== void 0) return this.toDisplayValue(aliasValue);
|
|
7755
|
-
const contentValue = this.extractContentFieldValue(item.content, column);
|
|
8453
|
+
const contentValue = this.extractContentFieldValue((_b = item == null ? void 0 : item.content) != null ? _b : "", column);
|
|
7756
8454
|
if (contentValue !== null) return contentValue;
|
|
7757
|
-
const aliasContentValue = this.extractAliasedContentFieldValue(item.content, column);
|
|
8455
|
+
const aliasContentValue = this.extractAliasedContentFieldValue((_c = item == null ? void 0 : item.content) != null ? _c : "", column);
|
|
7758
8456
|
return aliasContentValue != null ? aliasContentValue : "";
|
|
7759
8457
|
}
|
|
7760
8458
|
static resolveAliasedTableCell(meta, column) {
|
|
@@ -7804,6 +8502,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7804
8502
|
return { inStockCount: inStock, outOfStockCount: outOfStock };
|
|
7805
8503
|
}
|
|
7806
8504
|
static determineStockStatus(item) {
|
|
8505
|
+
if (!item) return true;
|
|
7807
8506
|
const meta = item.metadata || {};
|
|
7808
8507
|
const stockValue = resolveMetadataValue(meta, "stock");
|
|
7809
8508
|
if (stockValue !== void 0) {
|
|
@@ -7849,35 +8548,64 @@ ${schemaProfileText}` : ""}`;
|
|
|
7849
8548
|
return resolveMetadataValue(meta, uiKey);
|
|
7850
8549
|
}
|
|
7851
8550
|
static extractProductInfo(item, config, trainedSchema) {
|
|
7852
|
-
var _a2;
|
|
8551
|
+
var _a2, _b;
|
|
8552
|
+
if (!item) return null;
|
|
7853
8553
|
const meta = item.metadata || {};
|
|
8554
|
+
const content = item.content || "";
|
|
7854
8555
|
const name = this.getDynamicVal(meta, "name", config, trainedSchema);
|
|
7855
8556
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
7856
8557
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
7857
8558
|
const description = this.cleanProductDescription(
|
|
7858
|
-
(_a2 = this.extractProductDescriptionFromContent(
|
|
8559
|
+
(_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
7859
8560
|
);
|
|
7860
8561
|
if (name || this.isProductData(item)) {
|
|
7861
8562
|
let finalName = name ? String(name) : void 0;
|
|
8563
|
+
if (!finalName && content) {
|
|
8564
|
+
const nameMatch = content.match(/(?:Product|Item|Name):\s*([^\n]+)/i);
|
|
8565
|
+
finalName = nameMatch ? nameMatch[1].trim() : (_b = content.split("\n")[0]) == null ? void 0 : _b.substring(0, 60);
|
|
8566
|
+
}
|
|
7862
8567
|
if (!finalName) {
|
|
7863
|
-
|
|
7864
|
-
|
|
8568
|
+
console.warn(
|
|
8569
|
+
`[UITransformer] Unable to read product name from metadata or content for item ${item.id}. Defaulting to 'Unnamed Product'.`,
|
|
8570
|
+
{ metadataKeys: Object.keys(meta), contentLength: content.length }
|
|
8571
|
+
);
|
|
7865
8572
|
}
|
|
7866
8573
|
let finalPrice = typeof price === "number" || typeof price === "string" ? price : void 0;
|
|
7867
|
-
if (!finalPrice) {
|
|
7868
|
-
const priceMatch =
|
|
8574
|
+
if (!finalPrice && content) {
|
|
8575
|
+
const priceMatch = content.match(/(?:Price|Cost):\s*\$?([\d,.]+)/i) || content.match(/\$\s*([\d,.]+)/);
|
|
7869
8576
|
if (priceMatch) finalPrice = priceMatch[1].replace(/,/g, "");
|
|
7870
8577
|
}
|
|
8578
|
+
if (finalPrice === void 0) {
|
|
8579
|
+
console.warn(
|
|
8580
|
+
`[UITransformer] Unable to read product price from metadata or content for item ${item.id}.`,
|
|
8581
|
+
{ metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
|
|
8582
|
+
);
|
|
8583
|
+
}
|
|
7871
8584
|
const imageValue = this.getDynamicVal(meta, "image", config, trainedSchema);
|
|
8585
|
+
if (!imageValue) {
|
|
8586
|
+
console.debug(
|
|
8587
|
+
`[UITransformer] Unable to read product image URL from metadata for item ${item.id}.`
|
|
8588
|
+
);
|
|
8589
|
+
}
|
|
8590
|
+
if (!description) {
|
|
8591
|
+
console.debug(
|
|
8592
|
+
`[UITransformer] Unable to read product description from metadata or content for item ${item.id}.`
|
|
8593
|
+
);
|
|
8594
|
+
}
|
|
7872
8595
|
return {
|
|
7873
8596
|
id: item.id,
|
|
7874
|
-
name: finalName,
|
|
8597
|
+
name: finalName || "Unnamed Product",
|
|
7875
8598
|
price: finalPrice,
|
|
7876
8599
|
image: typeof imageValue === "string" ? imageValue : void 0,
|
|
7877
8600
|
brand: brand ? String(brand) : void 0,
|
|
7878
8601
|
description,
|
|
7879
8602
|
inStock: this.determineStockStatus(item)
|
|
7880
8603
|
};
|
|
8604
|
+
} else {
|
|
8605
|
+
console.warn(
|
|
8606
|
+
`[UITransformer] Item ${item.id} skipped: unable to read name or identify as product data from metadata/content.`,
|
|
8607
|
+
{ metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
|
|
8608
|
+
);
|
|
7881
8609
|
}
|
|
7882
8610
|
return null;
|
|
7883
8611
|
}
|
|
@@ -7962,13 +8690,13 @@ RULES:
|
|
|
7962
8690
|
5. If no relevant data is found, return text: "I cannot answer this question based on the available information."`;
|
|
7963
8691
|
}
|
|
7964
8692
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
7965
|
-
const items = sources.map((s, i) => {
|
|
8693
|
+
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
7966
8694
|
var _a2, _b, _c, _d;
|
|
7967
8695
|
return {
|
|
7968
8696
|
index: i + 1,
|
|
7969
|
-
content: (_b = (_a2 = s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
|
|
7970
|
-
metadata: (_c = s.metadata) != null ? _c : {},
|
|
7971
|
-
score: (_d = s.score) != null ? _d : 0
|
|
8697
|
+
content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
|
|
8698
|
+
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8699
|
+
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
7972
8700
|
};
|
|
7973
8701
|
});
|
|
7974
8702
|
const full = JSON.stringify(items, null, 2);
|
|
@@ -8492,7 +9220,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8492
9220
|
*/
|
|
8493
9221
|
askStreamInternal(_0) {
|
|
8494
9222
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8495
|
-
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;
|
|
8496
9224
|
yield new __await(this.initialize());
|
|
8497
9225
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8498
9226
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8535,40 +9263,65 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8535
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;
|
|
8536
9264
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8537
9265
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8538
|
-
const wantsExhaustiveList =
|
|
8539
|
-
const retrievalLimit =
|
|
8540
|
-
const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
|
|
9266
|
+
const wantsExhaustiveList = true;
|
|
9267
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
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"));
|
|
9269
|
+
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
9270
|
+
rawCount: rawSources.length,
|
|
9271
|
+
sample: rawSources.slice(0, 2).map((s) => {
|
|
9272
|
+
var _a3;
|
|
9273
|
+
return {
|
|
9274
|
+
id: s == null ? void 0 : s.id,
|
|
9275
|
+
score: s == null ? void 0 : s.score,
|
|
9276
|
+
contentType: typeof (s == null ? void 0 : s.content),
|
|
9277
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9278
|
+
metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
|
|
9279
|
+
};
|
|
9280
|
+
})
|
|
9281
|
+
});
|
|
8541
9282
|
const retrieveEnd = performance.now();
|
|
8542
9283
|
const embedMs = retrieveEnd - embedStart;
|
|
8543
9284
|
const retrieveMs = retrieveEnd - embedStart;
|
|
8544
9285
|
const rerankStart = performance.now();
|
|
8545
|
-
const structuredSources = this.applyStructuredFilters(rawSources, filter);
|
|
8546
|
-
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) =>
|
|
8547
|
-
|
|
9286
|
+
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
9287
|
+
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
9288
|
+
var _a3;
|
|
9289
|
+
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
9290
|
+
});
|
|
9291
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8548
9292
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8549
9293
|
if (!hasNumericPredicates && useReranking) {
|
|
8550
|
-
fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
|
|
8551
|
-
} else if (!wantsExhaustiveList) {
|
|
8552
|
-
fullSources = fullSources.slice(0, topK);
|
|
9294
|
+
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8553
9295
|
}
|
|
8554
9296
|
const rerankMs = performance.now() - rerankStart;
|
|
8555
|
-
|
|
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) => {
|
|
8556
9302
|
var _a3;
|
|
8557
9303
|
return `[Source ${i + 1}]
|
|
8558
9304
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8559
9305
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
}
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
9306
|
+
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
9307
|
+
var _a3, _b2;
|
|
9308
|
+
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
9309
|
+
});
|
|
9310
|
+
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
9311
|
+
count: sources.length,
|
|
9312
|
+
totalRawCount: rawSources.length,
|
|
9313
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
9314
|
+
var _a3;
|
|
9315
|
+
return {
|
|
9316
|
+
rank: idx + 1,
|
|
9317
|
+
id: s == null ? void 0 : s.id,
|
|
9318
|
+
score: s == null ? void 0 : s.score,
|
|
9319
|
+
contentType: typeof (s == null ? void 0 : s.content),
|
|
9320
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9321
|
+
metadata: s == null ? void 0 : s.metadata
|
|
9322
|
+
};
|
|
9323
|
+
})
|
|
9324
|
+
});
|
|
8572
9325
|
if (graphData && graphData.nodes.length > 0) {
|
|
8573
9326
|
const graphContext = graphData.nodes.map(
|
|
8574
9327
|
(n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
|
|
@@ -8594,18 +9347,18 @@ ${context}`;
|
|
|
8594
9347
|
}
|
|
8595
9348
|
yield {
|
|
8596
9349
|
reply: "",
|
|
8597
|
-
sources: sources.map((s) => {
|
|
8598
|
-
var _a3;
|
|
9350
|
+
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
9351
|
+
var _a3, _b2, _c2;
|
|
8599
9352
|
return {
|
|
8600
9353
|
id: s.id,
|
|
8601
|
-
score: s.score,
|
|
8602
|
-
content: s.content,
|
|
8603
|
-
metadata: (
|
|
9354
|
+
score: (_a3 = s.score) != null ? _a3 : 0,
|
|
9355
|
+
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
9356
|
+
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8604
9357
|
namespace: ns
|
|
8605
9358
|
};
|
|
8606
9359
|
})
|
|
8607
9360
|
};
|
|
8608
|
-
const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
|
|
9361
|
+
const allMetadataKeys = Array.from(new Set(sources.filter(Boolean).flatMap((s) => Object.keys((s == null ? void 0 : s.metadata) || {}))));
|
|
8609
9362
|
const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
|
|
8610
9363
|
if (allMetadataKeys.length > 0 && !cachedSchema) {
|
|
8611
9364
|
SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => {
|
|
@@ -8757,7 +9510,7 @@ ${context}`;
|
|
|
8757
9510
|
}
|
|
8758
9511
|
yield fullReply;
|
|
8759
9512
|
}
|
|
8760
|
-
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;
|
|
8761
9514
|
if (runHallucination) {
|
|
8762
9515
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8763
9516
|
}
|
|
@@ -8766,7 +9519,7 @@ ${context}`;
|
|
|
8766
9519
|
const latency = {
|
|
8767
9520
|
embedMs: Math.round(embedMs),
|
|
8768
9521
|
retrieveMs: Math.round(retrieveMs),
|
|
8769
|
-
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,
|
|
8770
9523
|
generateMs: Math.round(generateMs),
|
|
8771
9524
|
totalMs: Math.round(totalMs)
|
|
8772
9525
|
};
|
|
@@ -8779,7 +9532,7 @@ ${context}`;
|
|
|
8779
9532
|
totalTokens: promptTokens + completionTokens,
|
|
8780
9533
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8781
9534
|
};
|
|
8782
|
-
const awaitHallucination = ((
|
|
9535
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8783
9536
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8784
9537
|
uiTransformationPromise,
|
|
8785
9538
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8808,10 +9561,10 @@ ${context}`;
|
|
|
8808
9561
|
hallucinationReason: hScore.reason
|
|
8809
9562
|
} : {});
|
|
8810
9563
|
const trace = buildTrace(hallucinationResult);
|
|
8811
|
-
const isTelemetryActive = (
|
|
9564
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8812
9565
|
if (isTelemetryActive) {
|
|
8813
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";
|
|
8814
|
-
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;
|
|
8815
9568
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8816
9569
|
(async () => {
|
|
8817
9570
|
try {
|
|
@@ -8870,9 +9623,8 @@ ${context}`;
|
|
|
8870
9623
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8871
9624
|
);
|
|
8872
9625
|
}
|
|
8873
|
-
const
|
|
8874
|
-
|
|
8875
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9626
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9627
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8876
9628
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8877
9629
|
}
|
|
8878
9630
|
try {
|
|
@@ -8897,6 +9649,8 @@ ${context}`;
|
|
|
8897
9649
|
});
|
|
8898
9650
|
}
|
|
8899
9651
|
resolveNumericPredicateValue(source, predicate) {
|
|
9652
|
+
var _a2;
|
|
9653
|
+
if (!source) return null;
|
|
8900
9654
|
const meta = source.metadata || {};
|
|
8901
9655
|
const field = predicate.field;
|
|
8902
9656
|
const entries = Object.entries(meta).filter(([, value]) => value !== null && value !== void 0 && typeof value !== "object");
|
|
@@ -8908,7 +9662,7 @@ ${context}`;
|
|
|
8908
9662
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
8909
9663
|
if (value !== null) return value;
|
|
8910
9664
|
}
|
|
8911
|
-
const contentValue = this.extractNumericValueFromContent(source.content, field);
|
|
9665
|
+
const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
|
|
8912
9666
|
if (contentValue !== null) return contentValue;
|
|
8913
9667
|
}
|
|
8914
9668
|
for (const [key, value] of entries) {
|
|
@@ -8919,6 +9673,7 @@ ${context}`;
|
|
|
8919
9673
|
return null;
|
|
8920
9674
|
}
|
|
8921
9675
|
extractNumericValueFromContent(content, field) {
|
|
9676
|
+
if (!content || typeof content !== "string") return null;
|
|
8922
9677
|
const escapedWords = field.split(/\s+|_+|-+/).filter(Boolean).map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
8923
9678
|
if (escapedWords.length === 0) return null;
|
|
8924
9679
|
const pattern = new RegExp(`(?:${escapedWords.join("[\\\\s_:-]*")})\\s*[:\\-\u2013]?\\s*([\\d,]+(?:\\.\\d+)?)`, "i");
|
|
@@ -9004,6 +9759,20 @@ ${context}`;
|
|
|
9004
9759
|
resolvedSources.push(source);
|
|
9005
9760
|
}
|
|
9006
9761
|
}
|
|
9762
|
+
console.log("[Pipeline] retrieve() response:", {
|
|
9763
|
+
query,
|
|
9764
|
+
namespace: ns,
|
|
9765
|
+
count: resolvedSources.length,
|
|
9766
|
+
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9767
|
+
var _a3;
|
|
9768
|
+
return {
|
|
9769
|
+
id: s == null ? void 0 : s.id,
|
|
9770
|
+
score: s == null ? void 0 : s.score,
|
|
9771
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9772
|
+
metadata: s == null ? void 0 : s.metadata
|
|
9773
|
+
};
|
|
9774
|
+
})
|
|
9775
|
+
});
|
|
9007
9776
|
return { sources: resolvedSources, graphData };
|
|
9008
9777
|
}
|
|
9009
9778
|
/** Rewrite the user query for better retrieval performance. */
|