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.
Files changed (208) hide show
  1. package/README.md +605 -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/binary-index-format.d.ts +52 -0
  12. package/dist/core/binary-index-format.js +122 -0
  13. package/dist/core/chunker.d.ts +2 -0
  14. package/dist/core/cli-database-utils.d.ts +53 -0
  15. package/dist/core/cli-database-utils.js +239 -0
  16. package/dist/core/config.js +10 -3
  17. package/dist/core/content-errors.d.ts +111 -0
  18. package/dist/core/content-errors.js +362 -0
  19. package/dist/core/content-manager.d.ts +343 -0
  20. package/dist/core/content-manager.js +1504 -0
  21. package/dist/core/content-performance-optimizer.d.ts +150 -0
  22. package/dist/core/content-performance-optimizer.js +516 -0
  23. package/dist/core/content-resolver.d.ts +104 -0
  24. package/dist/core/content-resolver.js +285 -0
  25. package/dist/core/cross-modal-search.d.ts +164 -0
  26. package/dist/core/cross-modal-search.js +342 -0
  27. package/dist/core/database-connection-manager.d.ts +109 -0
  28. package/dist/core/database-connection-manager.js +304 -0
  29. package/dist/core/db.d.ts +141 -2
  30. package/dist/core/db.js +631 -89
  31. package/dist/core/embedder-factory.d.ts +176 -0
  32. package/dist/core/embedder-factory.js +338 -0
  33. package/dist/core/index.d.ts +3 -1
  34. package/dist/core/index.js +4 -1
  35. package/dist/core/ingestion.d.ts +85 -15
  36. package/dist/core/ingestion.js +510 -45
  37. package/dist/core/lazy-dependency-loader.d.ts +152 -0
  38. package/dist/core/lazy-dependency-loader.js +453 -0
  39. package/dist/core/mode-detection-service.d.ts +150 -0
  40. package/dist/core/mode-detection-service.js +565 -0
  41. package/dist/core/mode-model-validator.d.ts +92 -0
  42. package/dist/core/mode-model-validator.js +203 -0
  43. package/dist/core/model-registry.d.ts +120 -0
  44. package/dist/core/model-registry.js +415 -0
  45. package/dist/core/model-validator.d.ts +217 -0
  46. package/dist/core/model-validator.js +782 -0
  47. package/dist/core/polymorphic-search-factory.d.ts +154 -0
  48. package/dist/core/polymorphic-search-factory.js +344 -0
  49. package/dist/core/raglite-paths.d.ts +121 -0
  50. package/dist/core/raglite-paths.js +145 -0
  51. package/dist/core/reranking-config.d.ts +42 -0
  52. package/dist/core/reranking-config.js +156 -0
  53. package/dist/core/reranking-factory.d.ts +92 -0
  54. package/dist/core/reranking-factory.js +591 -0
  55. package/dist/core/reranking-strategies.d.ts +325 -0
  56. package/dist/core/reranking-strategies.js +720 -0
  57. package/dist/core/resource-cleanup.d.ts +163 -0
  58. package/dist/core/resource-cleanup.js +371 -0
  59. package/dist/core/resource-manager.d.ts +212 -0
  60. package/dist/core/resource-manager.js +564 -0
  61. package/dist/core/search.d.ts +28 -1
  62. package/dist/core/search.js +83 -5
  63. package/dist/core/streaming-operations.d.ts +145 -0
  64. package/dist/core/streaming-operations.js +409 -0
  65. package/dist/core/types.d.ts +3 -0
  66. package/dist/core/universal-embedder.d.ts +177 -0
  67. package/dist/core/universal-embedder.js +139 -0
  68. package/dist/core/validation-messages.d.ts +99 -0
  69. package/dist/core/validation-messages.js +334 -0
  70. package/dist/core/vector-index.d.ts +1 -1
  71. package/dist/core/vector-index.js +37 -39
  72. package/dist/factories/index.d.ts +3 -1
  73. package/dist/factories/index.js +2 -0
  74. package/dist/factories/polymorphic-factory.d.ts +50 -0
  75. package/dist/factories/polymorphic-factory.js +159 -0
  76. package/dist/factories/text-factory.d.ts +128 -34
  77. package/dist/factories/text-factory.js +346 -97
  78. package/dist/file-processor.d.ts +88 -2
  79. package/dist/file-processor.js +720 -17
  80. package/dist/index.d.ts +32 -0
  81. package/dist/index.js +29 -0
  82. package/dist/ingestion.d.ts +16 -0
  83. package/dist/ingestion.js +21 -0
  84. package/dist/mcp-server.d.ts +35 -3
  85. package/dist/mcp-server.js +1107 -31
  86. package/dist/multimodal/clip-embedder.d.ts +327 -0
  87. package/dist/multimodal/clip-embedder.js +992 -0
  88. package/dist/multimodal/index.d.ts +6 -0
  89. package/dist/multimodal/index.js +6 -0
  90. package/dist/run-error-recovery-tests.d.ts +7 -0
  91. package/dist/run-error-recovery-tests.js +101 -0
  92. package/dist/search.d.ts +60 -9
  93. package/dist/search.js +82 -11
  94. package/dist/test-utils.d.ts +8 -26
  95. package/dist/text/chunker.d.ts +1 -0
  96. package/dist/text/embedder.js +15 -8
  97. package/dist/text/index.d.ts +1 -0
  98. package/dist/text/index.js +1 -0
  99. package/dist/text/reranker.d.ts +1 -2
  100. package/dist/text/reranker.js +17 -47
  101. package/dist/text/sentence-transformer-embedder.d.ts +96 -0
  102. package/dist/text/sentence-transformer-embedder.js +340 -0
  103. package/dist/types.d.ts +39 -0
  104. package/dist/utils/vector-math.d.ts +31 -0
  105. package/dist/utils/vector-math.js +70 -0
  106. package/package.json +27 -6
  107. package/dist/api-errors.d.ts.map +0 -1
  108. package/dist/api-errors.js.map +0 -1
  109. package/dist/cli/indexer.d.ts.map +0 -1
  110. package/dist/cli/indexer.js.map +0 -1
  111. package/dist/cli/search.d.ts.map +0 -1
  112. package/dist/cli/search.js.map +0 -1
  113. package/dist/cli.d.ts.map +0 -1
  114. package/dist/cli.js.map +0 -1
  115. package/dist/config.d.ts.map +0 -1
  116. package/dist/config.js.map +0 -1
  117. package/dist/core/adapters.d.ts.map +0 -1
  118. package/dist/core/adapters.js.map +0 -1
  119. package/dist/core/chunker.d.ts.map +0 -1
  120. package/dist/core/chunker.js.map +0 -1
  121. package/dist/core/config.d.ts.map +0 -1
  122. package/dist/core/config.js.map +0 -1
  123. package/dist/core/db.d.ts.map +0 -1
  124. package/dist/core/db.js.map +0 -1
  125. package/dist/core/error-handler.d.ts.map +0 -1
  126. package/dist/core/error-handler.js.map +0 -1
  127. package/dist/core/index.d.ts.map +0 -1
  128. package/dist/core/index.js.map +0 -1
  129. package/dist/core/ingestion.d.ts.map +0 -1
  130. package/dist/core/ingestion.js.map +0 -1
  131. package/dist/core/interfaces.d.ts.map +0 -1
  132. package/dist/core/interfaces.js.map +0 -1
  133. package/dist/core/path-manager.d.ts.map +0 -1
  134. package/dist/core/path-manager.js.map +0 -1
  135. package/dist/core/search-example.d.ts +0 -25
  136. package/dist/core/search-example.d.ts.map +0 -1
  137. package/dist/core/search-example.js +0 -138
  138. package/dist/core/search-example.js.map +0 -1
  139. package/dist/core/search-pipeline-example.d.ts +0 -21
  140. package/dist/core/search-pipeline-example.d.ts.map +0 -1
  141. package/dist/core/search-pipeline-example.js +0 -188
  142. package/dist/core/search-pipeline-example.js.map +0 -1
  143. package/dist/core/search-pipeline.d.ts.map +0 -1
  144. package/dist/core/search-pipeline.js.map +0 -1
  145. package/dist/core/search.d.ts.map +0 -1
  146. package/dist/core/search.js.map +0 -1
  147. package/dist/core/types.d.ts.map +0 -1
  148. package/dist/core/types.js.map +0 -1
  149. package/dist/core/vector-index.d.ts.map +0 -1
  150. package/dist/core/vector-index.js.map +0 -1
  151. package/dist/dom-polyfills.d.ts.map +0 -1
  152. package/dist/dom-polyfills.js.map +0 -1
  153. package/dist/examples/clean-api-examples.d.ts +0 -44
  154. package/dist/examples/clean-api-examples.d.ts.map +0 -1
  155. package/dist/examples/clean-api-examples.js +0 -206
  156. package/dist/examples/clean-api-examples.js.map +0 -1
  157. package/dist/factories/index.d.ts.map +0 -1
  158. package/dist/factories/index.js.map +0 -1
  159. package/dist/factories/text-factory.d.ts.map +0 -1
  160. package/dist/factories/text-factory.js.map +0 -1
  161. package/dist/file-processor.d.ts.map +0 -1
  162. package/dist/file-processor.js.map +0 -1
  163. package/dist/index-manager.d.ts.map +0 -1
  164. package/dist/index-manager.js.map +0 -1
  165. package/dist/index.d.ts.map +0 -1
  166. package/dist/index.js.map +0 -1
  167. package/dist/indexer.d.ts.map +0 -1
  168. package/dist/indexer.js.map +0 -1
  169. package/dist/ingestion.d.ts.map +0 -1
  170. package/dist/ingestion.js.map +0 -1
  171. package/dist/mcp-server.d.ts.map +0 -1
  172. package/dist/mcp-server.js.map +0 -1
  173. package/dist/preprocess.d.ts.map +0 -1
  174. package/dist/preprocess.js.map +0 -1
  175. package/dist/preprocessors/index.d.ts.map +0 -1
  176. package/dist/preprocessors/index.js.map +0 -1
  177. package/dist/preprocessors/mdx.d.ts.map +0 -1
  178. package/dist/preprocessors/mdx.js.map +0 -1
  179. package/dist/preprocessors/mermaid.d.ts.map +0 -1
  180. package/dist/preprocessors/mermaid.js.map +0 -1
  181. package/dist/preprocessors/registry.d.ts.map +0 -1
  182. package/dist/preprocessors/registry.js.map +0 -1
  183. package/dist/search-standalone.d.ts.map +0 -1
  184. package/dist/search-standalone.js.map +0 -1
  185. package/dist/search.d.ts.map +0 -1
  186. package/dist/search.js.map +0 -1
  187. package/dist/test-utils.d.ts.map +0 -1
  188. package/dist/test-utils.js.map +0 -1
  189. package/dist/text/chunker.d.ts.map +0 -1
  190. package/dist/text/chunker.js.map +0 -1
  191. package/dist/text/embedder.d.ts.map +0 -1
  192. package/dist/text/embedder.js.map +0 -1
  193. package/dist/text/index.d.ts.map +0 -1
  194. package/dist/text/index.js.map +0 -1
  195. package/dist/text/preprocessors/index.d.ts.map +0 -1
  196. package/dist/text/preprocessors/index.js.map +0 -1
  197. package/dist/text/preprocessors/mdx.d.ts.map +0 -1
  198. package/dist/text/preprocessors/mdx.js.map +0 -1
  199. package/dist/text/preprocessors/mermaid.d.ts.map +0 -1
  200. package/dist/text/preprocessors/mermaid.js.map +0 -1
  201. package/dist/text/preprocessors/registry.d.ts.map +0 -1
  202. package/dist/text/preprocessors/registry.js.map +0 -1
  203. package/dist/text/reranker.d.ts.map +0 -1
  204. package/dist/text/reranker.js.map +0 -1
  205. package/dist/text/tokenizer.d.ts.map +0 -1
  206. package/dist/text/tokenizer.js.map +0 -1
  207. package/dist/types.d.ts.map +0 -1
  208. package/dist/types.js.map +0 -1
