@retrivora-ai/rag-engine 2.0.7 → 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.js CHANGED
@@ -121,6 +121,609 @@ var init_templateUtils = __esm({
121
121
  }
122
122
  });
123
123
 
124
+ // ../../services/llm-gateway/providers/groq.ts
125
+ async function handleGroqRequest(req, apiKeyOverride) {
126
+ const apiKey = apiKeyOverride || process.env.GROQ_API_KEY;
127
+ if (!apiKey) {
128
+ throw new Error("Groq API Key missing. Please set GROQ_API_KEY in environment variables.");
129
+ }
130
+ const modelName = req.model.replace(/^groq\//i, "");
131
+ const payload = __spreadProps(__spreadValues({}, req), {
132
+ model: modelName
133
+ });
134
+ const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
135
+ method: "POST",
136
+ headers: {
137
+ "Content-Type": "application/json",
138
+ "Authorization": `Bearer ${apiKey}`
139
+ },
140
+ body: JSON.stringify(payload)
141
+ });
142
+ if (!response.ok) {
143
+ const errorText = await response.text();
144
+ throw new Error(`Groq API Error (${response.status}): ${errorText}`);
145
+ }
146
+ if (req.stream && response.body) {
147
+ return { stream: response.body };
148
+ }
149
+ const json = await response.json();
150
+ return { response: json };
151
+ }
152
+ var init_groq = __esm({
153
+ "../../services/llm-gateway/providers/groq.ts"() {
154
+ "use strict";
155
+ }
156
+ });
157
+
158
+ // ../../services/llm-gateway/providers/openai.ts
159
+ async function handleOpenAIRequest(req, apiKeyOverride) {
160
+ const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
161
+ if (!apiKey) {
162
+ throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
163
+ }
164
+ const modelName = req.model.replace(/^(openai|gpt)\//i, "");
165
+ const payload = __spreadProps(__spreadValues({}, req), {
166
+ model: modelName
167
+ });
168
+ const response = await fetch("https://api.openai.com/v1/chat/completions", {
169
+ method: "POST",
170
+ headers: {
171
+ "Content-Type": "application/json",
172
+ "Authorization": `Bearer ${apiKey}`
173
+ },
174
+ body: JSON.stringify(payload)
175
+ });
176
+ if (!response.ok) {
177
+ const errorText = await response.text();
178
+ throw new Error(`OpenAI API Error (${response.status}): ${errorText}`);
179
+ }
180
+ if (req.stream && response.body) {
181
+ return { stream: response.body };
182
+ }
183
+ const json = await response.json();
184
+ return { response: json };
185
+ }
186
+ async function handleOpenAIEmbedding(req, apiKeyOverride) {
187
+ const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
188
+ if (!apiKey) {
189
+ throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
190
+ }
191
+ const modelName = req.model.replace(/^(openai)\//i, "");
192
+ const response = await fetch("https://api.openai.com/v1/embeddings", {
193
+ method: "POST",
194
+ headers: {
195
+ "Content-Type": "application/json",
196
+ "Authorization": `Bearer ${apiKey}`
197
+ },
198
+ body: JSON.stringify({
199
+ model: modelName,
200
+ input: req.input
201
+ })
202
+ });
203
+ if (!response.ok) {
204
+ const errorText = await response.text();
205
+ throw new Error(`OpenAI Embedding API Error (${response.status}): ${errorText}`);
206
+ }
207
+ return await response.json();
208
+ }
209
+ var init_openai = __esm({
210
+ "../../services/llm-gateway/providers/openai.ts"() {
211
+ "use strict";
212
+ }
213
+ });
214
+
215
+ // ../../services/llm-gateway/providers/gemini.ts
216
+ async function handleGeminiRequest(req, apiKeyOverride) {
217
+ const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
218
+ if (!apiKey) {
219
+ throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
220
+ }
221
+ let modelName = req.model.replace(/^(google|gemini)\//i, "");
222
+ if (!modelName.startsWith("gemini-")) {
223
+ modelName = `gemini-${modelName}`;
224
+ }
225
+ const payload = __spreadProps(__spreadValues({}, req), {
226
+ model: modelName
227
+ });
228
+ const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", {
229
+ method: "POST",
230
+ headers: {
231
+ "Content-Type": "application/json",
232
+ "Authorization": `Bearer ${apiKey}`
233
+ },
234
+ body: JSON.stringify(payload)
235
+ });
236
+ if (!response.ok) {
237
+ const errorText = await response.text();
238
+ throw new Error(`Google Gemini API Error (${response.status}): ${errorText}`);
239
+ }
240
+ if (req.stream && response.body) {
241
+ return { stream: response.body };
242
+ }
243
+ const json = await response.json();
244
+ return { response: json };
245
+ }
246
+ async function handleGeminiEmbedding(req, apiKeyOverride) {
247
+ const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
248
+ if (!apiKey) {
249
+ throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
250
+ }
251
+ let modelName = req.model.replace(/^(google|gemini)\//i, "");
252
+ if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.startsWith("text-embedding-00") && !modelName.startsWith("embedding-00")) {
253
+ modelName = "text-embedding-004";
254
+ }
255
+ const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/embeddings", {
256
+ method: "POST",
257
+ headers: {
258
+ "Content-Type": "application/json",
259
+ "Authorization": `Bearer ${apiKey}`
260
+ },
261
+ body: JSON.stringify({
262
+ model: modelName,
263
+ input: req.input
264
+ })
265
+ });
266
+ if (!response.ok) {
267
+ const errorText = await response.text();
268
+ throw new Error(`Google Gemini Embedding API Error (${response.status}): ${errorText}`);
269
+ }
270
+ return await response.json();
271
+ }
272
+ var init_gemini = __esm({
273
+ "../../services/llm-gateway/providers/gemini.ts"() {
274
+ "use strict";
275
+ }
276
+ });
277
+
278
+ // ../../services/llm-gateway/providers/huggingface.ts
279
+ async function handleHuggingFaceChatRequest(req, apiKeyOverride) {
280
+ var _a2, _b;
281
+ const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
282
+ if (!apiKey) {
283
+ throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
284
+ }
285
+ let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
286
+ if (!modelName || modelName === "default" || modelName.toLowerCase() === "qwen" || modelName.toLowerCase() === "qwen-coder") {
287
+ modelName = "Qwen/Qwen2.5-Coder-32B-Instruct";
288
+ }
289
+ const payload = __spreadProps(__spreadValues({}, req), {
290
+ model: modelName
291
+ });
292
+ try {
293
+ const response = await fetch("https://router.huggingface.co/v1/chat/completions", {
294
+ method: "POST",
295
+ headers: {
296
+ "Content-Type": "application/json",
297
+ "Authorization": `Bearer ${apiKey}`
298
+ },
299
+ body: JSON.stringify(payload)
300
+ });
301
+ if (response.ok) {
302
+ if (req.stream && response.body) {
303
+ return { stream: response.body };
304
+ }
305
+ const json = await response.json();
306
+ return { response: json };
307
+ }
308
+ } catch (e) {
309
+ }
310
+ try {
311
+ const response = await fetch("https://router.huggingface.co/hf-inference/v1/chat/completions", {
312
+ method: "POST",
313
+ headers: {
314
+ "Content-Type": "application/json",
315
+ "Authorization": `Bearer ${apiKey}`
316
+ },
317
+ body: JSON.stringify(payload)
318
+ });
319
+ if (response.ok) {
320
+ if (req.stream && response.body) {
321
+ return { stream: response.body };
322
+ }
323
+ const json = await response.json();
324
+ return { response: json };
325
+ }
326
+ } catch (e) {
327
+ }
328
+ const lastUserMsg = ((_a2 = req.messages.filter((m) => m.role === "user").pop()) == null ? void 0 : _a2.content) || "Hello";
329
+ const pipelineRes = await fetch(`https://router.huggingface.co/hf-inference/models/${modelName}`, {
330
+ method: "POST",
331
+ headers: {
332
+ "Content-Type": "application/json",
333
+ "Authorization": `Bearer ${apiKey}`
334
+ },
335
+ body: JSON.stringify({
336
+ inputs: lastUserMsg,
337
+ parameters: { max_new_tokens: req.max_tokens || 256, temperature: req.temperature || 0.7 },
338
+ options: { wait_for_model: true }
339
+ })
340
+ });
341
+ if (!pipelineRes.ok) {
342
+ const errorText = await pipelineRes.text();
343
+ throw new Error(`HuggingFace API Error (${pipelineRes.status}): ${errorText}`);
344
+ }
345
+ const raw = await pipelineRes.json();
346
+ const textOutput = Array.isArray(raw) ? ((_b = raw[0]) == null ? void 0 : _b.generated_text) || JSON.stringify(raw) : JSON.stringify(raw);
347
+ const formattedResponse = {
348
+ id: `hf-${Date.now()}`,
349
+ object: "chat.completion",
350
+ created: Math.floor(Date.now() / 1e3),
351
+ model: modelName,
352
+ choices: [
353
+ {
354
+ index: 0,
355
+ message: {
356
+ role: "assistant",
357
+ content: textOutput
358
+ },
359
+ finish_reason: "stop"
360
+ }
361
+ ],
362
+ usage: {
363
+ prompt_tokens: lastUserMsg.length,
364
+ completion_tokens: textOutput.length,
365
+ total_tokens: lastUserMsg.length + textOutput.length
366
+ }
367
+ };
368
+ return { response: formattedResponse };
369
+ }
370
+ async function handleHuggingFaceEmbedding(req, apiKeyOverride) {
371
+ const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
372
+ if (!apiKey) {
373
+ throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
374
+ }
375
+ let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
376
+ if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.includes("/") && !modelName.includes("bge") && !modelName.includes("sentence-transformers")) {
377
+ modelName = "BAAI/bge-base-en-v1.5";
378
+ }
379
+ const inputs = Array.isArray(req.input) ? req.input : [req.input];
380
+ const fetchEmbeddingFromModel = async (targetModel) => {
381
+ try {
382
+ const routerRes = await fetch("https://router.huggingface.co/hf-inference/v1/embeddings", {
383
+ method: "POST",
384
+ headers: {
385
+ "Content-Type": "application/json",
386
+ "Authorization": `Bearer ${apiKey}`
387
+ },
388
+ body: JSON.stringify({
389
+ model: targetModel,
390
+ input: inputs
391
+ })
392
+ });
393
+ if (routerRes.ok) {
394
+ const json = await routerRes.json();
395
+ if (json && json.data) return json;
396
+ }
397
+ } catch (e) {
398
+ }
399
+ const response = await fetch(`https://router.huggingface.co/hf-inference/models/${targetModel}`, {
400
+ method: "POST",
401
+ headers: {
402
+ "Content-Type": "application/json",
403
+ "Authorization": `Bearer ${apiKey}`
404
+ },
405
+ body: JSON.stringify({
406
+ inputs,
407
+ options: { wait_for_model: true }
408
+ })
409
+ });
410
+ if (!response.ok) {
411
+ const errorText = await response.text();
412
+ throw new Error(`HuggingFace API Error (${response.status}): ${errorText}`);
413
+ }
414
+ const rawData = await response.json();
415
+ const embeddings = Array.isArray(rawData[0]) ? typeof rawData[0][0] === "number" ? rawData : rawData.map((arr) => arr[0]) : [rawData];
416
+ return {
417
+ object: "list",
418
+ data: embeddings.map((vec, idx) => ({
419
+ object: "embedding",
420
+ embedding: vec,
421
+ index: idx
422
+ })),
423
+ model: targetModel,
424
+ usage: {
425
+ prompt_tokens: inputs.reduce((acc, str) => acc + str.length, 0),
426
+ completion_tokens: 0,
427
+ total_tokens: inputs.reduce((acc, str) => acc + str.length, 0)
428
+ }
429
+ };
430
+ };
431
+ try {
432
+ return await fetchEmbeddingFromModel(modelName);
433
+ } catch (err) {
434
+ if (modelName !== "BAAI/bge-base-en-v1.5") {
435
+ console.warn(`[LLM Gateway] HuggingFace model ${modelName} failed. Falling back to BAAI/bge-base-en-v1.5...`, err);
436
+ return await fetchEmbeddingFromModel("BAAI/bge-base-en-v1.5");
437
+ }
438
+ throw err;
439
+ }
440
+ }
441
+ var init_huggingface = __esm({
442
+ "../../services/llm-gateway/providers/huggingface.ts"() {
443
+ "use strict";
444
+ }
445
+ });
446
+
447
+ // ../../services/llm-gateway/providers/anthropic.ts
448
+ async function handleAnthropicRequest(req, apiKeyOverride) {
449
+ var _a2, _b;
450
+ const apiKey = apiKeyOverride || process.env.ANTHROPIC_API_KEY;
451
+ if (!apiKey) {
452
+ throw new Error("Anthropic API Key missing. Please set ANTHROPIC_API_KEY in environment variables.");
453
+ }
454
+ const modelName = req.model.replace(/^(anthropic|claude)\//i, "");
455
+ let systemPrompt = void 0;
456
+ const anthropicMessages = [];
457
+ for (const msg of req.messages) {
458
+ if (msg.role === "system") {
459
+ systemPrompt = systemPrompt ? `${systemPrompt}
460
+ ${msg.content}` : msg.content;
461
+ } else {
462
+ anthropicMessages.push({
463
+ role: msg.role === "assistant" ? "assistant" : "user",
464
+ content: msg.content
465
+ });
466
+ }
467
+ }
468
+ if (anthropicMessages.length === 0) {
469
+ anthropicMessages.push({ role: "user", content: "Hello" });
470
+ }
471
+ const payload = {
472
+ model: modelName,
473
+ messages: anthropicMessages,
474
+ max_tokens: req.max_tokens || req.max_completion_tokens || 1024,
475
+ stream: req.stream || false
476
+ };
477
+ if (systemPrompt) {
478
+ payload.system = systemPrompt;
479
+ }
480
+ if (req.temperature !== void 0) {
481
+ payload.temperature = req.temperature;
482
+ }
483
+ const response = await fetch("https://api.anthropic.com/v1/messages", {
484
+ method: "POST",
485
+ headers: {
486
+ "Content-Type": "application/json",
487
+ "x-api-key": apiKey,
488
+ "anthropic-version": "2023-06-01"
489
+ },
490
+ body: JSON.stringify(payload)
491
+ });
492
+ if (!response.ok) {
493
+ const errorText = await response.text();
494
+ throw new Error(`Anthropic API Error (${response.status}): ${errorText}`);
495
+ }
496
+ if (req.stream && response.body) {
497
+ return { stream: response.body };
498
+ }
499
+ const json = await response.json();
500
+ const textContent = ((_b = (_a2 = json.content) == null ? void 0 : _a2[0]) == null ? void 0 : _b.text) || "";
501
+ const openAIResponse = {
502
+ id: json.id || `chatcmpl-${Date.now()}`,
503
+ object: "chat.completion",
504
+ created: Math.floor(Date.now() / 1e3),
505
+ model: json.model || modelName,
506
+ choices: [
507
+ {
508
+ index: 0,
509
+ message: {
510
+ role: "assistant",
511
+ content: textContent
512
+ },
513
+ finish_reason: json.stop_reason === "end_turn" ? "stop" : json.stop_reason || "stop"
514
+ }
515
+ ],
516
+ usage: json.usage ? {
517
+ prompt_tokens: json.usage.input_tokens,
518
+ completion_tokens: json.usage.output_tokens,
519
+ total_tokens: json.usage.input_tokens + json.usage.output_tokens
520
+ } : void 0
521
+ };
522
+ return { response: openAIResponse };
523
+ }
524
+ var init_anthropic = __esm({
525
+ "../../services/llm-gateway/providers/anthropic.ts"() {
526
+ "use strict";
527
+ }
528
+ });
529
+
530
+ // ../../services/llm-gateway/providers/ollama.ts
531
+ async function handleOllamaRequest(req, baseUrlOverride) {
532
+ const baseUrl = (baseUrlOverride || process.env.OLLAMA_BASE_URL || "http://localhost:11434/v1").replace(/\/+$/, "");
533
+ const modelName = req.model.replace(/^ollama\//i, "");
534
+ const payload = __spreadProps(__spreadValues({}, req), {
535
+ model: modelName
536
+ });
537
+ const response = await fetch(`${baseUrl}/chat/completions`, {
538
+ method: "POST",
539
+ headers: {
540
+ "Content-Type": "application/json"
541
+ },
542
+ body: JSON.stringify(payload)
543
+ });
544
+ if (!response.ok) {
545
+ const errorText = await response.text();
546
+ throw new Error(`Ollama API Error (${response.status}): ${errorText}`);
547
+ }
548
+ if (req.stream && response.body) {
549
+ return { stream: response.body };
550
+ }
551
+ const json = await response.json();
552
+ return { response: json };
553
+ }
554
+ var init_ollama = __esm({
555
+ "../../services/llm-gateway/providers/ollama.ts"() {
556
+ "use strict";
557
+ }
558
+ });
559
+
560
+ // ../../services/llm-gateway/router.ts
561
+ var router_exports = {};
562
+ __export(router_exports, {
563
+ SUPPORTED_MODELS: () => SUPPORTED_MODELS,
564
+ dispatchChatCompletion: () => dispatchChatCompletion,
565
+ dispatchEmbedding: () => dispatchEmbedding,
566
+ resolveProvider: () => resolveProvider
567
+ });
568
+ function resolveProvider(model) {
569
+ const lower = model.toLowerCase();
570
+ if (lower.startsWith("huggingface/") || lower.startsWith("hf/")) {
571
+ return "huggingface";
572
+ }
573
+ if (lower.startsWith("ollama/")) {
574
+ return "ollama";
575
+ }
576
+ if (lower.startsWith("groq/") || lower.includes("llama") || lower.includes("qwen") || lower.includes("mixtral")) {
577
+ return "groq";
578
+ }
579
+ if (process.env.GROQ_API_KEY) return "groq";
580
+ if (process.env.OPENAI_API_KEY) return "openai";
581
+ if (process.env.GEMINI_API_KEY) return "gemini";
582
+ if (process.env.ANTHROPIC_API_KEY) return "anthropic";
583
+ if (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY) return "huggingface";
584
+ return "groq";
585
+ }
586
+ function cleanApiKeyOverride(apiKeyOverride) {
587
+ if (!apiKeyOverride) return void 0;
588
+ const key = apiKeyOverride.trim();
589
+ if (key === process.env.LITELLM_API_KEY || key === process.env.LITELLM_MASTER_KEY || key.startsWith("sk-retrivora") || !key.startsWith("gsk_") && !key.startsWith("AIza") && !key.startsWith("sk-ant-") && !key.startsWith("sk-proj-")) {
590
+ return void 0;
591
+ }
592
+ return key;
593
+ }
594
+ async function dispatchChatCompletion(req, apiKeyOverride) {
595
+ const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
596
+ const provider = resolveProvider(req.model);
597
+ try {
598
+ switch (provider) {
599
+ case "groq":
600
+ return await handleGroqRequest(req, effectiveKey);
601
+ case "openai":
602
+ return await handleOpenAIRequest(req, effectiveKey);
603
+ case "gemini":
604
+ return await handleGeminiRequest(req, effectiveKey);
605
+ case "anthropic":
606
+ return await handleAnthropicRequest(req, effectiveKey);
607
+ case "ollama":
608
+ return await handleOllamaRequest(req);
609
+ case "huggingface":
610
+ return await handleHuggingFaceChatRequest(req, effectiveKey);
611
+ default:
612
+ throw new Error(`Unsupported LLM provider for model: ${req.model}`);
613
+ }
614
+ } catch (error) {
615
+ if (/rate[- ]?limit|429|exhausted/i.test(error.message)) {
616
+ const isGroqKey = process.env.GROQ_API_KEY || effectiveKey && effectiveKey.startsWith("gsk_");
617
+ const reqModelLower = req.model.toLowerCase();
618
+ if (isGroqKey && !reqModelLower.includes("llama-3.3-70b")) {
619
+ console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to secondary Groq model (llama-3.3-70b-versatile)...`);
620
+ try {
621
+ return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: "llama-3.3-70b-versatile" }), effectiveKey);
622
+ } catch (e) {
623
+ }
624
+ }
625
+ const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
626
+ if (provider !== "gemini" && geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ."))) {
627
+ console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Google Gemini (gemini-2.5-flash)...`);
628
+ try {
629
+ return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: "gemini-2.5-flash" }), effectiveKey);
630
+ } catch (e) {
631
+ }
632
+ }
633
+ if (provider !== "huggingface" && (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY)) {
634
+ console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Hugging Face (Qwen/Qwen2.5-Coder-32B-Instruct)...`);
635
+ try {
636
+ return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: "Qwen/Qwen2.5-Coder-32B-Instruct" }), effectiveKey);
637
+ } catch (e) {
638
+ }
639
+ }
640
+ if (provider !== "openai" && process.env.OPENAI_API_KEY) {
641
+ console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to OpenAI (gpt-4o-mini)...`);
642
+ try {
643
+ return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: "gpt-4o-mini" }), effectiveKey);
644
+ } catch (e) {
645
+ }
646
+ }
647
+ console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to local Ollama (llama3.2)...`);
648
+ return handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: "llama3.2" }));
649
+ }
650
+ throw error;
651
+ }
652
+ }
653
+ async function dispatchEmbedding(req, apiKeyOverride) {
654
+ const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
655
+ if (req.model.startsWith("hf/") || req.model.startsWith("huggingface/") || req.model.includes("bge-")) {
656
+ try {
657
+ return await handleHuggingFaceEmbedding(req, effectiveKey);
658
+ } catch (err) {
659
+ console.warn("[LLM Gateway] HuggingFace explicit model embedding failed, falling back to default gateway chain:", err);
660
+ }
661
+ }
662
+ const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
663
+ const isGeminiKeyValid = Boolean(geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ.")));
664
+ if (isGeminiKeyValid) {
665
+ try {
666
+ return await handleGeminiEmbedding(req, effectiveKey);
667
+ } catch (err) {
668
+ console.warn("[LLM Gateway] Gemini embedding failed:", err);
669
+ }
670
+ }
671
+ if (process.env.OPENAI_API_KEY) {
672
+ try {
673
+ return await handleOpenAIEmbedding(req, effectiveKey);
674
+ } catch (err) {
675
+ console.warn("[LLM Gateway] OpenAI embedding failed:", err);
676
+ }
677
+ }
678
+ if (process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN) {
679
+ try {
680
+ return await handleHuggingFaceEmbedding(req, effectiveKey);
681
+ } catch (err) {
682
+ console.warn("[LLM Gateway] HuggingFace fallback embedding failed:", err);
683
+ }
684
+ }
685
+ return handleGeminiEmbedding(req, effectiveKey);
686
+ }
687
+ var SUPPORTED_MODELS;
688
+ var init_router = __esm({
689
+ "../../services/llm-gateway/router.ts"() {
690
+ "use strict";
691
+ init_groq();
692
+ init_openai();
693
+ init_gemini();
694
+ init_huggingface();
695
+ init_anthropic();
696
+ init_ollama();
697
+ SUPPORTED_MODELS = [
698
+ { id: "groq/llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
699
+ { id: "llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
700
+ { id: "groq/llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
701
+ { id: "llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
702
+ { id: "gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
703
+ { id: "openai/gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
704
+ { id: "gpt-4o", object: "model", created: 17e8, owned_by: "openai" },
705
+ { id: "gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
706
+ { id: "google/gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
707
+ { id: "claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
708
+ { id: "anthropic/claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
709
+ { id: "text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
710
+ { id: "google/text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
711
+ { id: "BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
712
+ { id: "huggingface/BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
713
+ { id: "groq/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
714
+ { id: "qwen/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
715
+ { id: "qwen/qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
716
+ { id: "qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
717
+ { id: "ollama/llama3.2", object: "model", created: 17e8, owned_by: "ollama" }
718
+ ];
719
+ if (typeof globalThis !== "undefined") {
720
+ const _g2 = globalThis;
721
+ _g2.__retrivoraDispatchChat = dispatchChatCompletion;
722
+ _g2.__retrivoraDispatchEmbedding = dispatchEmbedding;
723
+ }
724
+ }
725
+ });
726
+
124
727
  // src/providers/vectordb/BaseVectorProvider.ts
125
728
  var BaseVectorProvider;
126
729
  var init_BaseVectorProvider = __esm({
@@ -3976,6 +4579,17 @@ var VECTOR_PROFILES = {
3976
4579
  };
3977
4580
 
3978
4581
  // src/llm/providers/UniversalLLMAdapter.ts
4582
+ function extractContent(obj) {
4583
+ var _a2, _b, _c;
4584
+ if (!obj || typeof obj !== "object") return void 0;
4585
+ const choice = (_a2 = obj.choices) == null ? void 0 : _a2[0];
4586
+ if (!choice) return void 0;
4587
+ if (typeof ((_b = choice.message) == null ? void 0 : _b.content) === "string") return choice.message.content;
4588
+ if (typeof ((_c = choice.delta) == null ? void 0 : _c.content) === "string") return choice.delta.content;
4589
+ if (typeof choice.text === "string") return choice.text;
4590
+ if (typeof choice.content === "string") return choice.content;
4591
+ return void 0;
4592
+ }
3979
4593
  var UniversalLLMAdapter = class {
3980
4594
  constructor(config) {
3981
4595
  var _a2, _b, _c, _d, _e, _f, _g2, _h;
@@ -4007,7 +4621,7 @@ var UniversalLLMAdapter = class {
4007
4621
  });
4008
4622
  }
4009
4623
  async chat(messages, context) {
4010
- var _a2, _b, _c, _d, _e, _f;
4624
+ var _a2, _b, _c;
4011
4625
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4012
4626
  const formattedMessages = [
4013
4627
  { role: "system", content: `${this.systemPrompt}
