@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.
@@ -106,644 +106,6 @@ var init_templateUtils = __esm({
106
106
  }
107
107
  });
108
108
 
109
- // ../../services/llm-gateway/providers/groq.ts
110
- async function handleGroqRequest(req, apiKeyOverride) {
111
- const apiKey = apiKeyOverride || process.env.GROQ_API_KEY;
112
- if (!apiKey) {
113
- throw new Error("LLM service credentials not configured.");
114
- }
115
- const modelName = req.model.replace(/^groq\//i, "");
116
- const payload = __spreadProps(__spreadValues({}, req), {
117
- model: modelName
118
- });
119
- const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
120
- method: "POST",
121
- headers: {
122
- "Content-Type": "application/json",
123
- "Authorization": `Bearer ${apiKey}`
124
- },
125
- body: JSON.stringify(payload)
126
- });
127
- if (!response.ok) {
128
- const errorText = await response.text();
129
- throw new Error(`Groq API Error (${response.status}): ${errorText}`);
130
- }
131
- if (req.stream && response.body) {
132
- return { stream: response.body };
133
- }
134
- const json = await response.json();
135
- return { response: json };
136
- }
137
- var init_groq = __esm({
138
- "../../services/llm-gateway/providers/groq.ts"() {
139
- "use strict";
140
- }
141
- });
142
-
143
- // ../../services/llm-gateway/providers/openai.ts
144
- async function handleOpenAIRequest(req, apiKeyOverride) {
145
- const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
146
- if (!apiKey) {
147
- throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
148
- }
149
- const modelName = req.model.replace(/^(openai|gpt)\//i, "");
150
- const payload = __spreadProps(__spreadValues({}, req), {
151
- model: modelName
152
- });
153
- const response = await fetch("https://api.openai.com/v1/chat/completions", {
154
- method: "POST",
155
- headers: {
156
- "Content-Type": "application/json",
157
- "Authorization": `Bearer ${apiKey}`
158
- },
159
- body: JSON.stringify(payload)
160
- });
161
- if (!response.ok) {
162
- const errorText = await response.text();
163
- throw new Error(`OpenAI API Error (${response.status}): ${errorText}`);
164
- }
165
- if (req.stream && response.body) {
166
- return { stream: response.body };
167
- }
168
- const json = await response.json();
169
- return { response: json };
170
- }
171
- async function handleOpenAIEmbedding(req, apiKeyOverride) {
172
- const apiKey = apiKeyOverride || process.env.OPENAI_API_KEY;
173
- if (!apiKey) {
174
- throw new Error("OpenAI API Key missing. Please set OPENAI_API_KEY in environment variables.");
175
- }
176
- const modelName = req.model.replace(/^(openai)\//i, "");
177
- const response = await fetch("https://api.openai.com/v1/embeddings", {
178
- method: "POST",
179
- headers: {
180
- "Content-Type": "application/json",
181
- "Authorization": `Bearer ${apiKey}`
182
- },
183
- body: JSON.stringify({
184
- model: modelName,
185
- input: req.input
186
- })
187
- });
188
- if (!response.ok) {
189
- const errorText = await response.text();
190
- throw new Error(`OpenAI Embedding API Error (${response.status}): ${errorText}`);
191
- }
192
- return await response.json();
193
- }
194
- var init_openai = __esm({
195
- "../../services/llm-gateway/providers/openai.ts"() {
196
- "use strict";
197
- }
198
- });
199
-
200
- // ../../services/llm-gateway/providers/gemini.ts
201
- async function handleGeminiRequest(req, apiKeyOverride) {
202
- const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
203
- if (!apiKey) {
204
- throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
205
- }
206
- let modelName = req.model.replace(/^(google|gemini)\//i, "");
207
- if (!modelName.startsWith("gemini-")) {
208
- modelName = `gemini-${modelName}`;
209
- }
210
- const payload = __spreadProps(__spreadValues({}, req), {
211
- model: modelName
212
- });
213
- const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/chat/completions", {
214
- method: "POST",
215
- headers: {
216
- "Content-Type": "application/json",
217
- "Authorization": `Bearer ${apiKey}`
218
- },
219
- body: JSON.stringify(payload)
220
- });
221
- if (!response.ok) {
222
- const errorText = await response.text();
223
- throw new Error(`Google Gemini API Error (${response.status}): ${errorText}`);
224
- }
225
- if (req.stream && response.body) {
226
- return { stream: response.body };
227
- }
228
- const json = await response.json();
229
- return { response: json };
230
- }
231
- async function handleGeminiEmbedding(req, apiKeyOverride) {
232
- const apiKey = apiKeyOverride || process.env.GEMINI_API_KEY;
233
- if (!apiKey) {
234
- throw new Error("Gemini API Key missing. Please set GEMINI_API_KEY in environment variables.");
235
- }
236
- let modelName = req.model.replace(/^(google|gemini)\//i, "");
237
- if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.startsWith("text-embedding-00") && !modelName.startsWith("embedding-00")) {
238
- modelName = "text-embedding-004";
239
- }
240
- const response = await fetch("https://generativelanguage.googleapis.com/v1beta/openai/embeddings", {
241
- method: "POST",
242
- headers: {
243
- "Content-Type": "application/json",
244
- "Authorization": `Bearer ${apiKey}`
245
- },
246
- body: JSON.stringify({
247
- model: modelName,
248
- input: req.input
249
- })
250
- });
251
- if (!response.ok) {
252
- const errorText = await response.text();
253
- throw new Error(`Google Gemini Embedding API Error (${response.status}): ${errorText}`);
254
- }
255
- return await response.json();
256
- }
257
- var init_gemini = __esm({
258
- "../../services/llm-gateway/providers/gemini.ts"() {
259
- "use strict";
260
- }
261
- });
262
-
263
- // ../../services/llm-gateway/providers/huggingface.ts
264
- async function handleHuggingFaceChatRequest(req, apiKeyOverride) {
265
- var _a2, _b;
266
- const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
267
- if (!apiKey) {
268
- throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
269
- }
270
- let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
271
- if (!modelName || modelName === "default" || modelName.toLowerCase() === "qwen" || modelName.toLowerCase() === "qwen-coder") {
272
- modelName = "Qwen/Qwen2.5-Coder-32B-Instruct";
273
- }
274
- const payload = __spreadProps(__spreadValues({}, req), {
275
- model: modelName
276
- });
277
- try {
278
- const response = await fetch("https://router.huggingface.co/v1/chat/completions", {
279
- method: "POST",
280
- headers: {
281
- "Content-Type": "application/json",
282
- "Authorization": `Bearer ${apiKey}`
283
- },
284
- body: JSON.stringify(payload)
285
- });
286
- if (response.ok) {
287
- if (req.stream && response.body) {
288
- return { stream: response.body };
289
- }
290
- const json = await response.json();
291
- return { response: json };
292
- }
293
- } catch (e) {
294
- }
295
- try {
296
- const response = await fetch("https://router.huggingface.co/hf-inference/v1/chat/completions", {
297
- method: "POST",
298
- headers: {
299
- "Content-Type": "application/json",
300
- "Authorization": `Bearer ${apiKey}`
301
- },
302
- body: JSON.stringify(payload)
303
- });
304
- if (response.ok) {
305
- if (req.stream && response.body) {
306
- return { stream: response.body };
307
- }
308
- const json = await response.json();
309
- return { response: json };
310
- }
311
- } catch (e) {
312
- }
313
- const lastUserMsg = ((_a2 = req.messages.filter((m) => m.role === "user").pop()) == null ? void 0 : _a2.content) || "Hello";
314
- const pipelineRes = await fetch(`https://router.huggingface.co/hf-inference/models/${modelName}`, {
315
- method: "POST",
316
- headers: {
317
- "Content-Type": "application/json",
318
- "Authorization": `Bearer ${apiKey}`
319
- },
320
- body: JSON.stringify({
321
- inputs: lastUserMsg,
322
- parameters: { max_new_tokens: req.max_tokens || 256, temperature: req.temperature || 0.7 },
323
- options: { wait_for_model: true }
324
- })
325
- });
326
- if (!pipelineRes.ok) {
327
- const errorText = await pipelineRes.text();
328
- throw new Error(`HuggingFace API Error (${pipelineRes.status}): ${errorText}`);
329
- }
330
- const raw = await pipelineRes.json();
331
- const textOutput = Array.isArray(raw) ? ((_b = raw[0]) == null ? void 0 : _b.generated_text) || JSON.stringify(raw) : JSON.stringify(raw);
332
- const formattedResponse = {
333
- id: `hf-${Date.now()}`,
334
- object: "chat.completion",
335
- created: Math.floor(Date.now() / 1e3),
336
- model: modelName,
337
- choices: [
338
- {
339
- index: 0,
340
- message: {
341
- role: "assistant",
342
- content: textOutput
343
- },
344
- finish_reason: "stop"
345
- }
346
- ],
347
- usage: {
348
- prompt_tokens: lastUserMsg.length,
349
- completion_tokens: textOutput.length,
350
- total_tokens: lastUserMsg.length + textOutput.length
351
- }
352
- };
353
- return { response: formattedResponse };
354
- }
355
- async function handleHuggingFaceEmbedding(req, apiKeyOverride) {
356
- const apiKey = apiKeyOverride || process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN;
357
- if (!apiKey) {
358
- throw new Error("HuggingFace API Key missing. Set HUGGINGFACE_API_KEY or HF_TOKEN in environment variables.");
359
- }
360
- let modelName = req.model.replace(/^(huggingface|hf)\//i, "");
361
- if (!modelName || modelName === "default" || modelName.includes("text-embedding-3") || modelName.includes("ada") || !modelName.includes("/") && !modelName.includes("bge") && !modelName.includes("sentence-transformers")) {
362
- modelName = "BAAI/bge-base-en-v1.5";
363
- }
364
- const inputs = Array.isArray(req.input) ? req.input : [req.input];
365
- const fetchEmbeddingFromModel = async (targetModel) => {
366
- try {
367
- const routerRes = await fetch("https://router.huggingface.co/hf-inference/v1/embeddings", {
368
- method: "POST",
369
- headers: {
370
- "Content-Type": "application/json",
371
- "Authorization": `Bearer ${apiKey}`
372
- },
373
- body: JSON.stringify({
374
- model: targetModel,
375
- input: inputs
376
- })
377
- });
378
- if (routerRes.ok) {
379
- const json = await routerRes.json();
380
- if (json && json.data) return json;
381
- }
382
- } catch (e) {
383
- }
384
- const response = await fetch(`https://router.huggingface.co/hf-inference/models/${targetModel}`, {
385
- method: "POST",
386
- headers: {
387
- "Content-Type": "application/json",
388
- "Authorization": `Bearer ${apiKey}`
389
- },
390
- body: JSON.stringify({
391
- inputs,
392
- options: { wait_for_model: true }
393
- })
394
- });
395
- if (!response.ok) {
396
- const errorText = await response.text();
397
- throw new Error(`HuggingFace API Error (${response.status}): ${errorText}`);
398
- }
399
- const rawData = await response.json();
400
- const embeddings = Array.isArray(rawData[0]) ? typeof rawData[0][0] === "number" ? rawData : rawData.map((arr) => arr[0]) : [rawData];
401
- return {
402
- object: "list",
403
- data: embeddings.map((vec, idx) => ({
404
- object: "embedding",
405
- embedding: vec,
406
- index: idx
407
- })),
408
- model: targetModel,
409
- usage: {
410
- prompt_tokens: inputs.reduce((acc, str) => acc + str.length, 0),
411
- completion_tokens: 0,
412
- total_tokens: inputs.reduce((acc, str) => acc + str.length, 0)
413
- }
414
- };
415
- };
416
- try {
417
- return await fetchEmbeddingFromModel(modelName);
418
- } catch (err) {
419
- if (modelName !== "BAAI/bge-base-en-v1.5") {
420
- console.warn(`[LLM Gateway] HuggingFace model ${modelName} failed. Falling back to BAAI/bge-base-en-v1.5...`, err);
421
- return await fetchEmbeddingFromModel("BAAI/bge-base-en-v1.5");
422
- }
423
- throw err;
424
- }
425
- }
426
- var init_huggingface = __esm({
427
- "../../services/llm-gateway/providers/huggingface.ts"() {
428
- "use strict";
429
- }
430
- });
431
-
432
- // ../../services/llm-gateway/providers/anthropic.ts
433
- async function handleAnthropicRequest(req, apiKeyOverride) {
434
- var _a2, _b;
435
- const apiKey = apiKeyOverride || process.env.ANTHROPIC_API_KEY;
436
- if (!apiKey) {
437
- throw new Error("Anthropic API Key missing. Please set ANTHROPIC_API_KEY in environment variables.");
438
- }
439
- const modelName = req.model.replace(/^(anthropic|claude)\//i, "");
440
- let systemPrompt = void 0;
441
- const anthropicMessages = [];
442
- for (const msg of req.messages) {
443
- if (msg.role === "system") {
444
- systemPrompt = systemPrompt ? `${systemPrompt}
445
- ${msg.content}` : msg.content;
446
- } else {
447
- anthropicMessages.push({
448
- role: msg.role === "assistant" ? "assistant" : "user",
449
- content: msg.content
450
- });
451
- }
452
- }
453
- if (anthropicMessages.length === 0) {
454
- anthropicMessages.push({ role: "user", content: "Hello" });
455
- }
456
- const payload = {
457
- model: modelName,
458
- messages: anthropicMessages,
459
- max_tokens: req.max_tokens || req.max_completion_tokens || 1024,
460
- stream: req.stream || false
461
- };
462
- if (systemPrompt) {
463
- payload.system = systemPrompt;
464
- }
465
- if (req.temperature !== void 0) {
466
- payload.temperature = req.temperature;
467
- }
468
- const response = await fetch("https://api.anthropic.com/v1/messages", {
469
- method: "POST",
470
- headers: {
471
- "Content-Type": "application/json",
472
- "x-api-key": apiKey,
473
- "anthropic-version": "2023-06-01"
474
- },
475
- body: JSON.stringify(payload)
476
- });
477
- if (!response.ok) {
478
- const errorText = await response.text();
479
- throw new Error(`Anthropic API Error (${response.status}): ${errorText}`);
480
- }
481
- if (req.stream && response.body) {
482
- return { stream: response.body };
483
- }
484
- const json = await response.json();
485
- const textContent = ((_b = (_a2 = json.content) == null ? void 0 : _a2[0]) == null ? void 0 : _b.text) || "";
486
- const openAIResponse = {
487
- id: json.id || `chatcmpl-${Date.now()}`,
488
- object: "chat.completion",
489
- created: Math.floor(Date.now() / 1e3),
490
- model: json.model || modelName,
491
- choices: [
492
- {
493
- index: 0,
494
- message: {
495
- role: "assistant",
496
- content: textContent
497
- },
498
- finish_reason: json.stop_reason === "end_turn" ? "stop" : json.stop_reason || "stop"
499
- }
500
- ],
501
- usage: json.usage ? {
502
- prompt_tokens: json.usage.input_tokens,
503
- completion_tokens: json.usage.output_tokens,
504
- total_tokens: json.usage.input_tokens + json.usage.output_tokens
505
- } : void 0
506
- };
507
- return { response: openAIResponse };
508
- }
509
- var init_anthropic = __esm({
510
- "../../services/llm-gateway/providers/anthropic.ts"() {
511
- "use strict";
512
- }
513
- });
514
-
515
- // ../../services/llm-gateway/providers/ollama.ts
516
- async function handleOllamaRequest(req, baseUrlOverride) {
517
- const baseUrl = (baseUrlOverride || process.env.OLLAMA_BASE_URL || "http://localhost:11434/v1").replace(/\/+$/, "");
518
- const modelName = req.model.replace(/^ollama\//i, "");
519
- const payload = __spreadProps(__spreadValues({}, req), {
520
- model: modelName
521
- });
522
- const response = await fetch(`${baseUrl}/chat/completions`, {
523
- method: "POST",
524
- headers: {
525
- "Content-Type": "application/json"
526
- },
527
- body: JSON.stringify(payload)
528
- });
529
- if (!response.ok) {
530
- const errorText = await response.text();
531
- throw new Error(`Ollama API Error (${response.status}): ${errorText}`);
532
- }
533
- if (req.stream && response.body) {
534
- return { stream: response.body };
535
- }
536
- const json = await response.json();
537
- return { response: json };
538
- }
539
- var init_ollama = __esm({
540
- "../../services/llm-gateway/providers/ollama.ts"() {
541
- "use strict";
542
- }
543
- });
544
-
545
- // ../../services/llm-gateway/router.ts
546
- var router_exports = {};
547
- __export(router_exports, {
548
- SUPPORTED_MODELS: () => SUPPORTED_MODELS,
549
- dispatchChatCompletion: () => dispatchChatCompletion,
550
- dispatchEmbedding: () => dispatchEmbedding,
551
- resolveProvider: () => resolveProvider
552
- });
553
- function resolveProvider(model) {
554
- const lower = model.toLowerCase();
555
- if (lower.startsWith("huggingface/") || lower.startsWith("hf/")) {
556
- return "huggingface";
557
- }
558
- if (lower.startsWith("ollama/")) {
559
- return "ollama";
560
- }
561
- if (lower.startsWith("groq/") || lower.includes("llama") || lower.includes("qwen") || lower.includes("mixtral")) {
562
- return "groq";
563
- }
564
- if (process.env.GROQ_API_KEY) return "groq";
565
- if (process.env.OPENAI_API_KEY) return "openai";
566
- if (process.env.GEMINI_API_KEY) return "gemini";
567
- if (process.env.ANTHROPIC_API_KEY) return "anthropic";
568
- if (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY) return "huggingface";
569
- return "groq";
570
- }
571
- function cleanApiKeyOverride(apiKeyOverride) {
572
- if (!apiKeyOverride) return void 0;
573
- const key = apiKeyOverride.trim();
574
- if (key === process.env.LITELLM_API_KEY || key === process.env.LITELLM_MASTER_KEY || key.startsWith("sk-retrivora") || !key.startsWith("gsk_") && !key.startsWith("AIza") && !key.startsWith("sk-ant-") && !key.startsWith("sk-proj-")) {
575
- return void 0;
576
- }
577
- return key;
578
- }
579
- async function resolveUserGatewayConfig(apiKeyOverride) {
580
- var _a2;
581
- if (!apiKeyOverride || !process.env.NEXT_PUBLIC_SUPABASE_URL || !process.env.SUPABASE_SERVICE_ROLE_KEY) {
582
- return {};
583
- }
584
- try {
585
- const { createAdminClient } = await import("@/lib/supabase-server");
586
- const supabase = createAdminClient();
587
- const { data: licenseRecord } = await supabase.from("licenses").select("project_id, customer_name, tier").eq("license_key", apiKeyOverride.trim()).single();
588
- if (!licenseRecord) {
589
- return {};
590
- }
591
- const projectId = licenseRecord.project_id;
592
- 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);
593
- if (!configs || configs.length === 0) {
594
- return {};
595
- }
596
- const matchedConfig = configs.find((c) => c.project_id === projectId) || configs.find((c) => c.project_id === "global");
597
- const customGroqKey = (_a2 = matchedConfig == null ? void 0 : matchedConfig.provider_keys) == null ? void 0 : _a2.groq;
598
- const targetModel = matchedConfig == null ? void 0 : matchedConfig.default_model;
599
- return { customGroqKey, targetModel };
600
- } catch (err) {
601
- console.warn("[LLM Gateway Router] Error resolving user gateway_config:", err.message);
602
- return {};
603
- }
604
- }
605
- async function dispatchChatCompletion(req, apiKeyOverride) {
606
- const { customGroqKey, targetModel } = await resolveUserGatewayConfig(apiKeyOverride);
607
- const effectiveKey = customGroqKey || cleanApiKeyOverride(apiKeyOverride);
608
- const activeModel = req.model || targetModel || "llama-3.1-8b-instant";
609
- const provider = resolveProvider(activeModel);
610
- try {
611
- switch (provider) {
612
- case "groq":
613
- return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
614
- case "openai":
615
- return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
616
- case "gemini":
617
- return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
618
- case "anthropic":
619
- return await handleAnthropicRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
620
- case "ollama":
621
- return await handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }));
622
- case "huggingface":
623
- return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: activeModel }), effectiveKey);
624
- default:
625
- throw new Error(`Unsupported LLM provider for model: ${activeModel}`);
626
- }
627
- } catch (error) {
628
- console.error(`[LLM Gateway Router] Provider '${provider}' failed for model '${req.model}':`, {
629
- message: error.message,
630
- stack: error.stack
631
- });
632
- if (/rate[- ]?limit|429|exhausted/i.test(error.message)) {
633
- const isGroqKey = process.env.GROQ_API_KEY || effectiveKey && effectiveKey.startsWith("gsk_");
634
- const reqModelLower = req.model.toLowerCase();
635
- if (isGroqKey && !reqModelLower.includes("llama-3.3-70b")) {
636
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to secondary Groq model (llama-3.3-70b-versatile)...`);
637
- try {
638
- return await handleGroqRequest(__spreadProps(__spreadValues({}, req), { model: "llama-3.3-70b-versatile" }), effectiveKey);
639
- } catch (fErr) {
640
- console.error("[LLM Gateway] Fallback groq/llama-3.3-70b-versatile failed:", fErr.message);
641
- }
642
- }
643
- const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
644
- if (provider !== "gemini" && geminiKey && (geminiKey.startsWith("AIza") || !geminiKey.startsWith("AQ."))) {
645
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Google Gemini (gemini-2.5-flash)...`);
646
- try {
647
- return await handleGeminiRequest(__spreadProps(__spreadValues({}, req), { model: "gemini-2.5-flash" }), effectiveKey);
648
- } catch (fErr) {
649
- console.error("[LLM Gateway] Fallback gemini-2.5-flash failed:", fErr.message);
650
- }
651
- }
652
- if (provider !== "huggingface" && (process.env.HF_TOKEN || process.env.HUGGINGFACE_API_KEY)) {
653
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to Hugging Face (Qwen/Qwen2.5-Coder-32B-Instruct)...`);
654
- try {
655
- return await handleHuggingFaceChatRequest(__spreadProps(__spreadValues({}, req), { model: "Qwen/Qwen2.5-Coder-32B-Instruct" }), effectiveKey);
656
- } catch (fErr) {
657
- console.error("[LLM Gateway] Fallback HuggingFace Qwen failed:", fErr.message);
658
- }
659
- }
660
- if (provider !== "openai" && process.env.OPENAI_API_KEY) {
661
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to OpenAI (gpt-4o-mini)...`);
662
- try {
663
- return await handleOpenAIRequest(__spreadProps(__spreadValues({}, req), { model: "gpt-4o-mini" }), effectiveKey);
664
- } catch (e) {
665
- }
666
- }
667
- console.warn(`[LLM Gateway] Provider ${provider} rate limited (${error.message}). Falling back to local Ollama (llama3.2)...`);
668
- return handleOllamaRequest(__spreadProps(__spreadValues({}, req), { model: "llama3.2" }));
669
- }
670
- throw error;
671
- }
672
- }
673
- async function dispatchEmbedding(req, apiKeyOverride) {
674
- const effectiveKey = cleanApiKeyOverride(apiKeyOverride);
675
- if (req.model.startsWith("hf/") || req.model.startsWith("huggingface/") || req.model.includes("bge-")) {
676
- try {
677
- return await handleHuggingFaceEmbedding(req, effectiveKey);
678
- } catch (err) {
679
- console.warn("[LLM Gateway] HuggingFace explicit model embedding failed, falling back to default gateway chain:", err);
680
- }
681
- }
682
- const geminiKey = process.env.GEMINI_API_KEY || effectiveKey;
683
- const isGeminiKeyValid = Boolean(geminiKey && !geminiKey.startsWith("eyJ"));
684
- if (isGeminiKeyValid) {
685
- try {
686
- return await handleGeminiEmbedding(req, effectiveKey);
687
- } catch (err) {
688
- console.warn("[LLM Gateway] Gemini embedding failed:", err);
689
- }
690
- }
691
- if (process.env.OPENAI_API_KEY) {
692
- try {
693
- return await handleOpenAIEmbedding(req, effectiveKey);
694
- } catch (err) {
695
- console.warn("[LLM Gateway] OpenAI embedding failed:", err);
696
- }
697
- }
698
- if (process.env.HUGGINGFACE_API_KEY || process.env.HF_TOKEN) {
699
- try {
700
- return await handleHuggingFaceEmbedding(req, effectiveKey);
701
- } catch (err) {
702
- console.warn("[LLM Gateway] HuggingFace fallback embedding failed:", err);
703
- }
704
- }
705
- return handleGeminiEmbedding(req, effectiveKey);
706
- }
707
- var SUPPORTED_MODELS;
708
- var init_router = __esm({
709
- "../../services/llm-gateway/router.ts"() {
710
- "use strict";
711
- init_groq();
712
- init_openai();
713
- init_gemini();
714
- init_huggingface();
715
- init_anthropic();
716
- init_ollama();
717
- SUPPORTED_MODELS = [
718
- { id: "groq/llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
719
- { id: "llama-3.1-8b-instant", object: "model", created: 17e8, owned_by: "groq" },
720
- { id: "groq/llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
721
- { id: "llama-3.3-70b-versatile", object: "model", created: 17e8, owned_by: "groq" },
722
- { id: "gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
723
- { id: "openai/gpt-4o-mini", object: "model", created: 17e8, owned_by: "openai" },
724
- { id: "gpt-4o", object: "model", created: 17e8, owned_by: "openai" },
725
- { id: "gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
726
- { id: "google/gemini-2.5-flash", object: "model", created: 17e8, owned_by: "google" },
727
- { id: "claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
728
- { id: "anthropic/claude-3-5-haiku-20241022", object: "model", created: 17e8, owned_by: "anthropic" },
729
- { id: "text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
730
- { id: "google/text-embedding-004", object: "model", created: 17e8, owned_by: "google" },
731
- { id: "BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
732
- { id: "huggingface/BAAI/bge-base-en-v1.5", object: "model", created: 17e8, owned_by: "huggingface" },
733
- { id: "groq/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
734
- { id: "qwen/qwen3-32b", object: "model", created: 17e8, owned_by: "groq" },
735
- { id: "qwen/qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
736
- { id: "qwen3-embedding-8b", object: "model", created: 17e8, owned_by: "qwen" },
737
- { id: "ollama/llama3.2", object: "model", created: 17e8, owned_by: "ollama" }
738
- ];
739
- if (typeof globalThis !== "undefined") {
740
- const _g2 = globalThis;
741
- _g2.__retrivoraDispatchChat = dispatchChatCompletion;
742
- _g2.__retrivoraDispatchEmbedding = dispatchEmbedding;
743
- }
744
- }
745
- });
746
-
747
109
  // src/providers/vectordb/BaseVectorProvider.ts
748
110
  var BaseVectorProvider;
749
111
  var init_BaseVectorProvider = __esm({
@@ -800,8 +162,8 @@ var init_ConfigFetcher = __esm({
800
162
  process.env.NEXT_PUBLIC_RETRIVORA_CONTROL_PLANE_URL,
801
163
  "https://www.retrivora.com",
802
164
  "https://retrivora.com",
803
- "http://localhost:3001",
804
- "http://localhost:3000"
165
+ "http://localhost:3000",
166
+ "http://localhost:3001"
805
167
  ].filter(Boolean);
806
168
  for (const baseUrl of controlPlaneUrls) {
807
169
  try {
@@ -3356,7 +2718,7 @@ function getEnvConfig(env = process.env, base) {
3356
2718
  },
3357
2719
  telemetry: {
3358
2720
  enabled: telemetryEnabled,
3359
- 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"
2721
+ 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"
3360
2722
  }
3361
2723
  }, readString(env, "GRAPH_DB_PROVIDER") ? {
3362
2724
  graphDb: {
@@ -4605,9 +3967,7 @@ var OPENAI_BASE = {
4605
3967
  };
4606
3968
  var LLM_PROFILES = {
4607
3969
  "openai-compatible": OPENAI_BASE,
4608
- "litellm": __spreadProps(__spreadValues({}, OPENAI_BASE), {
4609
- chatPayloadTemplate: '{"model":"{{model}}","messages":{{messages}},"max_tokens":{{maxTokens}},"temperature":{{temperature}},"stream":false}'
4610
- }),
3970
+ "litellm": __spreadValues({}, OPENAI_BASE),
4611
3971
  "anthropic-claude": {
4612
3972
  chatPath: "/v1/messages",
4613
3973
  responseExtractPath: "content[0].text",
@@ -4713,18 +4073,7 @@ ${context != null ? context : "None"}` },
4713
4073
  }
4714
4074
  } catch (httpErr) {
4715
4075
  const _g2 = globalThis;
4716
- let dispatch = _g2.__retrivoraDispatchChat;
4717
- if (typeof dispatch !== "function") {
4718
- try {
4719
- const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
4720
- if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
4721
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4722
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4723
- dispatch = gateway.dispatchChatCompletion;
4724
- }
4725
- } catch (e) {
4726
- }
4727
- }
4076
+ const dispatch = _g2.__retrivoraDispatchChat;
4728
4077
  if (typeof dispatch === "function") {
4729
4078
  const res = await dispatch({
4730
4079
  model: this.model,
@@ -4750,11 +4099,10 @@ ${context != null ? context : "None"}` },
4750
4099
  /**
4751
4100
  * Streaming chat using native fetch + ReadableStream.
4752
4101
  * Parses OpenAI-compatible SSE frames: `data: {...}\n\n`
4753
- * Works with vLLM, LMStudio, Together AI, Fireworks, and any OpenAI-compatible API.
4754
4102
  */
4755
4103
  chatStream(messages, context) {
4756
4104
  return __asyncGenerator(this, null, function* () {
4757
- var _a2, _b, _c, _d, _e;
4105
+ var _a2, _b, _c, _d, _e, _f;
4758
4106
  const path2 = (_a2 = this.opts.chatPath) != null ? _a2 : "/chat/completions";
4759
4107
  const url = `${this.baseUrl.replace(/\/$/, "")}${path2}`;
4760
4108
  const extractPath = ((_b = this.opts.responseExtractPath) != null ? _b : "choices[0].message.content").replace("message.content", "delta.content");
@@ -4789,22 +4137,35 @@ ${context != null ? context : "None"}` },
4789
4137
  stream: true
4790
4138
  };
4791
4139
  }
4792
- const isSelfHost = this.baseUrl.includes("retrivora.com") || this.baseUrl.includes("localhost");
4793
4140
  let streamBody = null;
4794
- if (isSelfHost || Boolean(process.env.VERCEL)) {
4795
- const _g2 = globalThis;
4796
- let dispatch = _g2.__retrivoraDispatchChat;
4797
- if (typeof dispatch !== "function") {
4798
- try {
4799
- const gateway = yield new __await(Promise.resolve().then(() => (init_router(), router_exports)));
4800
- if (gateway == null ? void 0 : gateway.dispatchChatCompletion) {
4801
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4802
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4803
- dispatch = gateway.dispatchChatCompletion;
4141
+ try {
4142
+ const response = yield new __await(fetch(url, {
4143
+ method: "POST",
4144
+ headers: this.resolvedHeaders,
4145
+ body: typeof payload === "string" ? payload : JSON.stringify(payload)
4146
+ }));
4147
+ if (response.ok) {
4148
+ const contentType = response.headers.get("content-type") || "";
4149
+ if (contentType.includes("application/json")) {
4150
+ const json = yield new __await(response.json());
4151
+ const text = (_c = resolvePath(json, extractPath)) != null ? _c : extractContent(json);
4152
+ if (text && typeof text === "string") {
4153
+ yield text;
4154
+ return;
4804
4155
  }
4805
- } catch (e) {
4156
+ } else if (response.body) {
4157
+ streamBody = response.body;
4806
4158
  }
4159
+ } else {
4160
+ const errorText = yield new __await(response.text().catch(() => response.statusText));
4161
+ console.warn(`[UniversalLLMAdapter] Remote HTTP stream returned ${response.status}: ${errorText}. Attempting in-process fallback...`);
4807
4162
  }
4163
+ } catch (fetchErr) {
4164
+ console.warn(`[UniversalLLMAdapter] Remote HTTP stream fetch warning: ${fetchErr == null ? void 0 : fetchErr.message}. Attempting in-process fallback...`);
4165
+ }
4166
+ if (!streamBody) {
4167
+ const _g2 = globalThis;
4168
+ const dispatch = _g2.__retrivoraDispatchChat;
4808
4169
  if (typeof dispatch === "function") {
4809
4170
  try {
4810
4171
  const res = yield new __await(dispatch({
@@ -4822,29 +4183,14 @@ ${context != null ? context : "None"}` },
4822
4183
  yield content;
4823
4184
  return;
4824
4185
  }
4825
- throw new Error(`[UniversalLLMAdapter] In-process dispatch stream returned empty response for model: ${this.model}`);
4826
4186
  }
4827
4187
  } catch (dispatchErr) {
4828
- throw dispatchErr;
4188
+ console.warn("[UniversalLLMAdapter] In-process dispatch error:", dispatchErr);
4829
4189
  }
4830
- } else {
4831
- 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.`);
4832
4190
  }
4833
4191
  }
4834
4192
  if (!streamBody) {
4835
- const response = yield new __await(fetch(url, {
4836
- method: "POST",
4837
- headers: this.resolvedHeaders,
4838
- body: JSON.stringify(payload)
4839
- }));
4840
- if (!response.ok) {
4841
- const errorText = yield new __await(response.text().catch(() => response.statusText));
4842
- throw new Error(`[UniversalLLMAdapter] Streaming request failed (${response.status}): ${errorText}`);
4843
- }
4844
- if (!response.body) {
4845
- throw new Error("[UniversalLLMAdapter] Response body is null \u2014 server did not send a streaming response.");
4846
- }
4847
- streamBody = response.body;
4193
+ throw new Error(`[UniversalLLMAdapter] Streaming request failed. Ensure RETRIVORA_LICENSE_KEY is valid or LLM service is available.`);
4848
4194
  }
4849
4195
  const reader = streamBody.getReader();
4850
4196
  const decoder = new TextDecoder("utf-8");
@@ -4855,14 +4201,14 @@ ${context != null ? context : "None"}` },
4855
4201
  if (done) break;
4856
4202
  buffer += decoder.decode(value, { stream: true });
4857
4203
  const lines = buffer.split("\n");
4858
- buffer = (_c = lines.pop()) != null ? _c : "";
4204
+ buffer = (_d = lines.pop()) != null ? _d : "";
4859
4205
  for (const line of lines) {
4860
4206
  const trimmed = line.trim();
4861
4207
  if (!trimmed || trimmed === "data: [DONE]") continue;
4862
4208
  if (!trimmed.startsWith("data:")) continue;
4863
4209
  try {
4864
4210
  const json = JSON.parse(trimmed.slice(5).trim());
4865
- const text = (_d = resolvePath(json, extractPath)) != null ? _d : extractContent(json);
4211
+ const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
4866
4212
  if (text && typeof text === "string") yield text;
4867
4213
  } catch (e) {
4868
4214
  }
@@ -4872,7 +4218,7 @@ ${context != null ? context : "None"}` },
4872
4218
  const jsonStr = buffer.replace(/^data:\s*/, "").trim();
4873
4219
  try {
4874
4220
  const json = JSON.parse(jsonStr);
4875
- const text = (_e = resolvePath(json, extractPath)) != null ? _e : extractContent(json);
4221
+ const text = (_f = resolvePath(json, extractPath)) != null ? _f : extractContent(json);
4876
4222
  if (text && typeof text === "string") yield text;
4877
4223
  } catch (e) {
4878
4224
  }
@@ -4885,74 +4231,42 @@ ${context != null ? context : "None"}` },
4885
4231
  async embed(text) {
4886
4232
  var _a2, _b, _c, _d, _e;
4887
4233
  const path2 = (_a2 = this.opts.embedPath) != null ? _a2 : "/embeddings";
4888
- let payload;
4889
- if (this.opts.embedPayloadTemplate) {
4890
- payload = buildPayload(this.opts.embedPayloadTemplate, {
4891
- model: this.model,
4892
- input: text
4893
- });
4894
- } else {
4895
- payload = {
4896
- model: this.model,
4897
- input: text
4898
- };
4899
- }
4234
+ const payload = this.opts.embedPayloadTemplate ? buildPayload(this.opts.embedPayloadTemplate, { input: text, model: this.model }) : { input: text, model: this.model };
4900
4235
  try {
4901
4236
  const { data: data2 } = await this.http.post(path2, payload);
4902
4237
  const extractPath2 = (_b = this.opts.embedExtractPath) != null ? _b : "data[0].embedding";
4903
4238
  const vector2 = resolvePath(data2, extractPath2);
4904
- if (Array.isArray(vector2)) {
4905
- return vector2;
4906
- }
4907
- } catch (httpErr) {
4908
- console.warn(`[UniversalLLMAdapter] Direct HTTP embedding POST to ${this.baseUrl}${path2} failed (${httpErr.message}). Attempting in-process gateway dispatch fallback...`);
4239
+ if (Array.isArray(vector2)) return vector2;
4240
+ } catch (e) {
4909
4241
  const _g2 = globalThis;
4910
- let dispatch = _g2.__retrivoraDispatchEmbedding;
4911
- if (typeof dispatch !== "function") {
4912
- try {
4913
- const gateway = await Promise.resolve().then(() => (init_router(), router_exports));
4914
- if (gateway == null ? void 0 : gateway.dispatchEmbedding) {
4915
- _g2.__retrivoraDispatchChat = gateway.dispatchChatCompletion;
4916
- _g2.__retrivoraDispatchEmbedding = gateway.dispatchEmbedding;
4917
- dispatch = gateway.dispatchEmbedding;
4918
- }
4919
- } catch (e) {
4920
- }
4921
- }
4922
- if (typeof dispatch === "function") {
4923
- const res = await dispatch({
4924
- model: this.model,
4925
- input: text
4926
- }, this.apiKey);
4242
+ const dispatchEmbed = _g2.__retrivoraDispatchEmbedding;
4243
+ if (typeof dispatchEmbed === "function") {
4244
+ const res = await dispatchEmbed({ input: text, model: this.model }, this.apiKey);
4927
4245
  if ((_d = (_c = res == null ? void 0 : res.data) == null ? void 0 : _c[0]) == null ? void 0 : _d.embedding) {
4928
4246
  return res.data[0].embedding;
4929
4247
  }
4930
4248
  }
4931
- throw httpErr;
4932
4249
  }
4933
4250
  const { data } = await this.http.post(path2, payload);
4934
4251
  const extractPath = (_e = this.opts.embedExtractPath) != null ? _e : "data[0].embedding";
4935
4252
  const vector = resolvePath(data, extractPath);
4936
4253
  if (!Array.isArray(vector)) {
4937
- throw new Error(`[UniversalLLMAdapter] Expected a number array at '${extractPath}' for embeddings.`);
4254
+ throw new Error(`[UniversalLLMAdapter] Could not extract embedding vector from path '${extractPath}' in response.`);
4938
4255
  }
4939
4256
  return vector;
4940
4257
  }
4941
4258
  async batchEmbed(texts) {
4942
- const vectors = [];
4259
+ const results = [];
4943
4260
  for (const text of texts) {
4944
- vectors.push(await this.embed(text));
4261
+ results.push(await this.embed(text));
4945
4262
  }
4946
- return vectors;
4263
+ return results;
4947
4264
  }
4948
4265
  async ping() {
4949
4266
  try {
4950
- if (this.opts.pingPath) {
4951
- await this.http.get(this.opts.pingPath);
4952
- }
4267
+ await this.embed("ping");
4953
4268
  return true;
4954
- } catch (err) {
4955
- console.error("[UniversalLLMAdapter] Ping failed:", err);
4269
+ } catch (e) {
4956
4270
  return false;
4957
4271
  }
4958
4272
  }
@@ -5358,7 +4672,7 @@ var ConfigValidator = class {
5358
4672
  // package.json
5359
4673
  var package_default = {
5360
4674
  name: "@retrivora-ai/rag-engine",
5361
- version: "2.2.4",
4675
+ version: "2.2.5",
5362
4676
  description: "Retrivora AI is a plug-and-play AI engine for RAG chat experiences \u2014 generic vector DB + LLM provider, embeddable or standalone.",
5363
4677
  author: "Abhinav Alkuchi",
5364
4678
  license: "UNLICENSED",
@@ -5395,6 +4709,8 @@ var package_default = {
5395
4709
  import: "./dist/index.mjs"
5396
4710
  },
5397
4711
  "./style.css": "./dist/index.css",
4712
+ "./index.css": "./dist/index.css",
4713
+ "./styles.css": "./dist/index.css",
5398
4714
  "./handlers": {
5399
4715
  types: "./dist/handlers/index.d.ts",
5400
4716
  require: "./dist/handlers/index.js",
@@ -7563,19 +6879,6 @@ var UITransformer = class _UITransformer {
7563
6879
  if (!retrievedData || retrievedData.length === 0) {
7564
6880
  return this.createTextResponse("No data available", "No relevant data found for your query.");
7565
6881
  }
7566
- console.log("[UITransformer.transform] Processing retrievedData:", {
7567
- userQuery,
7568
- retrievedCount: retrievedData.length,
7569
- sample: retrievedData.slice(0, 2).map((item) => {
7570
- var _a3;
7571
- return {
7572
- id: item == null ? void 0 : item.id,
7573
- contentType: typeof (item == null ? void 0 : item.content),
7574
- contentSnippet: String((_a3 = item == null ? void 0 : item.content) != null ? _a3 : "").substring(0, 150),
7575
- metadataKeys: Object.keys((item == null ? void 0 : item.metadata) || {})
7576
- };
7577
- })
7578
- });
7579
6882
  const resolvedIntent = intent != null ? intent : this.detectIntentHeuristic(userQuery);
7580
6883
  const filteredData = resolvedIntent.filterInStockOnly ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
7581
6884
  const profile = this.profileData(filteredData);
@@ -8915,59 +8218,70 @@ RULES:
8915
8218
  var SchemaMapper = class {
8916
8219
  /**
8917
8220
  * Trains the plugin on a set of keys.
8918
- * This is done once per schema and cached.
8221
+ * Results are cached in-process; concurrent calls for the same key set are
8222
+ * deduplicated to a single LLM request.
8919
8223
  */
8920
8224
  static async train(llm, projectId, keys) {
8921
- const cacheKey = `${projectId}:${keys.sort().join(",")}`;
8225
+ const cacheKey = `${projectId}:${keys.slice().sort().join(",")}`;
8922
8226
  if (this.cache.has(cacheKey)) {
8923
8227
  return this.cache.get(cacheKey);
8924
8228
  }
8925
- console.log(`[SchemaMapper] \u{1F9E0} Training AI on new schema keys: ${keys.join(", ")}`);
8229
+ if (this.pending.has(cacheKey)) {
8230
+ return this.pending.get(cacheKey);
8231
+ }
8232
+ const promise = this._doTrain(llm, cacheKey, keys);
8233
+ this.pending.set(cacheKey, promise);
8234
+ promise.finally(() => this.pending.delete(cacheKey));
8235
+ return promise;
8236
+ }
8237
+ static async _doTrain(llm, cacheKey, keys) {
8238
+ var _a2, _b, _c, _d, _e, _f, _g2, _h, _i, _j, _k;
8239
+ console.log(`[SchemaMapper] \u{1F9E0} Training on new schema keys: ${keys.join(", ")}`);
8926
8240
  const propertyList = Object.entries(this.TARGET_PROPERTIES).map(([prop, desc]) => `- ${prop} (${desc})`).join("\n");
8927
- const prompt = `
8928
- Given these metadata keys from a database: [${keys.join(", ")}]
8241
+ const messages = [
8242
+ { role: "system", content: "You are a database schema expert. Respond ONLY with valid JSON." },
8243
+ {
8244
+ role: "user",
8245
+ content: `Keys: [${keys.join(", ")}]
8929
8246
 
8930
- Identify which keys best correspond to these standard UI properties:
8247
+ Map to:
8931
8248
  ${propertyList}
8932
8249
 
8933
- 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.
8934
- If no good match is found for a property, omit it.
8935
-
8936
- Example:
8937
- {
8938
- "name": "Title",
8939
- "price": "Variant Price",
8940
- "brand": "Vendor",
8941
- "image": "Image Src",
8942
- "stock": "Variant Inventory Qty"
8943
- }
8944
- `;
8250
+ Return a JSON object like {"name":"Title","price":"Price",...}. Omit unmapped properties.`
8251
+ }
8252
+ ];
8945
8253
  try {
8946
- const response = await llm.chat(
8947
- [
8948
- { role: "system", content: "You are a database schema expert. You ONLY respond with valid JSON." },
8949
- { role: "user", content: prompt }
8950
- ],
8951
- ""
8952
- );
8953
- const startIdx = response.indexOf("{");
8954
- if (startIdx !== -1) {
8955
- let braceCount = 0;
8956
- let endIdx = -1;
8957
- for (let i = startIdx; i < response.length; i++) {
8958
- if (response[i] === "{") braceCount++;
8959
- else if (response[i] === "}") {
8960
- braceCount--;
8961
- if (braceCount === 0) {
8962
- endIdx = i;
8963
- break;
8964
- }
8965
- }
8254
+ const baseUrl = (_a2 = llm == null ? void 0 : llm.baseUrl) != null ? _a2 : "";
8255
+ const apiKey = (_b = llm == null ? void 0 : llm.apiKey) != null ? _b : "";
8256
+ const model = (_c = llm == null ? void 0 : llm.model) != null ? _c : "llama-3.1-8b-instant";
8257
+ let responseText;
8258
+ if (baseUrl) {
8259
+ const endpoint = `${baseUrl.replace(/\/$/, "")}/chat/completions`;
8260
+ const headers = { "Content-Type": "application/json" };
8261
+ if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
8262
+ const res = await fetch(endpoint, {
8263
+ method: "POST",
8264
+ headers,
8265
+ body: JSON.stringify({
8266
+ model,
8267
+ messages,
8268
+ max_tokens: 256,
8269
+ // Only needs a small JSON object back
8270
+ temperature: 0,
8271
+ stream: false
8272
+ }),
8273
+ signal: AbortSignal.timeout(8e3)
8274
+ });
8275
+ if (res.ok) {
8276
+ const data = await res.json();
8277
+ 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;
8278
+ } else {
8279
+ console.warn(`[SchemaMapper] LLM returned ${res.status}, falling back to heuristics.`);
8966
8280
  }
8967
- if (endIdx !== -1) {
8968
- const jsonContent = response.substring(startIdx, endIdx + 1);
8969
- const cleanJson = this.sanitizeJson(jsonContent);
8970
- const mapping = JSON.parse(cleanJson);
8281
+ }
8282
+ if (responseText) {
8283
+ const mapping = this._parseJson(responseText);
8284
+ if (mapping) {
8971
8285
  this.cache.set(cacheKey, mapping);
8972
8286
  return mapping;
8973
8287
  }
@@ -8975,23 +8289,42 @@ Example:
8975
8289
  } catch (error) {
8976
8290
  console.warn("[SchemaMapper] AI training failed, falling back to heuristics:", error);
8977
8291
  }
8292
+ this.cache.set(cacheKey, {});
8978
8293
  return {};
8979
8294
  }
8980
- /**
8981
- * Forgiving JSON parser that fixes common AI formatting mistakes.
8982
- */
8983
- static sanitizeJson(s) {
8295
+ static _parseJson(text) {
8296
+ const startIdx = text.indexOf("{");
8297
+ if (startIdx === -1) return null;
8298
+ let braceCount = 0;
8299
+ let endIdx = -1;
8300
+ for (let i = startIdx; i < text.length; i++) {
8301
+ if (text[i] === "{") braceCount++;
8302
+ else if (text[i] === "}") {
8303
+ braceCount--;
8304
+ if (braceCount === 0) {
8305
+ endIdx = i;
8306
+ break;
8307
+ }
8308
+ }
8309
+ }
8310
+ if (endIdx === -1) return null;
8311
+ try {
8312
+ return JSON.parse(this._sanitizeJson(text.substring(startIdx, endIdx + 1)));
8313
+ } catch (e) {
8314
+ return null;
8315
+ }
8316
+ }
8317
+ static _sanitizeJson(s) {
8984
8318
  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();
8985
8319
  }
8986
8320
  static getCached(projectId, keys) {
8987
- const cacheKey = `${projectId}:${keys.sort().join(",")}`;
8321
+ const cacheKey = `${projectId}:${keys.slice().sort().join(",")}`;
8988
8322
  return this.cache.get(cacheKey);
8989
8323
  }
8990
8324
  };
8991
8325
  SchemaMapper.cache = /* @__PURE__ */ new Map();
8992
- /**
8993
- * Descriptions of standard UI properties to help the AI map fields accurately.
8994
- */
8326
+ /** In-flight deduplication — prevents concurrent identical LLM calls. */
8327
+ SchemaMapper.pending = /* @__PURE__ */ new Map();
8995
8328
  SchemaMapper.TARGET_PROPERTIES = {
8996
8329
  name: "The primary title, name, or label of the item",
8997
8330
  price: "The numeric cost, price, MSRP, or amount",
@@ -9463,19 +8796,6 @@ ${m.content}`).join("\n\n---\n\n");
9463
8796
  const wantsExhaustiveList = true;
9464
8797
  const retrievalLimit = Math.max(topK * 50, 1e3);
9465
8798
  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"));
9466
- console.log("[Pipeline] Raw vectorDB.query response:", {
9467
- rawCount: rawSources.length,
9468
- sample: rawSources.slice(0, 2).map((s) => {
9469
- var _a3;
9470
- return {
9471
- id: s == null ? void 0 : s.id,
9472
- score: s == null ? void 0 : s.score,
9473
- contentType: typeof (s == null ? void 0 : s.content),
9474
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9475
- metadataKeys: Object.keys((s == null ? void 0 : s.metadata) || {})
9476
- };
9477
- })
9478
- });
9479
8799
  const retrieveEnd = performance.now();
9480
8800
  const embedMs = retrieveEnd - embedStart;
9481
8801
  const retrieveMs = retrieveEnd - embedStart;
@@ -9504,21 +8824,6 @@ ${(_a3 = m == null ? void 0 : m.content) != null ? _a3 : ""}`;
9504
8824
  var _a3, _b2;
9505
8825
  return ((_a3 = b == null ? void 0 : b.score) != null ? _a3 : 0) - ((_b2 = a == null ? void 0 : a.score) != null ? _b2 : 0);
9506
8826
  });
9507
- console.log("[Pipeline] Final sources for prompt & UI:", {
9508
- count: sources.length,
9509
- totalRawCount: rawSources.length,
9510
- sources: sources.slice(0, 10).map((s, idx) => {
9511
- var _a3;
9512
- return {
9513
- rank: idx + 1,
9514
- id: s == null ? void 0 : s.id,
9515
- score: s == null ? void 0 : s.score,
9516
- contentType: typeof (s == null ? void 0 : s.content),
9517
- contentSnippet: String((_a3 = s == null ? void 0 : s.content) != null ? _a3 : "").substring(0, 150),
9518
- metadata: s == null ? void 0 : s.metadata
9519
- };
9520
- })
9521
- });
9522
8827
  if (graphData && graphData.nodes.length > 0) {
9523
8828
  const graphContext = graphData.nodes.map(
9524
8829
  (n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
@@ -9760,9 +9065,9 @@ ${context}`;
9760
9065
  const trace = buildTrace(hallucinationResult);
9761
9066
  const isTelemetryActive = (_A = (_z = this.config.telemetry) == null ? void 0 : _z.enabled) != null ? _A : Boolean(this.config.licenseKey);
9762
9067
  if (isTelemetryActive) {
9763
- 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";
9068
+ const defaultUrl = "https://www.retrivora.com/api/telemetry";
9764
9069
  const telemetryUrl = ((_B = this.config.telemetry) == null ? void 0 : _B.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
9765
- const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : (process.env.NEXT_PUBLIC_APP_URL || `http://localhost:${process.env.PORT || 3e3}`) + telemetryUrl;
9070
+ const absoluteUrl = telemetryUrl.startsWith("http") ? telemetryUrl : "https://www.retrivora.com" + (telemetryUrl.startsWith("/") ? telemetryUrl : "/" + telemetryUrl);
9766
9071
  (async () => {
9767
9072
  var _a3, _b2, _c2, _d2, _e2;
9768
9073
  try {
@@ -10299,8 +9604,8 @@ var VectorPlugin = class {
10299
9604
  }
10300
9605
  try {
10301
9606
  return await this.pipeline.getSuggestions(query, namespace);
10302
- } catch (err) {
10303
- throw wrapError(err, "RETRIEVAL_FAILED");
9607
+ } catch (e) {
9608
+ return [];
10304
9609
  }
10305
9610
  }
10306
9611
  };
@@ -10897,15 +10202,14 @@ function getOrCreatePlugin(configOrPlugin) {
10897
10202
  return _g[cacheKey];
10898
10203
  }
10899
10204
  function reportTelemetry(req, plugin, action, status, details, trace) {
10900
- var _a2, _b, _c, _d, _e, _f, _g2, _h;
10205
+ var _a2, _b, _c, _d, _e, _f, _g2;
10901
10206
  try {
10902
10207
  const config = plugin.getConfig();
10903
10208
  const licenseKey = config.licenseKey || process.env.RAG_LICENSE_KEY || process.env.RETRIVORA_LICENSE_KEY || process.env.NEXT_PUBLIC_RETRIVORA_LICENSE_KEY;
10904
10209
  const telemetryConfig = config.telemetry;
10905
- const enabled = (_a2 = telemetryConfig == null ? void 0 : telemetryConfig.enabled) != null ? _a2 : Boolean(licenseKey);
10906
- 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";
10907
- const telemetryUrl = (telemetryConfig == null ? void 0 : telemetryConfig.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
10908
10210
  const host = req.headers.get("host") || "localhost";
10211
+ const defaultUrl = "https://www.retrivora.com/api/telemetry";
10212
+ const telemetryUrl = (telemetryConfig == null ? void 0 : telemetryConfig.url) || process.env.TELEMETRY_URL || process.env.NEXT_PUBLIC_TELEMETRY_URL || defaultUrl;
10909
10213
  const userAgent = req.headers.get("user-agent") || `Retrivora-SDK/${SDK_VERSION}`;
10910
10214
  let absoluteUrl = telemetryUrl;
10911
10215
  if (!telemetryUrl.startsWith("http")) {
@@ -10913,11 +10217,11 @@ function reportTelemetry(req, plugin, action, status, details, trace) {
10913
10217
  absoluteUrl = `${proto}://${host}${telemetryUrl}`;
10914
10218
  }
10915
10219
  const projectId = config.projectId || "default";
10916
- 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";
10917
- 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";
10918
- const tokens = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10919
- const costUsd = Number(((_g2 = trace == null ? void 0 : trace.tokens) == null ? void 0 : _g2.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
10920
- const latencyMs = Number(((_h = trace == null ? void 0 : trace.latency) == null ? void 0 : _h.totalMs) || (trace == null ? void 0 : trace.latencyMs) || 0);
10220
+ 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";
10221
+ 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";
10222
+ const tokens = Number(((_e = trace == null ? void 0 : trace.tokens) == null ? void 0 : _e.totalTokens) || (trace == null ? void 0 : trace.totalTokens) || 0);
10223
+ const costUsd = Number(((_f = trace == null ? void 0 : trace.tokens) == null ? void 0 : _f.estimatedCostUsd) || (trace == null ? void 0 : trace.costUsd) || 0);
10224
+ const latencyMs = Number(((_g2 = trace == null ? void 0 : trace.latency) == null ? void 0 : _g2.totalMs) || (trace == null ? void 0 : trace.latencyMs) || 0);
10921
10225
  const payload = {
10922
10226
  trace,
10923
10227
  licenseKey,
@@ -10994,7 +10298,7 @@ function createChatHandler(configOrPlugin, options) {
10994
10298
  const plugin = getOrCreatePlugin(configOrPlugin);
10995
10299
  const storage = new DatabaseStorage(plugin.getConfig());
10996
10300
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
10997
- return async function POST(req) {
10301
+ return async function POST(req, context) {
10998
10302
  var _a2, _b, _c, _d;
10999
10303
  const authResult = await checkAuth(req, onAuthorize);
11000
10304
  if (authResult) return authResult;
@@ -11050,7 +10354,7 @@ function createStreamHandler(configOrPlugin, options) {
11050
10354
  const plugin = getOrCreatePlugin(configOrPlugin);
11051
10355
  const storage = new DatabaseStorage(plugin.getConfig());
11052
10356
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11053
- return async function POST(req) {
10357
+ return async function POST(req, context) {
11054
10358
  var _a2;
11055
10359
  const authResult = await checkAuth(req, onAuthorize);
11056
10360
  if (authResult) return authResult;
@@ -11200,7 +10504,7 @@ function createStreamHandler(configOrPlugin, options) {
11200
10504
  function createIngestHandler(configOrPlugin, options) {
11201
10505
  const plugin = getOrCreatePlugin(configOrPlugin);
11202
10506
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11203
- return async function POST(req) {
10507
+ return async function POST(req, context) {
11204
10508
  const authResult = await checkAuth(req, onAuthorize);
11205
10509
  if (authResult) return authResult;
11206
10510
  try {
@@ -11244,7 +10548,7 @@ function createHealthHandler(configOrPlugin, options) {
11244
10548
  function createUploadHandler(configOrPlugin, options) {
11245
10549
  const plugin = getOrCreatePlugin(configOrPlugin);
11246
10550
  const onAuthorize = options == null ? void 0 : options.onAuthorize;
11247
- return async function POST(req) {
10551
+ return async function POST(req, context) {
11248
10552
  const authResult = await checkAuth(req, onAuthorize);
11249
10553
  if (authResult) return authResult;
11250
10554
  try {