@retrivora-ai/rag-engine 0.4.5 → 1.0.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 (74) hide show
  1. package/README.md +32 -57
  2. package/dist/{ChromaDBProvider-GI7TB7GJ.mjs → ChromaDBProvider-MIDOR4FW.mjs} +2 -2
  3. package/dist/{DocumentChunker-3yElxTO3.d.mts → DocumentChunker-C-sCZPhi.d.mts} +6 -6
  4. package/dist/{DocumentChunker-3yElxTO3.d.ts → DocumentChunker-C-sCZPhi.d.ts} +6 -6
  5. package/dist/{MilvusProvider-WDVTFB7D.mjs → MilvusProvider-U7SKC27V.mjs} +2 -2
  6. package/dist/{MongoDBProvider-RE3Q5S5B.mjs → MongoDBProvider-Z6ALOVDN.mjs} +2 -2
  7. package/dist/{PineconeProvider-BE2JWSPD.mjs → PineconeProvider-QZNRKTN2.mjs} +2 -2
  8. package/dist/{PostgreSQLProvider-5HHTK4SU.mjs → PostgreSQLProvider-BMOETDZA.mjs} +2 -2
  9. package/dist/{QdrantProvider-XVDVBNIG.mjs → QdrantProvider-YNUNEOZH.mjs} +2 -2
  10. package/dist/{RagConfig-BgRDL9Vy.d.mts → RagConfig-DRJO4hGU.d.mts} +12 -1
  11. package/dist/{RagConfig-BgRDL9Vy.d.ts → RagConfig-DRJO4hGU.d.ts} +12 -1
  12. package/dist/{RedisProvider-EK2R2PQH.mjs → RedisProvider-SR65SCKV.mjs} +2 -2
  13. package/dist/{SimpleGraphProvider-M6T7SE7D.mjs → SimpleGraphProvider-SLOXO4M7.mjs} +1 -1
  14. package/dist/{UniversalVectorProvider-YIDRX6VT.mjs → UniversalVectorProvider-IN67OS56.mjs} +3 -3
  15. package/dist/{WeaviateProvider-4CAPQ7UY.mjs → WeaviateProvider-5FWDFITI.mjs} +2 -2
  16. package/dist/{chunk-5KNBWQM6.mjs → chunk-3DSHW676.mjs} +5 -1
  17. package/dist/{chunk-PRC5CZIZ.mjs → chunk-5W2YWFT3.mjs} +1248 -1361
  18. package/dist/{chunk-H6RKMU7W.mjs → chunk-5YGUXK7Z.mjs} +1 -1
  19. package/dist/{chunk-PQKTC73Y.mjs → chunk-CD6TSNL4.mjs} +67 -6
  20. package/dist/{chunk-RK2UDJA2.mjs → chunk-CFVEZTBJ.mjs} +1 -1
  21. package/dist/{chunk-LJWWPTWE.mjs → chunk-FLOSGE6A.mjs} +76 -14
  22. package/dist/{chunk-GQT5LF4G.mjs → chunk-LR3VMDVK.mjs} +2 -2
  23. package/dist/{chunk-KTS3LLHY.mjs → chunk-M6JSPGAR.mjs} +5 -5
  24. package/dist/{chunk-3QWAK3RZ.mjs → chunk-U55XRW3U.mjs} +6 -2
  25. package/dist/{chunk-XCNXPECE.mjs → chunk-VUQJVIJT.mjs} +55 -1
  26. package/dist/chunk-X4TOT24V.mjs +89 -0
  27. package/dist/{chunk-EDLTMSNY.mjs → chunk-YLTMFW4M.mjs} +1 -1
  28. package/dist/handlers/index.d.mts +2 -2
  29. package/dist/handlers/index.d.ts +2 -2
  30. package/dist/handlers/index.js +1488 -1371
  31. package/dist/handlers/index.mjs +5 -3
  32. package/dist/index-B2mutkgp.d.ts +116 -0
  33. package/dist/index-Bjy0es5a.d.mts +116 -0
  34. package/dist/index.d.mts +17 -11
  35. package/dist/index.d.ts +17 -11
  36. package/dist/index.js +253 -363
  37. package/dist/index.mjs +243 -353
  38. package/dist/server.d.mts +108 -158
  39. package/dist/server.d.ts +108 -158
  40. package/dist/server.js +1452 -1386
  41. package/dist/server.mjs +12 -12
  42. package/package.json +5 -1
  43. package/src/config/RagConfig.ts +7 -0
  44. package/src/core/ConfigValidator.ts +66 -492
  45. package/src/core/LangChainAgent.ts +78 -0
  46. package/src/core/Pipeline.ts +210 -240
  47. package/src/core/ProviderHealthCheck.ts +35 -406
  48. package/src/core/ProviderInterfaces.ts +37 -0
  49. package/src/core/ProviderRegistry.ts +70 -55
  50. package/src/core/QueryProcessor.ts +173 -0
  51. package/src/core/VectorPlugin.ts +7 -0
  52. package/src/handlers/index.ts +45 -0
  53. package/src/llm/ILLMProvider.ts +10 -0
  54. package/src/llm/LLMFactory.ts +33 -13
  55. package/src/llm/providers/AnthropicProvider.ts +55 -15
  56. package/src/llm/providers/GeminiProvider.ts +51 -0
  57. package/src/llm/providers/OllamaProvider.ts +100 -15
  58. package/src/llm/providers/OpenAIProvider.ts +60 -11
  59. package/src/providers/vectordb/BaseVectorProvider.ts +11 -0
  60. package/src/providers/vectordb/MilvusProvider.ts +4 -0
  61. package/src/providers/vectordb/MongoDBProvider.ts +72 -8
  62. package/src/providers/vectordb/PineconeProvider.ts +60 -5
  63. package/src/providers/vectordb/PostgreSQLProvider.ts +84 -14
  64. package/src/providers/vectordb/QdrantProvider.ts +4 -0
  65. package/src/providers/vectordb/WeaviateProvider.ts +8 -4
  66. package/src/rag/DocumentChunker.ts +15 -19
  67. package/src/rag/EntityExtractor.ts +3 -0
  68. package/src/rag/LlamaIndexIngestor.ts +61 -0
  69. package/src/rag/Reranker.ts +20 -0
  70. package/src/server.ts +1 -1
  71. package/src/types/index.ts +9 -0
  72. package/dist/chunk-FWCSY2DS.mjs +0 -37
  73. package/dist/index-7qeLTPBL.d.mts +0 -114
  74. package/dist/index-DowY4_K0.d.ts +0 -114
