@retrivora-ai/rag-engine 1.9.1 → 1.9.2

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.
@@ -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
- const systemKeys = ["fileName", "fileSize", "fileType", "uploadedAt", "dimension", "chunkIndex", "id", "namespace", "content", "metadata", "embedding"];
614
- const csvHeaders = Object.keys(firstMeta).filter((k) => !systemKeys.includes(k) && !systemKeys.includes(k.toLowerCase()));
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) {
@@ -4316,7 +4416,8 @@ var QueryProcessor = class {
4316
4416
  const fieldValuePatterns = [
4317
4417
  new RegExp(`\\b${fieldPattern}\\s*(?:=|:)\\s*["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi"),
4318
4418
  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")
4419
+ new RegExp(`\\bwith\\s+${fieldPattern}\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi"),
4420
+ new RegExp(`\\b(?:under|in|for|from|of)\\s+${fieldPattern}\\s+["']?${valuePattern}["']?(?=[?.!,]|$)`, "gi")
4320
4421
  ];
4321
4422
  for (const pattern of fieldValuePatterns) {
4322
4423
  for (const match of question.matchAll(pattern)) {
@@ -4550,73 +4651,8 @@ var LLMRouter = class {
4550
4651
  }
4551
4652
  };
4552
4653
 
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
4654
  // src/utils/UITransformer.ts
4655
+ init_synonyms();
4620
4656
  var UITransformer = class {
4621
4657
  // ─── Public Entry Points ─────────────────────────────────────────────────
4622
4658
  /**
@@ -4913,7 +4949,7 @@ RULES:
4913
4949
  }
4914
4950
  // ─── Transform Helpers ────────────────────────────────────────────────────
4915
4951
  static transformToProductCarousel(data, config, trainedSchema) {
4916
- const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null);
4952
+ const products = data.map((item) => this.extractProductInfo(item, config, trainedSchema)).filter((p) => p !== null).slice(0, 15);
4917
4953
  return {
4918
4954
  type: "product_carousel",
4919
4955
  title: "Recommended Products",
@@ -5872,14 +5908,16 @@ Given these metadata keys from a database: [${keys.join(", ")}]
5872
5908
  Identify which keys best correspond to these standard UI properties:
5873
5909
  ${propertyList}
5874
5910
 
5875
- Return ONLY a JSON object where the keys are the UI properties and the values are the matching database keys.
5911
+ 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
5912
  If no good match is found for a property, omit it.
5877
5913
 
5878
5914
  Example:
5879
5915
  {
5880
- "name": "Product_Title",
5881
- "price": "MSRP_USD",
5882
- "brand": "VendorName"
5916
+ "name": "Title",
5917
+ "price": "Variant Price",
5918
+ "brand": "Vendor",
5919
+ "image": "Image Src",
5920
+ "stock": "Variant Inventory Qty"
5883
5921
  }
5884
5922
  `;
5885
5923
  try {
@@ -6170,7 +6208,10 @@ var Pipeline = class {
6170
6208
  upsertBatchOptions
6171
6209
  );
6172
6210
  if (upsertResult.errors.length > 0) {
6173
- console.warn(`[Pipeline] Ingestion: ${upsertResult.errors.length} batches failed`);
6211
+ console.warn(`[Pipeline] Ingestion: ${upsertResult.errors.length} batches failed. Error details:`);
6212
+ upsertResult.errors.forEach((err, idx) => {
6213
+ console.warn(` Batch ${idx + 1} Error: ${err.error.message || String(err.error)}`);
6214
+ });
6174
6215
  }
6175
6216
  return upsertResult.totalProcessed;
6176
6217
  }
@@ -6285,8 +6326,9 @@ var Pipeline = class {
6285
6326
  this.embeddingCache.set(cacheKey, queryVector);
6286
6327
  }
6287
6328
  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;
6329
+ const hasMetadataFilter = filter.metadata && Object.keys(filter.metadata).length > 0;
6288
6330
  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);
6331
+ const wantsExhaustiveList = hasNumericPredicates || hasMetadataFilter || /\b(list|all|show|provide|give|get|browse|find|search|display)\b/i.test(question);
6290
6332
  const retrievalLimit = wantsExhaustiveList ? Math.max(topK * 20, 100) : topK * 2;
6291
6333
  const rawSources = (strategyResult === "vector" || strategyResult === "both") && queryVector && queryVector.length > 0 ? yield new __await(this.vectorDB.query(queryVector, retrievalLimit, ns, filter)) : [];
6292
6334
  const retrieveEnd = performance.now();
@@ -6294,15 +6336,27 @@ var Pipeline = class {
6294
6336
  const retrieveMs = retrieveEnd - embedStart;
6295
6337
  const rerankStart = performance.now();
6296
6338
  const structuredSources = this.applyStructuredFilters(rawSources, filter);
6297
- let sources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => m.score >= scoreThreshold);
6339
+ let fullSources = hasNumericPredicates ? structuredSources : structuredSources.filter((m) => m.score >= scoreThreshold);
6340
+ const rerankLimit = wantsExhaustiveList ? retrievalLimit : topK;
6298
6341
  if (!hasNumericPredicates && ((_k = this.config.rag) == null ? void 0 : _k.useReranking)) {
6299
- sources = yield new __await(this.reranker.rerank(sources, question, topK));
6342
+ fullSources = yield new __await(this.reranker.rerank(fullSources, question, rerankLimit));
6300
6343
  } else if (!wantsExhaustiveList) {
6301
- sources = sources.slice(0, topK);
6344
+ fullSources = fullSources.slice(0, topK);
6302
6345
  }
6303
6346
  const rerankMs = performance.now() - rerankStart;
6304
- let context = sources.length ? sources.map((m, i) => `[Source ${i + 1}]
6347
+ let context = fullSources.length ? fullSources.map((m, i) => `[Source ${i + 1}]
6305
6348
  ${m.content}`).join("\n\n---\n\n") : "No relevant context found.";
6349
+ let displayCount = 15;
6350
+ if (hasMetadataFilter) {
6351
+ displayCount = fullSources.length;
6352
+ } else {
6353
+ const highlyRelevant = fullSources.filter((m) => m.score >= 0.4);
6354
+ displayCount = Math.max(highlyRelevant.length, topK);
6355
+ if (displayCount > 15) {
6356
+ displayCount = 15;
6357
+ }
6358
+ }
6359
+ const sources = [...fullSources].sort((a, b) => b.score - a.score).slice(0, displayCount);
6306
6360
  if (graphData && graphData.nodes.length > 0) {
6307
6361
  const graphContext = graphData.nodes.map(
6308
6362
  (n) => `Entity: ${n.label} (${n.id})${n.properties ? " - " + JSON.stringify(n.properties) : ""}`
@@ -6315,7 +6369,18 @@ ${context}`;
6315
6369
  }
6316
6370
  const allMetadataKeys = Array.from(new Set(sources.flatMap((s) => Object.keys(s.metadata || {}))));
6317
6371
  const trainedSchemaPromise = allMetadataKeys.length > 0 ? SchemaMapper.train(this.llmProvider, ns, allMetadataKeys).catch(() => void 0) : Promise.resolve(void 0);
6318
- const restrictionSuffix = "\n\n(IMPORTANT: Use plain text only. NEVER generate 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 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.)";
6372
+ const uiTransformationPromise = trainedSchemaPromise.then(
6373
+ (trainedSchema) => this.generateUiTransformation(
6374
+ question,
6375
+ sources,
6376
+ trainedSchema,
6377
+ hasNumericPredicates
6378
+ )
6379
+ ).catch((uiError) => {
6380
+ console.warn("[Pipeline] UI transformation failed concurrently:", uiError);
6381
+ return UITransformer.transform(question, sources, this.config);
6382
+ });
6383
+ 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
6384
  const hardenedHistory = [...history];
6320
6385
  const userQuestion = { role: "user", content: question + restrictionSuffix };
6321
6386
  const messages = [...hardenedHistory, userQuestion];
@@ -6385,19 +6450,7 @@ ${context}`;
6385
6450
  tokens,
6386
6451
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
6387
6452
  };
6388
- let uiTransformation;
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
- }
6453
+ const uiTransformation = yield new __await(uiTransformationPromise);
6401
6454
  yield {
6402
6455
  reply: "",
6403
6456
  sources,
@@ -6917,15 +6970,24 @@ function createStreamHandler(configOrPlugin) {
6917
6970
  });
6918
6971
  }
6919
6972
  const encoder = new TextEncoder();
6973
+ let isActive = true;
6920
6974
  const stream = new ReadableStream({
6921
6975
  async start(controller) {
6922
6976
  var _a;
6923
- const enqueue = (text) => controller.enqueue(encoder.encode(text));
6977
+ const enqueue = (text) => {
6978
+ if (!isActive) return;
6979
+ try {
6980
+ controller.enqueue(encoder.encode(text));
6981
+ } catch (err) {
6982
+ console.warn("[createStreamHandler] Failed to enqueue (stream already closed):", err);
6983
+ }
6984
+ };
6924
6985
  try {
6925
6986
  const pipelineStream = plugin.chatStream(message, history, namespace);
6926
6987
  try {
6927
6988
  for (var iter = __forAwait(pipelineStream), more, temp, error; more = !(temp = await iter.next()).done; more = false) {
6928
6989
  const chunk = temp.value;
6990
+ if (!isActive) break;
6929
6991
  if (typeof chunk === "string") {
6930
6992
  enqueue(sseTextFrame(chunk));
6931
6993
  } else {
@@ -6963,12 +7025,27 @@ function createStreamHandler(configOrPlugin) {
6963
7025
  }
6964
7026
  }
6965
7027
  } catch (streamError) {
6966
- const errorMessage = streamError instanceof Error ? streamError.message : String(streamError);
6967
- console.error("[createStreamHandler] Stream error:", streamError);
6968
- enqueue(sseErrorFrame(errorMessage));
7028
+ if (isActive) {
7029
+ const errorMessage = streamError instanceof Error ? streamError.message : String(streamError);
7030
+ console.error("[createStreamHandler] Stream error:", streamError);
7031
+ try {
7032
+ enqueue(sseErrorFrame(errorMessage));
7033
+ } catch (e) {
7034
+ }
7035
+ }
6969
7036
  } finally {
6970
- controller.close();
7037
+ if (isActive) {
7038
+ isActive = false;
7039
+ try {
7040
+ controller.close();
7041
+ } catch (e) {
7042
+ }
7043
+ }
6971
7044
  }
7045
+ },
7046
+ cancel(reason) {
7047
+ isActive = false;
7048
+ console.log("[createStreamHandler] Stream connection closed by client:", reason);
6972
7049
  }
6973
7050
  });
6974
7051
  return new Response(stream, { headers: SSE_HEADERS });
@@ -7029,6 +7106,7 @@ function createUploadHandler(configOrPlugin) {
7029
7106
  if (parsed.data && parsed.data.length > 0) {
7030
7107
  let i = 0;
7031
7108
  let lastRowData = null;
7109
+ const csvCols = Object.keys(parsed.data[0]);
7032
7110
  for (const row of parsed.data) {
7033
7111
  i++;
7034
7112
  const rowData = row;
@@ -7050,12 +7128,14 @@ function createUploadHandler(configOrPlugin) {
7050
7128
  documents.push({
7051
7129
  docId: `${file.name}-row-${i}`,
7052
7130
  content: contentParts.join(", "),
7053
- metadata: __spreadValues(__spreadValues({
7131
+ metadata: __spreadValues(__spreadProps(__spreadValues({
7054
7132
  fileName: file.name,
7055
7133
  fileSize: file.size,
7056
7134
  fileType: file.type,
7057
7135
  uploadedAt: (/* @__PURE__ */ new Date()).toISOString()
7058
- }, dimension ? { dimension } : {}), rowData)
7136
+ }, dimension ? { dimension } : {}), {
7137
+ csvHeaders: csvCols
7138
+ }), rowData)
7059
7139
  });
7060
7140
  }
7061
7141
  }
@@ -1,4 +1,4 @@
1
- import { k as RagConfig, I as ILLMProvider, C as ChatMessage, d as ChatResponse, g as IngestDocument } from './ILLMProvider-BQyKZLnd.mjs';
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-BQyKZLnd.js';
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-BQyKZLnd.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-BQyKZLnd.mjs';
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-BQyKZLnd.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-BQyKZLnd.js';
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';