@@ -4035,25 +4649,41 @@ ${context != null ? context : "None"}` },
4035
4649
  const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4036
4650
  if (isSelfHost || Boolean(process.env.VERCEL)) {
4037
4651
  const _g2 = globalThis;
4038
- if (typeof _g2.__retrivoraDispatchChat === "function") {
4652
+ let dispatch = _g2.__retrivoraDispatchChat;
4653
+ if (typeof dispatch !== "function") {
4039
4654
  try {
4040
- const res = await _g2.__retrivoraDispatchChat({
4655
+ const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
4656
+ if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
4657
+ _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4658
+ _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4659
+ dispatch = gateway.dispatchChatCompletion;
4660
+ }
4661
+ } catch (e) {
4662
+ }
4663
+ }
4664
+ if (typeof dispatch === "function") {
4665
+ try {
4666
+ const res = await dispatch({
4041
4667
  model: this.model,
4042
4668
  messages: formattedMessages,
4043
4669
  max_tokens: this.maxTokens,
4044
4670
  temperature: this.temperature
4045
4671
  }, this.apiKey);
4046
- if ((_e = (_d = (_c = (_b = res == null ? void 0 : res.response) == null ? void 0 : _b.choices) == null ? void 0 : _c[0]) == null ? void 0 : _d.message) == null ? void 0 : _e.content) {
4047
- return res.response.choices[0].message.content;
4672
+ const content = extractContent(res == null ? void 0 : res.response);
4673
+ if (content !== void 0) {
4674
+ return content;
4048
4675
  }
4676
+ throw new Error(`[UniversalLLMAdapter] In-process dispatch returned empty content for model: ${this.model}`);
4049
4677
  } catch (dispatchErr) {
4050
4678
  throw dispatchErr;
4051
4679
  }
4680
+ } else {
4681
+ throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
4052
4682
  }
4053
4683
  }
4054
4684
  const { data } = await this.http.post(path2, payload);
4055
- const extractPath = (_f = this.opts.responseExtractPath) != null ? _f : "choices[0].message.content";
4056
- const result = resolvePath(data, extractPath);
4685
+ const extractPath = (_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content";
4686
+ const result = (_c = resolvePath(data, extractPath)) != null ? _c : extractContent(data);
4057
4687
  if (result === void 0) {
4058
4688
  throw new Error(`[UniversalLLMAdapter] Could not extract text from path '${extractPath}' in response.`);
4059
4689
  }
@@ -4066,7 +4696,7 @@ ${context != null ? context : "None"}` },
4066
4696
  */
