@retrivora-ai/rag-engine 1.8.1 → 1.8.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.
- package/dist/{ILLMProvider-BfRgI1Xh.d.mts → ILLMProvider-BOJFz3Na.d.mts} +47 -1
- package/dist/{ILLMProvider-BfRgI1Xh.d.ts → ILLMProvider-BOJFz3Na.d.ts} +47 -1
- package/dist/{MultiTablePostgresProvider-YY7LPNJK.mjs → MultiTablePostgresProvider-ZLGSKTJR.mjs} +1 -1
- package/dist/chunk-ICKRMZQK.mjs +76 -0
- package/dist/{chunk-BFYLQYQU.mjs → chunk-LZVVLSDN.mjs} +192 -100
- package/dist/{chunk-R3RGUMHE.mjs → chunk-OZFBG4BA.mjs} +121 -48
- package/dist/handlers/index.d.mts +2 -2
- package/dist/handlers/index.d.ts +2 -2
- package/dist/handlers/index.js +368 -147
- package/dist/handlers/index.mjs +4 -1
- package/dist/{index-BV0z5mb6.d.mts → index-BwpcaziY.d.ts} +4 -2
- package/dist/{index-1Z4GuYBi.d.ts → index-D3V9Et2M.d.mts} +4 -2
- package/dist/index.d.mts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +1143 -790
- package/dist/index.mjs +1065 -770
- package/dist/server.d.mts +15 -25
- package/dist/server.d.ts +15 -25
- package/dist/server.js +366 -147
- package/dist/server.mjs +3 -2
- package/package.json +4 -2
- package/src/app/api/upload/route.ts +4 -0
- package/src/app/constants.tsx +2 -2
- package/src/app/page.tsx +12 -321
- package/src/components/AmbientBackground.tsx +29 -0
- package/src/components/ArchitectureCard.tsx +17 -0
- package/src/components/ArchitectureCardsSection.tsx +15 -0
- package/src/components/ChatWindow.tsx +32 -0
- package/src/components/CodeViewer.tsx +51 -0
- package/src/components/ConfigProvider.tsx +1 -0
- package/src/components/DocViewer.tsx +37 -0
- package/src/components/DocumentUpload.tsx +44 -1
- package/src/components/Documentation.tsx +58 -0
- package/src/components/DynamicChart.tsx +27 -2
- package/src/components/Hero.tsx +59 -0
- package/src/components/HourglassLoader.tsx +87 -0
- package/src/components/Lifecycle.tsx +37 -0
- package/src/components/MarkdownComponents.tsx +140 -0
- package/src/components/MessageBubble.tsx +88 -1010
- package/src/components/Navbar.tsx +55 -0
- package/src/components/ObservabilityPanel.tsx +374 -0
- package/src/components/ProductCard.tsx +3 -1
- package/src/components/UIDispatcher.tsx +344 -0
- package/src/components/VisualizationRenderer.tsx +48 -26
- package/src/core/Pipeline.ts +186 -76
- package/src/handlers/index.ts +72 -12
- package/src/hooks/useRagChat.ts +19 -9
- package/src/index.ts +9 -1
- package/src/providers/vectordb/MultiTablePostgresProvider.ts +150 -64
- package/src/types/chat.ts +2 -0
- package/src/types/index.ts +52 -0
- package/src/types/props.ts +9 -1
- package/src/utils/ProductExtractor.ts +347 -0
- package/src/utils/UITransformer.ts +4 -53
- package/src/utils/synonyms.ts +78 -0
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { Pool } from "pg";
|
|
12
12
|
var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
13
13
|
constructor(config) {
|
|
14
|
-
var _a, _b, _c
|
|
14
|
+
var _a, _b, _c;
|
|
15
15
|
super(config);
|
|
16
16
|
const opts = config.options || {};
|
|
17
17
|
if (!opts.connectionString) {
|
|
@@ -19,37 +19,37 @@ var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
|
19
19
|
}
|
|
20
20
|
this.connectionString = opts.connectionString;
|
|
21
21
|
this.dimensions = (_a = opts.dimensions) != null ? _a : 768;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (this.tables.length === 0) {
|
|
25
|
-
console.warn(
|
|
26
|
-
"[MultiTablePostgresProvider] No tables configured. Set VECTOR_DB_TABLES as a comma-separated list of table names or pass options.tables."
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
const rawSearchFields = (_e = (_d = opts.searchFields) != null ? _d : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _e : ["name", "product_name", "productname", "title"];
|
|
22
|
+
this.tables = [];
|
|
23
|
+
const rawSearchFields = (_c = (_b = opts.searchFields) != null ? _b : process.env.VECTOR_DB_SEARCH_FIELDS) != null ? _c : ["name", "product_name", "productname", "title"];
|
|
30
24
|
this.searchFields = typeof rawSearchFields === "string" ? rawSearchFields.split(",").map((f) => f.trim()).filter(Boolean) : rawSearchFields;
|
|
25
|
+
this.uploadTable = opts.uploadTable || "document_chunks";
|
|
31
26
|
}
|
|
32
27
|
async initialize() {
|
|
33
28
|
this.pool = new Pool({ connectionString: this.connectionString });
|
|
34
29
|
const client = await this.pool.connect();
|
|
35
30
|
try {
|
|
31
|
+
await client.query("CREATE EXTENSION IF NOT EXISTS vector");
|
|
32
|
+
await client.query(`
|
|
33
|
+
CREATE TABLE IF NOT EXISTS ${this.uploadTable} (
|
|
34
|
+
id TEXT PRIMARY KEY,
|
|
35
|
+
namespace TEXT NOT NULL DEFAULT '',
|
|
36
|
+
content TEXT NOT NULL,
|
|
37
|
+
metadata JSONB,
|
|
38
|
+
embedding VECTOR(${this.dimensions})
|
|
39
|
+
)
|
|
40
|
+
`);
|
|
41
|
+
await client.query(`
|
|
42
|
+
CREATE INDEX IF NOT EXISTS ${this.uploadTable}_embedding_idx
|
|
43
|
+
ON ${this.uploadTable}
|
|
44
|
+
USING hnsw (embedding vector_cosine_ops)
|
|
45
|
+
`);
|
|
36
46
|
const res = await client.query(`
|
|
37
47
|
SELECT table_name
|
|
38
48
|
FROM information_schema.columns
|
|
39
49
|
WHERE column_name = 'embedding'
|
|
40
50
|
AND table_schema = 'public'
|
|
41
51
|
`);
|
|
42
|
-
|
|
43
|
-
if (this.tables.length === 0) {
|
|
44
|
-
this.tables = discoveredTables;
|
|
45
|
-
} else {
|
|
46
|
-
const staticTables = [...this.tables];
|
|
47
|
-
this.tables = staticTables.filter((t) => discoveredTables.includes(t));
|
|
48
|
-
if (this.tables.length < staticTables.length) {
|
|
49
|
-
const missing = staticTables.filter((t) => !discoveredTables.includes(t));
|
|
50
|
-
console.warn(`[MultiTablePostgresProvider] Some configured tables were skipped (missing 'embedding' column): ${missing.join(", ")}`);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
52
|
+
this.tables = res.rows.map((r) => r.table_name);
|
|
53
53
|
if (this.tables.length === 0) {
|
|
54
54
|
console.warn('[MultiTablePostgresProvider] No tables with "embedding" columns found in the database.');
|
|
55
55
|
} else {
|
|
@@ -62,27 +62,106 @@ var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
|
-
* Upsert
|
|
66
|
-
* searching across pre-existing tables with varying schemas.
|
|
65
|
+
* Upsert a document by dynamically provisioning a table and columns.
|
|
67
66
|
*/
|
|
68
|
-
async upsert(
|
|
69
|
-
|
|
70
|
-
"[MultiTablePostgresProvider] upsert() is not supported in multi-table mode. Please use the standard PostgreSQLProvider for single-table managed indices."
|
|
71
|
-
);
|
|
67
|
+
async upsert(doc, namespace = "") {
|
|
68
|
+
await this.batchUpsert([doc], namespace);
|
|
72
69
|
}
|
|
73
70
|
/**
|
|
74
|
-
* Batch upsert
|
|
71
|
+
* Batch upsert documents by dynamically provisioning tables and columns based on CSV headers.
|
|
75
72
|
*/
|
|
76
|
-
async batchUpsert(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
async batchUpsert(docs, namespace = "") {
|
|
74
|
+
var _a;
|
|
75
|
+
if (docs.length === 0) return;
|
|
76
|
+
const docsByFile = {};
|
|
77
|
+
for (const doc of docs) {
|
|
78
|
+
const fileName = ((_a = doc.metadata) == null ? void 0 : _a.fileName) || this.uploadTable;
|
|
79
|
+
if (!docsByFile[fileName]) docsByFile[fileName] = [];
|
|
80
|
+
docsByFile[fileName].push(doc);
|
|
81
|
+
}
|
|
82
|
+
const client = await this.pool.connect();
|
|
83
|
+
try {
|
|
84
|
+
await client.query("BEGIN");
|
|
85
|
+
for (const [fileName, fileDocs] of Object.entries(docsByFile)) {
|
|
86
|
+
let tableName = fileName;
|
|
87
|
+
if (tableName.toLowerCase().endsWith(".csv")) {
|
|
88
|
+
tableName = tableName.slice(0, -4);
|
|
89
|
+
}
|
|
90
|
+
tableName = tableName.replace(/[^a-z0-9_]/gi, "_").toLowerCase() || this.uploadTable;
|
|
91
|
+
const firstMeta = fileDocs[0].metadata || {};
|
|
92
|
+
const systemKeys = ["fileName", "fileSize", "fileType", "uploadedAt", "dimension", "chunkIndex", "id", "namespace", "content", "metadata", "embedding"];
|
|
93
|
+
const csvHeaders = Object.keys(firstMeta).filter((k) => !systemKeys.includes(k) && !systemKeys.includes(k.toLowerCase()));
|
|
94
|
+
const columnDefs = csvHeaders.map((h) => `"${h}" TEXT`).join(",\n ");
|
|
95
|
+
const createTableSql = `
|
|
96
|
+
CREATE TABLE IF NOT EXISTS "${tableName}" (
|
|
97
|
+
id TEXT PRIMARY KEY,
|
|
98
|
+
${columnDefs ? columnDefs + "," : ""}
|
|
99
|
+
namespace TEXT NOT NULL DEFAULT '',
|
|
100
|
+
content TEXT NOT NULL,
|
|
101
|
+
metadata JSONB,
|
|
102
|
+
embedding VECTOR(${this.dimensions})
|
|
103
|
+
)
|
|
104
|
+
`;
|
|
105
|
+
await client.query(createTableSql);
|
|
106
|
+
await client.query(`
|
|
107
|
+
CREATE INDEX IF NOT EXISTS "${tableName}_embedding_idx"
|
|
108
|
+
ON "${tableName}"
|
|
109
|
+
USING hnsw (embedding vector_cosine_ops)
|
|
110
|
+
`);
|
|
111
|
+
if (!this.tables.includes(tableName)) {
|
|
112
|
+
this.tables.push(tableName);
|
|
113
|
+
}
|
|
114
|
+
const BATCH_SIZE = 50;
|
|
115
|
+
for (let i = 0; i < fileDocs.length; i += BATCH_SIZE) {
|
|
116
|
+
const batch = fileDocs.slice(i, i + BATCH_SIZE);
|
|
117
|
+
const values = [];
|
|
118
|
+
const headerColumns = csvHeaders.map((h) => `"${h}"`).join(", ");
|
|
119
|
+
const allColumns = `id, ${headerColumns ? headerColumns + ", " : ""}namespace, content, metadata, embedding`;
|
|
120
|
+
const valuePlaceholders = batch.map((doc, idx) => {
|
|
121
|
+
var _a2, _b;
|
|
122
|
+
const offset = idx * (5 + csvHeaders.length);
|
|
123
|
+
values.push(doc.id);
|
|
124
|
+
for (const h of csvHeaders) {
|
|
125
|
+
values.push(String(((_a2 = doc.metadata) == null ? void 0 : _a2[h]) || ""));
|
|
126
|
+
}
|
|
127
|
+
values.push(namespace, doc.content, JSON.stringify((_b = doc.metadata) != null ? _b : {}), `[${doc.vector.join(",")}]`);
|
|
128
|
+
const docPlaceholders = [];
|
|
129
|
+
for (let j = 1; j <= 5 + csvHeaders.length; j++) {
|
|
130
|
+
if (j === 5 + csvHeaders.length) {
|
|
131
|
+
docPlaceholders.push(`$${offset + j}::vector`);
|
|
132
|
+
} else {
|
|
133
|
+
docPlaceholders.push(`$${offset + j}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return `(${docPlaceholders.join(", ")})`;
|
|
137
|
+
}).join(", ");
|
|
138
|
+
const conflictUpdates = csvHeaders.map((h) => `"${h}" = EXCLUDED."${h}"`).join(",\n ");
|
|
139
|
+
const query = `
|
|
140
|
+
INSERT INTO "${tableName}" (${allColumns})
|
|
141
|
+
VALUES ${valuePlaceholders}
|
|
142
|
+
ON CONFLICT (id) DO UPDATE
|
|
143
|
+
SET ${conflictUpdates ? conflictUpdates + "," : ""}
|
|
144
|
+
namespace = EXCLUDED.namespace,
|
|
145
|
+
content = EXCLUDED.content,
|
|
146
|
+
metadata = EXCLUDED.metadata,
|
|
147
|
+
embedding = EXCLUDED.embedding
|
|
148
|
+
`;
|
|
149
|
+
await client.query(query, values);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
await client.query("COMMIT");
|
|
153
|
+
} catch (error) {
|
|
154
|
+
await client.query("ROLLBACK");
|
|
155
|
+
throw error;
|
|
156
|
+
} finally {
|
|
157
|
+
client.release();
|
|
158
|
+
}
|
|
80
159
|
}
|
|
81
160
|
/**
|
|
82
161
|
* Query all configured tables and merge results, sorted by cosine similarity score.
|
|
83
162
|
*/
|
|
84
163
|
async query(vector, topK, _namespace, _filter) {
|
|
85
|
-
var _a
|
|
164
|
+
var _a;
|
|
86
165
|
if (!this.pool) {
|
|
87
166
|
throw new Error("[MultiTablePostgresProvider] Provider not initialized. Call initialize() first.");
|
|
88
167
|
}
|
|
@@ -174,22 +253,16 @@ var MultiTablePostgresProvider = class extends BaseVectorProvider {
|
|
|
174
253
|
for (const tableResults of resultsArray) {
|
|
175
254
|
allResults.push(...tableResults);
|
|
176
255
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
const finalSorted = balancedResults.sort((a, b) => b.score - a.score);
|
|
189
|
-
if (finalSorted.length > 0) {
|
|
190
|
-
console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
|
|
191
|
-
console.log(`[MultiTablePostgresProvider] Final top match from "${(_c = (_b = finalSorted[0].metadata) == null ? void 0 : _b.source_table) != null ? _c : "unknown"}" with score ${finalSorted[0].score.toFixed(4)}`);
|
|
192
|
-
}
|
|
256
|
+
allResults.sort((a, b) => b.score - a.score);
|
|
257
|
+
if (allResults.length === 0) return [];
|
|
258
|
+
const bestMatchTable = (_a = allResults[0].metadata) == null ? void 0 : _a.source_table;
|
|
259
|
+
const finalSorted = allResults.filter((res) => {
|
|
260
|
+
var _a2;
|
|
261
|
+
return ((_a2 = res.metadata) == null ? void 0 : _a2.source_table) === bestMatchTable;
|
|
262
|
+
});
|
|
263
|
+
console.log(`[MultiTablePostgresProvider] --- Search Complete ---`);
|
|
264
|
+
console.log(`[MultiTablePostgresProvider] Final top match from "${bestMatchTable}" with score ${finalSorted[0].score.toFixed(4)}`);
|
|
265
|
+
console.log(`[MultiTablePostgresProvider] Restricting recommendations strictly to table: "${bestMatchTable}"`);
|
|
193
266
|
return finalSorted.slice(0, Math.max(topK, 15));
|
|
194
267
|
}
|
|
195
268
|
async delete(_id, _namespace) {
|
|
@@ -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, j as sseTextFrame,
|
|
1
|
+
import '../ILLMProvider-BOJFz3Na.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-D3V9Et2M.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, j as sseTextFrame,
|
|
1
|
+
import '../ILLMProvider-BOJFz3Na.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-BwpcaziY.js';
|
|
3
3
|
import 'next/server';
|