@retrivora-ai/rag-engine 1.8.9 → 1.9.0
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-CbUtvWAW.d.mts → ILLMProvider-BOJFz3Na.d.mts} +0 -2
- package/dist/{ILLMProvider-CbUtvWAW.d.ts → ILLMProvider-BOJFz3Na.d.ts} +0 -2
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +52 -100
- package/dist/handlers/index.mjs +52 -100
- package/dist/{index-DgzcnqZs.d.ts → index-BwpcaziY.d.ts} +1 -1
- package/dist/{index-c_y_5qdw.d.mts → index-D3V9Et2M.d.mts} +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/server.d.mts +3 -3
- package/dist/server.d.ts +3 -3
- package/dist/server.js +55 -108
- package/dist/server.mjs +55 -108
- package/package.json +1 -1
- package/src/config/RagConfig.ts +0 -2
- package/src/providers/vectordb/ChromaDBProvider.ts +0 -4
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +5 -18
- package/src/providers/vectordb/PostgreSQLProvider.ts +3 -14
- package/src/providers/vectordb/QdrantProvider.ts +1 -4
- package/src/utils/UITransformer.ts +51 -99
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-BOJFz3Na.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-BOJFz3Na.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-BOJFz3Na.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-BOJFz3Na.js';
|
|
5
5
|
export { C as Chunk, a as ChunkOptions } from './DocumentChunker-Dh9TvmGG.js';
|
|
6
6
|
|
|
7
7
|
type ChatViewportSize = 'compact' | 'medium' | 'large';
|
package/dist/server.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as VectorDBConfig, L as LLMConfig, e as EmbeddingConfig, k as RagConfig, I as ILLMProvider, g as IngestDocument, C as ChatMessage, d as ChatResponse, p as RetrievalResult, m as UpsertDocument, V as VectorMatch, G as GraphDBConfig, q as GraphNode, r as Edge, s as GraphSearchResult, o as VectorDBProvider, h as LLMProvider, f as EmbeddingProvider, j as RAGConfig, U as UIConfig, c as ChatOptions, E as EmbedOptions } from './ILLMProvider-
|
|
1
|
+
import { n as VectorDBConfig, L as LLMConfig, e as EmbeddingConfig, k as RagConfig, I as ILLMProvider, g as IngestDocument, C as ChatMessage, d as ChatResponse, p as RetrievalResult, m as UpsertDocument, V as VectorMatch, G as GraphDBConfig, q as GraphNode, r as Edge, s as GraphSearchResult, o as VectorDBProvider, h as LLMProvider, f as EmbeddingProvider, j as RAGConfig, U as UIConfig, c as ChatOptions, E as EmbedOptions } from './ILLMProvider-BOJFz3Na.mjs';
|
|
2
2
|
export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-Dh9TvmGG.mjs';
|
|
3
|
-
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-
|
|
4
|
-
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-
|
|
3
|
+
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-D3V9Et2M.mjs';
|
|
4
|
+
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-D3V9Et2M.mjs';
|
|
5
5
|
import 'next/server';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as VectorDBConfig, L as LLMConfig, e as EmbeddingConfig, k as RagConfig, I as ILLMProvider, g as IngestDocument, C as ChatMessage, d as ChatResponse, p as RetrievalResult, m as UpsertDocument, V as VectorMatch, G as GraphDBConfig, q as GraphNode, r as Edge, s as GraphSearchResult, o as VectorDBProvider, h as LLMProvider, f as EmbeddingProvider, j as RAGConfig, U as UIConfig, c as ChatOptions, E as EmbedOptions } from './ILLMProvider-
|
|
1
|
+
import { n as VectorDBConfig, L as LLMConfig, e as EmbeddingConfig, k as RagConfig, I as ILLMProvider, g as IngestDocument, C as ChatMessage, d as ChatResponse, p as RetrievalResult, m as UpsertDocument, V as VectorMatch, G as GraphDBConfig, q as GraphNode, r as Edge, s as GraphSearchResult, o as VectorDBProvider, h as LLMProvider, f as EmbeddingProvider, j as RAGConfig, U as UIConfig, c as ChatOptions, E as EmbedOptions } from './ILLMProvider-BOJFz3Na.js';
|
|
2
2
|
export { C as Chunk, a as ChunkOptions, D as DocumentChunker } from './DocumentChunker-Dh9TvmGG.js';
|
|
3
|
-
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-
|
|
4
|
-
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-
|
|
3
|
+
import { H as HealthCheckResult, I as IProviderValidator, a as IProviderHealthChecker } from './index-BwpcaziY.js';
|
|
4
|
+
export { C as ConfigValidator, V as ValidationError, b as VectorPlugin, c as createChatHandler, d as createHealthHandler, e as createIngestHandler, f as createStreamHandler, g as createUploadHandler, s as sseErrorFrame, h as sseFrame, i as sseMetaFrame, j as sseTextFrame } from './index-BwpcaziY.js';
|
|
5
5
|
import 'next/server';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/server.js
CHANGED
|
@@ -374,12 +374,10 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
374
374
|
embedding VECTOR(${this.dimensions})
|
|
375
375
|
)
|
|
376
376
|
`);
|
|
377
|
-
const metric = this.config.distanceMetric || "cosine";
|
|
378
|
-
const indexOps = metric === "euclidean" ? "vector_l2_ops" : metric === "dotproduct" ? "vector_ip_ops" : "vector_cosine_ops";
|
|
379
377
|
await client.query(`
|
|
380
378
|
CREATE INDEX IF NOT EXISTS ${this.uploadTable}_embedding_idx
|
|
381
379
|
ON ${this.uploadTable}
|
|
382
|
-
USING hnsw (embedding
|
|
380
|
+
USING hnsw (embedding vector_cosine_ops)
|
|
383
381
|
`);
|
|
384
382
|
const res = await client.query(`
|
|
385
383
|
SELECT table_name
|
|
@@ -441,12 +439,10 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
441
439
|
)
|
|
442
440
|
`;
|
|
443
441
|
await client.query(createTableSql);
|
|
444
|
-
const metric = this.config.distanceMetric || "cosine";
|
|
445
|
-
const indexOps = metric === "euclidean" ? "vector_l2_ops" : metric === "dotproduct" ? "vector_ip_ops" : "vector_cosine_ops";
|
|
446
442
|
await client.query(`
|
|
447
443
|
CREATE INDEX IF NOT EXISTS "${tableName}_embedding_idx"
|
|
448
444
|
ON "${tableName}"
|
|
449
|
-
USING hnsw (embedding
|
|
445
|
+
USING hnsw (embedding vector_cosine_ops)
|
|
450
446
|
`);
|
|
451
447
|
if (!this.tables.includes(tableName)) {
|
|
452
448
|
this.tables.push(tableName);
|
|
@@ -528,8 +524,6 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
528
524
|
try {
|
|
529
525
|
let sqlQuery = "";
|
|
530
526
|
let params = [];
|
|
531
|
-
const metric = this.config.distanceMetric || "cosine";
|
|
532
|
-
const scoreExpr = metric === "euclidean" ? `1 / (1 + (embedding <-> $1::vector))` : metric === "dotproduct" ? `(embedding <#> $1::vector) * -1` : `1 - (embedding <=> $1::vector)`;
|
|
533
527
|
if (queryText) {
|
|
534
528
|
const hasEntityHints = entityHints.length > 0;
|
|
535
529
|
const exactNameScoreExpr = hasEntityHints ? `+ (
|
|
@@ -542,9 +536,9 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
542
536
|
) * 3.0` : "";
|
|
543
537
|
sqlQuery = `
|
|
544
538
|
SELECT *,
|
|
545
|
-
($
|
|
539
|
+
(1 - (embedding <=> $1::vector)) AS vector_score,
|
|
546
540
|
COALESCE(ts_rank(to_tsvector('english', (to_jsonb(t) - 'embedding')::text), to_tsquery('english', $2)), 0) AS keyword_score,
|
|
547
|
-
(($
|
|
541
|
+
((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
|
|
548
542
|
FROM "${table}" t
|
|
549
543
|
ORDER BY hybrid_score DESC
|
|
550
544
|
LIMIT 50
|
|
@@ -553,7 +547,7 @@ var init_MultiTablePostgresProvider = __esm({
|
|
|
553
547
|
} else {
|
|
554
548
|
sqlQuery = `
|
|
555
549
|
SELECT *,
|
|
556
|
-
($
|
|
550
|
+
(1 - (embedding <=> $1::vector)) AS hybrid_score
|
|
557
551
|
FROM "${table}" t
|
|
558
552
|
ORDER BY hybrid_score DESC
|
|
559
553
|
LIMIT 50
|
|
@@ -1027,13 +1021,11 @@ var init_QdrantProvider = __esm({
|
|
|
1027
1021
|
if (import_axios4.default.isAxiosError(err) && ((_a = err.response) == null ? void 0 : _a.status) === 404) {
|
|
1028
1022
|
const opts = this.config.options;
|
|
1029
1023
|
const dimensionsForCreate = opts.dimensions || 1536;
|
|
1030
|
-
const metric = this.config.distanceMetric || "cosine";
|
|
1031
|
-
const distance = metric === "euclidean" ? "Euclid" : metric === "dotproduct" ? "Dot" : "Cosine";
|
|
1032
1024
|
console.log(`[QdrantProvider] \u23F3 Creating collection "${this.indexName}" (dimensions: ${dimensionsForCreate})...`);
|
|
1033
1025
|
await this.http.put(`/collections/${this.indexName}`, {
|
|
1034
1026
|
vectors: {
|
|
1035
1027
|
size: dimensionsForCreate,
|
|
1036
|
-
distance
|
|
1028
|
+
distance: "Cosine"
|
|
1037
1029
|
}
|
|
1038
1030
|
});
|
|
1039
1031
|
console.log(`[QdrantProvider] \u2705 Created collection "${this.indexName}"`);
|
|
@@ -1211,12 +1203,9 @@ var init_ChromaDBProvider = __esm({
|
|
|
1211
1203
|
console.log(`[ChromaDBProvider] \u2705 Collection "${this.indexName}" found (id: ${this.collectionId})`);
|
|
1212
1204
|
} catch (err) {
|
|
1213
1205
|
if (import_axios5.default.isAxiosError(err) && ((_a = err.response) == null ? void 0 : _a.status) === 404) {
|
|
1214
|
-
const metric = this.config.distanceMetric || "cosine";
|
|
1215
|
-
const space = metric === "euclidean" ? "l2" : metric === "dotproduct" ? "ip" : "cosine";
|
|
1216
1206
|
console.log(`[ChromaDBProvider] \u23F3 Collection "${this.indexName}" not found. Creating...`);
|
|
1217
1207
|
const { data } = await this.http.post("/api/v1/collections", {
|
|
1218
|
-
name: this.indexName
|
|
1219
|
-
metadata: { "hnsw:space": space }
|
|
1208
|
+
name: this.indexName
|
|
1220
1209
|
});
|
|
1221
1210
|
this.collectionId = data.id;
|
|
1222
1211
|
console.log(`[ChromaDBProvider] \u2705 Created collection "${this.indexName}" (id: ${this.collectionId})`);
|
|
@@ -4253,20 +4242,18 @@ var UITransformer = class {
|
|
|
4253
4242
|
}
|
|
4254
4243
|
const isStockRequest = this.isStockQuery(userQuery);
|
|
4255
4244
|
const filteredData = isStockRequest ? retrievedData.filter((item) => this.determineStockStatus(item)) : retrievedData;
|
|
4256
|
-
const
|
|
4257
|
-
const categories = this.detectCategories(filteredData, groupByField);
|
|
4245
|
+
const categories = this.detectCategories(filteredData);
|
|
4258
4246
|
const hasProducts = filteredData.some((item) => this.isProductData(item));
|
|
4259
4247
|
const isTimeSeries = filteredData.some((item) => this.isTimeSeriesData(item));
|
|
4260
4248
|
const isTrendQuery = this.isTrendQuery(userQuery);
|
|
4261
4249
|
if (isTrendQuery && isTimeSeries) {
|
|
4262
4250
|
return this.transformToLineChart(filteredData);
|
|
4263
4251
|
}
|
|
4264
|
-
|
|
4265
|
-
if (hasProducts && !explicitChartRequest && !this.shouldShowCategoryChart(userQuery)) {
|
|
4252
|
+
if (hasProducts && !this.shouldShowCategoryChart(userQuery, categories)) {
|
|
4266
4253
|
return this.transformToProductCarousel(filteredData, config, trainedSchema);
|
|
4267
4254
|
}
|
|
4268
|
-
if (
|
|
4269
|
-
return this.transformToPieChart(filteredData
|
|
4255
|
+
if (categories.length > 1 && this.shouldShowCategoryChart(userQuery, categories)) {
|
|
4256
|
+
return this.transformToPieChart(filteredData);
|
|
4270
4257
|
}
|
|
4271
4258
|
if (hasProducts) {
|
|
4272
4259
|
return this.transformToProductCarousel(filteredData, config, trainedSchema);
|
|
@@ -4291,12 +4278,11 @@ var UITransformer = class {
|
|
|
4291
4278
|
/**
|
|
4292
4279
|
* Transform data to pie chart format
|
|
4293
4280
|
*/
|
|
4294
|
-
static transformToPieChart(data
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
const categoryData = this.aggregateByCategory(data, categories, groupByField);
|
|
4281
|
+
static transformToPieChart(data) {
|
|
4282
|
+
const categories = this.detectCategories(data);
|
|
4283
|
+
const categoryData = this.aggregateByCategory(data, categories);
|
|
4298
4284
|
const pieData = Object.entries(categoryData).map(([label, count]) => {
|
|
4299
|
-
const { inStockCount, outOfStockCount } = this.calculateStockCounts(label, data
|
|
4285
|
+
const { inStockCount, outOfStockCount } = this.calculateStockCounts(label, data);
|
|
4300
4286
|
return {
|
|
4301
4287
|
label,
|
|
4302
4288
|
value: count,
|
|
@@ -4306,7 +4292,7 @@ var UITransformer = class {
|
|
|
4306
4292
|
});
|
|
4307
4293
|
return {
|
|
4308
4294
|
type: "pie_chart",
|
|
4309
|
-
title:
|
|
4295
|
+
title: "Distribution by Category",
|
|
4310
4296
|
description: `Showing breakdown across ${categories.length} categories`,
|
|
4311
4297
|
data: pieData
|
|
4312
4298
|
};
|
|
@@ -4529,11 +4515,10 @@ var UITransformer = class {
|
|
|
4529
4515
|
});
|
|
4530
4516
|
return hasTimeKeyword || hasValidDateValue;
|
|
4531
4517
|
}
|
|
4532
|
-
static
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
static shouldShowCategoryChart(query) {
|
|
4518
|
+
static shouldShowCategoryChart(query, categories) {
|
|
4519
|
+
if (categories.length < 2) {
|
|
4520
|
+
return false;
|
|
4521
|
+
}
|
|
4537
4522
|
const normalized = query.toLowerCase();
|
|
4538
4523
|
const chartKeywords = [
|
|
4539
4524
|
"distribution",
|
|
@@ -4546,11 +4531,7 @@ var UITransformer = class {
|
|
|
4546
4531
|
"segmentation",
|
|
4547
4532
|
"split",
|
|
4548
4533
|
"category breakdown",
|
|
4549
|
-
"category distribution"
|
|
4550
|
-
"pie chart",
|
|
4551
|
-
"piechart",
|
|
4552
|
-
"bar chart",
|
|
4553
|
-
"barchart"
|
|
4534
|
+
"category distribution"
|
|
4554
4535
|
];
|
|
4555
4536
|
return chartKeywords.some((keyword) => normalized.includes(keyword));
|
|
4556
4537
|
}
|
|
@@ -4626,67 +4607,44 @@ var UITransformer = class {
|
|
|
4626
4607
|
return null;
|
|
4627
4608
|
}
|
|
4628
4609
|
/**
|
|
4629
|
-
* Helper:
|
|
4630
|
-
*/
|
|
4631
|
-
static determineGroupByField(query, data) {
|
|
4632
|
-
const normalized = query.toLowerCase();
|
|
4633
|
-
const match = normalized.match(/(?:by|across|per|based on)\s+([a-zA-Z]+)/i);
|
|
4634
|
-
let targetField = "category";
|
|
4635
|
-
if (match && match[1]) {
|
|
4636
|
-
let field = match[1].toLowerCase();
|
|
4637
|
-
if (field.endsWith("ies")) field = field.replace(/ies$/, "y");
|
|
4638
|
-
else if (field.endsWith("s") && field !== "status") field = field.slice(0, -1);
|
|
4639
|
-
const stopWords = ["the", "all", "different", "various", "some", "these", "those"];
|
|
4640
|
-
if (!stopWords.includes(field)) {
|
|
4641
|
-
targetField = field;
|
|
4642
|
-
}
|
|
4643
|
-
}
|
|
4644
|
-
const hasTargetField = data.some((d) => d.metadata && d.metadata[targetField] !== void 0);
|
|
4645
|
-
if (!hasTargetField && targetField === "category") {
|
|
4646
|
-
if (data.some((d) => d.metadata && d.metadata["type"] !== void 0)) return "type";
|
|
4647
|
-
if (data.some((d) => d.metadata && d.metadata["brand"] !== void 0)) return "brand";
|
|
4648
|
-
}
|
|
4649
|
-
return targetField;
|
|
4650
|
-
}
|
|
4651
|
-
/**
|
|
4652
|
-
* Helper: Detect grouping values dynamically
|
|
4610
|
+
* Helper: Detect categories in data
|
|
4653
4611
|
*/
|
|
4654
|
-
static detectCategories(data
|
|
4612
|
+
static detectCategories(data) {
|
|
4655
4613
|
const categories = /* @__PURE__ */ new Set();
|
|
4656
4614
|
data.forEach((item) => {
|
|
4657
4615
|
const meta = item.metadata || {};
|
|
4658
|
-
if (meta
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4616
|
+
if (meta.category) {
|
|
4617
|
+
categories.add(String(meta.category));
|
|
4618
|
+
}
|
|
4619
|
+
if (meta.type) {
|
|
4620
|
+
categories.add(String(meta.type));
|
|
4621
|
+
}
|
|
4622
|
+
if (meta.tag) {
|
|
4623
|
+
const tags = Array.isArray(meta.tag) ? meta.tag : [meta.tag];
|
|
4624
|
+
tags.forEach((t) => categories.add(String(t)));
|
|
4625
|
+
}
|
|
4626
|
+
const contentCategories = Array.from(new Set(
|
|
4627
|
+
Array.from(item.content.matchAll(/^\s*([^:\n]+):\s*(?:•|\*|-)*/gm)).map((match) => match[1].trim()).filter(Boolean)
|
|
4628
|
+
));
|
|
4629
|
+
contentCategories.forEach((category) => categories.add(category));
|
|
4630
|
+
const categoryMatch = item.content.match(/(?:Category|Type|Class):\s*([^\n]+)/i);
|
|
4631
|
+
if (categoryMatch) {
|
|
4632
|
+
categories.add(categoryMatch[1].trim());
|
|
4670
4633
|
}
|
|
4671
4634
|
});
|
|
4672
4635
|
return Array.from(categories);
|
|
4673
4636
|
}
|
|
4674
4637
|
/**
|
|
4675
|
-
* Helper: Aggregate data
|
|
4638
|
+
* Helper: Aggregate data by category
|
|
4676
4639
|
*/
|
|
4677
|
-
static aggregateByCategory(data, categories
|
|
4640
|
+
static aggregateByCategory(data, categories) {
|
|
4678
4641
|
const result = {};
|
|
4679
4642
|
categories.forEach((cat) => {
|
|
4680
4643
|
result[cat] = 0;
|
|
4681
4644
|
});
|
|
4682
4645
|
data.forEach((item) => {
|
|
4683
4646
|
const meta = item.metadata || {};
|
|
4684
|
-
|
|
4685
|
-
if (meta[groupByField] !== void 0) {
|
|
4686
|
-
itemCategory = String(meta[groupByField]);
|
|
4687
|
-
} else if (groupByField === "category" && meta.type) {
|
|
4688
|
-
itemCategory = String(meta.type);
|
|
4689
|
-
}
|
|
4647
|
+
const itemCategory = meta.category || meta.type || "Other";
|
|
4690
4648
|
if (Object.prototype.hasOwnProperty.call(result, itemCategory)) {
|
|
4691
4649
|
result[itemCategory]++;
|
|
4692
4650
|
} else {
|
|
@@ -4736,19 +4694,14 @@ var UITransformer = class {
|
|
|
4736
4694
|
});
|
|
4737
4695
|
}
|
|
4738
4696
|
/**
|
|
4739
|
-
* Helper: Calculate stock counts
|
|
4697
|
+
* Helper: Calculate stock counts by category
|
|
4740
4698
|
*/
|
|
4741
|
-
static calculateStockCounts(category, data
|
|
4699
|
+
static calculateStockCounts(category, data) {
|
|
4742
4700
|
let inStock = 0;
|
|
4743
4701
|
let outOfStock = 0;
|
|
4744
4702
|
data.forEach((d) => {
|
|
4745
4703
|
const meta = d.metadata || {};
|
|
4746
|
-
|
|
4747
|
-
if (meta[groupByField] !== void 0) {
|
|
4748
|
-
itemCategory = String(meta[groupByField]);
|
|
4749
|
-
} else if (groupByField === "category" && meta.type) {
|
|
4750
|
-
itemCategory = String(meta.type);
|
|
4751
|
-
}
|
|
4704
|
+
const itemCategory = meta.category || meta.type || "Other";
|
|
4752
4705
|
if (itemCategory === category) {
|
|
4753
4706
|
if (this.determineStockStatus(d)) {
|
|
4754
4707
|
inStock++;
|
|
@@ -4873,13 +4826,12 @@ DATA SHAPE per type:
|
|
|
4873
4826
|
- text: { "content": "<prose answer>" }
|
|
4874
4827
|
|
|
4875
4828
|
DECISION RULES (follow strictly):
|
|
4876
|
-
1.
|
|
4877
|
-
2.
|
|
4878
|
-
3.
|
|
4879
|
-
4.
|
|
4880
|
-
5.
|
|
4881
|
-
6.
|
|
4882
|
-
7. text \u2192 conversational or free-form answers where no chart adds value
|
|
4829
|
+
1. bar_chart \u2192 comparing quantities across categories (e.g. sales by region, price by product). Use this when there is only ONE value per category.
|
|
4830
|
+
2. line_chart \u2192 trends or changes over time (dates, months, years, sequential events)
|
|
4831
|
+
3. pie_chart \u2192 proportional breakdown or percentage distribution
|
|
4832
|
+
4. radar_chart \u2192 comparing 2 or more products across MULTIPLE attributes (e.g. comparing features, ratings, or characteristics of 2 specific products). If the user asks to "compare" products and the data contains multiple dimensions or ratings for them, you MUST use this.
|
|
4833
|
+
5. table \u2192 multi-field structured records where each item has \u2265 3 attributes
|
|
4834
|
+
6. text \u2192 conversational or free-form answers where no chart adds value
|
|
4883
4835
|
|
|
4884
4836
|
IMPORTANT:
|
|
4885
4837
|
- Aggregate numeric values from the raw data \u2014 do not pass raw object arrays as data.
|
|
@@ -6037,12 +5989,10 @@ var PostgreSQLProvider = class extends BaseVectorProvider {
|
|
|
6037
5989
|
embedding VECTOR(${this.dimensions})
|
|
6038
5990
|
)
|
|
6039
5991
|
`);
|
|
6040
|
-
const metric = this.config.distanceMetric || "cosine";
|
|
6041
|
-
const indexOps = metric === "euclidean" ? "vector_l2_ops" : metric === "dotproduct" ? "vector_ip_ops" : "vector_cosine_ops";
|
|
6042
5992
|
await client.query(`
|
|
6043
5993
|
CREATE INDEX IF NOT EXISTS ${this.tableName}_embedding_idx
|
|
6044
5994
|
ON ${this.tableName}
|
|
6045
|
-
USING hnsw (embedding
|
|
5995
|
+
USING hnsw (embedding vector_cosine_ops)
|
|
6046
5996
|
`);
|
|
6047
5997
|
} finally {
|
|
6048
5998
|
client.release();
|
|
@@ -6114,14 +6064,11 @@ var PostgreSQLProvider = class extends BaseVectorProvider {
|
|
|
6114
6064
|
try {
|
|
6115
6065
|
const efSearch = this.config.options.efSearch || Math.max(topK * 10, 40);
|
|
6116
6066
|
await client.query(`SET LOCAL hnsw.ef_search = ${efSearch}`);
|
|
6117
|
-
const metric = this.config.distanceMetric || "cosine";
|
|
6118
|
-
const queryOp = metric === "euclidean" ? "<->" : metric === "dotproduct" ? "<#>" : "<=>";
|
|
6119
|
-
const scoreExpr = metric === "euclidean" ? `1 / (1 + (embedding <-> $1::vector))` : metric === "dotproduct" ? `(embedding <#> $1::vector) * -1` : `1 - (embedding <=> $1::vector)`;
|
|
6120
6067
|
const result = await client.query(
|
|
6121
|
-
`SELECT id, content, metadata, $
|
|
6068
|
+
`SELECT id, content, metadata, 1 - (embedding <=> $1::vector) AS score
|
|
6122
6069
|
FROM ${this.tableName}
|
|
6123
6070
|
${whereClause}
|
|
6124
|
-
ORDER BY embedding
|
|
6071
|
+
ORDER BY embedding <=> $1::vector
|
|
6125
6072
|
LIMIT $2`,
|
|
6126
6073
|
params
|
|
6127
6074
|
);
|