@retrivora-ai/rag-engine 1.6.4 → 1.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2263,14 +2263,15 @@ var Pipeline = class {
2263
2263
  const chartInstruction = `
2264
2264
 
2265
2265
  ${CHART_MARKER}
2266
- ### UNIVERSAL UI PROTOCOL (EXPERT MODE):
2267
- You have high-performance graphical capabilities. For any analytical query or product list, you MUST use the \`\`\`ui\`\`\` block.
2268
- 1. WRAPPING: You MUST wrap the JSON in \`\`\`ui and \`\`\` code markers. NEVER output naked JSON.
2269
- 2. VIEW SELECTION:
2270
- - "chart": ALWAYS use this for distributions, percentages, or statistics. You MUST aggregate/count the data yourself.
2271
- - "carousel": Use for browsing product items.
2272
- - "table": Use ONLY for raw data details if explicitly asked for a "table" or "list".
2273
- 3. SCHEMA:
2266
+ ### UNIVERSAL UI PROTOCOL
2267
+ When the user asks for a visual representation, comparison, distribution, breakdown, table, list, catalog, products, carousel, stock view, or category summary, you MUST include exactly one \`\`\`ui\`\`\` block.
2268
+
2269
+ 1. VIEW SELECTION
2270
+ - Use "chart" for distributions, percentages, counts, comparisons, trends, or "show me in a chart".
2271
+ - Use "carousel" for browseable product recommendations or when the user asks to see products/items/cards.
2272
+ - Use "table" for tabular/raw detail, explicit table/list requests, or when there are many attributes to compare.
2273
+
2274
+ 2. REQUIRED JSON SHAPE
2274
2275
  {
2275
2276
  "view": "chart" | "carousel" | "table",
2276
2277
  "title": "Short heading",
@@ -3826,14 +3826,15 @@ var Pipeline = class {
3826
3826
  const chartInstruction = `
3827
3827
 
3828
3828
  ${CHART_MARKER}
3829
- ### UNIVERSAL UI PROTOCOL (EXPERT MODE):
3830
- You have high-performance graphical capabilities. For any analytical query or product list, you MUST use the \`\`\`ui\`\`\` block.
3831
- 1. WRAPPING: You MUST wrap the JSON in \`\`\`ui and \`\`\` code markers. NEVER output naked JSON.
3832
- 2. VIEW SELECTION:
3833
- - "chart": ALWAYS use this for distributions, percentages, or statistics. You MUST aggregate/count the data yourself.
3834
- - "carousel": Use for browsing product items.
3835
- - "table": Use ONLY for raw data details if explicitly asked for a "table" or "list".
3836
- 3. SCHEMA:
3829
+ ### UNIVERSAL UI PROTOCOL
3830
+ When the user asks for a visual representation, comparison, distribution, breakdown, table, list, catalog, products, carousel, stock view, or category summary, you MUST include exactly one \`\`\`ui\`\`\` block.
3831
+
3832
+ 1. VIEW SELECTION
3833
+ - Use "chart" for distributions, percentages, counts, comparisons, trends, or "show me in a chart".
3834
+ - Use "carousel" for browseable product recommendations or when the user asks to see products/items/cards.
3835
+ - Use "table" for tabular/raw detail, explicit table/list requests, or when there are many attributes to compare.
3836
+
3837
+ 2. REQUIRED JSON SHAPE
3837
3838
  {
3838
3839
  "view": "chart" | "carousel" | "table",
3839
3840
  "title": "Short heading",
@@ -9,7 +9,7 @@ import {
9
9
  sseFrame,
10
10
  sseMetaFrame,
11
11
  sseTextFrame
12
- } from "../chunk-EE2Z4HNW.mjs";
12
+ } from "../chunk-5K7EU4KW.mjs";
13
13
  import "../chunk-YLTMFW4M.mjs";
14
14
  import "../chunk-X4TOT24V.mjs";
15
15
  export {
package/dist/index.js CHANGED
@@ -782,7 +782,7 @@ function MessageBubble({
782
782
  for (const candidate of payloadCandidates) {
783
783
  try {
784
784
  const data = JSON.parse(sanitizeJson(candidate));
785
- const itemSet = Array.isArray(data.items) ? data.items : Array.isArray(data.products) ? data.products : null;
785
+ const itemSet = Array.isArray(data.data) ? data.data : Array.isArray(data.items) ? data.items : Array.isArray(data.products) ? data.products : null;
786
786
  if ((data.type === "products" || data.view === "carousel" || data.view === "table" || Array.isArray(data.products)) && itemSet) {
787
787
  products.push(
788
788
  ...itemSet.map((item) => {
package/dist/index.mjs CHANGED
@@ -745,7 +745,7 @@ function MessageBubble({
745
745
  for (const candidate of payloadCandidates) {
746
746
  try {
747
747
  const data = JSON.parse(sanitizeJson(candidate));
748
- const itemSet = Array.isArray(data.items) ? data.items : Array.isArray(data.products) ? data.products : null;
748
+ const itemSet = Array.isArray(data.data) ? data.data : Array.isArray(data.items) ? data.items : Array.isArray(data.products) ? data.products : null;
749
749
  if ((data.type === "products" || data.view === "carousel" || data.view === "table" || Array.isArray(data.products)) && itemSet) {
750
750
  products.push(
751
751
  ...itemSet.map((item) => {
package/dist/server.js CHANGED
@@ -3917,14 +3917,15 @@ var Pipeline = class {
3917
3917
  const chartInstruction = `
3918
3918
 
3919
3919
  ${CHART_MARKER}
3920
- ### UNIVERSAL UI PROTOCOL (EXPERT MODE):
3921
- You have high-performance graphical capabilities. For any analytical query or product list, you MUST use the \`\`\`ui\`\`\` block.
3922
- 1. WRAPPING: You MUST wrap the JSON in \`\`\`ui and \`\`\` code markers. NEVER output naked JSON.
3923
- 2. VIEW SELECTION:
3924
- - "chart": ALWAYS use this for distributions, percentages, or statistics. You MUST aggregate/count the data yourself.
3925
- - "carousel": Use for browsing product items.
3926
- - "table": Use ONLY for raw data details if explicitly asked for a "table" or "list".
3927
- 3. SCHEMA:
3920
+ ### UNIVERSAL UI PROTOCOL
3921
+ When the user asks for a visual representation, comparison, distribution, breakdown, table, list, catalog, products, carousel, stock view, or category summary, you MUST include exactly one \`\`\`ui\`\`\` block.
3922
+
3923
+ 1. VIEW SELECTION
3924
+ - Use "chart" for distributions, percentages, counts, comparisons, trends, or "show me in a chart".
3925
+ - Use "carousel" for browseable product recommendations or when the user asks to see products/items/cards.
3926
+ - Use "table" for tabular/raw detail, explicit table/list requests, or when there are many attributes to compare.
3927
+
3928
+ 2. REQUIRED JSON SHAPE
3928
3929
  {
3929
3930
  "view": "chart" | "carousel" | "table",
3930
3931
  "title": "Short heading",
package/dist/server.mjs CHANGED
@@ -39,7 +39,7 @@ import {
39
39
  sseFrame,
40
40
  sseMetaFrame,
41
41
  sseTextFrame
42
- } from "./chunk-EE2Z4HNW.mjs";
42
+ } from "./chunk-5K7EU4KW.mjs";
43
43
  import "./chunk-YLTMFW4M.mjs";
44
44
  import {
45
45
  PineconeProvider
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@retrivora-ai/rag-engine",
3
- "version": "1.6.4",
3
+ "version": "1.6.6",
4
4
  "description": "Retrivora AI is a plug-and-play AI engine for RAG chat experiences — generic vector DB + LLM provider, embeddable or standalone.",
5
5
  "author": "Abhinav Alkuchi",
6
6
  "license": "MIT",
@@ -439,7 +439,7 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
439
439
  .trim();
440
440
  const parsed = JSON.parse(sanitizeJson(extractLikelyJsonBlock(clean)));
441
441
  const config = { ...parsed } as Partial<RawUIConfig> & Record<string, unknown>;
442
-
442
+
443
443
  // Smart Auto-Detection for legacy or simpler formats
444
444
  if (!config.view) {
445
445
  if (config.type === 'products' || Array.isArray(config.items)) {
@@ -502,8 +502,8 @@ function UIDispatcher({ rawContent, primaryColor, accentColor, isStreaming, onAd
502
502
  {hasDescription && (
503
503
  <p className={`px-2 ${isCompact ? 'text-xs' : 'text-sm'} text-slate-500 dark:text-white/60`}>{config.description}</p>
504
504
  )}
505
- <DynamicChart
506
- config={{
505
+ <DynamicChart
506
+ config={{
507
507
  type: (config.chartType || 'bar') as 'bar' | 'line' | 'pie',
508
508
  data: config.data as unknown as Record<string, string | number>[],
509
509
  xAxisKey: config.xAxisKey,
@@ -629,9 +629,10 @@ export function MessageBubble({
629
629
  try {
630
630
  const data = JSON.parse(sanitizeJson(candidate));
631
631
  const itemSet =
632
- Array.isArray(data.items) ? data.items
633
- : Array.isArray(data.products) ? data.products
634
- : null;
632
+ Array.isArray(data.data) ? data.data
633
+ : Array.isArray(data.items) ? data.items
634
+ : Array.isArray(data.products) ? data.products
635
+ : null;
635
636
 
636
637
  if (
637
638
  (data.type === 'products' || data.view === 'carousel' || data.view === 'table' || Array.isArray(data.products)) &&
@@ -692,13 +693,14 @@ export function MessageBubble({
692
693
  const processedMarkdown = React.useMemo(() => {
693
694
  let raw = structuredContent.payload ? structuredContent.text : (cleanContent || message.content);
694
695
  const hasStructuredUiBlock = Boolean(structuredContent.payload) || /```(?:ui|json|chart)\s*[\s\S]*?"(?:view|chartType|type|data|items|rows|products|results)"\s*:/i.test(raw);
695
-
696
+
696
697
  // 1. Structural fixes
697
698
  raw = raw.replace(/([^\n])\n\|/g, '$1\n\n|') // Ensure blank line before table
698
- .replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, '$1\n'); // Remove blank lines between rows
699
+ .replace(/(\|[^\n]*\|)\n\n+(?=\|)/g, '$1\n'); // Remove blank lines between rows
699
700
 
