@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.mjs
CHANGED
|
@@ -106,6 +106,609 @@ var init_templateUtils = __esm({
|
|
|
106
106
|
}
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
+
// ../../services/llm-gateway/providers/groq.ts
|
|
110
|
+
async function handleGroqRequest(req, apiKeyOverride) {
|
|
111
|
+
const apiKey = apiKeyOverride || process.env.GROQ_API_KEY;
|
|
112
|
+
if (!apiKey) {
|
|
113
|
+
throw new Error("Groq API Key missing. Please set GROQ_API_KEY in environment variables.");
|
|
114
|
+
}
|
|
115
|
+
const modelName = req.model.replace(/^groq\//i, "");
|
|
116
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
117
|
+
model: modelName
|
|
118
|
+
});
|
|
119
|
+
const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
|
|
120
|
+
method: "POST",
|
|
121
|
+
headers: {
|
|
122
|
+
"Content-Type": "application/json",
|
|
123
|
+
"Authorization": `Bearer ${apiKey}`
|
|
124
|
+
},
|
|
125
|
+
body: JSON.stringify(payload)
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const errorText = await response.text();
|
|
129
|
+
throw new Error(`Groq API Error (${response.status}): ${errorText}`);
|
|
130
|
+
}
|
|
131
|
+
if (req.stream && response.body) {
|
|
132
|
+
return { stream: response.body };
|
|
133
|
+
}
|
|
134
|
+
const json = await response.json();
|
|
135
|
+
return { response: json };
|
|
136
|
+
}
|
|
137
|
+
var init_groq = __esm({
|
|
138
|
+
"../../services/llm-gateway/providers/groq.ts"() {
|
|
139
|
+
"use strict";
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// ../../services/llm-gateway/providers/openai.ts
|
|
144
|
+
async function handleOpenAIRequest(req, apiKeyOverride) {
|
|
145
|
+
const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
|
|
146
|
+
if (!apiKey) {
|
|
147
|
+
throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
|
|
148
|
+
}
|
|
149
|
+
const modelName = req.model.replace(/^(openai|gpt)\//i, "");
|
|
150
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
151
|
+
model: modelName
|
|
152
|
+
});
|
|
153
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
154
|
+
method: "POST",
|
|
155
|
+
headers: {
|
|
156
|
+
"Content-Type": "application/json",
|
|
157
|
+
"Authorization": `Bearer ${apiKey}`
|
|
158
|
+
},
|
|
159
|
+
body: JSON.stringify(payload)
|
|
160
|
+
});
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
const errorText = await response.text();
|
|
163
|
+
throw new Error(`OpenAI API Error (${response.status}): ${errorText}`);
|
|
164
|
+
}
|
|
165
|
+
if (req.stream && response.body) {
|
|
166
|
+
return { stream: response.body };
|
|
167
|
+
}
|
|
168
|
+
const json = await response.json();
|
|
169
|
+
return { response: json };
|
|
170
|
+
}
|
|
171
|
+
async function handleOpenAIEmbedding(req, apiKeyOverride) {
|
|
172
|
+
const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
|
|
173
|
+
if (!apiKey) {
|
|
174
|
+
throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
|
|
175
|
+
}
|
|
176
|
+
const modelName = req.model.replace(/^(openai)\//i, "");
|
|
177
|
+
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
178
|
+
method: "POST",
|
|
179
|
+
headers: {
|
|
180
|
+
"Content-Type": "application/json",
|
|
181
|
+
"Authorization": `Bearer ${apiKey}`
|
|
182
|
+
},
|
|
183
|
+
body: JSON.stringify({
|
|
184
|
+
model: modelName,
|
|
185
|
+
input: req.input
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
if (!response.ok) {
|
|
189
|
+
const errorText = await response.text();
|
|
190
|
+
throw new Error(`OpenAI Embedding API Error (${response.status}): ${errorText}`);
|
|
191
|
+
}
|
|
192
|
+
return await response.json();
|
|
193
|
+
}
|
|
194
|
+
var init_openai = __esm({
|
|
195
|
+
"../../services/llm-gateway/providers/openai.ts"() {
|
|
196
|
+
"use strict";
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// ../../services/llm-gateway/providers/gemini.ts
|
|
201
|
+
async function handleGeminiRequest(req, apiKeyOverride) {
|
|
202
|
+
const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
|
|
203
|
+
if (!apiKey) {
|
|
204
|
+
throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
|
|
205
|
+
}
|
|
206
|
+
let modelName = req.model.replace(/^(google|gemini)\//i, "");
|
|
207
|
+
if (!modelName.startsWith("gemini-")) {
|
|
208
|
+
modelName = `gemini-${modelName}`;
|
|
209
|
+
}
|
|
210
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
211
|
+
model: modelName
|
|
212
|
+
});
|
|
213
|
+
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", {
|
|
214
|
+
method: "POST",
|
|
215
|
+
headers: {
|
|
216
|
+
"Content-Type": "application/json",
|
|
217
|
+
"Authorization": `Bearer ${apiKey}`
|
|
218
|
+
},
|
|
219
|
+
body: JSON.stringify(payload)
|
|
220
|
+
});
|
|
221
|
+
if (!response.ok) {
|
|
222
|
+
const errorText = await response.text();
|
|
223
|
+
throw new Error(`Google Gemini API Error (${response.status}): ${errorText}`);
|
|
224
|
+
}
|
|
225
|
+
if (req.stream && response.body) {
|
|
226
|
+
return { stream: response.body };
|
|
227
|
+
}
|
|
228
|
+
const json = await response.json();
|
|
229
|
+
return { response: json };
|
|
230
|
+
}
|
|
231
|
+
async function handleGeminiEmbedding(req, apiKeyOverride) {
|
|
232
|
+
const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
|
|
233
|
+
if (!apiKey) {
|
|
234
|
+
throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
|
|
235
|
+
}
|
|
236
|
+
let modelName = req.model.replace(/^(google|gemini)\//i, "");
|
|
237
|
+
if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.startsWith("text-embedding-00") && !modelName.startsWith("embedding-00")) {
|
|
238
|
+
modelName = "text-embedding-004";
|
|
239
|
+
}
|
|
240
|
+
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/embeddings", {
|
|
241
|
+
method: "POST",
|
|
242
|
+
headers: {
|
|
243
|
+
"Content-Type": "application/json",
|
|
244
|
+
"Authorization": `Bearer ${apiKey}`
|
|
245
|
+
},
|
|
246
|
+
body: JSON.stringify({
|
|
247
|
+
model: modelName,
|
|
248
|
+
input: req.input
|
|
249
|
+
})
|
|
250
|
+
});
|
|
251
|
+
if (!response.ok) {
|
|
252
|
+
const errorText = await response.text();
|
|
253
|
+
throw new Error(`Google Gemini Embedding API Error (${response.status}): ${errorText}`);
|
|
254
|
+
}
|
|
255
|
+
return await response.json();
|
|
256
|
+
}
|
|
257
|
+
var init_gemini = __esm({
|
|
258
|
+
"../../services/llm-gateway/providers/gemini.ts"() {
|
|
259
|
+
"use strict";
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// ../../services/llm-gateway/providers/huggingface.ts
|
|
264
|
+
async function handleHuggingFaceChatRequest(req, apiKeyOverride) {
|
|
265
|
+
var _a2, _b;
|
|
266
|
+
const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
|
|
267
|
+
if (!apiKey) {
|
|
268
|
+
throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
|
|
269
|
+
}
|
|
270
|
+
let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
|
|
271
|
+
if (!modelName || modelName === "default" || modelName.toLowerCase() === "qwen" || modelName.toLowerCase() === "qwen-coder") {
|
|
272
|
+
modelName = "Qwen/Qwen2.5-Coder-32B-Instruct";
|
|
273
|
+
}
|
|
274
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
275
|
+
model: modelName
|
|
276
|
+
});
|
|
277
|
+
try {
|
|
278
|
+
const response = await fetch("https://router.huggingface.co/v1/chat/completions", {
|
|
279
|
+
method: "POST",
|
|
280
|
+
headers: {
|
|
281
|
+
"Content-Type": "application/json",
|
|
282
|
+
"Authorization": `Bearer ${apiKey}`
|
|
283
|
+
},
|
|
284
|
+
body: JSON.stringify(payload)
|
|
285
|
+
});
|
|
286
|
+
if (response.ok) {
|
|
287
|
+
if (req.stream && response.body) {
|
|
288
|
+
return { stream: response.body };
|
|
289
|
+
}
|
|
290
|
+
const json = await response.json();
|
|
291
|
+
return { response: json };
|
|
292
|
+
}
|
|
293
|
+
} catch (e) {
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
const response = await fetch("https://router.huggingface.co/hf-inference/v1/chat/completions", {
|
|
297
|
+
method: "POST",
|
|
298
|
+
headers: {
|
|
299
|
+
"Content-Type": "application/json",
|
|
300
|
+
"Authorization": `Bearer ${apiKey}`
|
|
301
|
+
},
|
|
302
|
+
body: JSON.stringify(payload)
|
|
303
|
+
});
|
|
304
|
+
if (response.ok) {
|
|
305
|
+
if (req.stream && response.body) {
|
|
306
|
+
return { stream: response.body };
|
|
307
|
+
}
|
|
308
|
+
const json = await response.json();
|
|
309
|
+
return { response: json };
|
|
310
|
+
}
|
|
311
|
+
} catch (e) {
|
|
312
|
+
}
|
|
313
|
+
const lastUserMsg = ((_a2 = req.messages.filter((m) => m.role === "user").pop()) == null ? void 0 : _a2.content) || "Hello";
|
|
314
|
+
const pipelineRes = await fetch(`https://router.huggingface.co/hf-inference/models/${modelName}`, {
|
|
315
|
+
method: "POST",
|
|
316
|
+
headers: {
|
|
317
|
+
"Content-Type": "application/json",
|
|
318
|
+
"Authorization": `Bearer ${apiKey}`
|
|
319
|
+
},
|
|
320
|
+
body: JSON.stringify({
|
|
321
|
+
inputs: lastUserMsg,
|
|
322
|
+
parameters: { max_new_tokens: req.max_tokens || 256, temperature: req.temperature || 0.7 },
|
|
323
|
+
options: { wait_for_model: true }
|
|
324
|
+
})
|
|
325
|
+
});
|
|
326
|
+
if (!pipelineRes.ok) {
|
|
327
|
+
const errorText = await pipelineRes.text();
|
|
328
|
+
throw new Error(`HuggingFace API Error (${pipelineRes.status}): ${errorText}`);
|
|
329
|
+
}
|
|
330
|
+
const raw = await pipelineRes.json();
|
|
331
|
+
const textOutput = Array.isArray(raw) ? ((_b = raw[0]) == null ? void 0 : _b.generated_text) || JSON.stringify(raw) : JSON.stringify(raw);
|
|
332
|
+
const formattedResponse = {
|
|
333
|
+
id: `hf-${Date.now()}`,
|
|
334
|
+
object: "chat.completion",
|
|
335
|
+
created: Math.floor(Date.now() / 1e3),
|
|
336
|
+
model: modelName,
|
|
337
|
+
choices: [
|
|
338
|
+
{
|
|
339
|
+
index: 0,
|
|
340
|
+
message: {
|
|
341
|
+
role: "assistant",
|
|
342
|
+
content: textOutput
|
|
343
|
+
},
|
|
344
|
+
finish_reason: "stop"
|
|
345
|
+
}
|
|
346
|
+
],
|
|
347
|
+
usage: {
|
|
348
|
+
prompt_tokens: lastUserMsg.length,
|
|
349
|
+
completion_tokens: textOutput.length,
|
|
350
|
+
total_tokens: lastUserMsg.length + textOutput.length
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
return { response: formattedResponse };
|
|
354
|
+
}
|
|
355
|
+
async function handleHuggingFaceEmbedding(req, apiKeyOverride) {
|
|
356
|
+
const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
|
|
357
|
+
if (!apiKey) {
|
|
358
|
+
throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
|
|
359
|
+
}
|
|
360
|
+
let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
|
|
361
|
+
if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.includes("/") && !modelName.includes("bge") && !modelName.includes("sentence-transformers")) {
|
|
362
|
+
modelName = "BAAI/bge-base-en-v1.5";
|
|
363
|
+
}
|
|
364
|
+
const inputs = Array.isArray(req.input) ? req.input : [req.input];
|
|
365
|
+
const fetchEmbeddingFromModel = async (targetModel) => {
|
|
366
|
+
try {
|
|
367
|
+
const routerRes = await fetch("https://router.huggingface.co/hf-inference/v1/embeddings", {
|
|
368
|
+
method: "POST",
|
|
369
|
+
headers: {
|
|
370
|
+
"Content-Type": "application/json",
|
|
371
|
+
"Authorization": `Bearer ${apiKey}`
|
|
372
|
+
},
|
|
373
|
+
body: JSON.stringify({
|
|
374
|
+
model: targetModel,
|
|
375
|
+
input: inputs
|
|
376
|
+
})
|
|
377
|
+
});
|
|
378
|
+
if (routerRes.ok) {
|
|
379
|
+
const json = await routerRes.json();
|
|
380
|
+
if (json && json.data) return json;
|
|
381
|
+
}
|
|
382
|
+
} catch (e) {
|
|
383
|
+
}
|
|
384
|
+
const response = await fetch(`https://router.huggingface.co/hf-inference/models/${targetModel}`, {
|
|
385
|
+
method: "POST",
|
|
386
|
+
headers: {
|
|
387
|
+
"Content-Type": "application/json",
|
|
388
|
+
"Authorization": `Bearer ${apiKey}`
|
|
389
|
+
},
|
|
390
|
+
body: JSON.stringify({
|
|
391
|
+
inputs,
|
|
392
|
+
options: { wait_for_model: true }
|
|
393
|
+
})
|
|
394
|
+
});
|
|
395
|
+
if (!response.ok) {
|
|
396
|
+
const errorText = await response.text();
|
|
397
|
+
throw new Error(`HuggingFace API Error (${response.status}): ${errorText}`);
|
|
398
|
+
}
|
|
399
|
+
const rawData = await response.json();
|
|
400
|
+
const embeddings = Array.isArray(rawData[0]) ? typeof rawData[0][0] === "number" ? rawData : rawData.map((arr) => arr[0]) : [rawData];
|
|
401
|
+
return {
|
|
402
|
+
object: "list",
|
|
403
|
+
data: embeddings.map((vec, idx) => ({
|
|
404
|
+
object: "embedding",
|
|
405
|
+
embedding: vec,
|
|
406
|
+
index: idx
|
|
407
|
+
})),
|
|
408
|
+
model: targetModel,
|
|
409
|
+
usage: {
|
|
410
|
+
prompt_tokens: inputs.reduce((acc, str) => acc + str.length, 0),
|
|
411
|
+
completion_tokens: 0,
|
|
412
|
+
total_tokens: inputs.reduce((acc, str) => acc + str.length, 0)
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
};
|
|
416
|
+
try {
|
|
417
|
+
return await fetchEmbeddingFromModel(modelName);
|
|
418
|
+
} catch (err) {
|
|
419
|
+
if (modelName !== "BAAI/bge-base-en-v1.5") {
|
|
420
|
+
console.warn(`[LLM Gateway] HuggingFace model ${modelName} failed. Falling back to BAAI/bge-base-en-v1.5...`, err);
|
|
421
|
+
return await fetchEmbeddingFromModel("BAAI/bge-base-en-v1.5");
|
|
422
|
+
}
|
|
423
|
+
throw err;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
var init_huggingface = __esm({
|
|
427
|
+
"../../services/llm-gateway/providers/huggingface.ts"() {
|
|
428
|
+
"use strict";
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// ../../services/llm-gateway/providers/anthropic.ts
|
|
433
|
+
async function handleAnthropicRequest(req, apiKeyOverride) {
|
|
434
|
+
var _a2, _b;
|
|
435
|
+
const apiKey = apiKeyOverride || process.env.ANTHROPIC_API_KEY;
|
|
436
|
+
if (!apiKey) {
|
|
437
|
+
throw new Error("Anthropic API Key missing. Please set ANTHROPIC_API_KEY in environment variables.");
|
|
438
|
+
}
|
|
439
|
+
const modelName = req.model.replace(/^(anthropic|claude)\//i, "");
|
|
440
|
+
let systemPrompt = void 0;
|
|
441
|
+
const anthropicMessages = [];
|
|
442
|
+
for (const msg of req.messages) {
|
|
443
|
+
if (msg.role === "system") {
|
|
444
|
+
systemPrompt = systemPrompt ? `${systemPrompt}
|
|
445
|
+
${msg.content}` : msg.content;
|
|
446
|
+
} else {
|
|
447
|
+
anthropicMessages.push({
|
|
448
|
+
role: msg.role === "assistant" ? "assistant" : "user",
|
|
449
|
+
content: msg.content
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
if (anthropicMessages.length === 0) {
|
|
454
|
+
anthropicMessages.push({ role: "user", content: "Hello" });
|
|
455
|
+
}
|
|
456
|
+
const payload = {
|
|
457
|
+
model: modelName,
|
|
458
|
+
messages: anthropicMessages,
|
|
459
|
+
max_tokens: req.max_tokens || req.max_completion_tokens || 1024,
|
|
460
|
+
stream: req.stream || false
|
|
461
|
+
};
|
|
462
|
+
if (systemPrompt) {
|
|
463
|
+
payload.system = systemPrompt;
|
|
464
|
+
}
|
|
465
|
+
if (req.temperature !== void 0) {
|
|
466
|
+
payload.temperature = req.temperature;
|
|
467
|
+
}
|
|
468
|
+
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
|
469
|
+
method: "POST",
|
|
470
|
+
headers: {
|
|
471
|
+
"Content-Type": "application/json",
|
|
472
|
+
"x-api-key": apiKey,
|
|
473
|
+
"anthropic-version": "2023-06-01"
|
|
474
|
+
},
|
|
475
|
+
body: JSON.stringify(payload)
|
|
476
|
+
});
|
|
477
|
+
if (!response.ok) {
|
|
478
|
+
const errorText = await response.text();
|
|
479
|
+
throw new Error(`Anthropic API Error (${response.status}): ${errorText}`);
|
|
480
|
+
}
|
|
481
|
+
if (req.stream && response.body) {
|
|
482
|
+
return { stream: response.body };
|
|
483
|
+
}
|
|
484
|
+
const json = await response.json();
|
|
485
|
+
const textContent = ((_b = (_a2 = json.content) == null ? void 0 : _a2[0]) == null ? void 0 : _b.text) || "";
|
|
486
|
+
const openAIResponse = {
|
|
487
|
+
id: json.id || `chatcmpl-${Date.now()}`,
|
|
488
|
+
object: "chat.completion",
|
|
489
|
+
created: Math.floor(Date.now() / 1e3),
|
|
490
|
+
model: json.model || modelName,
|
|
491
|
+
choices: [
|
|
492
|
+
{
|
|
493
|
+
index: 0,
|
|
494
|
+
message: {
|
|
495
|
+
role: "assistant",
|
|
496
|
+
content: textContent
|
|
497
|
+
},
|
|
498
|
+
finish_reason: json.stop_reason === "end_turn" ? "stop" : json.stop_reason || "stop"
|
|
499
|
+
}
|
|
500
|
+
],
|
|
501
|
+
usage: json.usage ? {
|
|
502
|
+
prompt_tokens: json.usage.input_tokens,
|
|
503
|
+
completion_tokens: json.usage.output_tokens,
|
|
504
|
+
total_tokens: json.usage.input_tokens + json.usage.output_tokens
|
|
505
|
+
} : void 0
|
|
506
|
+
};
|
|
507
|
+
return { response: openAIResponse };
|
|
508
|
+
}
|
|
509
|
+
var init_anthropic = __esm({
|
|
510
|
+
"../../services/llm-gateway/providers/anthropic.ts"() {
|
|
511
|
+
"use strict";
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// ../../services/llm-gateway/providers/ollama.ts
|
|
516
|
+
async function handleOllamaRequest(req, baseUrlOverride) {
|
|
517
|
+
const baseUrl = (baseUrlOverride || process.env.OLLAMA_BASE_URL || "http://localhost:11434/v1").replace(/\/+$/, "");
|
|
518
|
+
const modelName = req.model.replace(/^ollama\//i, "");
|
|
519
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
520
|
+
model: modelName
|
|
521
|
+
});
|
|
522
|
+
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
523
|
+
method: "POST",
|
|
524
|
+
headers: {
|
|
525
|
+
"Content-Type": "application/json"
|
|
526
|
+
},
|
|
527
|
+
body: JSON.stringify(payload)
|
|
528
|
+
});
|
|
529
|
+
if (!response.ok) {
|
|
530
|
+
const errorText = await response.text();
|
|
531
|
+
throw new Error(`Ollama API Error (${response.status}): ${errorText}`);
|
|
532
|
+
}
|
|
533
|
+
if (req.stream && response.body) {
|
|
534
|
+
return { stream: response.body };
|
|
535
|
+
}
|
|
536
|
+
const json = await response.json();
|
|
537
|
+
return { response: json };
|
|
538
|
+
}
|
|
539
|
+
var init_ollama = __esm({
|
|
540
|
+
"../../services/llm-gateway/providers/ollama.ts"() {
|
|
541
|
+
"use strict";
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// ../../services/llm-gateway/router.ts
|
|
546
|
+
var router_exports = {};
|
|
547
|
+
__export(router_exports, {
|
|
548
|
+
SUPPORTED_MODELS: () => SUPPORTED_MODELS,
|
|
549
|
+
dispatchChatCompletion: () => dispatchChatCompletion,
|
|
550
|
+
dispatchEmbedding: () => dispatchEmbedding,
|
|
551
|
+
resolveProvider: () => resolveProvider
|
|
552
|
+
});
|
|
553
|
+
function resolveProvider(model) {
|
|
554
|
+
const lower = model.toLowerCase();
|
|
555
|
+
if (lower.startsWith("huggingface/") || lower.startsWith("hf/")) {
|
|
556
|
+
return "huggingface";
|
|
557
|
+
}
|
|
558
|
+
if (lower.startsWith("ollama/")) {
|
|
559
|
+
return "ollama";
|
|
560
|
+
}
|
|
561
|
+
if (lower.startsWith("groq/") || lower.includes("llama") || lower.includes("qwen") || lower.includes("mixtral")) {
|
|
562
|
+
return "groq";
|
|
563
|
+
}
|
|
564
|
+
if (process.env.GROQ_API_KEY) return "groq";
|
|
565
|
+
if (process.env.OPENAI_API_KEY) return "openai";
|
|
566
|
+
if (process.env.GEMINI_API_KEY) return "gemini";
|
|
567
|
+
if (process.env.ANTHROPIC_API_KEY) return "anthropic";
|
|
568
|
+
if (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY) return "huggingface";
|
|
569
|
+
return "groq";
|
|
570
|
+
}
|
|
571
|
+
function cleanApiKeyOverride(apiKeyOverride) {
|
|
572
|
+
if (!apiKeyOverride) return void 0;
|
|
573
|
+
const key = apiKeyOverride.trim();
|
|
574
|
+
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-")) {
|
|
575
|
+
return void 0;
|
|
576
|
+
}
|
|
577
|
+
return key;
|
|
578
|
+
}
|
|
579
|
+
async function dispatchChatCompletion(req, apiKeyOverride) {
|
|
580
|
+
const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
|
|
581
|
+
const provider = resolveProvider(req.model);
|
|
582
|
+
try {
|
|
583
|
+
switch (provider) {
|
|
584
|
+
case "groq":
|
|
585
|
+
return await handleGroqRequest(req, effectiveKey);
|
|
586
|
+
case "openai":
|
|
587
|
+
return await handleOpenAIRequest(req, effectiveKey);
|
|
588
|
+
case "gemini":
|
|
589
|
+
return await handleGeminiRequest(req, effectiveKey);
|
|
590
|
+
case "anthropic":
|
|
591
|
+
return await handleAnthropicRequest(req, effectiveKey);
|
|
592
|
+
case "ollama":
|
|
593
|
+
return await handleOllamaRequest(req);
|
|
594
|
+
case "huggingface":
|
|
595
|
+
return await handleHuggingFaceChatRequest(req, effectiveKey);
|
|
596
|
+
default:
|
|
597
|
+
throw new Error(`Unsupported LLM provider for model: ${req.model}`);
|
|
598
|
+
}
|
|
599
|
+
} catch (error) {
|
|
600
|
+
if (/rate[- ]?limit|429|exhausted/i.test(error.message)) {
|
|
601
|
+
const isGroqKey = process.env.GROQ_API_KEY || effectiveKey && effectiveKey.startsWith("gsk_");
|
|
602
|
+
const reqModelLower = req.model.toLowerCase();
|
|
603
|
+
if (isGroqKey && !reqModelLower.includes("llama-3.3-70b")) {
|
|
604
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to secondary Groq model (llama-3.3-70b-versatile)...`);
|
|
605
|
+
try {
|
|
606
|
+
return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: "llama-3.3-70b-versatile" }), effectiveKey);
|
|
607
|
+
} catch (e) {
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
|
|
611
|
+
if (provider !== "gemini" && geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ."))) {
|
|
612
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Google Gemini (gemini-2.5-flash)...`);
|
|
613
|
+
try {
|
|
614
|
+
return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: "gemini-2.5-flash" }), effectiveKey);
|
|
615
|
+
} catch (e) {
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (provider !== "huggingface" && (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY)) {
|
|
619
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Hugging Face (Qwen/Qwen2.5-Coder-32B-Instruct)...`);
|
|
620
|
+
try {
|
|
621
|
+
return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: "Qwen/Qwen2.5-Coder-32B-Instruct" }), effectiveKey);
|
|
622
|
+
} catch (e) {
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
if (provider !== "openai" && process.env.OPENAI_API_KEY) {
|
|
626
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to OpenAI (gpt-4o-mini)...`);
|
|
627
|
+
try {
|
|
628
|
+
return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: "gpt-4o-mini" }), effectiveKey);
|
|
629
|
+
} catch (e) {
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to local Ollama (llama3.2)...`);
|
|
633
|
+
return handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: "llama3.2" }));
|
|
634
|
+
}
|
|
635
|
+
throw error;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
async function dispatchEmbedding(req, apiKeyOverride) {
|
|
639
|
+
const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
|
|
640
|
+
if (req.model.startsWith("hf/") || req.model.startsWith("huggingface/") || req.model.includes("bge-")) {
|
|
641
|
+
try {
|
|
642
|
+
return await handleHuggingFaceEmbedding(req, effectiveKey);
|
|
643
|
+
} catch (err) {
|
|
644
|
+
console.warn("[LLM Gateway] HuggingFace explicit model embedding failed, falling back to default gateway chain:", err);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
|
|
648
|
+
const isGeminiKeyValid = Boolean(geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ.")));
|
|
649
|
+
if (isGeminiKeyValid) {
|
|
650
|
+
try {
|
|
651
|
+
return await handleGeminiEmbedding(req, effectiveKey);
|
|
652
|
+
} catch (err) {
|
|
653
|
+
console.warn("[LLM Gateway] Gemini embedding failed:", err);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
if (process.env.OPENAI_API_KEY) {
|
|
657
|
+
try {
|
|
658
|
+
return await handleOpenAIEmbedding(req, effectiveKey);
|
|
659
|
+
} catch (err) {
|
|
660
|
+
console.warn("[LLM Gateway] OpenAI embedding failed:", err);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
if (process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN) {
|
|
664
|
+
try {
|
|
665
|
+
return await handleHuggingFaceEmbedding(req, effectiveKey);
|
|
666
|
+
} catch (err) {
|
|
667
|
+
console.warn("[LLM Gateway] HuggingFace fallback embedding failed:", err);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return handleGeminiEmbedding(req, effectiveKey);
|
|
671
|
+
}
|
|
672
|
+
var SUPPORTED_MODELS;
|
|
673
|
+
var init_router = __esm({
|
|
674
|
+
"../../services/llm-gateway/router.ts"() {
|
|
675
|
+
"use strict";
|
|
676
|
+
init_groq();
|
|
677
|
+
init_openai();
|
|
678
|
+
init_gemini();
|
|
679
|
+
init_huggingface();
|
|
680
|
+
init_anthropic();
|
|
681
|
+
init_ollama();
|
|
682
|
+
SUPPORTED_MODELS = [
|
|
683
|
+
{ id: "groq/llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
|
|
684
|
+
{ id: "llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
|
|
685
|
+
{ id: "groq/llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
|
|
686
|
+
{ id: "llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
|
|
687
|
+
{ id: "gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
|
|
688
|
+
{ id: "openai/gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
|
|
689
|
+
{ id: "gpt-4o", object: "model", created: 17e8, owned_by: "openai" },
|
|
690
|
+
{ id: "gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
|
|
691
|
+
{ id: "google/gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
|
|
692
|
+
{ id: "claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
|
|
693
|
+
{ id: "anthropic/claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
|
|
694
|
+
{ id: "text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
|
|
695
|
+
{ id: "google/text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
|
|
696
|
+
{ id: "BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
|
|
697
|
+
{ id: "huggingface/BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
|
|
698
|
+
{ id: "groq/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
|
|
699
|
+
{ id: "qwen/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
|
|
700
|
+
{ id: "qwen/qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
|
|
701
|
+
{ id: "qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
|
|
702
|
+
{ id: "ollama/llama3.2", object: "model", created: 17e8, owned_by: "ollama" }
|
|
703
|
+
];
|
|
704
|
+
if (typeof globalThis !== "undefined") {
|
|
705
|
+
const _g2 = globalThis;
|
|
706
|
+
_g2.__retrivoraDispatchChat = dispatchChatCompletion;
|
|
707
|
+
_g2.__retrivoraDispatchEmbedding = dispatchEmbedding;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
});
|
|
711
|
+
|
|
109
712
|
// src/providers/vectordb/BaseVectorProvider.ts
|
|
110
713
|
var BaseVectorProvider;
|
|
111
714
|
var init_BaseVectorProvider = __esm({
|
|
@@ -3880,6 +4483,17 @@ var VECTOR_PROFILES = {
|
|
|
3880
4483
|
};
|
|
3881
4484
|
|
|
3882
4485
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4486
|
+
function extractContent(obj) {
|
|
4487
|
+
var _a2, _b, _c;
|
|
4488
|
+
if (!obj || typeof obj !== "object") return void 0;
|
|
4489
|
+
const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
|
|
4490
|
+
if (!choice) return void 0;
|
|
4491
|
+
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4492
|
+
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
4493
|
+
if (typeof choice.text === "string") return choice.text;
|
|
4494
|
+
if (typeof choice.content === "string") return choice.content;
|
|
4495
|
+
return void 0;
|
|
4496
|
+
}
|
|
3883
4497
|
var UniversalLLMAdapter = class {
|
|
3884
4498
|
constructor(config) {
|
|
3885
4499
|
var _a2, _b, _c, _d, _e, _f, _g2, _h;
|
|
@@ -3911,7 +4525,7 @@ var UniversalLLMAdapter = class {
|
|
|
3911
4525
|
});
|
|
3912
4526
|
}
|
|
3913
4527
|
async chat(messages, context) {
|
|
3914
|
-
var _a2, _b, _c
|
|
4528
|
+
var _a2, _b, _c;
|
|
3915
4529
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3916
4530
|
const formattedMessages = [
|
|
3917
4531
|
{ role: "system", content: `${this.systemPrompt}
|
|
@@ -3938,25 +4552,42 @@ ${context != null ? context : "None"}` },
|
|
|
3938
4552
|
}
|
|
3939
4553
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3940
4554
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
4555
|
+
const _g2 = globalThis;
|
|
4556
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4557
|
+
if (typeof dispatch !== "function") {
|
|
4558
|
+
try {
|
|
4559
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4560
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4561
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4562
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4563
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4564
|
+
}
|
|
4565
|
+
} catch (e) {
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
if (typeof dispatch === "function") {
|
|
4569
|
+
try {
|
|
4570
|
+
const res = await dispatch({
|
|
3945
4571
|
model: this.model,
|
|
3946
4572
|
messages: formattedMessages,
|
|
3947
4573
|
max_tokens: this.maxTokens,
|
|
3948
4574
|
temperature: this.temperature
|
|
3949
4575
|
}, this.apiKey);
|
|
3950
|
-
|
|
3951
|
-
|
|
4576
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4577
|
+
if (content !== void 0) {
|
|
4578
|
+
return content;
|
|
3952
4579
|
}
|
|
4580
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
|
|
4581
|
+
} catch (dispatchErr) {
|
|
4582
|
+
throw dispatchErr;
|
|
3953
4583
|
}
|
|
3954
|
-
}
|
|
4584
|
+
} else {
|
|
4585
|
+
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.`);
|
|
3955
4586
|
}
|
|
3956
4587
|
}
|
|
3957
4588
|
const { data } = await this.http.post(path2, payload);
|
|
3958
|
-
const extractPath = (
|
|
3959
|
-
const result = resolvePath(data, extractPath);
|
|
4589
|
+
const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
|
|
4590
|
+
const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
|
|
3960
4591
|
if (result === void 0) {
|
|
3961
4592
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
3962
4593
|
}
|
|
@@ -3969,7 +4600,7 @@ ${context != null ? context : "None"}` },
|
|
|
3969
4600
|
*/
|
|
3970
4601
|
chatStream(messages, context) {
|
|
3971
4602
|
return __asyncGenerator(this, null, function* () {
|
|
3972
|
-
var _a2, _b, _c, _d, _e
|
|
4603
|
+
var _a2, _b, _c, _d, _e;
|
|
3973
4604
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3974
4605
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
3975
4606
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
@@ -4003,10 +4634,22 @@ ${context != null ? context : "None"}` },
|
|
|
4003
4634
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4004
4635
|
let streamBody = null;
|
|
4005
4636
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4637
|
+
const _g2 = globalThis;
|
|
4638
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4639
|
+
if (typeof dispatch !== "function") {
|
|
4640
|
+
try {
|
|
4641
|
+
const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
|
|
4642
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4643
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4644
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4645
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4646
|
+
}
|
|
4647
|
+
} catch (e) {
|
|
4648
|
+
}
|
|
4649
|
+
}
|
|
4650
|
+
if (typeof dispatch === "function") {
|
|
4651
|
+
try {
|
|
4652
|
+
const res = yield new __await(dispatch({
|
|
4010
4653
|
model: this.model,
|
|
4011
4654
|
messages: formattedMessages,
|
|
4012
4655
|
max_tokens: this.maxTokens,
|
|
@@ -4015,12 +4658,19 @@ ${context != null ? context : "None"}` },
|
|
|
4015
4658
|
}, this.apiKey));
|
|
4016
4659
|
if (res == null ? void 0 : res.stream) {
|
|
4017
4660
|
streamBody = res.stream;
|
|
4018
|
-
} else
|
|
4019
|
-
|
|
4020
|
-
|
|
4661
|
+
} else {
|
|
4662
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4663
|
+
if (content !== void 0) {
|
|
4664
|
+
yield content;
|
|
4665
|
+
return;
|
|
4666
|
+
}
|
|
4667
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
|
|
4021
4668
|
}
|
|
4669
|
+
} catch (dispatchErr) {
|
|
4670
|
+
throw dispatchErr;
|
|
4022
4671
|
}
|
|
4023
|
-
}
|
|
4672
|
+
} else {
|
|
4673
|
+
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.`);
|
|
4024
4674
|
}
|
|
4025
4675
|
}
|
|
4026
4676
|
if (!streamBody) {
|
|
@@ -4047,14 +4697,14 @@ ${context != null ? context : "None"}` },
|
|
|
4047
4697
|
if (done) break;
|
|
4048
4698
|
buffer += decoder.decode(value, { stream: true });
|
|
4049
4699
|
const lines = buffer.split("\n");
|
|
4050
|
-
buffer = (
|
|
4700
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4051
4701
|
for (const line of lines) {
|
|
4052
4702
|
const trimmed = line.trim();
|
|
4053
4703
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4054
4704
|
if (!trimmed.startsWith("data:")) continue;
|
|
4055
4705
|
try {
|
|
4056
4706
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4057
|
-
const text = resolvePath(json, extractPath);
|
|
4707
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4058
4708
|
if (text && typeof text === "string") yield text;
|
|
4059
4709
|
} catch (e) {
|
|
4060
4710
|
}
|
|
@@ -4064,7 +4714,7 @@ ${context != null ? context : "None"}` },
|
|
|
4064
4714
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4065
4715
|
try {
|
|
4066
4716
|
const json = JSON.parse(jsonStr);
|
|
4067
|
-
const text = resolvePath(json, extractPath);
|
|
4717
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4068
4718
|
if (text && typeof text === "string") yield text;
|
|
4069
4719
|
} catch (e) {
|
|
4070
4720
|
}
|
|
@@ -4091,18 +4741,34 @@ ${context != null ? context : "None"}` },
|
|
|
4091
4741
|
}
|
|
4092
4742
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4093
4743
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4744
|
+
const _g2 = globalThis;
|
|
4745
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4746
|
+
if (typeof dispatch !== "function") {
|
|
4747
|
+
try {
|
|
4748
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4749
|
+
if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
|
|
4750
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4751
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4752
|
+
dispatch = gateway.dispatchEmbedding;
|
|
4753
|
+
}
|
|
4754
|
+
} catch (e) {
|
|
4755
|
+
}
|
|
4756
|
+
}
|
|
4757
|
+
if (typeof dispatch === "function") {
|
|
4758
|
+
try {
|
|
4759
|
+
const res = await dispatch({
|
|
4098
4760
|
model: this.model,
|
|
4099
4761
|
input: text
|
|
4100
4762
|
}, this.apiKey);
|
|
4101
4763
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4102
4764
|
return res.data[0].embedding;
|
|
4103
4765
|
}
|
|
4766
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4767
|
+
} catch (dispatchErr) {
|
|
4768
|
+
throw dispatchErr;
|
|
4104
4769
|
}
|
|
4105
|
-
}
|
|
4770
|
+
} else {
|
|
4771
|
+
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.`);
|
|
4106
4772
|
}
|
|
4107
4773
|
}
|
|
4108
4774
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -4695,7 +5361,8 @@ var Reranker = class {
|
|
|
4695
5361
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
4696
5362
|
}
|
|
4697
5363
|
const scoredMatches = matches.map((match) => {
|
|
4698
|
-
|
|
5364
|
+
var _a2;
|
|
5365
|
+
const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
|
|
4699
5366
|
let keywordScore = 0;
|
|
4700
5367
|
keywords.forEach((keyword) => {
|
|
4701
5368
|
if (contentLower.includes(keyword)) {
|
|
@@ -4716,7 +5383,10 @@ var Reranker = class {
|
|
|
4716
5383
|
[{ role: "user", content: `Query: "${query}"
|
|
4717
5384
|
|
|
4718
5385
|
Documents:
|
|
4719
|
-
${topN.map((m, i) =>
|
|
5386
|
+
${topN.map((m, i) => {
|
|
5387
|
+
var _a2;
|
|
5388
|
+
return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
|
|
5389
|
+
}).join("\n")}` }],
|
|
4720
5390
|
"",
|
|
4721
5391
|
{
|
|
4722
5392
|
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.',
|
|
@@ -5887,10 +6557,10 @@ Return ONLY 'vector', 'graph', or 'both'. No explanation.`;
|
|
|
5887
6557
|
"",
|
|
5888
6558
|
{ temperature: 0, maxTokens: 10 }
|
|
5889
6559
|
);
|
|
5890
|
-
const cleanResponse = response.trim().toLowerCase();
|
|
5891
|
-
if (cleanResponse.includes("vector")) return "vector";
|
|
5892
|
-
if (cleanResponse.includes("graph")) return "graph";
|
|
6560
|
+
const cleanResponse = (response != null ? response : "").trim().toLowerCase();
|
|
5893
6561
|
if (cleanResponse.includes("both")) return "both";
|
|
6562
|
+
if (cleanResponse.includes("graph")) return "graph";
|
|
6563
|
+
if (cleanResponse.includes("vector")) return "vector";
|
|
5894
6564
|
} catch (error) {
|
|
5895
6565
|
console.warn("[QueryProcessor] LLM strategy classification failed, falling back to keywords:", error);
|
|
5896
6566
|
}
|
|
@@ -6064,7 +6734,10 @@ var IntentClassifier = class {
|
|
|
6064
6734
|
hasCategoricalFields = catKeys.size > 0;
|
|
6065
6735
|
numericFieldCount = numericKeys.size;
|
|
6066
6736
|
categoricalFieldCount = catKeys.size;
|
|
6067
|
-
if (productKeyMatches >= 2 || docs.some((d) =>
|
|
6737
|
+
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6738
|
+
var _a2, _b;
|
|
6739
|
+
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");
|
|
6740
|
+
})) {
|
|
6068
6741
|
isProductLike = true;
|
|
6069
6742
|
}
|
|
6070
6743
|
}
|
|
@@ -6344,7 +7017,10 @@ var TextRendererStrategy = class {
|
|
|
6344
7017
|
return { type: "text", title, data: { content: data } };
|
|
6345
7018
|
}
|
|
6346
7019
|
const docs = Array.isArray(data) ? data : [];
|
|
6347
|
-
const text = docs.map((d) =>
|
|
7020
|
+
const text = docs.map((d) => {
|
|
7021
|
+
var _a2;
|
|
7022
|
+
return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
|
|
7023
|
+
}).join("\n\n");
|
|
6348
7024
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6349
7025
|
}
|
|
6350
7026
|
};
|
|
@@ -6601,6 +7277,19 @@ var UITransformer = class _UITransformer {
|
|
|
6601
7277
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6602
7278
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6603
7279
|
}
|
|
7280
|
+
console.log("[UITransformer.transform] Processing retrievedData:", {
|
|
7281
|
+
userQuery,
|
|
7282
|
+
retrievedCount: retrievedData.length,
|
|
7283
|
+
sample: retrievedData.slice(0, 2).map((item) => {
|
|
7284
|
+
var _a3;
|
|
7285
|
+
return {
|
|
7286
|
+
id: item == null ? void 0 : item.id,
|
|
7287
|
+
contentType: typeof (item == null ? void 0 : item.content),
|
|
7288
|
+
contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
|
|
7289
|
+
metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
|
|
7290
|
+
};
|
|
7291
|
+
})
|
|
7292
|
+
});
|
|
6604
7293
|
const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
|
|
6605
7294
|
const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
|
|
6606
7295
|
const profile = this.profileData(filteredData);
|
|
@@ -6941,7 +7630,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
6941
7630
|
}
|
|
6942
7631
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
6943
7632
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
6944
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null)
|
|
7633
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
6945
7634
|
return {
|
|
6946
7635
|
type: "product_carousel",
|
|
6947
7636
|
title: "Recommended Products",
|
|
@@ -7090,7 +7779,10 @@ ${schemaProfileText}` : ""}`;
|
|
|
7090
7779
|
type: "radar_chart",
|
|
7091
7780
|
title: "Product Comparison",
|
|
7092
7781
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7093
|
-
data: radarData.length > 0 ? radarData : data.map((d) =>
|
|
7782
|
+
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7783
|
+
var _a2;
|
|
7784
|
+
return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
|
|
7785
|
+
})
|
|
7094
7786
|
};
|
|
7095
7787
|
}
|
|
7096
7788
|
static transformToTable(data, query = "") {
|
|
@@ -7107,7 +7799,10 @@ ${schemaProfileText}` : ""}`;
|
|
|
7107
7799
|
static transformToText(data) {
|
|
7108
7800
|
return this.createTextResponse(
|
|
7109
7801
|
"Retrieved Context",
|
|
7110
|
-
data.map((item) =>
|
|
7802
|
+
data.map((item) => {
|
|
7803
|
+
var _a2;
|
|
7804
|
+
return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
|
|
7805
|
+
}).join("\n\n"),
|
|
7111
7806
|
`Found ${data.length} relevant results`
|
|
7112
7807
|
);
|
|
7113
7808
|
}
|
|
@@ -7268,6 +7963,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7268
7963
|
return productTerms && productAction && !nonProductEntityTerms;
|
|
7269
7964
|
}
|
|
7270
7965
|
static isProductData(item) {
|
|
7966
|
+
if (!item) return false;
|
|
7271
7967
|
const content = (item.content || "").toLowerCase();
|
|
7272
7968
|
const productKeywords = [
|
|
7273
7969
|
"product",
|
|
@@ -7314,7 +8010,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7314
8010
|
return fieldCount.size > 2;
|
|
7315
8011
|
}
|
|
7316
8012
|
static profileData(data) {
|
|
7317
|
-
const records = data.map((item) => {
|
|
8013
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
8014
|
+
var _a2, _b;
|
|
7318
8015
|
const fields2 = {};
|
|
7319
8016
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7320
8017
|
const primitive = this.toPrimitive(value);
|
|
@@ -7323,8 +8020,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7323
8020
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7324
8021
|
return {
|
|
7325
8022
|
id: item.id,
|
|
7326
|
-
content: item.content,
|
|
7327
|
-
score: item.score,
|
|
8023
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
8024
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7328
8025
|
fields: fields2,
|
|
7329
8026
|
source: item
|
|
7330
8027
|
};
|
|
@@ -7526,12 +8223,12 @@ ${schemaProfileText}` : ""}`;
|
|
|
7526
8223
|
}
|
|
7527
8224
|
static extractTimeSeriesData(data) {
|
|
7528
8225
|
return data.map((item) => {
|
|
7529
|
-
var _a2, _b, _c, _d, _e;
|
|
8226
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
7530
8227
|
const meta = item.metadata || {};
|
|
7531
8228
|
return {
|
|
7532
8229
|
timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7533
8230
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7534
|
-
label: (
|
|
8231
|
+
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7535
8232
|
};
|
|
7536
8233
|
});
|
|
7537
8234
|
}
|
|
@@ -7645,7 +8342,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7645
8342
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7646
8343
|
}
|
|
7647
8344
|
static resolveTableCellValue(item, column) {
|
|
7648
|
-
|
|
8345
|
+
var _a2, _b, _c;
|
|
8346
|
+
if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
|
|
7649
8347
|
const meta = item.metadata || {};
|
|
7650
8348
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7651
8349
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -7656,9 +8354,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7656
8354
|
}
|
|
7657
8355
|
const aliasValue = this.resolveAliasedTableCell(meta, column);
|
|
7658
8356
|
if (aliasValue !== void 0) return this.toDisplayValue(aliasValue);
|
|
7659
|
-
const contentValue = this.extractContentFieldValue(item.content, column);
|
|
8357
|
+
const contentValue = this.extractContentFieldValue((_b = item == null ? void 0 : item.content) != null ? _b : "", column);
|
|
7660
8358
|
if (contentValue !== null) return contentValue;
|
|
7661
|
-
const aliasContentValue = this.extractAliasedContentFieldValue(item.content, column);
|
|
8359
|
+
const aliasContentValue = this.extractAliasedContentFieldValue((_c = item == null ? void 0 : item.content) != null ? _c : "", column);
|
|
7662
8360
|
return aliasContentValue != null ? aliasContentValue : "";
|
|
7663
8361
|
}
|
|
7664
8362
|
static resolveAliasedTableCell(meta, column) {
|
|
@@ -7708,6 +8406,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7708
8406
|
return { inStockCount: inStock, outOfStockCount: outOfStock };
|
|
7709
8407
|
}
|
|
7710
8408
|
static determineStockStatus(item) {
|
|
8409
|
+
if (!item) return true;
|
|
7711
8410
|
const meta = item.metadata || {};
|
|
7712
8411
|
const stockValue = resolveMetadataValue(meta, "stock");
|
|
7713
8412
|
if (stockValue !== void 0) {
|
|
@@ -7753,35 +8452,64 @@ ${schemaProfileText}` : ""}`;
|
|
|
7753
8452
|
return resolveMetadataValue(meta, uiKey);
|
|
7754
8453
|
}
|
|
7755
8454
|
static extractProductInfo(item, config, trainedSchema) {
|
|
7756
|
-
var _a2;
|
|
8455
|
+
var _a2, _b;
|
|
8456
|
+
if (!item) return null;
|
|
7757
8457
|
const meta = item.metadata || {};
|
|
8458
|
+
const content = item.content || "";
|
|
7758
8459
|
const name = this.getDynamicVal(meta, "name", config, trainedSchema);
|
|
7759
8460
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
7760
8461
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
7761
8462
|
const description = this.cleanProductDescription(
|
|
7762
|
-
(_a2 = this.extractProductDescriptionFromContent(
|
|
8463
|
+
(_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
7763
8464
|
);
|
|
7764
8465
|
if (name || this.isProductData(item)) {
|
|
7765
8466
|
let finalName = name ? String(name) : void 0;
|
|
8467
|
+
if (!finalName && content) {
|
|
8468
|
+
const nameMatch = content.match(/(?:Product|Item|Name):\s*([^\n]+)/i);
|
|
8469
|
+
finalName = nameMatch ? nameMatch[1].trim() : (_b = content.split("\n")[0]) == null ? void 0 : _b.substring(0, 60);
|
|
8470
|
+
}
|
|
7766
8471
|
if (!finalName) {
|
|
7767
|
-
|
|
7768
|
-
|
|
8472
|
+
console.warn(
|
|
8473
|
+
`[UITransformer] Unable to read product name from metadata or content for item ${item.id}. Defaulting to 'Unnamed Product'.`,
|
|
8474
|
+
{ metadataKeys: Object.keys(meta), contentLength: content.length }
|
|
8475
|
+
);
|
|
7769
8476
|
}
|
|
7770
8477
|
let finalPrice = typeof price === "number" || typeof price === "string" ? price : void 0;
|
|
7771
|
-
if (!finalPrice) {
|
|
7772
|
-
const priceMatch =
|
|
8478
|
+
if (!finalPrice && content) {
|
|
8479
|
+
const priceMatch = content.match(/(?:Price|Cost):\s*\$?([\d,.]+)/i) || content.match(/\$\s*([\d,.]+)/);
|
|
7773
8480
|
if (priceMatch) finalPrice = priceMatch[1].replace(/,/g, "");
|
|
7774
8481
|
}
|
|
8482
|
+
if (finalPrice === void 0) {
|
|
8483
|
+
console.warn(
|
|
8484
|
+
`[UITransformer] Unable to read product price from metadata or content for item ${item.id}.`,
|
|
8485
|
+
{ metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
|
|
8486
|
+
);
|
|
8487
|
+
}
|
|
7775
8488
|
const imageValue = this.getDynamicVal(meta, "image", config, trainedSchema);
|
|
8489
|
+
if (!imageValue) {
|
|
8490
|
+
console.debug(
|
|
8491
|
+
`[UITransformer] Unable to read product image URL from metadata for item ${item.id}.`
|
|
8492
|
+
);
|
|
8493
|
+
}
|
|
8494
|
+
if (!description) {
|
|
8495
|
+
console.debug(
|
|
8496
|
+
`[UITransformer] Unable to read product description from metadata or content for item ${item.id}.`
|
|
8497
|
+
);
|
|
8498
|
+
}
|
|
7776
8499
|
return {
|
|
7777
8500
|
id: item.id,
|
|
7778
|
-
name: finalName,
|
|
8501
|
+
name: finalName || "Unnamed Product",
|
|
7779
8502
|
price: finalPrice,
|
|
7780
8503
|
image: typeof imageValue === "string" ? imageValue : void 0,
|
|
7781
8504
|
brand: brand ? String(brand) : void 0,
|
|
7782
8505
|
description,
|
|
7783
8506
|
inStock: this.determineStockStatus(item)
|
|
7784
8507
|
};
|
|
8508
|
+
} else {
|
|
8509
|
+
console.warn(
|
|
8510
|
+
`[UITransformer] Item ${item.id} skipped: unable to read name or identify as product data from metadata/content.`,
|
|
8511
|
+
{ metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
|
|
8512
|
+
);
|
|
7785
8513
|
}
|
|
7786
8514
|
return null;
|
|
7787
8515
|
}
|
|
@@ -7866,13 +8594,13 @@ RULES:
|
|
|
7866
8594
|
5. If no relevant data is found, return text: "I cannot answer this question based on the available information."`;
|
|
7867
8595
|
}
|
|
7868
8596
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
7869
|
-
const items = sources.map((s, i) => {
|
|
8597
|
+
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
7870
8598
|
var _a2, _b, _c, _d;
|
|
7871
8599
|
return {
|
|
7872
8600
|
index: i + 1,
|
|
7873
|
-
content: (_b = (_a2 = s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
|
|
7874
|
-
metadata: (_c = s.metadata) != null ? _c : {},
|
|
7875
|
-
score: (_d = s.score) != null ? _d : 0
|
|
8601
|
+
content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
|
|
8602
|
+
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8603
|
+
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
7876
8604
|
};
|
|
7877
8605
|
});
|
|
7878
8606
|
const full = JSON.stringify(items, null, 2);
|
|
@@ -8396,7 +9124,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8396
9124
|
*/
|
|
8397
9125
|
askStreamInternal(_0) {
|
|
8398
9126
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8399
|
-
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
|
|
9127
|
+
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;
|
|
8400
9128
|
yield new __await(this.initialize());
|
|
8401
9129
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8402
9130
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8439,40 +9167,65 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8439
9167
|
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;
|
|
8440
9168
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8441
9169
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8442
|
-
const wantsExhaustiveList =
|
|
8443
|
-
const retrievalLimit =
|
|
8444
|
-
const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
|
|
9170
|
+
const wantsExhaustiveList = true;
|
|
9171
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
9172
|
+
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"));
|
|
9173
|
+
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
9174
|
+
rawCount: rawSources.length,
|
|
9175
|
+
sample: rawSources.slice(0, 2).map((s) => {
|
|
9176
|
+
var _a3;
|
|
9177
|
+
return {
|
|
9178
|
+
id: s == null ? void 0 : s.id,
|
|
9179
|
+
score: s == null ? void 0 : s.score,
|
|
9180
|
+
contentType: typeof (s == null ? void 0 : s.content),
|
|
9181
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9182
|
+
metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
|
|
9183
|
+
};
|
|
9184
|
+
})
|
|
9185
|
+
});
|
|
8445
9186
|
const retrieveEnd = performance.now();
|
|
8446
9187
|
const embedMs = retrieveEnd - embedStart;
|
|
8447
9188
|
const retrieveMs = retrieveEnd - embedStart;
|
|
8448
9189
|
const rerankStart = performance.now();
|
|
8449
|
-
const structuredSources = this.applyStructuredFilters(rawSources, filter);
|
|
8450
|
-
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) =>
|
|
8451
|
-
|
|
9190
|
+
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
9191
|
+
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
9192
|
+
var _a3;
|
|
9193
|
+
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
9194
|
+
});
|
|
9195
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8452
9196
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8453
9197
|
if (!hasNumericPredicates && useReranking) {
|
|
8454
|
-
fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
|
|
8455
|
-
} else if (!wantsExhaustiveList) {
|
|
8456
|
-
fullSources = fullSources.slice(0, topK);
|
|
9198
|
+
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8457
9199
|
}
|
|
8458
9200
|
const rerankMs = performance.now() - rerankStart;
|
|
8459
|
-
|
|
9201
|
+
const totalCount = fullSources.length;
|
|
9202
|
+
const promptSources = fullSources.slice(0, 15);
|
|
9203
|
+
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]
|
|
9204
|
+
|
|
9205
|
+
` + promptSources.map((m, i) => {
|
|
8460
9206
|
var _a3;
|
|
8461
9207
|
return `[Source ${i + 1}]
|
|
8462
9208
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8463
9209
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
}
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
|
|
8475
|
-
|
|
9210
|
+
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
9211
|
+
var _a3, _b2;
|
|
9212
|
+
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
9213
|
+
});
|
|
9214
|
+
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
9215
|
+
count: sources.length,
|
|
9216
|
+
totalRawCount: rawSources.length,
|
|
9217
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
9218
|
+
var _a3;
|
|
9219
|
+
return {
|
|
9220
|
+
rank: idx + 1,
|
|
9221
|
+
id: s == null ? void 0 : s.id,
|
|
9222
|
+
score: s == null ? void 0 : s.score,
|
|
9223
|
+
contentType: typeof (s == null ? void 0 : s.content),
|
|
9224
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9225
|
+
metadata: s == null ? void 0 : s.metadata
|
|
9226
|
+
};
|
|
9227
|
+
})
|
|
9228
|
+
});
|
|
8476
9229
|
if (graphData && graphData.nodes.length > 0) {
|
|
8477
9230
|
const graphContext = graphData.nodes.map(
|
|
8478
9231
|
(n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
|
|
@@ -8498,18 +9251,18 @@ ${context}`;
|
|
|
8498
9251
|
}
|
|
8499
9252
|
yield {
|
|
8500
9253
|
reply: "",
|
|
8501
|
-
sources: sources.map((s) => {
|
|
8502
|
-
var _a3;
|
|
9254
|
+
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
9255
|
+
var _a3, _b2, _c2;
|
|
8503
9256
|
return {
|
|
8504
9257
|
id: s.id,
|
|
8505
|
-
score: s.score,
|
|
8506
|
-
content: s.content,
|
|
8507
|
-
metadata: (
|
|
9258
|
+
score: (_a3 = s.score) != null ? _a3 : 0,
|
|
9259
|
+
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
9260
|
+
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8508
9261
|
namespace: ns
|
|
8509
9262
|
};
|
|
8510
9263
|
})
|
|
8511
9264
|
};
|
|
8512
|
-
const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
|
|
9265
|
+
const allMetadataKeys = Array.from(new Set(sources.filter(Boolean).flatMap((s) => Object.keys((s == null ? void 0 : s.metadata) || {}))));
|
|
8513
9266
|
const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
|
|
8514
9267
|
if (allMetadataKeys.length > 0 && !cachedSchema) {
|
|
8515
9268
|
SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => {
|
|
@@ -8661,7 +9414,7 @@ ${context}`;
|
|
|
8661
9414
|
}
|
|
8662
9415
|
yield fullReply;
|
|
8663
9416
|
}
|
|
8664
|
-
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true
|
|
9417
|
+
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
|
|
8665
9418
|
if (runHallucination) {
|
|
8666
9419
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8667
9420
|
}
|
|
@@ -8670,7 +9423,7 @@ ${context}`;
|
|
|
8670
9423
|
const latency = {
|
|
8671
9424
|
embedMs: Math.round(embedMs),
|
|
8672
9425
|
retrieveMs: Math.round(retrieveMs),
|
|
8673
|
-
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((
|
|
9426
|
+
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
|
|
8674
9427
|
generateMs: Math.round(generateMs),
|
|
8675
9428
|
totalMs: Math.round(totalMs)
|
|
8676
9429
|
};
|
|
@@ -8683,7 +9436,7 @@ ${context}`;
|
|
|
8683
9436
|
totalTokens: promptTokens + completionTokens,
|
|
8684
9437
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8685
9438
|
};
|
|
8686
|
-
const awaitHallucination = ((
|
|
9439
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8687
9440
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8688
9441
|
uiTransformationPromise,
|
|
8689
9442
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8712,10 +9465,10 @@ ${context}`;
|
|
|
8712
9465
|
hallucinationReason: hScore.reason
|
|
8713
9466
|
} : {});
|
|
8714
9467
|
const trace = buildTrace(hallucinationResult);
|
|
8715
|
-
const isTelemetryActive = (
|
|
9468
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8716
9469
|
if (isTelemetryActive) {
|
|
8717
9470
|
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";
|
|
8718
|
-
const telemetryUrl = ((
|
|
9471
|
+
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
8719
9472
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8720
9473
|
(async () => {
|
|
8721
9474
|
try {
|
|
@@ -8774,9 +9527,8 @@ ${context}`;
|
|
|
8774
9527
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8775
9528
|
);
|
|
8776
9529
|
}
|
|
8777
|
-
const
|
|
8778
|
-
|
|
8779
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9530
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9531
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8780
9532
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8781
9533
|
}
|
|
8782
9534
|
try {
|
|
@@ -8801,6 +9553,8 @@ ${context}`;
|
|
|
8801
9553
|
});
|
|
8802
9554
|
}
|
|
8803
9555
|
resolveNumericPredicateValue(source, predicate) {
|
|
9556
|
+
var _a2;
|
|
9557
|
+
if (!source) return null;
|
|
8804
9558
|
const meta = source.metadata || {};
|
|
8805
9559
|
const field = predicate.field;
|
|
8806
9560
|
const entries = Object.entries(meta).filter(([, value]) => value !== null && value !== void 0 && typeof value !== "object");
|
|
@@ -8812,7 +9566,7 @@ ${context}`;
|
|
|
8812
9566
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
8813
9567
|
if (value !== null) return value;
|
|
8814
9568
|
}
|
|
8815
|
-
const contentValue = this.extractNumericValueFromContent(source.content, field);
|
|
9569
|
+
const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
|
|
8816
9570
|
if (contentValue !== null) return contentValue;
|
|
8817
9571
|
}
|
|
8818
9572
|
for (const [key, value] of entries) {
|
|
@@ -8823,6 +9577,7 @@ ${context}`;
|
|
|
8823
9577
|
return null;
|
|
8824
9578
|
}
|
|
8825
9579
|
extractNumericValueFromContent(content, field) {
|
|
9580
|
+
if (!content || typeof content !== "string") return null;
|
|
8826
9581
|
const escapedWords = field.split(/\s+|_+|-+/).filter(Boolean).map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
8827
9582
|
if (escapedWords.length === 0) return null;
|
|
8828
9583
|
const pattern = new RegExp(`(?:${escapedWords.join("[\\\\s_:-]*")})\\s*[:\\-\u2013]?\\s*([\\d,]+(?:\\.\\d+)?)`, "i");
|
|
@@ -8908,6 +9663,20 @@ ${context}`;
|
|
|
8908
9663
|
resolvedSources.push(source);
|
|
8909
9664
|
}
|
|
8910
9665
|
}
|
|
9666
|
+
console.log("[Pipeline] retrieve() response:", {
|
|
9667
|
+
query,
|
|
9668
|
+
namespace: ns,
|
|
9669
|
+
count: resolvedSources.length,
|
|
9670
|
+
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9671
|
+
var _a3;
|
|
9672
|
+
return {
|
|
9673
|
+
id: s == null ? void 0 : s.id,
|
|
9674
|
+
score: s == null ? void 0 : s.score,
|
|
9675
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9676
|
+
metadata: s == null ? void 0 : s.metadata
|
|
9677
|
+
};
|
|
9678
|
+
})
|
|
9679
|
+
});
|
|
8911
9680
|
return { sources: resolvedSources, graphData };
|
|
8912
9681
|
}
|
|
8913
9682
|
/** Rewrite the user query for better retrieval performance. */
|