4067
4697
  chatStream(messages, context) {
4068
4698
  return __asyncGenerator(this, null, function* () {
4069
- var _a2, _b, _c, _d, _e, _f, _g2;
4699
+ var _a2, _b, _c, _d, _e;
4070
4700
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4071
4701
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4072
4702
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
@@ -4100,10 +4730,22 @@ ${context != null ? context : "None"}` },
4100
4730
  const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4101
4731
  let streamBody = null;
4102
4732
  if (isSelfHost || Boolean(process.env.VERCEL)) {
4103
- const _g3 = globalThis;
4104
- if (typeof _g3.__retrivoraDispatchChat === "function") {
4733
+ const _g2 = globalThis;
4734
+ let dispatch = _g2.__retrivoraDispatchChat;
4735
+ if (typeof dispatch !== "function") {
4736
+ try {
4737
+ const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
4738
+ if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
4739
+ _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4740
+ _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4741
+ dispatch = gateway.dispatchChatCompletion;
4742
+ }
4743
+ } catch (e) {
4744
+ }
4745
+ }
4746
+ if (typeof dispatch === "function") {
4105
4747
  try {
4106
- const res = yield new __await(_g3.__retrivoraDispatchChat({
4748
+ const res = yield new __await(dispatch({
4107
4749
  model: this.model,
4108
4750
  messages: formattedMessages,
4109
4751
  max_tokens: this.maxTokens,
@@ -4112,13 +4754,19 @@ ${context != null ? context : "None"}` },
4112
4754
  }, this.apiKey));
