@retrivora-ai/rag-engine 1.9.1 → 1.9.3
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/{ILLMProvider-BQyKZLnd.d.mts → ILLMProvider-Bw2A28nU.d.mts} +2 -0
- package/dist/{ILLMProvider-BQyKZLnd.d.ts → ILLMProvider-Bw2A28nU.d.ts} +2 -0
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +193 -109
- package/dist/handlers/index.mjs +193 -109
- package/dist/{index-CDftK3qs.d.mts → index-B70ZLkfG.d.mts} +1 -1
- package/dist/{index-A0GqPsaG.d.ts → index-DVu-mkAM.d.ts} +1 -1
- package/dist/index.css +57 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +90 -36
- package/dist/index.mjs +91 -37
- package/dist/server.d.mts +3 -3
- package/dist/server.d.ts +3 -3
- package/dist/server.js +193 -109
- package/dist/server.mjs +193 -109
- package/package.json +1 -1
- package/src/components/ChatWindow.tsx +24 -14
- package/src/components/MessageBubble.tsx +41 -6
- package/src/components/ProductCard.tsx +4 -4
- package/src/core/Pipeline.ts +53 -25
- package/src/core/QueryProcessor.ts +10 -9
- package/src/handlers/index.ts +31 -8
- package/src/hooks/useRagChat.ts +24 -0
- package/src/providers/vectordb/MongoDBProvider.ts +13 -6
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +36 -4
- package/src/types/chat.ts +2 -0
- package/src/utils/SchemaMapper.ts +6 -4
- package/src/utils/UITransformer.ts +2 -1
- package/src/utils/synonyms.ts +5 -5
|
@@ -52,6 +52,8 @@ interface UseRagChatReturn {
|
|
|
52
52
|
retry: () => Promise<void>;
|
|
53
53
|
/** Programmatically set the conversation (e.g. to restore from a DB) */
|
|
54
54
|
setMessages: React.Dispatch<React.SetStateAction<RagMessage[]>>;
|
|
55
|
+
/** Abort the current active stream request */
|
|
56
|
+
stop: () => void;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
/**
|
|
@@ -52,6 +52,8 @@ interface UseRagChatReturn {
|
|
|
52
52
|
retry: () => Promise<void>;
|
|
53
53
|
/** Programmatically set the conversation (e.g. to restore from a DB) */
|
|
54
54
|
setMessages: React.Dispatch<React.SetStateAction<RagMessage[]>>;
|
|
55
|
+
/** Abort the current active stream request */
|
|
56
|
+
stop: () => void;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
/**
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import '../ILLMProvider-
|
|
2
|
-
export { c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, k as createSuggestionsHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, l as sseObservabilityFrame, j as sseTextFrame, m as sseUIFrame } from '../index-
|
|
1
|
+
import '../ILLMProvider-Bw2A28nU.mjs';
|
|
2
|
+
export { c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, k as createSuggestionsHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, l as sseObservabilityFrame, j as sseTextFrame, m as sseUIFrame } from '../index-B70ZLkfG.mjs';
|
|
3
3
|
import 'next/server';
|
package/dist/handlers/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import '../ILLMProvider-
|
|
2
|
-
export { c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, k as createSuggestionsHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, l as sseObservabilityFrame, j as sseTextFrame, m as sseUIFrame } from '../index-
|
|
1
|
+
import '../ILLMProvider-Bw2A28nU.js';
|
|
2
|
+
export { c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, k as createSuggestionsHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, l as sseObservabilityFrame, j as sseTextFrame, m as sseUIFrame } from '../index-DVu-mkAM.js';
|
|
3
3
|
import 'next/server';
|
package/dist/handlers/index.js
CHANGED
|
@@ -540,6 +540,82 @@ var init_PostgreSQLProvider = __esm({
|
|
|
540
540
|
}
|
|
541
541
|
});
|
|
542
542
|
|
|
543
|
+
// src/utils/synonyms.ts
|
|
544
|
+
function resolveMetadataValue(meta, uiKey) {
|
|
545
|
+
var _a;
|
|
546
|
+
const synonyms = (_a = FIELD_SYNONYMS[uiKey]) != null ? _a : [];
|
|
547
|
+
const keys = Object.keys(meta);
|
|
548
|
+
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
549
|
+
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
550
|
+
if (match !== void 0) return meta[match];
|
|
551
|
+
match = keys.find((k) => synonyms.map((s) => s.toLowerCase()).includes(k.toLowerCase()));
|
|
552
|
+
if (match !== void 0) return meta[match];
|
|
553
|
+
const isBlacklisted = (kl) => {
|
|
554
|
+
return systemKeys.includes(kl) || kl.startsWith("option1") || kl.startsWith("option2") || kl.startsWith("option3");
|
|
555
|
+
};
|
|
556
|
+
match = keys.find((k) => {
|
|
557
|
+
const kl = k.toLowerCase();
|
|
558
|
+
if (isBlacklisted(kl)) return false;
|
|
559
|
+
return kl.includes(uiKey.toLowerCase());
|
|
560
|
+
});
|
|
561
|
+
if (match !== void 0) return meta[match];
|
|
562
|
+
match = keys.find((k) => {
|
|
563
|
+
const kl = k.toLowerCase();
|
|
564
|
+
if (isBlacklisted(kl)) return false;
|
|
565
|
+
return synonyms.some((sk) => kl.includes(sk.toLowerCase()) || sk.toLowerCase().includes(kl));
|
|
566
|
+
});
|
|
567
|
+
return match !== void 0 ? meta[match] : void 0;
|
|
568
|
+
}
|
|
569
|
+
var FIELD_SYNONYMS;
|
|
570
|
+
var init_synonyms = __esm({
|
|
571
|
+
"src/utils/synonyms.ts"() {
|
|
572
|
+
"use strict";
|
|
573
|
+
FIELD_SYNONYMS = {
|
|
574
|
+
name: ["product", "item", "title", "label", "heading", "subject", "product name", "item name"],
|
|
575
|
+
price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd", "variant price"],
|
|
576
|
+
brand: ["manufacturer", "vendor", "make", "company", "brand_name", "supplier"],
|
|
577
|
+
image: [
|
|
578
|
+
"imageUrl",
|
|
579
|
+
"thumbnail",
|
|
580
|
+
"img",
|
|
581
|
+
"url",
|
|
582
|
+
"photo",
|
|
583
|
+
"picture",
|
|
584
|
+
"media",
|
|
585
|
+
"image_url",
|
|
586
|
+
"main_image",
|
|
587
|
+
"product_image",
|
|
588
|
+
"thumb",
|
|
589
|
+
"image src",
|
|
590
|
+
"variant image"
|
|
591
|
+
],
|
|
592
|
+
stock: [
|
|
593
|
+
"inventory",
|
|
594
|
+
"quantity",
|
|
595
|
+
"count",
|
|
596
|
+
"availability",
|
|
597
|
+
"stock_level",
|
|
598
|
+
"inStock",
|
|
599
|
+
"is_available",
|
|
600
|
+
"in stock",
|
|
601
|
+
"status",
|
|
602
|
+
"variant inventory qty"
|
|
603
|
+
],
|
|
604
|
+
category: [
|
|
605
|
+
"product_category",
|
|
606
|
+
"product category",
|
|
607
|
+
"category_name",
|
|
608
|
+
"category name",
|
|
609
|
+
"department",
|
|
610
|
+
"collection",
|
|
611
|
+
"type"
|
|
612
|
+
],
|
|
613
|
+
description: ["summary", "content", "body", "text", "info", "details", "body (html)", "seo description"],
|
|
614
|
+
link: ["url", "href", "product_url", "page_url", "link"]
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
|
|
543
619
|
// src/providers/vectordb/MultiTablePostgresProvider.ts
|
|
544
620
|
var MultiTablePostgresProvider_exports = {};
|
|
545
621
|
__export(MultiTablePostgresProvider_exports, {
|
|
@@ -551,6 +627,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
551
627
|
"use strict";
|
|
552
628
|
import_pg2 = require("pg");
|
|
553
629
|
init_BaseVectorProvider();
|
|
630
|
+
init_synonyms();
|
|
554
631
|
MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
555
632
|
constructor(config) {
|
|
556
633
|
var _a, _b, _c;
|
|
@@ -631,8 +708,13 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
631
708
|
}
|
|
632
709
|
tableName = tableName.replace(/[^a-z0-9_]/gi, "_").toLowerCase() || this.uploadTable;
|
|
633
710
|
const firstMeta = fileDocs[0].metadata || {};
|
|
634
|
-
|
|
635
|
-
|
|
711
|
+
let csvHeaders = [];
|
|
712
|
+
if (Array.isArray(firstMeta.csvHeaders)) {
|
|
713
|
+
csvHeaders = firstMeta.csvHeaders;
|
|
714
|
+
} else {
|
|
715
|
+
const systemKeys = ["fileName", "fileSize", "fileType", "uploadedAt", "dimension", "chunkIndex", "id", "namespace", "content", "metadata", "embedding", "docId", "docid", "chunkId", "chunkid", "csvHeaders", "csvheaders"];
|
|
716
|
+
csvHeaders = Object.keys(firstMeta).filter((k) => !systemKeys.includes(k) && !systemKeys.includes(k.toLowerCase()));
|
|
717
|
+
}
|
|
636
718
|
const columnDefs = csvHeaders.map((h) => `"${h}" TEXT`).join(",\n ");
|
|
637
719
|
const createTableSql = `
|
|
638
720
|
CREATE TABLE IF NOT EXISTS "${tableName}" (
|
|
@@ -725,10 +807,26 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
725
807
|
};
|
|
726
808
|
const dynamicKeywordQuery = getDynamicKeywordQuery();
|
|
727
809
|
const tableLimit = Math.max(topK, 50);
|
|
810
|
+
const metadataFilters = _filter == null ? void 0 : _filter.metadata;
|
|
728
811
|
const queryPromises = this.tables.map(async (table) => {
|
|
729
812
|
try {
|
|
730
813
|
let sqlQuery = "";
|
|
731
814
|
let params = [];
|
|
815
|
+
let whereClause = "";
|
|
816
|
+
const filterParams = [];
|
|
817
|
+
if (metadataFilters && Object.keys(metadataFilters).length > 0) {
|
|
818
|
+
const conditions = Object.entries(metadataFilters).map(([key, val]) => {
|
|
819
|
+
var _a3;
|
|
820
|
+
filterParams.push(String(val));
|
|
821
|
+
const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
|
|
822
|
+
const paramIdx = baseOffset + filterParams.length;
|
|
823
|
+
const synonyms = (_a3 = FIELD_SYNONYMS[key]) != null ? _a3 : [];
|
|
824
|
+
const keysToCheck = [key, ...synonyms];
|
|
825
|
+
const coalesceExprs = keysToCheck.map((k) => `LOWER(metadata->>'${k}')`);
|
|
826
|
+
return `COALESCE(${coalesceExprs.join(", ")}) = LOWER($${paramIdx})`;
|
|
827
|
+
});
|
|
828
|
+
whereClause = `WHERE ${conditions.join(" AND ")}`;
|
|
829
|
+
}
|
|
732
830
|
if (queryText && dynamicKeywordQuery) {
|
|
733
831
|
const hasEntityHints = entityHints.length > 0;
|
|
734
832
|
const exactNameScoreExpr = hasEntityHints ? `+ (
|
|
@@ -745,19 +843,21 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
745
843
|
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) AS keyword_score,
|
|
746
844
|
((1 - (embedding <=> $1::vector)) + (COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) * 2.0) ${exactNameScoreExpr}) AS hybrid_score
|
|
747
845
|
FROM "${table}" t
|
|
846
|
+
${whereClause}
|
|
748
847
|
ORDER BY hybrid_score DESC
|
|
749
848
|
LIMIT ${tableLimit}
|
|
750
849
|
`;
|
|
751
|
-
params = [vectorLiteral, dynamicKeywordQuery];
|
|
850
|
+
params = [vectorLiteral, dynamicKeywordQuery, ...filterParams];
|
|
752
851
|
} else {
|
|
753
852
|
sqlQuery = `
|
|
754
853
|
SELECT *,
|
|
755
854
|
(1 - (embedding <=> $1::vector)) AS hybrid_score
|
|
756
855
|
FROM "${table}" t
|
|
856
|
+
${whereClause}
|
|
757
857
|
ORDER BY hybrid_score DESC
|
|
758
858
|
LIMIT ${tableLimit}
|
|
759
859
|
`;
|
|
760
|
-
params = [vectorLiteral];
|
|
860
|
+
params = [vectorLiteral, ...filterParams];
|
|
761
861
|
}
|
|
762
862
|
const result = await this.pool.query(sqlQuery, params);
|
|
763
863
|
if (result.rowCount && result.rowCount > 0) {
|
|
@@ -990,12 +1090,15 @@ var init_MongoDBProvider = __esm({
|
|
|
990
1090
|
}
|
|
991
1091
|
);
|
|
992
1092
|
const results = await this.collection.aggregate(pipeline).toArray();
|
|
993
|
-
return results.map((res) =>
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
1093
|
+
return results.map((res) => {
|
|
1094
|
+
const normalizedScore = res.score * 2 - 1;
|
|
1095
|
+
return {
|
|
1096
|
+
id: res._id,
|
|
1097
|
+
content: res[this.contentKey],
|
|
1098
|
+
metadata: res[this.metadataKey] || {},
|
|
1099
|
+
score: normalizedScore
|
|
1100
|
+
};
|
|
1101
|
+
});
|
|
999
1102
|
}
|
|
1000
1103
|
async delete(id, namespace) {
|
|
1001
1104
|
await this.collection.deleteOne(__spreadValues({ _id: id }, namespace ? { namespace } : {}));
|
|
@@ -4353,7 +4456,8 @@ var QueryProcessor = class {
|
|
|
4353
4456
|
const fieldValuePatterns = [
|
|
4354
4457
|
new RegExp(`\\b${fieldPattern}\\s*(?:=|:)\\s*["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi"),
|
|
4355
4458
|
new RegExp(`\\b${fieldPattern}\\s+(?:is|are|was|were|equals?|equal to|named|called)\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi"),
|
|
4356
|
-
new RegExp(`\\bwith\\s+${fieldPattern}\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi")
|
|
4459
|
+
new RegExp(`\\bwith\\s+${fieldPattern}\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi"),
|
|
4460
|
+
new RegExp(`\\b(?:under|in|for|from|of)\\s+${fieldPattern}\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi")
|
|
4357
4461
|
];
|
|
4358
4462
|
for (const pattern of fieldValuePatterns) {
|
|
4359
4463
|
for (const match of question.matchAll(pattern)) {
|
|
@@ -4587,73 +4691,8 @@ var LLMRouter = class {
|
|
|
4587
4691
|
}
|
|
4588
4692
|
};
|
|
4589
4693
|
|
|
4590
|
-
// src/utils/synonyms.ts
|
|
4591
|
-
var FIELD_SYNONYMS = {
|
|
4592
|
-
name: ["product", "item", "title", "label", "heading", "subject", "product name", "item name"],
|
|
4593
|
-
price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd"],
|
|
4594
|
-
brand: ["manufacturer", "vendor", "make", "company", "brand_name", "supplier"],
|
|
4595
|
-
image: [
|
|
4596
|
-
"imageUrl",
|
|
4597
|
-
"thumbnail",
|
|
4598
|
-
"img",
|
|
4599
|
-
"url",
|
|
4600
|
-
"photo",
|
|
4601
|
-
"picture",
|
|
4602
|
-
"media",
|
|
4603
|
-
"image_url",
|
|
4604
|
-
"main_image",
|
|
4605
|
-
"product_image",
|
|
4606
|
-
"thumb"
|
|
4607
|
-
],
|
|
4608
|
-
stock: [
|
|
4609
|
-
"inventory",
|
|
4610
|
-
"quantity",
|
|
4611
|
-
"count",
|
|
4612
|
-
"availability",
|
|
4613
|
-
"stock_level",
|
|
4614
|
-
"inStock",
|
|
4615
|
-
"is_available",
|
|
4616
|
-
"in stock",
|
|
4617
|
-
"status"
|
|
4618
|
-
],
|
|
4619
|
-
category: [
|
|
4620
|
-
"product_category",
|
|
4621
|
-
"product category",
|
|
4622
|
-
"category_name",
|
|
4623
|
-
"category name",
|
|
4624
|
-
"department",
|
|
4625
|
-
"collection"
|
|
4626
|
-
],
|
|
4627
|
-
description: ["summary", "content", "body", "text", "info", "details"],
|
|
4628
|
-
link: ["url", "href", "product_url", "page_url", "link"]
|
|
4629
|
-
};
|
|
4630
|
-
function resolveMetadataValue(meta, uiKey) {
|
|
4631
|
-
var _a;
|
|
4632
|
-
const synonyms = (_a = FIELD_SYNONYMS[uiKey]) != null ? _a : [];
|
|
4633
|
-
const keys = Object.keys(meta);
|
|
4634
|
-
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
4635
|
-
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
4636
|
-
if (match !== void 0) return meta[match];
|
|
4637
|
-
match = keys.find((k) => synonyms.map((s) => s.toLowerCase()).includes(k.toLowerCase()));
|
|
4638
|
-
if (match !== void 0) return meta[match];
|
|
4639
|
-
const isBlacklisted = (kl) => {
|
|
4640
|
-
return systemKeys.includes(kl) || kl.startsWith("option1") || kl.startsWith("option2") || kl.startsWith("option3");
|
|
4641
|
-
};
|
|
4642
|
-
match = keys.find((k) => {
|
|
4643
|
-
const kl = k.toLowerCase();
|
|
4644
|
-
if (isBlacklisted(kl)) return false;
|
|
4645
|
-
return kl.includes(uiKey.toLowerCase());
|
|
4646
|
-
});
|
|
4647
|
-
if (match !== void 0) return meta[match];
|
|
4648
|
-
match = keys.find((k) => {
|
|
4649
|
-
const kl = k.toLowerCase();
|
|
4650
|
-
if (isBlacklisted(kl)) return false;
|
|
4651
|
-
return synonyms.some((sk) => kl.includes(sk.toLowerCase()) || sk.toLowerCase().includes(kl));
|
|
4652
|
-
});
|
|
4653
|
-
return match !== void 0 ? meta[match] : void 0;
|
|
4654
|
-
}
|
|
4655
|
-
|
|
4656
4694
|
// src/utils/UITransformer.ts
|
|
4695
|
+
init_synonyms();
|
|
4657
4696
|
var UITransformer = class {
|
|
4658
4697
|
// ─── Public Entry Points ─────────────────────────────────────────────────
|
|
4659
4698
|
/**
|
|
@@ -4950,7 +4989,7 @@ RULES:
|
|
|
4950
4989
|
}
|
|
4951
4990
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
4952
4991
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
4953
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
4992
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null).slice(0, 15);
|
|
4954
4993
|
return {
|
|
4955
4994
|
type: "product_carousel",
|
|
4956
4995
|
title: "Recommended Products",
|
|
@@ -5909,14 +5948,16 @@ Given these metadata keys from a database: [${keys.join(", ")}]
|
|
|
5909
5948
|
Identify which keys best correspond to these standard UI properties:
|
|
5910
5949
|
${propertyList}
|
|
5911
5950
|
|
|
5912
|
-
Return ONLY a JSON object where the keys are the UI properties and the values are the matching database keys.
|
|
5951
|
+
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.
|
|
5913
5952
|
If no good match is found for a property, omit it.
|
|
5914
5953
|
|
|
5915
5954
|
Example:
|
|
5916
5955
|
{
|
|
5917
|
-
"name": "
|
|
5918
|
-
"price": "
|
|
5919
|
-
"brand": "
|
|
5956
|
+
"name": "Title",
|
|
5957
|
+
"price": "Variant Price",
|
|
5958
|
+
"brand": "Vendor",
|
|
5959
|
+
"image": "Image Src",
|
|
5960
|
+
"stock": "Variant Inventory Qty"
|
|
5920
5961
|
}
|
|
5921
5962
|
`;
|
|
5922
5963
|
try {
|
|
@@ -6207,7 +6248,10 @@ var Pipeline = class {
|
|
|
6207
6248
|
upsertBatchOptions
|
|
6208
6249
|
);
|
|
6209
6250
|
if (upsertResult.errors.length > 0) {
|
|
6210
|
-
console.warn(`[Pipeline] Ingestion: ${upsertResult.errors.length} batches failed
|
|
6251
|
+
console.warn(`[Pipeline] Ingestion: ${upsertResult.errors.length} batches failed. Error details:`);
|
|
6252
|
+
upsertResult.errors.forEach((err, idx) => {
|
|
6253
|
+
console.warn(` Batch ${idx + 1} Error: ${err.error.message || String(err.error)}`);
|
|
6254
|
+
});
|
|
6211
6255
|
}
|
|
6212
6256
|
return upsertResult.totalProcessed;
|
|
6213
6257
|
}
|
|
@@ -6322,8 +6366,9 @@ var Pipeline = class {
|
|
|
6322
6366
|
this.embeddingCache.set(cacheKey, queryVector);
|
|
6323
6367
|
}
|
|
6324
6368
|
const graphData = (strategyResult === "graph" || strategyResult === "both") && this.graphDB && ((_j = this.config.rag) == null ? void 0 : _j.useGraphRetrieval) ? yield new __await(this.graphDB.query(searchQuery)) : void 0;
|
|
6369
|
+
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
6325
6370
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
6326
|
-
const wantsExhaustiveList = hasNumericPredicates || /\b(list|all|show|provide|give|get)\b/i.test(question);
|
|
6371
|
+
const wantsExhaustiveList = hasNumericPredicates || hasMetadataFilter || /\b(list|all|show|provide|give|get|browse|find|search|display)\b/i.test(question);
|
|
6327
6372
|
const retrievalLimit = wantsExhaustiveList ? Math.max(topK * 20, 100) : topK * 2;
|
|
6328
6373
|
const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
|
|
6329
6374
|
const retrieveEnd = performance.now();
|
|
@@ -6331,15 +6376,28 @@ var Pipeline = class {
|
|
|
6331
6376
|
const retrieveMs = retrieveEnd - embedStart;
|
|
6332
6377
|
const rerankStart = performance.now();
|
|
6333
6378
|
const structuredSources = this.applyStructuredFilters(rawSources, filter);
|
|
6334
|
-
let
|
|
6379
|
+
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => m.score >= scoreThreshold);
|
|
6380
|
+
const rerankLimit = wantsExhaustiveList ? retrievalLimit : topK;
|
|
6335
6381
|
if (!hasNumericPredicates && ((_k = this.config.rag) == null ? void 0 : _k.useReranking)) {
|
|
6336
|
-
|
|
6382
|
+
fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
|
|
6337
6383
|
} else if (!wantsExhaustiveList) {
|
|
6338
|
-
|
|
6384
|
+
fullSources = fullSources.slice(0, topK);
|
|
6339
6385
|
}
|
|
6340
6386
|
const rerankMs = performance.now() - rerankStart;
|
|
6341
|
-
let context =
|
|
6387
|
+
let context = fullSources.length ? fullSources.map((m, i) => `[Source ${i + 1}]
|
|
6342
6388
|
${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
|
|
6389
|
+
let displayCount = 15;
|
|
6390
|
+
if (hasMetadataFilter) {
|
|
6391
|
+
displayCount = fullSources.length;
|
|
6392
|
+
} else {
|
|
6393
|
+
const baseThreshold = Math.max(scoreThreshold, 0.4);
|
|
6394
|
+
const highlyRelevant = fullSources.filter((m) => m.score >= baseThreshold);
|
|
6395
|
+
displayCount = Math.max(highlyRelevant.length, topK);
|
|
6396
|
+
if (displayCount > 15) {
|
|
6397
|
+
displayCount = 15;
|
|
6398
|
+
}
|
|
6399
|
+
}
|
|
6400
|
+
const sources = [...fullSources].sort((a, b) => b.score - a.score).slice(0, displayCount);
|
|
6343
6401
|
if (graphData && graphData.nodes.length > 0) {
|
|
6344
6402
|
const graphContext = graphData.nodes.map(
|
|
6345
6403
|
(n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
|
|
@@ -6352,7 +6410,18 @@ ${context}`;
|
|
|
6352
6410
|
}
|
|
6353
6411
|
const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
|
|
6354
6412
|
const trainedSchemaPromise = allMetadataKeys.length > 0 ? SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => void 0) : Promise.resolve(void 0);
|
|
6355
|
-
const
|
|
6413
|
+
const uiTransformationPromise = trainedSchemaPromise.then(
|
|
6414
|
+
(trainedSchema) => this.generateUiTransformation(
|
|
6415
|
+
question,
|
|
6416
|
+
sources,
|
|
6417
|
+
trainedSchema,
|
|
6418
|
+
hasNumericPredicates
|
|
6419
|
+
)
|
|
6420
|
+
).catch((uiError) => {
|
|
6421
|
+
console.warn("[Pipeline] UI transformation failed concurrently:", uiError);
|
|
6422
|
+
return UITransformer.transform(question, sources, this.config);
|
|
6423
|
+
});
|
|
6424
|
+
const restrictionSuffix = "\n\n(IMPORTANT: Format your response beautifully using rich Markdown! Use bolding for emphasis, headings (##) for structure, bullet points for lists, and proper line breaks between paragraphs to make it highly readable. However, NEVER generate Markdown tables, HTML figures, or text charts (the UI renders requested charts separately, so NEVER say you cannot create, display, draw, render, or provide a chart/visualization). If listing products, use simple markdown bullet points or comma-separated names. NEVER use plus signs (+) to separate product names, category names, or list items. For product description/detail questions, provide customer-facing prose only and do NOT list internal catalog fields such as Handle, Body (HTML), Vendor, Type, Tags, Published, Option, Variant, SKU, or raw metadata labels. You CAN use numbers for years/counts like 2006 or 5800, but NEVER put a dollar sign ($) before them.)";
|
|
6356
6425
|
const hardenedHistory = [...history];
|
|
6357
6426
|
const userQuestion = { role: "user", content: question + restrictionSuffix };
|
|
6358
6427
|
const messages = [...hardenedHistory, userQuestion];
|
|
@@ -6422,19 +6491,7 @@ ${context}`;
|
|
|
6422
6491
|
tokens,
|
|
6423
6492
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
6424
6493
|
};
|
|
6425
|
-
|
|
6426
|
-
try {
|
|
6427
|
-
const trainedSchema = yield new __await(trainedSchemaPromise);
|
|
6428
|
-
uiTransformation = yield new __await(this.generateUiTransformation(
|
|
6429
|
-
question,
|
|
6430
|
-
sources,
|
|
6431
|
-
trainedSchema,
|
|
6432
|
-
hasNumericPredicates
|
|
6433
|
-
));
|
|
6434
|
-
} catch (uiError) {
|
|
6435
|
-
console.warn("[Pipeline] UI transformation failed before metadata yield:", uiError);
|
|
6436
|
-
uiTransformation = UITransformer.transform(question, sources, this.config);
|
|
6437
|
-
}
|
|
6494
|
+
const uiTransformation = yield new __await(uiTransformationPromise);
|
|
6438
6495
|
yield {
|
|
6439
6496
|
reply: "",
|
|
6440
6497
|
sources,
|
|
@@ -6954,15 +7011,24 @@ function createStreamHandler(configOrPlugin) {
|
|
|
6954
7011
|
});
|
|
6955
7012
|
}
|
|
6956
7013
|
const encoder = new TextEncoder();
|
|
7014
|
+
let isActive = true;
|
|
6957
7015
|
const stream = new ReadableStream({
|
|
6958
7016
|
async start(controller) {
|
|
6959
7017
|
var _a;
|
|
6960
|
-
const enqueue = (text) =>
|
|
7018
|
+
const enqueue = (text) => {
|
|
7019
|
+
if (!isActive) return;
|
|
7020
|
+
try {
|
|
7021
|
+
controller.enqueue(encoder.encode(text));
|
|
7022
|
+
} catch (err) {
|
|
7023
|
+
console.warn("[createStreamHandler] Failed to enqueue (stream already closed):", err);
|
|
7024
|
+
}
|
|
7025
|
+
};
|
|
6961
7026
|
try {
|
|
6962
7027
|
const pipelineStream = plugin.chatStream(message, history, namespace);
|
|
6963
7028
|
try {
|
|
6964
7029
|
for (var iter = __forAwait(pipelineStream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
|
|
6965
7030
|
const chunk = temp.value;
|
|
7031
|
+
if (!isActive) break;
|
|
6966
7032
|
if (typeof chunk === "string") {
|
|
6967
7033
|
enqueue(sseTextFrame(chunk));
|
|
6968
7034
|
} else {
|
|
@@ -7000,12 +7066,27 @@ function createStreamHandler(configOrPlugin) {
|
|
|
7000
7066
|
}
|
|
7001
7067
|
}
|
|
7002
7068
|
} catch (streamError) {
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7069
|
+
if (isActive) {
|
|
7070
|
+
const errorMessage = streamError instanceof Error ? streamError.message : String(streamError);
|
|
7071
|
+
console.error("[createStreamHandler] Stream error:", streamError);
|
|
7072
|
+
try {
|
|
7073
|
+
enqueue(sseErrorFrame(errorMessage));
|
|
7074
|
+
} catch (e) {
|
|
7075
|
+
}
|
|
7076
|
+
}
|
|
7006
7077
|
} finally {
|
|
7007
|
-
|
|
7078
|
+
if (isActive) {
|
|
7079
|
+
isActive = false;
|
|
7080
|
+
try {
|
|
7081
|
+
controller.close();
|
|
7082
|
+
} catch (e) {
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7008
7085
|
}
|
|
7086
|
+
},
|
|
7087
|
+
cancel(reason) {
|
|
7088
|
+
isActive = false;
|
|
7089
|
+
console.log("[createStreamHandler] Stream connection closed by client:", reason);
|
|
7009
7090
|
}
|
|
7010
7091
|
});
|
|
7011
7092
|
return new Response(stream, { headers: SSE_HEADERS });
|
|
@@ -7066,6 +7147,7 @@ function createUploadHandler(configOrPlugin) {
|
|
|
7066
7147
|
if (parsed.data && parsed.data.length > 0) {
|
|
7067
7148
|
let i = 0;
|
|
7068
7149
|
let lastRowData = null;
|
|
7150
|
+
const csvCols = Object.keys(parsed.data[0]);
|
|
7069
7151
|
for (const row of parsed.data) {
|
|
7070
7152
|
i++;
|
|
7071
7153
|
const rowData = row;
|
|
@@ -7087,12 +7169,14 @@ function createUploadHandler(configOrPlugin) {
|
|
|
7087
7169
|
documents.push({
|
|
7088
7170
|
docId: `${file.name}-row-${i}`,
|
|
7089
7171
|
content: contentParts.join(", "),
|
|
7090
|
-
metadata: __spreadValues(__spreadValues({
|
|
7172
|
+
metadata: __spreadValues(__spreadProps(__spreadValues({
|
|
7091
7173
|
fileName: file.name,
|
|
7092
7174
|
fileSize: file.size,
|
|
7093
7175
|
fileType: file.type,
|
|
7094
7176
|
uploadedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7095
|
-
}, dimension ? { dimension } : {}),
|
|
7177
|
+
}, dimension ? { dimension } : {}), {
|
|
7178
|
+
csvHeaders: csvCols
|
|
7179
|
+
}), rowData)
|
|
7096
7180
|
});
|
|
7097
7181
|
}
|
|
7098
7182
|
}
|