@@ -0,0 +1,334 @@
1
+ /**
2
+ * CORE MODULE — Validation Messages and Error Descriptions
3
+ * Comprehensive error messages and user guidance for model validation
4
+ * Provides helpful, actionable error messages with troubleshooting steps
5
+ */
6
+ import { ModelRegistry } from './model-registry.js';
7
+ // =============================================================================
8
+ // ERROR MESSAGE TEMPLATES
9
+ // =============================================================================
10
+ /**
11
+ * Error message templates for different validation scenarios
12
+ */
13
+ export const ERROR_MESSAGES = {
14
+ MODEL_NOT_FOUND: (modelName, suggestions) => ({
15
+ title: `Model '${modelName}' not found`,
16
+ description: `The specified model is not supported by the Chameleon architecture.`,
17
+ details: [
18
+ `Model '${modelName}' is not in the supported models registry.`,
19
+ `This could be due to a typo in the model name or the model not being compatible with transformers.js.`
20
+ ],
21
+ suggestions: suggestions.length > 0 ? [
22
+ `Did you mean one of these models?`,
23
+ ...suggestions.map(s => ` • ${s}`)
24
+ ] : [
25
+ `Available models:`,
26
+ ...ModelRegistry.getSupportedModels().map(s => ` • ${s}`)
27
+ ],
28
+ actions: [
29
+ `Check the model name for typos`,
30
+ `Use 'ModelRegistry.getSupportedModels()' to see all available models`,
31
+ `Visit the documentation for the latest supported models list`
32
+ ]
33
+ }),
34
+ TRANSFORMERS_VERSION_INCOMPATIBLE: (modelName, required, current) => ({
35
+ title: `Transformers.js version incompatible`,
36
+ description: `Model '${modelName}' requires a newer version of transformers.js.`,
37
+ details: [
38
+ `Required version: ${required}`,
39
+ `Current version: ${current}`,
40
+ `The model uses features not available in the current transformers.js version.`
41
+ ],
42
+ suggestions: [
43
+ `Upgrade transformers.js to the latest version:`,
44
+ ` npm install @huggingface/transformers@latest`,
45
+ ``,
46
+ `Or install a specific compatible version:`,
47
+ ` npm install @huggingface/transformers@${required.replace(/[>=<~^]/g, '')}`
48
+ ],
49
+ actions: [
50
+ `Update your package.json dependencies`,
51
+ `Run npm install to update transformers.js`,
52
+ `Restart your application after updating`
53
+ ]
54
+ }),
55
+ INSUFFICIENT_MEMORY: (modelName, required, available) => ({
56
+ title: `Insufficient memory for model`,
57
+ description: `Model '${modelName}' requires more memory than available.`,
58
+ details: [
59
+ `Required memory: ${required}MB`,
60
+ `Available memory: ${available}MB`,
61
+ `Shortfall: ${required - available}MB`
62
+ ],
63
+ suggestions: [
64
+ `Consider using a smaller model variant:`,
65
+ ...ModelRegistry.getSupportedModels().filter(name => {
66
+ const info = ModelRegistry.getModelInfo(name);
67
+ return info &&
68
+ info.requirements.minimumMemory &&
69
+ info.requirements.minimumMemory <= available;
70
+ }).map(name => ` • ${name}`),
71
+ ``,
72
+ `Or increase available memory by:`,
73
+ ` • Closing other applications`,
74
+ ` • Increasing Node.js memory limit: --max-old-space-size=${required + 512}`,
75
+ ` • Using a machine with more RAM`
76
+ ],
77
+ actions: [
78
+ `Free up system memory`,
79
+ `Choose a more memory-efficient model`,
80
+ `Consider using model quantization if available`
81
+ ]
82
+ }),
83
+ PLATFORM_UNSUPPORTED: (modelName, currentPlatform, supportedPlatforms) => ({
84
+ title: `Platform not supported`,
85
+ description: `Model '${modelName}' is not supported on ${currentPlatform}.`,
86
+ details: [
87
+ `Current platform: ${currentPlatform}`,
88
+ `Supported platforms: ${supportedPlatforms.join(', ')}`,
89
+ `The model may use platform-specific features or optimizations.`
90
+ ],
91
+ suggestions: [
92
+ `Try running on a supported platform:`,
93
+ ...supportedPlatforms.map(platform => ` • ${platform}`),
94
+ ``,
95
+ `Or use a platform-agnostic model:`,
96
+ ...ModelRegistry.getSupportedModels().filter(name => {
97
+ const info = ModelRegistry.getModelInfo(name);
98
+ return info &&
99
+ info.requirements.platformSupport &&
100
+ info.requirements.platformSupport.includes(currentPlatform);
101
+ }).slice(0, 3).map(name => ` • ${name}`)
102
+ ],
103
+ actions: [
104
+ `Switch to a supported platform`,
105
+ `Use a different model that supports your platform`,
106
+ `Check if there are platform-specific installation instructions`
107
+ ]
108
+ }),
109
+ FEATURES_MISSING: (modelName, missingFeatures) => ({
110
+ title: `Required features not available`,
111
+ description: `Model '${modelName}' requires features not available in current transformers.js version.`,
112
+ details: [
113
+ `Missing features: ${missingFeatures.join(', ')}`,
114
+ `These features are required for the model to function properly.`
115
+ ],
116
+ suggestions: [
117
+ `Upgrade transformers.js to get missing features:`,
118
+ ` npm install @huggingface/transformers@latest`,
119
+ ``,
120
+ `Or use a model that doesn't require these features:`,
121
+ ...ModelRegistry.getSupportedModels().filter(name => {
122
+ const info = ModelRegistry.getModelInfo(name);
123
+ return info &&
124
+ (!info.requirements.requiredFeatures ||
125
+ info.requirements.requiredFeatures.every(f => !missingFeatures.includes(f)));
126
+ }).slice(0, 3).map(name => ` • ${name}`)
127
+ ],
128
+ actions: [
129
+ `Update transformers.js to the latest version`,
130
+ `Check the transformers.js changelog for feature availability`,
131
+ `Use an alternative model with fewer feature requirements`
132
+ ]
133
+ }),
134
+ CONTENT_TYPE_UNSUPPORTED: (contentType, modelName, supportedTypes) => ({
135
+ title: `Content type not supported`,
136
+ description: `Model '${modelName}' does not support '${contentType}' content.`,
137
+ details: [
138
+ `Requested content type: ${contentType}`,
139
+ `Supported content types: ${supportedTypes.join(', ')}`,
140
+ `The model was not trained to handle this type of content.`
141
+ ],
142
+ suggestions: [
143
+ `Use a model that supports '${contentType}' content:`,
144
+ ...ModelRegistry.getModelsByContentType(contentType).slice(0, 3).map(name => ` • ${name}`),
145
+ ``,
146
+ `Or convert your content to a supported type:`,
147
+ ...supportedTypes.map(type => ` • Convert to ${type}`)
148
+ ],
149
+ actions: [
150
+ `Choose a multimodal model for mixed content types`,
151
+ `Preprocess your content to match supported types`,
152
+ `Use separate models for different content types`
153
+ ]
154
+ })
155
+ };
156
+ // =============================================================================
157
+ // WARNING MESSAGE TEMPLATES
158
+ // =============================================================================
159
+ /**
160
+ * Warning message templates for non-critical issues
161
+ */
162
+ export const WARNING_MESSAGES = {
163
+ HIGH_MEMORY_USAGE: (modelName, memoryMB) => ({
164
+ title: `High memory usage`,
165
+ message: `Model '${modelName}' requires ${memoryMB}MB of memory, which may impact performance.`,
166
+ suggestions: [
167
+ `Monitor system memory usage during operation`,
168
+ `Consider using a smaller model variant if performance is affected`,
169
+ `Ensure sufficient swap space is available`
170
+ ]
171
+ }),
172
+ LIMITED_BATCH_SIZE: (modelName, maxBatchSize) => ({
173
+ title: `Limited batch processing`,
174
+ message: `Model '${modelName}' supports maximum batch size of ${maxBatchSize}.`,
175
+ suggestions: [
176
+ `Use smaller batch sizes for optimal performance`,
177
+ `Process large datasets in smaller chunks`,
178
+ `Consider parallel processing with multiple model instances`
179
+ ]
180
+ }),
181
+ EXPERIMENTAL_FEATURES: (modelName, features) => ({
182
+ title: `Experimental features in use`,
183
+ message: `Model '${modelName}' uses experimental features: ${features.join(', ')}.`,
184
+ suggestions: [
185
+ `Test thoroughly before using in production`,
186
+ `Monitor for unexpected behavior or errors`,
187
+ `Have fallback options ready`,
188
+ `Check for updates that may stabilize these features`
189
+ ]
190
+ }),
191
+ PERFORMANCE_IMPACT: (modelName, reason) => ({
192
+ title: `Potential performance impact`,
193
+ message: `Model '${modelName}' may have reduced performance: ${reason}.`,
194
+ suggestions: [
195
+ `Monitor processing times and resource usage`,
196
+ `Consider using GPU acceleration if available`,
197
+ `Optimize batch sizes for your use case`,
198
+ `Profile your application to identify bottlenecks`
199
+ ]
200
+ })
201
+ };
202
+ // =============================================================================
203
+ // MESSAGE FORMATTING UTILITIES
204
+ // =============================================================================
205
+ /**
206
+ * Format an error message for console output
207
+ */
208
+ export function formatErrorMessage(error) {
209
+ const lines = [];
210
+ lines.push(`❌ ${error.title}`);
211
+ lines.push('');
212
+ lines.push(error.description);
213
+ if (error.details.length > 0) {
214
+ lines.push('');
215
+ lines.push('Details:');
216
+ error.details.forEach(detail => lines.push(` ${detail}`));
217
+ }
218
+ if (error.suggestions.length > 0) {
219
+ lines.push('');
220
+ lines.push('Suggestions:');
221
+ error.suggestions.forEach(suggestion => lines.push(` ${suggestion}`));
222
+ }
223
+ if (error.actions.length > 0) {
224
+ lines.push('');
225
+ lines.push('Actions:');
226
+ error.actions.forEach((action, index) => lines.push(` ${index + 1}. ${action}`));
227
+ }
228
+ return lines.join('\n');
229
+ }
230
+ /**
231
+ * Format a warning message for console output
232
+ */
233
+ export function formatWarningMessage(warning) {
234
+ const lines = [];
235
+ lines.push(`⚠️ ${warning.title}`);
236
+ lines.push('');
237
+ lines.push(warning.message);
238
+ if (warning.suggestions.length > 0) {
239
+ lines.push('');
240
+ lines.push('Suggestions:');
241
+ warning.suggestions.forEach(suggestion => lines.push(` • ${suggestion}`));
242
+ }
243
+ return lines.join('\n');
244
+ }
245
+ /**
246
+ * Create a comprehensive error message for model validation failure
247
+ */
248
+ export function createValidationErrorMessage(modelName, errorType, context = {}) {
249
+ switch (errorType) {
250
+ case 'not_found':
251
+ return formatErrorMessage(ERROR_MESSAGES.MODEL_NOT_FOUND(modelName, context.suggestions || []));
252
+ case 'version_incompatible':
253
+ return formatErrorMessage(ERROR_MESSAGES.TRANSFORMERS_VERSION_INCOMPATIBLE(modelName, context.required || 'unknown', context.current || 'unknown'));
254
+ case 'insufficient_memory':
255
+ return formatErrorMessage(ERROR_MESSAGES.INSUFFICIENT_MEMORY(modelName, context.required || 0, context.available || 0));
256
+ case 'platform_unsupported':
257
+ return formatErrorMessage(ERROR_MESSAGES.PLATFORM_UNSUPPORTED(modelName, context.currentPlatform || 'unknown', context.supportedPlatforms || []));
258
+ case 'features_missing':
259
+ return formatErrorMessage(ERROR_MESSAGES.FEATURES_MISSING(modelName, context.missingFeatures || []));
260
+ case 'content_type_unsupported':
261
+ return formatErrorMessage(ERROR_MESSAGES.CONTENT_TYPE_UNSUPPORTED(context.contentType || 'unknown', modelName, context.supportedTypes || []));
262
+ default:
263
+ return `❌ Validation failed for model '${modelName}': ${errorType}`;
264
+ }
265
+ }
266
+ /**
267
+ * Create helpful suggestions based on model type and use case
268
+ */
269
+ export function createModelSuggestions(modelType, contentTypes, memoryLimit) {
270
+ const suggestions = [];
271
+ if (modelType === 'sentence-transformer') {
272
+ suggestions.push('For text-only tasks, sentence-transformers are most efficient');
273
+ suggestions.push('all-MiniLM-L6-v2 offers the best balance of speed and accuracy');
274
+ suggestions.push('all-mpnet-base-v2 provides higher accuracy but uses more memory');
275
+ }
276
+ if (modelType === 'clip') {
277
+ suggestions.push('CLIP models support both text and image content');
278
+ suggestions.push('clip-vit-base-patch32 is recommended for most use cases');
279
+ suggestions.push('patch16 variants are more accurate but slower');
280
+ }
281
+ if (contentTypes?.includes('image')) {
282
+ suggestions.push('Multimodal content requires CLIP models');
283
+ suggestions.push('Ensure images are in supported formats (jpg, png, webp)');
284
+ suggestions.push('Consider image preprocessing for better results');
285
+ }
286
+ if (memoryLimit && memoryLimit < 1024) {
287
+ suggestions.push('Low memory environments should use smaller models');
288
+ suggestions.push('Consider model quantization to reduce memory usage');
289
+ suggestions.push('Process content in smaller batches');
290
+ }
291
+ return suggestions;
292
+ }
293
+ /**
294
+ * Get troubleshooting steps for common issues
295
+ */
296
+ export function getTroubleshootingSteps(issue) {
297
+ const steps = {
298
+ 'model_loading_failed': [
299
+ 'Check internet connection for model download',
300
+ 'Verify model name spelling and availability',
301
+ 'Ensure sufficient disk space for model cache',
302
+ 'Try clearing the model cache and re-downloading',
303
+ 'Check transformers.js version compatibility'
304
+ ],
305
+ 'out_of_memory': [
306
+ 'Reduce batch size for processing',
307
+ 'Use a smaller model variant',
308
+ 'Increase Node.js memory limit with --max-old-space-size',
309
+ 'Close other memory-intensive applications',
310
+ 'Consider using model quantization'
311
+ ],
312
+ 'slow_performance': [
313
+ 'Use GPU acceleration if available',
314
+ 'Optimize batch sizes for your hardware',
315
+ 'Consider using a smaller, faster model',
316
+ 'Profile your code to identify bottlenecks',
317
+ 'Use appropriate hardware for your model size'
318
+ ],
319
+ 'compatibility_issues': [
320
+ 'Update transformers.js to the latest version',
321
+ 'Check model requirements against your environment',
322
+ 'Verify platform compatibility (Node.js vs browser)',
323
+ 'Test with a known working model first',
324
+ 'Check for conflicting dependencies'
325
+ ]
326
+ };
327
+ return steps[issue] || [
328
+ 'Check the documentation for your specific issue',
329
+ 'Search for similar issues in the project repository',
330
+ 'Ensure all dependencies are up to date',
331
+ 'Try with a minimal test case to isolate the problem'
332
+ ];
333
+ }
334
+ //# sourceMappingURL=validation-messages.js.map
@@ -30,7 +30,7 @@ export declare class VectorIndex {
30
30
  */
31
31
  loadIndex(): Promise<void>;
32
32
  /**
33
- * Save index to file using JSON format (since IDBFS doesn't work in Node.js)
33
+ * Save index to binary format
34
34
  */
35
35
  saveIndex(): Promise<void>;
36
36
  /**
@@ -2,9 +2,11 @@
2
2
  * CORE MODULE — Shared between text-only (rag-lite-ts) and future multimodal (rag-lite-mm)
3
3
  * Model-agnostic. No transformer or modality-specific logic.
4
4
  */
5
- import { readFileSync, writeFileSync, existsSync } from 'fs';
5
+ import { existsSync } from 'fs';
6
6
  import { JSDOM } from 'jsdom';
7
7
  import { ErrorCategory, ErrorSeverity, safeExecute } from './error-handler.js';
8
+ import { createMissingFileError, createDimensionMismatchError } from './actionable-error-messages.js';
9
+ import { BinaryIndexFormat } from './binary-index-format.js';
8
10
  // Set up browser-like environment for hnswlib-wasm
9
11
  if (typeof window === 'undefined') {
10
12
  const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
@@ -103,7 +105,9 @@ export class VectorIndex {
103
105
  */
104
106
  async loadIndex() {
105
107
  if (!existsSync(this.indexPath)) {
106
- throw new Error(`Index file not found: ${this.indexPath}`);
108
+ throw createMissingFileError(this.indexPath, 'index', {
109
+ operationContext: 'VectorIndex.loadIndex'
110
+ });
107
111
  }
108
112
  try {
109
113
  // Load the hnswlib module
@@ -150,70 +154,64 @@ export class VectorIndex {
150
154
  }
151
155
  // Create new HNSW index (third parameter is autoSaveFilename, but we'll handle persistence manually)
152
156
  this.index = new this.hnswlib.HierarchicalNSW('cosine', this.options.dimensions, '');
153
- // Load from JSON format since IDBFS doesn't work in Node.js
154
- const data = readFileSync(this.indexPath, 'utf-8');
155
- const stored = JSON.parse(data);
156
- // Check dimension compatibility and log details
157
- if (stored.dimensions && stored.dimensions !== this.options.dimensions) {
157
+ // Load from binary format
158
+ const data = await BinaryIndexFormat.load(this.indexPath);
159
+ // Validate dimensions
160
+ if (data.dimensions !== this.options.dimensions) {
158
161
  console.log(`⚠️ Dimension mismatch detected:`);
159
- console.log(` Stored dimensions: ${stored.dimensions}`);
162
+ console.log(` Stored dimensions: ${data.dimensions}`);
160
163
  console.log(` Expected dimensions: ${this.options.dimensions}`);
161
- console.log(` Number of vectors: ${stored.vectors?.length || 0}`);
162
- if (stored.vectors && stored.vectors.length > 0) {
163
- console.log(` Actual vector length: ${stored.vectors[0].vector.length}`);
164
+ console.log(` Number of vectors: ${data.vectors.length}`);
165
+ if (data.vectors.length > 0) {
166
+ console.log(` Actual vector length: ${data.vectors[0].vector.length}`);
164
167
  }
165
- throw new Error(`Vector dimension mismatch!\n` +
166
- `Index was created with ${stored.dimensions} dimensions\n` +
167
- `Current model expects ${this.options.dimensions} dimensions\n` +
168
- `This indicates the embedding model has changed.\n` +
169
- `Please rebuild the index with the current model.`);
168
+ throw createDimensionMismatchError(this.options.dimensions, data.dimensions, 'vector index loading', { operationContext: 'VectorIndex.loadIndex' });
170
169
  }
171
170
  // Update options from stored data
172
- this.options.maxElements = stored.maxElements || this.options.maxElements;
173
- this.options.M = stored.M || this.options.M;
174
- this.options.efConstruction = stored.efConstruction || this.options.efConstruction;
175
- this.options.seed = stored.seed || this.options.seed;
176
- // Recreate the index from stored data
177
- this.index.initIndex(this.options.maxElements, this.options.M || 16, this.options.efConstruction || 200, this.options.seed || 100);
171
+ this.options.maxElements = data.maxElements;
172
+ this.options.M = data.M;
173
+ this.options.efConstruction = data.efConstruction;
174
+ this.options.seed = data.seed;
175
+ // Initialize HNSW index
176
+ this.index.initIndex(this.options.maxElements, this.options.M, this.options.efConstruction, this.options.seed);
178
177
  // Clear and repopulate vector storage
179
178
  this.vectorStorage.clear();
180
- // Add all stored vectors back
181
- for (const item of stored.vectors || []) {
182
- const vector = new Float32Array(item.vector);
183
- this.index.addPoint(vector, item.id, false);
184
- this.vectorStorage.set(item.id, vector);
179
+ // Add all stored vectors to HNSW index
180
+ for (const item of data.vectors) {
181
+ this.index.addPoint(item.vector, item.id, false);
182
+ this.vectorStorage.set(item.id, item.vector);
185
183
  }
186
- this.currentSize = stored.vectors?.length || 0;
187
- console.log(`Loaded HNSW index with ${this.currentSize} vectors from ${this.indexPath}`);
184
+ this.currentSize = data.currentSize;
185
+ console.log(`✓ Loaded HNSW index with ${this.currentSize} vectors from ${this.indexPath}`);
188
186
  }
189
187
  catch (error) {
190
188
  throw new Error(`Failed to load index from ${this.indexPath}: ${error}`);
191
189
  }
192
190
  }
193
191
  /**
194
- * Save index to file using JSON format (since IDBFS doesn't work in Node.js)
192
+ * Save index to binary format
195
193
  */
196
194
  async saveIndex() {
197
195
  if (!this.index) {
198
196
  throw new Error('Index not initialized');
199
197
  }
200
198
  try {
201
- // Convert stored vectors to serializable format
199
+ // Collect all vectors from storage
202
200
  const vectors = Array.from(this.vectorStorage.entries()).map(([id, vector]) => ({
203
201
  id,
204
- vector: Array.from(vector)
202
+ vector
205
203
  }));
206
- const stored = {
204
+ // Save to binary format
205
+ await BinaryIndexFormat.save(this.indexPath, {
207
206
  dimensions: this.options.dimensions,
208
207
  maxElements: this.options.maxElements,
209
208
  M: this.options.M || 16,
210
209
  efConstruction: this.options.efConstruction || 200,
211
210
  seed: this.options.seed || 100,
212
211
  currentSize: this.currentSize,
213
- vectors: vectors
214
- };
215
- writeFileSync(this.indexPath, JSON.stringify(stored, null, 2));
216
- console.log(`Saved HNSW index with ${this.currentSize} vectors to ${this.indexPath}`);
212
+ vectors
213
+ });
214
+ console.log(`✓ Saved HNSW index with ${this.currentSize} vectors to ${this.indexPath}`);
217
215
  }
218
216
  catch (error) {
219
217
  throw new Error(`Failed to save index to ${this.indexPath}: ${error}`);
@@ -227,7 +225,7 @@ export class VectorIndex {
227
225
  throw new Error('Index not initialized');
228
226
  }
229
227
  if (vector.length !== this.options.dimensions) {
230
- throw new Error(`Vector dimension mismatch: expected ${this.options.dimensions}, got ${vector.length}`);
228
+ throw createDimensionMismatchError(this.options.dimensions, vector.length, 'vector addition', { operationContext: 'VectorIndex.addVector' });
231
229
  }
232
230
  try {
233
231
  this.index.addPoint(vector, embeddingId, false);
@@ -255,7 +253,7 @@ export class VectorIndex {
255
253
  throw new Error('Index not initialized');
256
254
  }
257
255
  if (queryVector.length !== this.options.dimensions) {
258
- throw new Error(`Query vector dimension mismatch: expected ${this.options.dimensions}, got ${queryVector.length}`);
256
+ throw createDimensionMismatchError(this.options.dimensions, queryVector.length, 'vector search', { operationContext: 'VectorIndex.search' });
259
257
  }
260
258
  if (this.currentSize === 0) {
261
259
  return { neighbors: [], distances: [] };
@@ -36,7 +36,9 @@
36
36
  * ```
37
37
  */
38
38
  export { TextSearchFactory, TextIngestionFactory, TextRAGFactory, TextFactoryHelpers } from './text-factory.js';
39
- export type { TextSearchOptions, TextIngestionOptions } from './text-factory.js';
39
+ export { PolymorphicSearchFactory } from './polymorphic-factory.js';
40
+ export type { PolymorphicSearchOptions } from './polymorphic-factory.js';
41
+ export type { TextSearchOptions, TextIngestionOptions, ContentSystemConfig } from './text-factory.js';
40
42
  export { TextSearchFactory as SearchFactory } from './text-factory.js';
41
43
  export { TextIngestionFactory as IngestionFactory } from './text-factory.js';
42
44
  export { TextRAGFactory as RAGFactory } from './text-factory.js';
@@ -37,6 +37,8 @@
37
37
  */
38
38
  // Main factory classes
39
39
  export { TextSearchFactory, TextIngestionFactory, TextRAGFactory, TextFactoryHelpers } from './text-factory.js';
40
+ // Polymorphic factory for mode-aware search
41
+ export { PolymorphicSearchFactory } from './polymorphic-factory.js';
40
42
  // Convenience re-exports for common patterns
41
43
  export { TextSearchFactory as SearchFactory } from './text-factory.js';
42
44
  export { TextIngestionFactory as IngestionFactory } from './text-factory.js';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Polymorphic factory for creating mode-aware search engines
3
+ * Automatically detects mode from database and uses appropriate embedder
4
+ *
5
+ * This factory implements the Chameleon Architecture principle:
6
+ * - Detects mode (text/multimodal) from database configuration
7
+ * - Uses appropriate embedder based on detected mode
8
+ * - Provides seamless polymorphic behavior without user intervention
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Automatically detects mode and creates appropriate search engine
13
+ * const search = await PolymorphicSearchFactory.create('./index.bin', './db.sqlite');
14
+ *
15
+ * // Works for both text and multimodal modes
16
+ * const results = await search.search('query');
17
+ * ```
18
+ */
19
+ import { SearchEngine } from '../core/search.js';
20
+ export interface PolymorphicSearchOptions {
21
+ /** Whether to enable reranking (default: true) */
22
+ enableReranking?: boolean;
23
+ /** Top-k results to return (default: from config) */
24
+ topK?: number;
25
+ }
26
+ /**
27
+ * Factory for creating mode-aware search engines
28
+ * Automatically detects mode from database and uses appropriate embedder
29
+ */
30
+ export declare class PolymorphicSearchFactory {
31
+ /**
32
+ * Create a SearchEngine that automatically adapts to the mode stored in the database
33
+ *
34
+ * This method:
35
+ * 1. Validates that required files exist
36
+ * 2. Opens database and reads system configuration
37
+ * 3. Detects mode (text/multimodal) from database
38
+ * 4. Creates appropriate embedder based on mode
39
+ * 5. Optionally creates reranker based on configuration
40
+ * 6. Returns fully configured SearchEngine
41
+ *
42
+ * @param indexPath - Path to the vector index file (must exist)
43
+ * @param dbPath - Path to the SQLite database file (must exist)
44
+ * @param options - Optional configuration overrides
45
+ * @returns Promise resolving to configured SearchEngine
46
+ * @throws {Error} If required files don't exist or initialization fails
47
+ */
48
+ static create(indexPath: string, dbPath: string, options?: PolymorphicSearchOptions): Promise<SearchEngine>;
49
+ }
50
+ //# sourceMappingURL=polymorphic-factory.d.ts.map