@retrivora-ai/rag-engine 2.0.6 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/handlers/index.js +863 -94
- package/dist/handlers/index.mjs +863 -94
- package/dist/index.js +84 -26
- package/dist/index.mjs +84 -26
- package/dist/server.js +863 -94
- package/dist/server.mjs +863 -94
- package/package.json +1 -1
- package/src/core/Pipeline.ts +67 -47
- package/src/core/QueryProcessor.ts +3 -3
- package/src/llm/providers/UniversalLLMAdapter.ts +86 -26
- package/src/rag/Reranker.ts +2 -2
- package/src/rendering/IntentClassifier.ts +1 -1
- package/src/rendering/RendererRegistry.ts +1 -1
- package/src/utils/ProductExtractor.ts +1 -1
- package/src/utils/UITransformer.ts +66 -22
package/dist/handlers/index.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({
|
|
@@ -3841,6 +4444,17 @@ var LLM_PROFILES = {
|
|
|
3841
4444
|
};
|
|
3842
4445
|
|
|
3843
4446
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4447
|
+
function extractContent(obj) {
|
|
4448
|
+
var _a2, _b, _c;
|
|
4449
|
+
if (!obj || typeof obj !== "object") return void 0;
|
|
4450
|
+
const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
|
|
4451
|
+
if (!choice) return void 0;
|
|
4452
|
+
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4453
|
+
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
4454
|
+
if (typeof choice.text === "string") return choice.text;
|
|
4455
|
+
if (typeof choice.content === "string") return choice.content;
|
|
4456
|
+
return void 0;
|
|
4457
|
+
}
|
|
3844
4458
|
var UniversalLLMAdapter = class {
|
|
3845
4459
|
constructor(config) {
|
|
3846
4460
|
var _a2, _b, _c, _d, _e, _f, _g2, _h;
|
|
@@ -3872,7 +4486,7 @@ var UniversalLLMAdapter = class {
|
|
|
3872
4486
|
});
|
|
3873
4487
|
}
|
|
3874
4488
|
async chat(messages, context) {
|
|
3875
|
-
var _a2, _b, _c
|
|
4489
|
+
var _a2, _b, _c;
|
|
3876
4490
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3877
4491
|
const formattedMessages = [
|
|
3878
4492
|
{ role: "system", content: `${this.systemPrompt}
|
|
@@ -3899,25 +4513,42 @@ ${context != null ? context : "None"}` },
|
|
|
3899
4513
|
}
|
|
3900
4514
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3901
4515
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
4516
|
+
const _g2 = globalThis;
|
|
4517
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4518
|
+
if (typeof dispatch !== "function") {
|
|
4519
|
+
try {
|
|
4520
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4521
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4522
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4523
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4524
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4525
|
+
}
|
|
4526
|
+
} catch (e) {
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
if (typeof dispatch === "function") {
|
|
4530
|
+
try {
|
|
4531
|
+
const res = await dispatch({
|
|
3906
4532
|
model: this.model,
|
|
3907
4533
|
messages: formattedMessages,
|
|
3908
4534
|
max_tokens: this.maxTokens,
|
|
3909
4535
|
temperature: this.temperature
|
|
3910
4536
|
}, this.apiKey);
|
|
3911
|
-
|
|
3912
|
-
|
|
4537
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4538
|
+
if (content !== void 0) {
|
|
4539
|
+
return content;
|
|
3913
4540
|
}
|
|
4541
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
|
|
4542
|
+
} catch (dispatchErr) {
|
|
4543
|
+
throw dispatchErr;
|
|
3914
4544
|
}
|
|
3915
|
-
}
|
|
4545
|
+
} else {
|
|
4546
|
+
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.`);
|
|
3916
4547
|
}
|
|
3917
4548
|
}
|
|
3918
4549
|
const { data } = await this.http.post(path2, payload);
|
|
3919
|
-
const extractPath = (
|
|
3920
|
-
const result = resolvePath(data, extractPath);
|
|
4550
|
+
const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
|
|
4551
|
+
const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
|
|
3921
4552
|
if (result === void 0) {
|
|
3922
4553
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
3923
4554
|
}
|
|
@@ -3930,7 +4561,7 @@ ${context != null ? context : "None"}` },
|
|
|
3930
4561
|
*/
|
|
3931
4562
|
chatStream(messages, context) {
|
|
3932
4563
|
return __asyncGenerator(this, null, function* () {
|
|
3933
|
-
var _a2, _b, _c, _d, _e
|
|
4564
|
+
var _a2, _b, _c, _d, _e;
|
|
3934
4565
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3935
4566
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
3936
4567
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
@@ -3964,10 +4595,22 @@ ${context != null ? context : "None"}` },
|
|
|
3964
4595
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3965
4596
|
let streamBody = null;
|
|
3966
4597
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
4598
|
+
const _g2 = globalThis;
|
|
4599
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4600
|
+
if (typeof dispatch !== "function") {
|
|
4601
|
+
try {
|
|
4602
|
+
const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
|
|
4603
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4604
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4605
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4606
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4607
|
+
}
|
|
4608
|
+
} catch (e) {
|
|
4609
|
+
}
|
|
4610
|
+
}
|
|
4611
|
+
if (typeof dispatch === "function") {
|
|
4612
|
+
try {
|
|
4613
|
+
const res = yield new __await(dispatch({
|
|
3971
4614
|
model: this.model,
|
|
3972
4615
|
messages: formattedMessages,
|
|
3973
4616
|
max_tokens: this.maxTokens,
|
|
@@ -3976,12 +4619,19 @@ ${context != null ? context : "None"}` },
|
|
|
3976
4619
|
}, this.apiKey));
|
|
3977
4620
|
if (res == null ? void 0 : res.stream) {
|
|
3978
4621
|
streamBody = res.stream;
|
|
3979
|
-
} else
|
|
3980
|
-
|
|
3981
|
-
|
|
4622
|
+
} else {
|
|
4623
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4624
|
+
if (content !== void 0) {
|
|
4625
|
+
yield content;
|
|
4626
|
+
return;
|
|
4627
|
+
}
|
|
4628
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
|
|
3982
4629
|
}
|
|
4630
|
+
} catch (dispatchErr) {
|
|
4631
|
+
throw dispatchErr;
|
|
3983
4632
|
}
|
|
3984
|
-
}
|
|
4633
|
+
} else {
|
|
4634
|
+
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.`);
|
|
3985
4635
|
}
|
|
3986
4636
|
}
|
|
3987
4637
|
if (!streamBody) {
|
|
@@ -4008,14 +4658,14 @@ ${context != null ? context : "None"}` },
|
|
|
4008
4658
|
if (done) break;
|
|
4009
4659
|
buffer += decoder.decode(value, { stream: true });
|
|
4010
4660
|
const lines = buffer.split("\n");
|
|
4011
|
-
buffer = (
|
|
4661
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4012
4662
|
for (const line of lines) {
|
|
4013
4663
|
const trimmed = line.trim();
|
|
4014
4664
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4015
4665
|
if (!trimmed.startsWith("data:")) continue;
|
|
4016
4666
|
try {
|
|
4017
4667
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4018
|
-
const text = resolvePath(json, extractPath);
|
|
4668
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4019
4669
|
if (text && typeof text === "string") yield text;
|
|
4020
4670
|
} catch (e) {
|
|
4021
4671
|
}
|
|
@@ -4025,7 +4675,7 @@ ${context != null ? context : "None"}` },
|
|
|
4025
4675
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4026
4676
|
try {
|
|
4027
4677
|
const json = JSON.parse(jsonStr);
|
|
4028
|
-
const text = resolvePath(json, extractPath);
|
|
4678
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4029
4679
|
if (text && typeof text === "string") yield text;
|
|
4030
4680
|
} catch (e) {
|
|
4031
4681
|
}
|
|
@@ -4052,18 +4702,34 @@ ${context != null ? context : "None"}` },
|
|
|
4052
4702
|
}
|
|
4053
4703
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4054
4704
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4705
|
+
const _g2 = globalThis;
|
|
4706
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4707
|
+
if (typeof dispatch !== "function") {
|
|
4708
|
+
try {
|
|
4709
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4710
|
+
if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
|
|
4711
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4712
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4713
|
+
dispatch = gateway.dispatchEmbedding;
|
|
4714
|
+
}
|
|
4715
|
+
} catch (e) {
|
|
4716
|
+
}
|
|
4717
|
+
}
|
|
4718
|
+
if (typeof dispatch === "function") {
|
|
4719
|
+
try {
|
|
4720
|
+
const res = await dispatch({
|
|
4059
4721
|
model: this.model,
|
|
4060
4722
|
input: text
|
|
4061
4723
|
}, this.apiKey);
|
|
4062
4724
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4063
4725
|
return res.data[0].embedding;
|
|
4064
4726
|
}
|
|
4727
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4728
|
+
} catch (dispatchErr) {
|
|
4729
|
+
throw dispatchErr;
|
|
4065
4730
|
}
|
|
4066
|
-
}
|
|
4731
|
+
} else {
|
|
4732
|
+
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.`);
|
|
4067
4733
|
}
|
|
4068
4734
|
}
|
|
4069
4735
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -4656,7 +5322,8 @@ var Reranker = class {
|
|
|
4656
5322
|
return matches.sort((a, b) => b.score - a.score).slice(0, limit);
|
|
4657
5323
|
}
|
|
4658
5324
|
const scoredMatches = matches.map((match) => {
|
|
4659
|
-
|
|
5325
|
+
var _a2;
|
|
5326
|
+
const contentLower = ((_a2 = match == null ? void 0 : match.content) != null ? _a2 : "").toLowerCase();
|
|
4660
5327
|
let keywordScore = 0;
|
|
4661
5328
|
keywords.forEach((keyword) => {
|
|
4662
5329
|
if (contentLower.includes(keyword)) {
|
|
@@ -4677,7 +5344,10 @@ var Reranker = class {
|
|
|
4677
5344
|
[{ role: "user", content: `Query: "${query}"
|
|
4678
5345
|
|
|
4679
5346
|
Documents:
|
|
4680
|
-
${topN.map((m, i) =>
|
|
5347
|
+
${topN.map((m, i) => {
|
|
5348
|
+
var _a2;
|
|
5349
|
+
return `[${i}] ${((_a2 = m == null ? void 0 : m.content) != null ? _a2 : "").replace(/\n/g, " ")}`;
|
|
5350
|
+
}).join("\n")}` }],
|
|
4681
5351
|
"",
|
|
4682
5352
|
{
|
|
4683
5353
|
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.',
|
|
@@ -5842,10 +6512,10 @@ Return ONLY 'vector', 'graph', or 'both'. No explanation.`;
|
|
|
5842
6512
|
"",
|
|
5843
6513
|
{ temperature: 0, maxTokens: 10 }
|
|
5844
6514
|
);
|
|
5845
|
-
const cleanResponse = response.trim().toLowerCase();
|
|
5846
|
-
if (cleanResponse.includes("vector")) return "vector";
|
|
5847
|
-
if (cleanResponse.includes("graph")) return "graph";
|
|
6515
|
+
const cleanResponse = (response != null ? response : "").trim().toLowerCase();
|
|
5848
6516
|
if (cleanResponse.includes("both")) return "both";
|
|
6517
|
+
if (cleanResponse.includes("graph")) return "graph";
|
|
6518
|
+
if (cleanResponse.includes("vector")) return "vector";
|
|
5849
6519
|
} catch (error) {
|
|
5850
6520
|
console.warn("[QueryProcessor] LLM strategy classification failed, falling back to keywords:", error);
|
|
5851
6521
|
}
|
|
@@ -6019,7 +6689,10 @@ var IntentClassifier = class {
|
|
|
6019
6689
|
hasCategoricalFields = catKeys.size > 0;
|
|
6020
6690
|
numericFieldCount = numericKeys.size;
|
|
6021
6691
|
categoricalFieldCount = catKeys.size;
|
|
6022
|
-
if (productKeyMatches >= 2 || docs.some((d) =>
|
|
6692
|
+
if (productKeyMatches >= 2 || docs.some((d) => {
|
|
6693
|
+
var _a2, _b;
|
|
6694
|
+
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");
|
|
6695
|
+
})) {
|
|
6023
6696
|
isProductLike = true;
|
|
6024
6697
|
}
|
|
6025
6698
|
}
|
|
@@ -6299,7 +6972,10 @@ var TextRendererStrategy = class {
|
|
|
6299
6972
|
return { type: "text", title, data: { content: data } };
|
|
6300
6973
|
}
|
|
6301
6974
|
const docs = Array.isArray(data) ? data : [];
|
|
6302
|
-
const text = docs.map((d) =>
|
|
6975
|
+
const text = docs.map((d) => {
|
|
6976
|
+
var _a2;
|
|
6977
|
+
return (_a2 = d == null ? void 0 : d.content) != null ? _a2 : "";
|
|
6978
|
+
}).join("\n\n");
|
|
6303
6979
|
return { type: "text", title, data: { content: text || "No detailed content available." } };
|
|
6304
6980
|
}
|
|
6305
6981
|
};
|
|
@@ -6548,6 +7224,19 @@ var UITransformer = class _UITransformer {
|
|
|
6548
7224
|
if (!retrievedData || retrievedData.length === 0) {
|
|
6549
7225
|
return this.createTextResponse("No data available", "No relevant data found for your query.");
|
|
6550
7226
|
}
|
|
7227
|
+
console.log("[UITransformer.transform] Processing retrievedData:", {
|
|
7228
|
+
userQuery,
|
|
7229
|
+
retrievedCount: retrievedData.length,
|
|
7230
|
+
sample: retrievedData.slice(0, 2).map((item) => {
|
|
7231
|
+
var _a3;
|
|
7232
|
+
return {
|
|
7233
|
+
id: item == null ? void 0 : item.id,
|
|
7234
|
+
contentType: typeof (item == null ? void 0 : item.content),
|
|
7235
|
+
contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
|
|
7236
|
+
metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
|
|
7237
|
+
};
|
|
7238
|
+
})
|
|
7239
|
+
});
|
|
6551
7240
|
const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
|
|
6552
7241
|
const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
|
|
6553
7242
|
const profile = this.profileData(filteredData);
|
|
@@ -6888,7 +7577,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
6888
7577
|
}
|
|
6889
7578
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
6890
7579
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
6891
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null)
|
|
7580
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
6892
7581
|
return {
|
|
6893
7582
|
type: "product_carousel",
|
|
6894
7583
|
title: "Recommended Products",
|
|
@@ -7037,7 +7726,10 @@ ${schemaProfileText}` : ""}`;
|
|
|
7037
7726
|
type: "radar_chart",
|
|
7038
7727
|
title: "Product Comparison",
|
|
7039
7728
|
description: `Comparing ${data.length} items across ${radarData.length} attributes`,
|
|
7040
|
-
data: radarData.length > 0 ? radarData : data.map((d) =>
|
|
7729
|
+
data: radarData.length > 0 ? radarData : data.map((d) => {
|
|
7730
|
+
var _a2;
|
|
7731
|
+
return { attribute: ((_a2 = d == null ? void 0 : d.content) != null ? _a2 : "").substring(0, 40) };
|
|
7732
|
+
})
|
|
7041
7733
|
};
|
|
7042
7734
|
}
|
|
7043
7735
|
static transformToTable(data, query = "") {
|
|
@@ -7054,7 +7746,10 @@ ${schemaProfileText}` : ""}`;
|
|
|
7054
7746
|
static transformToText(data) {
|
|
7055
7747
|
return this.createTextResponse(
|
|
7056
7748
|
"Retrieved Context",
|
|
7057
|
-
data.map((item) =>
|
|
7749
|
+
data.map((item) => {
|
|
7750
|
+
var _a2;
|
|
7751
|
+
return (_a2 = item == null ? void 0 : item.content) != null ? _a2 : "";
|
|
7752
|
+
}).join("\n\n"),
|
|
7058
7753
|
`Found ${data.length} relevant results`
|
|
7059
7754
|
);
|
|
7060
7755
|
}
|
|
@@ -7215,6 +7910,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7215
7910
|
return productTerms && productAction && !nonProductEntityTerms;
|
|
7216
7911
|
}
|
|
7217
7912
|
static isProductData(item) {
|
|
7913
|
+
if (!item) return false;
|
|
7218
7914
|
const content = (item.content || "").toLowerCase();
|
|
7219
7915
|
const productKeywords = [
|
|
7220
7916
|
"product",
|
|
@@ -7261,7 +7957,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7261
7957
|
return fieldCount.size > 2;
|
|
7262
7958
|
}
|
|
7263
7959
|
static profileData(data) {
|
|
7264
|
-
const records = data.map((item) => {
|
|
7960
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7961
|
+
var _a2, _b;
|
|
7265
7962
|
const fields2 = {};
|
|
7266
7963
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7267
7964
|
const primitive = this.toPrimitive(value);
|
|
@@ -7270,8 +7967,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7270
7967
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7271
7968
|
return {
|
|
7272
7969
|
id: item.id,
|
|
7273
|
-
content: item.content,
|
|
7274
|
-
score: item.score,
|
|
7970
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
7971
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7275
7972
|
fields: fields2,
|
|
7276
7973
|
source: item
|
|
7277
7974
|
};
|
|
@@ -7473,12 +8170,12 @@ ${schemaProfileText}` : ""}`;
|
|
|
7473
8170
|
}
|
|
7474
8171
|
static extractTimeSeriesData(data) {
|
|
7475
8172
|
return data.map((item) => {
|
|
7476
|
-
var _a2, _b, _c, _d, _e;
|
|
8173
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
7477
8174
|
const meta = item.metadata || {};
|
|
7478
8175
|
return {
|
|
7479
8176
|
timestamp: (_b = (_a2 = meta.timestamp) != null ? _a2 : meta.date) != null ? _b : (/* @__PURE__ */ new Date()).toISOString(),
|
|
7480
8177
|
value: (_d = (_c = meta.value) != null ? _c : item.score) != null ? _d : 0,
|
|
7481
|
-
label: (
|
|
8178
|
+
label: (_f = meta.label) != null ? _f : ((_e = item == null ? void 0 : item.content) != null ? _e : "").substring(0, 50)
|
|
7482
8179
|
};
|
|
7483
8180
|
});
|
|
7484
8181
|
}
|
|
@@ -7592,7 +8289,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7592
8289
|
}, query.includes(normalizedField) ? 3 : 0);
|
|
7593
8290
|
}
|
|
7594
8291
|
static resolveTableCellValue(item, column) {
|
|
7595
|
-
|
|
8292
|
+
var _a2, _b, _c;
|
|
8293
|
+
if (column === "Content") return ((_a2 = item == null ? void 0 : item.content) != null ? _a2 : "").substring(0, 100);
|
|
7596
8294
|
const meta = item.metadata || {};
|
|
7597
8295
|
const normalizedColumn = this.normalizeComparableField(column);
|
|
7598
8296
|
const exactMetadata = Object.entries(meta).find(
|
|
@@ -7603,9 +8301,9 @@ ${schemaProfileText}` : ""}`;
|
|
|
7603
8301
|
}
|
|
7604
8302
|
const aliasValue = this.resolveAliasedTableCell(meta, column);
|
|
7605
8303
|
if (aliasValue !== void 0) return this.toDisplayValue(aliasValue);
|
|
7606
|
-
const contentValue = this.extractContentFieldValue(item.content, column);
|
|
8304
|
+
const contentValue = this.extractContentFieldValue((_b = item == null ? void 0 : item.content) != null ? _b : "", column);
|
|
7607
8305
|
if (contentValue !== null) return contentValue;
|
|
7608
|
-
const aliasContentValue = this.extractAliasedContentFieldValue(item.content, column);
|
|
8306
|
+
const aliasContentValue = this.extractAliasedContentFieldValue((_c = item == null ? void 0 : item.content) != null ? _c : "", column);
|
|
7609
8307
|
return aliasContentValue != null ? aliasContentValue : "";
|
|
7610
8308
|
}
|
|
7611
8309
|
static resolveAliasedTableCell(meta, column) {
|
|
@@ -7655,6 +8353,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7655
8353
|
return { inStockCount: inStock, outOfStockCount: outOfStock };
|
|
7656
8354
|
}
|
|
7657
8355
|
static determineStockStatus(item) {
|
|
8356
|
+
if (!item) return true;
|
|
7658
8357
|
const meta = item.metadata || {};
|
|
7659
8358
|
const stockValue = resolveMetadataValue(meta, "stock");
|
|
7660
8359
|
if (stockValue !== void 0) {
|
|
@@ -7700,35 +8399,64 @@ ${schemaProfileText}` : ""}`;
|
|
|
7700
8399
|
return resolveMetadataValue(meta, uiKey);
|
|
7701
8400
|
}
|
|
7702
8401
|
static extractProductInfo(item, config, trainedSchema) {
|
|
7703
|
-
var _a2;
|
|
8402
|
+
var _a2, _b;
|
|
8403
|
+
if (!item) return null;
|
|
7704
8404
|
const meta = item.metadata || {};
|
|
8405
|
+
const content = item.content || "";
|
|
7705
8406
|
const name = this.getDynamicVal(meta, "name", config, trainedSchema);
|
|
7706
8407
|
const price = this.getDynamicVal(meta, "price", config, trainedSchema);
|
|
7707
8408
|
const brand = this.getDynamicVal(meta, "brand", config, trainedSchema);
|
|
7708
8409
|
const description = this.cleanProductDescription(
|
|
7709
|
-
(_a2 = this.extractProductDescriptionFromContent(
|
|
8410
|
+
(_a2 = this.extractProductDescriptionFromContent(content)) != null ? _a2 : this.getProductDescriptionValue(meta, config, trainedSchema)
|
|
7710
8411
|
);
|
|
7711
8412
|
if (name || this.isProductData(item)) {
|
|
7712
8413
|
let finalName = name ? String(name) : void 0;
|
|
8414
|
+
if (!finalName && content) {
|
|
8415
|
+
const nameMatch = content.match(/(?:Product|Item|Name):\s*([^\n]+)/i);
|
|
8416
|
+
finalName = nameMatch ? nameMatch[1].trim() : (_b = content.split("\n")[0]) == null ? void 0 : _b.substring(0, 60);
|
|
8417
|
+
}
|
|
7713
8418
|
if (!finalName) {
|
|
7714
|
-
|
|
7715
|
-
|
|
8419
|
+
console.warn(
|
|
8420
|
+
`[UITransformer] Unable to read product name from metadata or content for item ${item.id}. Defaulting to 'Unnamed Product'.`,
|
|
8421
|
+
{ metadataKeys: Object.keys(meta), contentLength: content.length }
|
|
8422
|
+
);
|
|
7716
8423
|
}
|
|
7717
8424
|
let finalPrice = typeof price === "number" || typeof price === "string" ? price : void 0;
|
|
7718
|
-
if (!finalPrice) {
|
|
7719
|
-
const priceMatch =
|
|
8425
|
+
if (!finalPrice && content) {
|
|
8426
|
+
const priceMatch = content.match(/(?:Price|Cost):\s*\$?([\d,.]+)/i) || content.match(/\$\s*([\d,.]+)/);
|
|
7720
8427
|
if (priceMatch) finalPrice = priceMatch[1].replace(/,/g, "");
|
|
7721
8428
|
}
|
|
8429
|
+
if (finalPrice === void 0) {
|
|
8430
|
+
console.warn(
|
|
8431
|
+
`[UITransformer] Unable to read product price from metadata or content for item ${item.id}.`,
|
|
8432
|
+
{ metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
|
|
8433
|
+
);
|
|
8434
|
+
}
|
|
7722
8435
|
const imageValue = this.getDynamicVal(meta, "image", config, trainedSchema);
|
|
8436
|
+
if (!imageValue) {
|
|
8437
|
+
console.debug(
|
|
8438
|
+
`[UITransformer] Unable to read product image URL from metadata for item ${item.id}.`
|
|
8439
|
+
);
|
|
8440
|
+
}
|
|
8441
|
+
if (!description) {
|
|
8442
|
+
console.debug(
|
|
8443
|
+
`[UITransformer] Unable to read product description from metadata or content for item ${item.id}.`
|
|
8444
|
+
);
|
|
8445
|
+
}
|
|
7723
8446
|
return {
|
|
7724
8447
|
id: item.id,
|
|
7725
|
-
name: finalName,
|
|
8448
|
+
name: finalName || "Unnamed Product",
|
|
7726
8449
|
price: finalPrice,
|
|
7727
8450
|
image: typeof imageValue === "string" ? imageValue : void 0,
|
|
7728
8451
|
brand: brand ? String(brand) : void 0,
|
|
7729
8452
|
description,
|
|
7730
8453
|
inStock: this.determineStockStatus(item)
|
|
7731
8454
|
};
|
|
8455
|
+
} else {
|
|
8456
|
+
console.warn(
|
|
8457
|
+
`[UITransformer] Item ${item.id} skipped: unable to read name or identify as product data from metadata/content.`,
|
|
8458
|
+
{ metadataKeys: Object.keys(meta), contentSnippet: content.substring(0, 100) }
|
|
8459
|
+
);
|
|
7732
8460
|
}
|
|
7733
8461
|
return null;
|
|
7734
8462
|
}
|
|
@@ -7813,13 +8541,13 @@ RULES:
|
|
|
7813
8541
|
5. If no relevant data is found, return text: "I cannot answer this question based on the available information."`;
|
|
7814
8542
|
}
|
|
7815
8543
|
static buildContextSummary(sources, maxChars = 6e3) {
|
|
7816
|
-
const items = sources.map((s, i) => {
|
|
8544
|
+
const items = (sources || []).filter(Boolean).map((s, i) => {
|
|
7817
8545
|
var _a2, _b, _c, _d;
|
|
7818
8546
|
return {
|
|
7819
8547
|
index: i + 1,
|
|
7820
|
-
content: (_b = (_a2 = s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
|
|
7821
|
-
metadata: (_c = s.metadata) != null ? _c : {},
|
|
7822
|
-
score: (_d = s.score) != null ? _d : 0
|
|
8548
|
+
content: (_b = (_a2 = s == null ? void 0 : s.content) == null ? void 0 : _a2.substring(0, 400)) != null ? _b : "",
|
|
8549
|
+
metadata: (_c = s == null ? void 0 : s.metadata) != null ? _c : {},
|
|
8550
|
+
score: (_d = s == null ? void 0 : s.score) != null ? _d : 0
|
|
7823
8551
|
};
|
|
7824
8552
|
});
|
|
7825
8553
|
const full = JSON.stringify(items, null, 2);
|
|
@@ -8343,7 +9071,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8343
9071
|
*/
|
|
8344
9072
|
askStreamInternal(_0) {
|
|
8345
9073
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8346
|
-
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
|
|
9074
|
+
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;
|
|
8347
9075
|
yield new __await(this.initialize());
|
|
8348
9076
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8349
9077
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8386,40 +9114,65 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8386
9114
|
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;
|
|
8387
9115
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8388
9116
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8389
|
-
const wantsExhaustiveList =
|
|
8390
|
-
const retrievalLimit =
|
|
8391
|
-
const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
|
|
9117
|
+
const wantsExhaustiveList = true;
|
|
9118
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
9119
|
+
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"));
|
|
9120
|
+
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
9121
|
+
rawCount: rawSources.length,
|
|
9122
|
+
sample: rawSources.slice(0, 2).map((s) => {
|
|
9123
|
+
var _a3;
|
|
9124
|
+
return {
|
|
9125
|
+
id: s == null ? void 0 : s.id,
|
|
9126
|
+
score: s == null ? void 0 : s.score,
|
|
9127
|
+
contentType: typeof (s == null ? void 0 : s.content),
|
|
9128
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9129
|
+
metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
|
|
9130
|
+
};
|
|
9131
|
+
})
|
|
9132
|
+
});
|
|
8392
9133
|
const retrieveEnd = performance.now();
|
|
8393
9134
|
const embedMs = retrieveEnd - embedStart;
|
|
8394
9135
|
const retrieveMs = retrieveEnd - embedStart;
|
|
8395
9136
|
const rerankStart = performance.now();
|
|
8396
|
-
const structuredSources = this.applyStructuredFilters(rawSources, filter);
|
|
8397
|
-
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) =>
|
|
8398
|
-
|
|
9137
|
+
const structuredSources = this.applyStructuredFilters(rawSources, filter).filter((s) => Boolean(s && typeof s === "object"));
|
|
9138
|
+
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => {
|
|
9139
|
+
var _a3;
|
|
9140
|
+
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
9141
|
+
});
|
|
9142
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8399
9143
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8400
9144
|
if (!hasNumericPredicates && useReranking) {
|
|
8401
|
-
fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
|
|
8402
|
-
} else if (!wantsExhaustiveList) {
|
|
8403
|
-
fullSources = fullSources.slice(0, topK);
|
|
9145
|
+
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8404
9146
|
}
|
|
8405
9147
|
const rerankMs = performance.now() - rerankStart;
|
|
8406
|
-
|
|
9148
|
+
const totalCount = fullSources.length;
|
|
9149
|
+
const promptSources = fullSources.slice(0, 15);
|
|
9150
|
+
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]
|
|
9151
|
+
|
|
9152
|
+
` + promptSources.map((m, i) => {
|
|
8407
9153
|
var _a3;
|
|
8408
9154
|
return `[Source ${i + 1}]
|
|
8409
9155
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8410
9156
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
}
|
|
8415
|
-
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
9157
|
+
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
9158
|
+
var _a3, _b2;
|
|
9159
|
+
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
9160
|
+
});
|
|
9161
|
+
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
9162
|
+
count: sources.length,
|
|
9163
|
+
totalRawCount: rawSources.length,
|
|
9164
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
9165
|
+
var _a3;
|
|
9166
|
+
return {
|
|
9167
|
+
rank: idx + 1,
|
|
9168
|
+
id: s == null ? void 0 : s.id,
|
|
9169
|
+
score: s == null ? void 0 : s.score,
|
|
9170
|
+
contentType: typeof (s == null ? void 0 : s.content),
|
|
9171
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9172
|
+
metadata: s == null ? void 0 : s.metadata
|
|
9173
|
+
};
|
|
9174
|
+
})
|
|
9175
|
+
});
|
|
8423
9176
|
if (graphData && graphData.nodes.length > 0) {
|
|
8424
9177
|
const graphContext = graphData.nodes.map(
|
|
8425
9178
|
(n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
|
|
@@ -8445,18 +9198,18 @@ ${context}`;
|
|
|
8445
9198
|
}
|
|
8446
9199
|
yield {
|
|
8447
9200
|
reply: "",
|
|
8448
|
-
sources: sources.map((s) => {
|
|
8449
|
-
var _a3;
|
|
9201
|
+
sources: (sources || []).filter((s) => Boolean(s && typeof s === "object")).map((s) => {
|
|
9202
|
+
var _a3, _b2, _c2;
|
|
8450
9203
|
return {
|
|
8451
9204
|
id: s.id,
|
|
8452
|
-
score: s.score,
|
|
8453
|
-
content: s.content,
|
|
8454
|
-
metadata: (
|
|
9205
|
+
score: (_a3 = s.score) != null ? _a3 : 0,
|
|
9206
|
+
content: (_b2 = s == null ? void 0 : s.content) != null ? _b2 : "",
|
|
9207
|
+
metadata: (_c2 = s == null ? void 0 : s.metadata) != null ? _c2 : {},
|
|
8455
9208
|
namespace: ns
|
|
8456
9209
|
};
|
|
8457
9210
|
})
|
|
8458
9211
|
};
|
|
8459
|
-
const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
|
|
9212
|
+
const allMetadataKeys = Array.from(new Set(sources.filter(Boolean).flatMap((s) => Object.keys((s == null ? void 0 : s.metadata) || {}))));
|
|
8460
9213
|
const cachedSchema = allMetadataKeys.length > 0 ? SchemaMapper.getCached(ns, allMetadataKeys) : void 0;
|
|
8461
9214
|
if (allMetadataKeys.length > 0 && !cachedSchema) {
|
|
8462
9215
|
SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => {
|
|
@@ -8608,7 +9361,7 @@ ${context}`;
|
|
|
8608
9361
|
}
|
|
8609
9362
|
yield fullReply;
|
|
8610
9363
|
}
|
|
8611
|
-
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true
|
|
9364
|
+
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
|
|
8612
9365
|
if (runHallucination) {
|
|
8613
9366
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8614
9367
|
}
|
|
@@ -8617,7 +9370,7 @@ ${context}`;
|
|
|
8617
9370
|
const latency = {
|
|
8618
9371
|
embedMs: Math.round(embedMs),
|
|
8619
9372
|
retrieveMs: Math.round(retrieveMs),
|
|
8620
|
-
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((
|
|
9373
|
+
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
|
|
8621
9374
|
generateMs: Math.round(generateMs),
|
|
8622
9375
|
totalMs: Math.round(totalMs)
|
|
8623
9376
|
};
|
|
@@ -8630,7 +9383,7 @@ ${context}`;
|
|
|
8630
9383
|
totalTokens: promptTokens + completionTokens,
|
|
8631
9384
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8632
9385
|
};
|
|
8633
|
-
const awaitHallucination = ((
|
|
9386
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8634
9387
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8635
9388
|
uiTransformationPromise,
|
|
8636
9389
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8659,10 +9412,10 @@ ${context}`;
|
|
|
8659
9412
|
hallucinationReason: hScore.reason
|
|
8660
9413
|
} : {});
|
|
8661
9414
|
const trace = buildTrace(hallucinationResult);
|
|
8662
|
-
const isTelemetryActive = (
|
|
9415
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8663
9416
|
if (isTelemetryActive) {
|
|
8664
9417
|
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";
|
|
8665
|
-
const telemetryUrl = ((
|
|
9418
|
+
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
8666
9419
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8667
9420
|
(async () => {
|
|
8668
9421
|
try {
|
|
@@ -8721,9 +9474,8 @@ ${context}`;
|
|
|
8721
9474
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8722
9475
|
);
|
|
8723
9476
|
}
|
|
8724
|
-
const
|
|
8725
|
-
|
|
8726
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9477
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9478
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8727
9479
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8728
9480
|
}
|
|
8729
9481
|
try {
|
|
@@ -8748,6 +9500,8 @@ ${context}`;
|
|
|
8748
9500
|
});
|
|
8749
9501
|
}
|
|
8750
9502
|
resolveNumericPredicateValue(source, predicate) {
|
|
9503
|
+
var _a2;
|
|
9504
|
+
if (!source) return null;
|
|
8751
9505
|
const meta = source.metadata || {};
|
|
8752
9506
|
const field = predicate.field;
|
|
8753
9507
|
const entries = Object.entries(meta).filter(([, value]) => value !== null && value !== void 0 && typeof value !== "object");
|
|
@@ -8759,7 +9513,7 @@ ${context}`;
|
|
|
8759
9513
|
const value = this.toFiniteNumber(Array.isArray(fuzzy) ? fuzzy[1] : fuzzy.value);
|
|
8760
9514
|
if (value !== null) return value;
|
|
8761
9515
|
}
|
|
8762
|
-
const contentValue = this.extractNumericValueFromContent(source.content, field);
|
|
9516
|
+
const contentValue = this.extractNumericValueFromContent((_a2 = source.content) != null ? _a2 : "", field);
|
|
8763
9517
|
if (contentValue !== null) return contentValue;
|
|
8764
9518
|
}
|
|
8765
9519
|
for (const [key, value] of entries) {
|
|
@@ -8770,6 +9524,7 @@ ${context}`;
|
|
|
8770
9524
|
return null;
|
|
8771
9525
|
}
|
|
8772
9526
|
extractNumericValueFromContent(content, field) {
|
|
9527
|
+
if (!content || typeof content !== "string") return null;
|
|
8773
9528
|
const escapedWords = field.split(/\s+|_+|-+/).filter(Boolean).map((word) => word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
8774
9529
|
if (escapedWords.length === 0) return null;
|
|
8775
9530
|
const pattern = new RegExp(`(?:${escapedWords.join("[\\\\s_:-]*")})\\s*[:\\-\u2013]?\\s*([\\d,]+(?:\\.\\d+)?)`, "i");
|
|
@@ -8855,6 +9610,20 @@ ${context}`;
|
|
|
8855
9610
|
resolvedSources.push(source);
|
|
8856
9611
|
}
|
|
8857
9612
|
}
|
|
9613
|
+
console.log("[Pipeline] retrieve() response:", {
|
|
9614
|
+
query,
|
|
9615
|
+
namespace: ns,
|
|
9616
|
+
count: resolvedSources.length,
|
|
9617
|
+
sample: resolvedSources.slice(0, 2).map((s) => {
|
|
9618
|
+
var _a3;
|
|
9619
|
+
return {
|
|
9620
|
+
id: s == null ? void 0 : s.id,
|
|
9621
|
+
score: s == null ? void 0 : s.score,
|
|
9622
|
+
contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
|
|
9623
|
+
metadata: s == null ? void 0 : s.metadata
|
|
9624
|
+
};
|
|
9625
|
+
})
|
|
9626
|
+
});
|
|
8858
9627
|
return { sources: resolvedSources, graphData };
|
|
8859
9628
|
}
|
|
8860
9629
|
/** Rewrite the user query for better retrieval performance. */
|