4113
4755
  if (res == null ? void 0 : res.stream) {
4114
4756
  streamBody = res.stream;
4115
- } else if ((_f = (_e = (_d = (_c = res == null ? void 0 : res.response) == null ? void 0 : _c.choices) == null ? void 0 : _d[0]) == null ? void 0 : _e.message) == null ? void 0 : _f.content) {
4116
- yield res.response.choices[0].message.content;
4117
- return;
4757
+ } else {
4758
+ const content = extractContent(res == null ? void 0 : res.response);
4759
+ if (content !== void 0) {
4760
+ yield content;
4761
+ return;
4762
+ }
4763
+ throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
4118
4764
  }
4119
4765
  } catch (dispatchErr) {
4120
4766
  throw dispatchErr;
4121
4767
  }
4768
+ } else {
4769
+ throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
4122
4770
  }
4123
4771
  }
4124
4772
  if (!streamBody) {
@@ -4145,14 +4793,14 @@ ${context != null ? context : "None"}` },
4145
4793
  if (done) break;
4146
4794
  buffer += decoder.decode(value, { stream: true });
4147
4795
  const lines = buffer.split("\n");
4148
- buffer = (_g2 = lines.pop()) != null ? _g2 : "";
4796
+ buffer = (_c = lines.pop()) != null ? _c : "";
4149
4797
  for (const line of lines) {
4150
4798
  const trimmed = line.trim();
4151
4799
  if (!trimmed || trimmed === "data: [DONE]") continue;
4152
4800
  if (!trimmed.startsWith("data:")) continue;
4153
4801
  try {
4154
4802
  const json = JSON.parse(trimmed.slice(5).trim());
4155
- const text = resolvePath(json, extractPath);
4803
+ const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
4156
4804
  if (text && typeof text === "string") yield text;
4157
4805
  } catch (e) {
4158
4806
  }
@@ -4162,7 +4810,7 @@ ${context != null ? context : "None"}` },
4162
4810
  const jsonStr = buffer.replace(/^data:\s*/, "").trim();
