@retrivora-ai/rag-engine 2.2.4 → 2.2.6

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.
@@ -121,644 +121,6 @@ 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("LLM service credentials not configured.");
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 resolveUserGatewayConfig(apiKeyOverride) {
595
- var _a2;
596
- if (!apiKeyOverride || !process.env.NEXT_PUBLIC_SUPABASE_URL || !process.env.SUPABASE_SERVICE_ROLE_KEY) {
597
- return {};
598
- }
599
- try {
600
- const { createAdminClient } = await import("@/lib/supabase-server");
601
- const supabase = createAdminClient();
602
- const { data: licenseRecord } = await supabase.from("licenses").select("project_id, customer_name, tier").eq("license_key", apiKeyOverride.trim()).single();
603
- if (!licenseRecord) {
604
- return {};
605
- }
606
- const projectId = licenseRecord.project_id;
607
- const { data: configs } = await supabase.from("gateway_config").select("project_id, default_model, provider_keys, is_active").in("project_id", [projectId, "global"]).eq("is_active", true);
608
- if (!configs || configs.length === 0) {
609
- return {};
610
- }
611
- const matchedConfig = configs.find((c) => c.project_id === projectId) || configs.find((c) => c.project_id === "global");
612
- const customGroqKey = (_a2 = matchedConfig == null ? void 0 : matchedConfig.provider_keys) == null ? void 0 : _a2.groq;
613
- const targetModel = matchedConfig == null ? void 0 : matchedConfig.default_model;
614
- return { customGroqKey, targetModel };
615
- } catch (err) {
616
- console.warn("[LLM Gateway Router] Error resolving user gateway_config:", err.message);
617
- return {};
618
- }
619
- }
620
- async function dispatchChatCompletion(req, apiKeyOverride) {
621
- const { customGroqKey, targetModel } = await resolveUserGatewayConfig(apiKeyOverride);
622
- const effectiveKey = customGroqKey || cleanApiKeyOverride(apiKeyOverride);
623
- const activeModel = req.model || targetModel || "llama-3.1-8b-instant";
624
- const provider = resolveProvider(activeModel);
625
- try {
626
- switch (provider) {
627
- case "groq":
628
- return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
629
- case "openai":
630
- return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
631
- case "gemini":
632
- return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
633
- case "anthropic":
634
- return await handleAnthropicRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
635
- case "ollama":
636
- return await handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }));
637
- case "huggingface":
638
- return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
639
- default:
640
- throw new Error(`Unsupported LLM provider for model: ${activeModel}`);
641
- }
642
- } catch (error) {
643
- console.error(`[LLM Gateway Router] Provider '${provider}' failed for model '${req.model}':`, {
644
- message: error.message,
645
- stack: error.stack
646
- });
647
- if (/rate[- ]?limit|429|exhausted/i.test(error.message)) {
648
- const isGroqKey = process.env.GROQ_API_KEY || effectiveKey && effectiveKey.startsWith("gsk_");
649
- const reqModelLower = req.model.toLowerCase();
650
- if (isGroqKey && !reqModelLower.includes("llama-3.3-70b")) {
651
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to secondary Groq model (llama-3.3-70b-versatile)...`);
652
- try {
653
- return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: "llama-3.3-70b-versatile" }), effectiveKey);
654
- } catch (fErr) {
655
- console.error("[LLM Gateway] Fallback groq/llama-3.3-70b-versatile failed:", fErr.message);
656
- }
657
- }
658
- const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
659
- if (provider !== "gemini" && geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ."))) {
660
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Google Gemini (gemini-2.5-flash)...`);
661
- try {
662
- return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: "gemini-2.5-flash" }), effectiveKey);
663
- } catch (fErr) {
664
- console.error("[LLM Gateway] Fallback gemini-2.5-flash failed:", fErr.message);
665
- }
666
- }
667
- if (provider !== "huggingface" && (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY)) {
668
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Hugging Face (Qwen/Qwen2.5-Coder-32B-Instruct)...`);
669
- try {
670
- return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: "Qwen/Qwen2.5-Coder-32B-Instruct" }), effectiveKey);
671
- } catch (fErr) {
672
- console.error("[LLM Gateway] Fallback HuggingFace Qwen failed:", fErr.message);
673
- }
674
- }
675
- if (provider !== "openai" && process.env.OPENAI_API_KEY) {
676
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to OpenAI (gpt-4o-mini)...`);
677
- try {
678
- return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: "gpt-4o-mini" }), effectiveKey);
679
- } catch (e) {
680
- }
681
- }
682
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to local Ollama (llama3.2)...`);
683
- return handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: "llama3.2" }));
684
- }
685
- throw error;
686
- }
687
- }
688
- async function dispatchEmbedding(req, apiKeyOverride) {
689
- const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
690
- if (req.model.startsWith("hf/") || req.model.startsWith("huggingface/") || req.model.includes("bge-")) {
691
- try {
692
- return await handleHuggingFaceEmbedding(req, effectiveKey);
693
- } catch (err) {
694
- console.warn("[LLM Gateway] HuggingFace explicit model embedding failed, falling back to default gateway chain:", err);
695
- }
696
- }
697
- const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
698
- const isGeminiKeyValid = Boolean(geminiKey && !geminiKey.startsWith("eyJ"));
699
- if (isGeminiKeyValid) {
700
- try {
701
- return await handleGeminiEmbedding(req, effectiveKey);
702
- } catch (err) {
703
- console.warn("[LLM Gateway] Gemini embedding failed:", err);
704
- }
705
- }
706
- if (process.env.OPENAI_API_KEY) {
707
- try {
708
- return await handleOpenAIEmbedding(req, effectiveKey);
709
- } catch (err) {
710
- console.warn("[LLM Gateway] OpenAI embedding failed:", err);
711
- }
712
- }
713
- if (process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN) {
714
- try {
715
- return await handleHuggingFaceEmbedding(req, effectiveKey);
716
- } catch (err) {
717
- console.warn("[LLM Gateway] HuggingFace fallback embedding failed:", err);
718
- }
719
- }
720
- return handleGeminiEmbedding(req, effectiveKey);
721
- }
722
- var SUPPORTED_MODELS;
723
- var init_router = __esm({
724
- "../../services/llm-gateway/router.ts"() {
725
- "use strict";
726
- init_groq();
727
- init_openai();
728
- init_gemini();
729
- init_huggingface();
730
- init_anthropic();
731
- init_ollama();
732
- SUPPORTED_MODELS = [
733
- { id: "groq/llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
734
- { id: "llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
735
- { id: "groq/llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
736
- { id: "llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
737
- { id: "gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
738
- { id: "openai/gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
739
- { id: "gpt-4o", object: "model", created: 17e8, owned_by: "openai" },
740
- { id: "gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
741
- { id: "google/gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
742
- { id: "claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
743
- { id: "anthropic/claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
744
- { id: "text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
745
- { id: "google/text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
746
- { id: "BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
747
- { id: "huggingface/BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
748
- { id: "groq/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
749
- { id: "qwen/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
750
- { id: "qwen/qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
751
- { id: "qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
752
- { id: "ollama/llama3.2", object: "model", created: 17e8, owned_by: "ollama" }
753
- ];
754
- if (typeof globalThis !== "undefined") {
755
- const _g2 = globalThis;
756
- _g2.__retrivoraDispatchChat = dispatchChatCompletion;
757
- _g2.__retrivoraDispatchEmbedding = dispatchEmbedding;
758
- }
759
- }
760
- });
761
-
762
124
  // src/providers/vectordb/BaseVectorProvider.ts
763
125
  var BaseVectorProvider;
764
126
  var init_BaseVectorProvider = __esm({
@@ -815,8 +177,8 @@ var init_ConfigFetcher = __esm({
815
177
  process.env.NEXT_PUBLIC_RETRIVORA_CONTROL_PLANE_URL,
816
178
  "https://www.retrivora.com",
817
179
  "https://retrivora.com",
818
- "http://localhost:3001",
819
- "http://localhost:3000"
180
+ "http://localhost:3000",
181
+ "http://localhost:3001"
820
182
  ].filter(Boolean);
821
183
  for (const baseUrl of controlPlaneUrls) {
822
184
  try {
@@ -3391,7 +2753,7 @@ function getEnvConfig(env = process.env, base) {
3391
2753
  },
3392
2754
  telemetry: {
3393
2755
  enabled: telemetryEnabled,
3394
- url: (_Kb = (_Jb = (_Hb = readString(env, "TELEMETRY_URL")) != null ? _Hb : readString(env, "NEXT_PUBLIC_TELEMETRY_URL")) != null ? _Jb : (_Ib = base == null ? void 0 : base.telemetry) == null ? void 0 : _Ib.url) != null ? _Kb : process.env.NODE_ENV === "development" ? "http://localhost:3001/api/telemetry" : "https://retrivora.com/api/telemetry"
2756
+ url: (_Kb = (_Jb = (_Hb = readString(env, "TELEMETRY_URL")) != null ? _Hb : readString(env, "NEXT_PUBLIC_TELEMETRY_URL")) != null ? _Jb : (_Ib = base == null ? void 0 : base.telemetry) == null ? void 0 : _Ib.url) != null ? _Kb : "https://www.retrivora.com/api/telemetry"
3395
2757
  }
3396
2758
  }, readString(env, "GRAPH_DB_PROVIDER") ? {
3397
2759
  graphDb: {
@@ -4640,9 +4002,7 @@ var OPENAI_BASE = {
4640
4002
  };
4641
4003
  var LLM_PROFILES = {
4642
4004
  "openai-compatible": OPENAI_BASE,
4643
- "litellm": __spreadProps(__spreadValues({}, OPENAI_BASE), {
4644
- chatPayloadTemplate: '{"model":"{{model}}","messages":{{messages}},"max_tokens":{{maxTokens}},"temperature":{{temperature}},"stream":false}'
4645
- }),
4005
+ "litellm": __spreadValues({}, OPENAI_BASE),
4646
4006
  "anthropic-claude": {
4647
4007
  chatPath: "/v1/messages",
4648
4008
  responseExtractPath: "content[0].text",
@@ -4748,18 +4108,7 @@ ${context != null ? context : "None"}` },
4748
4108
  }
