@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/handlers/index.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({
|
|
@@ -2825,12 +3436,13 @@ var OpenAIProvider = class {
|
|
|
2825
3436
|
role: "system",
|
|
2826
3437
|
content: buildSystemContent(basePrompt, context)
|
|
2827
3438
|
};
|
|
3439
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
3440
|
+
role: m.role || "user",
|
|
3441
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
3442
|
+
}));
|
|
2828
3443
|
const formattedMessages = [
|
|
2829
3444
|
systemMessage,
|
|
2830
|
-
...
|
|
2831
|
-
role: m.role,
|
|
2832
|
-
content: m.content
|
|
2833
|
-
}))
|
|
3445
|
+
...safeMessages
|
|
2834
3446
|
];
|
|
2835
3447
|
const completion = await this.client.chat.completions.create({
|
|
2836
3448
|
model: this.llmConfig.model,
|
|
@@ -2849,12 +3461,13 @@ var OpenAIProvider = class {
|
|
|
2849
3461
|
role: "system",
|
|
2850
3462
|
content: buildSystemContent(basePrompt, context)
|
|
2851
3463
|
};
|
|
3464
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
3465
|
+
role: m.role || "user",
|
|
3466
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
3467
|
+
}));
|
|
2852
3468
|
const formattedMessages = [
|
|
2853
3469
|
systemMessage,
|
|
2854
|
-
...
|
|
2855
|
-
role: m.role,
|
|
2856
|
-
content: m.content
|
|
2857
|
-
}))
|
|
3470
|
+
...safeStreamMessages
|
|
2858
3471
|
];
|
|
2859
3472
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
2860
3473
|
model: this.llmConfig.model,
|
|
@@ -3385,9 +3998,9 @@ var GeminiProvider = class {
|
|
|
3385
3998
|
* - Messages must strictly alternate between `user` and `model`.
|
|
3386
3999
|
*/
|
|
3387
4000
|
buildGeminiContents(messages) {
|
|
3388
|
-
return messages.filter((m) => m.role !== "system").map((m) => ({
|
|
4001
|
+
return (messages || []).filter((m) => Boolean(m && typeof m === "object" && m.role !== "system")).map((m) => ({
|
|
3389
4002
|
role: m.role === "assistant" ? "model" : "user",
|
|
3390
|
-
parts: [{ text: m.content }]
|
|
4003
|
+
parts: [{ text: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : "" }]
|
|
3391
4004
|
}));
|
|
3392
4005
|
}
|
|
3393
4006
|
// -------------------------------------------------------------------------
|
|
@@ -3590,12 +4203,13 @@ var GroqProvider = class {
|
|
|
3590
4203
|
role: "system",
|
|
3591
4204
|
content: buildSystemContent(basePrompt, context)
|
|
3592
4205
|
};
|
|
4206
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4207
|
+
role: m.role || "user",
|
|
4208
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4209
|
+
}));
|
|
3593
4210
|
const formattedMessages = [
|
|
3594
4211
|
systemMessage,
|
|
3595
|
-
...
|
|
3596
|
-
role: m.role,
|
|
3597
|
-
content: m.content
|
|
3598
|
-
}))
|
|
4212
|
+
...safeMessages
|
|
3599
4213
|
];
|
|
3600
4214
|
const completion = await this.client.chat.completions.create({
|
|
3601
4215
|
model: this.llmConfig.model,
|
|
@@ -3614,12 +4228,13 @@ var GroqProvider = class {
|
|
|
3614
4228
|
role: "system",
|
|
3615
4229
|
content: buildSystemContent(basePrompt, context)
|
|
3616
4230
|
};
|
|
4231
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4232
|
+
role: m.role || "user",
|
|
4233
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4234
|
+
}));
|
|
3617
4235
|
const formattedMessages = [
|
|
3618
4236
|
systemMessage,
|
|
3619
|
-
...
|
|
3620
|
-
role: m.role,
|
|
3621
|
-
content: m.content
|
|
3622
|
-
}))
|
|
4237
|
+
...safeStreamMessages
|
|
3623
4238
|
];
|
|
3624
4239
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
3625
4240
|
model: this.llmConfig.model,
|
|
@@ -3748,12 +4363,13 @@ var QwenProvider = class {
|
|
|
3748
4363
|
role: "system",
|
|
3749
4364
|
content: buildSystemContent(basePrompt, context)
|
|
3750
4365
|
};
|
|
4366
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4367
|
+
role: m.role || "user",
|
|
4368
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4369
|
+
}));
|
|
3751
4370
|
const formattedMessages = [
|
|
3752
4371
|
systemMessage,
|
|
3753
|
-
...
|
|
3754
|
-
role: m.role,
|
|
3755
|
-
content: m.content
|
|
3756
|
-
}))
|
|
4372
|
+
...safeMessages
|
|
3757
4373
|
];
|
|
3758
4374
|
const completion = await this.client.chat.completions.create({
|
|
3759
4375
|
model: this.llmConfig.model,
|
|
@@ -3772,12 +4388,13 @@ var QwenProvider = class {
|
|
|
3772
4388
|
role: "system",
|
|
3773
4389
|
content: buildSystemContent(basePrompt, context)
|
|
3774
4390
|
};
|
|
4391
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4392
|
+
role: m.role || "user",
|
|
4393
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4394
|
+
}));
|
|
3775
4395
|
const formattedMessages = [
|
|
3776
4396
|
systemMessage,
|
|
3777
|
-
...
|
|
3778
|
-
role: m.role,
|
|
3779
|
-
content: m.content
|
|
3780
|
-
}))
|
|
4397
|
+
...safeStreamMessages
|
|
3781
4398
|
];
|
|
3782
4399
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
3783
4400
|
model: this.llmConfig.model,
|
|
@@ -3876,6 +4493,17 @@ var LLM_PROFILES = {
|
|
|
3876
4493
|
};
|
|
3877
4494
|
|
|
3878
4495
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4496
|
+
function extractContent(obj) {
|
|
4497
|
+
var _a2, _b, _c;
|
|
4498
|
+
if (!obj || typeof obj !== "object") return void 0;
|
|
4499
|
+
const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
|
|
4500
|
+
if (!choice) return void 0;
|
|
4501
|
+
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4502
|
+
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
4503
|
+
if (typeof choice.text === "string") return choice.text;
|
|
4504
|
+
if (typeof choice.content === "string") return choice.content;
|
|
4505
|
+
return void 0;
|
|
4506
|
+
}
|
|
3879
4507
|
var UniversalLLMAdapter = class {
|
|
3880
4508
|
constructor(config) {
|
|
3881
4509
|
var _a2, _b, _c, _d, _e, _f, _g2, _h;
|
|
@@ -3907,14 +4535,18 @@ var UniversalLLMAdapter = class {
|
|
|
3907
4535
|
});
|
|
3908
4536
|
}
|
|
3909
4537
|
async chat(messages, context) {
|
|
3910
|
-
var _a2, _b, _c
|
|
4538
|
+
var _a2, _b, _c;
|
|
3911
4539
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
4540
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4541
|
+
role: m.role || "user",
|
|
4542
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4543
|
+
}));
|
|
3912
4544
|
const formattedMessages = [
|
|
3913
4545
|
{ role: "system", content: `${this.systemPrompt}
|
|
3914
4546
|
|
|
3915
4547
|
Context:
|
|
3916
4548
|
${context != null ? context : "None"}` },
|
|
3917
|
-
...
|
|
4549
|
+
...safeMessages
|
|
3918
4550
|
];
|
|
3919
4551
|
let payload;
|
|
3920
4552
|
if (this.opts.chatPayloadTemplate) {
|
|
@@ -3935,25 +4567,41 @@ ${context != null ? context : "None"}` },
|
|
|
3935
4567
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3936
4568
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3937
4569
|
const _g2 = globalThis;
|
|
3938
|
-
|
|
4570
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4571
|
+
if (typeof dispatch !== "function") {
|
|
3939
4572
|
try {
|
|
3940
|
-
const
|
|
4573
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4574
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4575
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4576
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4577
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4578
|
+
}
|
|
4579
|
+
} catch (e) {
|
|
4580
|
+
}
|
|
4581
|
+
}
|
|
4582
|
+
if (typeof dispatch === "function") {
|
|
4583
|
+
try {
|
|
4584
|
+
const res = await dispatch({
|
|
3941
4585
|
model: this.model,
|
|
3942
4586
|
messages: formattedMessages,
|
|
3943
4587
|
max_tokens: this.maxTokens,
|
|
3944
4588
|
temperature: this.temperature
|
|
3945
4589
|
}, this.apiKey);
|
|
3946
|
-
|
|
3947
|
-
|
|
4590
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4591
|
+
if (content !== void 0) {
|
|
4592
|
+
return content;
|
|
3948
4593
|
}
|
|
4594
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
|
|
3949
4595
|
} catch (dispatchErr) {
|
|
3950
4596
|
throw dispatchErr;
|
|
3951
4597
|
}
|
|
4598
|
+
} else {
|
|
4599
|
+
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.`);
|
|
3952
4600
|
}
|
|
3953
4601
|
}
|
|
3954
4602
|
const { data } = await this.http.post(path2, payload);
|
|
3955
|
-
const extractPath = (
|
|
3956
|
-
const result = resolvePath(data, extractPath);
|
|
4603
|
+
const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
|
|
4604
|
+
const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
|
|
3957
4605
|
if (result === void 0) {
|
|
3958
4606
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
3959
4607
|
}
|
|
@@ -3966,16 +4614,20 @@ ${context != null ? context : "None"}` },
|
|
|
3966
4614
|
*/
|
|
3967
4615
|
chatStream(messages, context) {
|
|
3968
4616
|
return __asyncGenerator(this, null, function* () {
|
|
3969
|
-
var _a2, _b, _c, _d, _e
|
|
4617
|
+
var _a2, _b, _c, _d, _e;
|
|
3970
4618
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3971
4619
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
3972
4620
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4621
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4622
|
+
role: m.role || "user",
|
|
4623
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4624
|
+
}));
|
|
3973
4625
|
const formattedMessages = [
|
|
3974
4626
|
{ role: "system", content: `${this.systemPrompt}
|
|
3975
4627
|
|
|
3976
4628
|
Context:
|
|
3977
4629
|
${context != null ? context : "None"}` },
|
|
3978
|
-
...
|
|
4630
|
+
...safeMessages
|
|
3979
4631
|
];
|
|
3980
4632
|
let payload;
|
|
3981
4633
|
if (this.opts.chatPayloadTemplate) {
|
|
@@ -4000,10 +4652,22 @@ ${context != null ? context : "None"}` },
|
|
|
4000
4652
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4001
4653
|
let streamBody = null;
|
|
4002
4654
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4003
|
-
const
|
|
4004
|
-
|
|
4655
|
+
const _g2 = globalThis;
|
|
4656
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4657
|
+
if (typeof dispatch !== "function") {
|
|
4005
4658
|
try {
|
|
4006
|
-
const
|
|
4659
|
+
const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
|
|
4660
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4661
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4662
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4663
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4664
|
+
}
|
|
4665
|
+
} catch (e) {
|
|
4666
|
+
}
|
|
4667
|
+
}
|
|
4668
|
+
if (typeof dispatch === "function") {
|
|
4669
|
+
try {
|
|
4670
|
+
const res = yield new __await(dispatch({
|
|
4007
4671
|
model: this.model,
|
|
4008
4672
|
messages: formattedMessages,
|
|
4009
4673
|
max_tokens: this.maxTokens,
|
|
@@ -4012,13 +4676,19 @@ ${context != null ? context : "None"}` },
|
|
|
4012
4676
|
}, this.apiKey));
|
|
4013
4677
|
if (res == null ? void 0 : res.stream) {
|
|
4014
4678
|
streamBody = res.stream;
|
|
4015
|
-
} else
|
|
4016
|
-
|
|
4017
|
-
|
|
4679
|
+
} else {
|
|
4680
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4681
|
+
if (content !== void 0) {
|
|
4682
|
+
yield content;
|
|
4683
|
+
return;
|
|
4684
|
+
}
|
|
4685
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
|
|
4018
4686
|
}
|
|
4019
4687
|
} catch (dispatchErr) {
|
|
4020
4688
|
throw dispatchErr;
|
|
4021
4689
|
}
|
|
4690
|
+
} else {
|
|
4691
|
+
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.`);
|
|
4022
4692
|
}
|
|
4023
4693
|
}
|
|
4024
4694
|
if (!streamBody) {
|
|
@@ -4045,14 +4715,14 @@ ${context != null ? context : "None"}` },
|
|
|
4045
4715
|
if (done) break;
|
|
4046
4716
|
buffer += decoder.decode(value, { stream: true });
|
|
4047
4717
|
const lines = buffer.split("\n");
|
|
4048
|
-
buffer = (
|
|
4718
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4049
4719
|
for (const line of lines) {
|
|
4050
4720
|
const trimmed = line.trim();
|
|
4051
4721
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4052
4722
|
if (!trimmed.startsWith("data:")) continue;
|
|
4053
4723
|
try {
|
|
4054
4724
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4055
|
-
const text = resolvePath(json, extractPath);
|
|
4725
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4056
4726
|
if (text && typeof text === "string") yield text;
|
|
4057
4727
|
} catch (e) {
|
|
4058
4728
|
}
|
|
@@ -4062,7 +4732,7 @@ ${context != null ? context : "None"}` },
|
|
|
4062
4732
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4063
4733
|
try {
|
|
4064
4734
|
const json = JSON.parse(jsonStr);
|
|
4065
|
-
const text = resolvePath(json, extractPath);
|
|
4735
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4066
4736
|
if (text && typeof text === "string") yield text;
|
|
4067
4737
|
} catch (e) {
|
|
4068
4738
|
}
|
|
@@ -4090,18 +4760,33 @@ ${context != null ? context : "None"}` },
|
|
|
4090
4760
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4091
4761
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4092
4762
|
const _g2 = globalThis;
|
|
4093
|
-
|
|
4763
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4764
|
+
if (typeof dispatch !== "function") {
|
|
4094
4765
|
try {
|
|
4095
|
-
const
|
|
4766
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4767
|
+
if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
|
|
4768
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4769
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4770
|
+
dispatch = gateway.dispatchEmbedding;
|
|
4771
|
+
}
|
|
4772
|
+
} catch (e) {
|
|
4773
|
+
}
|
|
4774
|
+
}
|
|
4775
|
+
if (typeof dispatch === "function") {
|
|
4776
|
+
try {
|
|
4777
|
+
const res = await dispatch({
|
|
4096
4778
|
model: this.model,
|
|
4097
4779
|
input: text
|
|
4098
4780
|
}, this.apiKey);
|
|
4099
4781
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4100
4782
|
return res.data[0].embedding;
|
|
4101
4783
|
}
|
|
4784
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4102
4785
|
} catch (dispatchErr) {
|
|
4103
4786
|
throw dispatchErr;
|
|
4104
4787
|
}
|
|
4788
|
+
} else {
|
|
4789
|
+
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.`);
|
|
4105
4790
|
}
|
|
4106
4791
|
}
|
|
4107
4792
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -6080,8 +6765,8 @@ var IntentClassifier = class {
|
|
|
6080
6765
|
}
|
|
6081
6766
|
// ─── Intent Heuristic Checkers ─────────────────────────────────────────────
|
|
6082
6767
|
static isInformationLookup(query) {
|
|
6083
|
-
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)) {
|
|
6084
|
-
if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top selling|best)\b/i.test(query)) {
|
|
6768
|
+
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)) {
|
|
6769
|
+
if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top 10|top selling|best|chart|graph|plot|breakdown|analytics)\b/i.test(query)) {
|
|
6085
6770
|
return true;
|
|
6086
6771
|
}
|
|
6087
6772
|
}
|
|
@@ -6118,7 +6803,7 @@ var Rule1SpecificInfoRule = class {
|
|
|
6118
6803
|
}
|
|
6119
6804
|
evaluate(context, intent) {
|
|
6120
6805
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6121
|
-
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);
|
|
6806
|
+
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);
|
|
6122
6807
|
const isNonVisual = !/\b(compare|versus|vs\.?|trend|monthly|revenue|best|top 10|chart|table|list|grid)\b/i.test(q);
|
|
6123
6808
|
if (isFactQuery && isNonVisual) {
|
|
6124
6809
|
return {
|
|
@@ -6949,7 +7634,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
6949
7634
|
}
|
|
6950
7635
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
6951
7636
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
6952
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null)
|
|
7637
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
6953
7638
|
return {
|
|
6954
7639
|
type: "product_carousel",
|
|
6955
7640
|
title: "Recommended Products",
|
|
@@ -7329,7 +8014,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7329
8014
|
return fieldCount.size > 2;
|
|
7330
8015
|
}
|
|
7331
8016
|
static profileData(data) {
|
|
7332
|
-
const records = data.map((item) => {
|
|
8017
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
8018
|
+
var _a2, _b;
|
|
7333
8019
|
const fields2 = {};
|
|
7334
8020
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7335
8021
|
const primitive = this.toPrimitive(value);
|
|
@@ -7338,8 +8024,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7338
8024
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7339
8025
|
return {
|
|
7340
8026
|
id: item.id,
|
|
7341
|
-
content: item.content,
|
|
7342
|
-
score: item.score,
|
|
8027
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
8028
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7343
8029
|
fields: fields2,
|
|
7344
8030
|
source: item
|
|
7345
8031
|
};
|
|
@@ -7396,6 +8082,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7396
8082
|
}
|
|
7397
8083
|
static chooseAutomaticVisualization(data, profile, query) {
|
|
7398
8084
|
if (profile.records.length === 0) return null;
|
|
8085
|
+
const q = query.toLowerCase().trim();
|
|
8086
|
+
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);
|
|
8087
|
+
if (!isExplicitVisualOrAnalytic) {
|
|
8088
|
+
return null;
|
|
8089
|
+
}
|
|
7399
8090
|
if (profile.dateFields.length > 0 && profile.numericFields.length > 0) {
|
|
7400
8091
|
return this.transformToLineChart(profile);
|
|
7401
8092
|
}
|
|
@@ -7511,6 +8202,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7511
8202
|
return Array.from(categories);
|
|
7512
8203
|
}
|
|
7513
8204
|
static getProductCategory(item) {
|
|
8205
|
+
if (!item) return null;
|
|
7514
8206
|
const meta = item.metadata || {};
|
|
7515
8207
|
const metadataCategory = resolveMetadataValue(meta, "category");
|
|
7516
8208
|
if (this.isUsableCategory(metadataCategory)) return String(metadataCategory).trim();
|
|
@@ -7627,6 +8319,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7627
8319
|
if (!fields.has(normalized)) fields.set(normalized, clean);
|
|
7628
8320
|
};
|
|
7629
8321
|
data.forEach((item) => {
|
|
8322
|
+
if (!item) return;
|
|
7630
8323
|
Object.keys(item.metadata || {}).forEach(addField);
|
|
7631
8324
|
for (const match of (item.content || "").matchAll(/(?:^|\n)\s*([A-Za-z][A-Za-z0-9_ /-]{1,50})\s*[:\-–]\s*([^\n]+)/g)) {
|
|
7632
8325
|
addField(match[1]);
|
|
@@ -7743,6 +8436,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7743
8436
|
return true;
|
|
7744
8437
|
}
|
|
7745
8438
|
static extractStockQuantity(item) {
|
|
8439
|
+
if (!item) return null;
|
|
7746
8440
|
const meta = item.metadata || {};
|
|
7747
8441
|
const stockValue = resolveMetadataValue(meta, "stock");
|
|
7748
8442
|
const numericStock = this.toFiniteNumber(stockValue);
|
|
@@ -8442,7 +9136,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8442
9136
|
*/
|
|
8443
9137
|
askStreamInternal(_0) {
|
|
8444
9138
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8445
|
-
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
|
|
9139
|
+
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;
|
|
8446
9140
|
yield new __await(this.initialize());
|
|
8447
9141
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8448
9142
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8485,8 +9179,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8485
9179
|
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;
|
|
8486
9180
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8487
9181
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8488
|
-
const wantsExhaustiveList =
|
|
8489
|
-
const retrievalLimit =
|
|
9182
|
+
const wantsExhaustiveList = true;
|
|
9183
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
8490
9184
|
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"));
|
|
8491
9185
|
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
8492
9186
|
rawCount: rawSources.length,
|
|
@@ -8510,40 +9204,29 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8510
9204
|
var _a3;
|
|
8511
9205
|
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
8512
9206
|
});
|
|
8513
|
-
const rerankLimit =
|
|
9207
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8514
9208
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8515
9209
|
if (!hasNumericPredicates && useReranking) {
|
|
8516
9210
|
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8517
|
-
} else if (!wantsExhaustiveList) {
|
|
8518
|
-
fullSources = fullSources.slice(0, topK);
|
|
8519
9211
|
}
|
|
8520
9212
|
const rerankMs = performance.now() - rerankStart;
|
|
8521
|
-
|
|
9213
|
+
const totalCount = fullSources.length;
|
|
9214
|
+
const promptSources = fullSources.slice(0, 15);
|
|
9215
|
+
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]
|
|
9216
|
+
|
|
9217
|
+
` + promptSources.map((m, i) => {
|
|
8522
9218
|
var _a3;
|
|
8523
9219
|
return `[Source ${i + 1}]
|
|
8524
9220
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8525
9221
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8526
|
-
let displayCount = 15;
|
|
8527
|
-
if (hasMetadataFilter) {
|
|
8528
|
-
displayCount = fullSources.length;
|
|
8529
|
-
} else {
|
|
8530
|
-
const baseThreshold = Math.max(scoreThreshold, 0.4);
|
|
8531
|
-
const highlyRelevant = fullSources.filter((m) => {
|
|
8532
|
-
var _a3;
|
|
8533
|
-
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= baseThreshold;
|
|
8534
|
-
});
|
|
8535
|
-
displayCount = Math.max(highlyRelevant.length, topK);
|
|
8536
|
-
if (displayCount > 15) {
|
|
8537
|
-
displayCount = 15;
|
|
8538
|
-
}
|
|
8539
|
-
}
|
|
8540
9222
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8541
9223
|
var _a3, _b2;
|
|
8542
9224
|
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8543
|
-
})
|
|
9225
|
+
});
|
|
8544
9226
|
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
8545
9227
|
count: sources.length,
|
|
8546
|
-
|
|
9228
|
+
totalRawCount: rawSources.length,
|
|
9229
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
8547
9230
|
var _a3;
|
|
8548
9231
|
return {
|
|
8549
9232
|
rank: idx + 1,
|
|
@@ -8743,7 +9426,7 @@ ${context}`;
|
|
|
8743
9426
|
}
|
|
8744
9427
|
yield fullReply;
|
|
8745
9428
|
}
|
|
8746
|
-
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true
|
|
9429
|
+
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
|
|
8747
9430
|
if (runHallucination) {
|
|
8748
9431
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8749
9432
|
}
|
|
@@ -8752,7 +9435,7 @@ ${context}`;
|
|
|
8752
9435
|
const latency = {
|
|
8753
9436
|
embedMs: Math.round(embedMs),
|
|
8754
9437
|
retrieveMs: Math.round(retrieveMs),
|
|
8755
|
-
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((
|
|
9438
|
+
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
|
|
8756
9439
|
generateMs: Math.round(generateMs),
|
|
8757
9440
|
totalMs: Math.round(totalMs)
|
|
8758
9441
|
};
|
|
@@ -8765,7 +9448,7 @@ ${context}`;
|
|
|
8765
9448
|
totalTokens: promptTokens + completionTokens,
|
|
8766
9449
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8767
9450
|
};
|
|
8768
|
-
const awaitHallucination = ((
|
|
9451
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8769
9452
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8770
9453
|
uiTransformationPromise,
|
|
8771
9454
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8794,10 +9477,10 @@ ${context}`;
|
|
|
8794
9477
|
hallucinationReason: hScore.reason
|
|
8795
9478
|
} : {});
|
|
8796
9479
|
const trace = buildTrace(hallucinationResult);
|
|
8797
|
-
const isTelemetryActive = (
|
|
9480
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8798
9481
|
if (isTelemetryActive) {
|
|
8799
9482
|
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";
|
|
8800
|
-
const telemetryUrl = ((
|
|
9483
|
+
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
8801
9484
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8802
9485
|
(async () => {
|
|
8803
9486
|
try {
|
|
@@ -8856,9 +9539,8 @@ ${context}`;
|
|
|
8856
9539
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8857
9540
|
);
|
|
8858
9541
|
}
|
|
8859
|
-
const
|
|
8860
|
-
|
|
8861
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9542
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9543
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8862
9544
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8863
9545
|
}
|
|
8864
9546
|
try {
|
|
@@ -9015,7 +9697,10 @@ ${context}`;
|
|
|
9015
9697
|
Focus on extracting the core intent and entities. Do not answer the question, just rewrite it.
|
|
9016
9698
|
|
|
9017
9699
|
History:
|
|
9018
|
-
${history.map((m) =>
|
|
9700
|
+
${(history || []).map((m) => {
|
|
9701
|
+
var _a2;
|
|
9702
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a2 = m == null ? void 0 : m.content) != null ? _a2 : ""}`;
|
|
9703
|
+
}).join("\n")}
|
|
9019
9704
|
|
|
9020
9705
|
New Question: ${question}
|
|
9021
9706
|
|
|
@@ -9039,8 +9724,11 @@ Optimized Search Query:`;
|
|
|
9039
9724
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
9040
9725
|
try {
|
|
9041
9726
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9042
|
-
if (sources.length === 0) return [];
|
|
9043
|
-
const context = sources.map((s) =>
|
|
9727
|
+
if (!sources || sources.length === 0) return [];
|
|
9728
|
+
const context = sources.map((s) => {
|
|
9729
|
+
var _a2;
|
|
9730
|
+
return (_a2 = s == null ? void 0 : s.content) != null ? _a2 : "";
|
|
9731
|
+
}).join("\n\n---\n\n");
|
|
9044
9732
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9045
9733
|
Focus on questions that can be answered by the context.
|
|
9046
9734
|
Keep each question under 10 words and make them very specific to the content.
|