@retrivora-ai/rag-engine 0.1.3 → 0.1.5

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 (74) hide show
  1. package/dist/ChromaDBProvider-QNI7UCX4.mjs +8 -0
  2. package/dist/DocumentChunker-cfaMidtA.d.mts +93 -0
  3. package/dist/DocumentChunker-cfaMidtA.d.ts +93 -0
  4. package/dist/LLMFactory-JFOY2V4X.mjs +8 -0
  5. package/dist/MilvusProvider-OO6QGZDZ.mjs +8 -0
  6. package/dist/MongoDBProvider-WWVJG3WT.mjs +8 -0
  7. package/dist/PineconeProvider-NJ675H7U.mjs +8 -0
  8. package/dist/PostgreSQLProvider-ISNMD3BE.mjs +8 -0
  9. package/dist/QdrantProvider-LJWOIGES.mjs +8 -0
  10. package/dist/RagConfig-DG_0f8ka.d.mts +145 -0
  11. package/dist/RagConfig-DG_0f8ka.d.ts +145 -0
  12. package/dist/RedisProvider-ASONNYBI.mjs +8 -0
  13. package/dist/WeaviateProvider-PSDCUGC7.mjs +8 -0
  14. package/dist/chunk-6FODXNUF.mjs +91 -0
  15. package/dist/chunk-7NXI6ZWX.mjs +89 -0
  16. package/dist/chunk-AALIF3AL.mjs +91 -0
  17. package/dist/chunk-BP4U4TT5.mjs +548 -0
  18. package/dist/chunk-HUGLYKD6.mjs +84 -0
  19. package/dist/chunk-I4E63NIC.mjs +24 -0
  20. package/dist/chunk-JI6VD5TJ.mjs +387 -0
  21. package/dist/chunk-QEYVWVT5.mjs +102 -0
  22. package/dist/chunk-S5DRHETN.mjs +110 -0
  23. package/dist/{chunk-ZPXLQR5Q.mjs → chunk-UKDXCXW7.mjs} +5 -23
  24. package/dist/chunk-V75V7BT2.mjs +117 -0
  25. package/dist/chunk-VOIWNO5O.mjs +11 -0
  26. package/dist/chunk-VPNRDXIA.mjs +74 -0
  27. package/dist/handlers/index.d.mts +9 -33
  28. package/dist/handlers/index.d.ts +9 -33
  29. package/dist/handlers/index.js +1477 -962
  30. package/dist/handlers/index.mjs +4 -2
  31. package/dist/index.d.mts +4 -3
  32. package/dist/index.d.ts +4 -3
  33. package/dist/index.js +2 -2
  34. package/dist/index.mjs +4 -2
  35. package/dist/server.d.mts +220 -53
  36. package/dist/server.d.ts +220 -53
  37. package/dist/server.js +1531 -1099
  38. package/dist/server.mjs +55 -131
  39. package/package.json +19 -2
  40. package/src/app/page.tsx +1 -1
  41. package/src/components/MessageBubble.tsx +1 -1
  42. package/src/components/SourceCard.tsx +1 -1
  43. package/src/config/RagConfig.ts +1 -1
  44. package/src/config/serverConfig.ts +2 -2
  45. package/src/core/ConfigResolver.ts +69 -0
  46. package/src/core/Pipeline.ts +101 -0
  47. package/src/core/ProviderRegistry.ts +71 -0
  48. package/src/core/VectorPlugin.ts +52 -0
  49. package/src/handlers/index.ts +21 -100
  50. package/src/hooks/useRagChat.ts +1 -1
  51. package/src/index.ts +2 -6
  52. package/src/providers/vectordb/BaseVectorProvider.ts +61 -0
  53. package/src/providers/vectordb/ChromaDBProvider.ts +94 -0
  54. package/src/providers/vectordb/MilvusProvider.ts +100 -0
  55. package/src/providers/vectordb/MongoDBProvider.ts +118 -0
  56. package/src/{vectordb/adapters/PineconeAdapter.ts → providers/vectordb/PineconeProvider.ts} +21 -56
  57. package/src/{vectordb/adapters/PgVectorAdapter.ts → providers/vectordb/PostgreSQLProvider.ts} +23 -58
  58. package/src/providers/vectordb/QdrantProvider.ts +95 -0
  59. package/src/providers/vectordb/RedisProvider.ts +84 -0
  60. package/src/providers/vectordb/WeaviateProvider.ts +124 -0
  61. package/src/server.ts +16 -8
  62. package/src/test-refactor.ts +59 -0
  63. package/src/types/index.ts +24 -0
  64. package/src/utils/templateUtils.ts +6 -6
  65. package/dist/DocumentChunker-BUrIrcPk.d.mts +0 -43
  66. package/dist/DocumentChunker-BUrIrcPk.d.ts +0 -43
  67. package/dist/RAGPipeline-BmkIv1HD.d.mts +0 -298
  68. package/dist/RAGPipeline-BmkIv1HD.d.ts +0 -298
  69. package/dist/chunk-NVOMLHXW.mjs +0 -1259
  70. package/src/rag/RAGPipeline.ts +0 -200
  71. package/src/vectordb/IVectorDB.ts +0 -75
  72. package/src/vectordb/VectorDBFactory.ts +0 -41
  73. package/src/vectordb/adapters/MongoDbAdapter.ts +0 -175
  74. package/src/vectordb/adapters/UniversalVectorDBAdapter.ts +0 -177