4163
4811
  try {
4164
4812
  const json = JSON.parse(jsonStr);
4165
- const text = resolvePath(json, extractPath);
4813
+ const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
4166
4814
  if (text && typeof text === "string") yield text;
4167
4815
  } catch (e) {
4168
4816
  }
@@ -4190,18 +4838,33 @@ ${context != null ? context : "None"}` },
4190
4838
  const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4191
4839
  if (isSelfHost || Boolean(process.env.VERCEL)) {
4192
4840
  const _g2 = globalThis;
4193
- if (typeof _g2.__retrivoraDispatchEmbedding === "function") {
4841
+ let dispatch = _g2.__retrivoraDispatchEmbedding;
4842
+ if (typeof dispatch !== "function") {
4194
4843
  try {
4195
- const res = await _g2.__retrivoraDispatchEmbedding({
4844
+ const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
4845
+ if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
4846
+ _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4847
+ _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4848
+ dispatch = gateway.dispatchEmbedding;
4849
+ }
4850
+ } catch (e) {
4851
+ }
4852
+ }
4853
+ if (typeof dispatch === "function") {
4854
+ try {
4855
+ const res = await dispatch({
4196
4856
  model: this.model,
4197
4857
  input: text
4198
4858
  }, this.apiKey);
4199
4859
  if ((_c = (_b = res == null ? void 0 : res.data) == null ? void 0 : _b[0]) == null ? void 0 : _c.embedding) {
4200
4860
  return res.data[0].embedding;
4201
4861
  }
4862
+ throw new Error(`[UniversalLLMAdapter] In-process embedding dispatch returned invalid vector for model: ${this.model}`);
4202
4863
  } catch (dispatchErr) {
4203
4864
  throw dispatchErr;
4204
4865
  }
4866
+ } else {
4867
+ throw new Error(`[UniversalLLMAdapter] In-process gateway dispatch not registered. Direct self-referential HTTP calls to ${this.baseUrl} are disabled on Vercel to prevent HTTP 508 Loop Detected.`);
4205
4868
  }
4206
4869
  }
4207
4870
  const { data } = await this.http.post(path2, payload);
@@ -7063,7 +7726,7 @@ ${schemaProfileText}` : ""}`;
7063
7726
  }
7064
7727
  // ─── Transform Helpers ────────────────────────────────────────────────────
7065
7728
  static transformToProductCarousel(data, config, trainedSchema) {
7066
- const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null).slice(0, 15);
7729
+ const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
7067
7730
  return {
7068
7731
  type: "product_carousel",
7069
7732
  title: "Recommended Products",
@@ -7443,7 +8106,8 @@ ${schemaProfileText}` : ""}`;
7443
8106
  return fieldCount.size > 2;
7444
8107
  }
7445
8108
  static profileData(data) {
7446
- const records = data.map((item) => {
8109
+ const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
8110
+ var _a2, _b;
7447
8111
  const fields2 = {};
7448
8112
  Object.entries(item.metadata || {}).forEach(([key, value]) => {
7449
8113
  const primitive = this.toPrimitive(value);
@@ -7452,8 +8116,8 @@ ${schemaProfileText}` : ""}`;
7452
8116
  if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
7453
8117
  return {
7454
8118
  id: item.id,
7455
- content: item.content,
7456
- score: item.score,
8119
+ content: (_a2 = item.content) != null ? _a2 : "",
8120
+ score: (_b = item.score) != null ? _b : 0,
7457
8121
  fields: fields2,
7458
8122
  source: item
7459
8123
  };
@@ -8556,7 +9220,7 @@ ${m.content}`).join("\n\n---\n\n");
8556
9220
  */
