@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/handlers/index.js +776 -88
- package/dist/handlers/index.mjs +776 -88
- package/dist/index.js +24 -16
- package/dist/index.mjs +24 -16
- package/dist/server.js +776 -88
- package/dist/server.mjs +776 -88
- package/package.json +1 -1
- package/src/components/ChatWindow.tsx +22 -22
- package/src/core/Pipeline.ts +22 -40
- package/src/llm/providers/GeminiProvider.ts +4 -4
- package/src/llm/providers/GroqProvider.ts +16 -8
- package/src/llm/providers/OpenAIProvider.ts +16 -8
- package/src/llm/providers/QwenProvider.ts +16 -8
- package/src/llm/providers/UniversalLLMAdapter.ts +90 -18
- package/src/rendering/IntentClassifier.ts +3 -3
- package/src/rendering/rules/Rule1SpecificInfoRule.ts +1 -1
- package/src/utils/ProductExtractor.ts +4 -3
- package/src/utils/UITransformer.ts +16 -5
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: (
|
|
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
|
|
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)
|
|
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: (
|
|
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
|
|
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)
|
|
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);
|