@@ -1,37 +1,25 @@
1
- /**
2
- * Pinecone Vector DB Adapter
3
- *
4
- * Required options in VectorDBConfig.options:
5
- * - apiKey: string – Pinecone API key
6
- * - environment?: string – Pinecone environment (legacy, optional for new projects)
7
- */
8
-
9
1
  import { Pinecone, RecordMetadata } from '@pinecone-database/pinecone';
10
- import { IVectorDB, VectorMatch, UpsertDocument } from '../IVectorDB';
11
2
  import { VectorDBConfig } from '../../config/RagConfig';
3
+ import { BaseVectorProvider } from './BaseVectorProvider';
4
+ import { VectorMatch, UpsertDocument } from '../../types';
12
5
 
13
- export class PineconeAdapter implements IVectorDB {
6
+ export class PineconeProvider extends BaseVectorProvider {
14
7
  private client!: Pinecone;
15
- private readonly indexName: string;
16
8
  private readonly apiKey: string;
17
9
 
18
10
  constructor(config: VectorDBConfig) {
19
- this.indexName = config.indexName;
11
+ super(config);
20
12
  const opts = config.options as Record<string, string>;
21
- if (!opts.apiKey) throw new Error('[PineconeAdapter] options.apiKey is required');
13
+ if (!opts.apiKey) throw new Error('[PineconeProvider] options.apiKey is required');
22
14
  this.apiKey = opts.apiKey;
23
15
  }
24
16
 
25
17
  async initialize(): Promise<void> {
26
18
  this.client = new Pinecone({ apiKey: this.apiKey });
27
- // Verify index exists
28
19
  const indexes = await this.client.listIndexes();
29
20
  const names = indexes.indexes?.map((i) => i.name) ?? [];
30
21
  if (!names.includes(this.indexName)) {
31
- throw new Error(
32
- `[PineconeAdapter] Index "${this.indexName}" not found. ` +
33
- `Available: ${names.join(', ')}`
34
- );
22
+ throw new Error(`[PineconeProvider] Index "${this.indexName}" not found.`);
35
23
  }
36
24
  }
37
25
 
@@ -42,16 +30,11 @@ export class PineconeAdapter implements IVectorDB {
42
30
 
43
31
  async upsert(doc: UpsertDocument, namespace?: string): Promise<void> {
44
32
  await this.index(namespace).upsert({
45
- records: [
46
- {
47
- id: doc.id,
48
- values: doc.vector,
49
- metadata: {
50
- content: doc.content,
51
- ...(doc.metadata ?? {}),
52
- } as RecordMetadata,
53
- },
54
- ],
33
+ records: [{
34
+ id: doc.id,
35
+ values: doc.vector,
36
+ metadata: { content: doc.content, ...(doc.metadata ?? {}) } as RecordMetadata,
37
+ }],
55
38
  });
56
39
  }
57
40
 
@@ -61,40 +44,25 @@ export class PineconeAdapter implements IVectorDB {
61
44
  const records = docs.slice(i, i + BATCH).map((d) => ({
62
45
  id: d.id,
63
46
  values: d.vector,
64
- metadata: {
65
- content: d.content,
66
- ...(d.metadata ?? {}),
67
- } as RecordMetadata,
47
+ metadata: { content: d.content, ...(d.metadata ?? {}) } as RecordMetadata,
68
48
  }));
69
49
  await this.index(namespace).upsert({ records });
70
50
  }
71
51
  }
72
52
 
73
- async query(
74
- vector: number[],
75
- topK: number,
76
- namespace?: string,
77
- filter?: Record<string, unknown>
78
- ): Promise<VectorMatch[]> {
53
+ async query(vector: number[], topK: number, namespace?: string, filter?: Record<string, unknown>): Promise<VectorMatch[]> {
79
54
  const result = await this.index(namespace).query({
80
55
  vector,
81
56
  topK,
82
57
  includeMetadata: true,
83
58
  ...(filter ? { filter } : {}),
84
59
  });
85
-
86
- return (result.matches ?? []).map((m) => {
87
- const metadata = m.metadata as Record<string, unknown>;
88
- // Try multiple common fields for content
89
- const content = (metadata?.content || metadata?.text || metadata?.body || metadata?.description || '') as string;
90
-
91
- return {
92
- id: m.id,
93
- score: m.score ?? 0,
94
- content,
95
- metadata,
96
- };
97
- });
60
+ return (result.matches ?? []).map((m) => ({
61
+ id: m.id,
62
+ score: m.score ?? 0,
63
+ content: (m.metadata?.content || '') as string,
64
+ metadata: m.metadata as Record<string, unknown>,
65
+ }));
98
66
  }
99
67
 
100
68
  async delete(id: string, namespace?: string): Promise<void> {
@@ -109,13 +77,10 @@ export class PineconeAdapter implements IVectorDB {
109
77
  try {
110
78
  await this.client.listIndexes();
111
79
  return true;
112
- } catch (err) {
113
- console.error('[PineconeAdapter] Ping failed:', err);
80
+ } catch {
114
81
  return false;
115
82
  }
116
83
  }
117
84
 
118
- async disconnect(): Promise<void> {
119
- // Pinecone SDK is stateless REST, no persistent connection to close.
120
- }
85
+ async disconnect(): Promise<void> {}
121
86
  }
@@ -1,43 +1,31 @@
1
- /**
2
- * pgVector Adapter
3
- *
4
- * Stores embeddings in a PostgreSQL table using the pgvector extension.
5
- * Required options in VectorDBConfig.options:
6
- * - connectionString: string – PostgreSQL connection string
7
- * - dimensions?: number – vector dimensions (default 1536 for OpenAI ada-002)
8
- *
9
- * The adapter auto-creates the table and index on initialize().
10
- */
11
-
12
1
  import { Pool, PoolClient } from 'pg';
13
- import { IVectorDB, VectorMatch, UpsertDocument } from '../IVectorDB';
14
2
  import { VectorDBConfig } from '../../config/RagConfig';
3
+ import { BaseVectorProvider } from './BaseVectorProvider';
4
+ import { VectorMatch, UpsertDocument } from '../../types';
15
5
 
16
- export class PgVectorAdapter implements IVectorDB {
6
+ /**
7
+ * PostgreSQLProvider — PostgreSQL implementation using the pgvector extension.
8
+ */
9
+ export class PostgreSQLProvider extends BaseVectorProvider {
17
10
  private pool!: Pool;
18
- private readonly tableName: string;
19
11
  private readonly dimensions: number;
20
12
  private readonly connectionString: string;
13
+ private readonly tableName: string;
21
14
 
22
15
  constructor(config: VectorDBConfig) {
23
- this.tableName = config.indexName.replace(/[^a-z0-9_]/gi, '_'); // sanitize
16
+ super(config);
17
+ this.tableName = this.indexName.replace(/[^a-z0-9_]/gi, '_');
24
18
  const opts = config.options as Record<string, unknown>;
25
- if (!opts.connectionString) {
26
- throw new Error('[PgVectorAdapter] options.connectionString is required');
27
- }
19
+ if (!opts.connectionString) throw new Error('[PostgreSQLProvider] options.connectionString is required');
28
20
  this.connectionString = opts.connectionString as string;
29
21
  this.dimensions = (opts.dimensions as number) ?? 1536;
30
22
  }
31
23
 
32
24
  async initialize(): Promise<void> {
33
25
  this.pool = new Pool({ connectionString: this.connectionString });
34
-
35
26
  const client: PoolClient = await this.pool.connect();
36
27
  try {
37
- // Enable pgvector extension
38
28
  await client.query('CREATE EXTENSION IF NOT EXISTS vector');
39
-
40
- // Create the chunks table if it doesn't exist
41
29
  await client.query(`
42
30
  CREATE TABLE IF NOT EXISTS ${this.tableName} (
43
31
  id TEXT PRIMARY KEY,
@@ -47,8 +35,6 @@ export class PgVectorAdapter implements IVectorDB {
47
35
  embedding VECTOR(${this.dimensions})
48
36
  )
49
37
  `);
50
-
51
- // Create HNSW index for fast approximate nearest-neighbour search
52
38
  await client.query(`
53
39
  CREATE INDEX IF NOT EXISTS ${this.tableName}_embedding_idx
54
40
  ON ${this.tableName}
@@ -74,25 +60,17 @@ export class PgVectorAdapter implements IVectorDB {
74
60
  }
75
61
 
76
62
  async batchUpsert(docs: UpsertDocument[], namespace = ''): Promise<void> {
77
- // Sequential for simplicity; swap for COPY or multi-row INSERT for perf
78
63
  for (const doc of docs) {
79
64
  await this.upsert(doc, namespace);
80
65
  }
81
66
  }
82
67
 
83
- async query(
84
- vector: number[],
85
- topK: number,
86
- namespace?: string,
87
- filter?: Record<string, unknown>
88
- ): Promise<VectorMatch[]> {
68
+ async query(vector: number[], topK: number, namespace?: string, filter?: Record<string, unknown>): Promise<VectorMatch[]> {
89
69
  const vectorLiteral = `[${vector.join(',')}]`;
90
-
91
70
  let whereClause = namespace ? `WHERE namespace = $3` : '';
92
71
  const params: unknown[] = [vectorLiteral, topK];
93
72
  if (namespace) params.push(namespace);
94
73
 
95
- // Append metadata filter conditions if provided
96
74
  if (filter && Object.keys(filter).length > 0) {
97
75
  const filterConditions = Object.entries(filter)
98
76
  .map(([key, val]) => {
@@ -101,28 +79,23 @@ export class PgVectorAdapter implements IVectorDB {
101
79
  return `metadata->>'${key}' = $${paramIdx}`;
102
80
  })
103
81
  .join(' AND ');
104
- whereClause = whereClause
105
- ? `${whereClause} AND ${filterConditions}`
106
- : `WHERE ${filterConditions}`;
82
+ whereClause = whereClause ? `${whereClause} AND ${filterConditions}` : `WHERE ${filterConditions}`;
107
83
  }
108
84
 
109
85
  const result = await this.pool.query(
110
- `SELECT id,
111
- content,
112
- metadata,
113
- 1 - (embedding <=> $1::vector) AS score
114
- FROM ${this.tableName}
86
+ `SELECT id, content, metadata, 1 - (embedding <=> $1::vector) AS score
87
+ FROM ${this.tableName}
115
88
  ${whereClause}
116
- ORDER BY embedding <=> $1::vector
117
- LIMIT $2`,
89
+ ORDER BY embedding <=> $1::vector
90
+ LIMIT $2`,
118
91
  params
119
92
  );
120
93
 
121
94
  return result.rows.map((row: Record<string, unknown>) => ({
122
- id: String(row.id),
123
- score: parseFloat(String(row.score)),
124
- content: String(row.content),
125
- metadata: row.metadata as Record<string, unknown>,
95
+ id: String(row['id']),
96
+ score: parseFloat(String(row['score'])),
97
+ content: String(row['content']),
98
+ metadata: row['metadata'] as Record<string, unknown>,
126
99
  }));
127
100
  }
128
101
 
@@ -133,27 +106,19 @@ export class PgVectorAdapter implements IVectorDB {
133
106
  }
134
107
 
135
108
  async deleteNamespace(namespace: string): Promise<void> {
136
- await this.pool.query(
137
- `DELETE FROM ${this.tableName} WHERE namespace = $1`,
138
- [namespace]
139
- );
109
+ await this.pool.query(`DELETE FROM ${this.tableName} WHERE namespace = $1`, [namespace]);
140
110
  }
141
111
 
142
112
  async ping(): Promise<boolean> {
143
113
  try {
144
114
  await this.pool.query('SELECT 1');
145
115
  return true;
146
- } catch (err) {
147
- console.error('[PgVectorAdapter] Ping failed:', err);
116
+ } catch {
148
117
  return false;
149
118
  }
150
119
  }
151
120
 
152
121
  async disconnect(): Promise<void> {
153
- try {
154
- await this.pool.end();
155
- } catch (err) {
156
- console.error('[PgVectorAdapter] Failed to disconnect:', err);
157
- }
122
+ await this.pool.end();
158
123
  }
159
124
  }
@@ -0,0 +1,95 @@
1
+ import axios, { AxiosInstance } from 'axios';
2
+ import { VectorDBConfig } from '../../config/RagConfig';
3
+ import { BaseVectorProvider } from './BaseVectorProvider';
4
+ import { VectorMatch, UpsertDocument } from '../../types';
5
+
6
+ /**
7
+ * QdrantProvider — implementation for Qdrant using its REST API.
8
+ */
9
+ export class QdrantProvider extends BaseVectorProvider {
10
+ private http: AxiosInstance;
11
+
12
+ constructor(config: VectorDBConfig) {
13
+ super(config);
14
+ const opts = config.options as Record<string, unknown>;
15
+ const baseUrl = opts.baseUrl as string;
16
+ if (!baseUrl) throw new Error('[QdrantProvider] baseUrl is required');
17
+
18
+ this.http = axios.create({
19
+ baseURL: baseUrl,
20
+ headers: {
21
+ 'Content-Type': 'application/json',
22
+ ...(opts.apiKey ? { 'api-key': opts.apiKey as string } : {}),
23
+ },
24
+ });
25
+ }
26
+
27
+ async initialize(): Promise<void> {
28
+ await this.ping();
29
+ }
30
+
31
+ async upsert(doc: UpsertDocument, namespace?: string): Promise<void> {
32
+ await this.batchUpsert([doc], namespace);
33
+ }
34
+
35
+ async batchUpsert(docs: UpsertDocument[], namespace?: string): Promise<void> {
36
+ const payload = {
37
+ points: docs.map(doc => ({
38
+ id: doc.id,
39
+ vector: doc.vector,
40
+ payload: {
41
+ content: doc.content,
42
+ metadata: doc.metadata || {},
43
+ ...(namespace ? { namespace } : {}),
44
+ },
45
+ })),
46
+ };
47
+ await this.http.put(`/collections/${this.indexName}/points`, payload);
48
+ }
49
+
50
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
51
+ async query(vector: number[], topK: number, namespace?: string, _filter?: Record<string, unknown>): Promise<VectorMatch[]> {
52
+ const payload = {
53
+ vector: vector,
54
+ limit: topK,
55
+ with_payload: true,
56
+ filter: namespace ? {
57
+ must: [{ key: 'namespace', match: { value: namespace } }]
58
+ } : undefined,
59
+ };
60
+ const { data } = await this.http.post(`/collections/${this.indexName}/points/search`, payload);
61
+ return (data.result || []).map((res: Record<string, unknown>) => ({
62
+ id: res['id'] as string,
63
+ score: res['score'] as number,
64
+ content: (res['payload'] as Record<string, unknown>)?.content as string || '',
65
+ metadata: (res['payload'] as Record<string, unknown>)?.metadata as Record<string, unknown> || {},
66
+ }));
67
+ }
68
+
69
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
70
+ async delete(id: string, _namespace?: string): Promise<void> {
71
+ await this.http.post(`/collections/${this.indexName}/points/delete`, {
72
+ points: [id],
73
+ });
74
+ }
75
+
76
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
77
+ async deleteNamespace(_namespace: string): Promise<void> {
78
+ await this.http.post(`/collections/${this.indexName}/points/delete`, {
79
+ filter: {
80
+ must: [{ key: 'namespace', match: { value: _namespace } }]
81
+ }
82
+ });
83
+ }
84
+
85
+ async ping(): Promise<boolean> {
86
+ try {
87
+ await this.http.get('/healthz');
88
+ return true;
89
+ } catch {
90
+ return false;
91
+ }
92
+ }
93
+
94
+ async disconnect(): Promise<void> {}
95
+ }
@@ -0,0 +1,84 @@
1
+ import axios, { AxiosInstance } from 'axios';
2
+ import { VectorDBConfig } from '../../config/RagConfig';
3
+ import { BaseVectorProvider } from './BaseVectorProvider';
4
+ import { VectorMatch, UpsertDocument } from '../../types';
5
+
6
+ /**
7
+ * RedisProvider — implementation for Redis (e.g. Upstash) using its REST API.
8
+ */
9
+ export class RedisProvider extends BaseVectorProvider {
10
+ private http: AxiosInstance;
11
+
12
+ constructor(config: VectorDBConfig) {
13
+ super(config);
14
+ const opts = config.options as Record<string, unknown>;
15
+ const baseUrl = opts.baseUrl as string;
16
+ if (!baseUrl) throw new Error('[RedisProvider] baseUrl is required');
17
+
18
+ this.http = axios.create({
19
+ baseURL: baseUrl,
20
+ headers: {
21
+ 'Content-Type': 'application/json',
22
+ Authorization: `Bearer ${opts.apiKey}`,
23
+ },
24
+ });
25
+ }
26
+
27
+ async initialize(): Promise<void> {
28
+ await this.ping();
29
+ }
30
+
31
+ async upsert(doc: UpsertDocument, namespace?: string): Promise<void> {
32
+ const key = namespace ? `${namespace}:${doc.id}` : doc.id;
33
+ await this.http.post('/', ['JSON.SET', key, '$', JSON.stringify({
34
+ vector: doc.vector,
35
+ content: doc.content,
36
+ metadata: doc.metadata || {},
37
+ })]);
38
+ }
39
+
40
+ async batchUpsert(docs: UpsertDocument[], namespace?: string): Promise<void> {
41
+ for (const doc of docs) {
42
+ await this.upsert(doc, namespace);
43
+ }
44
+ }
45
+
46
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
47
+ async query(vector: number[], topK: number, namespace?: string, _filter?: Record<string, unknown>): Promise<VectorMatch[]> {
48
+ // This is a simplified representation of FT.SEARCH in Redis Vector
49
+ const payload = {
50
+ index: this.indexName,
51
+ vector: vector,
52
+ topK: topK,
53
+ namespace: namespace,
54
+ };
55
+ const { data } = await this.http.post('/search', payload);
56
+ return (data.results || []).map((res: Record<string, unknown>) => ({
57
+ id: res['id'] as string,
58
+ score: res['score'] as number,
59
+ content: res['content'] as string,
60
+ metadata: res['metadata'] as Record<string, unknown>,
61
+ }));
62
+ }
63
+
64
+ async delete(id: string, namespace?: string): Promise<void> {
65
+ const key = namespace ? `${namespace}:${id}` : id;
66
+ await this.http.post('/', ['DEL', key]);
67
+ }
68
+
69
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
70
+ async deleteNamespace(_namespace: string): Promise<void> {
71
+ // Redis doesn't have a direct "delete namespace" easily without SCAN
72
+ }
73
+
74
+ async ping(): Promise<boolean> {
75
+ try {
76
+ await this.http.post('/', ['PING']);
77
+ return true;
78
+ } catch {
79
+ return false;
80
+ }
81
+ }
82
+
83
+ async disconnect(): Promise<void> {}
84
+ }
@@ -0,0 +1,124 @@
1
+ import axios, { AxiosInstance } from 'axios';
2
+ import { VectorDBConfig } from '../../config/RagConfig';
3
+ import { BaseVectorProvider } from './BaseVectorProvider';
4
+ import { VectorMatch, UpsertDocument } from '../../types';
5
+
6
+ /**
7
+ * WeaviateProvider — implementation for Weaviate using its REST/GraphQL API.
8
+ */
9
+ export class WeaviateProvider extends BaseVectorProvider {
10
+ private http: AxiosInstance;
11
+
12
+ constructor(config: VectorDBConfig) {
13
+ super(config);
14
+ const opts = config.options as Record<string, unknown>;
15
+ const baseUrl = opts.baseUrl as string;
16
+ if (!baseUrl) throw new Error('[WeaviateProvider] baseUrl is required');
17
+
18
+ this.http = axios.create({
19
+ baseURL: baseUrl,
20
+ headers: {
21
+ 'Content-Type': 'application/json',
22
+ ...(opts.apiKey ? {
23
+ 'X-OpenAI-Api-Key': opts.apiKey as string,
24
+ 'Authorization': `Bearer ${opts.apiKey as string}`
25
+ } : {}),
26
+ },
27
+ });
28
+ }
29
+
30
+ async initialize(): Promise<void> {
31
+ await this.ping();
32
+ }
33
+
34
+ async upsert(doc: UpsertDocument, namespace?: string): Promise<void> {
35
+ const payload = {
36
+ class: this.indexName,
37
+ id: doc.id,
38
+ vector: doc.vector,
39
+ properties: {
40
+ content: doc.content,
41
+ metadata: JSON.stringify(doc.metadata || {}),
42
+ namespace: namespace || '',
43
+ },
44
+ };
45
+ await this.http.post('/v1/objects', payload);
46
+ }
47
+
48
+ async batchUpsert(docs: UpsertDocument[], namespace?: string): Promise<void> {
49
+ const payload = {
50
+ objects: docs.map(doc => ({
51
+ class: this.indexName,
52
+ id: doc.id,
53
+ vector: doc.vector,
54
+ properties: {
55
+ content: doc.content,
56
+ metadata: JSON.stringify(doc.metadata || {}),
57
+ namespace: namespace || '',
58
+ },
59
+ })),
60
+ };
61
+ await this.http.post('/v1/batch/objects', payload);
62
+ }
63
+
64
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
65
+ async query(vector: number[], topK: number, namespace?: string, _filter?: Record<string, unknown>): Promise<VectorMatch[]> {
66
+ const graphqlQuery = {
67
+ query: `
68
+ {
69
+ Get {
70
+ ${this.indexName}(
71
+ nearVector: {
72
+ vector: ${JSON.stringify(vector)}
73
+ }
74
+ limit: ${topK}
75
+ ${namespace ? `where: { path: ["namespace"], operator: Equal, valueString: "${namespace}" }` : ''}
76
+ ) {
77
+ content
78
+ metadata
79
+ _additional {
80
+ id
81
+ distance
82
+ }
83
+ }
84
+ }
85
+ }
86
+ `
87
+ };
88
+ const { data } = await this.http.post('/v1/graphql', graphqlQuery);
89
+ const results = data.data?.Get?.[this.indexName] || [];
90
+
91
+ return results.map((res: Record<string, unknown>) => ({
92
+ id: (res['_additional'] as Record<string, unknown>).id as string,
93
+ score: 1 - ((res['_additional'] as Record<string, unknown>).distance as number),
94
+ content: res['content'] as string,
95
+ metadata: res['metadata'] ? JSON.parse(res['metadata'] as string) : {},
96
+ }));
97
+ }
98
+
99
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
100
+ async delete(id: string, _namespace?: string): Promise<void> {
101
+ await this.http.delete(`/v1/objects/${this.indexName}/${id}`);
102
+ }
103
+
104
+ async deleteNamespace(namespace: string): Promise<void> {
105
+ // Weaviate batch delete
106
+ await this.http.post('/v1/batch/objects', {
107
+ match: {
108
+ class: this.indexName,
109
+ where: { path: ['namespace'], operator: 'Equal', valueString: namespace }
110
+ }
111
+ });
112
+ }
113
+
114
+ async ping(): Promise<boolean> {
115
+ try {
116
+ await this.http.get('/v1/.well-known/live');
117
+ return true;
118
+ } catch {
119
+ return false;
120
+ }
121
+ }
122
+
123
+ async disconnect(): Promise<void> {}
124
+ }
package/src/server.ts CHANGED
@@ -5,21 +5,29 @@
5
5
 
6
6
  // ── Shared Types (Safe for both) ──────────────────────────────
7
7
  export type { RagConfig, VectorDBConfig, LLMConfig, EmbeddingConfig, UIConfig, RAGConfig } from './config/RagConfig';
8
- export type { IVectorDB, VectorMatch, UpsertDocument } from './vectordb/IVectorDB';
8
+ export type { VectorMatch, UpsertDocument } from './types';
9
9
  export type { ILLMProvider, ChatMessage, ChatOptions, EmbedOptions } from './llm/ILLMProvider';
10
- export type { IngestDocument, ChatResponse } from './rag/RAGPipeline';
10
+ export type { IngestDocument, ChatResponse } from './types';
11
11
  export type { Chunk, ChunkOptions } from './rag/DocumentChunker';
12
12
 
13
13
  // ── Server-Only Logic (Node.js dependent) ─────────────────────
14
- export { RAGPipeline } from './rag/RAGPipeline';
14
+ export { VectorPlugin } from './core/VectorPlugin';
15
+ export { Pipeline } from './core/Pipeline';
16
+ export { ConfigResolver } from './core/ConfigResolver';
17
+ export { ProviderRegistry } from './core/ProviderRegistry';
15
18
  export { DocumentChunker } from './rag/DocumentChunker';
16
19
  export { getRagConfig } from './config/serverConfig';
17
20
 
18
- // ── Factories & Adapters (Node.js dependent) ──────────────────
19
- export { VectorDBFactory } from './vectordb/VectorDBFactory';
20
- export { PineconeAdapter } from './vectordb/adapters/PineconeAdapter';
21
- export { PgVectorAdapter } from './vectordb/adapters/PgVectorAdapter';
22
- export { MongoDbAdapter } from './vectordb/adapters/MongoDbAdapter';
21
+ // ── Providers (Node.js dependent) ─────────────────────────────
22
+ export { BaseVectorProvider } from './providers/vectordb/BaseVectorProvider';
23
+ export { PineconeProvider } from './providers/vectordb/PineconeProvider';
24
+ export { PostgreSQLProvider } from './providers/vectordb/PostgreSQLProvider';
25
+ export { MongoDBProvider } from './providers/vectordb/MongoDBProvider';
26
+ export { MilvusProvider } from './providers/vectordb/MilvusProvider';
27
+ export { QdrantProvider } from './providers/vectordb/QdrantProvider';
28
+ export { ChromaDBProvider } from './providers/vectordb/ChromaDBProvider';
29
+ export { RedisProvider } from './providers/vectordb/RedisProvider';
30
+ export { WeaviateProvider } from './providers/vectordb/WeaviateProvider';
23
31
 
24
32
  export { LLMFactory } from './llm/LLMFactory';
25
33
  export { OpenAIProvider } from './llm/providers/OpenAIProvider';