700
701
  // 2. HEALING: Detect naked JSON charts/products and wrap them if markers are missing
701
- // This handles models (like Llama 3.2) that often omit the ```ui markers.
702
+ // CRITICAL: DO NOT REVERT THIS REGEX. It must remain non-greedy and position-independent
703
+ // to catch JSON that is not preceded by a newline (common in many LLM outputs).
702
704
  if (!isStreaming) {
703
705
  // Find potential JSON objects that are not already wrapped in code blocks
704
706
  raw = raw.replace(/(\{[\s\S]+?\})(?!\s*```)/g, (match) => {
@@ -874,8 +876,8 @@ export function MessageBubble({
874
876
  {/* Avatar */}
875
877
  <div
876
878
  className={`flex-shrink-0 ${isCompact ? 'w-7 h-7' : 'w-8 h-8'} rounded-full flex items-center justify-center shadow-lg ${isUser
877
- ? 'text-white'
878
- : 'bg-slate-100 dark:bg-white/10 text-slate-700 dark:text-white/80'
879
+ ? 'text-white'
880
+ : 'bg-slate-100 dark:bg-white/10 text-slate-700 dark:text-white/80'
879
881
  }`}
880
882
  style={isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}}
881
883
  >
@@ -886,8 +888,8 @@ export function MessageBubble({
886
888
  {/* Bubble */}
887
889
  <div
888
890
  className={`relative ${isCompact ? 'px-3 py-2.5 text-[13px]' : 'px-4 py-3 text-sm'} rounded-2xl leading-relaxed shadow-sm dark:shadow-lg ${isUser
889
- ? 'text-white rounded-tr-sm'
890
- : 'bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm'
891
+ ? 'text-white rounded-tr-sm'
892
+ : 'bg-white dark:bg-white/5 border border-slate-200 dark:border-white/10 text-slate-800 dark:text-white/90 rounded-tl-sm'
891
893
  }`}
892
894
  style={
893
895
  isUser ? { background: `linear-gradient(135deg, ${primaryColor}, ${accentColor})` } : {}
@@ -103,14 +103,15 @@ export class Pipeline {
103
103
  // We use a unique marker to ensure this is only injected once but is ALWAYS present.
104
104
  const CHART_MARKER = '<!-- UI_PROTOCOL_V5 -->';
105
105
  const chartInstruction = `\n\n${CHART_MARKER}
106
- ### UNIVERSAL UI PROTOCOL (EXPERT MODE):
107
- You have high-performance graphical capabilities. For any analytical query or product list, you MUST use the \`\`\`ui\`\`\` block.
108
- 1. WRAPPING: You MUST wrap the JSON in \`\`\`ui and \`\`\` code markers. NEVER output naked JSON.
109
- 2. VIEW SELECTION:
110
- - "chart": ALWAYS use this for distributions, percentages, or statistics. You MUST aggregate/count the data yourself.
111
- - "carousel": Use for browsing product items.
112
- - "table": Use ONLY for raw data details if explicitly asked for a "table" or "list".
113
- 3. SCHEMA:
106
+ ### UNIVERSAL UI PROTOCOL
107
+ When the user asks for a visual representation, comparison, distribution, breakdown, table, list, catalog, products, carousel, stock view, or category summary, you MUST include exactly one \`\`\`ui\`\`\` block.
108
+
109
+ 1. VIEW SELECTION
110
+ - Use "chart" for distributions, percentages, counts, comparisons, trends, or "show me in a chart".
111
+ - Use "carousel" for browseable product recommendations or when the user asks to see products/items/cards.
112
+ - Use "table" for tabular/raw detail, explicit table/list requests, or when there are many attributes to compare.
113
+
114
+ 2. REQUIRED JSON SHAPE
114
115
  {
115
116
  "view": "chart" | "carousel" | "table",
116
117
  "title": "Short heading",
@@ -213,7 +214,7 @@ Assistant:
213
214
  try {
214
215
  const chunks = await this.prepareChunks(doc);
215
216
  const vectors = await this.processEmbeddings(chunks);
216
-
217
+
217
218
  const upsertDocs = chunks.map((chunk, i) => ({
218
219
  id: chunk.id,
219
220
  vector: vectors[i],
@@ -315,7 +316,7 @@ Assistant:
315
316
  */
316
317
  private async processGraphIngestion(docId: string | number, chunks: Chunk[]): Promise<void> {
317
318
  console.log(`[Pipeline] Extracting entities for doc ${docId} (${chunks.length} chunks)...`);
318
-
319
+
319
320
  const extractionOptions: BatchOptions = {
320
321
  batchSize: 2, // Low concurrency for LLM extraction
321
322
  maxRetries: 1,
@@ -386,11 +387,11 @@ Assistant:
386
387
  // 2. Parallel Retrieval
387
388
  const hints = QueryProcessor.extractQueryFieldHints(question, this.config.rag?.filterableFields);
388
389
  const filter = QueryProcessor.buildQueryFilter(question, hints);
389
-
390
+
390
391
  console.log(`[Pipeline] 🧩 Extracted filters:`, JSON.stringify(filter));
391
392
 
392
- const { sources: rawSources, graphData } = await this.retrieve(searchQuery, {
393
- namespace: ns,
393
+ const { sources: rawSources, graphData } = await this.retrieve(searchQuery, {
394
+ namespace: ns,
394
395
  topK: topK * 2,
395
396
  filter
396
397
  });
@@ -409,7 +410,7 @@ Assistant:
409
410
  : 'No relevant context found.';
410
411
 
411
412
  if (graphData && graphData.nodes.length > 0) {
412
- const graphContext = graphData.nodes.map(n =>
413
+ const graphContext = graphData.nodes.map(n =>
413
414
  `Entity: ${n.label} (${n.id})${n.properties ? ' - ' + JSON.stringify(n.properties) : ''}`
414
415
  ).join('\n');
415
416
  context = `GRAPH KNOWLEDGE:\n${graphContext}\n\nVECTOR CONTEXT:\n${context}`;
@@ -417,7 +418,7 @@ Assistant:
417
418
 
418
419
  // 5. Generation (Streaming)
419
420
  const messages: ChatMessage[] = [...history, { role: 'user', content: question }];
420
-
421
+
421
422
  if (this.llmProvider.chatStream) {
422
423
  const stream = this.llmProvider.chatStream(messages, context);
423
424
  if (!stream) {
@@ -449,7 +450,7 @@ Assistant:
449
450
 
450
451
  const cacheKey = `${ns}::${query}`;
451
452
  let queryVector = this.embeddingCache.get(cacheKey);
452
-
453
+
453
454
  const [retrievedVector, graphData] = await Promise.all([
454
455
  queryVector ? Promise.resolve(queryVector) : this.embeddingProvider.embed(query, { taskType: 'query' }),
455
456
  this.graphDB && this.config.rag?.useGraphRetrieval