@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.
package/dist/index.js CHANGED
@@ -1739,32 +1739,31 @@ function isLikelyUiOnlyMessage(text) {
1739
1739
  }
1740
1740
  function extractProductsFromSources(sources, isUser) {
1741
1741
  if (isUser || !sources) return [];
1742
- return sources.filter((s) => {
1743
- var _a;
1742
+ return sources.filter((s) => Boolean(s && typeof s === "object")).filter((s) => {
1743
+ var _a, _b;
1744
1744
  const m = (_a = s.metadata) != null ? _a : {};
1745
1745
  const keys = Object.keys(m).map((k) => k.toLowerCase());
1746
1746
  const hasStrongProductKey = keys.some(
1747
1747
  (k) => ["price", "image", "img", "thumbnail", "images", "product", "sku", "cost"].includes(k)
1748
1748
  );
1749
1749
  const hasProductIdentity = keys.some((k) => ["brand", "model"].includes(k)) && keys.some((k) => ["name", "title", "product_name", "product"].includes(k));
1750
- const hasPricePattern = /\$\s*\d+/.test(s.content);
1750
+ const hasPricePattern = /\$\s*\d+/.test((_b = s == null ? void 0 : s.content) != null ? _b : "");
1751
1751
  return hasStrongProductKey || hasProductIdentity || hasPricePattern || m.type === "product";
1752
1752
  }).map((s) => {
1753
- var _a, _b, _c;
1753
+ var _a, _b, _c, _d;
1754
1754
  const m = (_a = s.metadata) != null ? _a : {};
1755
1755
  const name = resolveMetadataValue(m, "name");
1756
1756
  const brand = resolveMetadataValue(m, "brand");
1757
1757
  const price = resolveMetadataValue(m, "price");
1758
1758
  const description = resolveMetadataValue(m, "description");
1759
1759
  return {
1760
- id: s.id,
1761
- name: (_c = name != null ? name : ((_b = s == null ? void 0 : s.content) != null ? _b : "").split("\n")[0]) != null ? _c : "Unknown Product",
1760
+ id: (_b = s == null ? void 0 : s.id) != null ? _b : `prod_${Math.random().toString(36).substring(2, 8)}`,
1761
+ name: (_d = name != null ? name : ((_c = s == null ? void 0 : s.content) != null ? _c : "").split("\n")[0]) != null ? _d : "Unknown Product",
1762
1762
  brand,
1763
1763
  price,
1764
1764
  image: resolveImage(m),
1765
1765
  link: resolveMetadataValue(m, "link"),
1766
1766
  description: description ? description : ""
1767
- //description ?? s.content,
1768
1767
  };
1769
1768
  });
1770
1769
  }
@@ -3142,10 +3141,10 @@ function ChatWindow({
3142
3141
  ] })
3143
3142
  ] }),
3144
3143
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1.5", children: [
3145
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2", children: [
3144
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex items-center gap-1.5 mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400", children: [
3146
3145
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }),
3147
3146
  "Online"
3148
- ] }),
3147
+ ] }) }),
3149
3148
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center bg-slate-100/50 dark:bg-white/5 rounded-lg p-0.5 border border-slate-200/50 dark:border-white/5", children: [
3150
3149
  mounted && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
3151
3150
  "button",
@@ -3673,8 +3672,8 @@ var IntentClassifier = class {
3673
3672
  }
3674
3673
  // ─── Intent Heuristic Checkers ─────────────────────────────────────────────
3675
3674
  static isInformationLookup(query) {
3676
- if (/^(what|who|explain|define|where|when|why|how|how does|can|could|does|do|is|are|has|have|will|should|would|meaning of)\s+/i.test(query)) {
3677
- if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top selling|best)\b/i.test(query)) {
3675
+ if (/^(what|who|explain|explore|define|where|when|why|how|how does|can|could|does|do|is|are|has|have|will|should|would|meaning of|tell me about|show details of|overview of|summarize)\s+/i.test(query)) {
3676
+ if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top 10|top selling|best|chart|graph|plot|breakdown|analytics)\b/i.test(query)) {
3678
3677
  return true;
3679
3678
  }
3680
3679
  }
@@ -3711,7 +3710,7 @@ var Rule1SpecificInfoRule = class {
3711
3710
  }
