rag-lite-ts 2.0.2 → 2.0.4

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/README.md +27 -0
  2. package/dist/cli/indexer.js +25 -6
  3. package/dist/cli/search.js +3 -3
  4. package/dist/cli.js +33 -6
  5. package/dist/core/actionable-error-messages.js +3 -3
  6. package/dist/core/content-manager.d.ts +0 -8
  7. package/dist/core/content-manager.js +2 -30
  8. package/dist/core/database-connection-manager.js +10 -0
  9. package/dist/core/db.d.ts +0 -32
  10. package/dist/core/db.js +11 -68
  11. package/dist/core/embedder-factory.d.ts +0 -22
  12. package/dist/core/embedder-factory.js +8 -35
  13. package/dist/core/index.d.ts +3 -3
  14. package/dist/core/index.js +3 -3
  15. package/dist/core/ingestion.d.ts +1 -16
  16. package/dist/core/ingestion.js +1 -30
  17. package/dist/core/interfaces.d.ts +1 -1
  18. package/dist/core/interfaces.js +1 -1
  19. package/dist/core/model-registry.d.ts +0 -4
  20. package/dist/core/model-registry.js +5 -9
  21. package/dist/core/search.d.ts +2 -2
  22. package/dist/core/search.js +2 -2
  23. package/dist/factories/index.d.ts +11 -29
  24. package/dist/factories/index.js +12 -29
  25. package/dist/factories/ingestion-factory.d.ts +200 -0
  26. package/dist/factories/ingestion-factory.js +475 -0
  27. package/dist/{core/polymorphic-search-factory.d.ts → factories/search-factory.d.ts} +7 -7
  28. package/dist/{core/polymorphic-search-factory.js → factories/search-factory.js} +22 -22
  29. package/dist/index-manager.js +25 -14
  30. package/dist/index.d.ts +5 -30
  31. package/dist/index.js +9 -24
  32. package/dist/indexer.js +5 -2
  33. package/dist/ingestion.d.ts +2 -4
  34. package/dist/ingestion.js +2 -2
  35. package/dist/mcp-server.js +31 -25
  36. package/dist/search.js +2 -2
  37. package/dist/text/embedder.d.ts +0 -11
  38. package/dist/text/embedder.js +11 -22
  39. package/dist/text/index.d.ts +2 -2
  40. package/dist/text/index.js +2 -2
  41. package/dist/text/reranker.d.ts +0 -10
  42. package/dist/text/reranker.js +10 -33
  43. package/package.json +7 -3
  44. package/dist/factories/polymorphic-factory.d.ts +0 -50
  45. package/dist/factories/polymorphic-factory.js +0 -159
  46. package/dist/factories/text-factory.d.ts +0 -560
  47. package/dist/factories/text-factory.js +0 -968
@@ -1,5 +1,5 @@
1
1
  import { VectorIndex } from './core/vector-index.js';
2
- import { openDatabase, getModelVersion, setModelVersion, getStoredModelInfo, setStoredModelInfo } from './core/db.js';
2
+ import { openDatabase, getSystemInfo, setSystemInfo } from './core/db.js';
3
3
  import { config, getModelDefaults } from './core/config.js';
