@retrivora-ai/rag-engine 1.7.9 → 1.8.1

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.
Files changed (47) hide show
  1. package/dist/DocumentChunker-Dh9TvmGG.d.mts +45 -0
  2. package/dist/DocumentChunker-Dh9TvmGG.d.ts +45 -0
  3. package/dist/{index-wCRqMtdX.d.mts → ILLMProvider-BfRgI1Xh.d.mts} +59 -1
  4. package/dist/{index-wCRqMtdX.d.ts → ILLMProvider-BfRgI1Xh.d.ts} +59 -1
  5. package/dist/MultiTablePostgresProvider-YY7LPNJK.mjs +8 -0
  6. package/dist/{chunk-UHGYLTTY.mjs → chunk-BFYLQYQU.mjs} +846 -458
  7. package/dist/chunk-R3RGUMHE.mjs +218 -0
  8. package/dist/handlers/index.d.mts +2 -2
  9. package/dist/handlers/index.d.ts +2 -2
  10. package/dist/handlers/index.js +1033 -622
  11. package/dist/handlers/index.mjs +1 -1
  12. package/dist/{index-BDqz2_Yu.d.ts → index-1Z4GuYBi.d.ts} +7 -1
  13. package/dist/{index-DhsG2o5q.d.mts → index-BV0z5mb6.d.mts} +7 -1
  14. package/dist/index.d.mts +3 -3
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +507 -352
  17. package/dist/index.mjs +427 -253
  18. package/dist/server.d.mts +35 -5
  19. package/dist/server.d.ts +35 -5
  20. package/dist/server.js +1183 -795
  21. package/dist/server.mjs +163 -176
  22. package/package.json +4 -2
  23. package/src/app/page.tsx +1 -2
  24. package/src/components/DynamicChart.tsx +10 -35
  25. package/src/components/MessageBubble.tsx +223 -74
  26. package/src/components/ProductCard.tsx +2 -2
  27. package/src/components/VisualizationRenderer.tsx +347 -247
  28. package/src/config/RagConfig.ts +5 -0
  29. package/src/config/serverConfig.ts +3 -1
  30. package/src/core/Pipeline.ts +70 -209
  31. package/src/core/ProviderRegistry.ts +2 -2
  32. package/src/core/VectorPlugin.ts +9 -0
  33. package/src/handlers/index.ts +23 -7
  34. package/src/hooks/useRagChat.ts +2 -2
  35. package/src/llm/LLMFactory.ts +54 -2
  36. package/src/llm/providers/AnthropicProvider.ts +12 -8
  37. package/src/llm/providers/GeminiProvider.ts +188 -143
  38. package/src/llm/providers/OllamaProvider.ts +7 -3
  39. package/src/llm/providers/OpenAIProvider.ts +12 -8
  40. package/src/types/chat.ts +6 -0
  41. package/src/types/index.ts +81 -0
  42. package/src/utils/SchemaMapper.ts +129 -0
  43. package/src/utils/UITransformer.ts +524 -194
  44. package/dist/DocumentChunker-Bmscbh-X.d.ts +0 -93
  45. package/dist/DocumentChunker-DCuxrOdM.d.mts +0 -93
  46. package/dist/PostgreSQLProvider-BMOETDZA.mjs +0 -8
  47. package/dist/chunk-FLOSGE6A.mjs +0 -202
