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,591 @@
1
+ /**
2
+ * Simple Reranking Creation Function
3
+ *
4
+ * Implements createReranker function with simple conditional logic and automatic
5
+ * fallback mechanism for failed strategy initialization. Follows the design
6
+ * principle of using simple functions over complex factory patterns.
7
+ */
8
+ import { getDefaultRerankingConfig, isStrategySupported, getSupportedStrategies, validateRerankingConfig } from './reranking-config.js';
9
+ import { createCrossEncoderRerankFunction, createTextDerivedRerankFunction, createMetadataRerankFunction } from './reranking-strategies.js';
10
+ /**
11
+ * Simple reranking creation function with conditional logic
12
+ *
13
+ * Creates appropriate reranking function based on mode and strategy with
14
+ * automatic fallback mechanism for failed strategy initialization.
15
+ *
16
+ * @param mode - Operating mode ('text' or 'multimodal')
17
+ * @param strategy - Desired reranking strategy
18
+ * @param config - Optional configuration for the strategy
19
+ * @returns RerankFunction or undefined if reranking is disabled
20
+ */
21
+ export function createReranker(mode, strategy, config) {
22
+ const startTime = Date.now();
23
+ try {
24
+ console.log(`🚀 Starting reranker creation for ${mode} mode`);
25
+ // Use default strategy for mode if not specified
26
+ if (!strategy) {
27
+ const defaultConfig = getDefaultRerankingConfig(mode);
28
+ strategy = defaultConfig.strategy;
29
+ console.log(`Using default strategy for ${mode} mode: ${strategy}`);
30
+ }
31
+ // Return undefined immediately for disabled strategy
32
+ if (strategy === 'disabled') {
33
+ console.log('Reranking disabled by configuration');
34
+ return undefined;
35
+ }
36
+ // Validate strategy is supported for the mode
37
+ if (!isStrategySupported(strategy, mode)) {
38
+ const supportedStrategies = getSupportedStrategies(mode);
39
+ throw new Error(`Strategy '${strategy}' not supported for ${mode} mode. ` +
40
+ `Supported strategies: ${supportedStrategies.join(', ')}`);
41
+ }
42
+ // Validate and merge configuration
43
+ let validatedConfig;
44
+ try {
45
+ validatedConfig = config ? validateRerankingConfig({
46
+ strategy,
47
+ ...config
48
+ }) : getDefaultRerankingConfig(mode);
49
+ }
50
+ catch (configError) {
51
+ console.warn(`⚠️ Configuration validation failed: ${configError instanceof Error ? configError.message : 'Unknown error'}. ` +
52
+ `Using default configuration.`);
53
+ validatedConfig = getDefaultRerankingConfig(mode);
54
+ validatedConfig.strategy = strategy; // Keep the requested strategy
55
+ }
56
+ // Create reranking function based on strategy with enhanced error handling
57
+ const reranker = createRerankingFunction(mode, strategy, validatedConfig);
58
+ const duration = Date.now() - startTime;
59
+ if (reranker) {
60
+ console.log(`✅ Reranker creation completed successfully (${duration}ms)`);
61
+ }
62
+ else {
63
+ console.log(`ℹ️ Reranker creation completed - reranking disabled (${duration}ms)`);
64
+ }
65
+ return reranker;
66
+ }
67
+ catch (error) {
68
+ const duration = Date.now() - startTime;
69
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
70
+ console.error(`❌ Failed to create reranker with strategy '${strategy}' for ${mode} mode (${duration}ms): ${errorMessage}`);
71
+ // Log error details for debugging
72
+ if (error instanceof RerankingStrategyError) {
73
+ console.error('Detailed error information:', {
74
+ strategy: error.strategy,
75
+ mode: error.mode,
76
+ errorCode: error.errorCode,
77
+ message: error.message
78
+ });
79
+ }
80
+ throw error;
81
+ }
82
+ }
83
+ /**
84
+ * Create reranking function for specific strategy with enhanced error handling and recovery
85
+ */
86
+ function createRerankingFunction(mode, strategy, config) {
87
+ const startTime = Date.now();
88
+ try {
89
+ logRerankingAttempt(mode, strategy, config);
90
+ let reranker;
91
+ switch (strategy) {
92
+ case 'cross-encoder':
93
+ console.log(`Creating cross-encoder reranker for ${mode} mode`);
94
+ reranker = createCrossEncoderRerankFunction(config.model);
95
+ break;
96
+ case 'text-derived':
97
+ if (mode !== 'multimodal') {
98
+ throw new RerankingStrategyError(strategy, mode, 'Text-derived strategy only supported in multimodal mode', 'UNSUPPORTED_MODE');
99
+ }
100
+ console.log('Creating text-derived reranker for multimodal mode');
101
+ reranker = createTextDerivedRerankFunction(config.model, // Image-to-text model
102
+ undefined // Use default cross-encoder model
103
+ );
104
+ break;
105
+ case 'metadata':
106
+ console.log(`Creating metadata reranker for ${mode} mode`);
107
+ reranker = createMetadataRerankFunction({
108
+ weights: config.weights ? {
109
+ filename: config.weights.metadata || 0.4,
110
+ contentType: 0.3,
111
+ metadata: config.weights.metadata || 0.3
112
+ } : undefined
113
+ });
114
+ break;
115
+ case 'hybrid':
116
+ if (mode !== 'multimodal') {
117
+ throw new RerankingStrategyError(strategy, mode, 'Hybrid strategy only supported in multimodal mode', 'UNSUPPORTED_MODE');
118
+ }
119
+ console.log('Creating hybrid reranker for multimodal mode');
120
+ reranker = createHybridRerankFunction(config);
121
+ break;
122
+ case 'disabled':
123
+ console.log('Reranking explicitly disabled');
124
+ return undefined;
125
+ default:
126
+ throw new RerankingStrategyError(strategy, mode, `Unknown reranking strategy: ${strategy}`, 'UNKNOWN_STRATEGY');
127
+ }
128
+ // Validate that reranker was created successfully
129
+ if (!reranker) {
130
+ throw new RerankingStrategyError(strategy, mode, `Strategy '${strategy}' returned undefined reranker`, 'CREATION_FAILED');
131
+ }
132
+ // Wrap reranker with error recovery
133
+ const wrappedReranker = wrapRerankFunctionWithErrorRecovery(reranker, strategy, mode);
134
+ const duration = Date.now() - startTime;
135
+ console.log(`✅ Successfully created ${strategy} reranker for ${mode} mode (${duration}ms)`);
136
+ return wrappedReranker;
137
+ }
138
+ catch (error) {
139
+ const duration = Date.now() - startTime;
140
+ const rerankingError = error instanceof RerankingStrategyError
141
+ ? error
142
+ : new RerankingStrategyError(strategy, mode, error instanceof Error ? error.message : 'Unknown error', 'CREATION_ERROR');
143
+ logRerankingError(rerankingError, duration);
144
+ throw rerankingError;
145
+ }
146
+ }
147
+ /**
148
+ * Custom error class for reranking strategy failures
149
+ */
150
+ class RerankingStrategyError extends Error {
151
+ strategy;
152
+ mode;
153
+ errorCode;
154
+ constructor(strategy, mode, message, errorCode) {
155
+ super(message);
156
+ this.strategy = strategy;
157
+ this.mode = mode;
158
+ this.errorCode = errorCode;
159
+ this.name = 'RerankingStrategyError';
160
+ }
161
+ }
162
+ /**
163
+ * Log reranking attempt details
164
+ */
165
+ function logRerankingAttempt(mode, strategy, config) {
166
+ console.log(`🔧 Creating reranker: ${strategy} (mode: ${mode})`);
167
+ if (config.model) {
168
+ console.log(` Model: ${config.model}`);
169
+ }
170
+ if (config.weights) {
171
+ console.log(` Weights: ${JSON.stringify(config.weights)}`);
172
+ }
173
+ if (config.fallback && config.fallback !== 'disabled') {
174
+ console.log(` Fallback: ${config.fallback}`);
175
+ }
176
+ }
177
+ /**
178
+ * Log comprehensive reranking error details
179
+ */
180
+ function logRerankingError(error, duration) {
181
+ console.error('❌ Reranking Strategy Creation Failed');
182
+ console.error(` Strategy: ${error.strategy}`);
183
+ console.error(` Mode: ${error.mode}`);
184
+ console.error(` Error Code: ${error.errorCode}`);
185
+ console.error(` Duration: ${duration}ms`);
186
+ console.error(` Message: ${error.message}`);
187
+ // Provide troubleshooting guidance based on error type
188
+ switch (error.errorCode) {
189
+ case 'UNSUPPORTED_MODE':
190
+ console.error('💡 Suggestion: Use a strategy supported by the current mode');
191
+ break;
192
+ case 'UNKNOWN_STRATEGY':
193
+ console.error('💡 Suggestion: Check strategy name spelling and supported strategies');
194
+ break;
195
+ case 'CREATION_FAILED':
196
+ console.error('💡 Suggestion: Check model availability and network connectivity');
197
+ break;
198
+ case 'CREATION_ERROR':
199
+ console.error('💡 Suggestion: Check logs above for specific model loading errors');
200
+ break;
201
+ }
202
+ }
203
+ /**
204
+ * Wrap rerank function with error recovery to ensure search operations continue
205
+ */
206
+ function wrapRerankFunctionWithErrorRecovery(reranker, strategy, mode) {
207
+ return async (query, results, contentType) => {
208
+ try {
209
+ const startTime = Date.now();
210
+ const rerankedResults = await reranker(query, results, contentType);
211
+ const duration = Date.now() - startTime;
212
+ console.log(`✅ ${strategy} reranking completed successfully (${duration}ms, ${results.length} → ${rerankedResults.length} results)`);
213
+ return rerankedResults;
214
+ }
215
+ catch (error) {
216
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
217
+ console.warn(`⚠️ ${strategy} reranking failed during execution: ${errorMessage}. ` +
218
+ `Falling back to vector similarity scores.`);
219
+ // Log detailed error information for debugging
220
+ console.error('Reranking execution error details:', {
221
+ strategy,
222
+ mode,
223
+ query: query.substring(0, 100) + (query.length > 100 ? '...' : ''),
224
+ resultCount: results.length,
225
+ contentType,
226
+ error: errorMessage
227
+ });
228
+ // Return original results with vector similarity scores
229
+ // This ensures search operations continue even when reranking fails
230
+ return results.map(result => ({
231
+ ...result,
232
+ metadata: {
233
+ ...result.metadata,
234
+ rerankingFailed: true,
235
+ rerankingError: errorMessage,
236
+ rerankingStrategy: strategy,
237
+ fallbackToVectorSimilarity: true
238
+ }
239
+ }));
240
+ }
241
+ };
242
+ }
243
+ /**
244
+ * Create hybrid reranking function that combines multiple strategies with enhanced error recovery
245
+ */
246
+ function createHybridRerankFunction(config) {
247
+ // Default weights if not specified
248
+ const weights = config.weights || {
249
+ semantic: 0.6,
250
+ metadata: 0.4,
251
+ visual: 0.0 // Not implemented yet
252
+ };
253
+ // Track which strategies are available
254
+ const availableStrategies = {};
255
+ // Initialize strategies with error handling
256
+ try {
257
+ if (weights.semantic && weights.semantic > 0) {
258
+ availableStrategies.textDerived = createTextDerivedRerankFunction();
259
+ console.log('✅ Text-derived strategy initialized for hybrid reranking');
260
+ }
261
+ }
262
+ catch (error) {
263
+ console.warn(`⚠️ Text-derived strategy initialization failed for hybrid reranking: ${error instanceof Error ? error.message : 'Unknown error'}`);
264
+ }
265
+ try {
266
+ if (weights.metadata && weights.metadata > 0) {
267
+ availableStrategies.metadata = createMetadataRerankFunction();
268
+ console.log('✅ Metadata strategy initialized for hybrid reranking');
269
+ }
270
+ }
271
+ catch (error) {
272
+ console.warn(`⚠️ Metadata strategy initialization failed for hybrid reranking: ${error instanceof Error ? error.message : 'Unknown error'}`);
273
+ }
274
+ // Check if any strategies are available
275
+ const hasAvailableStrategies = Object.keys(availableStrategies).length > 0;
276
+ if (!hasAvailableStrategies) {
277
+ throw new RerankingStrategyError('hybrid', 'multimodal', 'No hybrid reranking strategies could be initialized', 'NO_STRATEGIES_AVAILABLE');
278
+ }
279
+ console.log(`Hybrid reranking initialized with ${Object.keys(availableStrategies).length} available strategies`);
280
+ return async (query, results, contentType) => {
281
+ const startTime = Date.now();
282
+ const strategyResults = {};
283
+ try {
284
+ console.log(`🔄 Running hybrid reranking with ${Object.keys(availableStrategies).length} strategies`);
285
+ // Start with original results
286
+ let hybridResults = [...results];
287
+ let successfulStrategies = 0;
288
+ // Apply text-derived reranking if available and enabled
289
+ if (availableStrategies.textDerived && weights.semantic && weights.semantic > 0) {
290
+ const strategyStartTime = Date.now();
291
+ try {
292
+ console.log(`🔧 Applying text-derived reranking (weight: ${weights.semantic})`);
293
+ const textDerivedResults = await availableStrategies.textDerived(query, hybridResults, contentType);
294
+ // Combine scores with semantic weight
295
+ hybridResults = hybridResults.map((result, index) => {
296
+ const textDerivedScore = textDerivedResults[index]?.score || result.score;
297
+ const combinedScore = result.score * (1 - weights.semantic) + textDerivedScore * weights.semantic;
298
+ return {
299
+ ...result,
300
+ score: combinedScore,
301
+ metadata: {
302
+ ...result.metadata,
303
+ hybridScores: {
304
+ ...(result.metadata?.hybridScores || {}),
305
+ textDerived: textDerivedScore,
306
+ semantic: combinedScore
307
+ }
308
+ }
309
+ };
310
+ });
311
+ const strategyDuration = Date.now() - strategyStartTime;
312
+ strategyResults.textDerived = { success: true, duration: strategyDuration };
313
+ successfulStrategies++;
314
+ console.log(`✅ Text-derived reranking completed (${strategyDuration}ms)`);
315
+ }
316
+ catch (error) {
317
+ const strategyDuration = Date.now() - strategyStartTime;
318
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
319
+ strategyResults.textDerived = { success: false, error: errorMessage, duration: strategyDuration };
320
+ console.warn(`❌ Text-derived reranking failed in hybrid mode (${strategyDuration}ms): ${errorMessage}`);
321
+ }
322
+ }
323
+ // Apply metadata reranking if available and enabled
324
+ if (availableStrategies.metadata && weights.metadata && weights.metadata > 0) {
325
+ const strategyStartTime = Date.now();
326
+ try {
327
+ console.log(`🔧 Applying metadata reranking (weight: ${weights.metadata})`);
328
+ const metadataResults = await availableStrategies.metadata(query, hybridResults, contentType);
329
+ // Combine scores with metadata weight
330
+ hybridResults = hybridResults.map((result, index) => {
331
+ const metadataScore = metadataResults[index]?.score || result.score;
332
+ const currentScore = result.score;
333
+ const combinedScore = currentScore * (1 - weights.metadata) + metadataScore * weights.metadata;
334
+ return {
335
+ ...result,
336
+ score: combinedScore,
337
+ metadata: {
338
+ ...result.metadata,
339
+ hybridScores: {
340
+ ...(result.metadata?.hybridScores || {}),
341
+ metadata: metadataScore,
342
+ combined: combinedScore
343
+ }
344
+ }
345
+ };
346
+ });
347
+ const strategyDuration = Date.now() - strategyStartTime;
348
+ strategyResults.metadata = { success: true, duration: strategyDuration };
349
+ successfulStrategies++;
350
+ console.log(`✅ Metadata reranking completed (${strategyDuration}ms)`);
351
+ }
352
+ catch (error) {
353
+ const strategyDuration = Date.now() - strategyStartTime;
354
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
355
+ strategyResults.metadata = { success: false, error: errorMessage, duration: strategyDuration };
356
+ console.warn(`❌ Metadata reranking failed in hybrid mode (${strategyDuration}ms): ${errorMessage}`);
357
+ }
358
+ }
359
+ // Sort by final combined scores
360
+ hybridResults.sort((a, b) => b.score - a.score);
361
+ const totalDuration = Date.now() - startTime;
362
+ // Add hybrid reranking metadata to results
363
+ hybridResults = hybridResults.map(result => ({
364
+ ...result,
365
+ metadata: {
366
+ ...result.metadata,
367
+ hybridRerankingInfo: {
368
+ totalDuration,
369
+ successfulStrategies,
370
+ strategyResults,
371
+ weights
372
+ }
373
+ }
374
+ }));
375
+ if (successfulStrategies > 0) {
376
+ console.log(`✅ Hybrid reranking completed successfully (${totalDuration}ms, ${successfulStrategies}/${Object.keys(availableStrategies).length} strategies succeeded)`);
377
+ }
378
+ else {
379
+ console.warn(`⚠️ Hybrid reranking completed with no successful strategies (${totalDuration}ms), returning original results`);
380
+ return results; // Return original results if no strategies succeeded
381
+ }
382
+ return hybridResults;
383
+ }
384
+ catch (error) {
385
+ const totalDuration = Date.now() - startTime;
386
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
387
+ console.warn(`❌ Hybrid reranking failed (${totalDuration}ms): ${errorMessage}. ` +
388
+ `Returning original results.`);
389
+ // Log detailed error information
390
+ console.error('Hybrid reranking error details:', {
391
+ query: query.substring(0, 100) + (query.length > 100 ? '...' : ''),
392
+ resultCount: results.length,
393
+ contentType,
394
+ availableStrategies: Object.keys(availableStrategies),
395
+ weights,
396
+ strategyResults,
397
+ error: errorMessage
398
+ });
399
+ return results.map(result => ({
400
+ ...result,
401
+ metadata: {
402
+ ...result.metadata,
403
+ hybridRerankingFailed: true,
404
+ hybridRerankingError: errorMessage,
405
+ fallbackToVectorSimilarity: true
406
+ }
407
+ }));
408
+ }
409
+ };
410
+ }
411
+ /**
412
+ * Create reranker with automatic mode detection
413
+ *
414
+ * This is a convenience function that automatically detects the appropriate
415
+ * default strategy based on mode and creates the reranker.
416
+ *
417
+ * @param mode - Operating mode ('text' or 'multimodal')
418
+ * @param config - Optional configuration override
419
+ * @returns RerankFunction or undefined if reranking is disabled
420
+ */
421
+ export function createDefaultReranker(mode, config) {
422
+ const defaultConfig = getDefaultRerankingConfig(mode);
423
+ const strategy = config?.strategy || defaultConfig.strategy;
424
+ console.log(`Creating default reranker for ${mode} mode with ${strategy} strategy`);
425
+ return createReranker(mode, strategy, config);
426
+ }
427
+ /**
428
+ * Check if reranking is available for a given mode and strategy
429
+ *
430
+ * This function can be used to test if a reranking strategy can be created
431
+ * without actually creating it.
432
+ *
433
+ * @param mode - Operating mode ('text' or 'multimodal')
434
+ * @param strategy - Reranking strategy to test
435
+ * @returns Promise<boolean> indicating if the strategy is available
436
+ */
437
+ export async function isRerankingAvailable(mode, strategy) {
438
+ try {
439
+ if (!strategy) {
440
+ const defaultConfig = getDefaultRerankingConfig(mode);
441
+ strategy = defaultConfig.strategy;
442
+ }
443
+ if (strategy === 'disabled') {
444
+ return false;
445
+ }
446
+ if (!isStrategySupported(strategy, mode)) {
447
+ return false;
448
+ }
449
+ // Try to create the reranker to test availability
450
+ const reranker = createReranker(mode, strategy);
451
+ return reranker !== undefined;
452
+ }
453
+ catch (error) {
454
+ console.warn(`Reranking availability check failed for ${strategy} in ${mode} mode: ` +
455
+ `${error instanceof Error ? error.message : 'Unknown error'}`);
456
+ return false;
457
+ }
458
+ }
459
+ /**
460
+ * Get comprehensive information about available reranking strategies for a mode
461
+ *
462
+ * @param mode - Operating mode ('text' or 'multimodal')
463
+ * @returns Object with strategy information and availability
464
+ */
465
+ export async function getRerankingInfo(mode) {
466
+ const supportedStrategies = getSupportedStrategies(mode);
467
+ const defaultConfig = getDefaultRerankingConfig(mode);
468
+ const strategyInfo = await Promise.all(supportedStrategies.map(async (strategy) => {
469
+ const startTime = Date.now();
470
+ let available = false;
471
+ let error;
472
+ try {
473
+ available = await isRerankingAvailable(mode, strategy);
474
+ }
475
+ catch (e) {
476
+ error = e instanceof Error ? e.message : 'Unknown error';
477
+ }
478
+ const duration = Date.now() - startTime;
479
+ return {
480
+ strategy,
481
+ supported: true,
482
+ available,
483
+ isDefault: strategy === defaultConfig.strategy,
484
+ checkDuration: duration,
485
+ error
486
+ };
487
+ }));
488
+ return {
489
+ mode,
490
+ defaultStrategy: defaultConfig.strategy,
491
+ strategies: strategyInfo,
492
+ hasAvailableStrategies: strategyInfo.some(info => info.available)
493
+ };
494
+ }
495
+ /**
496
+ * Test reranking system health and error recovery
497
+ *
498
+ * @param mode - Operating mode to test
499
+ * @returns Comprehensive health report
500
+ */
501
+ export async function testRerankingHealth(mode) {
502
+ console.log(`🔍 Testing reranking system health for ${mode} mode`);
503
+ const supportedStrategies = getSupportedStrategies(mode);
504
+ const defaultConfig = getDefaultRerankingConfig(mode);
505
+ const strategyTests = [];
506
+ let defaultStrategyWorking = false;
507
+ let anyStrategyWorking = false;
508
+ // Test each supported strategy
509
+ for (const strategy of supportedStrategies) {
510
+ if (strategy === 'disabled')
511
+ continue;
512
+ const startTime = Date.now();
513
+ let success = false;
514
+ let error;
515
+ try {
516
+ const reranker = createReranker(mode, strategy);
517
+ success = reranker !== undefined;
518
+ if (success && strategy === defaultConfig.strategy) {
519
+ defaultStrategyWorking = true;
520
+ }
521
+ if (success) {
522
+ anyStrategyWorking = true;
523
+ }
524
+ }
525
+ catch (e) {
526
+ error = e instanceof Error ? e.message : 'Unknown error';
527
+ }
528
+ const duration = Date.now() - startTime;
529
+ strategyTests.push({ strategy, success, duration, error });
530
+ }
531
+ // Fallback system removed - no longer testing fallback functionality
532
+ let fallbackSystemWorking = true; // Always true since we don't use fallbacks anymore
533
+ // Determine overall health
534
+ let overallHealth;
535
+ if (defaultStrategyWorking) {
536
+ overallHealth = 'healthy';
537
+ }
538
+ else if (anyStrategyWorking || fallbackSystemWorking) {
539
+ overallHealth = 'degraded';
540
+ }
541
+ else {
542
+ overallHealth = 'failed';
543
+ }
544
+ // Generate recommendations
545
+ const recommendations = [];
546
+ if (!defaultStrategyWorking) {
547
+ recommendations.push(`Default strategy '${defaultConfig.strategy}' is not working. Check model availability.`);
548
+ }
549
+ if (!anyStrategyWorking) {
550
+ recommendations.push('No reranking strategies are working. Check network connectivity and model availability.');
551
+ }
552
+ else if (!fallbackSystemWorking) {
553
+ recommendations.push('Fallback system is not working properly. Manual intervention may be required.');
554
+ }
555
+ if (overallHealth === 'degraded') {
556
+ recommendations.push('System is running in degraded mode. Some reranking strategies are unavailable.');
557
+ }
558
+ if (overallHealth === 'healthy') {
559
+ recommendations.push('Reranking system is healthy and all strategies are working properly.');
560
+ }
561
+ console.log(`🏥 Health check completed: ${overallHealth} (${strategyTests.filter(t => t.success).length}/${strategyTests.length} strategies working)`);
562
+ return {
563
+ mode,
564
+ overallHealth,
565
+ defaultStrategyWorking,
566
+ fallbackSystemWorking,
567
+ strategyTests,
568
+ recommendations
569
+ };
570
+ }
571
+ /**
572
+ * Get reranking system statistics and performance metrics
573
+ */
574
+ export function getRerankingStats() {
575
+ // This would be implemented with actual metrics collection in a real system
576
+ // For now, return placeholder data
577
+ return {
578
+ totalCreationAttempts: 0,
579
+ successfulCreations: 0,
580
+ failedCreations: 0,
581
+ fallbacksTriggered: 0,
582
+ strategiesUsed: {
583
+ 'cross-encoder': 0,
584
+ 'text-derived': 0,
585
+ 'metadata': 0,
586
+ 'hybrid': 0,
587
+ 'disabled': 0
588
+ }
589
+ };
590
+ }
591
+ //# sourceMappingURL=reranking-factory.js.map