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,152 @@
1
+ /**
2
+ * CORE MODULE โ€” Lazy Dependency Loading System
3
+ * Implements dynamic imports for multimodal-specific dependencies
4
+ * Ensures text mode performance is not impacted by multimodal code
5
+ *
6
+ * Requirements: 9.2 - Lazy loading for multimodal dependencies
7
+ */
8
+ import '../dom-polyfills.js';
9
+ import type { UniversalEmbedder } from './universal-embedder.js';
10
+ import type { RerankFunction } from './interfaces.js';
11
+ /**
12
+ * Lazy loader for embedder implementations
13
+ * Only loads the specific embedder type when needed
14
+ */
15
+ export declare class LazyEmbedderLoader {
16
+ private static cache;
17
+ /**
18
+ * Lazily load and create a sentence transformer embedder
19
+ * Only imports the module when actually needed for text mode
20
+ */
21
+ static loadSentenceTransformerEmbedder(modelName: string, options?: any): Promise<UniversalEmbedder>;
22
+ /**
23
+ * Lazily load and create a CLIP embedder
24
+ * Only imports the module when actually needed for multimodal mode
25
+ */
26
+ static loadCLIPEmbedder(modelName: string, options?: any): Promise<UniversalEmbedder>;
27
+ /**
28
+ * Check if an embedder is already loaded in cache
29
+ */
30
+ static isEmbedderLoaded(modelName: string, modelType: 'sentence-transformer' | 'clip'): boolean;
31
+ /**
32
+ * Remove an embedder from the cache (called when embedder is cleaned up)
33
+ */
34
+ static removeEmbedderFromCache(modelName: string, modelType: 'sentence-transformer' | 'clip'): void;
35
+ /**
36
+ * Get statistics about loaded embedders
37
+ */
38
+ static getLoadingStats(): {
39
+ loadedEmbedders: string[];
40
+ totalLoaded: number;
41
+ textEmbedders: number;
42
+ multimodalEmbedders: number;
43
+ };
44
+ }
45
+ /**
46
+ * Lazy loader for reranking implementations
47
+ * Only loads the specific reranker type when needed
48
+ */
49
+ export declare class LazyRerankerLoader {
50
+ private static cache;
51
+ /**
52
+ * Lazily load text reranker (cross-encoder)
53
+ * Always available for both text and multimodal modes
54
+ */
55
+ static loadTextReranker(): Promise<RerankFunction>;
56
+ /**
57
+ * Lazily load text-derived reranker for multimodal mode
58
+ * Only imports multimodal-specific dependencies when needed
59
+ */
60
+ static loadTextDerivedReranker(): Promise<RerankFunction>;
61
+ /**
62
+ * Lazily load metadata-based reranker for multimodal mode
63
+ * Only imports when specifically needed
64
+ */
65
+ static loadMetadataReranker(): Promise<RerankFunction>;
66
+ /**
67
+ * Lazily load hybrid reranker for multimodal mode
68
+ * Combines multiple reranking strategies (uses text-derived for now)
69
+ */
70
+ static loadHybridReranker(): Promise<RerankFunction>;
71
+ /**
72
+ * Check if a reranker is already loaded in cache
73
+ */
74
+ static isRerankerLoaded(strategy: string): boolean;
75
+ /**
76
+ * Get statistics about loaded rerankers
77
+ */
78
+ static getLoadingStats(): {
79
+ loadedRerankers: string[];
80
+ totalLoaded: number;
81
+ textRerankers: number;
82
+ multimodalRerankers: number;
83
+ };
84
+ }
85
+ /**
86
+ * Lazy loader for multimodal content processing
87
+ * Only loads image processing dependencies when needed
88
+ */
89
+ export declare class LazyMultimodalLoader {
90
+ private static cache;
91
+ /**
92
+ * Lazily load image-to-text processing capabilities
93
+ * Only imports when multimodal content processing is needed
94
+ */
95
+ static loadImageToTextProcessor(modelName?: string): Promise<any>;
96
+ /**
97
+ * Lazily load image metadata extraction capabilities
98
+ * Only imports Sharp when image metadata processing is needed
99
+ */
100
+ static loadImageMetadataExtractor(): Promise<any>;
101
+ /**
102
+ * Check if multimodal processing capabilities are loaded
103
+ */
104
+ static getMultimodalLoadingStatus(): {
105
+ imageToTextLoaded: boolean;
106
+ metadataExtractorLoaded: boolean;
107
+ loadedProcessors: string[];
108
+ };
109
+ }
110
+ /**
111
+ * Unified interface for all lazy loading operations
112
+ * Provides a single entry point for dependency management
113
+ */
114
+ export declare class LazyDependencyManager {
115
+ /**
116
+ * Load embedder based on model type with lazy loading
117
+ */
118
+ static loadEmbedder(modelName: string, modelType: 'sentence-transformer' | 'clip', options?: any): Promise<UniversalEmbedder>;
119
+ /**
120
+ * Load reranker based on strategy with lazy loading
121
+ */
122
+ static loadReranker(strategy: string): Promise<RerankFunction | undefined>;
123
+ /**
124
+ * Get comprehensive loading statistics
125
+ */
126
+ static getLoadingStatistics(): {
127
+ embedders: ReturnType<typeof LazyEmbedderLoader.getLoadingStats>;
128
+ rerankers: ReturnType<typeof LazyRerankerLoader.getLoadingStats>;
129
+ multimodal: ReturnType<typeof LazyMultimodalLoader.getMultimodalLoadingStatus>;
130
+ totalModulesLoaded: number;
131
+ memoryImpact: 'low' | 'medium' | 'high';
132
+ };
133
+ /**
134
+ * Clear all cached modules (for testing or memory management)
135
+ */
136
+ static clearCache(): void;
137
+ /**
138
+ * Check if system is running in text-only mode (no multimodal dependencies loaded)
139
+ */
140
+ static isTextOnlyMode(): boolean;
141
+ /**
142
+ * Get performance impact assessment
143
+ */
144
+ static getPerformanceImpact(): {
145
+ mode: 'text-only' | 'multimodal';
146
+ startupTime: 'fast' | 'medium' | 'slow';
147
+ memoryUsage: 'low' | 'medium' | 'high';
148
+ recommendations: string[];
149
+ };
150
+ }
151
+ export default LazyDependencyManager;
152
+ //# sourceMappingURL=lazy-dependency-loader.d.ts.map
@@ -0,0 +1,453 @@
1
+ /**
2
+ * CORE MODULE โ€” Lazy Dependency Loading System
3
+ * Implements dynamic imports for multimodal-specific dependencies
4
+ * Ensures text mode performance is not impacted by multimodal code
5
+ *
6
+ * Requirements: 9.2 - Lazy loading for multimodal dependencies
7
+ */
8
+ // Ensure DOM polyfills are set up before any transformers.js usage
9
+ import '../dom-polyfills.js';
10
+ import { handleError, ErrorCategory, ErrorSeverity, createError } from './error-handler.js';
11
+ // =============================================================================
12
+ // LAZY LOADING CACHE
13
+ // =============================================================================
14
+ /**
15
+ * Cache for loaded modules to avoid repeated imports
16
+ */
17
+ class LazyLoadingCache {
18
+ static instance;
19
+ loadedModules = new Map();
20
+ loadingPromises = new Map();
21
+ static getInstance() {
22
+ if (!LazyLoadingCache.instance) {
23
+ LazyLoadingCache.instance = new LazyLoadingCache();
24
+ }
25
+ return LazyLoadingCache.instance;
26
+ }
27
+ async getOrLoad(key, loader) {
28
+ // Return cached module if available
29
+ if (this.loadedModules.has(key)) {
30
+ return this.loadedModules.get(key);
31
+ }
32
+ // Return existing loading promise if in progress
33
+ if (this.loadingPromises.has(key)) {
34
+ return this.loadingPromises.get(key);
35
+ }
36
+ // Start loading and cache the promise
37
+ const loadingPromise = loader().then(module => {
38
+ this.loadedModules.set(key, module);
39
+ this.loadingPromises.delete(key);
40
+ return module;
41
+ }).catch(error => {
42
+ this.loadingPromises.delete(key);
43
+ throw error;
44
+ });
45
+ this.loadingPromises.set(key, loadingPromise);
46
+ return loadingPromise;
47
+ }
48
+ clear() {
49
+ this.loadedModules.clear();
50
+ this.loadingPromises.clear();
51
+ }
52
+ remove(key) {
53
+ this.loadedModules.delete(key);
54
+ this.loadingPromises.delete(key);
55
+ }
56
+ getLoadedModules() {
57
+ return Array.from(this.loadedModules.keys());
58
+ }
59
+ }
60
+ // =============================================================================
61
+ // LAZY EMBEDDER LOADING
62
+ // =============================================================================
63
+ /**
64
+ * Lazy loader for embedder implementations
65
+ * Only loads the specific embedder type when needed
66
+ */
67
+ export class LazyEmbedderLoader {
68
+ static cache = LazyLoadingCache.getInstance();
69
+ /**
70
+ * Lazily load and create a sentence transformer embedder
71
+ * Only imports the module when actually needed for text mode
72
+ */
73
+ static async loadSentenceTransformerEmbedder(modelName, options = {}) {
74
+ const cacheKey = `sentence-transformer:${modelName}`;
75
+ return this.cache.getOrLoad(cacheKey, async () => {
76
+ try {
77
+ console.log(`๐Ÿ”„ Lazy loading sentence transformer embedder: ${modelName}`);
78
+ // Dynamic import - only loaded when text mode is used
79
+ const { SentenceTransformerEmbedder } = await import('../text/sentence-transformer-embedder.js');
80
+ const embedder = new SentenceTransformerEmbedder(modelName, options);
81
+ await embedder.loadModel();
82
+ console.log(`โœ… Sentence transformer embedder loaded: ${modelName}`);
83
+ return embedder;
84
+ }
85
+ catch (error) {
86
+ const enhancedError = createError.model(`Failed to lazy load sentence transformer embedder '${modelName}': ${error instanceof Error ? error.message : 'Unknown error'}`);
87
+ handleError(enhancedError, 'LazyEmbedderLoader', {
88
+ severity: ErrorSeverity.ERROR,
89
+ category: ErrorCategory.MODEL
90
+ });
91
+ throw enhancedError;
92
+ }
93
+ });
94
+ }
95
+ /**
96
+ * Lazily load and create a CLIP embedder
97
+ * Only imports the module when actually needed for multimodal mode
98
+ */
99
+ static async loadCLIPEmbedder(modelName, options = {}) {
100
+ const cacheKey = `clip:${modelName}`;
101
+ return this.cache.getOrLoad(cacheKey, async () => {
102
+ try {
103
+ console.log(`๐Ÿ”„ Lazy loading CLIP embedder: ${modelName}`);
104
+ // Dynamic import - only loaded when multimodal mode is used
105
+ const { CLIPEmbedder } = await import('../multimodal/clip-embedder.js');
106
+ const embedder = new CLIPEmbedder(modelName, options);
107
+ await embedder.loadModel();
108
+ console.log(`โœ… CLIP embedder loaded: ${modelName}`);
109
+ return embedder;
110
+ }
111
+ catch (error) {
112
+ const enhancedError = createError.model(`Failed to lazy load CLIP embedder '${modelName}': ${error instanceof Error ? error.message : 'Unknown error'}`);
113
+ handleError(enhancedError, 'LazyEmbedderLoader', {
114
+ severity: ErrorSeverity.ERROR,
115
+ category: ErrorCategory.MODEL
116
+ });
117
+ throw enhancedError;
118
+ }
119
+ });
120
+ }
121
+ /**
122
+ * Check if an embedder is already loaded in cache
123
+ */
124
+ static isEmbedderLoaded(modelName, modelType) {
125
+ const cacheKey = `${modelType}:${modelName}`;
126
+ return this.cache.getLoadedModules().includes(cacheKey);
127
+ }
128
+ /**
129
+ * Remove an embedder from the cache (called when embedder is cleaned up)
130
+ */
131
+ static removeEmbedderFromCache(modelName, modelType) {
132
+ const cacheKey = `${modelType}:${modelName}`;
133
+ this.cache.remove(cacheKey);
134
+ console.log(`๐Ÿงน Removed embedder from cache: ${cacheKey}`);
135
+ }
136
+ /**
137
+ * Get statistics about loaded embedders
138
+ */
139
+ static getLoadingStats() {
140
+ const loadedModules = this.cache.getLoadedModules();
141
+ const textEmbedders = loadedModules.filter(key => key.startsWith('sentence-transformer:')).length;
142
+ const multimodalEmbedders = loadedModules.filter(key => key.startsWith('clip:')).length;
143
+ return {
144
+ loadedEmbedders: loadedModules,
145
+ totalLoaded: loadedModules.length,
146
+ textEmbedders,
147
+ multimodalEmbedders
148
+ };
149
+ }
150
+ }
151
+ // =============================================================================
152
+ // LAZY RERANKER LOADING
153
+ // =============================================================================
154
+ /**
155
+ * Lazy loader for reranking implementations
156
+ * Only loads the specific reranker type when needed
157
+ */
158
+ export class LazyRerankerLoader {
159
+ static cache = LazyLoadingCache.getInstance();
160
+ /**
161
+ * Lazily load text reranker (cross-encoder)
162
+ * Always available for both text and multimodal modes
163
+ */
164
+ static async loadTextReranker() {
165
+ const cacheKey = 'reranker:text';
166
+ return this.cache.getOrLoad(cacheKey, async () => {
167
+ try {
168
+ console.log('๐Ÿ”„ Lazy loading text reranker (cross-encoder)');
169
+ // Dynamic import - loaded when reranking is needed
170
+ const { createTextRerankFunction } = await import('../text/reranker.js');
171
+ const rerankFn = createTextRerankFunction();
172
+ console.log('โœ… Text reranker loaded');
173
+ return rerankFn;
174
+ }
175
+ catch (error) {
176
+ const enhancedError = createError.model(`Failed to lazy load text reranker: ${error instanceof Error ? error.message : 'Unknown error'}`);
177
+ handleError(enhancedError, 'LazyRerankerLoader', {
178
+ severity: ErrorSeverity.WARNING,
179
+ category: ErrorCategory.MODEL
180
+ });
181
+ throw enhancedError;
182
+ }
183
+ });
184
+ }
185
+ /**
186
+ * Lazily load text-derived reranker for multimodal mode
187
+ * Only imports multimodal-specific dependencies when needed
188
+ */
189
+ static async loadTextDerivedReranker() {
190
+ const cacheKey = 'reranker:text-derived';
191
+ return this.cache.getOrLoad(cacheKey, async () => {
192
+ console.log('๐Ÿ”„ Lazy loading text-derived reranker (multimodal)');
193
+ // Dynamic import - only loaded when multimodal mode uses text-derived reranking
194
+ const { TextDerivedRerankingStrategy } = await import('./reranking-strategies.js');
195
+ const reranker = new TextDerivedRerankingStrategy();
196
+ console.log('โœ… Text-derived reranker loaded');
197
+ return reranker.rerank.bind(reranker);
198
+ });
199
+ }
200
+ /**
201
+ * Lazily load metadata-based reranker for multimodal mode
202
+ * Only imports when specifically needed
203
+ */
204
+ static async loadMetadataReranker() {
205
+ const cacheKey = 'reranker:metadata';
206
+ return this.cache.getOrLoad(cacheKey, async () => {
207
+ console.log('๐Ÿ”„ Lazy loading metadata reranker (multimodal)');
208
+ // Dynamic import - only loaded when multimodal mode uses metadata reranking
209
+ const { MetadataRerankingStrategy } = await import('./reranking-strategies.js');
210
+ const reranker = new MetadataRerankingStrategy();
211
+ console.log('โœ… Metadata reranker loaded');
212
+ return reranker.rerank.bind(reranker);
213
+ });
214
+ }
215
+ /**
216
+ * Lazily load hybrid reranker for multimodal mode
217
+ * Combines multiple reranking strategies (uses text-derived for now)
218
+ */
219
+ static async loadHybridReranker() {
220
+ const cacheKey = 'reranker:hybrid';
221
+ return this.cache.getOrLoad(cacheKey, async () => {
222
+ console.log('๐Ÿ”„ Lazy loading hybrid reranker (multimodal)');
223
+ // For now, hybrid reranking uses text-derived
224
+ // TODO: Implement proper hybrid reranking in future tasks
225
+ console.log('๐Ÿ”„ Hybrid reranking not yet implemented, using text-derived');
226
+ return this.loadTextDerivedReranker();
227
+ });
228
+ }
229
+ /**
230
+ * Check if a reranker is already loaded in cache
231
+ */
232
+ static isRerankerLoaded(strategy) {
233
+ const cacheKey = `reranker:${strategy}`;
234
+ return this.cache.getLoadedModules().includes(cacheKey);
235
+ }
236
+ /**
237
+ * Get statistics about loaded rerankers
238
+ */
239
+ static getLoadingStats() {
240
+ const loadedModules = this.cache.getLoadedModules().filter(key => key.startsWith('reranker:'));
241
+ const textRerankers = loadedModules.filter(key => key === 'reranker:text').length;
242
+ const multimodalRerankers = loadedModules.filter(key => key.includes('text-derived') || key.includes('metadata') || key.includes('hybrid')).length;
243
+ return {
244
+ loadedRerankers: loadedModules,
245
+ totalLoaded: loadedModules.length,
246
+ textRerankers,
247
+ multimodalRerankers
248
+ };
249
+ }
250
+ }
251
+ // =============================================================================
252
+ // LAZY MULTIMODAL PROCESSING LOADING
253
+ // =============================================================================
254
+ /**
255
+ * Lazy loader for multimodal content processing
256
+ * Only loads image processing dependencies when needed
257
+ */
258
+ export class LazyMultimodalLoader {
259
+ static cache = LazyLoadingCache.getInstance();
260
+ /**
261
+ * Lazily load image-to-text processing capabilities
262
+ * Only imports when multimodal content processing is needed
263
+ */
264
+ static async loadImageToTextProcessor(modelName = 'Xenova/vit-gpt2-image-captioning') {
265
+ const cacheKey = `image-to-text:${modelName}`;
266
+ return this.cache.getOrLoad(cacheKey, async () => {
267
+ try {
268
+ console.log(`๐Ÿ”„ Lazy loading image-to-text processor: ${modelName}`);
269
+ // Dynamic import - only loaded when multimodal content processing is needed
270
+ const { pipeline } = await import('@huggingface/transformers');
271
+ const processor = await pipeline('image-to-text', modelName, {
272
+ progress_callback: (progress) => {
273
+ if (progress.status === 'downloading') {
274
+ console.log(`๐Ÿ“ฅ Downloading image-to-text model: ${Math.round(progress.progress || 0)}%`);
275
+ }
276
+ }
277
+ });
278
+ console.log(`โœ… Image-to-text processor loaded: ${modelName}`);
279
+ return processor;
280
+ }
281
+ catch (error) {
282
+ const enhancedError = createError.model(`Failed to lazy load image-to-text processor '${modelName}': ${error instanceof Error ? error.message : 'Unknown error'}`);
283
+ handleError(enhancedError, 'LazyMultimodalLoader', {
284
+ severity: ErrorSeverity.ERROR,
285
+ category: ErrorCategory.MODEL
286
+ });
287
+ throw enhancedError;
288
+ }
289
+ });
290
+ }
291
+ /**
292
+ * Lazily load image metadata extraction capabilities
293
+ * Only imports Sharp when image metadata processing is needed
294
+ */
295
+ static async loadImageMetadataExtractor() {
296
+ const cacheKey = 'image-metadata-extractor';
297
+ return this.cache.getOrLoad(cacheKey, async () => {
298
+ try {
299
+ console.log('๐Ÿ”„ Lazy loading image metadata extractor (Sharp)');
300
+ // Dynamic import - only loaded when image metadata extraction is needed
301
+ // Sharp is an optional dependency for image metadata extraction
302
+ let sharp;
303
+ try {
304
+ // Use dynamic import with string to avoid TypeScript checking
305
+ sharp = await import('sharp');
306
+ }
307
+ catch (error) {
308
+ // Sharp is not available, will use fallback
309
+ throw new Error('Sharp not available for image metadata extraction');
310
+ }
311
+ console.log('โœ… Image metadata extractor loaded (Sharp)');
312
+ return sharp.default || sharp;
313
+ }
314
+ catch (error) {
315
+ console.warn(`Failed to load Sharp for image metadata extraction: ${error instanceof Error ? error.message : 'Unknown error'}`);
316
+ console.log('๐Ÿ“Š Image metadata extraction will be limited without Sharp');
317
+ // Return a fallback metadata extractor
318
+ return {
319
+ metadata: async () => ({
320
+ width: 0,
321
+ height: 0,
322
+ format: 'unknown',
323
+ size: 0
324
+ })
325
+ };
326
+ }
327
+ });
328
+ }
329
+ /**
330
+ * Check if multimodal processing capabilities are loaded
331
+ */
332
+ static getMultimodalLoadingStatus() {
333
+ const loadedModules = this.cache.getLoadedModules();
334
+ return {
335
+ imageToTextLoaded: loadedModules.some(key => key.startsWith('image-to-text:')),
336
+ metadataExtractorLoaded: loadedModules.includes('image-metadata-extractor'),
337
+ loadedProcessors: loadedModules.filter(key => key.startsWith('image-to-text:') || key === 'image-metadata-extractor')
338
+ };
339
+ }
340
+ }
341
+ // =============================================================================
342
+ // UNIFIED LAZY LOADING INTERFACE
343
+ // =============================================================================
344
+ /**
345
+ * Unified interface for all lazy loading operations
346
+ * Provides a single entry point for dependency management
347
+ */
348
+ export class LazyDependencyManager {
349
+ /**
350
+ * Load embedder based on model type with lazy loading
351
+ */
352
+ static async loadEmbedder(modelName, modelType, options = {}) {
353
+ switch (modelType) {
354
+ case 'sentence-transformer':
355
+ return LazyEmbedderLoader.loadSentenceTransformerEmbedder(modelName, options);
356
+ case 'clip':
357
+ return LazyEmbedderLoader.loadCLIPEmbedder(modelName, options);
358
+ default:
359
+ throw createError.validation(`Unsupported model type for lazy loading: ${modelType}`);
360
+ }
361
+ }
362
+ /**
363
+ * Load reranker based on strategy with lazy loading
364
+ */
365
+ static async loadReranker(strategy) {
366
+ if (strategy === 'disabled') {
367
+ return undefined;
368
+ }
369
+ switch (strategy) {
370
+ case 'cross-encoder':
371
+ return LazyRerankerLoader.loadTextReranker();
372
+ case 'text-derived':
373
+ return LazyRerankerLoader.loadTextDerivedReranker();
374
+ case 'metadata':
375
+ return LazyRerankerLoader.loadMetadataReranker();
376
+ case 'hybrid':
377
+ return LazyRerankerLoader.loadHybridReranker();
378
+ default:
379
+ throw new Error(`Unknown reranking strategy '${strategy}'. Supported strategies: cross-encoder, text-derived, metadata, hybrid, disabled`);
380
+ }
381
+ }
382
+ /**
383
+ * Get comprehensive loading statistics
384
+ */
385
+ static getLoadingStatistics() {
386
+ const embedderStats = LazyEmbedderLoader.getLoadingStats();
387
+ const rerankerStats = LazyRerankerLoader.getLoadingStats();
388
+ const multimodalStats = LazyMultimodalLoader.getMultimodalLoadingStatus();
389
+ const totalModules = embedderStats.totalLoaded + rerankerStats.totalLoaded + multimodalStats.loadedProcessors.length;
390
+ // Estimate memory impact based on loaded modules
391
+ let memoryImpact = 'low';
392
+ if (embedderStats.multimodalEmbedders > 0 || multimodalStats.imageToTextLoaded) {
393
+ memoryImpact = 'high';
394
+ }
395
+ else if (totalModules > 2) {
396
+ memoryImpact = 'medium';
397
+ }
398
+ return {
399
+ embedders: embedderStats,
400
+ rerankers: rerankerStats,
401
+ multimodal: multimodalStats,
402
+ totalModulesLoaded: totalModules,
403
+ memoryImpact
404
+ };
405
+ }
406
+ /**
407
+ * Clear all cached modules (for testing or memory management)
408
+ */
409
+ static clearCache() {
410
+ LazyLoadingCache.getInstance().clear();
411
+ console.log('๐Ÿงน Lazy loading cache cleared');
412
+ }
413
+ /**
414
+ * Check if system is running in text-only mode (no multimodal dependencies loaded)
415
+ */
416
+ static isTextOnlyMode() {
417
+ const stats = this.getLoadingStatistics();
418
+ return stats.embedders.multimodalEmbedders === 0 &&
419
+ stats.rerankers.multimodalRerankers === 0 &&
420
+ !stats.multimodal.imageToTextLoaded;
421
+ }
422
+ /**
423
+ * Get performance impact assessment
424
+ */
425
+ static getPerformanceImpact() {
426
+ const stats = this.getLoadingStatistics();
427
+ const isTextOnly = this.isTextOnlyMode();
428
+ const recommendations = [];
429
+ if (isTextOnly) {
430
+ recommendations.push('Optimal performance: Only text dependencies loaded');
431
+ }
432
+ else {
433
+ recommendations.push('Multimodal mode: Additional dependencies loaded as needed');
434
+ if (stats.embedders.multimodalEmbedders > 1) {
435
+ recommendations.push('Consider using a single multimodal model to reduce memory usage');
436
+ }
437
+ if (stats.multimodal.imageToTextLoaded && stats.multimodal.metadataExtractorLoaded) {
438
+ recommendations.push('Full multimodal processing active - expect higher memory usage');
439
+ }
440
+ }
441
+ return {
442
+ mode: isTextOnly ? 'text-only' : 'multimodal',
443
+ startupTime: stats.totalModulesLoaded === 0 ? 'fast' : stats.totalModulesLoaded < 3 ? 'medium' : 'slow',
444
+ memoryUsage: stats.memoryImpact,
445
+ recommendations
446
+ };
447
+ }
448
+ }
449
+ // =============================================================================
450
+ // DEFAULT EXPORT
451
+ // =============================================================================
452
+ export default LazyDependencyManager;
453
+ //# sourceMappingURL=lazy-dependency-loader.js.map