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.
- package/README.md +606 -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/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.js +7 -8
- package/dist/factories/index.d.ts +1 -1
- 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 +9 -0
- package/dist/index.js +11 -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 +314 -0
- package/dist/multimodal/clip-embedder.js +945 -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 +26 -0
- package/dist/search.js +54 -1
- 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 +15 -3
- 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,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
|