rag-lite-ts 1.0.2 โ 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +605 -93
- package/dist/cli/indexer.js +192 -4
- package/dist/cli/search.js +50 -11
- package/dist/cli.js +183 -26
- package/dist/core/abstract-embedder.d.ts +125 -0
- package/dist/core/abstract-embedder.js +264 -0
- package/dist/core/actionable-error-messages.d.ts +60 -0
- package/dist/core/actionable-error-messages.js +397 -0
- package/dist/core/batch-processing-optimizer.d.ts +155 -0
- package/dist/core/batch-processing-optimizer.js +541 -0
- package/dist/core/binary-index-format.d.ts +52 -0
- package/dist/core/binary-index-format.js +122 -0
- package/dist/core/chunker.d.ts +2 -0
- package/dist/core/cli-database-utils.d.ts +53 -0
- package/dist/core/cli-database-utils.js +239 -0
- package/dist/core/config.js +10 -3
- package/dist/core/content-errors.d.ts +111 -0
- package/dist/core/content-errors.js +362 -0
- package/dist/core/content-manager.d.ts +343 -0
- package/dist/core/content-manager.js +1504 -0
- package/dist/core/content-performance-optimizer.d.ts +150 -0
- package/dist/core/content-performance-optimizer.js +516 -0
- package/dist/core/content-resolver.d.ts +104 -0
- package/dist/core/content-resolver.js +285 -0
- package/dist/core/cross-modal-search.d.ts +164 -0
- package/dist/core/cross-modal-search.js +342 -0
- package/dist/core/database-connection-manager.d.ts +109 -0
- package/dist/core/database-connection-manager.js +304 -0
- package/dist/core/db.d.ts +141 -2
- package/dist/core/db.js +631 -89
- package/dist/core/embedder-factory.d.ts +176 -0
- package/dist/core/embedder-factory.js +338 -0
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.js +4 -1
- package/dist/core/ingestion.d.ts +85 -15
- package/dist/core/ingestion.js +510 -45
- package/dist/core/lazy-dependency-loader.d.ts +152 -0
- package/dist/core/lazy-dependency-loader.js +453 -0
- package/dist/core/mode-detection-service.d.ts +150 -0
- package/dist/core/mode-detection-service.js +565 -0
- package/dist/core/mode-model-validator.d.ts +92 -0
- package/dist/core/mode-model-validator.js +203 -0
- package/dist/core/model-registry.d.ts +120 -0
- package/dist/core/model-registry.js +415 -0
- package/dist/core/model-validator.d.ts +217 -0
- package/dist/core/model-validator.js +782 -0
- package/dist/core/polymorphic-search-factory.d.ts +154 -0
- package/dist/core/polymorphic-search-factory.js +344 -0
- package/dist/core/raglite-paths.d.ts +121 -0
- package/dist/core/raglite-paths.js +145 -0
- package/dist/core/reranking-config.d.ts +42 -0
- package/dist/core/reranking-config.js +156 -0
- package/dist/core/reranking-factory.d.ts +92 -0
- package/dist/core/reranking-factory.js +591 -0
- package/dist/core/reranking-strategies.d.ts +325 -0
- package/dist/core/reranking-strategies.js +720 -0
- package/dist/core/resource-cleanup.d.ts +163 -0
- package/dist/core/resource-cleanup.js +371 -0
- package/dist/core/resource-manager.d.ts +212 -0
- package/dist/core/resource-manager.js +564 -0
- package/dist/core/search.d.ts +28 -1
- package/dist/core/search.js +83 -5
- package/dist/core/streaming-operations.d.ts +145 -0
- package/dist/core/streaming-operations.js +409 -0
- package/dist/core/types.d.ts +3 -0
- package/dist/core/universal-embedder.d.ts +177 -0
- package/dist/core/universal-embedder.js +139 -0
- package/dist/core/validation-messages.d.ts +99 -0
- package/dist/core/validation-messages.js +334 -0
- package/dist/core/vector-index.d.ts +1 -1
- package/dist/core/vector-index.js +37 -39
- package/dist/factories/index.d.ts +3 -1
- package/dist/factories/index.js +2 -0
- package/dist/factories/polymorphic-factory.d.ts +50 -0
- package/dist/factories/polymorphic-factory.js +159 -0
- package/dist/factories/text-factory.d.ts +128 -34
- package/dist/factories/text-factory.js +346 -97
- package/dist/file-processor.d.ts +88 -2
- package/dist/file-processor.js +720 -17
- package/dist/index.d.ts +32 -0
- package/dist/index.js +29 -0
- package/dist/ingestion.d.ts +16 -0
- package/dist/ingestion.js +21 -0
- package/dist/mcp-server.d.ts +35 -3
- package/dist/mcp-server.js +1107 -31
- package/dist/multimodal/clip-embedder.d.ts +327 -0
- package/dist/multimodal/clip-embedder.js +992 -0
- package/dist/multimodal/index.d.ts +6 -0
- package/dist/multimodal/index.js +6 -0
- package/dist/run-error-recovery-tests.d.ts +7 -0
- package/dist/run-error-recovery-tests.js +101 -0
- package/dist/search.d.ts +60 -9
- package/dist/search.js +82 -11
- package/dist/test-utils.d.ts +8 -26
- package/dist/text/chunker.d.ts +1 -0
- package/dist/text/embedder.js +15 -8
- package/dist/text/index.d.ts +1 -0
- package/dist/text/index.js +1 -0
- package/dist/text/reranker.d.ts +1 -2
- package/dist/text/reranker.js +17 -47
- package/dist/text/sentence-transformer-embedder.d.ts +96 -0
- package/dist/text/sentence-transformer-embedder.js +340 -0
- package/dist/types.d.ts +39 -0
- package/dist/utils/vector-math.d.ts +31 -0
- package/dist/utils/vector-math.js +70 -0
- package/package.json +27 -6
- package/dist/api-errors.d.ts.map +0 -1
- package/dist/api-errors.js.map +0 -1
- package/dist/cli/indexer.d.ts.map +0 -1
- package/dist/cli/indexer.js.map +0 -1
- package/dist/cli/search.d.ts.map +0 -1
- package/dist/cli/search.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/core/adapters.d.ts.map +0 -1
- package/dist/core/adapters.js.map +0 -1
- package/dist/core/chunker.d.ts.map +0 -1
- package/dist/core/chunker.js.map +0 -1
- package/dist/core/config.d.ts.map +0 -1
- package/dist/core/config.js.map +0 -1
- package/dist/core/db.d.ts.map +0 -1
- package/dist/core/db.js.map +0 -1
- package/dist/core/error-handler.d.ts.map +0 -1
- package/dist/core/error-handler.js.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/core/ingestion.d.ts.map +0 -1
- package/dist/core/ingestion.js.map +0 -1
- package/dist/core/interfaces.d.ts.map +0 -1
- package/dist/core/interfaces.js.map +0 -1
- package/dist/core/path-manager.d.ts.map +0 -1
- package/dist/core/path-manager.js.map +0 -1
- package/dist/core/search-example.d.ts +0 -25
- package/dist/core/search-example.d.ts.map +0 -1
- package/dist/core/search-example.js +0 -138
- package/dist/core/search-example.js.map +0 -1
- package/dist/core/search-pipeline-example.d.ts +0 -21
- package/dist/core/search-pipeline-example.d.ts.map +0 -1
- package/dist/core/search-pipeline-example.js +0 -188
- package/dist/core/search-pipeline-example.js.map +0 -1
- package/dist/core/search-pipeline.d.ts.map +0 -1
- package/dist/core/search-pipeline.js.map +0 -1
- package/dist/core/search.d.ts.map +0 -1
- package/dist/core/search.js.map +0 -1
- package/dist/core/types.d.ts.map +0 -1
- package/dist/core/types.js.map +0 -1
- package/dist/core/vector-index.d.ts.map +0 -1
- package/dist/core/vector-index.js.map +0 -1
- package/dist/dom-polyfills.d.ts.map +0 -1
- package/dist/dom-polyfills.js.map +0 -1
- package/dist/examples/clean-api-examples.d.ts +0 -44
- package/dist/examples/clean-api-examples.d.ts.map +0 -1
- package/dist/examples/clean-api-examples.js +0 -206
- package/dist/examples/clean-api-examples.js.map +0 -1
- package/dist/factories/index.d.ts.map +0 -1
- package/dist/factories/index.js.map +0 -1
- package/dist/factories/text-factory.d.ts.map +0 -1
- package/dist/factories/text-factory.js.map +0 -1
- package/dist/file-processor.d.ts.map +0 -1
- package/dist/file-processor.js.map +0 -1
- package/dist/index-manager.d.ts.map +0 -1
- package/dist/index-manager.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/indexer.d.ts.map +0 -1
- package/dist/indexer.js.map +0 -1
- package/dist/ingestion.d.ts.map +0 -1
- package/dist/ingestion.js.map +0 -1
- package/dist/mcp-server.d.ts.map +0 -1
- package/dist/mcp-server.js.map +0 -1
- package/dist/preprocess.d.ts.map +0 -1
- package/dist/preprocess.js.map +0 -1
- package/dist/preprocessors/index.d.ts.map +0 -1
- package/dist/preprocessors/index.js.map +0 -1
- package/dist/preprocessors/mdx.d.ts.map +0 -1
- package/dist/preprocessors/mdx.js.map +0 -1
- package/dist/preprocessors/mermaid.d.ts.map +0 -1
- package/dist/preprocessors/mermaid.js.map +0 -1
- package/dist/preprocessors/registry.d.ts.map +0 -1
- package/dist/preprocessors/registry.js.map +0 -1
- package/dist/search-standalone.d.ts.map +0 -1
- package/dist/search-standalone.js.map +0 -1
- package/dist/search.d.ts.map +0 -1
- package/dist/search.js.map +0 -1
- package/dist/test-utils.d.ts.map +0 -1
- package/dist/test-utils.js.map +0 -1
- package/dist/text/chunker.d.ts.map +0 -1
- package/dist/text/chunker.js.map +0 -1
- package/dist/text/embedder.d.ts.map +0 -1
- package/dist/text/embedder.js.map +0 -1
- package/dist/text/index.d.ts.map +0 -1
- package/dist/text/index.js.map +0 -1
- package/dist/text/preprocessors/index.d.ts.map +0 -1
- package/dist/text/preprocessors/index.js.map +0 -1
- package/dist/text/preprocessors/mdx.d.ts.map +0 -1
- package/dist/text/preprocessors/mdx.js.map +0 -1
- package/dist/text/preprocessors/mermaid.d.ts.map +0 -1
- package/dist/text/preprocessors/mermaid.js.map +0 -1
- package/dist/text/preprocessors/registry.d.ts.map +0 -1
- package/dist/text/preprocessors/registry.js.map +0 -1
- package/dist/text/reranker.d.ts.map +0 -1
- package/dist/text/reranker.js.map +0 -1
- package/dist/text/tokenizer.d.ts.map +0 -1
- package/dist/text/tokenizer.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- 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
|