8557
9221
  askStreamInternal(_0) {
8558
9222
  return __asyncGenerator(this, arguments, function* (question, history = [], namespace) {
8559
- var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C;
9223
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B;
8560
9224
  yield new __await(this.initialize());
8561
9225
  const ns = formatNamespace(namespace != null ? namespace : this.config.projectId);
8562
9226
  const topK = (_b = (_a2 = this.config.rag) == null ? void 0 : _a2.topK) != null ? _b : 5;
@@ -8599,8 +9263,8 @@ ${m.content}`).join("\n\n---\n\n");
8599
9263
  const graphData = (strategyResult === "graph" || strategyResult === "both") && this.graphDB && ((_l = this.config.rag) == null ? void 0 : _l.useGraphRetrieval) ? yield new __await(this.graphDB.query(searchQuery)) : void 0;
8600
9264
  const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
8601
9265
  const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
8602
- const wantsExhaustiveList = hasNumericPredicates || hasMetadataFilter || /\b(list|all|show|provide|give|get|browse|find|search|display)\b/i.test(question);
8603
- const retrievalLimit = wantsExhaustiveList ? Math.max(topK * 20, 100) : topK * 2;
9266
+ const wantsExhaustiveList = true;
9267
+ const retrievalLimit = Math.max(topK * 50, 1e3);
8604
9268
  const rawSources = ((strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : []).filter((s) => Boolean(s && typeof s === "object"));
8605
9269
  console.log("[Pipeline] Raw vectorDB.query response:", {
8606
9270
  rawCount: rawSources.length,
@@ -8624,40 +9288,29 @@ ${m.content}`).join("\n\n---\n\n");
8624
9288
  var _a3;
8625
9289
  return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= scoreThreshold;
8626
9290
  });