@@ -1,24 +1,14 @@
1
- /**
2
- * ProviderHealthCheck.ts — Pre-flight validation for vector DB and LLM providers.
3
- *
4
- * Performs connectivity tests, credential validation, and capability checks
5
- * before initializing providers.
6
- *
7
- * Note: Option keys used here mirror each Provider constructor's expected keys.
8
- */
9
-
10
1
  import { VectorDBConfig, LLMConfig, EmbeddingConfig } from '../config/RagConfig';
11
2
  import { ConfigValidator } from './ConfigValidator';
3
+ import { ProviderRegistry } from './ProviderRegistry';
4
+ import { LLMFactory } from '../llm/LLMFactory';
5
+ import type { HealthCheckResult } from './ProviderInterfaces';
6
+ export type { HealthCheckResult };
12
7
 
13
- export interface HealthCheckResult {
14
- healthy: boolean;
15
- provider: string;
16
- version?: string;
17
- capabilities?: Record<string, unknown>;
18
- error?: string;
19
- timestamp: number;
20
- }
21
-
8
+ /**
9
+ * ProviderHealthCheck.ts — Pre-flight validation for vector DB and LLM providers.
10
+ * Performs connectivity tests, credential validation, and capability checks.
11
+ */
22
12
  export class ProviderHealthCheck {
23
13
  /**
24
14
  * Validates vector database configuration before initialization.
@@ -26,12 +16,11 @@ export class ProviderHealthCheck {
26
16
  static async checkVectorProvider(config: VectorDBConfig): Promise<HealthCheckResult> {
27
17
  const timestamp = Date.now();
28
18
 
29
- // Validate configuration first
30
- const configErrors = ConfigValidator.validate({
19
+ const configErrors = await ConfigValidator.validate({
31
20
  projectId: 'health-check',
32
21
  vectorDb: config,
33
- llm: { provider: 'openai', model: 'gpt-4o' },
34
- embedding: { provider: 'openai', model: 'text-embedding-3-small' },
22
+ llm: { provider: 'openai', model: 'gpt-4o', apiKey: 'none' },
23
+ embedding: { provider: 'openai', model: 'text-embedding-3-small', apiKey: 'none' },
35
24
  });
36
25
 
37
26
  const vectorDbErrors = configErrors.filter((e) => e.field.startsWith('vectorDb'));
@@ -45,35 +34,13 @@ export class ProviderHealthCheck {
45
34
  }
46
35
 
47
36
  try {
48
- switch (config.provider) {
49
- case 'pinecone':
50
- return await this.checkPinecone(config, timestamp);
51
- case 'pgvector':
52
- case 'postgresql':
53
- return await this.checkPostgres(config, timestamp);
54
- case 'mongodb':
55
- return await this.checkMongoDB(config, timestamp);
56
- case 'milvus':
57
- return await this.checkMilvus(config, timestamp);
58
- case 'qdrant':
59
- return await this.checkQdrant(config, timestamp);
60
- case 'chromadb':
61
- return await this.checkChromaDB(config, timestamp);
62
- case 'redis':
63
- return await this.checkRedis(config, timestamp);
64
- case 'weaviate':
65
- return await this.checkWeaviate(config, timestamp);
66
- case 'rest':
67
- case 'universal_rest':
68
- return await this.checkRestAPI(config, timestamp);
69
- default:
70
- return {
71
- healthy: false,
72
- provider: config.provider,
73
- error: `Unsupported provider: ${config.provider}`,
74
- timestamp,
75
- };
37
+ const checker = await ProviderRegistry.getVectorHealthChecker(config.provider);
38
+ if (checker) {
39
+ return await checker.check(config as unknown as Record<string, unknown>);
76
40
  }
41
+
42
+ // Fallback for non-migrated providers
43
+ return await this.fallbackVectorHealthCheck(config, timestamp);
77
44
  } catch (error) {
78
45
  return {
79
46
  healthy: false,
@@ -84,392 +51,54 @@ export class ProviderHealthCheck {
84
51
  }
85
52
  }
86
53
 
87
- private static async checkPinecone(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
88
- const opts = config.options as Record<string, string>;
89
- try {
90
- const { Pinecone } = await import('@pinecone-database/pinecone');
91
- const client = new Pinecone({ apiKey: opts.apiKey });
92
- const indexes = await client.listIndexes();
93
- const indexNames = indexes.indexes?.map((i) => i.name) ?? [];
54
+ private static async fallbackVectorHealthCheck(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
55
+ const opts = (config.options || {}) as Record<string, unknown>;
56
+ const baseUrl = (opts.baseUrl as string) || (opts.uri as string);
94
57
 
95
- if (!indexNames.includes(config.indexName)) {
58
+ if (baseUrl && baseUrl.startsWith('http')) {
59
+ try {
60
+ const response = await fetch(`${baseUrl.replace(/\/$/, '')}/health`);
96
61
  return {
97
- healthy: false,
98
- provider: 'pinecone',
99
- error: `Index "${config.indexName}" not found. Available: ${indexNames.join(', ')}`,
62
+ healthy: response.ok,
63
+ provider: config.provider,
64
+ error: response.ok ? undefined : `Health check failed: ${response.status}`,
100
65
  timestamp,
101
66
  };
102
- }
103
- return {
104
- healthy: true,
105
- provider: 'pinecone',
106
- capabilities: { indexes: indexNames.length, targetIndex: config.indexName },
107
- timestamp,
108
- };
109
- } catch (error) {
110
- return {
111
- healthy: false,
112
- provider: 'pinecone',
113
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
114
- timestamp,
115
- };
116
- }
117
- }
118
-
119
- private static async checkPostgres(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
120
- const opts = config.options as Record<string, string>;
121
- try {
122
- const { Client } = await import('pg');
123
- const client = new Client({ connectionString: opts.connectionString });
124
- await client.connect();
125
- const result = await client.query(`
126
- SELECT EXISTS(SELECT 1 FROM pg_extension WHERE extname = 'vector');
127
- `);
128
- const hasVector = result.rows[0].exists;
129
- await client.end();
130
- return {
131
- healthy: true,
132
- provider: 'postgresql',
133
- capabilities: { pgvectorInstalled: hasVector },
134
- timestamp,
135
- };
136
- } catch (error) {
137
- return {
138
- healthy: false,
139
- provider: 'postgresql',
140
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
141
- timestamp,
142
- };
143
- }
144
- }
145
-
146
- private static async checkMongoDB(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
147
- const opts = config.options as Record<string, string>;
148
- try {
149
- const { MongoClient } = await import('mongodb');
150
- const client = new MongoClient(opts.uri);
151
- await client.connect();
152
- const db = client.db(opts.database);
153
- const collections = await db.listCollections().toArray();
154
- const collectionNames = collections.map((c) => c.name);
155
- const hasCollection = collectionNames.includes(opts.collection);
156
- await client.close();
157
- return {
158
- healthy: true,
159
- provider: 'mongodb',
160
- capabilities: {
161
- collections: collectionNames.length,
162
- targetCollection: hasCollection ? opts.collection : 'NOT FOUND (will be created on first insert)',
163
- },
164
- timestamp,
165
- };
166
- } catch (error) {
167
- return {
168
- healthy: false,
169
- provider: 'mongodb',
170
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
171
- timestamp,
172
- };
173
- }
174
- }
175
-
176
- /**
177
- * Milvus health check — uses baseUrl/uri (matching MilvusProvider constructor).
178
- */
179
- private static async checkMilvus(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
180
- const opts = config.options as Record<string, unknown>;
181
-
182
- // Resolve endpoint — mirrors MilvusProvider constructor logic
183
- const baseUrl =
184
- (opts.baseUrl as string) ||
185
- (opts.uri as string) ||
186
- (opts.host ? `http://${opts.host}:${(opts.port as number) || 19530}` : 'http://localhost:19530');
187
-
188
- try {
189
- const controller = new AbortController();
190
- const timeoutId = setTimeout(() => controller.abort(), 5000);
191
- const response = await fetch(`${baseUrl}/v1/health`, { signal: controller.signal });
192
- clearTimeout(timeoutId);
193
-
194
- if (!response.ok) {
195
- throw new Error(`Health check returned ${response.status}`);
196
- }
197
- return {
198
- healthy: true,
199
- provider: 'milvus',
200
- capabilities: { endpoint: baseUrl },
201
- timestamp,
202
- };
203
- } catch (error) {
204
- return {
205
- healthy: false,
206
- provider: 'milvus',
207
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
208
- timestamp,
209
- };
210
- }
211
- }
212
-
213
- /**
214
- * Qdrant health check — uses baseUrl (matching QdrantProvider constructor).
215
- */
216
- private static async checkQdrant(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
217
- const opts = config.options as Record<string, unknown>;
218
- const baseUrl = ((opts.baseUrl as string) || (opts.url as string) || 'http://localhost:6333').replace(/\/$/, '');
219
- try {
220
- const apiKey = opts.apiKey as string | undefined;
221
- const response = await fetch(`${baseUrl}/`, {
222
- headers: apiKey ? { 'api-key': apiKey } : {},
223
- });
224
- if (!response.ok) throw new Error(`Health check returned ${response.status}`);
225
- const health = await response.json();
226
- return {
227
- healthy: true,
228
- provider: 'qdrant',
229
- capabilities: health as Record<string, unknown>,
230
- timestamp,
231
- };
232
- } catch (error) {
233
- return {
234
- healthy: false,
235
- provider: 'qdrant',
236
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
237
- timestamp,
238
- };
239
- }
240
- }
241
-
242
- /**
243
- * ChromaDB health check — uses baseUrl/host (matching ChromaDBProvider constructor).
244
- */
245
- private static async checkChromaDB(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
246
- const opts = config.options as Record<string, unknown>;
247
-
248
- // Mirrors ChromaDBProvider constructor
249
- const baseUrl =
250
- (opts.baseUrl as string) ||
251
- (opts.host ? `http://${opts.host}:${(opts.port as number) || 8000}` : 'http://localhost:8000');
252
-
253
- try {
254
- const response = await fetch(`${baseUrl}/api/v1/heartbeat`);
255
- if (!response.ok) throw new Error(`Health check returned ${response.status}`);
256
- return {
257
- healthy: true,
258
- provider: 'chromadb',
259
- capabilities: { endpoint: baseUrl },
260
- timestamp,
261
- };
262
- } catch (error) {
263
- return {
264
- healthy: false,
265
- provider: 'chromadb',
266
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
267
- timestamp,
268
- };
269
- }
270
- }
271
-
272
- /**
273
- * Redis health check — Redis is TCP-only (no HTTP endpoint).
274
- * We report healthy=true with a note; actual connectivity is validated at first operation.
275
- */
276
- private static async checkRedis(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
277
- const opts = config.options as Record<string, string>;
278
- const url =
279
- opts.baseUrl || opts.url || (opts.host && opts.port ? `redis://${opts.host}:${opts.port}` : 'redis://localhost:6379');
280
-
281
- // For Upstash REST endpoints, try an HTTP ping
282
- if (url.startsWith('http')) {
283
- try {
284
- await fetch(url);
285
- return { healthy: true, provider: 'redis', capabilities: { endpoint: url }, timestamp };
286
67
  } catch {
287
- // Ignore Upstash may reject GET but accept POST
68
+ return { healthy: false, provider: config.provider, error: 'Provider unreachable', timestamp };
288
69
  }
289
70
  }
290
71
 
291
72
  return {
292
73
  healthy: true,
293
- provider: 'redis',
294
- capabilities: {
295
- endpoint: url,
296
- note: 'Redis uses TCP; connectivity is validated on first operation.',
297
- },
74
+ provider: config.provider,
75
+ error: 'Pluggable health check not implemented; basic reachability assumed.',
298
76
  timestamp,
299
77
  };
300
78
  }
301
79
 
302
- /**
303
- * Weaviate health check — uses baseUrl/url (matching WeaviateProvider constructor).
304
- */
305
- private static async checkWeaviate(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
306
- const opts = config.options as Record<string, string>;
307
- const baseUrl = ((opts.baseUrl || opts.url) || 'http://localhost:8080').replace(/\/$/, '');
308
- try {
309
- const response = await fetch(`${baseUrl}/v1/.well-known/ready`);
310
- if (!response.ok) throw new Error(`Health check returned ${response.status}`);
311
- return {
312
- healthy: true,
313
- provider: 'weaviate',
314
- capabilities: { endpoint: baseUrl },
315
- timestamp,
316
- };
317
- } catch (error) {
318
- return {
319
- healthy: false,
320
- provider: 'weaviate',
321
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
322
- timestamp,
323
- };
324
- }
325
- }
326
-
327
- private static async checkRestAPI(config: VectorDBConfig, timestamp: number): Promise<HealthCheckResult> {
328
- const opts = config.options as Record<string, string>;
329
- const baseUrl = (opts.baseUrl || '').replace(/\/$/, '');
330
- if (!baseUrl) {
331
- return { healthy: false, provider: 'rest', error: 'baseUrl is required', timestamp };
332
- }
333
- try {
334
- const response = await fetch(`${baseUrl}/health`, {
335
- headers: opts.headers ? JSON.parse(opts.headers) : {},
336
- });
337
- return {
338
- healthy: response.ok,
339
- provider: 'rest',
340
- error: response.ok ? undefined : `Health check returned ${response.status}`,
341
- timestamp,
342
- };
343
- } catch (error) {
344
- return {
345
- healthy: false,
346
- provider: 'rest',
347
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
348
- timestamp,
349
- };
350
- }
351
- }
352
-
353
80
  /**
354
81
  * Validates LLM provider configuration.
355
82
  */
356
83
  static async checkLLMProvider(config: LLMConfig): Promise<HealthCheckResult> {
357
84
  const timestamp = Date.now();
358
85
  try {
359
- switch (config.provider) {
360
- case 'openai':
361
- return await this.checkOpenAI(config, timestamp);
362
- case 'anthropic':
363
- return await this.checkAnthropic(config, timestamp);
364
- case 'ollama':
365
- return await this.checkOllama(config, timestamp);
366
- case 'rest':
367
- case 'universal_rest':
368
- return await this.checkLLMRestAPI(config, timestamp);
369
- default:
370
- return {
371
- healthy: false,
372
- provider: config.provider,
373
- error: `Unsupported provider: ${config.provider}`,
374
- timestamp,
375
- };
86
+ const checker = LLMFactory.getHealthChecker(config.provider);
87
+ if (checker) {
88
+ return await checker.check(config as unknown as Record<string, unknown>);
376
89
  }
377
- } catch (error) {
378
- return {
379
- healthy: false,
380
- provider: config.provider,
381
- error: error instanceof Error ? error.message : String(error),
382
- timestamp,
383
- };
384
- }
385
- }
386
-
387
- private static async checkOpenAI(config: LLMConfig, timestamp: number): Promise<HealthCheckResult> {
388
- try {
389
- const OpenAI = await import('openai');
390
- const client = new OpenAI.default({ apiKey: config.apiKey });
391
- const models = await client.models.list();
392
- const hasModel = models.data.some((m) => m.id === config.model);
90
+
393
91
  return {
394
92
  healthy: true,
395
- provider: 'openai',
396
- capabilities: { model: config.model, available: hasModel, totalModels: models.data.length },
397
- timestamp,
398
- };
399
- } catch (error) {
400
- return {
401
- healthy: false,
402
- provider: 'openai',
403
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
404
- timestamp,
405
- };
406
- }
407
- }
408
-
409
- private static async checkAnthropic(config: LLMConfig, timestamp: number): Promise<HealthCheckResult> {
410
- try {
411
- const { default: Anthropic } = await import('@anthropic-ai/sdk');
412
- const client = new Anthropic({ apiKey: config.apiKey });
413
- await client.messages.create({
414
- model: config.model,
415
- max_tokens: 10,
416
- messages: [{ role: 'user', content: 'ping' }],
417
- });
418
- return { healthy: true, provider: 'anthropic', capabilities: { model: config.model }, timestamp };
419
- } catch (error) {
420
- return {
421
- healthy: false,
422
- provider: 'anthropic',
423
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
424
- timestamp,
425
- };
426
- }
427
- }
428
-
429
- private static async checkOllama(config: LLMConfig, timestamp: number): Promise<HealthCheckResult> {
430
- const baseUrl = (config.baseUrl || 'http://localhost:11434').replace(/\/$/, '');
431
- try {
432
- const response = await fetch(`${baseUrl}/api/tags`);
433
- if (!response.ok) throw new Error(`Health check returned ${response.status}`);
434
- const data = await response.json() as Record<string, unknown>;
435
- const models = (data.models as Array<{ name: string }>) || [];
436
- const hasModel = models.some((m) => m.name === config.model);
437
- return {
438
- healthy: true,
439
- provider: 'ollama',
440
- capabilities: { model: config.model, available: hasModel, totalModels: models.length },
441
- timestamp,
442
- };
443
- } catch (error) {
444
- return {
445
- healthy: false,
446
- provider: 'ollama',
447
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
448
- timestamp,
449
- };
450
- }
451
- }
452
-
453
- private static async checkLLMRestAPI(config: LLMConfig, timestamp: number): Promise<HealthCheckResult> {
454
- const baseUrlRaw = config.baseUrl || (config.options as Record<string, unknown>)?.baseUrl;
455
- const baseUrl = (typeof baseUrlRaw === 'string' ? baseUrlRaw : '').replace(/\/$/, '');
456
- if (!baseUrl) {
457
- return { healthy: false, provider: config.provider, error: 'baseUrl is required', timestamp };
458
- }
459
- try {
460
- const headers = (config.options as Record<string, unknown>)?.headers as Record<string, string> | undefined;
461
- const response = await fetch(`${baseUrl}/health`, { headers: headers || undefined });
462
- return {
463
- healthy: response.ok,
464
93
  provider: config.provider,
465
- error: response.ok ? undefined : `Health check returned ${response.status}`,
94
+ error: 'Pluggable health check not implemented; basic reachability assumed.',
466
95
  timestamp,
467
96
  };
468
97
  } catch (error) {
469
98
  return {
470
99
  healthy: false,
471
100
  provider: config.provider,
472
- error: `Connection failed: ${error instanceof Error ? error.message : String(error)}`,
101
+ error: error instanceof Error ? error.message : String(error),
473
102
  timestamp,
474
103
  };
475
104
  }
@@ -0,0 +1,37 @@
1
+ import { ValidationError } from './ConfigValidator';
2
+
3
+ /**
4
+ * Interface for provider-specific configuration validation logic.
5
+ */
6
+ export interface IProviderValidator {
7
+ /**
8
+ * Validates the configuration for a specific provider.
9
+ * @param config - The configuration object to validate.
10
+ * @returns An array of validation errors (empty if valid).
11
+ */
12
+ validate(config: Record<string, unknown>): ValidationError[];
13
+ }
14
+
15
+ /**
16
+ * Result of a provider health check.
17
+ */
18
+ export interface HealthCheckResult {
19
+ healthy: boolean;
20
+ provider: string;
21
+ version?: string;
22
+ capabilities?: Record<string, unknown>;
23
+ error?: string;
24
+ timestamp: number;
25
+ }
26
+
27
+ /**
28
+ * Interface for provider-specific health checking logic.
29
+ */
30
+ export interface IProviderHealthChecker {
31
+ /**
32
+ * Performs a health check for a specific provider.
33
+ * @param config - The configuration object used to connect to the provider.
34
+ * @returns A promise that resolves to the health check result.
35
+ */
36
+ check(config: Record<string, unknown>): Promise<HealthCheckResult>;
37
+ }