@retrivora-ai/rag-engine 2.0.7 → 2.1.1
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 +776 -88
- package/dist/handlers/index.mjs +776 -88
- package/dist/index.js +24 -16
- package/dist/index.mjs +24 -16
- package/dist/server.js +776 -88
- package/dist/server.mjs +776 -88
- package/package.json +1 -1
- package/src/components/ChatWindow.tsx +22 -22
- package/src/core/Pipeline.ts +22 -40
- package/src/llm/providers/GeminiProvider.ts +4 -4
- package/src/llm/providers/GroqProvider.ts +16 -8
- package/src/llm/providers/OpenAIProvider.ts +16 -8
- package/src/llm/providers/QwenProvider.ts +16 -8
- package/src/llm/providers/UniversalLLMAdapter.ts +90 -18
- package/src/rendering/IntentClassifier.ts +3 -3
- package/src/rendering/rules/Rule1SpecificInfoRule.ts +1 -1
- package/src/utils/ProductExtractor.ts +4 -3
- package/src/utils/UITransformer.ts +16 -5
package/dist/server.js
CHANGED
|
@@ -121,6 +121,617 @@ var init_templateUtils = __esm({
|
|
|
121
121
|
}
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
+
// ../../services/llm-gateway/providers/groq.ts
|
|
125
|
+
async function handleGroqRequest(req, apiKeyOverride) {
|
|
126
|
+
const apiKey = apiKeyOverride || process.env.GROQ_API_KEY;
|
|
127
|
+
if (!apiKey) {
|
|
128
|
+
throw new Error("Groq API Key missing. Please set GROQ_API_KEY in environment variables.");
|
|
129
|
+
}
|
|
130
|
+
const modelName = req.model.replace(/^groq\//i, "");
|
|
131
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
132
|
+
model: modelName
|
|
133
|
+
});
|
|
134
|
+
const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
|
|
135
|
+
method: "POST",
|
|
136
|
+
headers: {
|
|
137
|
+
"Content-Type": "application/json",
|
|
138
|
+
"Authorization": `Bearer ${apiKey}`
|
|
139
|
+
},
|
|
140
|
+
body: JSON.stringify(payload)
|
|
141
|
+
});
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
const errorText = await response.text();
|
|
144
|
+
throw new Error(`Groq API Error (${response.status}): ${errorText}`);
|
|
145
|
+
}
|
|
146
|
+
if (req.stream && response.body) {
|
|
147
|
+
return { stream: response.body };
|
|
148
|
+
}
|
|
149
|
+
const json = await response.json();
|
|
150
|
+
return { response: json };
|
|
151
|
+
}
|
|
152
|
+
var init_groq = __esm({
|
|
153
|
+
"../../services/llm-gateway/providers/groq.ts"() {
|
|
154
|
+
"use strict";
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// ../../services/llm-gateway/providers/openai.ts
|
|
159
|
+
async function handleOpenAIRequest(req, apiKeyOverride) {
|
|
160
|
+
const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
|
|
161
|
+
if (!apiKey) {
|
|
162
|
+
throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
|
|
163
|
+
}
|
|
164
|
+
const modelName = req.model.replace(/^(openai|gpt)\//i, "");
|
|
165
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
166
|
+
model: modelName
|
|
167
|
+
});
|
|
168
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
169
|
+
method: "POST",
|
|
170
|
+
headers: {
|
|
171
|
+
"Content-Type": "application/json",
|
|
172
|
+
"Authorization": `Bearer ${apiKey}`
|
|
173
|
+
},
|
|
174
|
+
body: JSON.stringify(payload)
|
|
175
|
+
});
|
|
176
|
+
if (!response.ok) {
|
|
177
|
+
const errorText = await response.text();
|
|
178
|
+
throw new Error(`OpenAI API Error (${response.status}): ${errorText}`);
|
|
179
|
+
}
|
|
180
|
+
if (req.stream && response.body) {
|
|
181
|
+
return { stream: response.body };
|
|
182
|
+
}
|
|
183
|
+
const json = await response.json();
|
|
184
|
+
return { response: json };
|
|
185
|
+
}
|
|
186
|
+
async function handleOpenAIEmbedding(req, apiKeyOverride) {
|
|
187
|
+
const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
|
|
188
|
+
if (!apiKey) {
|
|
189
|
+
throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
|
|
190
|
+
}
|
|
191
|
+
const modelName = req.model.replace(/^(openai)\//i, "");
|
|
192
|
+
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
193
|
+
method: "POST",
|
|
194
|
+
headers: {
|
|
195
|
+
"Content-Type": "application/json",
|
|
196
|
+
"Authorization": `Bearer ${apiKey}`
|
|
197
|
+
},
|
|
198
|
+
body: JSON.stringify({
|
|
199
|
+
model: modelName,
|
|
200
|
+
input: req.input
|
|
201
|
+
})
|
|
202
|
+
});
|
|
203
|
+
if (!response.ok) {
|
|
204
|
+
const errorText = await response.text();
|
|
205
|
+
throw new Error(`OpenAI Embedding API Error (${response.status}): ${errorText}`);
|
|
206
|
+
}
|
|
207
|
+
return await response.json();
|
|
208
|
+
}
|
|
209
|
+
var init_openai = __esm({
|
|
210
|
+
"../../services/llm-gateway/providers/openai.ts"() {
|
|
211
|
+
"use strict";
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// ../../services/llm-gateway/providers/gemini.ts
|
|
216
|
+
async function handleGeminiRequest(req, apiKeyOverride) {
|
|
217
|
+
const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
|
|
218
|
+
if (!apiKey) {
|
|
219
|
+
throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
|
|
220
|
+
}
|
|
221
|
+
let modelName = req.model.replace(/^(google|gemini)\//i, "");
|
|
222
|
+
if (!modelName.startsWith("gemini-")) {
|
|
223
|
+
modelName = `gemini-${modelName}`;
|
|
224
|
+
}
|
|
225
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
226
|
+
model: modelName
|
|
227
|
+
});
|
|
228
|
+
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", {
|
|
229
|
+
method: "POST",
|
|
230
|
+
headers: {
|
|
231
|
+
"Content-Type": "application/json",
|
|
232
|
+
"Authorization": `Bearer ${apiKey}`
|
|
233
|
+
},
|
|
234
|
+
body: JSON.stringify(payload)
|
|
235
|
+
});
|
|
236
|
+
if (!response.ok) {
|
|
237
|
+
const errorText = await response.text();
|
|
238
|
+
throw new Error(`Google Gemini API Error (${response.status}): ${errorText}`);
|
|
239
|
+
}
|
|
240
|
+
if (req.stream && response.body) {
|
|
241
|
+
return { stream: response.body };
|
|
242
|
+
}
|
|
243
|
+
const json = await response.json();
|
|
244
|
+
return { response: json };
|
|
245
|
+
}
|
|
246
|
+
async function handleGeminiEmbedding(req, apiKeyOverride) {
|
|
247
|
+
const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
|
|
248
|
+
if (!apiKey) {
|
|
249
|
+
throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
|
|
250
|
+
}
|
|
251
|
+
let modelName = req.model.replace(/^(google|gemini)\//i, "");
|
|
252
|
+
if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.startsWith("text-embedding-00") && !modelName.startsWith("embedding-00")) {
|
|
253
|
+
modelName = "text-embedding-004";
|
|
254
|
+
}
|
|
255
|
+
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/embeddings", {
|
|
256
|
+
method: "POST",
|
|
257
|
+
headers: {
|
|
258
|
+
"Content-Type": "application/json",
|
|
259
|
+
"Authorization": `Bearer ${apiKey}`
|
|
260
|
+
},
|
|
261
|
+
body: JSON.stringify({
|
|
262
|
+
model: modelName,
|
|
263
|
+
input: req.input
|
|
264
|
+
})
|
|
265
|
+
});
|
|
266
|
+
if (!response.ok) {
|
|
267
|
+
const errorText = await response.text();
|
|
268
|
+
throw new Error(`Google Gemini Embedding API Error (${response.status}): ${errorText}`);
|
|
269
|
+
}
|
|
270
|
+
return await response.json();
|
|
271
|
+
}
|
|
272
|
+
var init_gemini = __esm({
|
|
273
|
+
"../../services/llm-gateway/providers/gemini.ts"() {
|
|
274
|
+
"use strict";
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// ../../services/llm-gateway/providers/huggingface.ts
|
|
279
|
+
async function handleHuggingFaceChatRequest(req, apiKeyOverride) {
|
|
280
|
+
var _a2, _b;
|
|
281
|
+
const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
|
|
282
|
+
if (!apiKey) {
|
|
283
|
+
throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
|
|
284
|
+
}
|
|
285
|
+
let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
|
|
286
|
+
if (!modelName || modelName === "default" || modelName.toLowerCase() === "qwen" || modelName.toLowerCase() === "qwen-coder") {
|
|
287
|
+
modelName = "Qwen/Qwen2.5-Coder-32B-Instruct";
|
|
288
|
+
}
|
|
289
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
290
|
+
model: modelName
|
|
291
|
+
});
|
|
292
|
+
try {
|
|
293
|
+
const response = await fetch("https://router.huggingface.co/v1/chat/completions", {
|
|
294
|
+
method: "POST",
|
|
295
|
+
headers: {
|
|
296
|
+
"Content-Type": "application/json",
|
|
297
|
+
"Authorization": `Bearer ${apiKey}`
|
|
298
|
+
},
|
|
299
|
+
body: JSON.stringify(payload)
|
|
300
|
+
});
|
|
301
|
+
if (response.ok) {
|
|
302
|
+
if (req.stream && response.body) {
|
|
303
|
+
return { stream: response.body };
|
|
304
|
+
}
|
|
305
|
+
const json = await response.json();
|
|
306
|
+
return { response: json };
|
|
307
|
+
}
|
|
308
|
+
} catch (e) {
|
|
309
|
+
}
|
|
310
|
+
try {
|
|
311
|
+
const response = await fetch("https://router.huggingface.co/hf-inference/v1/chat/completions", {
|
|
312
|
+
method: "POST",
|
|
313
|
+
headers: {
|
|
314
|
+
"Content-Type": "application/json",
|
|
315
|
+
"Authorization": `Bearer ${apiKey}`
|
|
316
|
+
},
|
|
317
|
+
body: JSON.stringify(payload)
|
|
318
|
+
});
|
|
319
|
+
if (response.ok) {
|
|
320
|
+
if (req.stream && response.body) {
|
|
321
|
+
return { stream: response.body };
|
|
322
|
+
}
|
|
323
|
+
const json = await response.json();
|
|
324
|
+
return { response: json };
|
|
325
|
+
}
|
|
326
|
+
} catch (e) {
|
|
327
|
+
}
|
|
328
|
+
const lastUserMsg = ((_a2 = req.messages.filter((m) => m.role === "user").pop()) == null ? void 0 : _a2.content) || "Hello";
|
|
329
|
+
const pipelineRes = await fetch(`https://router.huggingface.co/hf-inference/models/${modelName}`, {
|
|
330
|
+
method: "POST",
|
|
331
|
+
headers: {
|
|
332
|
+
"Content-Type": "application/json",
|
|
333
|
+
"Authorization": `Bearer ${apiKey}`
|
|
334
|
+
},
|
|
335
|
+
body: JSON.stringify({
|
|
336
|
+
inputs: lastUserMsg,
|
|
337
|
+
parameters: { max_new_tokens: req.max_tokens || 256, temperature: req.temperature || 0.7 },
|
|
338
|
+
options: { wait_for_model: true }
|
|
339
|
+
})
|
|
340
|
+
});
|
|
341
|
+
if (!pipelineRes.ok) {
|
|
342
|
+
const errorText = await pipelineRes.text();
|
|
343
|
+
throw new Error(`HuggingFace API Error (${pipelineRes.status}): ${errorText}`);
|
|
344
|
+
}
|
|
345
|
+
const raw = await pipelineRes.json();
|
|
346
|
+
const textOutput = Array.isArray(raw) ? ((_b = raw[0]) == null ? void 0 : _b.generated_text) || JSON.stringify(raw) : JSON.stringify(raw);
|
|
347
|
+
const formattedResponse = {
|
|
348
|
+
id: `hf-${Date.now()}`,
|
|
349
|
+
object: "chat.completion",
|
|
350
|
+
created: Math.floor(Date.now() / 1e3),
|
|
351
|
+
model: modelName,
|
|
352
|
+
choices: [
|
|
353
|
+
{
|
|
354
|
+
index: 0,
|
|
355
|
+
message: {
|
|
356
|
+
role: "assistant",
|
|
357
|
+
content: textOutput
|
|
358
|
+
},
|
|
359
|
+
finish_reason: "stop"
|
|
360
|
+
}
|
|
361
|
+
],
|
|
362
|
+
usage: {
|
|
363
|
+
prompt_tokens: lastUserMsg.length,
|
|
364
|
+
completion_tokens: textOutput.length,
|
|
365
|
+
total_tokens: lastUserMsg.length + textOutput.length
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
return { response: formattedResponse };
|
|
369
|
+
}
|
|
370
|
+
async function handleHuggingFaceEmbedding(req, apiKeyOverride) {
|
|
371
|
+
const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
|
|
372
|
+
if (!apiKey) {
|
|
373
|
+
throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
|
|
374
|
+
}
|
|
375
|
+
let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
|
|
376
|
+
if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.includes("/") && !modelName.includes("bge") && !modelName.includes("sentence-transformers")) {
|
|
377
|
+
modelName = "BAAI/bge-base-en-v1.5";
|
|
378
|
+
}
|
|
379
|
+
const inputs = Array.isArray(req.input) ? req.input : [req.input];
|
|
380
|
+
const fetchEmbeddingFromModel = async (targetModel) => {
|
|
381
|
+
try {
|
|
382
|
+
const routerRes = await fetch("https://router.huggingface.co/hf-inference/v1/embeddings", {
|
|
383
|
+
method: "POST",
|
|
384
|
+
headers: {
|
|
385
|
+
"Content-Type": "application/json",
|
|
386
|
+
"Authorization": `Bearer ${apiKey}`
|
|
387
|
+
},
|
|
388
|
+
body: JSON.stringify({
|
|
389
|
+
model: targetModel,
|
|
390
|
+
input: inputs
|
|
391
|
+
})
|
|
392
|
+
});
|
|
393
|
+
if (routerRes.ok) {
|
|
394
|
+
const json = await routerRes.json();
|
|
395
|
+
if (json && json.data) return json;
|
|
396
|
+
}
|
|
397
|
+
} catch (e) {
|
|
398
|
+
}
|
|
399
|
+
const response = await fetch(`https://router.huggingface.co/hf-inference/models/${targetModel}`, {
|
|
400
|
+
method: "POST",
|
|
401
|
+
headers: {
|
|
402
|
+
"Content-Type": "application/json",
|
|
403
|
+
"Authorization": `Bearer ${apiKey}`
|
|
404
|
+
},
|
|
405
|
+
body: JSON.stringify({
|
|
406
|
+
inputs,
|
|
407
|
+
options: { wait_for_model: true }
|
|
408
|
+
})
|
|
409
|
+
});
|
|
410
|
+
if (!response.ok) {
|
|
411
|
+
const errorText = await response.text();
|
|
412
|
+
throw new Error(`HuggingFace API Error (${response.status}): ${errorText}`);
|
|
413
|
+
}
|
|
414
|
+
const rawData = await response.json();
|
|
415
|
+
const embeddings = Array.isArray(rawData[0]) ? typeof rawData[0][0] === "number" ? rawData : rawData.map((arr) => arr[0]) : [rawData];
|
|
416
|
+
return {
|
|
417
|
+
object: "list",
|
|
418
|
+
data: embeddings.map((vec, idx) => ({
|
|
419
|
+
object: "embedding",
|
|
420
|
+
embedding: vec,
|
|
421
|
+
index: idx
|
|
422
|
+
})),
|
|
423
|
+
model: targetModel,
|
|
424
|
+
usage: {
|
|
425
|
+
prompt_tokens: inputs.reduce((acc, str) => acc + str.length, 0),
|
|
426
|
+
completion_tokens: 0,
|
|
427
|
+
total_tokens: inputs.reduce((acc, str) => acc + str.length, 0)
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
try {
|
|
432
|
+
return await fetchEmbeddingFromModel(modelName);
|
|
433
|
+
} catch (err) {
|
|
434
|
+
if (modelName !== "BAAI/bge-base-en-v1.5") {
|
|
435
|
+
console.warn(`[LLM Gateway] HuggingFace model ${modelName} failed. Falling back to BAAI/bge-base-en-v1.5...`, err);
|
|
436
|
+
return await fetchEmbeddingFromModel("BAAI/bge-base-en-v1.5");
|
|
437
|
+
}
|
|
438
|
+
throw err;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
var init_huggingface = __esm({
|
|
442
|
+
"../../services/llm-gateway/providers/huggingface.ts"() {
|
|
443
|
+
"use strict";
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
// ../../services/llm-gateway/providers/anthropic.ts
|
|
448
|
+
async function handleAnthropicRequest(req, apiKeyOverride) {
|
|
449
|
+
var _a2, _b;
|
|
450
|
+
const apiKey = apiKeyOverride || process.env.ANTHROPIC_API_KEY;
|
|
451
|
+
if (!apiKey) {
|
|
452
|
+
throw new Error("Anthropic API Key missing. Please set ANTHROPIC_API_KEY in environment variables.");
|
|
453
|
+
}
|
|
454
|
+
const modelName = req.model.replace(/^(anthropic|claude)\//i, "");
|
|
455
|
+
let systemPrompt = void 0;
|
|
456
|
+
const anthropicMessages = [];
|
|
457
|
+
for (const msg of req.messages) {
|
|
458
|
+
if (msg.role === "system") {
|
|
459
|
+
systemPrompt = systemPrompt ? `${systemPrompt}
|
|
460
|
+
${msg.content}` : msg.content;
|
|
461
|
+
} else {
|
|
462
|
+
anthropicMessages.push({
|
|
463
|
+
role: msg.role === "assistant" ? "assistant" : "user",
|
|
464
|
+
content: msg.content
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (anthropicMessages.length === 0) {
|
|
469
|
+
anthropicMessages.push({ role: "user", content: "Hello" });
|
|
470
|
+
}
|
|
471
|
+
const payload = {
|
|
472
|
+
model: modelName,
|
|
473
|
+
messages: anthropicMessages,
|
|
474
|
+
max_tokens: req.max_tokens || req.max_completion_tokens || 1024,
|
|
475
|
+
stream: req.stream || false
|
|
476
|
+
};
|
|
477
|
+
if (systemPrompt) {
|
|
478
|
+
payload.system = systemPrompt;
|
|
479
|
+
}
|
|
480
|
+
if (req.temperature !== void 0) {
|
|
481
|
+
payload.temperature = req.temperature;
|
|
482
|
+
}
|
|
483
|
+
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
|
484
|
+
method: "POST",
|
|
485
|
+
headers: {
|
|
486
|
+
"Content-Type": "application/json",
|
|
487
|
+
"x-api-key": apiKey,
|
|
488
|
+
"anthropic-version": "2023-06-01"
|
|
489
|
+
},
|
|
490
|
+
body: JSON.stringify(payload)
|
|
491
|
+
});
|
|
492
|
+
if (!response.ok) {
|
|
493
|
+
const errorText = await response.text();
|
|
494
|
+
throw new Error(`Anthropic API Error (${response.status}): ${errorText}`);
|
|
495
|
+
}
|
|
496
|
+
if (req.stream && response.body) {
|
|
497
|
+
return { stream: response.body };
|
|
498
|
+
}
|
|
499
|
+
const json = await response.json();
|
|
500
|
+
const textContent = ((_b = (_a2 = json.content) == null ? void 0 : _a2[0]) == null ? void 0 : _b.text) || "";
|
|
501
|
+
const openAIResponse = {
|
|
502
|
+
id: json.id || `chatcmpl-${Date.now()}`,
|
|
503
|
+
object: "chat.completion",
|
|
504
|
+
created: Math.floor(Date.now() / 1e3),
|
|
505
|
+
model: json.model || modelName,
|
|
506
|
+
choices: [
|
|
507
|
+
{
|
|
508
|
+
index: 0,
|
|
509
|
+
message: {
|
|
510
|
+
role: "assistant",
|
|
511
|
+
content: textContent
|
|
512
|
+
},
|
|
513
|
+
finish_reason: json.stop_reason === "end_turn" ? "stop" : json.stop_reason || "stop"
|
|
514
|
+
}
|
|
515
|
+
],
|
|
516
|
+
usage: json.usage ? {
|
|
517
|
+
prompt_tokens: json.usage.input_tokens,
|
|
518
|
+
completion_tokens: json.usage.output_tokens,
|
|
519
|
+
total_tokens: json.usage.input_tokens + json.usage.output_tokens
|
|
520
|
+
} : void 0
|
|
521
|
+
};
|
|
522
|
+
return { response: openAIResponse };
|
|
523
|
+
}
|
|
524
|
+
var init_anthropic = __esm({
|
|
525
|
+
"../../services/llm-gateway/providers/anthropic.ts"() {
|
|
526
|
+
"use strict";
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// ../../services/llm-gateway/providers/ollama.ts
|
|
531
|
+
async function handleOllamaRequest(req, baseUrlOverride) {
|
|
532
|
+
const baseUrl = (baseUrlOverride || process.env.OLLAMA_BASE_URL || "http://localhost:11434/v1").replace(/\/+$/, "");
|
|
533
|
+
const modelName = req.model.replace(/^ollama\//i, "");
|
|
534
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
535
|
+
model: modelName
|
|
536
|
+
});
|
|
537
|
+
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
538
|
+
method: "POST",
|
|
539
|
+
headers: {
|
|
540
|
+
"Content-Type": "application/json"
|
|
541
|
+
},
|
|
542
|
+
body: JSON.stringify(payload)
|
|
543
|
+
});
|
|
544
|
+
if (!response.ok) {
|
|
545
|
+
const errorText = await response.text();
|
|
546
|
+
throw new Error(`Ollama API Error (${response.status}): ${errorText}`);
|
|
547
|
+
}
|
|
548
|
+
if (req.stream && response.body) {
|
|
549
|
+
return { stream: response.body };
|
|
550
|
+
}
|
|
551
|
+
const json = await response.json();
|
|
552
|
+
return { response: json };
|
|
553
|
+
}
|
|
554
|
+
var init_ollama = __esm({
|
|
555
|
+
"../../services/llm-gateway/providers/ollama.ts"() {
|
|
556
|
+
"use strict";
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// ../../services/llm-gateway/router.ts
|
|
561
|
+
var router_exports = {};
|
|
562
|
+
__export(router_exports, {
|
|
563
|
+
SUPPORTED_MODELS: () => SUPPORTED_MODELS,
|
|
564
|
+
dispatchChatCompletion: () => dispatchChatCompletion,
|
|
565
|
+
dispatchEmbedding: () => dispatchEmbedding,
|
|
566
|
+
resolveProvider: () => resolveProvider
|
|
567
|
+
});
|
|
568
|
+
function resolveProvider(model) {
|
|
569
|
+
const lower = model.toLowerCase();
|
|
570
|
+
if (lower.startsWith("huggingface/") || lower.startsWith("hf/")) {
|
|
571
|
+
return "huggingface";
|
|
572
|
+
}
|
|
573
|
+
if (lower.startsWith("ollama/")) {
|
|
574
|
+
return "ollama";
|
|
575
|
+
}
|
|
576
|
+
if (lower.startsWith("groq/") || lower.includes("llama") || lower.includes("qwen") || lower.includes("mixtral")) {
|
|
577
|
+
return "groq";
|
|
578
|
+
}
|
|
579
|
+
if (process.env.GROQ_API_KEY) return "groq";
|
|
580
|
+
if (process.env.OPENAI_API_KEY) return "openai";
|
|
581
|
+
if (process.env.GEMINI_API_KEY) return "gemini";
|
|
582
|
+
if (process.env.ANTHROPIC_API_KEY) return "anthropic";
|
|
583
|
+
if (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY) return "huggingface";
|
|
584
|
+
return "groq";
|
|
585
|
+
}
|
|
586
|
+
function cleanApiKeyOverride(apiKeyOverride) {
|
|
587
|
+
if (!apiKeyOverride) return void 0;
|
|
588
|
+
const key = apiKeyOverride.trim();
|
|
589
|
+
if (key === process.env.LITELLM_API_KEY || key === process.env.LITELLM_MASTER_KEY || key.startsWith("sk-retrivora") || !key.startsWith("gsk_") && !key.startsWith("AIza") && !key.startsWith("sk-ant-") && !key.startsWith("sk-proj-")) {
|
|
590
|
+
return void 0;
|
|
591
|
+
}
|
|
592
|
+
return key;
|
|
593
|
+
}
|
|
594
|
+
async function dispatchChatCompletion(req, apiKeyOverride) {
|
|
595
|
+
const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
|
|
596
|
+
const provider = resolveProvider(req.model);
|
|
597
|
+
console.log(`[LLM Gateway Router] Dispatching chat request: model=${req.model}, provider=${provider}, hasGroqKey=${Boolean(process.env.GROQ_API_KEY)}, hasGeminiKey=${Boolean(process.env.GROQ_API_KEY || process.env.GEMINI_API_KEY)}, hasHFToken=${Boolean(process.env.HF_TOKEN)}`);
|
|
598
|
+
try {
|
|
599
|
+
switch (provider) {
|
|
600
|
+
case "groq":
|
|
601
|
+
return await handleGroqRequest(req, effectiveKey);
|
|
602
|
+
case "openai":
|
|
603
|
+
return await handleOpenAIRequest(req, effectiveKey);
|
|
604
|
+
case "gemini":
|
|
605
|
+
return await handleGeminiRequest(req, effectiveKey);
|
|
606
|
+
case "anthropic":
|
|
607
|
+
return await handleAnthropicRequest(req, effectiveKey);
|
|
608
|
+
case "ollama":
|
|
609
|
+
return await handleOllamaRequest(req);
|
|
610
|
+
case "huggingface":
|
|
611
|
+
return await handleHuggingFaceChatRequest(req, effectiveKey);
|
|
612
|
+
default:
|
|
613
|
+
throw new Error(`Unsupported LLM provider for model: ${req.model}`);
|
|
614
|
+
}
|
|
615
|
+
} catch (error) {
|
|
616
|
+
console.error(`[LLM Gateway Router] Provider '${provider}' failed for model '${req.model}':`, {
|
|
617
|
+
message: error.message,
|
|
618
|
+
stack: error.stack
|
|
619
|
+
});
|
|
620
|
+
if (/rate[- ]?limit|429|exhausted/i.test(error.message)) {
|
|
621
|
+
const isGroqKey = process.env.GROQ_API_KEY || effectiveKey && effectiveKey.startsWith("gsk_");
|
|
622
|
+
const reqModelLower = req.model.toLowerCase();
|
|
623
|
+
if (isGroqKey && !reqModelLower.includes("llama-3.3-70b")) {
|
|
624
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to secondary Groq model (llama-3.3-70b-versatile)...`);
|
|
625
|
+
try {
|
|
626
|
+
return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: "llama-3.3-70b-versatile" }), effectiveKey);
|
|
627
|
+
} catch (fErr) {
|
|
628
|
+
console.error("[LLM Gateway] Fallback groq/llama-3.3-70b-versatile failed:", fErr.message);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
|
|
632
|
+
if (provider !== "gemini" && geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ."))) {
|
|
633
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Google Gemini (gemini-2.5-flash)...`);
|
|
634
|
+
try {
|
|
635
|
+
return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: "gemini-2.5-flash" }), effectiveKey);
|
|
636
|
+
} catch (fErr) {
|
|
637
|
+
console.error("[LLM Gateway] Fallback gemini-2.5-flash failed:", fErr.message);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
if (provider !== "huggingface" && (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY)) {
|
|
641
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Hugging Face (Qwen/Qwen2.5-Coder-32B-Instruct)...`);
|
|
642
|
+
try {
|
|
643
|
+
return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: "Qwen/Qwen2.5-Coder-32B-Instruct" }), effectiveKey);
|
|
644
|
+
} catch (fErr) {
|
|
645
|
+
console.error("[LLM Gateway] Fallback HuggingFace Qwen failed:", fErr.message);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
if (provider !== "openai" && process.env.OPENAI_API_KEY) {
|
|
649
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to OpenAI (gpt-4o-mini)...`);
|
|
650
|
+
try {
|
|
651
|
+
return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: "gpt-4o-mini" }), effectiveKey);
|
|
652
|
+
} catch (e) {
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to local Ollama (llama3.2)...`);
|
|
656
|
+
return handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: "llama3.2" }));
|
|
657
|
+
}
|
|
658
|
+
throw error;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
async function dispatchEmbedding(req, apiKeyOverride) {
|
|
662
|
+
const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
|
|
663
|
+
if (req.model.startsWith("hf/") || req.model.startsWith("huggingface/") || req.model.includes("bge-")) {
|
|
664
|
+
try {
|
|
665
|
+
return await handleHuggingFaceEmbedding(req, effectiveKey);
|
|
666
|
+
} catch (err) {
|
|
667
|
+
console.warn("[LLM Gateway] HuggingFace explicit model embedding failed, falling back to default gateway chain:", err);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
|
|
671
|
+
const isGeminiKeyValid = Boolean(geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ.")));
|
|
672
|
+
if (isGeminiKeyValid) {
|
|
673
|
+
try {
|
|
674
|
+
return await handleGeminiEmbedding(req, effectiveKey);
|
|
675
|
+
} catch (err) {
|
|
676
|
+
console.warn("[LLM Gateway] Gemini embedding failed:", err);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
if (process.env.OPENAI_API_KEY) {
|
|
680
|
+
try {
|
|
681
|
+
return await handleOpenAIEmbedding(req, effectiveKey);
|
|
682
|
+
} catch (err) {
|
|
683
|
+
console.warn("[LLM Gateway] OpenAI embedding failed:", err);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN) {
|
|
687
|
+
try {
|
|
688
|
+
return await handleHuggingFaceEmbedding(req, effectiveKey);
|
|
689
|
+
} catch (err) {
|
|
690
|
+
console.warn("[LLM Gateway] HuggingFace fallback embedding failed:", err);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return handleGeminiEmbedding(req, effectiveKey);
|
|
694
|
+
}
|
|
695
|
+
var SUPPORTED_MODELS;
|
|
696
|
+
var init_router = __esm({
|
|
697
|
+
"../../services/llm-gateway/router.ts"() {
|
|
698
|
+
"use strict";
|
|
699
|
+
init_groq();
|
|
700
|
+
init_openai();
|
|
701
|
+
init_gemini();
|
|
702
|
+
init_huggingface();
|
|
703
|
+
init_anthropic();
|
|
704
|
+
init_ollama();
|
|
705
|
+
SUPPORTED_MODELS = [
|
|
706
|
+
{ id: "groq/llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
|
|
707
|
+
{ id: "llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
|
|
708
|
+
{ id: "groq/llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
|
|
709
|
+
{ id: "llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
|
|
710
|
+
{ id: "gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
|
|
711
|
+
{ id: "openai/gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
|
|
712
|
+
{ id: "gpt-4o", object: "model", created: 17e8, owned_by: "openai" },
|
|
713
|
+
{ id: "gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
|
|
714
|
+
{ id: "google/gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
|
|
715
|
+
{ id: "claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
|
|
716
|
+
{ id: "anthropic/claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
|
|
717
|
+
{ id: "text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
|
|
718
|
+
{ id: "google/text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
|
|
719
|
+
{ id: "BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
|
|
720
|
+
{ id: "huggingface/BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
|
|
721
|
+
{ id: "groq/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
|
|
722
|
+
{ id: "qwen/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
|
|
723
|
+
{ id: "qwen/qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
|
|
724
|
+
{ id: "qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
|
|
725
|
+
{ id: "ollama/llama3.2", object: "model", created: 17e8, owned_by: "ollama" }
|
|
726
|
+
];
|
|
727
|
+
if (typeof globalThis !== "undefined") {
|
|
728
|
+
const _g2 = globalThis;
|
|
729
|
+
_g2.__retrivoraDispatchChat = dispatchChatCompletion;
|
|
730
|
+
_g2.__retrivoraDispatchEmbedding = dispatchEmbedding;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
|
|
124
735
|
// src/providers/vectordb/BaseVectorProvider.ts
|
|
125
736
|
var BaseVectorProvider;
|
|
126
737
|
var init_BaseVectorProvider = __esm({
|
|
@@ -2886,12 +3497,13 @@ var OpenAIProvider = class {
|
|
|
2886
3497
|
role: "system",
|
|
2887
3498
|
content: buildSystemContent(basePrompt, context)
|
|
2888
3499
|
};
|
|
3500
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
3501
|
+
role: m.role || "user",
|
|
3502
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
3503
|
+
}));
|
|
2889
3504
|
const formattedMessages = [
|
|
2890
3505
|
systemMessage,
|
|
2891
|
-
...
|
|
2892
|
-
role: m.role,
|
|
2893
|
-
content: m.content
|
|
2894
|
-
}))
|
|
3506
|
+
...safeMessages
|
|
2895
3507
|
];
|
|
2896
3508
|
const completion = await this.client.chat.completions.create({
|
|
2897
3509
|
model: this.llmConfig.model,
|
|
@@ -2910,12 +3522,13 @@ var OpenAIProvider = class {
|
|
|
2910
3522
|
role: "system",
|
|
2911
3523
|
content: buildSystemContent(basePrompt, context)
|
|
2912
3524
|
};
|
|
3525
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
3526
|
+
role: m.role || "user",
|
|
3527
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
3528
|
+
}));
|
|
2913
3529
|
const formattedMessages = [
|
|
2914
3530
|
systemMessage,
|
|
2915
|
-
...
|
|
2916
|
-
role: m.role,
|
|
2917
|
-
content: m.content
|
|
2918
|
-
}))
|
|
3531
|
+
...safeStreamMessages
|
|
2919
3532
|
];
|
|
2920
3533
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
2921
3534
|
model: this.llmConfig.model,
|
|
@@ -3446,9 +4059,9 @@ var GeminiProvider = class {
|
|
|
3446
4059
|
* - Messages must strictly alternate between `user` and `model`.
|
|
3447
4060
|
*/
|
|
3448
4061
|
buildGeminiContents(messages) {
|
|
3449
|
-
return messages.filter((m) => m.role !== "system").map((m) => ({
|
|
4062
|
+
return (messages || []).filter((m) => Boolean(m && typeof m === "object" && m.role !== "system")).map((m) => ({
|
|
3450
4063
|
role: m.role === "assistant" ? "model" : "user",
|
|
3451
|
-
parts: [{ text: m.content }]
|
|
4064
|
+
parts: [{ text: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : "" }]
|
|
3452
4065
|
}));
|
|
3453
4066
|
}
|
|
3454
4067
|
// -------------------------------------------------------------------------
|
|
@@ -3651,12 +4264,13 @@ var GroqProvider = class {
|
|
|
3651
4264
|
role: "system",
|
|
3652
4265
|
content: buildSystemContent(basePrompt, context)
|
|
3653
4266
|
};
|
|
4267
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4268
|
+
role: m.role || "user",
|
|
4269
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4270
|
+
}));
|
|
3654
4271
|
const formattedMessages = [
|
|
3655
4272
|
systemMessage,
|
|
3656
|
-
...
|
|
3657
|
-
role: m.role,
|
|
3658
|
-
content: m.content
|
|
3659
|
-
}))
|
|
4273
|
+
...safeMessages
|
|
3660
4274
|
];
|
|
3661
4275
|
const completion = await this.client.chat.completions.create({
|
|
3662
4276
|
model: this.llmConfig.model,
|
|
@@ -3675,12 +4289,13 @@ var GroqProvider = class {
|
|
|
3675
4289
|
role: "system",
|
|
3676
4290
|
content: buildSystemContent(basePrompt, context)
|
|
3677
4291
|
};
|
|
4292
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4293
|
+
role: m.role || "user",
|
|
4294
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4295
|
+
}));
|
|
3678
4296
|
const formattedMessages = [
|
|
3679
4297
|
systemMessage,
|
|
3680
|
-
...
|
|
3681
|
-
role: m.role,
|
|
3682
|
-
content: m.content
|
|
3683
|
-
}))
|
|
4298
|
+
...safeStreamMessages
|
|
3684
4299
|
];
|
|
3685
4300
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
3686
4301
|
model: this.llmConfig.model,
|
|
@@ -3809,12 +4424,13 @@ var QwenProvider = class {
|
|
|
3809
4424
|
role: "system",
|
|
3810
4425
|
content: buildSystemContent(basePrompt, context)
|
|
3811
4426
|
};
|
|
4427
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4428
|
+
role: m.role || "user",
|
|
4429
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4430
|
+
}));
|
|
3812
4431
|
const formattedMessages = [
|
|
3813
4432
|
systemMessage,
|
|
3814
|
-
...
|
|
3815
|
-
role: m.role,
|
|
3816
|
-
content: m.content
|
|
3817
|
-
}))
|
|
4433
|
+
...safeMessages
|
|
3818
4434
|
];
|
|
3819
4435
|
const completion = await this.client.chat.completions.create({
|
|
3820
4436
|
model: this.llmConfig.model,
|
|
@@ -3833,12 +4449,13 @@ var QwenProvider = class {
|
|
|
3833
4449
|
role: "system",
|
|
3834
4450
|
content: buildSystemContent(basePrompt, context)
|
|
3835
4451
|
};
|
|
4452
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4453
|
+
role: m.role || "user",
|
|
4454
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4455
|
+
}));
|
|
3836
4456
|
const formattedMessages = [
|
|
3837
4457
|
systemMessage,
|
|
3838
|
-
...
|
|
3839
|
-
role: m.role,
|
|
3840
|
-
content: m.content
|
|
3841
|
-
}))
|
|
4458
|
+
...safeStreamMessages
|
|
3842
4459
|
];
|
|
3843
4460
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
3844
4461
|
model: this.llmConfig.model,
|
|
@@ -3976,6 +4593,17 @@ var VECTOR_PROFILES = {
|
|
|
3976
4593
|
};
|
|
3977
4594
|
|
|
3978
4595
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4596
|
+
function extractContent(obj) {
|
|
4597
|
+
var _a2, _b, _c;
|
|
4598
|
+
if (!obj || typeof obj !== "object") return void 0;
|
|
4599
|
+
const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
|
|
4600
|
+
if (!choice) return void 0;
|
|
4601
|
+
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4602
|
+
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
4603
|
+
if (typeof choice.text === "string") return choice.text;
|
|
4604
|
+
if (typeof choice.content === "string") return choice.content;
|
|
4605
|
+
return void 0;
|
|
4606
|
+
}
|
|
3979
4607
|
var UniversalLLMAdapter = class {
|
|
3980
4608
|
constructor(config) {
|
|
3981
4609
|
var _a2, _b, _c, _d, _e, _f, _g2, _h;
|
|
@@ -4007,14 +4635,18 @@ var UniversalLLMAdapter = class {
|
|
|
4007
4635
|
});
|
|
4008
4636
|
}
|
|
4009
4637
|
async chat(messages, context) {
|
|
4010
|
-
var _a2, _b, _c
|
|
4638
|
+
var _a2, _b, _c;
|
|
4011
4639
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
4640
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4641
|
+
role: m.role || "user",
|
|
4642
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4643
|
+
}));
|
|
4012
4644
|
const formattedMessages = [
|
|
4013
4645
|
{ role: "system", content: `${this.systemPrompt}
|
|
4014
4646
|
|
|
4015
4647
|
Context:
|
|
4016
4648
|
${context != null ? context : "None"}` },
|
|
4017
|
-
...
|
|
4649
|
+
...safeMessages
|
|
4018
4650
|
];
|
|
4019
4651
|
let payload;
|
|
4020
4652
|
if (this.opts.chatPayloadTemplate) {
|
|
@@ -4035,25 +4667,41 @@ ${context != null ? context : "None"}` },
|
|
|
4035
4667
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4036
4668
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4037
4669
|
const _g2 = globalThis;
|
|
4038
|
-
|
|
4670
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4671
|
+
if (typeof dispatch !== "function") {
|
|
4039
4672
|
try {
|
|
4040
|
-
const
|
|
4673
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4674
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4675
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4676
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4677
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4678
|
+
}
|
|
4679
|
+
} catch (e) {
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
if (typeof dispatch === "function") {
|
|
4683
|
+
try {
|
|
4684
|
+
const res = await dispatch({
|
|
4041
4685
|
model: this.model,
|
|
4042
4686
|
messages: formattedMessages,
|
|
4043
4687
|
max_tokens: this.maxTokens,
|
|
4044
4688
|
temperature: this.temperature
|
|
4045
4689
|
}, this.apiKey);
|
|
4046
|
-
|
|
4047
|
-
|
|
4690
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4691
|
+
if (content !== void 0) {
|
|
4692
|
+
return content;
|
|
4048
4693
|
}
|
|
4694
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
|
|
4049
4695
|
} catch (dispatchErr) {
|
|
4050
4696
|
throw dispatchErr;
|
|
4051
4697
|
}
|
|
4698
|
+
} else {
|
|
4699
|
+
throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
|
|
4052
4700
|
}
|
|
4053
4701
|
}
|
|
4054
4702
|
const { data } = await this.http.post(path2, payload);
|
|
4055
|
-
const extractPath = (
|
|
4056
|
-
const result = resolvePath(data, extractPath);
|
|
4703
|
+
const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
|
|
4704
|
+
const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
|
|
4057
4705
|
if (result === void 0) {
|
|
4058
4706
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
4059
4707
|
}
|
|
@@ -4066,16 +4714,20 @@ ${context != null ? context : "None"}` },
|
|
|
4066
4714
|
*/
|
|
4067
4715
|
chatStream(messages, context) {
|
|
4068
4716
|
return __asyncGenerator(this, null, function* () {
|
|
4069
|
-
var _a2, _b, _c, _d, _e
|
|
4717
|
+
var _a2, _b, _c, _d, _e;
|
|
4070
4718
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
4071
4719
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
4072
4720
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4721
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4722
|
+
role: m.role || "user",
|
|
4723
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4724
|
+
}));
|
|
4073
4725
|
const formattedMessages = [
|
|
4074
4726
|
{ role: "system", content: `${this.systemPrompt}
|
|
4075
4727
|
|
|
4076
4728
|
Context:
|
|
4077
4729
|
${context != null ? context : "None"}` },
|
|
4078
|
-
...
|
|
4730
|
+
...safeMessages
|
|
4079
4731
|
];
|
|
4080
4732
|
let payload;
|
|
4081
4733
|
if (this.opts.chatPayloadTemplate) {
|
|
@@ -4100,10 +4752,22 @@ ${context != null ? context : "None"}` },
|
|
|
4100
4752
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4101
4753
|
let streamBody = null;
|
|
4102
4754
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4103
|
-
const
|
|
4104
|
-
|
|
4755
|
+
const _g2 = globalThis;
|
|
4756
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4757
|
+
if (typeof dispatch !== "function") {
|
|
4105
4758
|
try {
|
|
4106
|
-
const
|
|
4759
|
+
const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
|
|
4760
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4761
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4762
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4763
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4764
|
+
}
|
|
4765
|
+
} catch (e) {
|
|
4766
|
+
}
|
|
4767
|
+
}
|
|
4768
|
+
if (typeof dispatch === "function") {
|
|
4769
|
+
try {
|
|
4770
|
+
const res = yield new __await(dispatch({
|
|
4107
4771
|
model: this.model,
|
|
4108
4772
|
messages: formattedMessages,
|
|
4109
4773
|
max_tokens: this.maxTokens,
|
|
@@ -4112,13 +4776,19 @@ ${context != null ? context : "None"}` },
|
|
|
4112
4776
|
}, this.apiKey));
|
|
4113
4777
|
if (res == null ? void 0 : res.stream) {
|
|
4114
4778
|
streamBody = res.stream;
|
|
4115
|
-
} else
|
|
4116
|
-
|
|
4117
|
-
|
|
4779
|
+
} else {
|
|
4780
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4781
|
+
if (content !== void 0) {
|
|
4782
|
+
yield content;
|
|
4783
|
+
return;
|
|
4784
|
+
}
|
|
4785
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
|
|
4118
4786
|
}
|
|
4119
4787
|
} catch (dispatchErr) {
|
|
4120
4788
|
throw dispatchErr;
|
|
4121
4789
|
}
|
|
4790
|
+
} else {
|
|
4791
|
+
throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
|
|
4122
4792
|
}
|
|
4123
4793
|
}
|
|
4124
4794
|
if (!streamBody) {
|
|
@@ -4145,14 +4815,14 @@ ${context != null ? context : "None"}` },
|
|
|
4145
4815
|
if (done) break;
|
|
4146
4816
|
buffer += decoder.decode(value, { stream: true });
|
|
4147
4817
|
const lines = buffer.split("\n");
|
|
4148
|
-
buffer = (
|
|
4818
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4149
4819
|
for (const line of lines) {
|
|
4150
4820
|
const trimmed = line.trim();
|
|
4151
4821
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4152
4822
|
if (!trimmed.startsWith("data:")) continue;
|
|
4153
4823
|
try {
|
|
4154
4824
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4155
|
-
const text = resolvePath(json, extractPath);
|
|
4825
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4156
4826
|
if (text && typeof text === "string") yield text;
|
|
4157
4827
|
} catch (e) {
|
|
4158
4828
|
}
|
|
@@ -4162,7 +4832,7 @@ ${context != null ? context : "None"}` },
|
|
|
4162
4832
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4163
4833
|
try {
|
|
4164
4834
|
const json = JSON.parse(jsonStr);
|
|
4165
|
-
const text = resolvePath(json, extractPath);
|
|
4835
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4166
4836
|
if (text && typeof text === "string") yield text;
|
|
4167
4837
|
} catch (e) {
|
|
4168
4838
|
}
|
|
@@ -4190,18 +4860,33 @@ ${context != null ? context : "None"}` },
|
|
|
4190
4860
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4191
4861
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4192
4862
|
const _g2 = globalThis;
|
|
4193
|
-
|
|
4863
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4864
|
+
if (typeof dispatch !== "function") {
|
|
4194
4865
|
try {
|
|
4195
|
-
const
|
|
4866
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4867
|
+
if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
|
|
4868
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4869
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4870
|
+
dispatch = gateway.dispatchEmbedding;
|
|
4871
|
+
}
|
|
4872
|
+
} catch (e) {
|
|
4873
|
+
}
|
|
4874
|
+
}
|
|
4875
|
+
if (typeof dispatch === "function") {
|
|
4876
|
+
try {
|
|
4877
|
+
const res = await dispatch({
|
|
4196
4878
|
model: this.model,
|
|
4197
4879
|
input: text
|
|
4198
4880
|
}, this.apiKey);
|
|
4199
4881
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4200
4882
|
return res.data[0].embedding;
|
|
4201
4883
|
}
|
|
4884
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4202
4885
|
} catch (dispatchErr) {
|
|
4203
4886
|
throw dispatchErr;
|
|
4204
4887
|
}
|
|
4888
|
+
} else {
|
|
4889
|
+
throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
|
|
4205
4890
|
}
|
|
4206
4891
|
}
|
|
4207
4892
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -6186,8 +6871,8 @@ var IntentClassifier = class {
|
|
|
6186
6871
|
}
|
|
6187
6872
|
// ─── Intent Heuristic Checkers ─────────────────────────────────────────────
|
|
6188
6873
|
static isInformationLookup(query) {
|
|
6189
|
-
if (/^(what|who|explain|define|where|when|why|how|how does|can|could|does|do|is|are|has|have|will|should|would|meaning of)\s+/i.test(query)) {
|
|
6190
|
-
if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top selling|best)\b/i.test(query)) {
|
|
6874
|
+
if (/^(what|who|explain|explore|define|where|when|why|how|how does|can|could|does|do|is|are|has|have|will|should|would|meaning of|tell me about|show details of|overview of|summarize)\s+/i.test(query)) {
|
|
6875
|
+
if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top 10|top selling|best|chart|graph|plot|breakdown|analytics)\b/i.test(query)) {
|
|
6191
6876
|
return true;
|
|
6192
6877
|
}
|
|
6193
6878
|
}
|
|
@@ -6224,7 +6909,7 @@ var Rule1SpecificInfoRule = class {
|
|
|
6224
6909
|
}
|
|
6225
6910
|
evaluate(context, intent) {
|
|
6226
6911
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6227
|
-
const isFactQuery = intent === "information_lookup" || /^(what|who|explain|define|where|when|why|meaning of)\s+/i.test(q) || /^(what is the price of|price of|cost of)\b/i.test(q);
|
|
6912
|
+
const isFactQuery = intent === "information_lookup" || /^(what|who|explain|explore|define|where|when|why|meaning of|tell me about|show details of|overview of|summarize)\s+/i.test(q) || /^(what is the price of|price of|cost of)\b/i.test(q);
|
|
6228
6913
|
const isNonVisual = !/\b(compare|versus|vs\.?|trend|monthly|revenue|best|top 10|chart|table|list|grid)\b/i.test(q);
|
|
6229
6914
|
if (isFactQuery && isNonVisual) {
|
|
6230
6915
|
return {
|
|
@@ -7063,7 +7748,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7063
7748
|
}
|
|
7064
7749
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
7065
7750
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
7066
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null)
|
|
7751
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
7067
7752
|
return {
|
|
7068
7753
|
type: "product_carousel",
|
|
7069
7754
|
title: "Recommended Products",
|
|
@@ -7443,7 +8128,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7443
8128
|
return fieldCount.size > 2;
|
|
7444
8129
|
}
|
|
7445
8130
|
static profileData(data) {
|
|
7446
|
-
const records = data.map((item) => {
|
|
8131
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
8132
|
+
var _a2, _b;
|
|
7447
8133
|
const fields2 = {};
|
|
7448
8134
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7449
8135
|
const primitive = this.toPrimitive(value);
|
|
@@ -7452,8 +8138,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7452
8138
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7453
8139
|
return {
|
|
7454
8140
|
id: item.id,
|
|
7455
|
-
content: item.content,
|
|
7456
|
-
score: item.score,
|
|
8141
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
8142
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7457
8143
|
fields: fields2,
|
|
7458
8144
|
source: item
|
|
7459
8145
|
};
|
|
@@ -7510,6 +8196,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7510
8196
|
}
|
|
7511
8197
|
static chooseAutomaticVisualization(data, profile, query) {
|
|
7512
8198
|
if (profile.records.length === 0) return null;
|
|
8199
|
+
const q = query.toLowerCase().trim();
|
|
8200
|
+
const isExplicitVisualOrAnalytic = /\b(chart|graph|plot|visualize|trend|monthly|revenue|top\s*\d+|breakdown|analytics|compare|versus|vs\.?|histogram|pie|bar|line|distribution|percentage|share|summary of metrics)\b/i.test(q);
|
|
8201
|
+
if (!isExplicitVisualOrAnalytic) {
|
|
8202
|
+
return null;
|
|
8203
|
+
}
|
|
7513
8204
|
if (profile.dateFields.length > 0 && profile.numericFields.length > 0) {
|
|
7514
8205
|
return this.transformToLineChart(profile);
|
|
7515
8206
|
}
|
|
@@ -7625,6 +8316,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7625
8316
|
return Array.from(categories);
|
|
7626
8317
|
}
|
|
7627
8318
|
static getProductCategory(item) {
|
|
8319
|
+
if (!item) return null;
|
|
7628
8320
|
const meta = item.metadata || {};
|
|
7629
8321
|
const metadataCategory = resolveMetadataValue(meta, "category");
|
|
7630
8322
|
if (this.isUsableCategory(metadataCategory)) return String(metadataCategory).trim();
|
|
@@ -7741,6 +8433,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7741
8433
|
if (!fields.has(normalized)) fields.set(normalized, clean);
|
|
7742
8434
|
};
|
|
7743
8435
|
data.forEach((item) => {
|
|
8436
|
+
if (!item) return;
|
|
7744
8437
|
Object.keys(item.metadata || {}).forEach(addField);
|
|
7745
8438
|
for (const match of (item.content || "").matchAll(/(?:^|\n)\s*([A-Za-z][A-Za-z0-9_ /-]{1,50})\s*[:\-–]\s*([^\n]+)/g)) {
|
|
7746
8439
|
addField(match[1]);
|
|
@@ -7857,6 +8550,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7857
8550
|
return true;
|
|
7858
8551
|
}
|
|
7859
8552
|
static extractStockQuantity(item) {
|
|
8553
|
+
if (!item) return null;
|
|
7860
8554
|
const meta = item.metadata || {};
|
|
7861
8555
|
const stockValue = resolveMetadataValue(meta, "stock");
|
|
7862
8556
|
const numericStock = this.toFiniteNumber(stockValue);
|
|
@@ -8556,7 +9250,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8556
9250
|
*/
|
|
8557
9251
|
askStreamInternal(_0) {
|
|
8558
9252
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8559
|
-
var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B
|
|
9253
|
+
var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
|
|
8560
9254
|
yield new __await(this.initialize());
|
|
8561
9255
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8562
9256
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8599,8 +9293,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8599
9293
|
const graphData = (strategyResult === "graph" || strategyResult === "both") && this.graphDB && ((_l = this.config.rag) == null ? void 0 : _l.useGraphRetrieval) ? yield new __await(this.graphDB.query(searchQuery)) : void 0;
|
|
8600
9294
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8601
9295
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8602
|
-
const wantsExhaustiveList =
|
|
8603
|
-
const retrievalLimit =
|
|
9296
|
+
const wantsExhaustiveList = true;
|
|
9297
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
8604
9298
|
const rawSources = ((strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : []).filter((s) => Boolean(s && typeof s === "object"));
|
|
8605
9299
|
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
8606
9300
|
rawCount: rawSources.length,
|
|
@@ -8624,40 +9318,29 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8624
9318
|
var _a3;
|
|
8625
9319
|
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
8626
9320
|
});
|
|
8627
|
-
const rerankLimit =
|
|
9321
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8628
9322
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8629
9323
|
if (!hasNumericPredicates && useReranking) {
|
|
8630
9324
|
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8631
|
-
} else if (!wantsExhaustiveList) {
|
|
8632
|
-
fullSources = fullSources.slice(0, topK);
|
|
8633
9325
|
}
|
|
8634
9326
|
const rerankMs = performance.now() - rerankStart;
|
|
8635
|
-
|
|
9327
|
+
const totalCount = fullSources.length;
|
|
9328
|
+
const promptSources = fullSources.slice(0, 15);
|
|
9329
|
+
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]
|
|
9330
|
+
|
|
9331
|
+
` + promptSources.map((m, i) => {
|
|
8636
9332
|
var _a3;
|
|
8637
9333
|
return `[Source ${i + 1}]
|
|
8638
9334
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8639
9335
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8640
|
-
let displayCount = 15;
|
|
8641
|
-
if (hasMetadataFilter) {
|
|
8642
|
-
displayCount = fullSources.length;
|
|
8643
|
-
} else {
|
|
8644
|
-
const baseThreshold = Math.max(scoreThreshold, 0.4);
|
|
8645
|
-
const highlyRelevant = fullSources.filter((m) => {
|
|
8646
|
-
var _a3;
|
|
8647
|
-
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= baseThreshold;
|
|
8648
|
-
});
|
|
8649
|
-
displayCount = Math.max(highlyRelevant.length, topK);
|
|
8650
|
-
if (displayCount > 15) {
|
|
8651
|
-
displayCount = 15;
|
|
8652
|
-
}
|
|
8653
|
-
}
|
|
8654
9336
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8655
9337
|
var _a3, _b2;
|
|
8656
9338
|
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8657
|
-
})
|
|
9339
|
+
});
|
|
8658
9340
|
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
8659
9341
|
count: sources.length,
|
|
8660
|
-
|
|
9342
|
+
totalRawCount: rawSources.length,
|
|
9343
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
8661
9344
|
var _a3;
|
|
8662
9345
|
return {
|
|
8663
9346
|
rank: idx + 1,
|
|
@@ -8857,7 +9540,7 @@ ${context}`;
|
|
|
8857
9540
|
}
|
|
8858
9541
|
yield fullReply;
|
|
8859
9542
|
}
|
|
8860
|
-
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true
|
|
9543
|
+
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
|
|
8861
9544
|
if (runHallucination) {
|
|
8862
9545
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8863
9546
|
}
|
|
@@ -8866,7 +9549,7 @@ ${context}`;
|
|
|
8866
9549
|
const latency = {
|
|
8867
9550
|
embedMs: Math.round(embedMs),
|
|
8868
9551
|
retrieveMs: Math.round(retrieveMs),
|
|
8869
|
-
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((
|
|
9552
|
+
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
|
|
8870
9553
|
generateMs: Math.round(generateMs),
|
|
8871
9554
|
totalMs: Math.round(totalMs)
|
|
8872
9555
|
};
|
|
@@ -8879,7 +9562,7 @@ ${context}`;
|
|
|
8879
9562
|
totalTokens: promptTokens + completionTokens,
|
|
8880
9563
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8881
9564
|
};
|
|
8882
|
-
const awaitHallucination = ((
|
|
9565
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8883
9566
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8884
9567
|
uiTransformationPromise,
|
|
8885
9568
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8908,10 +9591,10 @@ ${context}`;
|
|
|
8908
9591
|
hallucinationReason: hScore.reason
|
|
8909
9592
|
} : {});
|
|
8910
9593
|
const trace = buildTrace(hallucinationResult);
|
|
8911
|
-
const isTelemetryActive = (
|
|
9594
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8912
9595
|
if (isTelemetryActive) {
|
|
8913
9596
|
const defaultUrl = process.env.NODE_ENV === "development" && !process.env.TELEMETRY_URL && !process.env.NEXT_PUBLIC_TELEMETRY_URL ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry";
|
|
8914
|
-
const telemetryUrl = ((
|
|
9597
|
+
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
8915
9598
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8916
9599
|
(async () => {
|
|
8917
9600
|
try {
|
|
@@ -8970,9 +9653,8 @@ ${context}`;
|
|
|
8970
9653
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8971
9654
|
);
|
|
8972
9655
|
}
|
|
8973
|
-
const
|
|
8974
|
-
|
|
8975
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9656
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9657
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8976
9658
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8977
9659
|
}
|
|
8978
9660
|
try {
|
|
@@ -9129,7 +9811,10 @@ ${context}`;
|
|
|
9129
9811
|
Focus on extracting the core intent and entities. Do not answer the question, just rewrite it.
|
|
9130
9812
|
|
|
9131
9813
|
History:
|
|
9132
|
-
${history.map((m) =>
|
|
9814
|
+
${(history || []).map((m) => {
|
|
9815
|
+
var _a2;
|
|
9816
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a2 = m == null ? void 0 : m.content) != null ? _a2 : ""}`;
|
|
9817
|
+
}).join("\n")}
|
|
9133
9818
|
|
|
9134
9819
|
New Question: ${question}
|
|
9135
9820
|
|
|
@@ -9153,8 +9838,11 @@ Optimized Search Query:`;
|
|
|
9153
9838
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
9154
9839
|
try {
|
|
9155
9840
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9156
|
-
if (sources.length === 0) return [];
|
|
9157
|
-
const context = sources.map((s) =>
|
|
9841
|
+
if (!sources || sources.length === 0) return [];
|
|
9842
|
+
const context = sources.map((s) => {
|
|
9843
|
+
var _a2;
|
|
9844
|
+
return (_a2 = s == null ? void 0 : s.content) != null ? _a2 : "";
|
|
9845
|
+
}).join("\n\n---\n\n");
|
|
9158
9846
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9159
9847
|
Focus on questions that can be answered by the context.
|
|
9160
9848
|
Keep each question under 10 words and make them very specific to the content.
|