@retrivora-ai/rag-engine 2.0.7 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/handlers/index.js +776 -88
- package/dist/handlers/index.mjs +776 -88
- package/dist/index.js +24 -16
- package/dist/index.mjs +24 -16
- package/dist/server.js +776 -88
- package/dist/server.mjs +776 -88
- package/package.json +1 -1
- package/src/components/ChatWindow.tsx +22 -22
- package/src/core/Pipeline.ts +22 -40
- package/src/llm/providers/GeminiProvider.ts +4 -4
- package/src/llm/providers/GroqProvider.ts +16 -8
- package/src/llm/providers/OpenAIProvider.ts +16 -8
- package/src/llm/providers/QwenProvider.ts +16 -8
- package/src/llm/providers/UniversalLLMAdapter.ts +90 -18
- package/src/rendering/IntentClassifier.ts +3 -3
- package/src/rendering/rules/Rule1SpecificInfoRule.ts +1 -1
- package/src/utils/ProductExtractor.ts +4 -3
- package/src/utils/UITransformer.ts +16 -5
package/dist/server.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,
|
|
@@ -3880,6 +4497,17 @@ var VECTOR_PROFILES = {
|
|
|
3880
4497
|
};
|
|
3881
4498
|
|
|
3882
4499
|
// src/llm/providers/UniversalLLMAdapter.ts
|
|
4500
|
+
function extractContent(obj) {
|
|
4501
|
+
var _a2, _b, _c;
|
|
4502
|
+
if (!obj || typeof obj !== "object") return void 0;
|
|
4503
|
+
const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
|
|
4504
|
+
if (!choice) return void 0;
|
|
4505
|
+
if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
|
|
4506
|
+
if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
|
|
4507
|
+
if (typeof choice.text === "string") return choice.text;
|
|
4508
|
+
if (typeof choice.content === "string") return choice.content;
|
|
4509
|
+
return void 0;
|
|
4510
|
+
}
|
|
3883
4511
|
var UniversalLLMAdapter = class {
|
|
3884
4512
|
constructor(config) {
|
|
3885
4513
|
var _a2, _b, _c, _d, _e, _f, _g2, _h;
|
|
@@ -3911,14 +4539,18 @@ var UniversalLLMAdapter = class {
|
|
|
3911
4539
|
});
|
|
3912
4540
|
}
|
|
3913
4541
|
async chat(messages, context) {
|
|
3914
|
-
var _a2, _b, _c
|
|
4542
|
+
var _a2, _b, _c;
|
|
3915
4543
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
4544
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4545
|
+
role: m.role || "user",
|
|
4546
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4547
|
+
}));
|
|
3916
4548
|
const formattedMessages = [
|
|
3917
4549
|
{ role: "system", content: `${this.systemPrompt}
|
|
3918
4550
|
|
|
3919
4551
|
Context:
|
|
3920
4552
|
${context != null ? context : "None"}` },
|
|
3921
|
-
...
|
|
4553
|
+
...safeMessages
|
|
3922
4554
|
];
|
|
3923
4555
|
let payload;
|
|
3924
4556
|
if (this.opts.chatPayloadTemplate) {
|
|
@@ -3939,25 +4571,41 @@ ${context != null ? context : "None"}` },
|
|
|
3939
4571
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
3940
4572
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
3941
4573
|
const _g2 = globalThis;
|
|
3942
|
-
|
|
4574
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4575
|
+
if (typeof dispatch !== "function") {
|
|
3943
4576
|
try {
|
|
3944
|
-
const
|
|
4577
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4578
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4579
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4580
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4581
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4582
|
+
}
|
|
4583
|
+
} catch (e) {
|
|
4584
|
+
}
|
|
4585
|
+
}
|
|
4586
|
+
if (typeof dispatch === "function") {
|
|
4587
|
+
try {
|
|
4588
|
+
const res = await dispatch({
|
|
3945
4589
|
model: this.model,
|
|
3946
4590
|
messages: formattedMessages,
|
|
3947
4591
|
max_tokens: this.maxTokens,
|
|
3948
4592
|
temperature: this.temperature
|
|
3949
4593
|
}, this.apiKey);
|
|
3950
|
-
|
|
3951
|
-
|
|
4594
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4595
|
+
if (content !== void 0) {
|
|
4596
|
+
return content;
|
|
3952
4597
|
}
|
|
4598
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
|
|
3953
4599
|
} catch (dispatchErr) {
|
|
3954
4600
|
throw dispatchErr;
|
|
3955
4601
|
}
|
|
4602
|
+
} else {
|
|
4603
|
+
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.`);
|
|
3956
4604
|
}
|
|
3957
4605
|
}
|
|
3958
4606
|
const { data } = await this.http.post(path2, payload);
|
|
3959
|
-
const extractPath = (
|
|
3960
|
-
const result = resolvePath(data, extractPath);
|
|
4607
|
+
const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
|
|
4608
|
+
const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
|
|
3961
4609
|
if (result === void 0) {
|
|
3962
4610
|
throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
|
|
3963
4611
|
}
|
|
@@ -3970,16 +4618,20 @@ ${context != null ? context : "None"}` },
|
|
|
3970
4618
|
*/
|
|
3971
4619
|
chatStream(messages, context) {
|
|
3972
4620
|
return __asyncGenerator(this, null, function* () {
|
|
3973
|
-
var _a2, _b, _c, _d, _e
|
|
4621
|
+
var _a2, _b, _c, _d, _e;
|
|
3974
4622
|
const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
|
|
3975
4623
|
const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
|
|
3976
4624
|
const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
|
|
4625
|
+
const safeMessages = (Array.isArray(messages) ? messages : []).filter((m) => Boolean(m && typeof m === "object")).map((m) => ({
|
|
4626
|
+
role: m.role || "user",
|
|
4627
|
+
content: typeof m.content === "string" ? m.content : m.content != null ? String(m.content) : ""
|
|
4628
|
+
}));
|
|
3977
4629
|
const formattedMessages = [
|
|
3978
4630
|
{ role: "system", content: `${this.systemPrompt}
|
|
3979
4631
|
|
|
3980
4632
|
Context:
|
|
3981
4633
|
${context != null ? context : "None"}` },
|
|
3982
|
-
...
|
|
4634
|
+
...safeMessages
|
|
3983
4635
|
];
|
|
3984
4636
|
let payload;
|
|
3985
4637
|
if (this.opts.chatPayloadTemplate) {
|
|
@@ -4004,10 +4656,22 @@ ${context != null ? context : "None"}` },
|
|
|
4004
4656
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4005
4657
|
let streamBody = null;
|
|
4006
4658
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4007
|
-
const
|
|
4008
|
-
|
|
4659
|
+
const _g2 = globalThis;
|
|
4660
|
+
let dispatch = _g2.__retrivoraDispatchChat;
|
|
4661
|
+
if (typeof dispatch !== "function") {
|
|
4009
4662
|
try {
|
|
4010
|
-
const
|
|
4663
|
+
const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
|
|
4664
|
+
if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
|
|
4665
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4666
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4667
|
+
dispatch = gateway.dispatchChatCompletion;
|
|
4668
|
+
}
|
|
4669
|
+
} catch (e) {
|
|
4670
|
+
}
|
|
4671
|
+
}
|
|
4672
|
+
if (typeof dispatch === "function") {
|
|
4673
|
+
try {
|
|
4674
|
+
const res = yield new __await(dispatch({
|
|
4011
4675
|
model: this.model,
|
|
4012
4676
|
messages: formattedMessages,
|
|
4013
4677
|
max_tokens: this.maxTokens,
|
|
@@ -4016,13 +4680,19 @@ ${context != null ? context : "None"}` },
|
|
|
4016
4680
|
}, this.apiKey));
|
|
4017
4681
|
if (res == null ? void 0 : res.stream) {
|
|
4018
4682
|
streamBody = res.stream;
|
|
4019
|
-
} else
|
|
4020
|
-
|
|
4021
|
-
|
|
4683
|
+
} else {
|
|
4684
|
+
const content = extractContent(res == null ? void 0 : res.response);
|
|
4685
|
+
if (content !== void 0) {
|
|
4686
|
+
yield content;
|
|
4687
|
+
return;
|
|
4688
|
+
}
|
|
4689
|
+
throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
|
|
4022
4690
|
}
|
|
4023
4691
|
} catch (dispatchErr) {
|
|
4024
4692
|
throw dispatchErr;
|
|
4025
4693
|
}
|
|
4694
|
+
} else {
|
|
4695
|
+
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.`);
|
|
4026
4696
|
}
|
|
4027
4697
|
}
|
|
4028
4698
|
if (!streamBody) {
|
|
@@ -4049,14 +4719,14 @@ ${context != null ? context : "None"}` },
|
|
|
4049
4719
|
if (done) break;
|
|
4050
4720
|
buffer += decoder.decode(value, { stream: true });
|
|
4051
4721
|
const lines = buffer.split("\n");
|
|
4052
|
-
buffer = (
|
|
4722
|
+
buffer = (_c = lines.pop()) != null ? _c : "";
|
|
4053
4723
|
for (const line of lines) {
|
|
4054
4724
|
const trimmed = line.trim();
|
|
4055
4725
|
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
4056
4726
|
if (!trimmed.startsWith("data:")) continue;
|
|
4057
4727
|
try {
|
|
4058
4728
|
const json = JSON.parse(trimmed.slice(5).trim());
|
|
4059
|
-
const text = resolvePath(json, extractPath);
|
|
4729
|
+
const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
|
|
4060
4730
|
if (text && typeof text === "string") yield text;
|
|
4061
4731
|
} catch (e) {
|
|
4062
4732
|
}
|
|
@@ -4066,7 +4736,7 @@ ${context != null ? context : "None"}` },
|
|
|
4066
4736
|
const jsonStr = buffer.replace(/^data:\s*/, "").trim();
|
|
4067
4737
|
try {
|
|
4068
4738
|
const json = JSON.parse(jsonStr);
|
|
4069
|
-
const text = resolvePath(json, extractPath);
|
|
4739
|
+
const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
|
|
4070
4740
|
if (text && typeof text === "string") yield text;
|
|
4071
4741
|
} catch (e) {
|
|
4072
4742
|
}
|
|
@@ -4094,18 +4764,33 @@ ${context != null ? context : "None"}` },
|
|
|
4094
4764
|
const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
|
|
4095
4765
|
if (isSelfHost || Boolean(process.env.VERCEL)) {
|
|
4096
4766
|
const _g2 = globalThis;
|
|
4097
|
-
|
|
4767
|
+
let dispatch = _g2.__retrivoraDispatchEmbedding;
|
|
4768
|
+
if (typeof dispatch !== "function") {
|
|
4098
4769
|
try {
|
|
4099
|
-
const
|
|
4770
|
+
const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
|
|
4771
|
+
if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
|
|
4772
|
+
_g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
|
|
4773
|
+
_g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
|
|
4774
|
+
dispatch = gateway.dispatchEmbedding;
|
|
4775
|
+
}
|
|
4776
|
+
} catch (e) {
|
|
4777
|
+
}
|
|
4778
|
+
}
|
|
4779
|
+
if (typeof dispatch === "function") {
|
|
4780
|
+
try {
|
|
4781
|
+
const res = await dispatch({
|
|
4100
4782
|
model: this.model,
|
|
4101
4783
|
input: text
|
|
4102
4784
|
}, this.apiKey);
|
|
4103
4785
|
if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
|
|
4104
4786
|
return res.data[0].embedding;
|
|
4105
4787
|
}
|
|
4788
|
+
throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
|
|
4106
4789
|
} catch (dispatchErr) {
|
|
4107
4790
|
throw dispatchErr;
|
|
4108
4791
|
}
|
|
4792
|
+
} else {
|
|
4793
|
+
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.`);
|
|
4109
4794
|
}
|
|
4110
4795
|
}
|
|
4111
4796
|
const { data } = await this.http.post(path2, payload);
|
|
@@ -6090,8 +6775,8 @@ var IntentClassifier = class {
|
|
|
6090
6775
|
}
|
|
6091
6776
|
// ─── Intent Heuristic Checkers ─────────────────────────────────────────────
|
|
6092
6777
|
static isInformationLookup(query) {
|
|
6093
|
-
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)) {
|
|
6094
|
-
if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top selling|best)\b/i.test(query)) {
|
|
6778
|
+
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)) {
|
|
6779
|
+
if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top 10|top selling|best|chart|graph|plot|breakdown|analytics)\b/i.test(query)) {
|
|
6095
6780
|
return true;
|
|
6096
6781
|
}
|
|
6097
6782
|
}
|
|
@@ -6128,7 +6813,7 @@ var Rule1SpecificInfoRule = class {
|
|
|
6128
6813
|
}
|
|
6129
6814
|
evaluate(context, intent) {
|
|
6130
6815
|
const q = (context.userQuery || "").toLowerCase().trim();
|
|
6131
|
-
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);
|
|
6816
|
+
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);
|
|
6132
6817
|
const isNonVisual = !/\b(compare|versus|vs\.?|trend|monthly|revenue|best|top 10|chart|table|list|grid)\b/i.test(q);
|
|
6133
6818
|
if (isFactQuery && isNonVisual) {
|
|
6134
6819
|
return {
|
|
@@ -6967,7 +7652,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
6967
7652
|
}
|
|
6968
7653
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
6969
7654
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
6970
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null)
|
|
7655
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
6971
7656
|
return {
|
|
6972
7657
|
type: "product_carousel",
|
|
6973
7658
|
title: "Recommended Products",
|
|
@@ -7347,7 +8032,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7347
8032
|
return fieldCount.size > 2;
|
|
7348
8033
|
}
|
|
7349
8034
|
static profileData(data) {
|
|
7350
|
-
const records = data.map((item) => {
|
|
8035
|
+
const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
|
|
8036
|
+
var _a2, _b;
|
|
7351
8037
|
const fields2 = {};
|
|
7352
8038
|
Object.entries(item.metadata || {}).forEach(([key, value]) => {
|
|
7353
8039
|
const primitive = this.toPrimitive(value);
|
|
@@ -7356,8 +8042,8 @@ ${schemaProfileText}` : ""}`;
|
|
|
7356
8042
|
if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
|
|
7357
8043
|
return {
|
|
7358
8044
|
id: item.id,
|
|
7359
|
-
content: item.content,
|
|
7360
|
-
score: item.score,
|
|
8045
|
+
content: (_a2 = item.content) != null ? _a2 : "",
|
|
8046
|
+
score: (_b = item.score) != null ? _b : 0,
|
|
7361
8047
|
fields: fields2,
|
|
7362
8048
|
source: item
|
|
7363
8049
|
};
|
|
@@ -7414,6 +8100,11 @@ ${schemaProfileText}` : ""}`;
|
|
|
7414
8100
|
}
|
|
7415
8101
|
static chooseAutomaticVisualization(data, profile, query) {
|
|
7416
8102
|
if (profile.records.length === 0) return null;
|
|
8103
|
+
const q = query.toLowerCase().trim();
|
|
8104
|
+
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);
|
|
8105
|
+
if (!isExplicitVisualOrAnalytic) {
|
|
8106
|
+
return null;
|
|
8107
|
+
}
|
|
7417
8108
|
if (profile.dateFields.length > 0 && profile.numericFields.length > 0) {
|
|
7418
8109
|
return this.transformToLineChart(profile);
|
|
7419
8110
|
}
|
|
@@ -7529,6 +8220,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7529
8220
|
return Array.from(categories);
|
|
7530
8221
|
}
|
|
7531
8222
|
static getProductCategory(item) {
|
|
8223
|
+
if (!item) return null;
|
|
7532
8224
|
const meta = item.metadata || {};
|
|
7533
8225
|
const metadataCategory = resolveMetadataValue(meta, "category");
|
|
7534
8226
|
if (this.isUsableCategory(metadataCategory)) return String(metadataCategory).trim();
|
|
@@ -7645,6 +8337,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7645
8337
|
if (!fields.has(normalized)) fields.set(normalized, clean);
|
|
7646
8338
|
};
|
|
7647
8339
|
data.forEach((item) => {
|
|
8340
|
+
if (!item) return;
|
|
7648
8341
|
Object.keys(item.metadata || {}).forEach(addField);
|
|
7649
8342
|
for (const match of (item.content || "").matchAll(/(?:^|\n)\s*([A-Za-z][A-Za-z0-9_ /-]{1,50})\s*[:\-–]\s*([^\n]+)/g)) {
|
|
7650
8343
|
addField(match[1]);
|
|
@@ -7761,6 +8454,7 @@ ${schemaProfileText}` : ""}`;
|
|
|
7761
8454
|
return true;
|
|
7762
8455
|
}
|
|
7763
8456
|
static extractStockQuantity(item) {
|
|
8457
|
+
if (!item) return null;
|
|
7764
8458
|
const meta = item.metadata || {};
|
|
7765
8459
|
const stockValue = resolveMetadataValue(meta, "stock");
|
|
7766
8460
|
const numericStock = this.toFiniteNumber(stockValue);
|
|
@@ -8460,7 +9154,7 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8460
9154
|
*/
|
|
8461
9155
|
askStreamInternal(_0) {
|
|
8462
9156
|
return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
|
|
8463
|
-
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
|
|
9157
|
+
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;
|
|
8464
9158
|
yield new __await(this.initialize());
|
|
8465
9159
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
8466
9160
|
const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
|
|
@@ -8503,8 +9197,8 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8503
9197
|
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;
|
|
8504
9198
|
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
8505
9199
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
8506
|
-
const wantsExhaustiveList =
|
|
8507
|
-
const retrievalLimit =
|
|
9200
|
+
const wantsExhaustiveList = true;
|
|
9201
|
+
const retrievalLimit = Math.max(topK * 50, 1e3);
|
|
8508
9202
|
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"));
|
|
8509
9203
|
console.log("[Pipeline] Raw vectorDB.query response:", {
|
|
8510
9204
|
rawCount: rawSources.length,
|
|
@@ -8528,40 +9222,29 @@ ${m.content}`).join("\n\n---\n\n");
|
|
|
8528
9222
|
var _a3;
|
|
8529
9223
|
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
|
|
8530
9224
|
});
|
|
8531
|
-
const rerankLimit =
|
|
9225
|
+
const rerankLimit = Math.max(retrievalLimit, fullSources.length);
|
|
8532
9226
|
const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
|
|
8533
9227
|
if (!hasNumericPredicates && useReranking) {
|
|
8534
9228
|
fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
|
|
8535
|
-
} else if (!wantsExhaustiveList) {
|
|
8536
|
-
fullSources = fullSources.slice(0, topK);
|
|
8537
9229
|
}
|
|
8538
9230
|
const rerankMs = performance.now() - rerankStart;
|
|
8539
|
-
|
|
9231
|
+
const totalCount = fullSources.length;
|
|
9232
|
+
const promptSources = fullSources.slice(0, 15);
|
|
9233
|
+
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]
|
|
9234
|
+
|
|
9235
|
+
` + promptSources.map((m, i) => {
|
|
8540
9236
|
var _a3;
|
|
8541
9237
|
return `[Source ${i + 1}]
|
|
8542
9238
|
${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
|
|
8543
9239
|
}).join("\n\n---\n\n") : "No relevant context found.";
|
|
8544
|
-
let displayCount = 15;
|
|
8545
|
-
if (hasMetadataFilter) {
|
|
8546
|
-
displayCount = fullSources.length;
|
|
8547
|
-
} else {
|
|
8548
|
-
const baseThreshold = Math.max(scoreThreshold, 0.4);
|
|
8549
|
-
const highlyRelevant = fullSources.filter((m) => {
|
|
8550
|
-
var _a3;
|
|
8551
|
-
return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= baseThreshold;
|
|
8552
|
-
});
|
|
8553
|
-
displayCount = Math.max(highlyRelevant.length, topK);
|
|
8554
|
-
if (displayCount > 15) {
|
|
8555
|
-
displayCount = 15;
|
|
8556
|
-
}
|
|
8557
|
-
}
|
|
8558
9240
|
const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
|
|
8559
9241
|
var _a3, _b2;
|
|
8560
9242
|
return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
|
|
8561
|
-
})
|
|
9243
|
+
});
|
|
8562
9244
|
console.log("[Pipeline] Final sources for prompt & UI:", {
|
|
8563
9245
|
count: sources.length,
|
|
8564
|
-
|
|
9246
|
+
totalRawCount: rawSources.length,
|
|
9247
|
+
sources: sources.slice(0, 10).map((s, idx) => {
|
|
8565
9248
|
var _a3;
|
|
8566
9249
|
return {
|
|
8567
9250
|
rank: idx + 1,
|
|
@@ -8761,7 +9444,7 @@ ${context}`;
|
|
|
8761
9444
|
}
|
|
8762
9445
|
yield fullReply;
|
|
8763
9446
|
}
|
|
8764
|
-
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true
|
|
9447
|
+
const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
|
|
8765
9448
|
if (runHallucination) {
|
|
8766
9449
|
hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
|
|
8767
9450
|
}
|
|
@@ -8770,7 +9453,7 @@ ${context}`;
|
|
|
8770
9453
|
const latency = {
|
|
8771
9454
|
embedMs: Math.round(embedMs),
|
|
8772
9455
|
retrieveMs: Math.round(retrieveMs),
|
|
8773
|
-
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((
|
|
9456
|
+
rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
|
|
8774
9457
|
generateMs: Math.round(generateMs),
|
|
8775
9458
|
totalMs: Math.round(totalMs)
|
|
8776
9459
|
};
|
|
@@ -8783,7 +9466,7 @@ ${context}`;
|
|
|
8783
9466
|
totalTokens: promptTokens + completionTokens,
|
|
8784
9467
|
estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
|
|
8785
9468
|
};
|
|
8786
|
-
const awaitHallucination = ((
|
|
9469
|
+
const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
|
|
8787
9470
|
const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
|
|
8788
9471
|
uiTransformationPromise,
|
|
8789
9472
|
awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
|
|
@@ -8812,10 +9495,10 @@ ${context}`;
|
|
|
8812
9495
|
hallucinationReason: hScore.reason
|
|
8813
9496
|
} : {});
|
|
8814
9497
|
const trace = buildTrace(hallucinationResult);
|
|
8815
|
-
const isTelemetryActive = (
|
|
9498
|
+
const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
|
|
8816
9499
|
if (isTelemetryActive) {
|
|
8817
9500
|
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";
|
|
8818
|
-
const telemetryUrl = ((
|
|
9501
|
+
const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
|
|
8819
9502
|
const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
|
|
8820
9503
|
(async () => {
|
|
8821
9504
|
try {
|
|
@@ -8874,9 +9557,8 @@ ${context}`;
|
|
|
8874
9557
|
{ visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
|
|
8875
9558
|
);
|
|
8876
9559
|
}
|
|
8877
|
-
const
|
|
8878
|
-
|
|
8879
|
-
if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
|
|
9560
|
+
const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
|
|
9561
|
+
if (forceDeterministic || !enableLlmUiTransform) {
|
|
8880
9562
|
return UITransformer.transform(question, sources, this.config, cachedSchema);
|
|
8881
9563
|
}
|
|
8882
9564
|
try {
|
|
@@ -9033,7 +9715,10 @@ ${context}`;
|
|
|
9033
9715
|
Focus on extracting the core intent and entities. Do not answer the question, just rewrite it.
|
|
9034
9716
|
|
|
9035
9717
|
History:
|
|
9036
|
-
${history.map((m) =>
|
|
9718
|
+
${(history || []).map((m) => {
|
|
9719
|
+
var _a2;
|
|
9720
|
+
return `${(m == null ? void 0 : m.role) || "user"}: ${(_a2 = m == null ? void 0 : m.content) != null ? _a2 : ""}`;
|
|
9721
|
+
}).join("\n")}
|
|
9037
9722
|
|
|
9038
9723
|
New Question: ${question}
|
|
9039
9724
|
|
|
@@ -9057,8 +9742,11 @@ Optimized Search Query:`;
|
|
|
9057
9742
|
const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
|
|
9058
9743
|
try {
|
|
9059
9744
|
const { sources } = await this.retrieve(query, { namespace: ns, topK: 5 });
|
|
9060
|
-
if (sources.length === 0) return [];
|
|
9061
|
-
const context = sources.map((s) =>
|
|
9745
|
+
if (!sources || sources.length === 0) return [];
|
|
9746
|
+
const context = sources.map((s) => {
|
|
9747
|
+
var _a2;
|
|
9748
|
+
return (_a2 = s == null ? void 0 : s.content) != null ? _a2 : "";
|
|
9749
|
+
}).join("\n\n---\n\n");
|
|
9062
9750
|
const prompt = `Based on the following snippets from a document, what are at least 5 short, relevant questions a user might ask?
|
|
9063
9751
|
Focus on questions that can be answered by the context.
|
|
9064
9752
|
Keep each question under 10 words and make them very specific to the content.
|