@@ -1,93 +0,0 @@
1
- import { C as ChatMessage, c as ChatOptions } from './index-wCRqMtdX.js';
2
-
3
- /**
4
- * Generic LLM Provider interface.
5
- * Covers both chat completion and embedding generation so a single
6
- * provider can handle both responsibilities when appropriate.
7
- */
8
-
9
- interface EmbedOptions {
10
- /** Override model for this specific embed call */
11
- model?: string;
12
- /** Specify the task type for models that require prefixes (e.g. nomic-embed-text) */
13
- taskType?: 'query' | 'document';
14
- }
15
- interface ILLMProvider {
16
- /**
17
- * Send a chat completion request.
18
- * @param messages – the full conversation history
19
- * @param context – retrieved RAG context to inject
20
- * @param options – optional per-call overrides
21
- * @returns – the assistant's reply text
22
- */
23
- chat(messages: ChatMessage[], context: string, options?: ChatOptions): Promise<string>;
24
- /**
25
- * Send a streaming chat completion request.
26
- * @returns – an async iterable of text chunks
27
- */
28
- chatStream?(messages: ChatMessage[], context: string, options?: ChatOptions): AsyncIterable<string>;
29
- /**
30
- * Generate an embedding vector for the given text.
31
- * @param text – text to embed
32
- * @param options – optional overrides
33
- * @returns – float array (the embedding)
34
- */
35
- embed(text: string, options?: EmbedOptions): Promise<number[]>;
36
- /**
37
- * Generate embedding vectors for multiple texts in a single batch.
38
- * @param texts – array of texts to embed
39
- * @param options – optional overrides
40
- * @returns – array of float arrays
41
- */
42
- batchEmbed(texts: string[], options?: EmbedOptions): Promise<number[][]>;
43
- /**
44
- * Check if the provider endpoint is reachable.
45
- */
46
- ping(): Promise<boolean>;
47
- }
48
-
49
- /**
50
- * DocumentChunker — splits long text into overlapping chunks
51
- * suitable for vector embedding and retrieval.
52
- *
53
- * Strategy: sentence-aware sliding window
54
- * 1. Split on sentence boundaries
55
- * 2. Accumulate sentences into chunks up to `chunkSize` characters
56
- * 3. Carry over `chunkOverlap` characters from the previous chunk
57
- */
58
- interface Chunk {
59
- id: string;
60
- content: string;
61
- metadata?: Record<string, unknown>;
62
- }
63
- interface ChunkOptions {
64
- /** Target chunk size in characters (default 1000) */
65
- chunkSize?: number;
66
- /** Overlap between consecutive chunks in characters (default 200) */
67
- chunkOverlap?: number;
68
- /** Source document identifier used as ID prefix */
69
- docId?: string | number;
70
- /** Extra metadata to attach to every chunk */
71
- metadata?: Record<string, unknown>;
72
- /** Characters used to split text, in order of priority */
73
- separators?: string[];
74
- }
75
- declare class DocumentChunker {
76
- private readonly chunkSize;
77
- private readonly chunkOverlap;
78
- private readonly separators;
79
- constructor(chunkSize?: number, chunkOverlap?: number, separators?: string[]);
80
- /**
81
- * Split a single text string into overlapping chunks using a recursive strategy.
82
- * Preserves structural boundaries (Markdown headers) where possible.
83
- */
84
- chunk(text: string, options?: ChunkOptions): Chunk[];
85
- private recursiveSplit;
86
- chunkMany(documents: Array<{
87
- content: string;
88
- docId?: string | number;
89
- metadata?: Record<string, unknown>;
90
- }>): Chunk[];
91
- }
92
-
93
- export { type Chunk as C, DocumentChunker as D, type EmbedOptions as E, type ILLMProvider as I, type ChunkOptions as a };
@@ -1,93 +0,0 @@
1
- import { C as ChatMessage, c as ChatOptions } from './index-wCRqMtdX.mjs';
2
-
3
- /**
4
- * Generic LLM Provider interface.
5
- * Covers both chat completion and embedding generation so a single
6
- * provider can handle both responsibilities when appropriate.
7
- */
8
-
9
- interface EmbedOptions {
10
- /** Override model for this specific embed call */
11
- model?: string;
12
- /** Specify the task type for models that require prefixes (e.g. nomic-embed-text) */
13
- taskType?: 'query' | 'document';
14
- }
15
- interface ILLMProvider {
16
- /**
17
- * Send a chat completion request.
18
- * @param messages – the full conversation history
19
- * @param context – retrieved RAG context to inject
20
- * @param options – optional per-call overrides
21
- * @returns – the assistant's reply text
22
- */
23
- chat(messages: ChatMessage[], context: string, options?: ChatOptions): Promise<string>;
24
- /**
25
- * Send a streaming chat completion request.
26
- * @returns – an async iterable of text chunks
27
- */
28
- chatStream?(messages: ChatMessage[], context: string, options?: ChatOptions): AsyncIterable<string>;
29
- /**
30
- * Generate an embedding vector for the given text.
31
- * @param text – text to embed
32
- * @param options – optional overrides
33
- * @returns – float array (the embedding)
34
- */
35
- embed(text: string, options?: EmbedOptions): Promise<number[]>;
36
- /**
37
- * Generate embedding vectors for multiple texts in a single batch.
38
- * @param texts – array of texts to embed
39
- * @param options – optional overrides
40
- * @returns – array of float arrays
41
- */
42
- batchEmbed(texts: string[], options?: EmbedOptions): Promise<number[][]>;
43
- /**
44
- * Check if the provider endpoint is reachable.
45
- */
46
- ping(): Promise<boolean>;
47
- }
48
-
49
- /**
50
- * DocumentChunker — splits long text into overlapping chunks
51
- * suitable for vector embedding and retrieval.
52
- *
53
- * Strategy: sentence-aware sliding window
54
- * 1. Split on sentence boundaries
55
- * 2. Accumulate sentences into chunks up to `chunkSize` characters
56
- * 3. Carry over `chunkOverlap` characters from the previous chunk
57
- */
58
- interface Chunk {
59
- id: string;
60
- content: string;
61
- metadata?: Record<string, unknown>;
62
- }
63
- interface ChunkOptions {
64
- /** Target chunk size in characters (default 1000) */
65
- chunkSize?: number;
66
- /** Overlap between consecutive chunks in characters (default 200) */
67
- chunkOverlap?: number;
68
- /** Source document identifier used as ID prefix */
69
- docId?: string | number;
70
- /** Extra metadata to attach to every chunk */
71
- metadata?: Record<string, unknown>;
72
- /** Characters used to split text, in order of priority */
73
- separators?: string[];
74
- }
75
- declare class DocumentChunker {
76
- private readonly chunkSize;
77
- private readonly chunkOverlap;
78
- private readonly separators;
79
- constructor(chunkSize?: number, chunkOverlap?: number, separators?: string[]);
80
- /**
81
- * Split a single text string into overlapping chunks using a recursive strategy.
82
- * Preserves structural boundaries (Markdown headers) where possible.
83
- */
84
- chunk(text: string, options?: ChunkOptions): Chunk[];
85
- private recursiveSplit;
86
- chunkMany(documents: Array<{
87
- content: string;
88
- docId?: string | number;
89
- metadata?: Record<string, unknown>;
90
- }>): Chunk[];
91
- }
92
-
93
- export { type Chunk as C, DocumentChunker as D, type EmbedOptions as E, type ILLMProvider as I, type ChunkOptions as a };
@@ -1,8 +0,0 @@
1
- import {
2
- PostgreSQLProvider
3
- } from "./chunk-FLOSGE6A.mjs";
4
- import "./chunk-IMP6FUCY.mjs";
5
- import "./chunk-X4TOT24V.mjs";
6
- export {
7
- PostgreSQLProvider
8
- };
@@ -1,202 +0,0 @@
1
- import {
2
- BaseVectorProvider
3
- } from "./chunk-IMP6FUCY.mjs";
4
-
5
- // src/providers/vectordb/PostgreSQLProvider.ts
6
- import { Pool } from "pg";
7
- var PostgreSQLProvider = class extends BaseVectorProvider {
8
- constructor(config) {
9
- var _a;
10
- super(config);
11
- this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, "_");
12
- const opts = config.options;
13
- if (!opts.connectionString) throw new Error("[PostgreSQLProvider] options.connectionString is required");
14
- this.connectionString = opts.connectionString;
15
- this.dimensions = (_a = opts.dimensions) != null ? _a : 1536;
16
- }
17
- static getValidator() {
18
- return {
19
- validate(config) {
20
- const errors = [];
21
- const opts = config.options || {};
22
- if (!opts.connectionString) {
23
- errors.push({
24
- field: "vectorDb.options.connectionString",
25
- message: "PostgreSQL connection string is required",
26
- suggestion: "Set PGVECTOR_CONNECTION_STRING environment variable",
27
- severity: "error"
28
- });
29
- }
30
- if (opts.tables && typeof opts.tables !== "string" && !Array.isArray(opts.tables)) {
31
- errors.push({
32
- field: "vectorDb.options.tables",
33
- message: "PostgreSQL tables must be a string or a string array",
34
- severity: "error"
35
- });
36
- }
37
- return errors;
38
- }
39
- };
40
- }
41
- static getHealthChecker() {
42
- return {
43
- async check(config) {
44
- const opts = config.options || {};
45
- const timestamp = Date.now();
46
- try {
47
- const { Client } = await import("pg");
48
- const client = new Client({ connectionString: opts.connectionString });
49
- await client.connect();
50
- const result = await client.query(`
51
- SELECT EXISTS(SELECT 1 FROM pg_extension WHERE extname = 'vector');
52
- `);
53
- const hasVector = result.rows[0].exists;
54
- await client.end();
55
- return {
56
- healthy: true,
57
- provider: "postgresql",
58
- capabilities: { pgvectorInstalled: hasVector },
59
- timestamp
60
- };
61
- } catch (error) {
62
- return {
63
- healthy: false,
64
- provider: "postgresql",
65
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
66
- timestamp
67
- };
68
- }
69
- }
70
- };
71
- }
72
- async initialize() {
73
- this.pool = new Pool({ connectionString: this.connectionString });
74
- const client = await this.pool.connect();
75
- try {
76
- await client.query("CREATE EXTENSION IF NOT EXISTS vector");
77
- await client.query(`
78
- CREATE TABLE IF NOT EXISTS ${this.tableName} (
79
- id TEXT PRIMARY KEY,
80
- namespace TEXT NOT NULL DEFAULT '',
81
- content TEXT NOT NULL,
82
- metadata JSONB,
83
- embedding VECTOR(${this.dimensions})
84
- )
85
- `);
86
- await client.query(`
87
- CREATE INDEX IF NOT EXISTS ${this.tableName}_embedding_idx
88
- ON ${this.tableName}
89
- USING hnsw (embedding vector_cosine_ops)
90
- `);
91
- } finally {
92
- client.release();
93
- }
94
- }
95
- async upsert(doc, namespace = "") {
96
- var _a;
97
- const vectorLiteral = `[${doc.vector.join(",")}]`;
98
- await this.pool.query(
99
- `INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
100
- VALUES ($1, $2, $3, $4, $5::vector)
101
- ON CONFLICT (id) DO UPDATE
102
- SET namespace = EXCLUDED.namespace,
103
- content = EXCLUDED.content,
104
- metadata = EXCLUDED.metadata,
105
- embedding = EXCLUDED.embedding`,
106
- [doc.id, namespace, doc.content, JSON.stringify((_a = doc.metadata) != null ? _a : {}), vectorLiteral]
107
- );
108
- }
109
- async batchUpsert(docs, namespace = "") {
110
- if (docs.length === 0) return;
111
- const client = await this.pool.connect();
112
- try {
113
- await client.query("BEGIN");
114
- const BATCH_SIZE = 50;
115
- for (let i = 0; i < docs.length; i += BATCH_SIZE) {
116
- const batch = docs.slice(i, i + BATCH_SIZE);
117
- const values = [];
118
- const valuePlaceholders = batch.map((doc, idx) => {
119
- var _a;
120
- const offset = idx * 5;
121
- values.push(doc.id, namespace, doc.content, JSON.stringify((_a = doc.metadata) != null ? _a : {}), `[${doc.vector.join(",")}]`);
122
- return `($${offset + 1}, $${offset + 2}, $${offset + 3}, $${offset + 4}, $${offset + 5}::vector)`;
123
- }).join(", ");
124
- const query = `
125
- INSERT INTO ${this.tableName} (id, namespace, content, metadata, embedding)
126
- VALUES ${valuePlaceholders}
127
- ON CONFLICT (id) DO UPDATE
128
- SET namespace = EXCLUDED.namespace,
129
- content = EXCLUDED.content,
130
- metadata = EXCLUDED.metadata,
131
- embedding = EXCLUDED.embedding
132
- `;
133
- await client.query(query, values);
134
- }
135
- await client.query("COMMIT");
136
- } catch (error) {
137
- await client.query("ROLLBACK");
138
- throw error;
139
- } finally {
140
- client.release();
141
- }
142
- }
143
- async query(vector, topK, namespace, filter) {
144
- const vectorLiteral = `[${vector.join(",")}]`;
145
- let whereClause = namespace ? `WHERE namespace = $3` : "";
146
- const params = [vectorLiteral, topK];
147
- if (namespace) params.push(namespace);
148
- const publicFilter = this.sanitizeFilter(filter);
149
- if (Object.keys(publicFilter).length > 0) {
150
- const filterConditions = Object.entries(publicFilter).map(([key, val]) => {
151
- const paramIdx = params.length + 1;
152
- params.push(JSON.stringify(val));
153
- return `metadata->>'${key}' = $${paramIdx}`;
154
- }).join(" AND ");
155
- whereClause = whereClause ? `${whereClause} AND ${filterConditions}` : `WHERE ${filterConditions}`;
156
- }
157
- const client = await this.pool.connect();
158
- try {
159
- const efSearch = this.config.options.efSearch || Math.max(topK * 10, 40);
160
- await client.query(`SET LOCAL hnsw.ef_search = ${efSearch}`);
161
- const result = await client.query(
162
- `SELECT id, content, metadata, 1 - (embedding <=> $1::vector) AS score
163
- FROM ${this.tableName}
164
- ${whereClause}
165
- ORDER BY embedding <=> $1::vector
166
- LIMIT $2`,
167
- params
168
- );
169
- return result.rows.map((row) => ({
170
- id: String(row["id"]),
171
- score: parseFloat(String(row["score"])),
172
- content: String(row["content"]),
173
- metadata: row["metadata"]
174
- }));
175
- } finally {
176
- client.release();
177
- }
178
- }
179
- async delete(id, namespace) {
180
- const where = namespace ? "WHERE id = $1 AND namespace = $2" : "WHERE id = $1";
181
- const params = namespace ? [id, namespace] : [id];
182
- await this.pool.query(`DELETE FROM ${this.tableName} ${where}`, params);
183
- }
184
- async deleteNamespace(namespace) {
185
- await this.pool.query(`DELETE FROM ${this.tableName} WHERE namespace = $1`, [namespace]);
186
- }
187
- async ping() {
188
- try {
189
- await this.pool.query("SELECT 1");
190
- return true;
191
- } catch (e) {
192
- return false;
193
- }
194
- }
195
- async disconnect() {
196
- await this.pool.end();
197
- }
198
- };
199
-
200
- export {
201
- PostgreSQLProvider
202
- };