@retrivora-ai/rag-engine 2.0.7 → 2.1.1

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.
@@ -560,8 +560,7 @@ RULES:
560
560
  ): UITransformationResponse {
561
561
  const products: CarouselProduct[] = data
562
562
  .map(item => this.extractProductInfo(item, config, trainedSchema))
563
- .filter((p): p is CarouselProduct => p !== null)
564
- .slice(0, 15);
563
+ .filter((p): p is CarouselProduct => p !== null);
565
564
 
566
565
  return {
567
566
  type: 'product_carousel',
@@ -1035,7 +1034,7 @@ RULES:
1035
1034
  }
1036
1035
 
1037
1036
  private static profileData(data: VectorMatch[]): DataProfile {
1038
- const records = data.map((item): DataRecord => {
1037
+ const records = (data || []).filter((item): item is VectorMatch => Boolean(item && typeof item === 'object')).map((item): DataRecord => {
1039
1038
  const fields: Record<string, PrimitiveValue> = {};
1040
1039
  Object.entries(item.metadata || {}).forEach(([key, value]) => {
1041
1040
  const primitive = this.toPrimitive(value);
@@ -1044,8 +1043,8 @@ RULES:
1044
1043
  if (!fields.content && item.content) fields.content = item.content.substring(0, 500);
1045
1044
  return {
1046
1045
  id: item.id,
1047
- content: item.content,
1048
- score: item.score,
1046
+ content: item.content ?? '',
1047
+ score: item.score ?? 0,
1049
1048
  fields,
1050
1049
  source: item,
1051
1050
  };
@@ -1122,6 +1121,15 @@ RULES:
1122
1121
  query: string,
1123
1122
  ): UITransformationResponse | null {
1124
1123
  if (profile.records.length === 0) return null;
1124
+
1125
+ const q = query.toLowerCase().trim();
1126
+ // Do not automatically force charts unless query contains visual or analytical intent
1127
+ const isExplicitVisualOrAnalytic = /\b(chart|graph|plot|visualize|trend|monthly|revenue|top\s*\d+|breakdown|analytics|compare|versus|vs\.?|histogram|pie|bar|line|distribution|percentage|share|summary of metrics)\b/i.test(q);
1128
+
1129
+ if (!isExplicitVisualOrAnalytic) {
1130
+ return null;
1131
+ }
1132
+
1125
1133
  if (profile.dateFields.length > 0 && profile.numericFields.length > 0) {
1126
1134
  return this.transformToLineChart(profile);
1127
1135
  }
@@ -1266,6 +1274,7 @@ RULES:
1266
1274
  }
1267
1275
 
1268
1276
  private static getProductCategory(item: VectorMatch): string | null {
1277
+ if (!item) return null;
1269
1278
  const meta = item.metadata || {};
1270
1279
  const metadataCategory = resolveMetadataValue(meta, 'category');
1271
1280
  if (this.isUsableCategory(metadataCategory)) return String(metadataCategory).trim();
@@ -1402,6 +1411,7 @@ RULES:
1402
1411
  };
1403
1412
 
1404
1413
  data.forEach(item => {
1414
+ if (!item) return;
1405
1415
  Object.keys(item.metadata || {}).forEach(addField);
1406
1416
  for (const match of (item.content || '').matchAll(/(?:^|\n)\s*([A-Za-z][A-Za-z0-9_ /-]{1,50})\s*[:\-–]\s*([^\n]+)/g)) {
1407
1417
  addField(match[1]);
@@ -1552,6 +1562,7 @@ RULES:
1552
1562
  }
1553
1563
 
1554
1564
  private static extractStockQuantity(item: VectorMatch): number | null {
1565
+ if (!item) return null;
1555
1566
  const meta = item.metadata || {};
1556
1567
  const stockValue = resolveMetadataValue(meta, 'stock');
1557
1568
  const numericStock = this.toFiniteNumber(stockValue);