3712
3711
  evaluate(context, intent) {
3713
3712
  const q = (context.userQuery || "").toLowerCase().trim();
3714
- const isFactQuery = intent === "information_lookup" || /^(what|who|explain|define|where|when|why|meaning of)\s+/i.test(q) || /^(what is the price of|price of|cost of)\b/i.test(q);
3713
+ const isFactQuery = intent === "information_lookup" || /^(what|who|explain|explore|define|where|when|why|meaning of|tell me about|show details of|overview of|summarize)\s+/i.test(q) || /^(what is the price of|price of|cost of)\b/i.test(q);
3715
3714
  const isNonVisual = !/\b(compare|versus|vs\.?|trend|monthly|revenue|best|top 10|chart|table|list|grid)\b/i.test(q);
3716
3715
  if (isFactQuery && isNonVisual) {
3717
3716
  return {
@@ -4401,7 +4400,7 @@ ${schemaProfileText}` : ""}`;
4401
4400
  }
4402
4401
  // ─── Transform Helpers ────────────────────────────────────────────────────
4403
4402
  static transformToProductCarousel(data, config, trainedSchema) {
4404
- const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null).slice(0, 15);
4403
+ const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
4405
4404
  return {
4406
4405
  type: "product_carousel",
4407
4406
  title: "Recommended Products",
@@ -4781,7 +4780,8 @@ ${schemaProfileText}` : ""}`;
4781
4780
  return fieldCount.size > 2;
4782
4781
  }
4783
4782
  static profileData(data) {
4784
- const records = data.map((item) => {
4783
+ const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
4784
+ var _a, _b;
4785
4785
  const fields2 = {};
4786
4786
  Object.entries(item.metadata || {}).forEach(([key, value]) => {
4787
4787
  const primitive = this.toPrimitive(value);
@@ -4790,8 +4790,8 @@ ${schemaProfileText}` : ""}`;
4790
4790
  if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
4791
4791
  return {
4792
4792
  id: item.id,
4793
- content: item.content,
4794
- score: item.score,
4793
+ content: (_a = item.content) != null ? _a : "",
4794
+ score: (_b = item.score) != null ? _b : 0,
4795
4795
  fields: fields2,
4796
4796
  source: item
4797
4797
  };
@@ -4848,6 +4848,11 @@ ${schemaProfileText}` : ""}`;
4848
4848
  }
4849
4849
  static chooseAutomaticVisualization(data, profile, query) {
4850
4850
  if (profile.records.length === 0) return null;
4851
+ const q = query.toLowerCase().trim();
4852
+ 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);
4853
+ if (!isExplicitVisualOrAnalytic) {
4854
+ return null;
4855
+ }
4851
4856
  if (profile.dateFields.length > 0 && profile.numericFields.length > 0) {
4852
4857
  return this.transformToLineChart(profile);
4853
4858
  }
@@ -4963,6 +4968,7 @@ ${schemaProfileText}` : ""}`;
4963
4968
  return Array.from(categories);
4964
4969
  }
4965
4970
  static getProductCategory(item) {
4971
+ if (!item) return null;
4966
4972
  const meta = item.metadata || {};
4967
4973
  const metadataCategory = resolveMetadataValue(meta, "category");
4968
4974
  if (this.isUsableCategory(metadataCategory)) return String(metadataCategory).trim();
@@ -5079,6 +5085,7 @@ ${schemaProfileText}` : ""}`;
5079
5085
  if (!fields.has(normalized)) fields.set(normalized, clean);
5080
5086
  };
5081
5087
  data.forEach((item) => {
5088
+ if (!item) return;
5082
5089
  Object.keys(item.metadata || {}).forEach(addField);
5083
5090
  for (const match of (item.content || "").matchAll(/(?:^|\n)\s*([A-Za-z][A-Za-z0-9_ /-]{1,50})\s*[:\-–]\s*([^\n]+)/g)) {
5084
5091
  addField(match[1]);
@@ -5195,6 +5202,7 @@ ${schemaProfileText}` : ""}`;
5195
5202
  return true;
5196
5203
  }
5197
5204
  static extractStockQuantity(item) {
5205
+ if (!item) return null;
5198
5206
  const meta = item.metadata || {};
5199
5207
  const stockValue = resolveMetadataValue(meta, "stock");
5200
5208
  const numericStock = this.toFiniteNumber(stockValue);
package/dist/index.mjs CHANGED
@@ -1741,32 +1741,31 @@ function isLikelyUiOnlyMessage(text) {
1741
1741
  }
1742
1742
  function extractProductsFromSources(sources, isUser) {
1743
1743
  if (isUser || !sources) return [];
1744
- return sources.filter((s) => {
1745
- var _a;
1744
+ return sources.filter((s) => Boolean(s && typeof s === "object")).filter((s) => {
1745
+ var _a, _b;
1746
1746
  const m = (_a = s.metadata) != null ? _a : {};
1747
1747
  const keys = Object.keys(m).map((k) => k.toLowerCase());
1748
1748
  const hasStrongProductKey = keys.some(
1749
1749
  (k) => ["price", "image", "img", "thumbnail", "images", "product", "sku", "cost"].includes(k)
1750
1750
  );
1751
1751
  const hasProductIdentity = keys.some((k) => ["brand", "model"].includes(k)) && keys.some((k) => ["name", "title", "product_name", "product"].includes(k));
1752
- const hasPricePattern = /\$\s*\d+/.test(s.content);
1752
+ const hasPricePattern = /\$\s*\d+/.test((_b = s == null ? void 0 : s.content) != null ? _b : "");
1753
1753
  return hasStrongProductKey || hasProductIdentity || hasPricePattern || m.type === "product";
1754
1754
  }).map((s) => {
1755
- var _a, _b, _c;
1755
+ var _a, _b, _c, _d;
1756
1756
  const m = (_a = s.metadata) != null ? _a : {};
1757
1757
  const name = resolveMetadataValue(m, "name");
1758
1758
  const brand = resolveMetadataValue(m, "brand");
1759
1759
  const price = resolveMetadataValue(m, "price");
1760
1760
  const description = resolveMetadataValue(m, "description");
1761
1761
  return {
1762
- id: s.id,
1763
- name: (_c = name != null ? name : ((_b = s == null ? void 0 : s.content) != null ? _b : "").split("\n")[0]) != null ? _c : "Unknown Product",
1762
+ id: (_b = s == null ? void 0 : s.id) != null ? _b : `prod_${Math.random().toString(36).substring(2, 8)}`,
1763
+ name: (_d = name != null ? name : ((_c = s == null ? void 0 : s.content) != null ? _c : "").split("\n")[0]) != null ? _d : "Unknown Product",
1764
1764
  brand,
1765
1765
  price,
1766
1766
  image: resolveImage(m),
1767
1767
  link: resolveMetadataValue(m, "link"),
1768
1768
  description: description ? description : ""
1769
- //description ?? s.content,
1770
1769
  };
1771
1770
  });
1772
1771
  }
@@ -3144,10 +3143,10 @@ function ChatWindow({
3144
3143
  ] })
3145
3144
  ] }),
3146
3145
  /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5", children: [
3147
- /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400 mr-2", children: [
3146
+ /* @__PURE__ */ jsx13("div", { className: "flex items-center gap-1.5 mr-2", children: /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-1 text-[10px] text-emerald-500 dark:text-emerald-400", children: [
3148
3147
  /* @__PURE__ */ jsx13("span", { className: "w-1.5 h-1.5 rounded-full bg-emerald-500 dark:bg-emerald-400 animate-pulse" }),
3149
3148
  "Online"
3150
- ] }),
3149
+ ] }) }),
3151
3150
  /* @__PURE__ */ jsxs12("div", { className: "flex items-center bg-slate-100/50 dark:bg-white/5 rounded-lg p-0.5 border border-slate-200/50 dark:border-white/5", children: [
3152
3151
  mounted && messages.length > 0 && /* @__PURE__ */ jsx13(
3153
3152
  "button",
@@ -3675,8 +3674,8 @@ var IntentClassifier = class {
3675
3674
  }
3676
3675
  // ─── Intent Heuristic Checkers ─────────────────────────────────────────────
3677
3676
  static isInformationLookup(query) {
3678
- if (/^(what|who|explain|define|where|when|why|how|how does|can|could|does|do|is|are|has|have|will|should|would|meaning of)\s+/i.test(query)) {
3679
- if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top selling|best)\b/i.test(query)) {
3677
+ if (/^(what|who|explain|explore|define|where|when|why|how|how does|can|could|does|do|is|are|has|have|will|should|would|meaning of|tell me about|show details of|overview of|summarize)\s+/i.test(query)) {
3678
+ if (!/\b(compare|versus|vs\.?|trend|monthly|revenue|top 10|top selling|best|chart|graph|plot|breakdown|analytics)\b/i.test(query)) {
3680
3679
  return true;
3681
3680
  }
3682
3681
  }
@@ -3713,7 +3712,7 @@ var Rule1SpecificInfoRule = class {
3713
3712
  }
3714
3713
  evaluate(context, intent) {
3715
3714
  const q = (context.userQuery || "").toLowerCase().trim();
3716
- const isFactQuery = intent === "information_lookup" || /^(what|who|explain|define|where|when|why|meaning of)\s+/i.test(q) || /^(what is the price of|price of|cost of)\b/i.test(q);
3715
+ const isFactQuery = intent === "information_lookup" || /^(what|who|explain|explore|define|where|when|why|meaning of|tell me about|show details of|overview of|summarize)\s+/i.test(q) || /^(what is the price of|price of|cost of)\b/i.test(q);
3717
3716
  const isNonVisual = !/\b(compare|versus|vs\.?|trend|monthly|revenue|best|top 10|chart|table|list|grid)\b/i.test(q);
3718
3717
  if (isFactQuery && isNonVisual) {
3719
3718
  return {
@@ -4403,7 +4402,7 @@ ${schemaProfileText}` : ""}`;
4403
4402
  }
4404
4403
  // ─── Transform Helpers ────────────────────────────────────────────────────
4405
4404
  static transformToProductCarousel(data, config, trainedSchema) {
4406
- const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null).slice(0, 15);
4405
+ const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
4407
4406
  return {
4408
4407
  type: "product_carousel",
4409
4408
  title: "Recommended Products",
@@ -4783,7 +4782,8 @@ ${schemaProfileText}` : ""}`;
4783
4782
  return fieldCount.size > 2;
4784
4783
  }
4785
4784
  static profileData(data) {
4786
- const records = data.map((item) => {
4785
+ const records = (data || []).filter((item) => Boolean(item && typeof item === "object")).map((item) => {
4786
+ var _a, _b;
4787
4787
  const fields2 = {};
4788
4788
  Object.entries(item.metadata || {}).forEach(([key, value]) => {
4789
4789
  const primitive = this.toPrimitive(value);
@@ -4792,8 +4792,8 @@ ${schemaProfileText}` : ""}`;
4792
4792
  if (!fields2.content && item.content) fields2.content = item.content.substring(0, 500);
4793
4793
  return {
4794
4794
  id: item.id,
4795
- content: item.content,
4796
- score: item.score,
4795
+ content: (_a = item.content) != null ? _a : "",
4796
+ score: (_b = item.score) != null ? _b : 0,
4797
4797
  fields: fields2,
4798
4798
  source: item
4799
4799
  };
@@ -4850,6 +4850,11 @@ ${schemaProfileText}` : ""}`;
4850
4850
  }
4851
4851
  static chooseAutomaticVisualization(data, profile, query) {
4852
4852
  if (profile.records.length === 0) return null;
4853
+ const q = query.toLowerCase().trim();
4854
+ 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);
4855
+ if (!isExplicitVisualOrAnalytic) {
4856
+ return null;
4857
+ }
4853
4858
  if (profile.dateFields.length > 0 && profile.numericFields.length > 0) {
4854
4859
  return this.transformToLineChart(profile);
4855
4860
  }
@@ -4965,6 +4970,7 @@ ${schemaProfileText}` : ""}`;
4965
4970
  return Array.from(categories);
4966
4971
  }
4967
4972
  static getProductCategory(item) {
4973
+ if (!item) return null;
4968
4974
  const meta = item.metadata || {};
4969
4975
  const metadataCategory = resolveMetadataValue(meta, "category");
4970
4976
  if (this.isUsableCategory(metadataCategory)) return String(metadataCategory).trim();
@@ -5081,6 +5087,7 @@ ${schemaProfileText}` : ""}`;
5081
5087
  if (!fields.has(normalized)) fields.set(normalized, clean);
5082
5088
  };
5083
5089
  data.forEach((item) => {
5090
+ if (!item) return;
5084
5091
  Object.keys(item.metadata || {}).forEach(addField);
5085
5092
  for (const match of (item.content || "").matchAll(/(?:^|\n)\s*([A-Za-z][A-Za-z0-9_ /-]{1,50})\s*[:\-–]\s*([^\n]+)/g)) {
5086
5093
  addField(match[1]);
@@ -5197,6 +5204,7 @@ ${schemaProfileText}` : ""}`;
5197
5204
  return true;
5198
5205
  }
5199
5206
  static extractStockQuantity(item) {
5207
+ if (!item) return null;
5200
5208
  const meta = item.metadata || {};
5201
5209
  const stockValue = resolveMetadataValue(meta, "stock");
5202
5210
  const numericStock = this.toFiniteNumber(stockValue);