rag-lite-ts 1.0.2 → 2.0.0

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 (202) hide show
  1. package/README.md +606 -93
  2. package/dist/cli/indexer.js +192 -4
  3. package/dist/cli/search.js +50 -11
  4. package/dist/cli.js +183 -26
  5. package/dist/core/abstract-embedder.d.ts +125 -0
  6. package/dist/core/abstract-embedder.js +264 -0
  7. package/dist/core/actionable-error-messages.d.ts +60 -0
  8. package/dist/core/actionable-error-messages.js +397 -0
  9. package/dist/core/batch-processing-optimizer.d.ts +155 -0
  10. package/dist/core/batch-processing-optimizer.js +541 -0
  11. package/dist/core/chunker.d.ts +2 -0
  12. package/dist/core/cli-database-utils.d.ts +53 -0
  13. package/dist/core/cli-database-utils.js +239 -0
  14. package/dist/core/config.js +10 -3
  15. package/dist/core/content-errors.d.ts +111 -0
  16. package/dist/core/content-errors.js +362 -0
  17. package/dist/core/content-manager.d.ts +343 -0
  18. package/dist/core/content-manager.js +1504 -0
  19. package/dist/core/content-performance-optimizer.d.ts +150 -0
  20. package/dist/core/content-performance-optimizer.js +516 -0
  21. package/dist/core/content-resolver.d.ts +104 -0
  22. package/dist/core/content-resolver.js +285 -0
  23. package/dist/core/cross-modal-search.d.ts +164 -0
  24. package/dist/core/cross-modal-search.js +342 -0
  25. package/dist/core/database-connection-manager.d.ts +109 -0
  26. package/dist/core/database-connection-manager.js +304 -0
  27. package/dist/core/db.d.ts +141 -2
  28. package/dist/core/db.js +631 -89
  29. package/dist/core/embedder-factory.d.ts +176 -0
  30. package/dist/core/embedder-factory.js +338 -0
  31. package/dist/core/index.d.ts +3 -1
  32. package/dist/core/index.js +4 -1
  33. package/dist/core/ingestion.d.ts +85 -15
  34. package/dist/core/ingestion.js +510 -45
  35. package/dist/core/lazy-dependency-loader.d.ts +152 -0
  36. package/dist/core/lazy-dependency-loader.js +453 -0
  37. package/dist/core/mode-detection-service.d.ts +150 -0
  38. package/dist/core/mode-detection-service.js +565 -0
  39. package/dist/core/mode-model-validator.d.ts +92 -0
  40. package/dist/core/mode-model-validator.js +203 -0
  41. package/dist/core/model-registry.d.ts +120 -0
  42. package/dist/core/model-registry.js +415 -0
  43. package/dist/core/model-validator.d.ts +217 -0
  44. package/dist/core/model-validator.js +782 -0
  45. package/dist/core/polymorphic-search-factory.d.ts +154 -0
  46. package/dist/core/polymorphic-search-factory.js +344 -0
  47. package/dist/core/raglite-paths.d.ts +121 -0
  48. package/dist/core/raglite-paths.js +145 -0
  49. package/dist/core/reranking-config.d.ts +42 -0
  50. package/dist/core/reranking-config.js +156 -0
  51. package/dist/core/reranking-factory.d.ts +92 -0
  52. package/dist/core/reranking-factory.js +591 -0
  53. package/dist/core/reranking-strategies.d.ts +325 -0
  54. package/dist/core/reranking-strategies.js +720 -0
  55. package/dist/core/resource-cleanup.d.ts +163 -0
  56. package/dist/core/resource-cleanup.js +371 -0
  57. package/dist/core/resource-manager.d.ts +212 -0
  58. package/dist/core/resource-manager.js +564 -0
  59. package/dist/core/search.d.ts +28 -1
  60. package/dist/core/search.js +83 -5
  61. package/dist/core/streaming-operations.d.ts +145 -0
  62. package/dist/core/streaming-operations.js +409 -0
  63. package/dist/core/types.d.ts +3 -0
  64. package/dist/core/universal-embedder.d.ts +177 -0
  65. package/dist/core/universal-embedder.js +139 -0
  66. package/dist/core/validation-messages.d.ts +99 -0
  67. package/dist/core/validation-messages.js +334 -0
  68. package/dist/core/vector-index.js +7 -8
  69. package/dist/factories/index.d.ts +1 -1
  70. package/dist/factories/text-factory.d.ts +128 -34
  71. package/dist/factories/text-factory.js +346 -97
  72. package/dist/file-processor.d.ts +88 -2
  73. package/dist/file-processor.js +720 -17
  74. package/dist/index.d.ts +9 -0
  75. package/dist/index.js +11 -0
  76. package/dist/ingestion.d.ts +16 -0
  77. package/dist/ingestion.js +21 -0
  78. package/dist/mcp-server.d.ts +35 -3
  79. package/dist/mcp-server.js +1107 -31
  80. package/dist/multimodal/clip-embedder.d.ts +314 -0
  81. package/dist/multimodal/clip-embedder.js +945 -0
  82. package/dist/multimodal/index.d.ts +6 -0
  83. package/dist/multimodal/index.js +6 -0
  84. package/dist/run-error-recovery-tests.d.ts +7 -0
  85. package/dist/run-error-recovery-tests.js +101 -0
  86. package/dist/search.d.ts +26 -0
  87. package/dist/search.js +54 -1
  88. package/dist/test-utils.d.ts +8 -26
  89. package/dist/text/chunker.d.ts +1 -0
  90. package/dist/text/embedder.js +15 -8
  91. package/dist/text/index.d.ts +1 -0
  92. package/dist/text/index.js +1 -0
  93. package/dist/text/reranker.d.ts +1 -2
  94. package/dist/text/reranker.js +17 -47
  95. package/dist/text/sentence-transformer-embedder.d.ts +96 -0
  96. package/dist/text/sentence-transformer-embedder.js +340 -0
  97. package/dist/types.d.ts +39 -0
  98. package/dist/utils/vector-math.d.ts +31 -0
  99. package/dist/utils/vector-math.js +70 -0
  100. package/package.json +15 -3
  101. package/dist/api-errors.d.ts.map +0 -1
  102. package/dist/api-errors.js.map +0 -1
  103. package/dist/cli/indexer.d.ts.map +0 -1
  104. package/dist/cli/indexer.js.map +0 -1
  105. package/dist/cli/search.d.ts.map +0 -1
  106. package/dist/cli/search.js.map +0 -1
  107. package/dist/cli.d.ts.map +0 -1
  108. package/dist/cli.js.map +0 -1
  109. package/dist/config.d.ts.map +0 -1
  110. package/dist/config.js.map +0 -1
  111. package/dist/core/adapters.d.ts.map +0 -1
  112. package/dist/core/adapters.js.map +0 -1
  113. package/dist/core/chunker.d.ts.map +0 -1
  114. package/dist/core/chunker.js.map +0 -1
  115. package/dist/core/config.d.ts.map +0 -1
  116. package/dist/core/config.js.map +0 -1
  117. package/dist/core/db.d.ts.map +0 -1
  118. package/dist/core/db.js.map +0 -1
  119. package/dist/core/error-handler.d.ts.map +0 -1
  120. package/dist/core/error-handler.js.map +0 -1
  121. package/dist/core/index.d.ts.map +0 -1
  122. package/dist/core/index.js.map +0 -1
  123. package/dist/core/ingestion.d.ts.map +0 -1
  124. package/dist/core/ingestion.js.map +0 -1
  125. package/dist/core/interfaces.d.ts.map +0 -1
  126. package/dist/core/interfaces.js.map +0 -1
  127. package/dist/core/path-manager.d.ts.map +0 -1
  128. package/dist/core/path-manager.js.map +0 -1
  129. package/dist/core/search-example.d.ts +0 -25
  130. package/dist/core/search-example.d.ts.map +0 -1
  131. package/dist/core/search-example.js +0 -138
  132. package/dist/core/search-example.js.map +0 -1
  133. package/dist/core/search-pipeline-example.d.ts +0 -21
  134. package/dist/core/search-pipeline-example.d.ts.map +0 -1
  135. package/dist/core/search-pipeline-example.js +0 -188
  136. package/dist/core/search-pipeline-example.js.map +0 -1
  137. package/dist/core/search-pipeline.d.ts.map +0 -1
  138. package/dist/core/search-pipeline.js.map +0 -1
  139. package/dist/core/search.d.ts.map +0 -1
  140. package/dist/core/search.js.map +0 -1
  141. package/dist/core/types.d.ts.map +0 -1
  142. package/dist/core/types.js.map +0 -1
  143. package/dist/core/vector-index.d.ts.map +0 -1
  144. package/dist/core/vector-index.js.map +0 -1
  145. package/dist/dom-polyfills.d.ts.map +0 -1
  146. package/dist/dom-polyfills.js.map +0 -1
  147. package/dist/examples/clean-api-examples.d.ts +0 -44
  148. package/dist/examples/clean-api-examples.d.ts.map +0 -1
  149. package/dist/examples/clean-api-examples.js +0 -206
  150. package/dist/examples/clean-api-examples.js.map +0 -1
  151. package/dist/factories/index.d.ts.map +0 -1
  152. package/dist/factories/index.js.map +0 -1
  153. package/dist/factories/text-factory.d.ts.map +0 -1
  154. package/dist/factories/text-factory.js.map +0 -1
  155. package/dist/file-processor.d.ts.map +0 -1
  156. package/dist/file-processor.js.map +0 -1
  157. package/dist/index-manager.d.ts.map +0 -1
  158. package/dist/index-manager.js.map +0 -1
  159. package/dist/index.d.ts.map +0 -1
  160. package/dist/index.js.map +0 -1
  161. package/dist/indexer.d.ts.map +0 -1
  162. package/dist/indexer.js.map +0 -1
  163. package/dist/ingestion.d.ts.map +0 -1
  164. package/dist/ingestion.js.map +0 -1
  165. package/dist/mcp-server.d.ts.map +0 -1
  166. package/dist/mcp-server.js.map +0 -1
  167. package/dist/preprocess.d.ts.map +0 -1
  168. package/dist/preprocess.js.map +0 -1
  169. package/dist/preprocessors/index.d.ts.map +0 -1
  170. package/dist/preprocessors/index.js.map +0 -1
  171. package/dist/preprocessors/mdx.d.ts.map +0 -1
  172. package/dist/preprocessors/mdx.js.map +0 -1
  173. package/dist/preprocessors/mermaid.d.ts.map +0 -1
  174. package/dist/preprocessors/mermaid.js.map +0 -1
  175. package/dist/preprocessors/registry.d.ts.map +0 -1
  176. package/dist/preprocessors/registry.js.map +0 -1
  177. package/dist/search-standalone.d.ts.map +0 -1
  178. package/dist/search-standalone.js.map +0 -1
  179. package/dist/search.d.ts.map +0 -1
  180. package/dist/search.js.map +0 -1
  181. package/dist/test-utils.d.ts.map +0 -1
  182. package/dist/test-utils.js.map +0 -1
  183. package/dist/text/chunker.d.ts.map +0 -1
  184. package/dist/text/chunker.js.map +0 -1
  185. package/dist/text/embedder.d.ts.map +0 -1
  186. package/dist/text/embedder.js.map +0 -1
  187. package/dist/text/index.d.ts.map +0 -1
  188. package/dist/text/index.js.map +0 -1
  189. package/dist/text/preprocessors/index.d.ts.map +0 -1
  190. package/dist/text/preprocessors/index.js.map +0 -1
  191. package/dist/text/preprocessors/mdx.d.ts.map +0 -1
  192. package/dist/text/preprocessors/mdx.js.map +0 -1
  193. package/dist/text/preprocessors/mermaid.d.ts.map +0 -1
  194. package/dist/text/preprocessors/mermaid.js.map +0 -1
  195. package/dist/text/preprocessors/registry.d.ts.map +0 -1
  196. package/dist/text/preprocessors/registry.js.map +0 -1
  197. package/dist/text/reranker.d.ts.map +0 -1
  198. package/dist/text/reranker.js.map +0 -1
  199. package/dist/text/tokenizer.d.ts.map +0 -1
  200. package/dist/text/tokenizer.js.map +0 -1
  201. package/dist/types.d.ts.map +0 -1
  202. package/dist/types.js.map +0 -1
