@retrivora-ai/rag-engine 2.2.4 → 2.2.5

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,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 {
@@ -3453,7 +2815,7 @@ function getEnvConfig(env = process.env, base) {
3453
2815
  },
3454
2816
  telemetry: {
3455
2817
  enabled: telemetryEnabled,
3456
- 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"
2818
+ 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"
3457
2819
  }
3458
2820
  }, readString(env, "GRAPH_DB_PROVIDER") ? {
3459
2821
  graphDb: {
@@ -4702,9 +4064,7 @@ var OPENAI_BASE = {
4702
4064
  };
4703
4065
  var LLM_PROFILES = {
4704
4066
  "openai-compatible": OPENAI_BASE,
4705
- "litellm": __spreadProps(__spreadValues({}, OPENAI_BASE), {
4706
- chatPayloadTemplate: '{"model":"{{model}}","messages":{{messages}},"max_tokens":{{maxTokens}},"temperature":{{temperature}},"stream":false}'
4707
- }),
4067
+ "litellm": __spreadValues({}, OPENAI_BASE),
4708
4068
  "anthropic-claude": {
4709
4069
  chatPath: "/v1/messages",
4710
4070
  responseExtractPath: "content[0].text",
@@ -4849,18 +4209,7 @@ ${context != null ? context : "None"}` },
4849
4209
  }
4850
4210
  } catch (httpErr) {
4851
4211
  const _g2 = globalThis;
4852
- let dispatch = _g2.__retrivoraDispatchChat;
4853
- if (typeof dispatch !== "function") {
4854
- try {
4855
- const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
4856
- if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
4857
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4858
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4859
- dispatch = gateway.dispatchChatCompletion;
4860
- }
4861
- } catch (e) {
4862
- }
4863
- }
4212
+ const dispatch = _g2.__retrivoraDispatchChat;
4864
4213
  if (typeof dispatch === "function") {
4865
4214
  const res = await dispatch({
4866
4215
  model: this.model,
@@ -4886,11 +4235,10 @@ ${context != null ? context : "None"}` },
4886
4235
  /**
4887
4236
  * Streaming chat using native fetch + ReadableStream.
4888
4237
  * Parses OpenAI-compatible SSE frames: `data: {...}\n\n`
4889
- * Works with vLLM, LMStudio, Together AI, Fireworks, and any OpenAI-compatible API.
4890
4238
  */
4891
4239
  chatStream(messages, context) {
4892
4240
  return __asyncGenerator(this, null, function* () {
4893
- var _a2, _b, _c, _d, _e;
4241
+ var _a2, _b, _c, _d, _e, _f;
4894
4242
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4895
4243
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4896
4244
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
@@ -4925,22 +4273,35 @@ ${context != null ? context : "None"}` },
4925
4273
  stream: true
4926
4274
  };
4927
4275
  }
4928
- const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4929
4276
  let streamBody = null;
4930
- if (isSelfHost || Boolean(process.env.VERCEL)) {
4931
- const _g2 = globalThis;
4932
- let dispatch = _g2.__retrivoraDispatchChat;
4933
- if (typeof dispatch !== "function") {
4934
- try {
4935
- const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
4936
- if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
4937
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4938
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4939
- dispatch = gateway.dispatchChatCompletion;
4277
+ try {
4278
+ const response = yield new __await(fetch(url, {
4279
+ method: "POST",
4280
+ headers: this.resolvedHeaders,
4281
+ body: typeof payload === "string" ? payload : JSON.stringify(payload)
4282
+ }));
4283
+ if (response.ok) {
4284
+ const contentType = response.headers.get("content-type") || "";
4285
+ if (contentType.includes("application/json")) {
4286
+ const json = yield new __await(response.json());
4287
+ const text = (_c = resolvePath(json, extractPath)) != null ? _c : extractContent(json);
4288
+ if (text && typeof text === "string") {
4289
+ yield text;
4290
+ return;
4940
4291
  }
4941
- } catch (e) {
4292
+ } else if (response.body) {
4293
+ streamBody = response.body;
4942
4294
  }
4295
+ } else {
4296
+ const errorText = yield new __await(response.text().catch(() => response.statusText));
4297
+ console.warn(`[UniversalLLMAdapter] Remote HTTP stream returned ${response.status}: ${errorText}. Attempting in-process fallback...`);
4943
4298
  }
4299
+ } catch (fetchErr) {
4300
+ console.warn(`[UniversalLLMAdapter] Remote HTTP stream fetch warning: ${fetchErr == null ? void 0 : fetchErr.message}. Attempting in-process fallback...`);
4301
+ }
4302
+ if (!streamBody) {
4303
+ const _g2 = globalThis;
4304
+ const dispatch = _g2.__retrivoraDispatchChat;
4944
4305
  if (typeof dispatch === "function") {
4945
4306
  try {
4946
4307
  const res = yield new __await(dispatch({
@@ -4958,29 +4319,14 @@ ${context != null ? context : "None"}` },
4958
4319
  yield content;
4959
4320
  return;
4960
4321
  }
4961
- throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
4962
4322
  }
4963
4323
  } catch (dispatchErr) {
4964
- throw dispatchErr;
4324
+ console.warn("[UniversalLLMAdapter] In-process dispatch error:", dispatchErr);
4965
4325
  }
4966
- } else {
4967
- 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.`);
4968
4326
  }
4969
4327
  }
4970
4328
  if (!streamBody) {
4971
- const response = yield new __await(fetch(url, {
4972
- method: "POST",
4973
- headers: this.resolvedHeaders,
4974
- body: JSON.stringify(payload)
4975
- }));
4976
- if (!response.ok) {
4977
- const errorText = yield new __await(response.text().catch(() => response.statusText));
4978
- throw new Error(`[UniversalLLMAdapter] Streaming request failed (${response.status}): ${errorText}`);
4979
- }
4980
- if (!response.body) {
4981
- throw new Error("[UniversalLLMAdapter] Response body is null \u2014 server did not send a streaming response.");
4982
- }
4983
- streamBody = response.body;
4329
+ throw new Error(`[UniversalLLMAdapter] Streaming request failed. Ensure RETRIVORA_LICENSE_KEY is valid or LLM service is available.`);
4984
4330
  }
4985
4331
  const reader = streamBody.getReader();
4986
4332
  const decoder = new TextDecoder("utf-8");
@@ -4991,14 +4337,14 @@ ${context != null ? context : "None"}` },
4991
4337
  if (done) break;
4992
4338
  buffer += decoder.decode(value, { stream: true });
4993
4339
  const lines = buffer.split("\n");
4994
- buffer = (_c = lines.pop()) != null ? _c : "";
4340
+ buffer = (_d = lines.pop()) != null ? _d : "";
4995
4341
  for (const line of lines) {
4996
4342
  const trimmed = line.trim();
4997
4343
  if (!trimmed || trimmed === "data: [DONE]") continue;
4998
4344
  if (!trimmed.startsWith("data:")) continue;
4999
4345
  try {
5000
4346
  const json = JSON.parse(trimmed.slice(5).trim());
5001
- const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
4347
+ const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
5002
4348
  if (text && typeof text === "string") yield text;
5003
4349
  } catch (e) {
5004
4350
  }
@@ -5008,7 +4354,7 @@ ${context != null ? context : "None"}` },
5008
4354
  const jsonStr = buffer.replace(/^data:\s*/, "").trim();
5009
4355
  try {
5010
4356
  const json = JSON.parse(jsonStr);
5011
- const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
4357
+ const text = (_f = resolvePath(json, extractPath)) != null ? _f : extractContent(json);
5012
4358
  if (text && typeof text === "string") yield text;
5013
4359
  } catch (e) {
5014
4360
  }
@@ -5021,74 +4367,42 @@ ${context != null ? context : "None"}` },
5021
4367
  async embed(text) {
5022
4368
  var _a2, _b, _c, _d, _e;
5023
4369
  const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
5024
- let payload;
5025
- if (this.opts.embedPayloadTemplate) {
5026
- payload = buildPayload(this.opts.embedPayloadTemplate, {
5027
- model: this.model,
5028
- input: text
5029
- });
5030
- } else {
5031
- payload = {
5032
- model: this.model,
5033
- input: text
5034
- };
5035
- }
4370
+ const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
5036
4371
  try {
5037
4372
  const { data: data2 } = await this.http.post(path2, payload);
5038
4373
  const extractPath2 = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
5039
4374
  const vector2 = resolvePath(data2, extractPath2);
5040
- if (Array.isArray(vector2)) {
5041
- return vector2;
5042
- }
5043
- } catch (httpErr) {
5044
- console.warn(`[UniversalLLMAdapter] Direct HTTP embedding POST to ${this.baseUrl}${path2} failed (${httpErr.message}). Attempting in-process gateway dispatch fallback...`);
4375
+ if (Array.isArray(vector2)) return vector2;
4376
+ } catch (e) {
5045
4377
  const _g2 = globalThis;
5046
- let dispatch = _g2.__retrivoraDispatchEmbedding;
5047
- if (typeof dispatch !== "function") {
5048
- try {
5049
- const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
5050
- if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
5051
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
5052
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
5053
- dispatch = gateway.dispatchEmbedding;
5054
- }
5055
- } catch (e) {
5056
- }
5057
- }
5058
- if (typeof dispatch === "function") {
5059
- const res = await dispatch({
5060
- model: this.model,
5061
- input: text
5062
- }, this.apiKey);
4378
+ const dispatchEmbed = _g2.__retrivoraDispatchEmbedding;
4379
+ if (typeof dispatchEmbed === "function") {
4380
+ const res = await dispatchEmbed({ input: text, model: this.model }, this.apiKey);
5063
4381
  if ((_d = (_c = res == null ? void 0 : res.data) == null ? void 0 : _c[0]) == null ? void 0 : _d.embedding) {
5064
4382
  return res.data[0].embedding;
5065
4383
  }
5066
4384
  }
5067
- throw httpErr;
5068
4385
  }
5069
4386
  const { data } = await this.http.post(path2, payload);
5070
4387
  const extractPath = (_e = this.opts.embedExtractPath) != null ? _e : "data[0].embedding";
5071
4388
  const vector = resolvePath(data, extractPath);
5072
4389
  if (!Array.isArray(vector)) {
5073
- throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
4390
+ throw new Error(`[UniversalLLMAdapter] Could not extract embedding vector from path '${extractPath}' in response.`);
5074
4391
  }
5075
4392
  return vector;
5076
4393
  }
5077
4394
  async batchEmbed(texts) {
5078
- const vectors = [];
4395
+ const results = [];
5079
4396
  for (const text of texts) {
5080
- vectors.push(await this.embed(text));
4397
+ results.push(await this.embed(text));
5081
4398
  }
5082
- return vectors;
4399
+ return results;
5083
4400
  }
5084
4401
  async ping() {
5085
4402
  try {
5086
- if (this.opts.pingPath) {
5087
- await this.http.get(this.opts.pingPath);
5088
- }
4403
+ await this.embed("ping");
5089
4404
  return true;
5090
- } catch (err) {
5091
- console.error("[UniversalLLMAdapter] Ping failed:", err);
4405
+ } catch (e) {
5092
4406
  return false;
5093
4407
  }
5094
4408
  }
@@ -5494,7 +4808,7 @@ var ConfigValidator = class {
5494
4808
  // package.json
5495
4809
  var package_default = {
5496
4810
  name: "@retrivora-ai/rag-engine",
5497
- version: "2.2.4",
4811
+ version: "2.2.5",
5498
4812
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
5499
4813
  author: "Abhinav Alkuchi",
5500
4814
  license: "UNLICENSED",
@@ -5531,6 +4845,8 @@ var package_default = {
5531
4845
  import: "./dist/index.mjs"
5532
4846
  },
5533
4847
  "./style.css": "./dist/index.css",
4848
+ "./index.css": "./dist/index.css",
4849
+ "./styles.css": "./dist/index.css",
5534
4850
  "./handlers": {
5535
4851
  types: "./dist/handlers/index.d.ts",
5536
4852
  require: "./dist/handlers/index.js",
@@ -7713,19 +7029,6 @@ var UITransformer = class _UITransformer {
7713
7029
  if (!retrievedData || retrievedData.length === 0) {
7714
7030
  return this.createTextResponse("No data available", "No relevant data found for your query.");
7715
7031
  }
7716
- console.log("[UITransformer.transform] Processing retrievedData:", {
7717
- userQuery,
7718
- retrievedCount: retrievedData.length,
7719
- sample: retrievedData.slice(0, 2).map((item) => {
7720
- var _a3;
7721
- return {
7722
- id: item == null ? void 0 : item.id,
7723
- contentType: typeof (item == null ? void 0 : item.content),
7724
- contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
7725
- metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
7726
- };
7727
- })
7728
- });
7729
7032
  const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
7730
7033
  const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
7731
7034
  const profile = this.profileData(filteredData);
@@ -9065,59 +8368,70 @@ RULES:
9065
8368
  var SchemaMapper = class {
9066
8369
  /**
9067
8370
  * Trains the plugin on a set of keys.
9068
- * This is done once per schema and cached.
8371
+ * Results are cached in-process; concurrent calls for the same key set are
8372
+ * deduplicated to a single LLM request.
9069
8373
  */
9070
8374
  static async train(llm, projectId, keys) {
9071
- const cacheKey = `${projectId}:${keys.sort().join(",")}`;
8375
+ const cacheKey = `${projectId}:${keys.slice().sort().join(",")}`;
9072
8376
  if (this.cache.has(cacheKey)) {
9073
8377
  return this.cache.get(cacheKey);
9074
8378
  }
9075
- console.log(`[SchemaMapper] \u{1F9E0} Training AI on new schema keys: ${keys.join(", ")}`);
8379
+ if (this.pending.has(cacheKey)) {
8380
+ return this.pending.get(cacheKey);
8381
+ }
8382
+ const promise = this._doTrain(llm, cacheKey, keys);
8383
+ this.pending.set(cacheKey, promise);
8384
+ promise.finally(() => this.pending.delete(cacheKey));
8385
+ return promise;
8386
+ }
8387
+ static async _doTrain(llm, cacheKey, keys) {
8388
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8389
+ console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
9076
8390
  const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
9077
- const prompt = `
9078
- Given these metadata keys from a database: [${keys.join(", ")}]
8391
+ const messages = [
8392
+ { role: "system", content: "You are a database schema expert. Respond ONLY with valid JSON." },
8393
+ {
8394
+ role: "user",
8395
+ content: `Keys: [${keys.join(", ")}]
9079
8396
 
9080
- Identify which keys best correspond to these standard UI properties:
8397
+ Map to:
9081
8398
  ${propertyList}
9082
8399
 
9083
- 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.
9084
- If no good match is found for a property, omit it.
9085
-
9086
- Example:
9087
- {
9088
- "name": "Title",
9089
- "price": "Variant Price",
9090
- "brand": "Vendor",
9091
- "image": "Image Src",
9092
- "stock": "Variant Inventory Qty"
9093
- }
9094
- `;
8400
+ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped properties.`
8401
+ }
8402
+ ];
9095
8403
  try {
9096
- const response = await llm.chat(
9097
- [
9098
- { role: "system", content: "You are a database schema expert. You ONLY respond with valid JSON." },
9099
- { role: "user", content: prompt }
9100
- ],
9101
- ""
9102
- );
9103
- const startIdx = response.indexOf("{");
9104
- if (startIdx !== -1) {
9105
- let braceCount = 0;
9106
- let endIdx = -1;
9107
- for (let i = startIdx; i < response.length; i++) {
9108
- if (response[i] === "{") braceCount++;
9109
- else if (response[i] === "}") {
9110
- braceCount--;
9111
- if (braceCount === 0) {
9112
- endIdx = i;
9113
- break;
9114
- }
9115
- }
8404
+ const baseUrl = (_a2 = llm == null ? void 0 : llm.baseUrl) != null ? _a2 : "";
8405
+ const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
8406
+ const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
8407
+ let responseText;
8408
+ if (baseUrl) {
8409
+ const endpoint = `${baseUrl.replace(/\/$/, "")}/chat/completions`;
8410
+ const headers = { "Content-Type": "application/json" };
8411
+ if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
8412
+ const res = await fetch(endpoint, {
8413
+ method: "POST",
8414
+ headers,
8415
+ body: JSON.stringify({
8416
+ model,
8417
+ messages,
8418
+ max_tokens: 256,
8419
+ // Only needs a small JSON object back
8420
+ temperature: 0,
8421
+ stream: false
8422
+ }),
8423
+ signal: AbortSignal.timeout(8e3)
8424
+ });
8425
+ if (res.ok) {
8426
+ const data = await res.json();
8427
+ 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;
8428
+ } else {
8429
+ console.warn(`[SchemaMapper] LLM returned ${res.status}, falling back to heuristics.`);
9116
8430
  }
9117
- if (endIdx !== -1) {
9118
- const jsonContent = response.substring(startIdx, endIdx + 1);
9119
- const cleanJson = this.sanitizeJson(jsonContent);
9120
- const mapping = JSON.parse(cleanJson);
8431
+ }
8432
+ if (responseText) {
8433
+ const mapping = this._parseJson(responseText);
8434
+ if (mapping) {
9121
8435
  this.cache.set(cacheKey, mapping);
9122
8436
  return mapping;
9123
8437
  }
@@ -9125,23 +8439,42 @@ Example:
9125
8439
  } catch (error) {
9126
8440
  console.warn("[SchemaMapper] AI training failed, falling back to heuristics:", error);
9127
8441
  }
8442
+ this.cache.set(cacheKey, {});
9128
8443
  return {};
9129
8444
  }
9130
- /**
9131
- * Forgiving JSON parser that fixes common AI formatting mistakes.
9132
- */
9133
- static sanitizeJson(s) {
8445
+ static _parseJson(text) {
8446
+ const startIdx = text.indexOf("{");
8447
+ if (startIdx === -1) return null;
8448
+ let braceCount = 0;
8449
+ let endIdx = -1;
8450
+ for (let i = startIdx; i < text.length; i++) {
8451
+ if (text[i] === "{") braceCount++;
8452
+ else if (text[i] === "}") {
8453
+ braceCount--;
8454
+ if (braceCount === 0) {
8455
+ endIdx = i;
8456
+ break;
8457
+ }
8458
+ }
8459
+ }
8460
+ if (endIdx === -1) return null;
8461
+ try {
8462
+ return JSON.parse(this._sanitizeJson(text.substring(startIdx, endIdx + 1)));
8463
+ } catch (e) {
8464
+ return null;
8465
+ }
8466
+ }
8467
+ static _sanitizeJson(s) {
9134
8468
  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();
9135
8469
  }
9136
8470
  static getCached(projectId, keys) {
9137
- const cacheKey = `${projectId}:${keys.sort().join(",")}`;
8471
+ const cacheKey = `${projectId}:${keys.slice().sort().join(",")}`;
9138
8472
  return this.cache.get(cacheKey);
9139
8473
  }
9140
8474
  };
9141
8475
  SchemaMapper.cache = /* @__PURE__ */ new Map();
9142
- /**
9143
- * Descriptions of standard UI properties to help the AI map fields accurately.
9144
- */
8476
+ /** In-flight deduplication — prevents concurrent identical LLM calls. */
8477
+ SchemaMapper.pending = /* @__PURE__ */ new Map();
9145
8478
  SchemaMapper.TARGET_PROPERTIES = {
9146
8479
  name: "The primary title, name, or label of the item",
9147
8480
  price: "The numeric cost, price, MSRP, or amount",
@@ -9613,19 +8946,6 @@ ${m.content}`).join("\n\n---\n\n");
9613
8946
  const wantsExhaustiveList = true;
9614
8947
  const retrievalLimit = Math.max(topK * 50, 1e3);
9615
8948
  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"));
9616
- console.log("[Pipeline] Raw vectorDB.query response:", {
9617
- rawCount: rawSources.length,
9618
- sample: rawSources.slice(0, 2).map((s) => {
9619
- var _a3;
9620
- return {
9621
- id: s == null ? void 0 : s.id,
9622
- score: s == null ? void 0 : s.score,
9623
- contentType: typeof (s == null ? void 0 : s.content),
9624
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9625
- metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
9626
- };
9627
- })
9628
- });
9629
8949
  const retrieveEnd = performance.now();
9630
8950
  const embedMs = retrieveEnd - embedStart;
9631
8951
  const retrieveMs = retrieveEnd - embedStart;
@@ -9654,21 +8974,6 @@ ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9654
8974
  var _a3, _b2;
9655
8975
  return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
9656
8976
  });
9657
- console.log("[Pipeline] Final sources for prompt & UI:", {
9658
- count: sources.length,
9659
- totalRawCount: rawSources.length,
9660
- sources: sources.slice(0, 10).map((s, idx) => {
9661
- var _a3;
9662
- return {
9663
- rank: idx + 1,
9664
- id: s == null ? void 0 : s.id,
9665
- score: s == null ? void 0 : s.score,
9666
- contentType: typeof (s == null ? void 0 : s.content),
9667
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9668
- metadata: s == null ? void 0 : s.metadata
9669
- };
9670
- })
9671
- });
9672
8977
  if (graphData && graphData.nodes.length > 0) {
9673
8978
  const graphContext = graphData.nodes.map(
9674
8979
  (n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
@@ -9910,9 +9215,9 @@ ${context}`;
9910
9215
  const trace = buildTrace(hallucinationResult);
9911
9216
  const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
9912
9217
  if (isTelemetryActive) {
9913
- 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";
9218
+ const defaultUrl = "https://www.retrivora.com/api/telemetry";
9914
9219
  const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
9915
- const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
9220
+ const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
9916
9221
  (async () => {
9917
9222
  var _a3, _b2, _c2, _d2, _e2;
9918
9223
  try {
@@ -10532,8 +9837,8 @@ var VectorPlugin = class {
10532
9837
  }
10533
9838
  try {
10534
9839
  return await this.pipeline.getSuggestions(query, namespace);
10535
- } catch (err) {
10536
- throw wrapError(err, "RETRIEVAL_FAILED");
9840
+ } catch (e) {
9841
+ return [];
10537
9842
  }
10538
9843
  }
10539
9844
  };
@@ -11346,15 +10651,14 @@ function getOrCreatePlugin(configOrPlugin) {
11346
10651
  return _g[cacheKey];
11347
10652
  }
11348
10653
  function reportTelemetry(req, plugin, action, status, details, trace) {
11349
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
10654
+ var _a2, _b, _c, _d, _e, _f, _g2;
11350
10655
  try {
11351
10656
  const config = plugin.getConfig();
11352
10657
  const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
11353
10658
  const telemetryConfig = config.telemetry;
11354
- const enabled = (_a2 = telemetryConfig == null ? void 0 : telemetryConfig.enabled) != null ? _a2 : Boolean(licenseKey);
11355
- 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";
11356
- const telemetryUrl = (telemetryConfig == null ? void 0 : telemetryConfig.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
11357
10659
  const host = req.headers.get("host") || "localhost";
10660
+ const defaultUrl = "https://www.retrivora.com/api/telemetry";
10661
+ const telemetryUrl = (telemetryConfig == null ? void 0 : telemetryConfig.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
11358
10662
  const userAgent = req.headers.get("user-agent") || `Retrivora-SDK/${SDK_VERSION}`;
11359
10663
  let absoluteUrl = telemetryUrl;
11360
10664
  if (!telemetryUrl.startsWith("http")) {
@@ -11362,11 +10666,11 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
11362
10666
  absoluteUrl = `${proto}://${host}${telemetryUrl}`;
11363
10667
  }
11364
10668
  const projectId = config.projectId || "default";
11365
- 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";
11366
- 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";
11367
- const tokens = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
11368
- const costUsd = Number(((_g2 = trace == null ? void 0 : trace.tokens) == null ? void 0 : _g2.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
11369
- const latencyMs = Number(((_h = trace == null ? void 0 : trace.latency) == null ? void 0 : _h.totalMs) || (trace == null ? void 0 : trace.latencyMs) || 0);
10669
+ 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";
10670
+ 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";
10671
+ const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10672
+ const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
10673
+ const latencyMs = Number(((_g2 = trace == null ? void 0 : trace.latency) == null ? void 0 : _g2.totalMs) || (trace == null ? void 0 : trace.latencyMs) || 0);
11370
10674
  const payload = {
11371
10675
  trace,
11372
10676
  licenseKey,
@@ -11443,7 +10747,7 @@ function createChatHandler(configOrPlugin, options) {
11443
10747
  const plugin = getOrCreatePlugin(configOrPlugin);
11444
10748
  const storage = new DatabaseStorage(plugin.getConfig());
11445
10749
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11446
- return async function POST(req) {
10750
+ return async function POST(req, context) {
11447
10751
  var _a2, _b, _c, _d;
11448
10752
  const authResult = await checkAuth(req, onAuthorize);
11449
10753
  if (authResult) return authResult;
@@ -11499,7 +10803,7 @@ function createStreamHandler(configOrPlugin, options) {
11499
10803
  const plugin = getOrCreatePlugin(configOrPlugin);
11500
10804
  const storage = new DatabaseStorage(plugin.getConfig());
11501
10805
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11502
- return async function POST(req) {
10806
+ return async function POST(req, context) {
11503
10807
  var _a2;
11504
10808
  const authResult = await checkAuth(req, onAuthorize);
11505
10809
  if (authResult) return authResult;
@@ -11649,7 +10953,7 @@ function createStreamHandler(configOrPlugin, options) {
11649
10953
  function createIngestHandler(configOrPlugin, options) {
11650
10954
  const plugin = getOrCreatePlugin(configOrPlugin);
11651
10955
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11652
- return async function POST(req) {
10956
+ return async function POST(req, context) {
11653
10957
  const authResult = await checkAuth(req, onAuthorize);
11654
10958
  if (authResult) return authResult;
11655
10959
  try {
@@ -11693,7 +10997,7 @@ function createHealthHandler(configOrPlugin, options) {
11693
10997
  function createUploadHandler(configOrPlugin, options) {
11694
10998
  const plugin = getOrCreatePlugin(configOrPlugin);
11695
10999
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11696
- return async function POST(req) {
11000
+ return async function POST(req, context) {
11697
11001
  const authResult = await checkAuth(req, onAuthorize);
11698
11002
  if (authResult) return authResult;
11699
11003
  try {