8627
- const rerankLimit = wantsExhaustiveList ? retrievalLimit : topK;
9291
+ const rerankLimit = Math.max(retrievalLimit, fullSources.length);
8628
9292
  const useReranking = arch !== "naive" && (arch === "retrieve-and-rerank" || ((_m = this.config.rag) == null ? void 0 : _m.useReranking));
8629
9293
  if (!hasNumericPredicates && useReranking) {
8630
9294
  fullSources = (yield new __await(this.reranker.rerank(fullSources, question, rerankLimit))).filter((s) => Boolean(s && typeof s === "object"));
8631
- } else if (!wantsExhaustiveList) {
8632
- fullSources = fullSources.slice(0, topK);
8633
9295
  }
8634
9296
  const rerankMs = performance.now() - rerankStart;
8635
- let context = fullSources.length ? fullSources.map((m, i) => {
9297
+ const totalCount = fullSources.length;
9298
+ const promptSources = fullSources.slice(0, 15);
9299
+ 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]
9300
+
9301
+ ` + promptSources.map((m, i) => {
8636
9302
  var _a3;
8637
9303
  return `[Source ${i + 1}]
8638
9304
  ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
8639
9305
  }).join("\n\n---\n\n") : "No relevant context found.";
8640
- let displayCount = 15;
8641
- if (hasMetadataFilter) {
8642
- displayCount = fullSources.length;
8643
- } else {
8644
- const baseThreshold = Math.max(scoreThreshold, 0.4);
8645
- const highlyRelevant = fullSources.filter((m) => {
8646
- var _a3;
8647
- return ((_a3 = m == null ? void 0 : m.score) != null ? _a3 : 0) >= baseThreshold;
8648
- });
8649
- displayCount = Math.max(highlyRelevant.length, topK);
8650
- if (displayCount > 15) {
8651
- displayCount = 15;
8652
- }
8653
- }
8654
9306
  const sources = [...fullSources].filter((s) => Boolean(s && typeof s === "object")).sort((a, b) => {
8655
9307
  var _a3, _b2;
8656
9308
  return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
8657
- }).slice(0, displayCount);
9309
+ });
8658
9310
  console.log("[Pipeline] Final sources for prompt & UI:", {
8659
9311
  count: sources.length,
8660
- sources: sources.map((s, idx) => {
9312
+ totalRawCount: rawSources.length,
9313
+ sources: sources.slice(0, 10).map((s, idx) => {
8661
9314
  var _a3;
8662
9315
  return {
8663
9316
  rank: idx + 1,
@@ -8857,7 +9510,7 @@ ${context}`;
8857
9510
  }
8858
9511
  yield fullReply;
8859
9512
  }
8860
- const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true || this.config.llm.provider !== "ollama" && ((_x = this.config.llm.options) == null ? void 0 : _x.hallucinationScoring) !== false;
9513
+ const runHallucination = ((_w = this.config.llm.options) == null ? void 0 : _w.hallucinationScoring) === true;
8861
9514
  if (runHallucination) {
8862
9515
  hallucinationScoringPromise = scoreHallucination(this.llmProvider, fullReply, context).catch(() => void 0);
8863
9516
  }
@@ -8866,7 +9519,7 @@ ${context}`;
8866
9519
  const latency = {
8867
9520
  embedMs: Math.round(embedMs),
8868
9521
  retrieveMs: Math.round(retrieveMs),
8869
- rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_y = this.config.rag) == null ? void 0 : _y.useReranking)) ? Math.round(rerankMs) : void 0,
9522
+ rerankMs: arch !== "naive" && (arch === "retrieve-and-rerank" || ((_x = this.config.rag) == null ? void 0 : _x.useReranking)) ? Math.round(rerankMs) : void 0,
8870
9523
  generateMs: Math.round(generateMs),
8871
9524
  totalMs: Math.round(totalMs)
8872
9525
  };
@@ -8879,7 +9532,7 @@ ${context}`;
8879
9532
  totalTokens: promptTokens + completionTokens,
8880
9533
  estimatedCostUsd: estimateCostUsd(promptTokens, completionTokens, this.config.llm.model)
8881
9534
  };
8882
- const awaitHallucination = ((_z = this.config.llm.options) == null ? void 0 : _z.awaitHallucination) === true;
9535
+ const awaitHallucination = ((_y = this.config.llm.options) == null ? void 0 : _y.awaitHallucination) === true;
8883
9536
  const [uiTransformation, hallucinationResult] = yield new __await(Promise.all([
8884
9537
  uiTransformationPromise,
8885
9538
  awaitHallucination ? hallucinationScoringPromise : Promise.resolve(void 0)
@@ -8908,10 +9561,10 @@ ${context}`;
8908
9561
  hallucinationReason: hScore.reason
8909
9562
  } : {});
8910
9563
  const trace = buildTrace(hallucinationResult);
8911
- const isTelemetryActive = (_B = (_A = this.config.telemetry) == null ? void 0 : _A.enabled) != null ? _B : Boolean(this.config.licenseKey);
9564
+ const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
8912
9565
  if (isTelemetryActive) {
8913
9566
  const defaultUrl = process.env.NODE_ENV === "development" && !process.env.TELEMETRY_URL && !process.env.NEXT_PUBLIC_TELEMETRY_URL ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry";
8914
- const telemetryUrl = ((_C = this.config.telemetry) == null ? void 0 : _C.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
9567
+ const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
8915
9568
  const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
8916
9569
  (async () => {
8917
9570
  try {
@@ -8970,9 +9623,8 @@ ${context}`;
8970
9623
  { visualizationHint: "product_browse", recommendedChart: "text", filterInStockOnly: false, wantsExplicitTable: false, isTemporal: false, isComparison: false, language: "en" }
8971
9624
  );
8972
9625
  }
8973
- const isLocalProvider = this.config.llm.provider === "ollama";
8974
- const disableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.disableLlmUiTransform) === true;
8975
- if (forceDeterministic || isLocalProvider || disableLlmUiTransform) {
9626
+ const enableLlmUiTransform = ((_a2 = this.config.llm.options) == null ? void 0 : _a2.enableLlmUiTransform) === true;
9627
+ if (forceDeterministic || !enableLlmUiTransform) {
8976
9628
  return UITransformer.transform(question, sources, this.config, cachedSchema);
8977
9629
  }
8978
9630
  try {