@@ -0,0 +1,154 @@
1
+ /**
2
+ * CORE MODULE — Polymorphic Search Factory for Chameleon Architecture
3
+ *
4
+ * Automatically detects mode from database and creates the appropriate search engine.
5
+ * No fallback mechanisms - each mode uses its optimal implementation reliably.
6
+ *
7
+ * Mode Behavior:
8
+ * - Text Mode: Uses sentence-transformer models for fast text-only search
9
+ * - Multimodal Mode: Uses CLIP models for cross-modal text/image search
10
+ *
11
+ * The mode is determined during ingestion and stored in the database, then
12
+ * automatically detected during search - no manual configuration needed.
13
+ */
14
+ import '../dom-polyfills.js';
15
+ import { SearchEngine } from './search.js';
16
+ import type { SystemInfo, ModeType } from '../types.js';
17
+ /**
18
+ * Factory for creating search engines with automatic mode detection
19
+ *
20
+ * Detects the mode from database configuration and creates the appropriate
21
+ * search engine without fallback mechanisms. Each mode uses its optimal
22
+ * implementation for predictable, reliable behavior.
23
+ *
24
+ * Mode Selection (configured during ingestion):
25
+ * - Text Mode: Optimized for text-only content
26
+ * - Uses sentence-transformer models
27
+ * - Fast text similarity search
28
+ * - Images converted to text descriptions
29
+ *
30
+ * - Multimodal Mode: Optimized for mixed text/image content
31
+ * - Uses CLIP models
32
+ * - Unified embedding space for text and images
33
+ * - True cross-modal search capabilities
34
+ * - Text queries find images, image queries find text
35
+ */
36
+ export declare class PolymorphicSearchFactory {
37
+ /**
38
+ * Create a SearchEngine with automatic mode detection and configuration
39
+ *
40
+ * Automatically detects the mode from database configuration and creates
41
+ * the appropriate search engine. No fallback mechanisms - each mode works
42
+ * reliably with its optimal implementation.
43
+ *
44
+ * Process:
45
+ * 1. Detects mode from database (text or multimodal)
46
+ * 2. Validates mode-model compatibility
47
+ * 3. Creates appropriate embedder (sentence-transformer or CLIP)
48
+ * 4. Creates appropriate reranker based on mode and strategy
49
+ * 5. Initializes SearchEngine with proper dependency injection
50
+ *
51
+ * Mode Behavior:
52
+ * - Text Mode: Fast text-only search with sentence-transformers
53
+ * - Optimized for text similarity
54
+ * - Optional cross-encoder reranking
55
+ *
56
+ * - Multimodal Mode: Cross-modal search with CLIP
57
+ * - Unified embedding space for text and images
58
+ * - Text queries find images, image queries find text
59
+ * - Optional text-derived or metadata reranking
60
+ *
61
+ * @param indexPath - Path to the vector index file (must exist)
62
+ * @param dbPath - Path to the SQLite database file (must exist)
63
+ * @returns Promise resolving to configured SearchEngine
64
+ * @throws {Error} If files don't exist, mode-model incompatible, or initialization fails
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * // Automatic mode detection and engine creation
69
+ * const search = await PolymorphicSearchFactory.create('./index.bin', './db.sqlite');
70
+ *
71
+ * // Search works based on detected mode:
72
+ * // Text mode: fast text similarity search
73
+ * const textResults = await search.search('machine learning');
74
+ *
75
+ * // Multimodal mode: cross-modal search
76
+ * const imageResults = await search.search('red sports car'); // Finds images
77
+ * ```
78
+ */
79
+ static create(indexPath: string, dbPath: string): Promise<SearchEngine>;
80
+ /**
81
+ * Create a search engine configured for text mode
82
+ * @private
83
+ */
84
+ private static createTextSearchEngine;
85
+ /**
86
+ * Create a search engine configured for multimodal mode
87
+ * @private
88
+ */
89
+ private static createMultimodalSearchEngine;
90
+ /**
91
+ * Create reranker for text mode using lazy loading
92
+ * @private
93
+ */
94
+ private static createTextReranker;
95
+ /**
96
+ * Create reranker for multimodal mode using lazy loading
97
+ * @private
98
+ */
99
+ private static createMultimodalReranker;
100
+ /**
101
+ * Validate that required files exist
102
+ * @private
103
+ */
104
+ private static validateRequiredFiles;
105
+ /**
106
+ * Enhance creation errors with helpful context
107
+ * @private
108
+ */
109
+ private static enhanceCreationError;
110
+ }
111
+ /**
112
+ * Quick function to create a search engine with automatic mode detection
113
+ * Convenience wrapper around PolymorphicSearchFactory.create
114
+ *
115
+ * @param indexPath - Path to the vector index file
116
+ * @param dbPath - Path to the database file
117
+ * @returns Promise resolving to configured SearchEngine
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * const search = await createPolymorphicSearchEngine('./index.bin', './db.sqlite');
122
+ * const results = await search.search('query');
123
+ * ```
124
+ */
125
+ export declare function createPolymorphicSearchEngine(indexPath: string, dbPath: string): Promise<SearchEngine>;
126
+ /**
127
+ * Check what mode a database is configured for
128
+ * Convenience function for inspecting database configuration
129
+ *
130
+ * @param dbPath - Path to the database file
131
+ * @returns Promise resolving to the detected mode
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const mode = await detectSearchEngineMode('./db.sqlite');
136
+ * console.log(`Database is configured for ${mode} mode`);
137
+ * ```
138
+ */
139
+ export declare function detectSearchEngineMode(dbPath: string): Promise<ModeType>;
140
+ /**
141
+ * Get system information for a database
142
+ * Convenience function for inspecting complete database configuration
143
+ *
144
+ * @param dbPath - Path to the database file
145
+ * @returns Promise resolving to complete SystemInfo
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * const info = await getSearchEngineInfo('./db.sqlite');
150
+ * console.log(`Mode: ${info.mode}, Model: ${info.modelName}, Dimensions: ${info.modelDimensions}`);
151
+ * ```
152
+ */
153
+ export declare function getSearchEngineInfo(dbPath: string): Promise<SystemInfo>;
154
+ //# sourceMappingURL=polymorphic-search-factory.d.ts.map
@@ -0,0 +1,344 @@
1
+ /**
2
+ * CORE MODULE — Polymorphic Search Factory for Chameleon Architecture
3
+ *
4
+ * Automatically detects mode from database and creates the appropriate search engine.
5
+ * No fallback mechanisms - each mode uses its optimal implementation reliably.
6
+ *
7
+ * Mode Behavior:
8
+ * - Text Mode: Uses sentence-transformer models for fast text-only search
9
+ * - Multimodal Mode: Uses CLIP models for cross-modal text/image search
10
+ *
11
+ * The mode is determined during ingestion and stored in the database, then
12
+ * automatically detected during search - no manual configuration needed.
13
+ */
14
+ // Ensure DOM polyfills are set up before any transformers.js usage
15
+ import '../dom-polyfills.js';
16
+ import { SearchEngine } from './search.js';
17
+ import { ModeDetectionService } from './mode-detection-service.js';
18
+ import { IndexManager } from '../index-manager.js';
19
+ import { DatabaseConnectionManager } from './database-connection-manager.js';
20
+ import { createEmbedder } from './embedder-factory.js';
21
+ import { ContentResolver } from './content-resolver.js';
22
+ import { validateModeModelCompatibilityOrThrow } from './mode-model-validator.js';
23
+ import { createMissingFileError } from './actionable-error-messages.js';
24
+ import { handleError, ErrorCategory, ErrorSeverity, createError } from './error-handler.js';
25
+ import { existsSync } from 'fs';
26
+ // =============================================================================
27
+ // POLYMORPHIC SEARCH FACTORY
28
+ // =============================================================================
29
+ /**
30
+ * Factory for creating search engines with automatic mode detection
31
+ *
32
+ * Detects the mode from database configuration and creates the appropriate
33
+ * search engine without fallback mechanisms. Each mode uses its optimal
34
+ * implementation for predictable, reliable behavior.
35
+ *
36
+ * Mode Selection (configured during ingestion):
37
+ * - Text Mode: Optimized for text-only content
38
+ * - Uses sentence-transformer models
39
+ * - Fast text similarity search
40
+ * - Images converted to text descriptions
41
+ *
42
+ * - Multimodal Mode: Optimized for mixed text/image content
43
+ * - Uses CLIP models
44
+ * - Unified embedding space for text and images
45
+ * - True cross-modal search capabilities
46
+ * - Text queries find images, image queries find text
47
+ */
48
+ export class PolymorphicSearchFactory {
49
+ /**
50
+ * Create a SearchEngine with automatic mode detection and configuration
51
+ *
52
+ * Automatically detects the mode from database configuration and creates
53
+ * the appropriate search engine. No fallback mechanisms - each mode works
54
+ * reliably with its optimal implementation.
55
+ *
56
+ * Process:
57
+ * 1. Detects mode from database (text or multimodal)
58
+ * 2. Validates mode-model compatibility
59
+ * 3. Creates appropriate embedder (sentence-transformer or CLIP)
60
+ * 4. Creates appropriate reranker based on mode and strategy
61
+ * 5. Initializes SearchEngine with proper dependency injection
62
+ *
63
+ * Mode Behavior:
64
+ * - Text Mode: Fast text-only search with sentence-transformers
65
+ * - Optimized for text similarity
66
+ * - Optional cross-encoder reranking
67
+ *
68
+ * - Multimodal Mode: Cross-modal search with CLIP
69
+ * - Unified embedding space for text and images
70
+ * - Text queries find images, image queries find text
71
+ * - Optional text-derived or metadata reranking
72
+ *
73
+ * @param indexPath - Path to the vector index file (must exist)
74
+ * @param dbPath - Path to the SQLite database file (must exist)
75
+ * @returns Promise resolving to configured SearchEngine
76
+ * @throws {Error} If files don't exist, mode-model incompatible, or initialization fails
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * // Automatic mode detection and engine creation
81
+ * const search = await PolymorphicSearchFactory.create('./index.bin', './db.sqlite');
82
+ *
83
+ * // Search works based on detected mode:
84
+ * // Text mode: fast text similarity search
85
+ * const textResults = await search.search('machine learning');
86
+ *
87
+ * // Multimodal mode: cross-modal search
88
+ * const imageResults = await search.search('red sports car'); // Finds images
89
+ * ```
90
+ */
91
+ static async create(indexPath, dbPath) {
92
+ try {
93
+ console.log('🎭 PolymorphicSearchFactory: Initializing search engine with mode detection...');
94
+ // Step 1: Validate input paths
95
+ if (!indexPath || !dbPath) {
96
+ throw createError.validation('Both indexPath and dbPath are required');
97
+ }
98
+ // Step 2: Validate that required files exist
99
+ this.validateRequiredFiles(indexPath, dbPath);
100
+ // Step 3: Get shared database connection
101
+ const db = await DatabaseConnectionManager.getConnection(dbPath);
102
+ // Step 4: Detect mode from database using shared connection
103
+ const modeService = new ModeDetectionService(dbPath);
104
+ const systemInfo = await modeService.detectMode(db);
105
+ console.log(`🎯 Detected mode: ${systemInfo.mode} (model: ${systemInfo.modelName})`);
106
+ // Step 4.5: Validate mode-model compatibility at creation time
107
+ console.log('🔍 Validating mode-model compatibility...');
108
+ validateModeModelCompatibilityOrThrow(systemInfo.mode, systemInfo.modelName);
109
+ console.log('✓ Mode-model compatibility validated');
110
+ // Step 5: Create search engine based on detected mode
111
+ switch (systemInfo.mode) {
112
+ case 'text':
113
+ return await this.createTextSearchEngine(indexPath, dbPath, systemInfo, db);
114
+ case 'multimodal':
115
+ return await this.createMultimodalSearchEngine(indexPath, dbPath, systemInfo, db);
116
+ default:
117
+ throw createError.validation(`Unsupported mode: ${systemInfo.mode}`);
118
+ }
119
+ }
120
+ catch (error) {
121
+ const enhancedError = this.enhanceCreationError(error, indexPath, dbPath);
122
+ handleError(enhancedError, 'Polymorphic Search Factory', {
123
+ severity: ErrorSeverity.ERROR,
124
+ category: ErrorCategory.GENERAL
125
+ });
126
+ throw enhancedError;
127
+ }
128
+ }
129
+ // =============================================================================
130
+ // MODE-SPECIFIC ENGINE CREATION
131
+ // =============================================================================
132
+ /**
133
+ * Create a search engine configured for text mode
134
+ * @private
135
+ */
136
+ static async createTextSearchEngine(indexPath, dbPath, systemInfo, db) {
137
+ console.log('📝 Creating text search engine...');
138
+ try {
139
+ // Step 1: Create text embedder
140
+ const embedder = await createEmbedder(systemInfo.modelName);
141
+ console.log(`✓ Text embedder created: ${systemInfo.modelName} (${systemInfo.modelDimensions}D)`);
142
+ // Step 2: Create reranker based on strategy
143
+ const rerankFn = await this.createTextReranker(systemInfo.rerankingStrategy);
144
+ if (rerankFn) {
145
+ console.log(`✓ Text reranker created: ${systemInfo.rerankingStrategy}`);
146
+ }
147
+ else {
148
+ console.log('ℹ️ Reranking disabled');
149
+ }
150
+ // Step 3: Initialize core components (using shared connection)
151
+ const indexManager = new IndexManager(indexPath, dbPath, systemInfo.modelDimensions, systemInfo.modelName);
152
+ await indexManager.initialize();
153
+ // Step 4: Create ContentResolver for unified content system
154
+ const contentResolver = new ContentResolver(db);
155
+ // Step 5: Create search engine with dependency injection
156
+ const searchEngine = new SearchEngine(embedder.embedText.bind(embedder), indexManager, db, rerankFn, contentResolver);
157
+ console.log('✅ Text search engine initialized successfully');
158
+ return searchEngine;
159
+ }
160
+ catch (error) {
161
+ throw createError.model(`Failed to create text search engine: ${error instanceof Error ? error.message : 'Unknown error'}`);
162
+ }
163
+ }
164
+ /**
165
+ * Create a search engine configured for multimodal mode
166
+ * @private
167
+ */
168
+ static async createMultimodalSearchEngine(indexPath, dbPath, systemInfo, db) {
169
+ console.log('🖼️ Creating multimodal search engine...');
170
+ try {
171
+ // Step 1: Create multimodal embedder (CLIP)
172
+ const embedder = await createEmbedder(systemInfo.modelName);
173
+ console.log(`✓ Multimodal embedder created: ${systemInfo.modelName} (${systemInfo.modelDimensions}D)`);
174
+ // Step 2: Create multimodal reranker based on strategy
175
+ const rerankFn = await this.createMultimodalReranker(systemInfo.rerankingStrategy);
176
+ if (rerankFn) {
177
+ console.log(`✓ Multimodal reranker created: ${systemInfo.rerankingStrategy}`);
178
+ }
179
+ else {
180
+ console.log('ℹ️ Reranking disabled');
181
+ }
182
+ // Step 3: Initialize core components (using shared connection)
183
+ const indexManager = new IndexManager(indexPath, dbPath, systemInfo.modelDimensions, systemInfo.modelName);
184
+ await indexManager.initialize();
185
+ // Step 4: Create ContentResolver for unified content system
186
+ const contentResolver = new ContentResolver(db);
187
+ // Step 5: Create search engine with dependency injection
188
+ const searchEngine = new SearchEngine(embedder.embedText.bind(embedder), indexManager, db, rerankFn, contentResolver);
189
+ console.log('✅ Multimodal search engine initialized successfully');
190
+ return searchEngine;
191
+ }
192
+ catch (error) {
193
+ throw createError.model(`Failed to create multimodal search engine: ${error instanceof Error ? error.message : 'Unknown error'}`);
194
+ }
195
+ }
196
+ // =============================================================================
197
+ // RERANKER CREATION FUNCTIONS
198
+ // =============================================================================
199
+ /**
200
+ * Create reranker for text mode using lazy loading
201
+ * @private
202
+ */
203
+ static async createTextReranker(strategy) {
204
+ try {
205
+ if (strategy === 'disabled') {
206
+ return undefined;
207
+ }
208
+ // Use lazy loading to avoid loading reranking dependencies unless needed
209
+ const { LazyRerankerLoader } = await import('./lazy-dependency-loader.js');
210
+ // For text mode, use cross-encoder reranking
211
+ if (strategy === 'cross-encoder') {
212
+ return LazyRerankerLoader.loadTextReranker();
213
+ }
214
+ // Fail clearly for unknown strategies in text mode
215
+ throw createError.validation(`Unknown text reranking strategy '${strategy}'. Supported strategies: cross-encoder, disabled`);
216
+ }
217
+ catch (error) {
218
+ throw createError.model(`Failed to create text reranker with strategy '${strategy}': ${error instanceof Error ? error.message : 'Unknown error'}`);
219
+ }
220
+ }
221
+ /**
222
+ * Create reranker for multimodal mode using lazy loading
223
+ * @private
224
+ */
225
+ static async createMultimodalReranker(strategy) {
226
+ try {
227
+ if (strategy === 'disabled') {
228
+ return undefined;
229
+ }
230
+ // Use lazy loading to avoid loading multimodal dependencies unless needed
231
+ const { LazyDependencyManager } = await import('./lazy-dependency-loader.js');
232
+ // Load the appropriate reranker based on strategy
233
+ return LazyDependencyManager.loadReranker(strategy);
234
+ }
235
+ catch (error) {
236
+ throw createError.model(`Failed to create multimodal reranker with strategy '${strategy}': ${error instanceof Error ? error.message : 'Unknown error'}`);
237
+ }
238
+ }
239
+ // =============================================================================
240
+ // VALIDATION AND ERROR HANDLING
241
+ // =============================================================================
242
+ /**
243
+ * Validate that required files exist
244
+ * @private
245
+ */
246
+ static validateRequiredFiles(indexPath, dbPath) {
247
+ if (!existsSync(indexPath)) {
248
+ throw createMissingFileError(indexPath, 'index', {
249
+ operationContext: 'PolymorphicSearchFactory.create'
250
+ });
251
+ }
252
+ if (!existsSync(dbPath)) {
253
+ throw createMissingFileError(dbPath, 'database', {
254
+ operationContext: 'PolymorphicSearchFactory.create'
255
+ });
256
+ }
257
+ }
258
+ /**
259
+ * Enhance creation errors with helpful context
260
+ * @private
261
+ */
262
+ static enhanceCreationError(error, indexPath, dbPath) {
263
+ if (error instanceof Error) {
264
+ // Add context about the operation that failed
265
+ let enhancedMessage = `PolymorphicSearchFactory.create failed: ${error.message}`;
266
+ // Provide specific guidance based on error type
267
+ if (error.message.includes('ENOENT')) {
268
+ enhancedMessage += '\n\n💡 Make sure both the vector index and database files exist.';
269
+ enhancedMessage += '\n Run ingestion first: raglite ingest <directory>';
270
+ }
271
+ else if (error.message.includes('SQLITE_CORRUPT')) {
272
+ enhancedMessage += '\n\n💡 Database appears to be corrupted.';
273
+ enhancedMessage += '\n Try deleting the database and re-running ingestion.';
274
+ }
275
+ else if (error.message.includes('Model') && error.message.includes('not found')) {
276
+ enhancedMessage += '\n\n💡 The model specified in the database is not supported.';
277
+ enhancedMessage += '\n Check the model name or re-run ingestion with a supported model.';
278
+ }
279
+ else if (error.message.includes('dimensions')) {
280
+ enhancedMessage += '\n\n💡 Vector dimension mismatch detected.';
281
+ enhancedMessage += '\n The index was created with a different model. Rebuild the index:';
282
+ enhancedMessage += '\n raglite ingest <directory> --force-rebuild';
283
+ }
284
+ return new Error(enhancedMessage);
285
+ }
286
+ return new Error(`PolymorphicSearchFactory.create failed: Unknown error`);
287
+ }
288
+ }
289
+ // =============================================================================
290
+ // CONVENIENCE FUNCTIONS
291
+ // =============================================================================
292
+ /**
293
+ * Quick function to create a search engine with automatic mode detection
294
+ * Convenience wrapper around PolymorphicSearchFactory.create
295
+ *
296
+ * @param indexPath - Path to the vector index file
297
+ * @param dbPath - Path to the database file
298
+ * @returns Promise resolving to configured SearchEngine
299
+ *
300
+ * @example
301
+ * ```typescript
302
+ * const search = await createPolymorphicSearchEngine('./index.bin', './db.sqlite');
303
+ * const results = await search.search('query');
304
+ * ```
305
+ */
306
+ export async function createPolymorphicSearchEngine(indexPath, dbPath) {
307
+ return PolymorphicSearchFactory.create(indexPath, dbPath);
308
+ }
309
+ /**
310
+ * Check what mode a database is configured for
311
+ * Convenience function for inspecting database configuration
312
+ *
313
+ * @param dbPath - Path to the database file
314
+ * @returns Promise resolving to the detected mode
315
+ *
316
+ * @example
317
+ * ```typescript
318
+ * const mode = await detectSearchEngineMode('./db.sqlite');
319
+ * console.log(`Database is configured for ${mode} mode`);
320
+ * ```
321
+ */
322
+ export async function detectSearchEngineMode(dbPath) {
323
+ const modeService = new ModeDetectionService(dbPath);
324
+ const systemInfo = await modeService.detectMode();
325
+ return systemInfo.mode;
326
+ }
327
+ /**
328
+ * Get system information for a database
329
+ * Convenience function for inspecting complete database configuration
330
+ *
331
+ * @param dbPath - Path to the database file
332
+ * @returns Promise resolving to complete SystemInfo
333
+ *
334
+ * @example
335
+ * ```typescript
336
+ * const info = await getSearchEngineInfo('./db.sqlite');
337
+ * console.log(`Mode: ${info.mode}, Model: ${info.modelName}, Dimensions: ${info.modelDimensions}`);
338
+ * ```
339
+ */
340
+ export async function getSearchEngineInfo(dbPath) {
341
+ const modeService = new ModeDetectionService(dbPath);
342
+ return modeService.detectMode();
343
+ }
344
+ //# sourceMappingURL=polymorphic-search-factory.js.map
@@ -0,0 +1,121 @@
1
+ /**
2
+ * RAG-lite Path Management
3
+ *
4
+ * Manages the standardized .raglite directory structure as specified in the design:
5
+ * .raglite/
6
+ * ├── db.sqlite # Database
7
+ * ├── index.bin # Vector index
8
+ * └── content/ # Content directory
9
+ */
10
+ /**
11
+ * RAG-lite directory structure configuration
12
+ */
13
+ export interface RagLiteConfig {
14
+ /** Base directory for RAG-lite files (default: current working directory) */
15
+ baseDir?: string;
16
+ /** Custom database filename (default: 'db.sqlite') */
17
+ dbFilename?: string;
18
+ /** Custom index filename (default: 'index.bin') */
19
+ indexFilename?: string;
20
+ /** Custom content directory name (default: 'content') */
21
+ contentDirname?: string;
22
+ }
23
+ /**
24
+ * Resolved RAG-lite paths
25
+ */
26
+ export interface RagLitePaths {
27
+ /** Base .raglite directory */
28
+ ragliteDir: string;
29
+ /** Database file path */
30
+ dbPath: string;
31
+ /** Vector index file path */
32
+ indexPath: string;
33
+ /** Content directory path */
34
+ contentDir: string;
35
+ }
36
+ /**
37
+ * Resolves and creates the standardized .raglite directory structure
38
+ *
39
+ * @param config - Configuration for RAG-lite paths
40
+ * @returns Resolved paths for all RAG-lite components
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * // Use default structure in current directory
45
+ * const paths = resolveRagLitePaths();
46
+ * // Results in:
47
+ * // .raglite/db.sqlite
48
+ * // .raglite/index.bin
49
+ * // .raglite/content/
50
+ *
51
+ * // Use custom base directory
52
+ * const paths = resolveRagLitePaths({ baseDir: './my-project' });
53
+ * // Results in:
54
+ * // my-project/.raglite/db.sqlite
55
+ * // my-project/.raglite/index.bin
56
+ * // my-project/.raglite/content/
57
+ * ```
58
+ */
59
+ export declare function resolveRagLitePaths(config?: RagLiteConfig): RagLitePaths;
60
+ /**
61
+ * Ensures the .raglite directory structure exists
62
+ *
63
+ * @param paths - RAG-lite paths to create
64
+ * @throws {Error} If directory creation fails
65
+ */
66
+ export declare function ensureRagLiteStructure(paths: RagLitePaths): void;
67
+ /**
68
+ * Migrates from user-specified paths to standardized .raglite structure
69
+ *
70
+ * This function helps transition from the current approach where users specify
71
+ * arbitrary paths to the standardized .raglite structure.
72
+ *
73
+ * @param userDbPath - User-specified database path
74
+ * @param userIndexPath - User-specified index path
75
+ * @param config - Configuration for the target .raglite structure
76
+ * @returns Resolved .raglite paths and migration info
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * // Migrate from user paths to .raglite structure
81
+ * const migration = migrateToRagLiteStructure('./my-db.sqlite', './my-index.bin');
82
+ *
83
+ * console.log('Target paths:', migration.paths);
84
+ * console.log('Migration needed:', migration.needsMigration);
85
+ *
86
+ * if (migration.needsMigration) {
87
+ * console.log('Files will be moved from:');
88
+ * console.log(' DB:', migration.sourceDbPath, '->', migration.paths.dbPath);
89
+ * console.log(' Index:', migration.sourceIndexPath, '->', migration.paths.indexPath);
90
+ * }
91
+ * ```
92
+ */
93
+ export declare function migrateToRagLiteStructure(userDbPath: string, userIndexPath: string, config?: RagLiteConfig): {
94
+ paths: RagLitePaths;
95
+ needsMigration: boolean;
96
+ sourceDbPath: string;
97
+ sourceIndexPath: string;
98
+ };
99
+ /**
100
+ * Gets the standardized .raglite paths for a given project directory
101
+ *
102
+ * This is the recommended way to get RAG-lite paths for new projects.
103
+ *
104
+ * @param projectDir - Project directory (default: current working directory)
105
+ * @returns Standardized RAG-lite paths
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * // For current directory
110
+ * const paths = getStandardRagLitePaths();
111
+ *
112
+ * // For specific project
113
+ * const paths = getStandardRagLitePaths('./my-project');
114
+ *
115
+ * // Use with factories
116
+ * const search = await SearchFactory.create(paths.indexPath, paths.dbPath);
117
+ * const ingestion = await IngestionFactory.create(paths.dbPath, paths.indexPath);
118
+ * ```
119
+ */
120
+ export declare function getStandardRagLitePaths(projectDir?: string): RagLitePaths;
121
+ //# sourceMappingURL=raglite-paths.d.ts.map