4749
4109
  } catch (httpErr) {
4750
4110
  const _g2 = globalThis;
4751
- let dispatch = _g2.__retrivoraDispatchChat;
4752
- if (typeof dispatch !== "function") {
4753
- try {
4754
- const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
4755
- if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
4756
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4757
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4758
- dispatch = gateway.dispatchChatCompletion;
4759
- }
4760
- } catch (e) {
4761
- }
4762
- }
4111
+ const dispatch = _g2.__retrivoraDispatchChat;
4763
4112
  if (typeof dispatch === "function") {
4764
4113
  const res = await dispatch({
4765
4114
  model: this.model,
@@ -4785,11 +4134,10 @@ ${context != null ? context : "None"}` },
4785
4134
  /**
4786
4135
  * Streaming chat using native fetch + ReadableStream.
4787
4136
  * Parses OpenAI-compatible SSE frames: `data: {...}\n\n`
4788
- * Works with vLLM, LMStudio, Together AI, Fireworks, and any OpenAI-compatible API.
4789
4137
  */
4790
4138
  chatStream(messages, context) {
4791
4139
  return __asyncGenerator(this, null, function* () {
4792
- var _a2, _b, _c, _d, _e;
4140
+ var _a2, _b, _c, _d, _e, _f;
4793
4141
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4794
4142
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4795
4143
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
@@ -4824,22 +4172,35 @@ ${context != null ? context : "None"}` },
4824
4172
  stream: true
4825
4173
  };
4826
4174
  }
