@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.mjs
CHANGED
|
@@ -106,6 +106,617 @@ var init_templateUtils = __esm({
|
|
|
106
106
|
}
|
|
107
107
|
});
|
|
108
108
|
|
|
109
|
+
// ../../services/llm-gateway/providers/groq.ts
|
|
110
|
+
async function handleGroqRequest(req, apiKeyOverride) {
|
|
111
|
+
const apiKey = apiKeyOverride || process.env.GROQ_API_KEY;
|
|
112
|
+
if (!apiKey) {
|
|
113
|
+
throw new Error("Groq API Key missing. Please set GROQ_API_KEY in environment variables.");
|
|
114
|
+
}
|
|
115
|
+
const modelName = req.model.replace(/^groq\//i, "");
|
|
116
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
117
|
+
model: modelName
|
|
118
|
+
});
|
|
119
|
+
const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
|
|
120
|
+
method: "POST",
|
|
121
|
+
headers: {
|
|
122
|
+
"Content-Type": "application/json",
|
|
123
|
+
"Authorization": `Bearer ${apiKey}`
|
|
124
|
+
},
|
|
125
|
+
body: JSON.stringify(payload)
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const errorText = await response.text();
|
|
129
|
+
throw new Error(`Groq API Error (${response.status}): ${errorText}`);
|
|
130
|
+
}
|
|
131
|
+
if (req.stream && response.body) {
|
|
132
|
+
return { stream: response.body };
|
|
133
|
+
}
|
|
134
|
+
const json = await response.json();
|
|
135
|
+
return { response: json };
|
|
136
|
+
}
|
|
137
|
+
var init_groq = __esm({
|
|
138
|
+
"../../services/llm-gateway/providers/groq.ts"() {
|
|
139
|
+
"use strict";
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// ../../services/llm-gateway/providers/openai.ts
|
|
144
|
+
async function handleOpenAIRequest(req, apiKeyOverride) {
|
|
145
|
+
const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
|
|
146
|
+
if (!apiKey) {
|
|
147
|
+
throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
|
|
148
|
+
}
|
|
149
|
+
const modelName = req.model.replace(/^(openai|gpt)\//i, "");
|
|
150
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
151
|
+
model: modelName
|
|
152
|
+
});
|
|
153
|
+
const response = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
154
|
+
method: "POST",
|
|
155
|
+
headers: {
|
|
156
|
+
"Content-Type": "application/json",
|
|
157
|
+
"Authorization": `Bearer ${apiKey}`
|
|
158
|
+
},
|
|
159
|
+
body: JSON.stringify(payload)
|
|
160
|
+
});
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
const errorText = await response.text();
|
|
163
|
+
throw new Error(`OpenAI API Error (${response.status}): ${errorText}`);
|
|
164
|
+
}
|
|
165
|
+
if (req.stream && response.body) {
|
|
166
|
+
return { stream: response.body };
|
|
167
|
+
}
|
|
168
|
+
const json = await response.json();
|
|
169
|
+
return { response: json };
|
|
170
|
+
}
|
|
171
|
+
async function handleOpenAIEmbedding(req, apiKeyOverride) {
|
|
172
|
+
const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
|
|
173
|
+
if (!apiKey) {
|
|
174
|
+
throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
|
|
175
|
+
}
|
|
176
|
+
const modelName = req.model.replace(/^(openai)\//i, "");
|
|
177
|
+
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
178
|
+
method: "POST",
|
|
179
|
+
headers: {
|
|
180
|
+
"Content-Type": "application/json",
|
|
181
|
+
"Authorization": `Bearer ${apiKey}`
|
|
182
|
+
},
|
|
183
|
+
body: JSON.stringify({
|
|
184
|
+
model: modelName,
|
|
185
|
+
input: req.input
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
if (!response.ok) {
|
|
189
|
+
const errorText = await response.text();
|
|
190
|
+
throw new Error(`OpenAI Embedding API Error (${response.status}): ${errorText}`);
|
|
191
|
+
}
|
|
192
|
+
return await response.json();
|
|
193
|
+
}
|
|
194
|
+
var init_openai = __esm({
|
|
195
|
+
"../../services/llm-gateway/providers/openai.ts"() {
|
|
196
|
+
"use strict";
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// ../../services/llm-gateway/providers/gemini.ts
|
|
201
|
+
async function handleGeminiRequest(req, apiKeyOverride) {
|
|
202
|
+
const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
|
|
203
|
+
if (!apiKey) {
|
|
204
|
+
throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
|
|
205
|
+
}
|
|
206
|
+
let modelName = req.model.replace(/^(google|gemini)\//i, "");
|
|
207
|
+
if (!modelName.startsWith("gemini-")) {
|
|
208
|
+
modelName = `gemini-${modelName}`;
|
|
209
|
+
}
|
|
210
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
211
|
+
model: modelName
|
|
212
|
+
});
|
|
213
|
+
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", {
|
|
214
|
+
method: "POST",
|
|
215
|
+
headers: {
|
|
216
|
+
"Content-Type": "application/json",
|
|
217
|
+
"Authorization": `Bearer ${apiKey}`
|
|
218
|
+
},
|
|
219
|
+
body: JSON.stringify(payload)
|
|
220
|
+
});
|
|
221
|
+
if (!response.ok) {
|
|
222
|
+
const errorText = await response.text();
|
|
223
|
+
throw new Error(`Google Gemini API Error (${response.status}): ${errorText}`);
|
|
224
|
+
}
|
|
225
|
+
if (req.stream && response.body) {
|
|
226
|
+
return { stream: response.body };
|
|
227
|
+
}
|
|
228
|
+
const json = await response.json();
|
|
229
|
+
return { response: json };
|
|
230
|
+
}
|
|
231
|
+
async function handleGeminiEmbedding(req, apiKeyOverride) {
|
|
232
|
+
const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
|
|
233
|
+
if (!apiKey) {
|
|
234
|
+
throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
|
|
235
|
+
}
|
|
236
|
+
let modelName = req.model.replace(/^(google|gemini)\//i, "");
|
|
237
|
+
if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.startsWith("text-embedding-00") && !modelName.startsWith("embedding-00")) {
|
|
238
|
+
modelName = "text-embedding-004";
|
|
239
|
+
}
|
|
240
|
+
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/embeddings", {
|
|
241
|
+
method: "POST",
|
|
242
|
+
headers: {
|
|
243
|
+
"Content-Type": "application/json",
|
|
244
|
+
"Authorization": `Bearer ${apiKey}`
|
|
245
|
+
},
|
|
246
|
+
body: JSON.stringify({
|
|
247
|
+
model: modelName,
|
|
248
|
+
input: req.input
|
|
249
|
+
})
|
|
250
|
+
});
|
|
251
|
+
if (!response.ok) {
|
|
252
|
+
const errorText = await response.text();
|
|
253
|
+
throw new Error(`Google Gemini Embedding API Error (${response.status}): ${errorText}`);
|
|
254
|
+
}
|
|
255
|
+
return await response.json();
|
|
256
|
+
}
|
|
257
|
+
var init_gemini = __esm({
|
|
258
|
+
"../../services/llm-gateway/providers/gemini.ts"() {
|
|
259
|
+
"use strict";
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// ../../services/llm-gateway/providers/huggingface.ts
|
|
264
|
+
async function handleHuggingFaceChatRequest(req, apiKeyOverride) {
|
|
265
|
+
var _a2, _b;
|
|
266
|
+
const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
|
|
267
|
+
if (!apiKey) {
|
|
268
|
+
throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
|
|
269
|
+
}
|
|
270
|
+
let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
|
|
271
|
+
if (!modelName || modelName === "default" || modelName.toLowerCase() === "qwen" || modelName.toLowerCase() === "qwen-coder") {
|
|
272
|
+
modelName = "Qwen/Qwen2.5-Coder-32B-Instruct";
|
|
273
|
+
}
|
|
274
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
275
|
+
model: modelName
|
|
276
|
+
});
|
|
277
|
+
try {
|
|
278
|
+
const response = await fetch("https://router.huggingface.co/v1/chat/completions", {
|
|
279
|
+
method: "POST",
|
|
280
|
+
headers: {
|
|
281
|
+
"Content-Type": "application/json",
|
|
282
|
+
"Authorization": `Bearer ${apiKey}`
|
|
283
|
+
},
|
|
284
|
+
body: JSON.stringify(payload)
|
|
285
|
+
});
|
|
286
|
+
if (response.ok) {
|
|
287
|
+
if (req.stream && response.body) {
|
|
288
|
+
return { stream: response.body };
|
|
289
|
+
}
|
|
290
|
+
const json = await response.json();
|
|
291
|
+
return { response: json };
|
|
292
|
+
}
|
|
293
|
+
} catch (e) {
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
const response = await fetch("https://router.huggingface.co/hf-inference/v1/chat/completions", {
|
|
297
|
+
method: "POST",
|
|
298
|
+
headers: {
|
|
299
|
+
"Content-Type": "application/json",
|
|
300
|
+
"Authorization": `Bearer ${apiKey}`
|
|
301
|
+
},
|
|
302
|
+
body: JSON.stringify(payload)
|
|
303
|
+
});
|
|
304
|
+
if (response.ok) {
|
|
305
|
+
if (req.stream && response.body) {
|
|
306
|
+
return { stream: response.body };
|
|
307
|
+
}
|
|
308
|
+
const json = await response.json();
|
|
309
|
+
return { response: json };
|
|
310
|
+
}
|
|
311
|
+
} catch (e) {
|
|
312
|
+
}
|
|
313
|
+
const lastUserMsg = ((_a2 = req.messages.filter((m) => m.role === "user").pop()) == null ? void 0 : _a2.content) || "Hello";
|
|
314
|
+
const pipelineRes = await fetch(`https://router.huggingface.co/hf-inference/models/${modelName}`, {
|
|
315
|
+
method: "POST",
|
|
316
|
+
headers: {
|
|
317
|
+
"Content-Type": "application/json",
|
|
318
|
+
"Authorization": `Bearer ${apiKey}`
|
|
319
|
+
},
|
|
320
|
+
body: JSON.stringify({
|
|
321
|
+
inputs: lastUserMsg,
|
|
322
|
+
parameters: { max_new_tokens: req.max_tokens || 256, temperature: req.temperature || 0.7 },
|
|
323
|
+
options: { wait_for_model: true }
|
|
324
|
+
})
|
|
325
|
+
});
|
|
326
|
+
if (!pipelineRes.ok) {
|
|
327
|
+
const errorText = await pipelineRes.text();
|
|
328
|
+
throw new Error(`HuggingFace API Error (${pipelineRes.status}): ${errorText}`);
|
|
329
|
+
}
|
|
330
|
+
const raw = await pipelineRes.json();
|
|
331
|
+
const textOutput = Array.isArray(raw) ? ((_b = raw[0]) == null ? void 0 : _b.generated_text) || JSON.stringify(raw) : JSON.stringify(raw);
|
|
332
|
+
const formattedResponse = {
|
|
333
|
+
id: `hf-${Date.now()}`,
|
|
334
|
+
object: "chat.completion",
|
|
335
|
+
created: Math.floor(Date.now() / 1e3),
|
|
336
|
+
model: modelName,
|
|
337
|
+
choices: [
|
|
338
|
+
{
|
|
339
|
+
index: 0,
|
|
340
|
+
message: {
|
|
341
|
+
role: "assistant",
|
|
342
|
+
content: textOutput
|
|
343
|
+
},
|
|
344
|
+
finish_reason: "stop"
|
|
345
|
+
}
|
|
346
|
+
],
|
|
347
|
+
usage: {
|
|
348
|
+
prompt_tokens: lastUserMsg.length,
|
|
349
|
+
completion_tokens: textOutput.length,
|
|
350
|
+
total_tokens: lastUserMsg.length + textOutput.length
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
return { response: formattedResponse };
|
|
354
|
+
}
|
|
355
|
+
async function handleHuggingFaceEmbedding(req, apiKeyOverride) {
|
|
356
|
+
const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
|
|
357
|
+
if (!apiKey) {
|
|
358
|
+
throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
|
|
359
|
+
}
|
|
360
|
+
let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
|
|
361
|
+
if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.includes("/") && !modelName.includes("bge") && !modelName.includes("sentence-transformers")) {
|
|
362
|
+
modelName = "BAAI/bge-base-en-v1.5";
|
|
363
|
+
}
|
|
364
|
+
const inputs = Array.isArray(req.input) ? req.input : [req.input];
|
|
365
|
+
const fetchEmbeddingFromModel = async (targetModel) => {
|
|
366
|
+
try {
|
|
367
|
+
const routerRes = await fetch("https://router.huggingface.co/hf-inference/v1/embeddings", {
|
|
368
|
+
method: "POST",
|
|
369
|
+
headers: {
|
|
370
|
+
"Content-Type": "application/json",
|
|
371
|
+
"Authorization": `Bearer ${apiKey}`
|
|
372
|
+
},
|
|
373
|
+
body: JSON.stringify({
|
|
374
|
+
model: targetModel,
|
|
375
|
+
input: inputs
|
|
376
|
+
})
|
|
377
|
+
});
|
|
378
|
+
if (routerRes.ok) {
|
|
379
|
+
const json = await routerRes.json();
|
|
380
|
+
if (json && json.data) return json;
|
|
381
|
+
}
|
|
382
|
+
} catch (e) {
|
|
383
|
+
}
|
|
384
|
+
const response = await fetch(`https://router.huggingface.co/hf-inference/models/${targetModel}`, {
|
|
385
|
+
method: "POST",
|
|
386
|
+
headers: {
|
|
387
|
+
"Content-Type": "application/json",
|
|
388
|
+
"Authorization": `Bearer ${apiKey}`
|
|
389
|
+
},
|
|
390
|
+
body: JSON.stringify({
|
|
391
|
+
inputs,
|
|
392
|
+
options: { wait_for_model: true }
|
|
393
|
+
})
|
|
394
|
+
});
|
|
395
|
+
if (!response.ok) {
|
|
396
|
+
const errorText = await response.text();
|
|
397
|
+
throw new Error(`HuggingFace API Error (${response.status}): ${errorText}`);
|
|
398
|
+
}
|
|
399
|
+
const rawData = await response.json();
|
|
400
|
+
const embeddings = Array.isArray(rawData[0]) ? typeof rawData[0][0] === "number" ? rawData : rawData.map((arr) => arr[0]) : [rawData];
|
|
401
|
+
return {
|
|
402
|
+
object: "list",
|
|
403
|
+
data: embeddings.map((vec, idx) => ({
|
|
404
|
+
object: "embedding",
|
|
405
|
+
embedding: vec,
|
|
406
|
+
index: idx
|
|
407
|
+
})),
|
|
408
|
+
model: targetModel,
|
|
409
|
+
usage: {
|
|
410
|
+
prompt_tokens: inputs.reduce((acc, str) => acc + str.length, 0),
|
|
411
|
+
completion_tokens: 0,
|
|
412
|
+
total_tokens: inputs.reduce((acc, str) => acc + str.length, 0)
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
};
|
|
416
|
+
try {
|
|
417
|
+
return await fetchEmbeddingFromModel(modelName);
|
|
418
|
+
} catch (err) {
|
|
419
|
+
if (modelName !== "BAAI/bge-base-en-v1.5") {
|
|
420
|
+
console.warn(`[LLM Gateway] HuggingFace model ${modelName} failed. Falling back to BAAI/bge-base-en-v1.5...`, err);
|
|
421
|
+
return await fetchEmbeddingFromModel("BAAI/bge-base-en-v1.5");
|
|
422
|
+
}
|
|
423
|
+
throw err;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
var init_huggingface = __esm({
|
|
427
|
+
"../../services/llm-gateway/providers/huggingface.ts"() {
|
|
428
|
+
"use strict";
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// ../../services/llm-gateway/providers/anthropic.ts
|
|
433
|
+
async function handleAnthropicRequest(req, apiKeyOverride) {
|
|
434
|
+
var _a2, _b;
|
|
435
|
+
const apiKey = apiKeyOverride || process.env.ANTHROPIC_API_KEY;
|
|
436
|
+
if (!apiKey) {
|
|
437
|
+
throw new Error("Anthropic API Key missing. Please set ANTHROPIC_API_KEY in environment variables.");
|
|
438
|
+
}
|
|
439
|
+
const modelName = req.model.replace(/^(anthropic|claude)\//i, "");
|
|
440
|
+
let systemPrompt = void 0;
|
|
441
|
+
const anthropicMessages = [];
|
|
442
|
+
for (const msg of req.messages) {
|
|
443
|
+
if (msg.role === "system") {
|
|
444
|
+
systemPrompt = systemPrompt ? `${systemPrompt}
|
|
445
|
+
${msg.content}` : msg.content;
|
|
446
|
+
} else {
|
|
447
|
+
anthropicMessages.push({
|
|
448
|
+
role: msg.role === "assistant" ? "assistant" : "user",
|
|
449
|
+
content: msg.content
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
if (anthropicMessages.length === 0) {
|
|
454
|
+
anthropicMessages.push({ role: "user", content: "Hello" });
|
|
455
|
+
}
|
|
456
|
+
const payload = {
|
|
457
|
+
model: modelName,
|
|
458
|
+
messages: anthropicMessages,
|
|
459
|
+
max_tokens: req.max_tokens || req.max_completion_tokens || 1024,
|
|
460
|
+
stream: req.stream || false
|
|
461
|
+
};
|
|
462
|
+
if (systemPrompt) {
|
|
463
|
+
payload.system = systemPrompt;
|
|
464
|
+
}
|
|
465
|
+
if (req.temperature !== void 0) {
|
|
466
|
+
payload.temperature = req.temperature;
|
|
467
|
+
}
|
|
468
|
+
const response = await fetch("https://api.anthropic.com/v1/messages", {
|
|
469
|
+
method: "POST",
|
|
470
|
+
headers: {
|
|
471
|
+
"Content-Type": "application/json",
|
|
472
|
+
"x-api-key": apiKey,
|
|
473
|
+
"anthropic-version": "2023-06-01"
|
|
474
|
+
},
|
|
475
|
+
body: JSON.stringify(payload)
|
|
476
|
+
});
|
|
477
|
+
if (!response.ok) {
|
|
478
|
+
const errorText = await response.text();
|
|
479
|
+
throw new Error(`Anthropic API Error (${response.status}): ${errorText}`);
|
|
480
|
+
}
|
|
481
|
+
if (req.stream && response.body) {
|
|
482
|
+
return { stream: response.body };
|
|
483
|
+
}
|
|
484
|
+
const json = await response.json();
|
|
485
|
+
const textContent = ((_b = (_a2 = json.content) == null ? void 0 : _a2[0]) == null ? void 0 : _b.text) || "";
|
|
486
|
+
const openAIResponse = {
|
|
487
|
+
id: json.id || `chatcmpl-${Date.now()}`,
|
|
488
|
+
object: "chat.completion",
|
|
489
|
+
created: Math.floor(Date.now() / 1e3),
|
|
490
|
+
model: json.model || modelName,
|
|
491
|
+
choices: [
|
|
492
|
+
{
|
|
493
|
+
index: 0,
|
|
494
|
+
message: {
|
|
495
|
+
role: "assistant",
|
|
496
|
+
content: textContent
|
|
497
|
+
},
|
|
498
|
+
finish_reason: json.stop_reason === "end_turn" ? "stop" : json.stop_reason || "stop"
|
|
499
|
+
}
|
|
500
|
+
],
|
|
501
|
+
usage: json.usage ? {
|
|
502
|
+
prompt_tokens: json.usage.input_tokens,
|
|
503
|
+
completion_tokens: json.usage.output_tokens,
|
|
504
|
+
total_tokens: json.usage.input_tokens + json.usage.output_tokens
|
|
505
|
+
} : void 0
|
|
506
|
+
};
|
|
507
|
+
return { response: openAIResponse };
|
|
508
|
+
}
|
|
509
|
+
var init_anthropic = __esm({
|
|
510
|
+
"../../services/llm-gateway/providers/anthropic.ts"() {
|
|
511
|
+
"use strict";
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// ../../services/llm-gateway/providers/ollama.ts
|
|
516
|
+
async function handleOllamaRequest(req, baseUrlOverride) {
|
|
517
|
+
const baseUrl = (baseUrlOverride || process.env.OLLAMA_BASE_URL || "http://localhost:11434/v1").replace(/\/+$/, "");
|
|
518
|
+
const modelName = req.model.replace(/^ollama\//i, "");
|
|
519
|
+
const payload = __spreadProps(__spreadValues({}, req), {
|
|
520
|
+
model: modelName
|
|
521
|
+
});
|
|
522
|
+
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
523
|
+
method: "POST",
|
|
524
|
+
headers: {
|
|
525
|
+
"Content-Type": "application/json"
|
|
526
|
+
},
|
|
527
|
+
body: JSON.stringify(payload)
|
|
528
|
+
});
|
|
529
|
+
if (!response.ok) {
|
|
530
|
+
const errorText = await response.text();
|
|
531
|
+
throw new Error(`Ollama API Error (${response.status}): ${errorText}`);
|
|
532
|
+
}
|
|
533
|
+
if (req.stream && response.body) {
|
|
534
|
+
return { stream: response.body };
|
|
535
|
+
}
|
|
536
|
+
const json = await response.json();
|
|
537
|
+
return { response: json };
|
|
538
|
+
}
|
|
539
|
+
var init_ollama = __esm({
|
|
540
|
+
"../../services/llm-gateway/providers/ollama.ts"() {
|
|
541
|
+
"use strict";
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
// ../../services/llm-gateway/router.ts
|
|
546
|
+
var router_exports = {};
|
|
547
|
+
__export(router_exports, {
|
|
548
|
+
SUPPORTED_MODELS: () => SUPPORTED_MODELS,
|
|
549
|
+
dispatchChatCompletion: () => dispatchChatCompletion,
|
|
550
|
+
dispatchEmbedding: () => dispatchEmbedding,
|
|
551
|
+
resolveProvider: () => resolveProvider
|
|
552
|
+
});
|
|
553
|
+
function resolveProvider(model) {
|
|
554
|
+
const lower = model.toLowerCase();
|
|
555
|
+
if (lower.startsWith("huggingface/") || lower.startsWith("hf/")) {
|
|
556
|
+
return "huggingface";
|
|
557
|
+
}
|
|
558
|
+
if (lower.startsWith("ollama/")) {
|
|
559
|
+
return "ollama";
|
|
560
|
+
}
|
|
561
|
+
if (lower.startsWith("groq/") || lower.includes("llama") || lower.includes("qwen") || lower.includes("mixtral")) {
|
|
562
|
+
return "groq";
|
|
563
|
+
}
|
|
564
|
+
if (process.env.GROQ_API_KEY) return "groq";
|
|
565
|
+
if (process.env.OPENAI_API_KEY) return "openai";
|
|
566
|
+
if (process.env.GEMINI_API_KEY) return "gemini";
|
|
567
|
+
if (process.env.ANTHROPIC_API_KEY) return "anthropic";
|
|
568
|
+
if (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY) return "huggingface";
|
|
569
|
+
return "groq";
|
|
570
|
+
}
|
|
571
|
+
function cleanApiKeyOverride(apiKeyOverride) {
|
|
572
|
+
if (!apiKeyOverride) return void 0;
|
|
573
|
+
const key = apiKeyOverride.trim();
|
|
574
|
+
if (key === process.env.LITELLM_API_KEY || key === process.env.LITELLM_MASTER_KEY || key.startsWith("sk-retrivora") || !key.startsWith("gsk_") && !key.startsWith("AIza") && !key.startsWith("sk-ant-") && !key.startsWith("sk-proj-")) {
|
|
575
|
+
return void 0;
|
|
576
|
+
}
|
|
577
|
+
return key;
|
|
578
|
+
}
|
|
579
|
+
async function dispatchChatCompletion(req, apiKeyOverride) {
|
|
580
|
+
const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
|
|
581
|
+
const provider = resolveProvider(req.model);
|
|
582
|
+
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)}`);
|
|
583
|
+
try {
|
|
584
|
+
switch (provider) {
|
|
585
|
+
case "groq":
|
|
586
|
+
return await handleGroqRequest(req, effectiveKey);
|
|
587
|
+
case "openai":
|
|
588
|
+
return await handleOpenAIRequest(req, effectiveKey);
|
|
589
|
+
case "gemini":
|
|
590
|
+
return await handleGeminiRequest(req, effectiveKey);
|
|
591
|
+
case "anthropic":
|
|
592
|
+
return await handleAnthropicRequest(req, effectiveKey);
|
|
593
|
+
case "ollama":
|
|
594
|
+
return await handleOllamaRequest(req);
|
|
595
|
+
case "huggingface":
|
|
596
|
+
return await handleHuggingFaceChatRequest(req, effectiveKey);
|
|
597
|
+
default:
|
|
598
|
+
throw new Error(`Unsupported LLM provider for model: ${req.model}`);
|
|
599
|
+
}
|
|
600
|
+
} catch (error) {
|
|
601
|
+
console.error(`[LLM Gateway Router] Provider '${provider}' failed for model '${req.model}':`, {
|
|
602
|
+
message: error.message,
|
|
603
|
+
stack: error.stack
|
|
604
|
+
});
|
|
605
|
+
if (/rate[- ]?limit|429|exhausted/i.test(error.message)) {
|
|
606
|
+
const isGroqKey = process.env.GROQ_API_KEY || effectiveKey && effectiveKey.startsWith("gsk_");
|
|
607
|
+
const reqModelLower = req.model.toLowerCase();
|
|
608
|
+
if (isGroqKey && !reqModelLower.includes("llama-3.3-70b")) {
|
|
609
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to secondary Groq model (llama-3.3-70b-versatile)...`);
|
|
610
|
+
try {
|
|
611
|
+
return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: "llama-3.3-70b-versatile" }), effectiveKey);
|
|
612
|
+
} catch (fErr) {
|
|
613
|
+
console.error("[LLM Gateway] Fallback groq/llama-3.3-70b-versatile failed:", fErr.message);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
|
|
617
|
+
if (provider !== "gemini" && geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ."))) {
|
|
618
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Google Gemini (gemini-2.5-flash)...`);
|
|
619
|
+
try {
|
|
620
|
+
return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: "gemini-2.5-flash" }), effectiveKey);
|
|
621
|
+
} catch (fErr) {
|
|
622
|
+
console.error("[LLM Gateway] Fallback gemini-2.5-flash failed:", fErr.message);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
if (provider !== "huggingface" && (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY)) {
|
|
626
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Hugging Face (Qwen/Qwen2.5-Coder-32B-Instruct)...`);
|
|
627
|
+
try {
|
|
628
|
+
return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: "Qwen/Qwen2.5-Coder-32B-Instruct" }), effectiveKey);
|
|
629
|
+
} catch (fErr) {
|
|
630
|
+
console.error("[LLM Gateway] Fallback HuggingFace Qwen failed:", fErr.message);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (provider !== "openai" && process.env.OPENAI_API_KEY) {
|
|
634
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to OpenAI (gpt-4o-mini)...`);
|
|
635
|
+
try {
|
|
636
|
+
return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: "gpt-4o-mini" }), effectiveKey);
|
|
637
|
+
} catch (e) {
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to local Ollama (llama3.2)...`);
|
|
641
|
+
return handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: "llama3.2" }));
|
|
642
|
+
}
|
|
643
|
+
throw error;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
async function dispatchEmbedding(req, apiKeyOverride) {
|
|
647
|
+
const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
|
|
648
|
+
if (req.model.startsWith("hf/") || req.model.startsWith("huggingface/") || req.model.includes("bge-")) {
|
|
649
|
+
try {
|
|
650
|
+
return await handleHuggingFaceEmbedding(req, effectiveKey);
|
|
651
|
+
} catch (err) {
|
|
652
|
+
console.warn("[LLM Gateway] HuggingFace explicit model embedding failed, falling back to default gateway chain:", err);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
|
|
656
|
+
const isGeminiKeyValid = Boolean(geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ.")));
|
|
657
|
+
if (isGeminiKeyValid) {
|
|
658
|
+
try {
|
|
659
|
+
return await handleGeminiEmbedding(req, effectiveKey);
|
|
660
|
+
} catch (err) {
|
|
661
|
+
console.warn("[LLM Gateway] Gemini embedding failed:", err);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (process.env.OPENAI_API_KEY) {
|
|
665
|
+
try {
|
|
666
|
+
return await handleOpenAIEmbedding(req, effectiveKey);
|
|
667
|
+
} catch (err) {
|
|
668
|
+
console.warn("[LLM Gateway] OpenAI embedding failed:", err);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
if (process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN) {
|
|
672
|
+
try {
|
|
673
|
+
return await handleHuggingFaceEmbedding(req, effectiveKey);
|
|
674
|
+
} catch (err) {
|
|
675
|
+
console.warn("[LLM Gateway] HuggingFace fallback embedding failed:", err);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return handleGeminiEmbedding(req, effectiveKey);
|
|
679
|
+
}
|
|
680
|
+
var SUPPORTED_MODELS;
|
|
681
|
+
var init_router = __esm({
|
|
682
|
+
"../../services/llm-gateway/router.ts"() {
|
|
683
|
+
"use strict";
|
|
684
|
+
init_groq();
|
|
685
|
+
init_openai();
|
|
686
|
+
init_gemini();
|
|
687
|
+
init_huggingface();
|
|
688
|
+
init_anthropic();
|
|
689
|
+
init_ollama();
|
|
690
|
+
SUPPORTED_MODELS = [
|
|
691
|
+
{ id: "groq/llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
|
|
692
|
+
{ id: "llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
|
|
693
|
+
{ id: "groq/llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
|
|
694
|
+
{ id: "llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
|
|
695
|
+
{ id: "gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
|
|
696
|
+
{ id: "openai/gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
|
|
697
|
+
{ id: "gpt-4o", object: "model", created: 17e8, owned_by: "openai" },
|
|
698
|
+
{ id: "gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
|
|
699
|
+
{ id: "google/gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
|
|
700
|
+
{ id: "claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
|
|
701
|
+
{ id: "anthropic/claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
|
|
702
|
+
{ id: "text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
|
|
703
|
+
{ id: "google/text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
|
|
704
|
+
{ id: "BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
|
|
705
|
+
{ id: "huggingface/BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
|
|
706
|
+
{ id: "groq/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
|
|
707
|
+
{ id: "qwen/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
|
|
708
|
+
{ id: "qwen/qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
|
|
709
|
+
{ id: "qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
|
|
710
|
+
{ id: "ollama/llama3.2", object: "model", created: 17e8, owned_by: "ollama" }
|
|
711
|
+
];
|
|
712
|
+
if (typeof globalThis !== "undefined") {
|
|
713
|
+
const _g2 = globalThis;
|
|
714
|
+
_g2.__retrivoraDispatchChat = dispatchChatCompletion;
|
|
715
|
+
_g2.__retrivoraDispatchEmbedding = dispatchEmbedding;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
|
|
109
720
|
// src/providers/vectordb/BaseVectorProvider.ts
|
|
110
721
|
var BaseVectorProvider;
|
|
111
722
|
var init_BaseVectorProvider = __esm({
|
|
@@ -2790,12 +3401,13 @@ var OpenAIProvider = class {
|
|
|
2790
3401
|
role: "system",
|
|
2791
3402
|
content: buildSystemContent(basePrompt, context)
|
|
2792
3403
|
};
|
|
3404
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
3405
|
+
role: m.role || "user",
|
|
3406
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
3407
|
+
}));
|
|
2793
3408
|
const formattedMessages = [
|
|
2794
3409
|
systemMessage,
|
|
2795
|
-
...
|
|
2796
|
-
role: m.role,
|
|
2797
|
-
content: m.content
|
|
2798
|
-
}))
|
|
3410
|
+
...safeMessages
|
|
2799
3411
|
];
|
|
2800
3412
|
const completion = await this.client.chat.completions.create({
|
|
2801
3413
|
model: this.llmConfig.model,
|
|
@@ -2814,12 +3426,13 @@ var OpenAIProvider = class {
|
|
|
2814
3426
|
role: "system",
|
|
2815
3427
|
content: buildSystemContent(basePrompt, context)
|
|
2816
3428
|
};
|
|
3429
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
3430
|
+
role: m.role || "user",
|
|
3431
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
3432
|
+
}));
|
|
2817
3433
|
const formattedMessages = [
|
|
2818
3434
|
systemMessage,
|
|
2819
|
-
...
|
|
2820
|
-
role: m.role,
|
|
2821
|
-
content: m.content
|
|
2822
|
-
}))
|
|
3435
|
+
...safeStreamMessages
|
|
2823
3436
|
];
|
|
2824
3437
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
2825
3438
|
model: this.llmConfig.model,
|
|
@@ -3350,9 +3963,9 @@ var GeminiProvider = class {
|
|
|
3350
3963
|
* - Messages must strictly alternate between `user` and `model`.
|
|
3351
3964
|
*/
|
|
3352
3965
|
buildGeminiContents(messages) {
|
|
3353
|
-
return messages.filter((m) => m.role !== "system").map((m) => ({
|
|
3966
|
+
return (messages || []).filter((m) => Boolean(m && typeof m === "object" && m.role !== "system")).map((m) => ({
|
|
3354
3967
|
role: m.role === "assistant" ? "model" : "user",
|
|
3355
|
-
parts: [{ text: m.content }]
|
|
3968
|
+
parts: [{ text: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : "" }]
|
|
3356
3969
|
}));
|
|
3357
3970
|
}
|
|
3358
3971
|
// -------------------------------------------------------------------------
|
|
@@ -3555,12 +4168,13 @@ var GroqProvider = class {
|
|
|
3555
4168
|
role: "system",
|
|
3556
4169
|
content: buildSystemContent(basePrompt, context)
|
|
3557
4170
|
};
|
|
4171
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4172
|
+
role: m.role || "user",
|
|
4173
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4174
|
+
}));
|
|
3558
4175
|
const formattedMessages = [
|
|
3559
4176
|
systemMessage,
|
|
3560
|
-
...
|
|
3561
|
-
role: m.role,
|
|
3562
|
-
content: m.content
|
|
3563
|
-
}))
|
|
4177
|
+
...safeMessages
|
|
3564
4178
|
];
|
|
3565
4179
|
const completion = await this.client.chat.completions.create({
|
|
3566
4180
|
model: this.llmConfig.model,
|
|
@@ -3579,12 +4193,13 @@ var GroqProvider = class {
|
|
|
3579
4193
|
role: "system",
|
|
3580
4194
|
content: buildSystemContent(basePrompt, context)
|
|
3581
4195
|
};
|
|
4196
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4197
|
+
role: m.role || "user",
|
|
4198
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4199
|
+
}));
|
|
3582
4200
|
const formattedMessages = [
|
|
3583
4201
|
systemMessage,
|
|
3584
|
-
...
|
|
3585
|
-
role: m.role,
|
|
3586
|
-
content: m.content
|
|
3587
|
-
}))
|
|
4202
|
+
...safeStreamMessages
|
|
3588
4203
|
];
|
|
3589
4204
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
3590
4205
|
model: this.llmConfig.model,
|
|
@@ -3713,12 +4328,13 @@ var QwenProvider = class {
|
|
|
3713
4328
|
role: "system",
|
|
3714
4329
|
content: buildSystemContent(basePrompt, context)
|
|
3715
4330
|
};
|
|
4331
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4332
|
+
role: m.role || "user",
|
|
4333
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4334
|
+
}));
|
|
3716
4335
|
const formattedMessages = [
|
|
3717
4336
|
systemMessage,
|
|
3718
|
-
...
|
|
3719
|
-
role: m.role,
|
|
3720
|
-
content: m.content
|
|
3721
|
-
}))
|
|
4337
|
+
...safeMessages
|
|
3722
4338
|
];
|
|
3723
4339
|
const completion = await this.client.chat.completions.create({
|
|
3724
4340
|
model: this.llmConfig.model,
|
|
@@ -3737,12 +4353,13 @@ var QwenProvider = class {
|
|
|
3737
4353
|
role: "system",
|
|
3738
4354
|
content: buildSystemContent(basePrompt, context)
|
|
3739
4355
|
};
|
|
4356
|
+
const safeStreamMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4357
|
+
role: m.role || "user",
|
|
4358
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4359
|
+
}));
|
|
3740
4360
|
const formattedMessages = [
|
|
3741
4361
|
systemMessage,
|
|
3742
|
-
...
|
|
3743
|
-
role: m.role,
|
|
3744
|
-
content: m.content
|
|
3745
|
-
}))
|
|
4362
|
+
...safeStreamMessages
|
|
3746
4363
|
];
|
|
3747
4364
|
const stream = yield new __await(this.client.chat.completions.create({
|
|
3748
4365
|
model: this.llmConfig.model,
|
|
@@ -3841,6 +4458,17 @@ var LLM_PROFILES = {
|
|
|
3841
4458
|
};
|
|
3842
4459
|
|
|
3843
4460
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4461
|
+
function extractContent(obj) {
|
|
4462
|
+
var _a2, _b, _c;
|
|
4463
|
+
if (!obj || typeof obj !== "object") return void 0;
|
|
4464
|
+
const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
|
|
4465
|
+
if (!choice) return void 0;
|
|
4466
|
+
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4467
|
+
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
4468
|
+
if (typeof choice.text === "string") return choice.text;
|
|
4469
|
+
if (typeof choice.content === "string") return choice.content;
|
|
4470
|
+
return void 0;
|
|
4471
|
+
}
|
|
3844
4472
|
var UniversalLLMAdapter = class {
|
|
3845
4473
|
constructor(config) {
|
|
3846
4474
|
var _a2, _b, _c, _d, _e, _f, _g2, _h;
|
|
@@ -3872,14 +4500,18 @@ var UniversalLLMAdapter = class {
|
|
|
3872
4500
|
});
|
|
3873
4501
|
}
|
|
3874
4502
|
async chat(messages, context) {
|
|
3875
|
-
var _a2, _b, _c
|
|
4503
|
+
var _a2, _b, _c;
|
|
3876
4504
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
4505
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4506
|
+
role: m.role || "user",
|
|
4507
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4508
|
+
}));
|
|
3877
4509
|
const formattedMessages = [
|
|
3878
4510
|
{ role: "system", content: `${this.systemPrompt}
|
|
3879
4511
|
|
|
3880
4512
|
Context:
|
|
3881
4513
|
${context != null ? context : "None"}` },
|
|
3882
|
-
...
|
|
4514
|
+
...safeMessages
|
|
3883
4515
|
];
|
|
3884
4516
|
let payload;
|
|
3885
4517
|
if (this.opts.chatPayloadTemplate) {
|
|
@@ -3900,25 +4532,41 @@ ${context != null ? context : "None"}` },
|
|
|
3900
4532
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3901
4533
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3902
4534
|
const _g2 = globalThis;
|
|
3903
|
-
|
|
4535
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4536
|
+
if (typeof dispatch !== "function") {
|
|
3904
4537
|
try {
|
|
3905
|
-
const
|
|
4538
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4539
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4540
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4541
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4542
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4543
|
+
}
|
|
4544
|
+
} catch (e) {
|
|
4545
|
+
}
|
|
4546
|
+
}
|
|
4547
|
+
if (typeof dispatch === "function") {
|
|
4548
|
+
try {
|
|
4549
|
+
const res = await dispatch({
|
|
3906
4550
|
model: this.model,
|
|
3907
4551
|
messages: formattedMessages,
|
|
3908
4552
|
max_tokens: this.maxTokens,
|
|
3909
4553
|
temperature: this.temperature
|
|
3910
4554
|
}, this.apiKey);
|
|
3911
|
-
|
|
3912
|
-
|
|
4555
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4556
|
+
if (content !== void 0) {
|
|
4557
|
+
return content;
|
|
3913
4558
|
}
|
|
4559
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
|
|
3914
4560
|
} catch (dispatchErr) {
|
|
3915
4561
|
throw dispatchErr;
|
|
3916
4562
|
}
|
|
4563
|
+
} else {
|
|
4564
|
+
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.`);
|
|
3917
4565
|
}
|
|
3918
4566
|
}
|
|
3919
4567
|
const { data } = await this.http.post(path2, payload);
|
|
3920
|
-
const extractPath = (
|
|
3921
|
-
const result = resolvePath(data, extractPath);
|
|
4568
|
+
const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
|
|
4569
|
+
const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
|
|
3922
4570
|
if (result === void 0) {
|
|
3923
4571
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
3924
4572
|
}
|
|
@@ -3931,16 +4579,20 @@ ${context != null ? context : "None"}` },
|
|
|
3931
4579
|
*/
|
|
3932
4580
|
chatStream(messages, context) {
|
|
3933
4581
|
return __asyncGenerator(this, null, function* () {
|
|
3934
|
-
var _a2, _b, _c, _d, _e
|
|
4582
|
+
var _a2, _b, _c, _d, _e;
|
|
3935
4583
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3936
4584
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
3937
4585
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4586
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4587
|
+
role: m.role || "user",
|
|
4588
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4589
|
+
}));
|
|
3938
4590
|
const formattedMessages = [
|
|
3939
4591
|
{ role: "system", content: `${this.systemPrompt}
|
|
3940
4592
|
|
|
3941
4593
|
Context:
|
|
3942
4594
|
${context != null ? context : "None"}` },
|
|
3943
|
-
...
|
|
4595
|
+
...safeMessages
|
|
3944
4596
|
];
|
|
3945
4597
|
let payload;
|
|
3946
4598
|
if (this.opts.chatPayloadTemplate) {
|
|
@@ -3965,10 +4617,22 @@ ${context != null ? context : "None"}` },
|
|
|
3965
4617
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3966
4618
|
let streamBody = null;
|
|
3967
4619
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3968
|
-
const
|
|
3969
|
-
|
|
4620
|
+
const _g2 = globalThis;
|
|
4621
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4622
|
+
if (typeof dispatch !== "function") {
|
|
3970
4623
|
try {
|
|
3971
|
-
const
|
|
4624
|
+
const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
|
|
4625
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4626
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4627
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4628
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4629
|
+
}
|
|
4630
|
+
} catch (e) {
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
if (typeof dispatch === "function") {
|
|
4634
|
+
try {
|
|
4635
|
+
const res = yield new __await(dispatch({
|
|
3972
4636
|
model: this.model,
|
|
3973
4637
|
messages: formattedMessages,
|
|
3974
4638
|
max_tokens: this.maxTokens,
|
|
@@ -3977,13 +4641,19 @@ ${context != null ? context : "None"}` },
|
|
|
3977
4641
|
}, this.apiKey));
|
|
3978
4642
|
if (res == null ? void 0 : res.stream) {
|
|
3979
4643
|
streamBody = res.stream;
|
|
3980
|
-
} else
|
|
3981
|
-
|
|
3982
|
-
|
|
4644
|
+
} else {
|
|
4645
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4646
|
+
if (content !== void 0) {
|
|
4647
|
+
yield content;
|
|
4648
|
+
return;
|
|
4649
|
+
}
|
|
4650
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
|
|
3983
4651
|
}
|
|
3984
4652
|
} catch (dispatchErr) {
|
|
3985
4653
|
throw dispatchErr;
|
|
3986
4654
|
}
|
|
4655
|
+
} else {
|
|
4656
|
+
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.`);
|
|
3987
4657
|
}
|
|
3988
4658
|
}
|
|
3989
4659
|
if (!streamBody) {
|
|
@@ -4010,14 +4680,14 @@ ${context != null ? context : "None"}` },
|
|
|
4010
4680
|
if (done) break;
|
|
4011
4681
|
buffer += decoder.decode(value, { stream: true });
|
|
4012
4682
|
const lines = buffer.split("\n");
|
|
4013
|
-
buffer = (
|
|
4683
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4014
4684
|
for (const line of lines) {
|
|
4015
4685
|
const trimmed = line.trim();
|
|
4016
4686
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4017
4687
|
if (!trimmed.startsWith("data:")) continue;
|
|
4018
4688
|
try {
|
|
4019
4689
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4020
|
-
const text = resolvePath(json, extractPath);
|
|
4690
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4021
4691
|
if (text && typeof text === "string") yield text;
|
|
4022
4692
|
} catch (e) {
|
|
4023
4693
|
}
|
|
@@ -4027,7 +4697,7 @@ ${context != null ? context : "None"}` },
|
|
|
4027
4697
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4028
4698
|
try {
|
|
4029
4699
|
const json = JSON.parse(jsonStr);
|
|
4030
|
-
const text = resolvePath(json, extractPath);
|
|
4700
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4031
4701
|
if (text && typeof text === "string") yield text;
|
|
4032
4702
|
} catch (e) {
|
|
4033
4703
|
}
|
|
@@ -4055,18 +4725,33 @@ ${context != null ? context : "None"}` },
|
|
|
4055
4725
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4056
4726
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4057
4727
|
const _g2 = globalThis;
|
|
4058
|
-
|
|
4728
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4729
|
+
if (typeof dispatch !== "function") {
|
|
4059
4730
|
try {
|
|
4060
|
-
const
|
|
4731
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4732
|
+
if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
|
|
4733
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4734
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4735
|
+
dispatch = gateway.dispatchEmbedding;
|
|
4736
|
+
}
|
|
4737
|
+
} catch (e) {
|
|
4738
|
+
}
|
|
4739
|
+
}
|
|
4740
|
+
if (typeof dispatch === "function") {
|
|
4741
|
+
try {
|
|
4742
|
+
const res = await dispatch({
|
|
4061
4743
|
model: this.model,
|
|
4062
4744
|
input: text
|
|
4063
4745
|
}, this.apiKey);
|
|
4064
4746
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4065
4747
|
return res.data[0].embedding;
|
|
4066
4748
|
}
|
|
4749
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4067
4750
|
} catch (dispatchErr) {
|
|
4068
4751
|
throw dispatchErr;
|
|
4069
4752
|
}
|
|
4753
|
+
} else {
|
|
4754
|
+
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.`);
|
|
4070
4755
|
}
|
|
4071
4756
|
}
|
|
4072
4757
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -6045,8 +6730,8 @@ var IntentClassifier = class {
|
|
|
6045
6730
|
}
|
|
6046
6731
|
// ─── Intent Heuristic Checkers ─────────────────────────────────────────────
|
|
6047
6732
|
static isInformationLookup(query) {
|
|
6048
|
-
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)) {
|
|
6049
|
-
if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top selling|best)\b/i.test(query)) {
|
|
6733
|
+
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)) {
|
|
6734
|
+
if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top 10|top selling|best|chart|graph|plot|breakdown|analytics)\b/i.test(query)) {
|
|
6050
6735
|
return true;
|
|
6051
6736
|
}
|
|
6052
6737
|
}
|
|
@@ -6083,7 +6768,7 @@ var Rule1SpecificInfoRule = class {
|
|
|
6083
6768
|
}
|
|
6084
6769
|
evaluate(context, intent) {
|
|
6085
6770
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6086
|
-
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);
|
|
6771
|
+
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);
|
|
6087
6772
|
const isNonVisual = !/\b(compare|versus|vs\.?|trend|monthly|revenue|best|top 10|chart|table|list|grid)\b/i.test(q);
|
|
6088
6773
|
if (isFactQuery && isNonVisual) {
|
|
6089
6774
|
return {
|
|
@@ -6914,7 +7599,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
6914
7599
|
}
|
|
6915
7600
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
6916
7601
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
6917
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null)
|
|
7602
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
6918
7603
|
return {
|
|
6919
7604
|
type: "product_carousel",
|
|
6920
7605
|
title: "Recommended Products",
|
|
@@ -7294,7 +7979,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7294
7979
|
return fieldCount.size > 2;
|
|
7295
7980
|
}
|
|
7296
7981
|
static profileData(data) {
|
|
7297
|
-
const records = data.map((item) => {
|
|
7982
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
7983
|
+
var _a2, _b;
|
|
7298
7984
|
const fields2 = {};
|
|
7299
7985
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7300
7986
|
const primitive = this.toPrimitive(value);
|
|
@@ -7303,8 +7989,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7303
7989
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7304
7990
|
return {
|
|
7305
7991
|
id: item.id,
|
|
7306
|
-
content: item.content,
|
|
7307
|
-
score: item.score,
|
|
7992
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
7993
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7308
7994
|
fields: fields2,
|
|
7309
7995
|
source: item
|
|
7310
7996
|
};
|
|
@@ -7361,6 +8047,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7361
8047
|
}
|
|
7362
8048
|
static chooseAutomaticVisualization(data, profile, query) {
|
|
7363
8049
|
if (profile.records.length === 0) return null;
|
|
8050
|
+
const q = query.toLowerCase().trim();
|
|
8051
|
+
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);
|
|
8052
|
+
if (!isExplicitVisualOrAnalytic) {
|
|
8053
|
+
return null;
|
|
8054
|
+
}
|
|
7364
8055
|
if (profile.dateFields.length > 0 && profile.numericFields.length > 0) {
|
|
7365
8056
|
return this.transformToLineChart(profile);
|
|
7366
8057
|
}
|
|
@@ -7476,6 +8167,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7476
8167
|
return Array.from(categories);
|
|
7477
8168
|
}
|
|
7478
8169
|
static getProductCategory(item) {
|
|
8170
|
+
if (!item) return null;
|
|
7479
8171
|
const meta = item.metadata || {};
|
|
7480
8172
|
const metadataCategory = resolveMetadataValue(meta, "category");
|
|
7481
8173
|
if (this.isUsableCategory(metadataCategory)) return String(metadataCategory).trim();
|
|
@@ -7592,6 +8284,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7592
8284
|
if (!fields.has(normalized)) fields.set(normalized, clean);
|
|
7593
8285
|
};
|
|
7594
8286
|
data.forEach((item) => {
|
|
8287
|
+
if (!item) return;
|
|
7595
8288
|
Object.keys(item.metadata || {}).forEach(addField);
|
|
7596
8289
|
for (const match of (item.content || "").matchAll(/(?:^|\n)\s*([A-Za-z][A-Za-z0-9_ /-]{1,50})\s*[:\-–]\s*([^\n]+)/g)) {
|
|
7597
8290
|
addField(match[1]);
|
|
@@ -7708,6 +8401,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7708
8401
|
return true;
|
|
7709
8402
|
}
|
|
7710
8403
|
static extractStockQuantity(item) {
|
|
8404
|
+
if (!item) return null;
|
|
7711
8405
|
const meta = item.metadata || {};
|
|
7712
8406
|
const stockValue = resolveMetadataValue(meta, "stock");
|
|
7713
8407
|
const numericStock = this.toFiniteNumber(stockValue);
|
|
@@ -8407,7 +9101,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8407
9101
|
*/
|
|
8408
9102
|
askStreamInternal(_0) {
|
|
8409
9103
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8410
|
-
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
|
|
9104
|
+
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;
|
|
8411
9105
|
yield new __await(this.initialize());
|
|
8412
9106
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8413
9107
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8450,8 +9144,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8450
9144
|
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;
|
|
8451
9145
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8452
9146
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8453
|
-
const wantsExhaustiveList =
|
|
8454
|
-
const retrievalLimit =
|
|
9147
|
+
const wantsExhaustiveList = true;
|
|
9148
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
8455
9149
|
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"));
|
|
8456
9150
|
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
8457
9151
|
rawCount: rawSources.length,
|
|
@@ -8475,40 +9169,29 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8475
9169
|
var _a3;
|
|
8476
9170
|
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
8477
9171
|
});
|
|
8478
|
-
const rerankLimit =
|
|
9172
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8479
9173
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8480
9174
|
if (!hasNumericPredicates && useReranking) {
|
|
8481
9175
|
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8482
|
-
} else if (!wantsExhaustiveList) {
|
|
8483
|
-
fullSources = fullSources.slice(0, topK);
|
|
8484
9176
|
}
|
|
8485
9177
|
const rerankMs = performance.now() - rerankStart;
|
|
8486
|
-
|
|
9178
|
+
const totalCount = fullSources.length;
|
|
9179
|
+
const promptSources = fullSources.slice(0, 15);
|
|
9180
|
+
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]
|
|
9181
|
+
|
|
9182
|
+
` + promptSources.map((m, i) => {
|
|
8487
9183
|
var _a3;
|
|
8488
9184
|
return `[Source ${i + 1}]
|
|
8489
9185
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8490
9186
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8491
|
-
let displayCount = 15;
|
|
8492
|
-
if (hasMetadataFilter) {
|
|
8493
|
-
displayCount = fullSources.length;
|
|
8494
|
-
} else {
|
|
8495
|
-
const baseThreshold = Math.max(scoreThreshold, 0.4);
|
|
8496
|
-
const highlyRelevant = fullSources.filter((m) => {
|
|
8497
|
-
var _a3;
|
|
8498
|
-
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= baseThreshold;
|
|
8499
|
-
});
|
|
8500
|
-
displayCount = Math.max(highlyRelevant.length, topK);
|
|
8501
|
-
if (displayCount > 15) {
|
|
8502
|
-
displayCount = 15;
|
|
8503
|
-
}
|
|
8504
|
-
}
|
|
8505
9187
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8506
9188
|
var _a3, _b2;
|
|
8507
9189
|
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8508
|
-
})
|
|
9190
|
+
});
|
|
8509
9191
|
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
8510
9192
|
count: sources.length,
|
|
8511
|
-
|
|
9193
|
+
totalRawCount: rawSources.length,
|
|
9194
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
8512
9195
|
var _a3;
|
|
8513
9196
|
return {
|
|
8514
9197
|
rank: idx + 1,
|
|
@@ -8708,7 +9391,7 @@ ${context}`;
|
|
|
8708
9391
|
}
|
|
8709
9392
|
yield fullReply;
|
|
8710
9393
|
}
|
|
8711
|
-
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true
|
|
9394
|
+
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
|
|
8712
9395
|
if (runHallucination) {
|
|
8713
9396
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8714
9397
|
}
|
|
@@ -8717,7 +9400,7 @@ ${context}`;
|
|
|
8717
9400
|
const latency = {
|
|
8718
9401
|
embedMs: Math.round(embedMs),
|
|
8719
9402
|
retrieveMs: Math.round(retrieveMs),
|
|
8720
|
-
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((
|
|
9403
|
+
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
|
|
8721
9404
|
generateMs: Math.round(generateMs),
|
|
8722
9405
|
totalMs: Math.round(totalMs)
|
|
8723
9406
|
};
|
|
@@ -8730,7 +9413,7 @@ ${context}`;
|
|
|
8730
9413
|
totalTokens: promptTokens + completionTokens,
|
|
8731
9414
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8732
9415
|
};
|
|
8733
|
-
const awaitHallucination = ((
|
|
9416
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8734
9417
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8735
9418
|
uiTransformationPromise,
|
|
8736
9419
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8759,10 +9442,10 @@ ${context}`;
|
|
|
8759
9442
|
hallucinationReason: hScore.reason
|
|
8760
9443
|
} : {});
|
|
8761
9444
|
const trace = buildTrace(hallucinationResult);
|
|
8762
|
-
const isTelemetryActive = (
|
|
9445
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8763
9446
|
if (isTelemetryActive) {
|
|
8764
9447
|
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";
|
|
8765
|
-
const telemetryUrl = ((
|
|
9448
|
+
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
8766
9449
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8767
9450
|
(async () => {
|
|
8768
9451
|
try {
|
|
@@ -8821,9 +9504,8 @@ ${context}`;
|
|
|
8821
9504
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8822
9505
|
);
|
|
8823
9506
|
}
|
|
8824
|
-
const
|
|
8825
|
-
|
|
8826
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9507
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9508
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8827
9509
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8828
9510
|
}
|
|
8829
9511
|
try {
|
|
@@ -8980,7 +9662,10 @@ ${context}`;
|
|
|
8980
9662
|
Focus on extracting the core intent and entities. Do not answer the question, just rewrite it.
|
|
8981
9663
|
|
|
8982
9664
|
History:
|
|
8983
|
-
${history.map((m) =>
|
|
9665
|
+
${(history || []).map((m) => {
|
|
9666
|
+
var _a2;
|
|
9667
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a2 = m == null ? void 0 : m.content) != null ? _a2 : ""}`;
|
|
9668
|
+
}).join("\n")}
|
|
8984
9669
|
|
|
8985
9670
|
New Question: ${question}
|
|
8986
9671
|
|
|
@@ -9004,8 +9689,11 @@ Optimized Search Query:`;
|
|
|
9004
9689
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
9005
9690
|
try {
|
|
9006
9691
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9007
|
-
if (sources.length === 0) return [];
|
|
9008
|
-
const context = sources.map((s) =>
|
|
9692
|
+
if (!sources || sources.length === 0) return [];
|
|
9693
|
+
const context = sources.map((s) => {
|
|
9694
|
+
var _a2;
|
|
9695
|
+
return (_a2 = s == null ? void 0 : s.content) != null ? _a2 : "";
|
|
9696
|
+
}).join("\n\n---\n\n");
|
|
9009
9697
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9010
9698
|
Focus on questions that can be answered by the context.
|
|
9011
9699
|
Keep each question under 10 words and make them very specific to the content.
|