@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
package/dist/handlers/index.mjs
CHANGED
|
@@ -519,6 +519,82 @@ var init_PostgreSQLProvider = __esm({
|
|
|
519
519
|
}
|
|
520
520
|
});
|
|
521
521
|
|
|
522
|
+
// src/utils/synonyms.ts
|
|
523
|
+
function resolveMetadataValue(meta, uiKey) {
|
|
524
|
+
var _a;
|
|
525
|
+
const synonyms = (_a = FIELD_SYNONYMS[uiKey]) != null ? _a : [];
|
|
526
|
+
const keys = Object.keys(meta);
|
|
527
|
+
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
528
|
+
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
529
|
+
if (match !== void 0) return meta[match];
|
|
530
|
+
match = keys.find((k) => synonyms.map((s) => s.toLowerCase()).includes(k.toLowerCase()));
|
|
531
|
+
if (match !== void 0) return meta[match];
|
|
532
|
+
const isBlacklisted = (kl) => {
|
|
533
|
+
return systemKeys.includes(kl) || kl.startsWith("option1") || kl.startsWith("option2") || kl.startsWith("option3");
|
|
534
|
+
};
|
|
535
|
+
match = keys.find((k) => {
|
|
536
|
+
const kl = k.toLowerCase();
|
|
537
|
+
if (isBlacklisted(kl)) return false;
|
|
538
|
+
return kl.includes(uiKey.toLowerCase());
|
|
539
|
+
});
|
|
540
|
+
if (match !== void 0) return meta[match];
|
|
541
|
+
match = keys.find((k) => {
|
|
542
|
+
const kl = k.toLowerCase();
|
|
543
|
+
if (isBlacklisted(kl)) return false;
|
|
544
|
+
return synonyms.some((sk) => kl.includes(sk.toLowerCase()) || sk.toLowerCase().includes(kl));
|
|
545
|
+
});
|
|
546
|
+
return match !== void 0 ? meta[match] : void 0;
|
|
547
|
+
}
|
|
548
|
+
var FIELD_SYNONYMS;
|
|
549
|
+
var init_synonyms = __esm({
|
|
550
|
+
"src/utils/synonyms.ts"() {
|
|
551
|
+
"use strict";
|
|
552
|
+
FIELD_SYNONYMS = {
|
|
553
|
+
name: ["product", "item", "title", "label", "heading", "subject", "product name", "item name"],
|
|
554
|
+
price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd", "variant price"],
|
|
555
|
+
brand: ["manufacturer", "vendor", "make", "company", "brand_name", "supplier"],
|
|
556
|
+
image: [
|
|
557
|
+
"imageUrl",
|
|
558
|
+
"thumbnail",
|
|
559
|
+
"img",
|
|
560
|
+
"url",
|
|
561
|
+
"photo",
|
|
562
|
+
"picture",
|
|
563
|
+
"media",
|
|
564
|
+
"image_url",
|
|
565
|
+
"main_image",
|
|
566
|
+
"product_image",
|
|
567
|
+
"thumb",
|
|
568
|
+
"image src",
|
|
569
|
+
"variant image"
|
|
570
|
+
],
|
|
571
|
+
stock: [
|
|
572
|
+
"inventory",
|
|
573
|
+
"quantity",
|
|
574
|
+
"count",
|
|
575
|
+
"availability",
|
|
576
|
+
"stock_level",
|
|
577
|
+
"inStock",
|
|
578
|
+
"is_available",
|
|
579
|
+
"in stock",
|
|
580
|
+
"status",
|
|
581
|
+
"variant inventory qty"
|
|
582
|
+
],
|
|
583
|
+
category: [
|
|
584
|
+
"product_category",
|
|
585
|
+
"product category",
|
|
586
|
+
"category_name",
|
|
587
|
+
"category name",
|
|
588
|
+
"department",
|
|
589
|
+
"collection",
|
|
590
|
+
"type"
|
|
591
|
+
],
|
|
592
|
+
description: ["summary", "content", "body", "text", "info", "details", "body (html)", "seo description"],
|
|
593
|
+
link: ["url", "href", "product_url", "page_url", "link"]
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
|
|
522
598
|
// src/providers/vectordb/MultiTablePostgresProvider.ts
|
|
523
599
|
var MultiTablePostgresProvider_exports = {};
|
|
524
600
|
__export(MultiTablePostgresProvider_exports, {
|
|
@@ -530,6 +606,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
530
606
|
"src/providers/vectordb/MultiTablePostgresProvider.ts"() {
|
|
531
607
|
"use strict";
|
|
532
608
|
init_BaseVectorProvider();
|
|
609
|
+
init_synonyms();
|
|
533
610
|
MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
534
611
|
constructor(config) {
|
|
535
612
|
var _a, _b, _c;
|
|
@@ -610,8 +687,13 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
610
687
|
}
|
|
611
688
|
tableName = tableName.replace(/[^a-z0-9_]/gi, "_").toLowerCase() || this.uploadTable;
|
|
612
689
|
const firstMeta = fileDocs[0].metadata || {};
|
|
613
|
-
|
|
614
|
-
|
|
690
|
+
let csvHeaders = [];
|
|
691
|
+
if (Array.isArray(firstMeta.csvHeaders)) {
|
|
692
|
+
csvHeaders = firstMeta.csvHeaders;
|
|
693
|
+
} else {
|
|
694
|
+
const systemKeys = ["fileName", "fileSize", "fileType", "uploadedAt", "dimension", "chunkIndex", "id", "namespace", "content", "metadata", "embedding", "docId", "docid", "chunkId", "chunkid", "csvHeaders", "csvheaders"];
|
|
695
|
+
csvHeaders = Object.keys(firstMeta).filter((k) => !systemKeys.includes(k) && !systemKeys.includes(k.toLowerCase()));
|
|
696
|
+
}
|
|
615
697
|
const columnDefs = csvHeaders.map((h) => `"${h}" TEXT`).join(",\n ");
|
|
616
698
|
const createTableSql = `
|
|
617
699
|
CREATE TABLE IF NOT EXISTS "${tableName}" (
|
|
@@ -704,10 +786,26 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
704
786
|
};
|
|
705
787
|
const dynamicKeywordQuery = getDynamicKeywordQuery();
|
|
706
788
|
const tableLimit = Math.max(topK, 50);
|
|
789
|
+
const metadataFilters = _filter == null ? void 0 : _filter.metadata;
|
|
707
790
|
const queryPromises = this.tables.map(async (table) => {
|
|
708
791
|
try {
|
|
709
792
|
let sqlQuery = "";
|
|
710
793
|
let params = [];
|
|
794
|
+
let whereClause = "";
|
|
795
|
+
const filterParams = [];
|
|
796
|
+
if (metadataFilters && Object.keys(metadataFilters).length > 0) {
|
|
797
|
+
const conditions = Object.entries(metadataFilters).map(([key, val]) => {
|
|
798
|
+
var _a3;
|
|
799
|
+
filterParams.push(String(val));
|
|
800
|
+
const baseOffset = queryText && dynamicKeywordQuery ? 2 : 1;
|
|
801
|
+
const paramIdx = baseOffset + filterParams.length;
|
|
802
|
+
const synonyms = (_a3 = FIELD_SYNONYMS[key]) != null ? _a3 : [];
|
|
803
|
+
const keysToCheck = [key, ...synonyms];
|
|
804
|
+
const coalesceExprs = keysToCheck.map((k) => `LOWER(metadata->>'${k}')`);
|
|
805
|
+
return `COALESCE(${coalesceExprs.join(", ")}) = LOWER($${paramIdx})`;
|
|
806
|
+
});
|
|
807
|
+
whereClause = `WHERE ${conditions.join(" AND ")}`;
|
|
808
|
+
}
|
|
711
809
|
if (queryText && dynamicKeywordQuery) {
|
|
712
810
|
const hasEntityHints = entityHints.length > 0;
|
|
713
811
|
const exactNameScoreExpr = hasEntityHints ? `+ (
|
|
@@ -724,19 +822,21 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
724
822
|
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) AS keyword_score,
|
|
725
823
|
((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
|
|
726
824
|
FROM "${table}" t
|
|
825
|
+
${whereClause}
|
|
727
826
|
ORDER BY hybrid_score DESC
|
|
728
827
|
LIMIT ${tableLimit}
|
|
729
828
|
`;
|
|
730
|
-
params = [vectorLiteral, dynamicKeywordQuery];
|
|
829
|
+
params = [vectorLiteral, dynamicKeywordQuery, ...filterParams];
|
|
731
830
|
} else {
|
|
732
831
|
sqlQuery = `
|
|
733
832
|
SELECT *,
|
|
734
833
|
(1 - (embedding <=> $1::vector)) AS hybrid_score
|
|
735
834
|
FROM "${table}" t
|
|
835
|
+
${whereClause}
|
|
736
836
|
ORDER BY hybrid_score DESC
|
|
737
837
|
LIMIT ${tableLimit}
|
|
738
838
|
`;
|
|
739
|
-
params = [vectorLiteral];
|
|
839
|
+
params = [vectorLiteral, ...filterParams];
|
|
740
840
|
}
|
|
741
841
|
const result = await this.pool.query(sqlQuery, params);
|
|
742
842
|
if (result.rowCount && result.rowCount > 0) {
|
|
@@ -969,12 +1069,15 @@ var init_MongoDBProvider = __esm({
|
|
|
969
1069
|
}
|
|
970
1070
|
);
|
|
971
1071
|
const results = await this.collection.aggregate(pipeline).toArray();
|
|
972
|
-
return results.map((res) =>
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1072
|
+
return results.map((res) => {
|
|
1073
|
+
const normalizedScore = res.score * 2 - 1;
|
|
1074
|
+
return {
|
|
1075
|
+
id: res._id,
|
|
1076
|
+
content: res[this.contentKey],
|
|
1077
|
+
metadata: res[this.metadataKey] || {},
|
|
1078
|
+
score: normalizedScore
|
|
1079
|
+
};
|
|
1080
|
+
});
|
|
978
1081
|
}
|
|
979
1082
|
async delete(id, namespace) {
|
|
980
1083
|
await this.collection.deleteOne(__spreadValues({ _id: id }, namespace ? { namespace } : {}));
|
|
@@ -4316,7 +4419,8 @@ var QueryProcessor = class {
|
|
|
4316
4419
|
const fieldValuePatterns = [
|
|
4317
4420
|
new RegExp(`\\b${fieldPattern}\\s*(?:=|:)\\s*["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi"),
|
|
4318
4421
|
new RegExp(`\\b${fieldPattern}\\s+(?:is|are|was|were|equals?|equal to|named|called)\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi"),
|
|
4319
|
-
new RegExp(`\\bwith\\s+${fieldPattern}\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi")
|
|
4422
|
+
new RegExp(`\\bwith\\s+${fieldPattern}\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi"),
|
|
4423
|
+
new RegExp(`\\b(?:under|in|for|from|of)\\s+${fieldPattern}\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi")
|
|
4320
4424
|
];
|
|
4321
4425
|
for (const pattern of fieldValuePatterns) {
|
|
4322
4426
|
for (const match of question.matchAll(pattern)) {
|
|
@@ -4550,73 +4654,8 @@ var LLMRouter = class {
|
|
|
4550
4654
|
}
|
|
4551
4655
|
};
|
|
4552
4656
|
|
|
4553
|
-
// src/utils/synonyms.ts
|
|
4554
|
-
var FIELD_SYNONYMS = {
|
|
4555
|
-
name: ["product", "item", "title", "label", "heading", "subject", "product name", "item name"],
|
|
4556
|
-
price: ["cost", "amount", "msrp", "price", "rate", "value", "price_usd"],
|
|
4557
|
-
brand: ["manufacturer", "vendor", "make", "company", "brand_name", "supplier"],
|
|
4558
|
-
image: [
|
|
4559
|
-
"imageUrl",
|
|
4560
|
-
"thumbnail",
|
|
4561
|
-
"img",
|
|
4562
|
-
"url",
|
|
4563
|
-
"photo",
|
|
4564
|
-
"picture",
|
|
4565
|
-
"media",
|
|
4566
|
-
"image_url",
|
|
4567
|
-
"main_image",
|
|
4568
|
-
"product_image",
|
|
4569
|
-
"thumb"
|
|
4570
|
-
],
|
|
4571
|
-
stock: [
|
|
4572
|
-
"inventory",
|
|
4573
|
-
"quantity",
|
|
4574
|
-
"count",
|
|
4575
|
-
"availability",
|
|
4576
|
-
"stock_level",
|
|
4577
|
-
"inStock",
|
|
4578
|
-
"is_available",
|
|
4579
|
-
"in stock",
|
|
4580
|
-
"status"
|
|
4581
|
-
],
|
|
4582
|
-
category: [
|
|
4583
|
-
"product_category",
|
|
4584
|
-
"product category",
|
|
4585
|
-
"category_name",
|
|
4586
|
-
"category name",
|
|
4587
|
-
"department",
|
|
4588
|
-
"collection"
|
|
4589
|
-
],
|
|
4590
|
-
description: ["summary", "content", "body", "text", "info", "details"],
|
|
4591
|
-
link: ["url", "href", "product_url", "page_url", "link"]
|
|
4592
|
-
};
|
|
4593
|
-
function resolveMetadataValue(meta, uiKey) {
|
|
4594
|
-
var _a;
|
|
4595
|
-
const synonyms = (_a = FIELD_SYNONYMS[uiKey]) != null ? _a : [];
|
|
4596
|
-
const keys = Object.keys(meta);
|
|
4597
|
-
const systemKeys = ["namespace", "filename", "filesize", "filetype", "docid", "uploadedat", "dimension", "chunkindex"];
|
|
4598
|
-
let match = keys.find((k) => k.toLowerCase() === uiKey.toLowerCase());
|
|
4599
|
-
if (match !== void 0) return meta[match];
|
|
4600
|
-
match = keys.find((k) => synonyms.map((s) => s.toLowerCase()).includes(k.toLowerCase()));
|
|
4601
|
-
if (match !== void 0) return meta[match];
|
|
4602
|
-
const isBlacklisted = (kl) => {
|
|
4603
|
-
return systemKeys.includes(kl) || kl.startsWith("option1") || kl.startsWith("option2") || kl.startsWith("option3");
|
|
4604
|
-
};
|
|
4605
|
-
match = keys.find((k) => {
|
|
4606
|
-
const kl = k.toLowerCase();
|
|
4607
|
-
if (isBlacklisted(kl)) return false;
|
|
4608
|
-
return kl.includes(uiKey.toLowerCase());
|
|
4609
|
-
});
|
|
4610
|
-
if (match !== void 0) return meta[match];
|
|
4611
|
-
match = keys.find((k) => {
|
|
4612
|
-
const kl = k.toLowerCase();
|
|
4613
|
-
if (isBlacklisted(kl)) return false;
|
|
4614
|
-
return synonyms.some((sk) => kl.includes(sk.toLowerCase()) || sk.toLowerCase().includes(kl));
|
|
4615
|
-
});
|
|
4616
|
-
return match !== void 0 ? meta[match] : void 0;
|
|
4617
|
-
}
|
|
4618
|
-
|
|
4619
4657
|
// src/utils/UITransformer.ts
|
|
4658
|
+
init_synonyms();
|
|
4620
4659
|
var UITransformer = class {
|
|
4621
4660
|
// ─── Public Entry Points ─────────────────────────────────────────────────
|
|
4622
4661
|
/**
|
|
@@ -4913,7 +4952,7 @@ RULES:
|
|
|
4913
4952
|
}
|
|
4914
4953
|
// ─── Transform Helpers ────────────────────────────────────────────────────
|
|
4915
4954
|
static transformToProductCarousel(data, config, trainedSchema) {
|
|
4916
|
-
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
|
|
4955
|
+
const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null).slice(0, 15);
|
|
4917
4956
|
return {
|
|
4918
4957
|
type: "product_carousel",
|
|
4919
4958
|
title: "Recommended Products",
|
|
@@ -5872,14 +5911,16 @@ Given these metadata keys from a database: [${keys.join(", ")}]
|
|
|
5872
5911
|
Identify which keys best correspond to these standard UI properties:
|
|
5873
5912
|
${propertyList}
|
|
5874
5913
|
|
|
5875
|
-
Return ONLY a JSON object where the keys are the UI properties and the values are the matching database keys.
|
|
5914
|
+
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.
|
|
5876
5915
|
If no good match is found for a property, omit it.
|
|
5877
5916
|
|
|
5878
5917
|
Example:
|
|
5879
5918
|
{
|
|
5880
|
-
"name": "
|
|
5881
|
-
"price": "
|
|
5882
|
-
"brand": "
|
|
5919
|
+
"name": "Title",
|
|
5920
|
+
"price": "Variant Price",
|
|
5921
|
+
"brand": "Vendor",
|
|
5922
|
+
"image": "Image Src",
|
|
5923
|
+
"stock": "Variant Inventory Qty"
|
|
5883
5924
|
}
|
|
5884
5925
|
`;
|
|
5885
5926
|
try {
|
|
@@ -6170,7 +6211,10 @@ var Pipeline = class {
|
|
|
6170
6211
|
upsertBatchOptions
|
|
6171
6212
|
);
|
|
6172
6213
|
if (upsertResult.errors.length > 0) {
|
|
6173
|
-
console.warn(`[Pipeline] Ingestion: ${upsertResult.errors.length} batches failed
|
|
6214
|
+
console.warn(`[Pipeline] Ingestion: ${upsertResult.errors.length} batches failed. Error details:`);
|
|
6215
|
+
upsertResult.errors.forEach((err, idx) => {
|
|
6216
|
+
console.warn(` Batch ${idx + 1} Error: ${err.error.message || String(err.error)}`);
|
|
6217
|
+
});
|
|
6174
6218
|
}
|
|
6175
6219
|
return upsertResult.totalProcessed;
|
|
6176
6220
|
}
|
|
@@ -6285,8 +6329,9 @@ var Pipeline = class {
|
|
|
6285
6329
|
this.embeddingCache.set(cacheKey, queryVector);
|
|
6286
6330
|
}
|
|
6287
6331
|
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;
|
|
6332
|
+
const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
|
|
6288
6333
|
const hasNumericPredicates = Array.isArray(filter.__numericPredicates) && filter.__numericPredicates.length > 0;
|
|
6289
|
-
const wantsExhaustiveList = hasNumericPredicates || /\b(list|all|show|provide|give|get)\b/i.test(question);
|
|
6334
|
+
const wantsExhaustiveList = hasNumericPredicates || hasMetadataFilter || /\b(list|all|show|provide|give|get|browse|find|search|display)\b/i.test(question);
|
|
6290
6335
|
const retrievalLimit = wantsExhaustiveList ? Math.max(topK * 20, 100) : topK * 2;
|
|
6291
6336
|
const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
|
|
6292
6337
|
const retrieveEnd = performance.now();
|
|
@@ -6294,15 +6339,28 @@ var Pipeline = class {
|
|
|
6294
6339
|
const retrieveMs = retrieveEnd - embedStart;
|
|
6295
6340
|
const rerankStart = performance.now();
|
|
6296
6341
|
const structuredSources = this.applyStructuredFilters(rawSources, filter);
|
|
6297
|
-
let
|
|
6342
|
+
let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => m.score >= scoreThreshold);
|
|
6343
|
+
const rerankLimit = wantsExhaustiveList ? retrievalLimit : topK;
|
|
6298
6344
|
if (!hasNumericPredicates && ((_k = this.config.rag) == null ? void 0 : _k.useReranking)) {
|
|
6299
|
-
|
|
6345
|
+
fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
|
|
6300
6346
|
} else if (!wantsExhaustiveList) {
|
|
6301
|
-
|
|
6347
|
+
fullSources = fullSources.slice(0, topK);
|
|
6302
6348
|
}
|
|
6303
6349
|
const rerankMs = performance.now() - rerankStart;
|
|
6304
|
-
let context =
|
|
6350
|
+
let context = fullSources.length ? fullSources.map((m, i) => `[Source ${i + 1}]
|
|
6305
6351
|
${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
|
|
6352
|
+
let displayCount = 15;
|
|
6353
|
+
if (hasMetadataFilter) {
|
|
6354
|
+
displayCount = fullSources.length;
|
|
6355
|
+
} else {
|
|
6356
|
+
const baseThreshold = Math.max(scoreThreshold, 0.4);
|
|
6357
|
+
const highlyRelevant = fullSources.filter((m) => m.score >= baseThreshold);
|
|
6358
|
+
displayCount = Math.max(highlyRelevant.length, topK);
|
|
6359
|
+
if (displayCount > 15) {
|
|
6360
|
+
displayCount = 15;
|
|
6361
|
+
}
|
|
6362
|
+
}
|
|
6363
|
+
const sources = [...fullSources].sort((a, b) => b.score - a.score).slice(0, displayCount);
|
|
6306
6364
|
if (graphData && graphData.nodes.length > 0) {
|
|
6307
6365
|
const graphContext = graphData.nodes.map(
|
|
6308
6366
|
(n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
|
|
@@ -6315,7 +6373,18 @@ ${context}`;
|
|
|
6315
6373
|
}
|
|
6316
6374
|
const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
|
|
6317
6375
|
const trainedSchemaPromise = allMetadataKeys.length > 0 ? SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => void 0) : Promise.resolve(void 0);
|
|
6318
|
-
const
|
|
6376
|
+
const uiTransformationPromise = trainedSchemaPromise.then(
|
|
6377
|
+
(trainedSchema) => this.generateUiTransformation(
|
|
6378
|
+
question,
|
|
6379
|
+
sources,
|
|
6380
|
+
trainedSchema,
|
|
6381
|
+
hasNumericPredicates
|
|
6382
|
+
)
|
|
6383
|
+
).catch((uiError) => {
|
|
6384
|
+
console.warn("[Pipeline] UI transformation failed concurrently:", uiError);
|
|
6385
|
+
return UITransformer.transform(question, sources, this.config);
|
|
6386
|
+
});
|
|
6387
|
+
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.)";
|
|
6319
6388
|
const hardenedHistory = [...history];
|
|
6320
6389
|
const userQuestion = { role: "user", content: question + restrictionSuffix };
|
|
6321
6390
|
const messages = [...hardenedHistory, userQuestion];
|
|
@@ -6385,19 +6454,7 @@ ${context}`;
|
|
|
6385
6454
|
tokens,
|
|
6386
6455
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
6387
6456
|
};
|
|
6388
|
-
|
|
6389
|
-
try {
|
|
6390
|
-
const trainedSchema = yield new __await(trainedSchemaPromise);
|
|
6391
|
-
uiTransformation = yield new __await(this.generateUiTransformation(
|
|
6392
|
-
question,
|
|
6393
|
-
sources,
|
|
6394
|
-
trainedSchema,
|
|
6395
|
-
hasNumericPredicates
|
|
6396
|
-
));
|
|
6397
|
-
} catch (uiError) {
|
|
6398
|
-
console.warn("[Pipeline] UI transformation failed before metadata yield:", uiError);
|
|
6399
|
-
uiTransformation = UITransformer.transform(question, sources, this.config);
|
|
6400
|
-
}
|
|
6457
|
+
const uiTransformation = yield new __await(uiTransformationPromise);
|
|
6401
6458
|
yield {
|
|
6402
6459
|
reply: "",
|
|
6403
6460
|
sources,
|
|
@@ -6917,15 +6974,24 @@ function createStreamHandler(configOrPlugin) {
|
|
|
6917
6974
|
});
|
|
6918
6975
|
}
|
|
6919
6976
|
const encoder = new TextEncoder();
|
|
6977
|
+
let isActive = true;
|
|
6920
6978
|
const stream = new ReadableStream({
|
|
6921
6979
|
async start(controller) {
|
|
6922
6980
|
var _a;
|
|
6923
|
-
const enqueue = (text) =>
|
|
6981
|
+
const enqueue = (text) => {
|
|
6982
|
+
if (!isActive) return;
|
|
6983
|
+
try {
|
|
6984
|
+
controller.enqueue(encoder.encode(text));
|
|
6985
|
+
} catch (err) {
|
|
6986
|
+
console.warn("[createStreamHandler] Failed to enqueue (stream already closed):", err);
|
|
6987
|
+
}
|
|
6988
|
+
};
|
|
6924
6989
|
try {
|
|
6925
6990
|
const pipelineStream = plugin.chatStream(message, history, namespace);
|
|
6926
6991
|
try {
|
|
6927
6992
|
for (var iter = __forAwait(pipelineStream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
|
|
6928
6993
|
const chunk = temp.value;
|
|
6994
|
+
if (!isActive) break;
|
|
6929
6995
|
if (typeof chunk === "string") {
|
|
6930
6996
|
enqueue(sseTextFrame(chunk));
|
|
6931
6997
|
} else {
|
|
@@ -6963,12 +7029,27 @@ function createStreamHandler(configOrPlugin) {
|
|
|
6963
7029
|
}
|
|
6964
7030
|
}
|
|
6965
7031
|
} catch (streamError) {
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
7032
|
+
if (isActive) {
|
|
7033
|
+
const errorMessage = streamError instanceof Error ? streamError.message : String(streamError);
|
|
7034
|
+
console.error("[createStreamHandler] Stream error:", streamError);
|
|
7035
|
+
try {
|
|
7036
|
+
enqueue(sseErrorFrame(errorMessage));
|
|
7037
|
+
} catch (e) {
|
|
7038
|
+
}
|
|
7039
|
+
}
|
|
6969
7040
|
} finally {
|
|
6970
|
-
|
|
7041
|
+
if (isActive) {
|
|
7042
|
+
isActive = false;
|
|
7043
|
+
try {
|
|
7044
|
+
controller.close();
|
|
7045
|
+
} catch (e) {
|
|
7046
|
+
}
|
|
7047
|
+
}
|
|
6971
7048
|
}
|
|
7049
|
+
},
|
|
7050
|
+
cancel(reason) {
|
|
7051
|
+
isActive = false;
|
|
7052
|
+
console.log("[createStreamHandler] Stream connection closed by client:", reason);
|
|
6972
7053
|
}
|
|
6973
7054
|
});
|
|
6974
7055
|
return new Response(stream, { headers: SSE_HEADERS });
|
|
@@ -7029,6 +7110,7 @@ function createUploadHandler(configOrPlugin) {
|
|
|
7029
7110
|
if (parsed.data && parsed.data.length > 0) {
|
|
7030
7111
|
let i = 0;
|
|
7031
7112
|
let lastRowData = null;
|
|
7113
|
+
const csvCols = Object.keys(parsed.data[0]);
|
|
7032
7114
|
for (const row of parsed.data) {
|
|
7033
7115
|
i++;
|
|
7034
7116
|
const rowData = row;
|
|
@@ -7050,12 +7132,14 @@ function createUploadHandler(configOrPlugin) {
|
|
|
7050
7132
|
documents.push({
|
|
7051
7133
|
docId: `${file.name}-row-${i}`,
|
|
7052
7134
|
content: contentParts.join(", "),
|
|
7053
|
-
metadata: __spreadValues(__spreadValues({
|
|
7135
|
+
metadata: __spreadValues(__spreadProps(__spreadValues({
|
|
7054
7136
|
fileName: file.name,
|
|
7055
7137
|
fileSize: file.size,
|
|
7056
7138
|
fileType: file.type,
|
|
7057
7139
|
uploadedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
7058
|
-
}, dimension ? { dimension } : {}),
|
|
7140
|
+
}, dimension ? { dimension } : {}), {
|
|
7141
|
+
csvHeaders: csvCols
|
|
7142
|
+
}), rowData)
|
|
7059
7143
|
});
|
|
7060
7144
|
}
|
|
7061
7145
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { k as RagConfig, I as ILLMProvider, C as ChatMessage, d as ChatResponse, g as IngestDocument } from './ILLMProvider-
|
|
1
|
+
import { k as RagConfig, I as ILLMProvider, C as ChatMessage, d as ChatResponse, g as IngestDocument } from './ILLMProvider-Bw2A28nU.mjs';
|
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
3
3
|
|
|
4
4
|
interface ValidationError {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { k as RagConfig, I as ILLMProvider, C as ChatMessage, d as ChatResponse, g as IngestDocument } from './ILLMProvider-
|
|
1
|
+
import { k as RagConfig, I as ILLMProvider, C as ChatMessage, d as ChatResponse, g as IngestDocument } from './ILLMProvider-Bw2A28nU.js';
|
|
2
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
3
3
|
|
|
4
4
|
interface ValidationError {
|
package/dist/index.css
CHANGED
|
@@ -313,6 +313,9 @@
|
|
|
313
313
|
.right-0 {
|
|
314
314
|
right: calc(var(--spacing) * 0);
|
|
315
315
|
}
|
|
316
|
+
.right-2 {
|
|
317
|
+
right: calc(var(--spacing) * 2);
|
|
318
|
+
}
|
|
316
319
|
.right-4 {
|
|
317
320
|
right: calc(var(--spacing) * 4);
|
|
318
321
|
}
|
|
@@ -809,6 +812,12 @@
|
|
|
809
812
|
--tw-scale-z: 90%;
|
|
810
813
|
scale: var(--tw-scale-x) var(--tw-scale-y);
|
|
811
814
|
}
|
|
815
|
+
.scale-95 {
|
|
816
|
+
--tw-scale-x: 95%;
|
|
817
|
+
--tw-scale-y: 95%;
|
|
818
|
+
--tw-scale-z: 95%;
|
|
819
|
+
scale: var(--tw-scale-x) var(--tw-scale-y);
|
|
820
|
+
}
|
|
812
821
|
.scale-100 {
|
|
813
822
|
--tw-scale-x: 100%;
|
|
814
823
|
--tw-scale-y: 100%;
|
|
@@ -1058,6 +1067,9 @@
|
|
|
1058
1067
|
.rounded-3xl {
|
|
1059
1068
|
border-radius: var(--radius-3xl);
|
|
1060
1069
|
}
|
|
1070
|
+
.rounded-\[2px\] {
|
|
1071
|
+
border-radius: 2px;
|
|
1072
|
+
}
|
|
1061
1073
|
.rounded-full {
|
|
1062
1074
|
border-radius: calc(infinity * 1px);
|
|
1063
1075
|
}
|
|
@@ -1144,6 +1156,12 @@
|
|
|
1144
1156
|
.border-emerald-500 {
|
|
1145
1157
|
border-color: var(--color-emerald-500);
|
|
1146
1158
|
}
|
|
1159
|
+
.border-emerald-500\/20 {
|
|
1160
|
+
border-color: color-mix(in srgb, oklch(69.6% 0.17 162.48) 20%, transparent);
|
|
1161
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1162
|
+
border-color: color-mix(in oklab, var(--color-emerald-500) 20%, transparent);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1147
1165
|
.border-indigo-100 {
|
|
1148
1166
|
border-color: var(--color-indigo-100);
|
|
1149
1167
|
}
|
|
@@ -1219,6 +1237,12 @@
|
|
|
1219
1237
|
.bg-emerald-500 {
|
|
1220
1238
|
background-color: var(--color-emerald-500);
|
|
1221
1239
|
}
|
|
1240
|
+
.bg-emerald-500\/10 {
|
|
1241
|
+
background-color: color-mix(in srgb, oklch(69.6% 0.17 162.48) 10%, transparent);
|
|
1242
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1243
|
+
background-color: color-mix(in oklab, var(--color-emerald-500) 10%, transparent);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1222
1246
|
.bg-green-500 {
|
|
1223
1247
|
background-color: var(--color-green-500);
|
|
1224
1248
|
}
|
|
@@ -1261,6 +1285,12 @@
|
|
|
1261
1285
|
.bg-slate-400 {
|
|
1262
1286
|
background-color: var(--color-slate-400);
|
|
1263
1287
|
}
|
|
1288
|
+
.bg-slate-500\/5 {
|
|
1289
|
+
background-color: color-mix(in srgb, oklch(55.4% 0.046 257.417) 5%, transparent);
|
|
1290
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1291
|
+
background-color: color-mix(in oklab, var(--color-slate-500) 5%, transparent);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1264
1294
|
.bg-slate-900 {
|
|
1265
1295
|
background-color: var(--color-slate-900);
|
|
1266
1296
|
}
|
|
@@ -1794,6 +1824,16 @@
|
|
|
1794
1824
|
.\[animation-delay\:300ms\] {
|
|
1795
1825
|
animation-delay: 300ms;
|
|
1796
1826
|
}
|
|
1827
|
+
.group-hover\:scale-100 {
|
|
1828
|
+
&:is(:where(.group):hover *) {
|
|
1829
|
+
@media (hover: hover) {
|
|
1830
|
+
--tw-scale-x: 100%;
|
|
1831
|
+
--tw-scale-y: 100%;
|
|
1832
|
+
--tw-scale-z: 100%;
|
|
1833
|
+
scale: var(--tw-scale-x) var(--tw-scale-y);
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1797
1837
|
.group-hover\:scale-105 {
|
|
1798
1838
|
&:is(:where(.group):hover *) {
|
|
1799
1839
|
@media (hover: hover) {
|
|
@@ -1933,6 +1973,13 @@
|
|
|
1933
1973
|
}
|
|
1934
1974
|
}
|
|
1935
1975
|
}
|
|
1976
|
+
.hover\:bg-rose-600 {
|
|
1977
|
+
&:hover {
|
|
1978
|
+
@media (hover: hover) {
|
|
1979
|
+
background-color: var(--color-rose-600);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1936
1983
|
.hover\:bg-slate-50 {
|
|
1937
1984
|
&:hover {
|
|
1938
1985
|
@media (hover: hover) {
|
|
@@ -1974,6 +2021,16 @@
|
|
|
1974
2021
|
}
|
|
1975
2022
|
}
|
|
1976
2023
|
}
|
|
2024
|
+
.hover\:bg-slate-500\/10 {
|
|
2025
|
+
&:hover {
|
|
2026
|
+
@media (hover: hover) {
|
|
2027
|
+
background-color: color-mix(in srgb, oklch(55.4% 0.046 257.417) 10%, transparent);
|
|
2028
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
2029
|
+
background-color: color-mix(in oklab, var(--color-slate-500) 10%, transparent);
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
1977
2034
|
.hover\:bg-white {
|
|
1978
2035
|
&:hover {
|
|
1979
2036
|
@media (hover: hover) {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { CSSProperties, MouseEvent, ReactNode } from 'react';
|
|
3
|
-
import { P as Product, U as UIConfig, R as RagMessage, V as VectorMatch, O as ObservabilityTrace, a as UseRagChatOptions, b as UseRagChatReturn } from './ILLMProvider-
|
|
4
|
-
export { C as ChatMessage, c as ChatOptions, d as ChatResponse, E as EmbedOptions, e as EmbeddingConfig, f as EmbeddingProvider, I as ILLMProvider, g as IngestDocument, L as LLMConfig, h as LLMProvider, i as LatencyBreakdown, j as RAGConfig, k as RagConfig, l as RetrievedChunk, T as TokenUsage, m as UpsertDocument, n as VectorDBConfig, o as VectorDBProvider } from './ILLMProvider-
|
|
3
|
+
import { P as Product, U as UIConfig, R as RagMessage, V as VectorMatch, O as ObservabilityTrace, a as UseRagChatOptions, b as UseRagChatReturn } from './ILLMProvider-Bw2A28nU.mjs';
|
|
4
|
+
export { C as ChatMessage, c as ChatOptions, d as ChatResponse, E as EmbedOptions, e as EmbeddingConfig, f as EmbeddingProvider, I as ILLMProvider, g as IngestDocument, L as LLMConfig, h as LLMProvider, i as LatencyBreakdown, j as RAGConfig, k as RagConfig, l as RetrievedChunk, T as TokenUsage, m as UpsertDocument, n as VectorDBConfig, o as VectorDBProvider } from './ILLMProvider-Bw2A28nU.mjs';
|
|
5
5
|
export { C as Chunk, a as ChunkOptions } from './DocumentChunker-Dh9TvmGG.mjs';
|
|
6
6
|
|
|
7
7
|
type ChatViewportSize = 'compact' | 'medium' | 'large';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { CSSProperties, MouseEvent, ReactNode } from 'react';
|
|
3
|
-
import { P as Product, U as UIConfig, R as RagMessage, V as VectorMatch, O as ObservabilityTrace, a as UseRagChatOptions, b as UseRagChatReturn } from './ILLMProvider-
|
|
4
|
-
export { C as ChatMessage, c as ChatOptions, d as ChatResponse, E as EmbedOptions, e as EmbeddingConfig, f as EmbeddingProvider, I as ILLMProvider, g as IngestDocument, L as LLMConfig, h as LLMProvider, i as LatencyBreakdown, j as RAGConfig, k as RagConfig, l as RetrievedChunk, T as TokenUsage, m as UpsertDocument, n as VectorDBConfig, o as VectorDBProvider } from './ILLMProvider-
|
|
3
|
+
import { P as Product, U as UIConfig, R as RagMessage, V as VectorMatch, O as ObservabilityTrace, a as UseRagChatOptions, b as UseRagChatReturn } from './ILLMProvider-Bw2A28nU.js';
|
|
4
|
+
export { C as ChatMessage, c as ChatOptions, d as ChatResponse, E as EmbedOptions, e as EmbeddingConfig, f as EmbeddingProvider, I as ILLMProvider, g as IngestDocument, L as LLMConfig, h as LLMProvider, i as LatencyBreakdown, j as RAGConfig, k as RagConfig, l as RetrievedChunk, T as TokenUsage, m as UpsertDocument, n as VectorDBConfig, o as VectorDBProvider } from './ILLMProvider-Bw2A28nU.js';
|
|
5
5
|
export { C as Chunk, a as ChunkOptions } from './DocumentChunker-Dh9TvmGG.js';
|
|
6
6
|
|
|
7
7
|
type ChatViewportSize = 'compact' | 'medium' | 'large';
|