4827
- const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4828
4175
  let streamBody = null;
4829
- if (isSelfHost || Boolean(process.env.VERCEL)) {
4830
- const _g2 = globalThis;
4831
- let dispatch = _g2.__retrivoraDispatchChat;
4832
- if (typeof dispatch !== "function") {
4833
- try {
4834
- const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
4835
- if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
4836
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4837
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4838
- dispatch = gateway.dispatchChatCompletion;
4176
+ try {
4177
+ const response = yield new __await(fetch(url, {
4178
+ method: "POST",
4179
+ headers: this.resolvedHeaders,
4180
+ body: typeof payload === "string" ? payload : JSON.stringify(payload)
4181
+ }));
4182
+ if (response.ok) {
4183
+ const contentType = response.headers.get("content-type") || "";
4184
+ if (contentType.includes("application/json")) {
4185
+ const json = yield new __await(response.json());
4186
+ const text = (_c = resolvePath(json, extractPath)) != null ? _c : extractContent(json);
4187
+ if (text && typeof text === "string") {
4188
+ yield text;
4189
+ return;
4839
4190
  }
4840
- } catch (e) {
4191
+ } else if (response.body) {
4192
+ streamBody = response.body;
4841
4193
  }
4194
+ } else {
4195
+ const errorText = yield new __await(response.text().catch(() => response.statusText));
4196
+ console.warn(`[UniversalLLMAdapter] Remote HTTP stream returned ${response.status}: ${errorText}. Attempting in-process fallback...`);
4842
4197
  }
4198
+ } catch (fetchErr) {
4199
+ console.warn(`[UniversalLLMAdapter] Remote HTTP stream fetch warning: ${fetchErr == null ? void 0 : fetchErr.message}. Attempting in-process fallback...`);
4200
+ }
4201
+ if (!streamBody) {
4202
+ const _g2 = globalThis;
4203
+ const dispatch = _g2.__retrivoraDispatchChat;
4843
4204
  if (typeof dispatch === "function") {
4844
4205
  try {
4845
4206
  const res = yield new __await(dispatch({
@@ -4857,29 +4218,14 @@ ${context != null ? context : "None"}` },
4857
4218
  yield content;
4858
4219
  return;
4859
4220
  }
4860
- throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
4861
4221
  }
4862
4222
  } catch (dispatchErr) {
4863
- throw dispatchErr;
4223
+ console.warn("[UniversalLLMAdapter] In-process dispatch error:", dispatchErr);
4864
4224
  }
4865
- } else {
4866
- 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.`);
4867
4225
  }
4868
4226
  }
4869
4227
  if (!streamBody) {
4870
- const response = yield new __await(fetch(url, {
4871
- method: "POST",
4872
- headers: this.resolvedHeaders,
4873
- body: JSON.stringify(payload)
4874
- }));
4875
- if (!response.ok) {
4876
- const errorText = yield new __await(response.text().catch(() => response.statusText));
4877
- throw new Error(`[UniversalLLMAdapter] Streaming request failed (${response.status}): ${errorText}`);
4878
- }
4879
- if (!response.body) {
4880
- throw new Error("[UniversalLLMAdapter] Response body is null \u2014 server did not send a streaming response.");
4881
- }
4882
- streamBody = response.body;
4228
+ throw new Error(`[UniversalLLMAdapter] Streaming request failed. Ensure RETRIVORA_LICENSE_KEY is valid or LLM service is available.`);
4883
4229
  }
4884
4230
  const reader = streamBody.getReader();
4885
4231
  const decoder = new TextDecoder("utf-8");
@@ -4890,14 +4236,14 @@ ${context != null ? context : "None"}` },
4890
4236
  if (done) break;
4891
4237
  buffer += decoder.decode(value, { stream: true });
4892
4238
  const lines = buffer.split("\n");
4893
- buffer = (_c = lines.pop()) != null ? _c : "";
4239
+ buffer = (_d = lines.pop()) != null ? _d : "";
4894
4240
  for (const line of lines) {
4895
4241
  const trimmed = line.trim();
4896
4242
  if (!trimmed || trimmed === "data: [DONE]") continue;
4897
4243
  if (!trimmed.startsWith("data:")) continue;
4898
4244
  try {
4899
4245
  const json = JSON.parse(trimmed.slice(5).trim());
4900
- const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
4246
+ const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
4901
4247
  if (text && typeof text === "string") yield text;
4902
4248
  } catch (e) {
4903
4249
  }
@@ -4907,7 +4253,7 @@ ${context != null ? context : "None"}` },
4907
4253
  const jsonStr = buffer.replace(/^data:\s*/, "").trim();
4908
4254
  try {
4909
4255
  const json = JSON.parse(jsonStr);
4910
- const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
4256
+ const text = (_f = resolvePath(json, extractPath)) != null ? _f : extractContent(json);
4911
4257
  if (text && typeof text === "string") yield text;
4912
4258
  } catch (e) {
4913
4259
  }
@@ -4920,74 +4266,42 @@ ${context != null ? context : "None"}` },
4920
4266
  async embed(text) {
4921
4267
  var _a2, _b, _c, _d, _e;
4922
4268
  const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
4923
- let payload;
4924
- if (this.opts.embedPayloadTemplate) {
4925
- payload = buildPayload(this.opts.embedPayloadTemplate, {
4926
- model: this.model,
4927
- input: text
4928
- });
4929
- } else {
4930
- payload = {
4931
- model: this.model,
4932
- input: text
4933
- };
4934
- }
4269
+ const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
4935
4270
  try {
4936
4271
  const { data: data2 } = await this.http.post(path2, payload);
4937
4272
  const extractPath2 = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
4938
4273
  const vector2 = resolvePath(data2, extractPath2);
4939
- if (Array.isArray(vector2)) {
4940
- return vector2;
4941
- }
4942
- } catch (httpErr) {
4943
- console.warn(`[UniversalLLMAdapter] Direct HTTP embedding POST to ${this.baseUrl}${path2} failed (${httpErr.message}). Attempting in-process gateway dispatch fallback...`);
4274
+ if (Array.isArray(vector2)) return vector2;
4275
+ } catch (e) {
4944
4276
  const _g2 = globalThis;
4945
- let dispatch = _g2.__retrivoraDispatchEmbedding;
4946
- if (typeof dispatch !== "function") {
4947
- try {
4948
- const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
4949
- if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
4950
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4951
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4952
- dispatch = gateway.dispatchEmbedding;
4953
- }
4954
- } catch (e) {
4955
- }
4956
- }
4957
- if (typeof dispatch === "function") {
4958
- const res = await dispatch({
4959
- model: this.model,
4960
- input: text
4961
- }, this.apiKey);
4277
+ const dispatchEmbed = _g2.__retrivoraDispatchEmbedding;
4278
+ if (typeof dispatchEmbed === "function") {
4279
+ const res = await dispatchEmbed({ input: text, model: this.model }, this.apiKey);
4962
4280
  if ((_d = (_c = res == null ? void 0 : res.data) == null ? void 0 : _c[0]) == null ? void 0 : _d.embedding) {
4963
4281
  return res.data[0].embedding;
4964
4282
  }
4965
4283
  }
4966
- throw httpErr;
4967
4284
  }
4968
4285
  const { data } = await this.http.post(path2, payload);
4969
4286
  const extractPath = (_e = this.opts.embedExtractPath) != null ? _e : "data[0].embedding";
4970
4287
  const vector = resolvePath(data, extractPath);
4971
4288
  if (!Array.isArray(vector)) {
4972
- throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
4289
+ throw new Error(`[UniversalLLMAdapter] Could not extract embedding vector from path '${extractPath}' in response.`);
4973
4290
  }
4974
4291
  return vector;
4975
4292
  }
4976
4293
  async batchEmbed(texts) {
4977
- const vectors = [];
4294
+ const results = [];
4978
4295
  for (const text of texts) {
4979
- vectors.push(await this.embed(text));
4296
+ results.push(await this.embed(text));
4980
4297
  }
4981
- return vectors;
4298
+ return results;
4982
4299
  }
4983
4300
  async ping() {
4984
4301
  try {
4985
- if (this.opts.pingPath) {
4986
- await this.http.get(this.opts.pingPath);
4987
- }
4302
+ await this.embed("ping");
4988
4303
  return true;
4989
- } catch (err) {
4990
- console.error("[UniversalLLMAdapter] Ping failed:", err);
4304
+ } catch (e) {
4991
4305
  return false;
4992
4306
  }
4993
4307
  }
@@ -5393,7 +4707,7 @@ var ConfigValidator = class {
5393
4707
  // package.json
5394
4708
  var package_default = {
5395
4709
  name: "@retrivora-ai/rag-engine",
5396
- version: "2.2.4",
4710
+ version: "2.2.6",
5397
4711
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
5398
4712
  author: "Abhinav Alkuchi",
5399
4713
  license: "UNLICENSED",
@@ -5430,6 +4744,8 @@ var package_default = {
5430
4744
  import: "./dist/index.mjs"
5431
4745
  },
5432
4746
  "./style.css": "./dist/index.css",
4747
+ "./index.css": "./dist/index.css",
4748
+ "./styles.css": "./dist/index.css",
5433
4749
  "./handlers": {
5434
4750
  types: "./dist/handlers/index.d.ts",
5435
4751
  require: "./dist/handlers/index.js",
@@ -7598,19 +6914,6 @@ var UITransformer = class _UITransformer {
7598
6914
  if (!retrievedData || retrievedData.length === 0) {
7599
6915
  return this.createTextResponse("No data available", "No relevant data found for your query.");
7600
6916
  }
7601
- console.log("[UITransformer.transform] Processing retrievedData:", {
7602
- userQuery,
7603
- retrievedCount: retrievedData.length,
7604
- sample: retrievedData.slice(0, 2).map((item) => {
7605
- var _a3;
7606
- return {
7607
- id: item == null ? void 0 : item.id,
7608
- contentType: typeof (item == null ? void 0 : item.content),
7609
- contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
7610
- metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
7611
- };
7612
- })
7613
- });
7614
6917
  const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
7615
6918
  const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
7616
6919
  const profile = this.profileData(filteredData);
@@ -8950,59 +8253,70 @@ RULES:
8950
8253
  var SchemaMapper = class {
8951
8254
  /**
8952
8255
  * Trains the plugin on a set of keys.
8953
- * This is done once per schema and cached.
8256
+ * Results are cached in-process; concurrent calls for the same key set are
8257
+ * deduplicated to a single LLM request.
8954
8258
  */
8955
8259
  static async train(llm, projectId, keys) {
8956
- const cacheKey = `${projectId}:${keys.sort().join(",")}`;
8260
+ const cacheKey = `${projectId}:${keys.slice().sort().join(",")}`;
8957
8261
  if (this.cache.has(cacheKey)) {
8958
8262
  return this.cache.get(cacheKey);
8959
8263
  }
8960
- console.log(`[SchemaMapper] \u{1F9E0} Training AI on new schema keys: ${keys.join(", ")}`);
8264
+ if (this.pending.has(cacheKey)) {
8265
+ return this.pending.get(cacheKey);
8266
+ }
8267
+ const promise = this._doTrain(llm, cacheKey, keys);
8268
+ this.pending.set(cacheKey, promise);
8269
+ promise.finally(() => this.pending.delete(cacheKey));
8270
+ return promise;
8271
+ }
8272
+ static async _doTrain(llm, cacheKey, keys) {
8273
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8274
+ console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
8961
8275
  const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
8962
- const prompt = `
8963
- Given these metadata keys from a database: [${keys.join(", ")}]
8276
+ const messages = [
8277
+ { role: "system", content: "You are a database schema expert. Respond ONLY with valid JSON." },
8278
+ {
8279
+ role: "user",
8280
+ content: `Keys: [${keys.join(", ")}]
8964
8281
 
8965
- Identify which keys best correspond to these standard UI properties:
8282
+ Map to:
8966
8283
  ${propertyList}
8967
8284
 
8968
- Return ONLY a valid JSON object where the keys are the UI properties and the values are the EXACT matching database keys from the list above.
8969
- If no good match is found for a property, omit it.
8970
-
8971
- Example:
8972
- {
8973
- "name": "Title",
8974
- "price": "Variant Price",
8975
- "brand": "Vendor",
8976
- "image": "Image Src",
8977
- "stock": "Variant Inventory Qty"
8978
- }
8979
- `;
8285
+ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped properties.`
8286
+ }
8287
+ ];
8980
8288
  try {
8981
- const response = await llm.chat(
8982
- [
8983
- { role: "system", content: "You are a database schema expert. You ONLY respond with valid JSON." },
8984
- { role: "user", content: prompt }
8985
- ],
8986
- ""
8987
- );
8988
- const startIdx = response.indexOf("{");
8989
- if (startIdx !== -1) {
8990
- let braceCount = 0;
8991
- let endIdx = -1;
8992
- for (let i = startIdx; i < response.length; i++) {
8993
- if (response[i] === "{") braceCount++;
8994
- else if (response[i] === "}") {
8995
- braceCount--;
8996
- if (braceCount === 0) {
8997
- endIdx = i;
8998
- break;
8999
- }
9000
- }
8289
+ const baseUrl = (_a2 = llm == null ? void 0 : llm.baseUrl) != null ? _a2 : "";
8290
+ const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
8291
+ const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
8292
+ let responseText;
8293
+ if (baseUrl) {
8294
+ const endpoint = `${baseUrl.replace(/\/$/, "")}/chat/completions`;
8295
+ const headers = { "Content-Type": "application/json" };
8296
+ if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
8297
+ const res = await fetch(endpoint, {
8298
+ method: "POST",
8299
+ headers,
8300
+ body: JSON.stringify({
8301
+ model,
8302
+ messages,
8303
+ max_tokens: 256,
8304
+ // Only needs a small JSON object back
8305
+ temperature: 0,
8306
+ stream: false
8307
+ }),
8308
+ signal: AbortSignal.timeout(8e3)
8309
+ });
8310
+ if (res.ok) {
8311
+ const data = await res.json();
8312
+ responseText = (_k = (_j = (_f = (_e = (_d = data == null ? void 0 : data.choices) == null ? void 0 : _d[0]) == null ? void 0 : _e.message) == null ? void 0 : _f.content) != null ? _j : (_i = (_h = (_g2 = data == null ? void 0 : data.choices) == null ? void 0 : _g2[0]) == null ? void 0 : _h.delta) == null ? void 0 : _i.content) != null ? _k : void 0;
8313
+ } else {
8314
+ console.warn(`[SchemaMapper] LLM returned ${res.status}, falling back to heuristics.`);
9001
8315
  }
9002
- if (endIdx !== -1) {
9003
- const jsonContent = response.substring(startIdx, endIdx + 1);
9004
- const cleanJson = this.sanitizeJson(jsonContent);
9005
- const mapping = JSON.parse(cleanJson);
8316
+ }
8317
+ if (responseText) {
8318
+ const mapping = this._parseJson(responseText);
8319
+ if (mapping) {
9006
8320
  this.cache.set(cacheKey, mapping);
9007
8321
  return mapping;
9008
8322
  }
@@ -9010,23 +8324,42 @@ Example:
9010
8324
  } catch (error) {
9011
8325
  console.warn("[SchemaMapper] AI training failed, falling back to heuristics:", error);
9012
8326
  }
8327
+ this.cache.set(cacheKey, {});
9013
8328
  return {};
9014
8329
  }
9015
- /**
9016
- * Forgiving JSON parser that fixes common AI formatting mistakes.
9017
- */
9018
- static sanitizeJson(s) {
8330
+ static _parseJson(text) {
8331
+ const startIdx = text.indexOf("{");
8332
+ if (startIdx === -1) return null;
8333
+ let braceCount = 0;
8334
+ let endIdx = -1;
8335
+ for (let i = startIdx; i < text.length; i++) {
8336
+ if (text[i] === "{") braceCount++;
8337
+ else if (text[i] === "}") {
8338
+ braceCount--;
8339
+ if (braceCount === 0) {
8340
+ endIdx = i;
8341
+ break;
8342
+ }
8343
+ }
8344
+ }
8345
+ if (endIdx === -1) return null;
8346
+ try {
8347
+ return JSON.parse(this._sanitizeJson(text.substring(startIdx, endIdx + 1)));
8348
+ } catch (e) {
8349
+ return null;
8350
+ }
8351
+ }
8352
+ static _sanitizeJson(s) {
9019
8353
  return s.replace(/\/\*[\s\S]*?\*\/|([^:]|^)\/\/.*$/gm, "").replace(/[\u201C\u201D\u2018\u2019]/g, '"').replace(/'/g, '"').replace(/([{,]\s*)([a-zA-Z0-9_]+?)\s*:/g, '$1"$2":').replace(/,\s*([}\]])/g, "$1").trim();
9020
8354
  }
9021
8355
  static getCached(projectId, keys) {
9022
- const cacheKey = `${projectId}:${keys.sort().join(",")}`;
8356
+ const cacheKey = `${projectId}:${keys.slice().sort().join(",")}`;
9023
8357
  return this.cache.get(cacheKey);
9024
8358
  }
9025
8359
  };
9026
8360
  SchemaMapper.cache = /* @__PURE__ */ new Map();
9027
- /**
9028
- * Descriptions of standard UI properties to help the AI map fields accurately.
9029
- */
8361
+ /** In-flight deduplication — prevents concurrent identical LLM calls. */
8362
+ SchemaMapper.pending = /* @__PURE__ */ new Map();
9030
8363
  SchemaMapper.TARGET_PROPERTIES = {
9031
8364
  name: "The primary title, name, or label of the item",
9032
8365
  price: "The numeric cost, price, MSRP, or amount",
@@ -9498,19 +8831,6 @@ ${m.content}`).join("\n\n---\n\n");
9498
8831
  const wantsExhaustiveList = true;
9499
8832
  const retrievalLimit = Math.max(topK * 50, 1e3);
9500
8833
  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"));
9501
- console.log("[Pipeline] Raw vectorDB.query response:", {
9502
- rawCount: rawSources.length,
9503
- sample: rawSources.slice(0, 2).map((s) => {
9504
- var _a3;
9505
- return {
9506
- id: s == null ? void 0 : s.id,
9507
- score: s == null ? void 0 : s.score,
9508
- contentType: typeof (s == null ? void 0 : s.content),
9509
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9510
- metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
9511
- };
9512
- })
9513
- });
9514
8834
  const retrieveEnd = performance.now();
9515
8835
  const embedMs = retrieveEnd - embedStart;
9516
8836
  const retrieveMs = retrieveEnd - embedStart;
@@ -9539,21 +8859,6 @@ ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9539
8859
  var _a3, _b2;
9540
8860
  return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
9541
8861
  });
9542
- console.log("[Pipeline] Final sources for prompt & UI:", {
9543
- count: sources.length,
9544
- totalRawCount: rawSources.length,
9545
- sources: sources.slice(0, 10).map((s, idx) => {
9546
- var _a3;
9547
- return {
9548
- rank: idx + 1,
9549
- id: s == null ? void 0 : s.id,
9550
- score: s == null ? void 0 : s.score,
9551
- contentType: typeof (s == null ? void 0 : s.content),
9552
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9553
- metadata: s == null ? void 0 : s.metadata
9554
- };
9555
- })
9556
- });
9557
8862
  if (graphData && graphData.nodes.length > 0) {
9558
8863
  const graphContext = graphData.nodes.map(
9559
8864
  (n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
@@ -9795,9 +9100,9 @@ ${context}`;
9795
9100
  const trace = buildTrace(hallucinationResult);
9796
9101
  const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
9797
9102
  if (isTelemetryActive) {
9798
- 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";
9103
+ const defaultUrl = "https://www.retrivora.com/api/telemetry";
9799
9104
  const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
9800
- const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
9105
+ const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
9801
9106
  (async () => {
9802
9107
  var _a3, _b2, _c2, _d2, _e2;
9803
9108
  try {
@@ -10334,8 +9639,8 @@ var VectorPlugin = class {
10334
9639
  }
10335
9640
  try {
10336
9641
  return await this.pipeline.getSuggestions(query, namespace);
10337
- } catch (err) {
10338
- throw wrapError(err, "RETRIEVAL_FAILED");
9642
+ } catch (e) {
9643
+ return [];
10339
9644
  }
10340
9645
  }
10341
9646
  };
@@ -10932,15 +10237,14 @@ function getOrCreatePlugin(configOrPlugin) {
10932
10237
  return _g[cacheKey];
10933
10238
  }
10934
10239
  function reportTelemetry(req, plugin, action, status, details, trace) {
10935
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
10240
+ var _a2, _b, _c, _d, _e, _f, _g2;
10936
10241
  try {
10937
10242
  const config = plugin.getConfig();
10938
10243
  const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
10939
10244
  const telemetryConfig = config.telemetry;
10940
- const enabled = (_a2 = telemetryConfig == null ? void 0 : telemetryConfig.enabled) != null ? _a2 : Boolean(licenseKey);
10941
- const defaultUrl = process.env.NODE_ENV === "development" && !process.env.TELEMETRY_URL && !process.env.NEXT_PUBLIC_TELEMETRY_URL ? "http://localhost:3001/api/telemetry" : "https://www.retrivora.com/api/telemetry";
10942
- const telemetryUrl = (telemetryConfig == null ? void 0 : telemetryConfig.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
10943
10245
  const host = req.headers.get("host") || "localhost";
10246
+ const defaultUrl = "https://www.retrivora.com/api/telemetry";
10247
+ const telemetryUrl = (telemetryConfig == null ? void 0 : telemetryConfig.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
10944
10248
  const userAgent = req.headers.get("user-agent") || `Retrivora-SDK/${SDK_VERSION}`;
10945
10249
  let absoluteUrl = telemetryUrl;
10946
10250
  if (!telemetryUrl.startsWith("http")) {
@@ -10948,11 +10252,11 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10948
10252
  absoluteUrl = `${proto}://${host}${telemetryUrl}`;
10949
10253
  }
10950
10254
  const projectId = config.projectId || "default";
10951
- const model = (trace == null ? void 0 : trace.model) || ((_b = config.llm) == null ? void 0 : _b.model) || ((_c = config.embedding) == null ? void 0 : _c.model) || "llama-3.1-8b-instant";
10952
- const provider = (trace == null ? void 0 : trace.provider) || ((_d = config.llm) == null ? void 0 : _d.provider) || ((_e = config.embedding) == null ? void 0 : _e.provider) || "groq";
10953
- const tokens = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10954
- const costUsd = Number(((_g2 = trace == null ? void 0 : trace.tokens) == null ? void 0 : _g2.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
10955
- const latencyMs = Number(((_h = trace == null ? void 0 : trace.latency) == null ? void 0 : _h.totalMs) || (trace == null ? void 0 : trace.latencyMs) || 0);
10255
+ const model = (trace == null ? void 0 : trace.model) || ((_a2 = config.llm) == null ? void 0 : _a2.model) || ((_b = config.embedding) == null ? void 0 : _b.model) || "llama-3.1-8b-instant";
10256
+ const provider = (trace == null ? void 0 : trace.provider) || ((_c = config.llm) == null ? void 0 : _c.provider) || ((_d = config.embedding) == null ? void 0 : _d.provider) || "groq";
10257
+ const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10258
+ const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
10259
+ const latencyMs = Number(((_g2 = trace == null ? void 0 : trace.latency) == null ? void 0 : _g2.totalMs) || (trace == null ? void 0 : trace.latencyMs) || 0);
10956
10260
  const payload = {
10957
10261
  trace,
10958
10262
  licenseKey,
@@ -11029,7 +10333,7 @@ function createChatHandler(configOrPlugin, options) {
11029
10333
  const plugin = getOrCreatePlugin(configOrPlugin);
11030
10334
  const storage = new DatabaseStorage(plugin.getConfig());
11031
10335
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11032
- return async function POST(req) {
10336
+ return async function POST(req, context) {
11033
10337
  var _a2, _b, _c, _d;
11034
10338
  const authResult = await checkAuth(req, onAuthorize);
11035
10339
  if (authResult) return authResult;
@@ -11085,7 +10389,7 @@ function createStreamHandler(configOrPlugin, options) {
11085
10389
  const plugin = getOrCreatePlugin(configOrPlugin);
11086
10390
  const storage = new DatabaseStorage(plugin.getConfig());
11087
10391
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11088
- return async function POST(req) {
10392
+ return async function POST(req, context) {
11089
10393
  var _a2;
11090
10394
  const authResult = await checkAuth(req, onAuthorize);
11091
10395
  if (authResult) return authResult;
@@ -11235,7 +10539,7 @@ function createStreamHandler(configOrPlugin, options) {
11235
10539
  function createIngestHandler(configOrPlugin, options) {
11236
10540
  const plugin = getOrCreatePlugin(configOrPlugin);
11237
10541
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11238
- return async function POST(req) {
10542
+ return async function POST(req, context) {
11239
10543
  const authResult = await checkAuth(req, onAuthorize);
11240
10544
  if (authResult) return authResult;
11241
10545
  try {
@@ -11279,7 +10583,7 @@ function createHealthHandler(configOrPlugin, options) {
11279
10583
  function createUploadHandler(configOrPlugin, options) {
11280
10584
  const plugin = getOrCreatePlugin(configOrPlugin);
11281
10585
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11282
- return async function POST(req) {
10586
+ return async function POST(req, context) {
11283
10587
  const authResult = await checkAuth(req, onAuthorize);
11284
10588
  if (authResult) return authResult;
11285
10589
  try {