4
4
  export class IndexManager {
5
5
  modelName;
@@ -71,15 +71,15 @@ export class IndexManager {
71
71
  }
72
72
  try {
73
73
  // Get stored model information
74
- const storedModel = await getStoredModelInfo(this.db);
74
+ const systemInfo = await getSystemInfo(this.db);
75
75
  const currentModel = this.modelName || config.embedding_model;
76
76
  const currentDefaults = getModelDefaults(currentModel);
77
- if (storedModel) {
77
+ if (systemInfo && systemInfo.modelName && systemInfo.modelDimensions) {
78
78
  // Check if models match
79
- if (storedModel.modelName !== currentModel) {
79
+ if (systemInfo.modelName !== currentModel) {
80
80
  throw new Error(`Model mismatch detected!\n` +
81
81
  `Current model: ${currentModel} (${currentDefaults.dimensions} dimensions)\n` +
82
- `Index model: ${storedModel.modelName} (${storedModel.dimensions} dimensions)\n` +
82
+ `Index model: ${systemInfo.modelName} (${systemInfo.modelDimensions} dimensions)\n` +
83
83
  `\n` +
84
84
  `The embedding model has changed since the index was created.\n` +
85
85
  `This requires a full index rebuild to maintain consistency.\n` +
@@ -91,10 +91,10 @@ export class IndexManager {
91
91
  `This will regenerate all embeddings with the new model.`);
92
92
  }
93
93
  // Check if dimensions match (additional safety check)
94
- if (storedModel.dimensions !== currentDefaults.dimensions) {
94
+ if (systemInfo.modelDimensions !== currentDefaults.dimensions) {
95
95
  throw new Error(`Model dimension mismatch detected!\n` +
96
96
  `Current model dimensions: ${currentDefaults.dimensions}\n` +
97
- `Index model dimensions: ${storedModel.dimensions}\n` +
97
+ `Index model dimensions: ${systemInfo.modelDimensions}\n` +
98
98
  `\n` +
99
99
  `This indicates a configuration inconsistency.\n` +
100
100
  `Please run: npm run rebuild`);
@@ -104,7 +104,10 @@ export class IndexManager {
104
104
  else {
105
105
  // First run - store the model info
106
106
  console.log(`No model info stored yet - storing current model info: ${currentModel}`);
107
- await setStoredModelInfo(this.db, currentModel, currentDefaults.dimensions);
107
+ await setSystemInfo(this.db, {
108
+ modelName: currentModel,
109
+ modelDimensions: currentDefaults.dimensions
110
+ });
108
111
  }
109
112
  }
110
113
  catch (error) {
@@ -228,7 +231,10 @@ export class IndexManager {
228
231
  // Store model info for the new model
229
232
  const currentModel = this.modelName || config.embedding_model;
230
233
  const currentDefaults = getModelDefaults(currentModel);
231
- await setStoredModelInfo(this.db, currentModel, currentDefaults.dimensions);
234
+ await setSystemInfo(this.db, {
235
+ modelName: currentModel,
236
+ modelDimensions: currentDefaults.dimensions
237
+ });
232
238
  await this.saveIndex();
233
239
  return;
234
240
  }
@@ -260,7 +266,10 @@ export class IndexManager {
260
266
  // Store model info for the new model
261
267
  const currentModel = this.modelName || config.embedding_model;
262
268
  const currentDefaults = getModelDefaults(currentModel);
263
- await setStoredModelInfo(this.db, currentModel, currentDefaults.dimensions);
269
+ await setSystemInfo(this.db, {
270
+ modelName: currentModel,
271
+ modelDimensions: currentDefaults.dimensions
272
+ });
264
273
  // Save the rebuilt index
265
274
  await this.saveIndex();
266
275
  console.log(`Index rebuild complete: ${vectors.length} vectors with new model version`);
@@ -278,10 +287,11 @@ export class IndexManager {
278
287
  throw new Error('Database not initialized');
279
288
  }
280
289
  try {
281
- const storedVersion = await getModelVersion(this.db);
290
+ const systemInfo = await getSystemInfo(this.db);
291
+ const storedVersion = systemInfo?.modelVersion;
282
292
  if (!storedVersion || storedVersion === "") {
283
293
  // No version stored yet, this is first run - store current version
284
- await setModelVersion(this.db, currentVersion);
294
+ await setSystemInfo(this.db, { modelVersion: currentVersion });
285
295
  console.log(`Stored initial model version: ${currentVersion}`);
286
296
  return true;
287
297
  }
@@ -307,7 +317,7 @@ export class IndexManager {
307
317
  throw new Error('Database not initialized');
308
318
  }
309
319
  try {
310
- await setModelVersion(this.db, version);
320
+ await setSystemInfo(this.db, { modelVersion: version });
311
321
  console.log(`Updated model version to: ${version}`);
312
322
  }
313
323
  catch (error) {
@@ -365,7 +375,8 @@ export class IndexManager {
365
375
  }
366
376
  const totalVectors = this.vectorIndex.getCurrentCount();
367
377
  try {
368
- const modelVersion = await getModelVersion(this.db);
378
+ const systemInfo = await getSystemInfo(this.db);
379
+ const modelVersion = systemInfo?.modelVersion || null;
369
380
  return {
370
381
  totalVectors,
371
382
  modelVersion: modelVersion || 'unknown',
package/dist/index.d.ts CHANGED
@@ -40,33 +40,8 @@
40
40
  * const search = new CoreSearchEngine(embedFn, indexManager, db);
41
41
  * ```
42
42
  */
43
- export { TextSearchFactory, TextIngestionFactory, TextRAGFactory, TextFactoryHelpers } from './factories/index.js';
44
- /**
45
- * @deprecated PolymorphicSearchFactory is no longer needed - SearchEngine now automatically
46
- * detects mode from database and adapts accordingly (Chameleon Architecture).
47
- *
48
- * Migration Guide:
49
- * ```typescript
50
- * // Old way (deprecated):
51
- * const search = await PolymorphicSearchFactory.create('./index.bin', './db.sqlite');
52
- *
53
- * // New way (recommended):
54
- * const search = new SearchEngine('./index.bin', './db.sqlite');
55
- * await search.search('query'); // Mode automatically detected
56
- * ```
57
- *
58
- * The SearchEngine constructor now uses the polymorphic factory internally,
59
- * providing the same automatic mode detection without requiring explicit factory usage.
60
- */
61
- export { PolymorphicSearchFactory } from './factories/index.js';
62
- export { TextSearchFactory as SearchFactory, TextIngestionFactory as IngestionFactory, TextRAGFactory as RAGFactory } from './factories/index.js';
63
- export type { TextSearchOptions, TextIngestionOptions } from './factories/index.js';
64
- /**
65
- * @deprecated PolymorphicSearchOptions is no longer needed - use SearchEngineOptions instead.
66
- * SearchEngine now automatically detects mode and adapts (Chameleon Architecture).
67
- */
68
- export type { PolymorphicSearchOptions } from './factories/index.js';
69
- export type { TextSearchOptions as SearchEngineOptions, TextIngestionOptions as IngestionPipelineOptions } from './factories/index.js';
43
+ export { IngestionFactory, SearchFactory } from './factories/index.js';
44
+ export type { IngestionFactoryOptions } from './factories/index.js';
70
45
  export { SearchEngine as CoreSearchEngine } from './core/search.js';
71
46
  export { IngestionPipeline as CoreIngestionPipeline } from './core/ingestion.js';
72
47
  export { SearchEngine } from './search.js';
@@ -76,15 +51,15 @@ export type { EmbedFunction, RerankFunction, EmbeddingQueryInterface, RerankingI
76
51
  export { InterfaceValidator } from './core/interfaces.js';
77
52
  export { validateModeModelCompatibility, validateModeModelCompatibilityOrThrow, getRecommendedModelsForMode, isModeModelCompatible, getCompatibleModelsForMode, type ModeModelValidationResult } from './core/mode-model-validator.js';
78
53
  export { createMissingFileError, createInvalidPathError, createModelLoadingError, createDimensionMismatchError, createModeMismatchError, createInvalidContentError, createMissingDependencyError, createFactoryCreationError, enhanceError, createContextualError, type ActionableErrorConfig } from './core/actionable-error-messages.js';
79
- export { EmbeddingEngine, getEmbeddingEngine, initializeEmbeddingEngine, createTextEmbedFunction, createTextEmbedder } from './text/embedder.js';
54
+ export { EmbeddingEngine, getEmbeddingEngine, initializeEmbeddingEngine, createTextEmbedFunction } from './text/embedder.js';
80
55
  export type { UniversalEmbedder } from './core/universal-embedder.js';
81
56
  export { CLIPEmbedder } from './multimodal/clip-embedder.js';
82
57
  export { createEmbedder } from './core/embedder-factory.js';
83
- export { CrossEncoderReranker, createTextRerankFunction, createTextReranker } from './text/reranker.js';
58
+ export { CrossEncoderReranker, createTextRerankFunction } from './text/reranker.js';
84
59
  export { countTokens } from './text/tokenizer.js';
85
60
  export type { RerankingStrategyType, RerankingConfig } from './core/reranking-config.js';
86
61
  export { validateRerankingStrategy, validateRerankingConfig, getDefaultRerankingConfig, isStrategySupported, getSupportedStrategies, RerankingConfigBuilder, DEFAULT_TEXT_RERANKING_CONFIG, DEFAULT_MULTIMODAL_RERANKING_CONFIG } from './core/reranking-config.js';
87
- export { openDatabase, initializeSchema, insertDocument, insertChunk, upsertDocument, getChunksByEmbeddingIds, getModelVersion, setModelVersion, getStoredModelInfo, setStoredModelInfo, type DatabaseConnection } from './core/db.js';
62
+ export { openDatabase, initializeSchema, insertDocument, insertChunk, upsertDocument, getChunksByEmbeddingIds, type DatabaseConnection } from './core/db.js';
88
63
  export { IndexManager } from './index-manager.js';
89
64
  export { VectorIndex } from './core/vector-index.js';
90
65
  export { config, getModelDefaults, type CoreConfig, type ExtensibleConfig, type ModelDefaults, EXIT_CODES, ConfigurationError, getDefaultModelCachePath, handleUnrecoverableError, logError } from './core/config.js';
package/dist/index.js CHANGED
@@ -44,27 +44,12 @@
44
44
  // PRIMARY API (FACTORY PATTERN)
45
45
  // =============================================================================
46
46
  // Main factory classes for simple usage
47
- export { TextSearchFactory, TextIngestionFactory, TextRAGFactory, TextFactoryHelpers } from './factories/index.js';
48
- /**
49
- * @deprecated PolymorphicSearchFactory is no longer needed - SearchEngine now automatically
50
- * detects mode from database and adapts accordingly (Chameleon Architecture).
51
- *
52
- * Migration Guide:
53
- * ```typescript
54
- * // Old way (deprecated):
55
- * const search = await PolymorphicSearchFactory.create('./index.bin', './db.sqlite');
56
- *
57
- * // New way (recommended):
58
- * const search = new SearchEngine('./index.bin', './db.sqlite');
59
- * await search.search('query'); // Mode automatically detected
60
- * ```
61
- *
62
- * The SearchEngine constructor now uses the polymorphic factory internally,
63
- * providing the same automatic mode detection without requiring explicit factory usage.
64
- */
65
- export { PolymorphicSearchFactory } from './factories/index.js';
66
- // Convenience aliases for common usage
67
- export { TextSearchFactory as SearchFactory, TextIngestionFactory as IngestionFactory, TextRAGFactory as RAGFactory } from './factories/index.js';
47
+ export { IngestionFactory, SearchFactory } from './factories/index.js';
48
+ // =============================================================================
49
+ // REMOVED IN v3.0.0: Type aliases
50
+ // =============================================================================
51
+ // IngestionPipelineOptions has been removed. Use IngestionFactoryOptions directly.
52
+ // Migration: Replace IngestionPipelineOptions with IngestionFactoryOptions
68
53
  // =============================================================================
69
54
  // CORE ARCHITECTURE (FOR LIBRARY AUTHORS)
70
55
  // =============================================================================
@@ -86,11 +71,11 @@ export { createMissingFileError, createInvalidPathError, createModelLoadingError
86
71
  // TEXT IMPLEMENTATIONS (FOR CUSTOM DEPENDENCY INJECTION)
87
72
  // =============================================================================
88
73
  // Text-specific embedding implementations
89
- export { EmbeddingEngine, getEmbeddingEngine, initializeEmbeddingEngine, createTextEmbedFunction, createTextEmbedder } from './text/embedder.js';
74
+ export { EmbeddingEngine, getEmbeddingEngine, initializeEmbeddingEngine, createTextEmbedFunction } from './text/embedder.js';
90
75
  export { CLIPEmbedder } from './multimodal/clip-embedder.js';
91
76
  export { createEmbedder } from './core/embedder-factory.js';
92
77
  // Text-specific reranking implementations
93
- export { CrossEncoderReranker, createTextRerankFunction, createTextReranker } from './text/reranker.js';
78
+ export { CrossEncoderReranker, createTextRerankFunction } from './text/reranker.js';
94
79
  // Text tokenization utilities
95
80
  export { countTokens } from './text/tokenizer.js';
96
81
  export { validateRerankingStrategy, validateRerankingConfig, getDefaultRerankingConfig, isStrategySupported, getSupportedStrategies, RerankingConfigBuilder, DEFAULT_TEXT_RERANKING_CONFIG, DEFAULT_MULTIMODAL_RERANKING_CONFIG } from './core/reranking-config.js';
@@ -98,7 +83,7 @@ export { validateRerankingStrategy, validateRerankingConfig, getDefaultReranking
98
83
  // CORE INFRASTRUCTURE (FOR ADVANCED USERS)
99
84
  // =============================================================================
100
85
  // Database operations
101
- export { openDatabase, initializeSchema, insertDocument, insertChunk, upsertDocument, getChunksByEmbeddingIds, getModelVersion, setModelVersion, getStoredModelInfo, setStoredModelInfo } from './core/db.js';
86
+ export { openDatabase, initializeSchema, insertDocument, insertChunk, upsertDocument, getChunksByEmbeddingIds } from './core/db.js';
102
87
  // Vector index management
103
88
  export { IndexManager } from './index-manager.js';
104
89
  export { VectorIndex } from './core/vector-index.js';
package/dist/indexer.js CHANGED
@@ -16,11 +16,14 @@ async function main() {
16
16
  console.error(' <path> File or directory path to ingest (.md and .txt files)');
17
17
  console.error('');
18
18
  console.error('Examples:');
19
- console.error(' node indexer.js ./docs/ # Ingest all .md/.txt files in docs/');
19
+ console.error(' node indexer.js ./docs/ # Ingest all .md/.txt/.pdf/.docs files in docs/');
20
20
  console.error(' node indexer.js ./readme.md # Ingest single file');
21
21
  console.error(' node indexer.js ../project/docs/ # Ingest from parent directory');
22
22
  console.error('');
23
- console.error('Supported file types: .md (Markdown), .txt (Plain text)');
23
+ console.error('Supported file types:');
24
+ console.error(' Text: .md, .txt, .mdx');
25
+ console.error(' Documents: .pdf, .docx');
26
+ console.error(' Images (multimodal mode): .jpg, .jpeg, .png, .gif, .webp, .bmp');
24
27
  console.error('');
25
28
  console.error('After ingestion, use: node search.js "your query"');
26
29
  process.exit(EXIT_CODES.INVALID_ARGUMENTS);
@@ -17,11 +17,9 @@
17
17
  * });
18
18
  * ```
19
19
  */
20
- import { type TextIngestionOptions } from './factories/index.js';
20
+ import { type IngestionFactoryOptions } from './factories/index.js';
21
21
  import type { IngestionOptions, IngestionResult } from './core/ingestion.js';
22
22
  import type { MemoryContentMetadata } from './core/content-manager.js';
23
- export interface IngestionPipelineOptions extends TextIngestionOptions {
24
- }
25
23
  export declare class IngestionPipeline {
26
24
  private dbPath;
27
25
  private indexPath;
@@ -29,7 +27,7 @@ export declare class IngestionPipeline {
29
27
  private corePipeline;
30
28
  private initPromise;
31
29
  private defaultChunkConfig;
32
- constructor(dbPath: string, indexPath: string, options?: IngestionPipelineOptions);
30
+ constructor(dbPath: string, indexPath: string, options?: IngestionFactoryOptions);
33
31
  /**
34
32
  * Initialize the ingestion pipeline using the factory
35
33
  */
package/dist/ingestion.js CHANGED
@@ -17,7 +17,7 @@
17
17
  * });
18
18
  * ```
19
19
  */
20
- import { TextIngestionFactory } from './factories/index.js';
20
+ import { IngestionFactory } from './factories/index.js';
21
21
  export class IngestionPipeline {
22
22
  dbPath;
23
23
  indexPath;
@@ -52,7 +52,7 @@ export class IngestionPipeline {
52
52
  return this.initPromise; // Initialization in progress
53
53
  }
54
54
  this.initPromise = (async () => {
55
- this.corePipeline = await TextIngestionFactory.create(this.dbPath, this.indexPath, this.options);
55
+ this.corePipeline = await IngestionFactory.create(this.dbPath, this.indexPath, this.options);
56
56
  })();
57
57
  return this.initPromise;
58
58
  }
@@ -26,9 +26,9 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
26
26
  import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
27
27
  import { existsSync, statSync } from 'fs';
28
28
  import { resolve } from 'path';
29
- import { PolymorphicSearchFactory } from './core/polymorphic-search-factory.js';
30
- import { TextIngestionFactory } from './factories/text-factory.js';
31
- import { openDatabase } from './core/db.js';
29
+ import { SearchFactory } from './factories/search-factory.js';
30
+ import { IngestionFactory } from './factories/ingestion-factory.js';
31
+ import { openDatabase, getSystemInfo } from './core/db.js';
32
32
  import { DatabaseConnectionManager } from './core/database-connection-manager.js';
33
33
  import { config, validateCoreConfig, ConfigurationError } from './core/config.js';
34
34
  /**
@@ -501,16 +501,23 @@ class RagLiteMCPServer {
501
501
  catch (error) {
502
502
  throw new Error(`Cannot access path: ${args.path}. Check permissions.`);
503
503
  }
504
- // Validate file type for single files
504
+ // Validate mode parameter
505
+ const mode = args.mode || 'text';
506
+ // Validate file type for single files (only formats with actual processing implementations)
505
507
  if (stats.isFile()) {
506
- const validExtensions = ['.md', '.txt'];
508
+ const textExtensions = ['.md', '.txt', '.mdx', '.pdf', '.docx'];
509
+ const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'];
510
+ const validExtensions = mode === 'multimodal'
511
+ ? [...textExtensions, ...imageExtensions]
512
+ : textExtensions;
507
513
  const hasValidExtension = validExtensions.some(ext => args.path.toLowerCase().endsWith(ext));
508
514
  if (!hasValidExtension) {
509
- throw new Error(`Unsupported file type: ${args.path}. Supported types: .md, .txt`);
515
+ const supportedTypes = mode === 'multimodal'
516
+ ? '.md, .txt, .mdx, .pdf, .docx, .jpg, .jpeg, .png, .gif, .webp, .bmp'
517
+ : '.md, .txt, .mdx, .pdf, .docx';
518
+ throw new Error(`Unsupported file type: ${args.path}. Supported types: ${supportedTypes}`);
510
519
  }
511
520
  }
512
- // Validate mode parameter
513
- const mode = args.mode || 'text';
514
521
  if (!['text', 'multimodal'].includes(mode)) {
515
522
  throw new Error(`Invalid mode: ${mode}. Supported modes: text, multimodal`);
516
523
  }
@@ -561,8 +568,8 @@ class RagLiteMCPServer {
561
568
  factoryOptions.forceRebuild = true;
562
569
  }
563
570
  // Create and run ingestion pipeline using text factory
564
- // The TextIngestionFactory already supports mode and reranking strategy parameters
565
- const pipeline = await TextIngestionFactory.create(config.db_file, config.index_file, factoryOptions);
571
+ // The IngestionFactory already supports mode and reranking strategy parameters
572
+ const pipeline = await IngestionFactory.create(config.db_file, config.index_file, factoryOptions);
566
573
  try {
567
574
  const result = await pipeline.ingestPath(resolvedPath);
568
575
  // Reset search engine initialization flag since index may have changed
@@ -585,8 +592,8 @@ class RagLiteMCPServer {
585
592
  chunks_per_second: result.processingTimeMs > 0 ?
586
593
  Math.round(result.chunksCreated / (result.processingTimeMs / 1000) * 100) / 100 : 0,
587
594
  supported_file_types: mode === 'multimodal'
588
- ? ['md', 'txt', 'jpg', 'jpeg', 'png', 'gif', 'webp']
589
- : ['md', 'txt'],
595
+ ? ['md', 'txt', 'mdx', 'pdf', 'docx', 'jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp']
596
+ : ['md', 'txt', 'mdx', 'pdf', 'docx'],
590
597
  success: true
591
598
  };
592
599
  return {
@@ -820,7 +827,7 @@ class RagLiteMCPServer {
820
827
  factoryOptions.rerankingStrategy = 'text-derived'; // Default for multimodal
821
828
  }
822
829
  // Create and run ingestion pipeline
823
- const pipeline = await TextIngestionFactory.create(config.db_file, config.index_file, factoryOptions);
830
+ const pipeline = await IngestionFactory.create(config.db_file, config.index_file, factoryOptions);
824
831
  try {
825
832
  const result = await pipeline.ingestFile(resolvedPath);
826
833
  // Reset search engine initialization flag since index may have changed
@@ -907,7 +914,7 @@ class RagLiteMCPServer {
907
914
  async handleRebuildIndex(_args) {
908
915
  try {
909
916
  // Create ingestion pipeline with force rebuild using factory
910
- const pipeline = await TextIngestionFactory.create(config.db_file, config.index_file, { forceRebuild: true });
917
+ const pipeline = await IngestionFactory.create(config.db_file, config.index_file, { forceRebuild: true });
911
918
  try {
912
919
  // Get all documents from database and re-ingest them
913
920
  const db = await openDatabase(config.db_file);
@@ -988,7 +995,6 @@ class RagLiteMCPServer {
988
995
  };
989
996
  // Get model information and compatibility status
990
997
  const { getModelDefaults } = await import('./config.js');
991
- const { getStoredModelInfo } = await import('./core/db.js');
992
998
  const currentModel = config.embedding_model;
993
999
  const currentDefaults = getModelDefaults(currentModel);
994
1000
  stats.model_info = {
@@ -1005,13 +1011,13 @@ class RagLiteMCPServer {
1005
1011
  try {
1006
1012
  const db = await openDatabase(config.db_file);
1007
1013
  try {
1008
- const storedModel = await getStoredModelInfo(db);
1009
- if (storedModel) {
1010
- stats.model_info.stored_model = storedModel.modelName;
1011
- stats.model_info.stored_dimensions = storedModel.dimensions;
1014
+ const systemInfo = await getSystemInfo(db);
1015
+ if (systemInfo && systemInfo.modelName && systemInfo.modelDimensions) {
1016
+ stats.model_info.stored_model = systemInfo.modelName;
1017
+ stats.model_info.stored_dimensions = systemInfo.modelDimensions;
1012
1018
  // Check for compatibility issues
1013
- const modelMatch = storedModel.modelName === currentModel;
1014
- const dimensionMatch = storedModel.dimensions === currentDefaults.dimensions;
1019
+ const modelMatch = systemInfo.modelName === currentModel;
1020
+ const dimensionMatch = systemInfo.modelDimensions === currentDefaults.dimensions;
1015
1021
  stats.model_info.compatibility = {
1016
1022
  model_matches: modelMatch,
1017
1023
  dimensions_match: dimensionMatch,
@@ -1132,7 +1138,7 @@ class RagLiteMCPServer {
1132
1138
  text_search: true,
1133
1139
  image_search: false,
1134
1140
  multimodal_reranking: false,
1135
- supported_file_types: ['md', 'txt']
1141
+ supported_file_types: ['md', 'txt', 'mdx', 'pdf', 'docx']
1136
1142
  };
1137
1143
  }
1138
1144
  else if (systemInfo.mode === 'multimodal') {
@@ -1140,7 +1146,7 @@ class RagLiteMCPServer {
1140
1146
  text_search: true,
1141
1147
  image_search: true,
1142
1148
  multimodal_reranking: true,
1143
- supported_file_types: ['md', 'txt', 'jpg', 'png', 'gif', 'webp']
1149
+ supported_file_types: ['md', 'txt', 'mdx', 'pdf', 'docx', 'jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp']
1144
1150
  };
1145
1151
  }
1146
1152
  }
@@ -1565,10 +1571,10 @@ class RagLiteMCPServer {
1565
1571
  try {
1566
1572
  // Validate configuration
1567
1573
  validateCoreConfig(config);
1568
- // Create search engine using PolymorphicSearchFactory (auto-detects mode)
1574
+ // Create search engine using SearchFactory (auto-detects mode)
1569
1575
  // This will automatically detect the mode from the database and create the appropriate engine
1570
1576
  console.error('🎭 MCP Server: Initializing search engine with automatic mode detection...');
1571
- this.searchEngine = await PolymorphicSearchFactory.create(config.index_file, config.db_file);
1577
+ this.searchEngine = await SearchFactory.create(config.index_file, config.db_file);
1572
1578
  // Log successful initialization with mode information
1573
1579
  const stats = await this.searchEngine.getStats();
1574
1580
  // Try to get mode information for enhanced logging
package/dist/search.js CHANGED
@@ -99,8 +99,8 @@ export class SearchEngine {
99
99
  // Use core polymorphic factory for automatic mode detection (Chameleon Architecture)
100
100
  // This enables SearchEngine to automatically adapt to text or multimodal mode
101
101
  // based on the configuration stored in the database during ingestion
102
- const { PolymorphicSearchFactory } = await import('./core/polymorphic-search-factory.js');
103
- this.coreEngine = await PolymorphicSearchFactory.create(this.indexPath, this.dbPath);
102
+ const { SearchFactory } = await import('./factories/search-factory.js');
103
+ this.coreEngine = await SearchFactory.create(this.indexPath, this.dbPath);
104
104
  }
105
105
  })();
106
106
  return this.initPromise;
@@ -108,15 +108,4 @@ export declare function initializeEmbeddingEngine(modelName?: string, batchSize?
108
108
  * @returns EmbedFunction that can be injected into core components
109
109
  */
110
110
  export declare function createTextEmbedFunction(modelName?: string, batchSize?: number): EmbedFunction;
111
- /**
112
- * Create a text embedding engine factory function
113
- * @param modelName - Optional model name override
114
- * @param batchSize - Optional batch size override
115
- * @returns Factory function that creates initialized embedding engines
116
- */
117
- export declare function createTextEmbedder(modelName?: string, batchSize?: number): {
118
- embedSingle(text: string): Promise<EmbeddingResult>;
119
- embedBatch(texts: string[]): Promise<EmbeddingResult[]>;
120
- embedDocumentBatch(chunks: string[]): Promise<EmbeddingResult[]>;
121
- };
122
111
  //# sourceMappingURL=embedder.d.ts.map
@@ -372,26 +372,15 @@ export function createTextEmbedFunction(modelName, batchSize) {
372
372
  };
373
373
  return embedFunction;
374
374
  }
375
- /**
376
- * Create a text embedding engine factory function
377
- * @param modelName - Optional model name override
378
- * @param batchSize - Optional batch size override
379
- * @returns Factory function that creates initialized embedding engines
380
- */
381
- export function createTextEmbedder(modelName, batchSize) {
382
- return {
383
- async embedSingle(text) {
384
- const engine = await initializeEmbeddingEngine(modelName, batchSize);
385
- return engine.embedSingle(text);
386
- },
387
- async embedBatch(texts) {
388
- const engine = await initializeEmbeddingEngine(modelName, batchSize);
389
- return engine.embedBatch(texts);
390
- },
391
- async embedDocumentBatch(chunks) {
392
- const engine = await initializeEmbeddingEngine(modelName, batchSize);
393
- return engine.embedDocumentBatch(chunks);
394
- }
395
- };
396
- }
375
+ // =============================================================================
376
+ // REMOVED: createTextEmbedder() factory object
377
+ // =============================================================================
378
+ // The createTextEmbedder() function has been removed as it was redundant.
379
+ // It was just a wrapper around initializeEmbeddingEngine() that provided no
380
+ // additional value over using the engine directly or using createEmbedder().
381
+ //
382
+ // Migration guide:
383
+ // - For public API: Use createEmbedder() from core/embedder-factory.ts
384
+ // - For dependency injection: Use createTextEmbedFunction()
385
+ // - For direct access: Use initializeEmbeddingEngine() or new EmbeddingEngine()
397
386
  //# sourceMappingURL=embedder.js.map
@@ -1,5 +1,5 @@
1
- export { EmbeddingEngine, getEmbeddingEngine, initializeEmbeddingEngine, createTextEmbedFunction, createTextEmbedder } from './embedder.js';
2
- export { CrossEncoderReranker, createTextRerankFunction, createTextReranker } from './reranker.js';
1
+ export { EmbeddingEngine, getEmbeddingEngine, initializeEmbeddingEngine, createTextEmbedFunction } from './embedder.js';
2
+ export { CrossEncoderReranker, createTextRerankFunction } from './reranker.js';
3
3
  export { countTokens, getTokenizer, resetTokenizer } from './tokenizer.js';
4
4
  export { chunkDocument, type Chunk, type Document } from '../core/chunker.js';
5
5
  export { type ChunkConfig } from '../core/chunker.js';
@@ -1,6 +1,6 @@
1
1
  // Text implementation layer exports
2
- export { EmbeddingEngine, getEmbeddingEngine, initializeEmbeddingEngine, createTextEmbedFunction, createTextEmbedder } from './embedder.js';
3
- export { CrossEncoderReranker, createTextRerankFunction, createTextReranker } from './reranker.js';
2
+ export { EmbeddingEngine, getEmbeddingEngine, initializeEmbeddingEngine, createTextEmbedFunction } from './embedder.js';
3
+ export { CrossEncoderReranker, createTextRerankFunction } from './reranker.js';
4
4
  export { countTokens, getTokenizer, resetTokenizer } from './tokenizer.js';
5
5
  export { chunkDocument } from '../core/chunker.js';
6
6
  export { SentenceTransformerEmbedder } from './sentence-transformer-embedder.js';
@@ -46,14 +46,4 @@ export declare class CrossEncoderReranker {
46
46
  private simpleTextReranking;
47
47
  }
48
48
  export declare function createTextRerankFunction(modelName?: string): RerankFunction;
49
- /**
50
- * Create a text reranker factory function
51
- * @param modelName - Optional model name override
52
- * @returns Factory function that creates initialized rerankers
53
- */
54
- export declare function createTextReranker(modelName?: string): {
55
- rerank(query: string, results: SearchResult[]): Promise<SearchResult[]>;
56
- loadModel(): Promise<void>;
57
- isLoaded(): boolean;
58
- };
59
49
  //# sourceMappingURL=reranker.d.ts.map
@@ -261,37 +261,14 @@ export function createTextRerankFunction(modelName) {
261
261
  };
262
262
  return rerankFunction;
263
263
  }
264
- /**
265
- * Create a text reranker factory function
266
- * @param modelName - Optional model name override
267
- * @returns Factory function that creates initialized rerankers
268
- */
269
- export function createTextReranker(modelName) {
270
- return {
271
- async rerank(query, results) {
272
- const reranker = new CrossEncoderReranker();
273
- if (modelName) {
274
- reranker.modelName = modelName;
275
- }
276
- await reranker.loadModel();
277
- if (!reranker.isLoaded()) {
278
- console.warn('Text reranker not loaded, returning results unchanged');
279
- return results;
280
- }
281
- return reranker.rerank(query, results);
282
- },
283
- async loadModel() {
284
- const reranker = new CrossEncoderReranker();
285
- if (modelName) {
286
- reranker.modelName = modelName;
287
- }
288
- await reranker.loadModel();
289
- },
290
- isLoaded() {
291
- // For the factory version, we create new instances each time
292
- // so we can't track loaded state
293
- return true;
294
- }
295
- };
296
- }
264
+ // =============================================================================
265
+ // REMOVED IN v3.0.0: createTextReranker() factory object
266
+ // =============================================================================
267
+ // The createTextReranker() function has been removed as it was redundant.
268
+ // It was just a wrapper that created new CrossEncoderReranker instances.
269
+ //
270
+ // Migration guide:
271
+ // - For public API: Use createReranker() from core/reranking-factory.ts
272
+ // - For dependency injection: Use createTextRerankFunction()
273
+ // - For direct access: Use new CrossEncoderReranker() directly
297
274
  //# sourceMappingURL=reranker.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rag-lite-ts",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Local-first TypeScript retrieval engine with Chameleon Multimodal Architecture for semantic search over text and image content",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,12 +31,16 @@
31
31
  "build:test": "tsc --project tsconfig.test.json",
32
32
  "clean": "rimraf dist",
33
33
  "dev": "tsc --watch",
34
- "test": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/core dist/__tests__/text dist/__tests__/preprocessors",
35
- "test:verbose": "npm run build:test && node --expose-gc --test --test-concurrency=1 --test-reporter=tap dist/__tests__/core dist/__tests__/text dist/__tests__/preprocessors",
34
+ "test": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/core dist/__tests__/text dist/__tests__/preprocessors dist/__tests__/cli dist/__tests__/factories",
35
+ "test:verbose": "npm run build:test && node --expose-gc --test --test-concurrency=1 --test-reporter=tap dist/__tests__/core dist/__tests__/text dist/__tests__/preprocessors dist/__tests__/cli dist/__tests__/factories",
36
36
  "test:core": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/core",
37
37
  "test:core:verbose": "npm run build:test && node --expose-gc --test --test-concurrency=1 --test-reporter=tap dist/__tests__/core",
38
38
  "test:text": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/text",
39
39
  "test:preprocessors": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/preprocessors",
40
+ "test:cli": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/cli",
41
+ "test:factories": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/factories",
42
+ "test:datasets": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/datasets",
43
+ "test:unit": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/core dist/__tests__/text dist/__tests__/preprocessors dist/__tests__/cli dist/__tests__/factories",
40
44
  "test:integration": "npm run build && npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__/integration",
41
45
  "test:integration:verbose": "npm run build && npm run build:test && node --expose-gc --test --test-concurrency=1 --test-reporter=tap dist/__tests__/integration",
42
46
  "test:all": "npm run build:test && node --expose-gc --test --test-concurrency=1 dist/__tests__",