rag-lite-ts 2.2.0 → 2.3.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 (100) hide show
  1. package/README.md +88 -5
  2. package/dist/cjs/cli/indexer.js +73 -15
  3. package/dist/cjs/cli/search.js +77 -2
  4. package/dist/cjs/cli/ui-server.d.ts +5 -0
  5. package/dist/cjs/cli/ui-server.js +152 -0
  6. package/dist/cjs/cli.js +53 -7
  7. package/dist/cjs/core/abstract-generator.d.ts +97 -0
  8. package/dist/cjs/core/abstract-generator.js +222 -0
  9. package/dist/cjs/core/binary-index-format.js +53 -10
  10. package/dist/cjs/core/db.d.ts +56 -0
  11. package/dist/cjs/core/db.js +105 -0
  12. package/dist/cjs/core/generator-registry.d.ts +114 -0
  13. package/dist/cjs/core/generator-registry.js +280 -0
  14. package/dist/cjs/core/index.d.ts +4 -0
  15. package/dist/cjs/core/index.js +11 -0
  16. package/dist/cjs/core/ingestion.js +3 -0
  17. package/dist/cjs/core/knowledge-base-manager.d.ts +109 -0
  18. package/dist/cjs/core/knowledge-base-manager.js +256 -0
  19. package/dist/cjs/core/lazy-dependency-loader.d.ts +43 -0
  20. package/dist/cjs/core/lazy-dependency-loader.js +111 -2
  21. package/dist/cjs/core/prompt-templates.d.ts +138 -0
  22. package/dist/cjs/core/prompt-templates.js +225 -0
  23. package/dist/cjs/core/response-generator.d.ts +132 -0
  24. package/dist/cjs/core/response-generator.js +69 -0
  25. package/dist/cjs/core/search-pipeline.js +1 -1
  26. package/dist/cjs/core/search.d.ts +72 -1
  27. package/dist/cjs/core/search.js +80 -7
  28. package/dist/cjs/core/types.d.ts +1 -0
  29. package/dist/cjs/core/vector-index-messages.d.ts +52 -0
  30. package/dist/cjs/core/vector-index-messages.js +5 -0
  31. package/dist/cjs/core/vector-index-worker.d.ts +6 -0
  32. package/dist/cjs/core/vector-index-worker.js +314 -0
  33. package/dist/cjs/core/vector-index.d.ts +45 -10
  34. package/dist/cjs/core/vector-index.js +279 -218
  35. package/dist/cjs/factories/generator-factory.d.ts +88 -0
  36. package/dist/cjs/factories/generator-factory.js +151 -0
  37. package/dist/cjs/factories/index.d.ts +1 -0
  38. package/dist/cjs/factories/index.js +5 -0
  39. package/dist/cjs/factories/ingestion-factory.js +3 -7
  40. package/dist/cjs/factories/search-factory.js +11 -0
  41. package/dist/cjs/index-manager.d.ts +23 -3
  42. package/dist/cjs/index-manager.js +84 -15
  43. package/dist/cjs/index.d.ts +11 -1
  44. package/dist/cjs/index.js +19 -1
  45. package/dist/cjs/text/generators/causal-lm-generator.d.ts +65 -0
  46. package/dist/cjs/text/generators/causal-lm-generator.js +197 -0
  47. package/dist/cjs/text/generators/index.d.ts +10 -0
  48. package/dist/cjs/text/generators/index.js +10 -0
  49. package/dist/cjs/text/generators/instruct-generator.d.ts +62 -0
  50. package/dist/cjs/text/generators/instruct-generator.js +192 -0
  51. package/dist/esm/cli/indexer.js +73 -15
  52. package/dist/esm/cli/search.js +77 -2
  53. package/dist/esm/cli/ui-server.d.ts +5 -0
  54. package/dist/esm/cli/ui-server.js +152 -0
  55. package/dist/esm/cli.js +53 -7
  56. package/dist/esm/core/abstract-generator.d.ts +97 -0
  57. package/dist/esm/core/abstract-generator.js +222 -0
  58. package/dist/esm/core/binary-index-format.js +53 -10
  59. package/dist/esm/core/db.d.ts +56 -0
  60. package/dist/esm/core/db.js +105 -0
  61. package/dist/esm/core/generator-registry.d.ts +114 -0
  62. package/dist/esm/core/generator-registry.js +280 -0
  63. package/dist/esm/core/index.d.ts +4 -0
  64. package/dist/esm/core/index.js +11 -0
  65. package/dist/esm/core/ingestion.js +3 -0
  66. package/dist/esm/core/knowledge-base-manager.d.ts +109 -0
  67. package/dist/esm/core/knowledge-base-manager.js +256 -0
  68. package/dist/esm/core/lazy-dependency-loader.d.ts +43 -0
  69. package/dist/esm/core/lazy-dependency-loader.js +111 -2
  70. package/dist/esm/core/prompt-templates.d.ts +138 -0
  71. package/dist/esm/core/prompt-templates.js +225 -0
  72. package/dist/esm/core/response-generator.d.ts +132 -0
  73. package/dist/esm/core/response-generator.js +69 -0
  74. package/dist/esm/core/search-pipeline.js +1 -1
  75. package/dist/esm/core/search.d.ts +72 -1
  76. package/dist/esm/core/search.js +80 -7
  77. package/dist/esm/core/types.d.ts +1 -0
  78. package/dist/esm/core/vector-index-messages.d.ts +52 -0
  79. package/dist/esm/core/vector-index-messages.js +5 -0
  80. package/dist/esm/core/vector-index-worker.d.ts +6 -0
  81. package/dist/esm/core/vector-index-worker.js +314 -0
  82. package/dist/esm/core/vector-index.d.ts +45 -10
  83. package/dist/esm/core/vector-index.js +279 -218
  84. package/dist/esm/factories/generator-factory.d.ts +88 -0
  85. package/dist/esm/factories/generator-factory.js +151 -0
  86. package/dist/esm/factories/index.d.ts +1 -0
  87. package/dist/esm/factories/index.js +5 -0
  88. package/dist/esm/factories/ingestion-factory.js +3 -7
  89. package/dist/esm/factories/search-factory.js +11 -0
  90. package/dist/esm/index-manager.d.ts +23 -3
  91. package/dist/esm/index-manager.js +84 -15
  92. package/dist/esm/index.d.ts +11 -1
  93. package/dist/esm/index.js +19 -1
  94. package/dist/esm/text/generators/causal-lm-generator.d.ts +65 -0
  95. package/dist/esm/text/generators/causal-lm-generator.js +197 -0
  96. package/dist/esm/text/generators/index.d.ts +10 -0
  97. package/dist/esm/text/generators/index.js +10 -0
  98. package/dist/esm/text/generators/instruct-generator.d.ts +62 -0
  99. package/dist/esm/text/generators/instruct-generator.js +192 -0
  100. package/package.json +14 -7
@@ -0,0 +1,88 @@
1
+ /**
2
+ * FACTORY MODULE — Generator Factory for RAG Response Generation
3
+ *
4
+ * Factory functions for creating response generator instances.
5
+ * Handles model validation, lazy loading, and proper initialization.
6
+ *
7
+ * SUPPORTED MODELS:
8
+ * - HuggingFaceTB/SmolLM2-135M-Instruct (instruct, balanced, DEFAULT, uses top 3 chunks)
9
+ * - HuggingFaceTB/SmolLM2-360M-Instruct (instruct, higher quality, uses top 5 chunks)
10
+ *
11
+ * PREREQUISITES:
12
+ * - Reranking must be enabled for response generation
13
+ *
14
+ * @experimental This feature is experimental and may change in future versions.
15
+ */
16
+ import type { ResponseGenerator, GeneratorCreationOptions, GenerateFunction } from '../core/response-generator.js';
17
+ /**
18
+ * Create a response generator for the specified model
19
+ *
20
+ * Uses lazy loading to defer model initialization until first use.
21
+ * Validates model compatibility before creation.
22
+ *
23
+ * @param modelName - Name of the generator model (default: SmolLM2-135M-Instruct)
24
+ * @param options - Optional configuration options
25
+ * @returns Promise resolving to a ResponseGenerator instance
26
+ * @throws {GeneratorValidationError} If model is not supported
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Create default generator (recommended)
31
+ * const generator = await createResponseGenerator();
32
+ *
33
+ * // Create higher quality generator
34
+ * const generator = await createResponseGenerator('HuggingFaceTB/SmolLM2-360M-Instruct');
35
+ *
36
+ * // Create with options
37
+ * const generator = await createResponseGenerator('HuggingFaceTB/SmolLM2-360M-Instruct', {
38
+ * cachePath: './models'
39
+ * });
40
+ * ```
41
+ *
42
+ * @experimental This feature is experimental and may change in future versions.
43
+ */
44
+ export declare function createResponseGenerator(modelName?: string, options?: GeneratorCreationOptions): Promise<ResponseGenerator>;
45
+ /**
46
+ * Create a GenerateFunction from a model name
47
+ *
48
+ * This is a convenience function that creates a generator and wraps it
49
+ * in a function suitable for dependency injection into SearchEngine.
50
+ *
51
+ * @param modelName - Name of the generator model
52
+ * @param options - Optional configuration options
53
+ * @returns Promise resolving to a GenerateFunction
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const generateFn = await createGenerateFunctionFromModel();
58
+ * const result = await generateFn(query, chunks);
59
+ * ```
60
+ *
61
+ * @experimental This feature is experimental and may change in future versions.
62
+ */
63
+ export declare function createGenerateFunctionFromModel(modelName?: string, options?: GeneratorCreationOptions): Promise<GenerateFunction>;
64
+ /**
65
+ * Get the default generator model name
66
+ */
67
+ export declare function getDefaultGeneratorModel(): string;
68
+ /**
69
+ * List available generator models
70
+ */
71
+ export declare function listGeneratorModels(): string[];
72
+ /**
73
+ * Check if a model name is a valid generator
74
+ */
75
+ export declare function isValidGeneratorModel(modelName: string): boolean;
76
+ /**
77
+ * Get recommended generator for specific use case
78
+ *
79
+ * @param preferSpeed - Prefer faster generation over quality
80
+ * @param preferQuality - Prefer higher quality over speed
81
+ * @returns Recommended model name
82
+ */
83
+ export declare function getRecommendedGenerator(options?: {
84
+ preferSpeed?: boolean;
85
+ preferQuality?: boolean;
86
+ }): string;
87
+ export { GeneratorRegistry, DEFAULT_GENERATOR_MODEL } from '../core/generator-registry.js';
88
+ //# sourceMappingURL=generator-factory.d.ts.map
@@ -0,0 +1,151 @@
1
+ /**
2
+ * FACTORY MODULE — Generator Factory for RAG Response Generation
3
+ *
4
+ * Factory functions for creating response generator instances.
5
+ * Handles model validation, lazy loading, and proper initialization.
6
+ *
7
+ * SUPPORTED MODELS:
8
+ * - HuggingFaceTB/SmolLM2-135M-Instruct (instruct, balanced, DEFAULT, uses top 3 chunks)
9
+ * - HuggingFaceTB/SmolLM2-360M-Instruct (instruct, higher quality, uses top 5 chunks)
10
+ *
11
+ * PREREQUISITES:
12
+ * - Reranking must be enabled for response generation
13
+ *
14
+ * @experimental This feature is experimental and may change in future versions.
15
+ */
16
+ import { createGenerateFunction, GeneratorValidationError } from '../core/response-generator.js';
17
+ import { GeneratorRegistry, DEFAULT_GENERATOR_MODEL, getGeneratorType } from '../core/generator-registry.js';
18
+ import { LazyGeneratorLoader } from '../core/lazy-dependency-loader.js';
19
+ // =============================================================================
20
+ // GENERATOR FACTORY
21
+ // =============================================================================
22
+ /**
23
+ * Create a response generator for the specified model
24
+ *
25
+ * Uses lazy loading to defer model initialization until first use.
26
+ * Validates model compatibility before creation.
27
+ *
28
+ * @param modelName - Name of the generator model (default: SmolLM2-135M-Instruct)
29
+ * @param options - Optional configuration options
30
+ * @returns Promise resolving to a ResponseGenerator instance
31
+ * @throws {GeneratorValidationError} If model is not supported
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * // Create default generator (recommended)
36
+ * const generator = await createResponseGenerator();
37
+ *
38
+ * // Create higher quality generator
39
+ * const generator = await createResponseGenerator('HuggingFaceTB/SmolLM2-360M-Instruct');
40
+ *
41
+ * // Create with options
42
+ * const generator = await createResponseGenerator('HuggingFaceTB/SmolLM2-360M-Instruct', {
43
+ * cachePath: './models'
44
+ * });
45
+ * ```
46
+ *
47
+ * @experimental This feature is experimental and may change in future versions.
48
+ */
49
+ export async function createResponseGenerator(modelName = DEFAULT_GENERATOR_MODEL, options = {}) {
50
+ console.log(`🏭 [EXPERIMENTAL] Creating response generator: ${modelName}`);
51
+ // Step 1: Validate model
52
+ const validation = GeneratorRegistry.validateGenerator(modelName);
53
+ if (!validation.isValid) {
54
+ throw new GeneratorValidationError(modelName, GeneratorRegistry.getSupportedGenerators(), validation.errors.join('; '));
55
+ }
56
+ // Log warnings
57
+ if (validation.warnings.length > 0) {
58
+ console.warn(`⚠️ Warnings for generator '${modelName}':`);
59
+ validation.warnings.forEach(w => console.warn(` • ${w}`));
60
+ }
61
+ // Log suggestions
62
+ if (validation.suggestions.length > 0) {
63
+ console.info(`💡 Suggestions for generator '${modelName}':`);
64
+ validation.suggestions.forEach(s => console.info(` • ${s}`));
65
+ }
66
+ // Step 2: Get model type and create appropriate generator
67
+ const modelType = getGeneratorType(modelName);
68
+ if (!modelType) {
69
+ throw new GeneratorValidationError(modelName, GeneratorRegistry.getSupportedGenerators(), `Could not determine model type for '${modelName}'`);
70
+ }
71
+ // Step 3: Use lazy loading to create the generator
72
+ let generator;
73
+ switch (modelType) {
74
+ case 'instruct':
75
+ generator = await LazyGeneratorLoader.loadInstructGenerator(modelName, options);
76
+ break;
77
+ case 'causal-lm':
78
+ generator = await LazyGeneratorLoader.loadCausalLMGenerator(modelName, options);
79
+ break;
80
+ default:
81
+ throw new GeneratorValidationError(modelName, GeneratorRegistry.getSupportedGenerators(), `Unsupported generator type: ${modelType}`);
82
+ }
83
+ console.log(`✅ [EXPERIMENTAL] Response generator created: ${modelName}`);
84
+ return generator;
85
+ }
86
+ /**
87
+ * Create a GenerateFunction from a model name
88
+ *
89
+ * This is a convenience function that creates a generator and wraps it
90
+ * in a function suitable for dependency injection into SearchEngine.
91
+ *
92
+ * @param modelName - Name of the generator model
93
+ * @param options - Optional configuration options
94
+ * @returns Promise resolving to a GenerateFunction
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * const generateFn = await createGenerateFunctionFromModel();
99
+ * const result = await generateFn(query, chunks);
100
+ * ```
101
+ *
102
+ * @experimental This feature is experimental and may change in future versions.
103
+ */
104
+ export async function createGenerateFunctionFromModel(modelName = DEFAULT_GENERATOR_MODEL, options = {}) {
105
+ const generator = await createResponseGenerator(modelName, options);
106
+ return createGenerateFunction(generator);
107
+ }
108
+ // =============================================================================
109
+ // UTILITY FUNCTIONS
110
+ // =============================================================================
111
+ /**
112
+ * Get the default generator model name
113
+ */
114
+ export function getDefaultGeneratorModel() {
115
+ return DEFAULT_GENERATOR_MODEL;
116
+ }
117
+ /**
118
+ * List available generator models
119
+ */
120
+ export function listGeneratorModels() {
121
+ return GeneratorRegistry.getSupportedGenerators();
122
+ }
123
+ /**
124
+ * Check if a model name is a valid generator
125
+ */
126
+ export function isValidGeneratorModel(modelName) {
127
+ return GeneratorRegistry.getGeneratorInfo(modelName) !== null;
128
+ }
129
+ /**
130
+ * Get recommended generator for specific use case
131
+ *
132
+ * @param preferSpeed - Prefer faster generation over quality
133
+ * @param preferQuality - Prefer higher quality over speed
134
+ * @returns Recommended model name
135
+ */
136
+ export function getRecommendedGenerator(options = {}) {
137
+ const { preferSpeed, preferQuality } = options;
138
+ if (preferSpeed) {
139
+ return 'Xenova/distilgpt2';
140
+ }
141
+ if (preferQuality) {
142
+ return 'HuggingFaceTB/SmolLM2-360M-Instruct';
143
+ }
144
+ // Default: balanced option
145
+ return DEFAULT_GENERATOR_MODEL;
146
+ }
147
+ // =============================================================================
148
+ // EXPORTS
149
+ // =============================================================================
150
+ export { GeneratorRegistry, DEFAULT_GENERATOR_MODEL } from '../core/generator-registry.js';
151
+ //# sourceMappingURL=generator-factory.js.map
@@ -24,4 +24,5 @@
24
24
  export { IngestionFactory } from './ingestion-factory.js';
25
25
  export { SearchFactory } from './search-factory.js';
26
26
  export type { IngestionFactoryOptions, ContentSystemConfig } from './ingestion-factory.js';
27
+ export { createResponseGenerator, createGenerateFunctionFromModel, getDefaultGeneratorModel, listGeneratorModels, isValidGeneratorModel, getRecommendedGenerator } from './generator-factory.js';
27
28
  //# sourceMappingURL=index.d.ts.map
@@ -26,4 +26,9 @@ export { IngestionFactory } from './ingestion-factory.js';
26
26
  // Polymorphic search factory (recommended for automatic mode detection)
27
27
  // Re-exported from core for convenience
28
28
  export { SearchFactory } from './search-factory.js';
29
+ // =============================================================================
30
+ // EXPERIMENTAL: Generator Factory
31
+ // =============================================================================
32
+ // Generator factory for creating response generators (experimental)
33
+ export { createResponseGenerator, createGenerateFunctionFromModel, getDefaultGeneratorModel, listGeneratorModels, isValidGeneratorModel, getRecommendedGenerator } from './generator-factory.js';
29
34
  //# sourceMappingURL=index.js.map
@@ -296,8 +296,7 @@ export class IngestionFactory {
296
296
  // Preserve custom error messages for model mismatch and mode mismatch
297
297
  if (error instanceof Error && (error.message.includes('Model mismatch') ||
298
298
  error.message.includes('Mode mismatch') ||
299
- error.message.includes('--force-rebuild') ||
300
- error.message.includes('--rebuild-if-needed'))) {
299
+ error.message.includes('--force-rebuild'))) {
301
300
  throw error; // Re-throw custom validation errors as-is
302
301
  }
303
302
  throw createFactoryCreationError('IngestionFactory', error instanceof Error ? error.message : 'Unknown error', { operationContext: 'ingestion pipeline creation' });
@@ -366,13 +365,10 @@ export class IngestionFactory {
366
365
  `❌ Model mismatch: Database is configured for '${existingSystemInfo.modelName}', but '${effectiveModel}' was requested.`,
367
366
  '',
368
367
  '🛠️ How to fix this:',
369
- ' 1. Use --force-rebuild to change models:',
368
+ ' 1. Use --force-rebuild to rebuild from scratch:',
370
369
  ' raglite ingest <path> --model ' + effectiveModel + ' --force-rebuild',
371
370
  '',
372
- ' 2. Or use --rebuild-if-needed for automatic handling:',
373
- ' raglite ingest <path> --model ' + effectiveModel + ' --rebuild-if-needed',
374
- '',
375
- ' 3. Or continue using the existing model:',
371
+ ' 2. Or continue using the existing model:',
376
372
  ' raglite ingest <path> # Uses ' + existingSystemInfo.modelName,
377
373
  '',
378
374
  '🔍 Model switching requires rebuilding the vector index because different models',
@@ -281,6 +281,17 @@ export class SearchFactory {
281
281
  enhancedMessage += '\n The index was created with a different model. Rebuild the index:';
282
282
  enhancedMessage += '\n raglite ingest <directory> --force-rebuild';
283
283
  }
284
+ else if (error.message.includes('Cannot enlarge memory') ||
285
+ error.message.includes('WebAssembly memory limit') ||
286
+ error.message.includes('memory limit exceeded')) {
287
+ enhancedMessage += '\n\n💡 WebAssembly memory limit exceeded.';
288
+ enhancedMessage += '\n Your vector index is too large for the 2GB WebAssembly memory limit.';
289
+ enhancedMessage += '\n Solutions:';
290
+ enhancedMessage += '\n 1. Increase Node.js memory: node --max-old-space-size=4096 ...';
291
+ enhancedMessage += '\n 2. Split your data into smaller indexes';
292
+ enhancedMessage += '\n 3. Use a smaller embedding model (fewer dimensions)';
293
+ enhancedMessage += '\n 4. Rebuild the index with fewer vectors';
294
+ }
284
295
  return new Error(enhancedMessage);
285
296
  }
286
297
  return new Error(`SearchFactory.create failed: Unknown error`);
@@ -86,11 +86,12 @@ export declare class IndexManager {
86
86
  saveGroupedIndex(textEmbeddings: EmbeddingResult[], imageEmbeddings: EmbeddingResult[]): Promise<void>;
87
87
  /**
88
88
  * Search for similar vectors
89
+ * Now async due to worker-based VectorIndex implementation
89
90
  */
90
- search(queryVector: Float32Array, k?: number, contentType?: 'text' | 'image' | 'combined'): {
91
+ search(queryVector: Float32Array, k?: number, contentType?: 'text' | 'image' | 'combined'): Promise<{
91
92
  embeddingIds: string[];
92
93
  distances: number[];
93
- };
94
+ }>;
94
95
  /**
95
96
  * Get index statistics
96
97
  */
@@ -109,8 +110,27 @@ export declare class IndexManager {
109
110
  */
110
111
  private unhashEmbeddingId;
111
112
  /**
112
- * Close database connection
113
+ * Close database connection and cleanup vector index worker
113
114
  */
114
115
  close(): Promise<void>;
116
+ /**
117
+ * Reset the vector index by clearing all vectors while keeping the index structure.
118
+ * This is a safer alternative to file deletion that avoids file locking issues on Windows.
119
+ *
120
+ * The reset operation:
121
+ * 1. Clears in-memory HNSW index
122
+ * 2. Clears in-memory vector storage and ID mappings
123
+ * 3. Reinitializes an empty index with the same parameters
124
+ * 4. Saves the empty index to disk (overwrites existing file)
125
+ *
126
+ * @returns Promise that resolves when reset is complete
127
+ */
128
+ reset(): Promise<void>;
129
+ /**
130
+ * Check if the index has any vectors
131
+ * @returns true if the index contains vectors, false if empty
132
+ * Now async due to worker-based VectorIndex implementation
133
+ */
134
+ hasVectors(): Promise<boolean>;
115
135
  }
116
136
  //# sourceMappingURL=index-manager.d.ts.map
@@ -64,7 +64,7 @@ export class IndexManager {
64
64
  this.hashEmbeddingId(chunk.embedding_id); // This will populate the mapping
65
65
  }
66
66
  this.isInitialized = true;
67
- const vectorCount = this.vectorIndex.getCurrentCount();
67
+ const vectorCount = await this.vectorIndex.getCurrentCount();
68
68
  console.log(`Index manager initialized with ${vectorCount} vectors${this.textIndex && this.imageIndex ? ' (multi-graph mode)' : ''}`);
69
69
  }
70
70
  catch (error) {
@@ -145,17 +145,18 @@ export class IndexManager {
145
145
  vector: embedding.vector
146
146
  }));
147
147
  // Check if we need to resize the index before adding
148
- const currentCount = this.vectorIndex.getCurrentCount();
149
- const newCount = currentCount + vectors.length;
148
+ const initialCount = await this.vectorIndex.getCurrentCount();
149
+ const newCount = initialCount + vectors.length;
150
150
  const currentCapacity = 100000; // This should match the initial capacity
151
151
  if (newCount > currentCapacity * 0.9) {
152
152
  const newCapacity = Math.ceil(newCount * 1.5);
153
153
  console.log(`Resizing index from ${currentCapacity} to ${newCapacity} to accommodate new vectors`);
154
- this.vectorIndex.resizeIndex(newCapacity);
154
+ await this.vectorIndex.resizeIndex(newCapacity);
155
155
  }
156
156
  // Add vectors incrementally (this is the key requirement - no rebuild needed)
157
- this.vectorIndex.addVectors(vectors);
158
- console.log(`Incrementally added ${embeddings.length} vectors to index (total: ${this.vectorIndex.getCurrentCount()})`);
157
+ await this.vectorIndex.addVectors(vectors);
158
+ const finalCount = await this.vectorIndex.getCurrentCount();
159
+ console.log(`Incrementally added ${embeddings.length} vectors to index (total: ${finalCount})`);
159
160
  // Save the updated index
160
161
  await this.saveIndex();
161
162
  }
@@ -223,7 +224,7 @@ export class IndexManager {
223
224
  const currentCapacity = 100000; // Default capacity
224
225
  if (chunkData.length > currentCapacity * 0.8) {
225
226
  const newCapacity = Math.ceil(chunkData.length * 1.5);
226
- this.vectorIndex.resizeIndex(newCapacity);
227
+ await this.vectorIndex.resizeIndex(newCapacity);
227
228
  console.log(`Resized index capacity to ${newCapacity} for ${chunkData.length} chunks`);
228
229
  }
229
230
  // Update model version if provided
@@ -279,7 +280,7 @@ export class IndexManager {
279
280
  const currentCapacity = 100000;
280
281
  if (chunkData.length > currentCapacity * 0.8) {
281
282
  const newCapacity = Math.ceil(chunkData.length * 1.5);
282
- this.vectorIndex.resizeIndex(newCapacity);
283
+ await this.vectorIndex.resizeIndex(newCapacity);
283
284
  console.log(`Resized index capacity to ${newCapacity}`);
284
285
  }
285
286
  // Re-generate embeddings for all chunks
@@ -294,7 +295,7 @@ export class IndexManager {
294
295
  id: this.hashEmbeddingId(embedding.embedding_id),
295
296
  vector: embedding.vector
296
297
  }));
297
- this.vectorIndex.addVectors(vectors);
298
+ await this.vectorIndex.addVectors(vectors);
298
299
  console.log(`Added ${vectors.length} vectors to rebuilt index`);
299
300
  // Update model version
300
301
  await this.updateModelVersion(embeddingEngine.getModelVersion());
@@ -414,12 +415,12 @@ export class IndexManager {
414
415
  // Create text-only index
415
416
  this.textIndex = new VectorIndex(`${this.indexPath}.text`, this.vectorIndexOptions);
416
417
  await this.textIndex.initialize();
417
- this.textIndex.addVectors(indexData.textVectors);
418
+ await this.textIndex.addVectors(indexData.textVectors);
418
419
  console.log(`✓ Text index created with ${indexData.textVectors.length} vectors`);
419
420
  // Create image-only index
420
421
  this.imageIndex = new VectorIndex(`${this.indexPath}.image`, this.vectorIndexOptions);
421
422
  await this.imageIndex.initialize();
422
- this.imageIndex.addVectors(indexData.imageVectors);
423
+ await this.imageIndex.addVectors(indexData.imageVectors);
423
424
  console.log(`✓ Image index created with ${indexData.imageVectors.length} vectors`);
424
425
  console.log('✓ Specialized indexes ready for content type filtering');
425
426
  }
@@ -475,8 +476,9 @@ export class IndexManager {
475
476
  }
476
477
  /**
477
478
  * Search for similar vectors
479
+ * Now async due to worker-based VectorIndex implementation
478
480
  */
479
- search(queryVector, k = 5, contentType) {
481
+ async search(queryVector, k = 5, contentType) {
480
482
  if (!this.isInitialized) {
481
483
  throw new Error('Index manager not initialized');
482
484
  }
@@ -499,7 +501,7 @@ export class IndexManager {
499
501
  // No specialized indexes (text-only mode) - ignore contentType and use combined index
500
502
  targetIndex = this.vectorIndex;
501
503
  }
502
- const results = targetIndex.search(queryVector, k);
504
+ const results = await targetIndex.search(queryVector, k);
503
505
  // Convert numeric IDs back to embedding IDs
504
506
  const embeddingIds = results.neighbors.map(id => this.unhashEmbeddingId(id));
505
507
  return {
@@ -514,7 +516,7 @@ export class IndexManager {
514
516
  if (!this.db) {
515
517
  throw new Error('Database not initialized');
516
518
  }
517
- const totalVectors = this.vectorIndex.getCurrentCount();
519
+ const totalVectors = await this.vectorIndex.getCurrentCount();
518
520
  try {
519
521
  const systemInfo = await getSystemInfo(this.db);
520
522
  const modelVersion = systemInfo?.modelVersion || null;
@@ -586,13 +588,80 @@ export class IndexManager {
586
588
  return embeddingId;
587
589
  }
588
590
  /**
589
- * Close database connection
591
+ * Close database connection and cleanup vector index worker
590
592
  */
591
593
  async close() {
592
594
  if (this.db) {
593
595
  await this.db.close();
594
596
  this.db = null;
595
597
  }
598
+ // Clean up vector index worker to free WebAssembly memory
599
+ if (this.vectorIndex && typeof this.vectorIndex.cleanup === 'function') {
600
+ await this.vectorIndex.cleanup();
601
+ }
602
+ // Also clean up specialized indexes
603
+ if (this.textIndex && typeof this.textIndex.cleanup === 'function') {
604
+ await this.textIndex.cleanup();
605
+ }
606
+ if (this.imageIndex && typeof this.imageIndex.cleanup === 'function') {
607
+ await this.imageIndex.cleanup();
608
+ }
609
+ }
610
+ /**
611
+ * Reset the vector index by clearing all vectors while keeping the index structure.
612
+ * This is a safer alternative to file deletion that avoids file locking issues on Windows.
613
+ *
614
+ * The reset operation:
615
+ * 1. Clears in-memory HNSW index
616
+ * 2. Clears in-memory vector storage and ID mappings
617
+ * 3. Reinitializes an empty index with the same parameters
618
+ * 4. Saves the empty index to disk (overwrites existing file)
619
+ *
620
+ * @returns Promise that resolves when reset is complete
621
+ */
622
+ async reset() {
623
+ console.log('🔄 Starting index reset...');
624
+ const startTime = Date.now();
625
+ try {
626
+ // Clear in-memory mappings
627
+ const previousVectorCount = await this.vectorIndex.getCurrentCount();
628
+ this.hashToEmbeddingId.clear();
629
+ this.embeddingIdToHash.clear();
630
+ // Clear grouped embeddings if any
631
+ this.groupedEmbeddings = undefined;
632
+ // Clear specialized indexes if they exist
633
+ if (this.textIndex) {
634
+ this.textIndex = undefined;
635
+ }
636
+ if (this.imageIndex) {
637
+ this.imageIndex = undefined;
638
+ }
639
+ // Reset the vector index (clears all vectors and reinitializes empty HNSW graph)
640
+ console.log(' Resetting HNSW index...');
641
+ await this.vectorIndex.reset();
642
+ // Save the empty index to disk (this overwrites the existing file)
643
+ console.log(' Saving empty index to disk...');
644
+ await this.vectorIndex.saveIndex();
645
+ const resetTimeMs = Date.now() - startTime;
646
+ const currentCount = await this.vectorIndex.getCurrentCount();
647
+ console.log(`✓ Index reset complete in ${resetTimeMs}ms`);
648
+ console.log(` Vectors cleared: ${previousVectorCount}`);
649
+ console.log(` Current vector count: ${currentCount}`);
650
+ }
651
+ catch (error) {
652
+ const resetTimeMs = Date.now() - startTime;
653
+ console.error(`❌ Index reset failed after ${resetTimeMs}ms:`, error);
654
+ throw new Error(`Failed to reset index: ${error instanceof Error ? error.message : 'Unknown error'}`);
655
+ }
656
+ }
657
+ /**
658
+ * Check if the index has any vectors
659
+ * @returns true if the index contains vectors, false if empty
660
+ * Now async due to worker-based VectorIndex implementation
661
+ */
662
+ async hasVectors() {
663
+ const count = await this.vectorIndex.getCurrentCount();
664
+ return count > 0;
596
665
  }
597
666
  }
598
667
  //# sourceMappingURL=index-manager.js.map
@@ -59,7 +59,8 @@ export { CrossEncoderReranker, createTextRerankFunction } from './text/reranker.
59
59
  export { countTokens } from './text/tokenizer.js';
60
60
  export type { RerankingStrategyType, RerankingConfig } from './core/reranking-config.js';
61
61
  export { validateRerankingStrategy, validateRerankingConfig, getDefaultRerankingConfig, isStrategySupported, getSupportedStrategies, RerankingConfigBuilder, DEFAULT_TEXT_RERANKING_CONFIG, DEFAULT_MULTIMODAL_RERANKING_CONFIG } from './core/reranking-config.js';
62
- export { openDatabase, initializeSchema, insertDocument, insertChunk, upsertDocument, getChunksByEmbeddingIds, type DatabaseConnection } from './core/db.js';
62
+ export { openDatabase, initializeSchema, insertDocument, insertChunk, upsertDocument, getChunksByEmbeddingIds, resetDatabase, hasDatabaseData, type DatabaseConnection, type DatabaseResetOptions, type DatabaseResetResult } from './core/db.js';
63
+ export { KnowledgeBaseManager, type KnowledgeBaseResetOptions, type KnowledgeBaseResetResult } from './core/knowledge-base-manager.js';
63
64
  export { IndexManager } from './index-manager.js';
64
65
  export { VectorIndex } from './core/vector-index.js';
65
66
  export { config, getModelDefaults, type CoreConfig, type ExtensibleConfig, type ModelDefaults, EXIT_CODES, ConfigurationError, getDefaultModelCachePath, handleUnrecoverableError, logError } from './core/config.js';
@@ -72,4 +73,13 @@ export type { Chunk, Preprocessor, PreprocessorOptions, PreprocessingConfig } fr
72
73
  export type { IngestionOptions, IngestionResult } from './core/ingestion.js';
73
74
  export { handleError, safeExecute, ErrorCategory, ErrorSeverity, createError, type ErrorContext } from './core/error-handler.js';
74
75
  export { APIError, IngestionError, SearchError, ResourceError, ModelCompatibilityError, ErrorFactory, CommonErrors, handleAPIError } from './api-errors.js';
76
+ export { createResponseGenerator, createGenerateFunctionFromModel, getDefaultGeneratorModel, listGeneratorModels, isValidGeneratorModel, getRecommendedGenerator } from './factories/generator-factory.js';
77
+ export type { ResponseGenerator, GeneratorModelType, GenerationRequest, GenerationResult, GeneratorCapabilities, GeneratorRequirements, GeneratorModelInfo, GeneratorValidationResult, GeneratorCreationOptions, GenerateFunction, CreateGeneratorFunction } from './core/response-generator.js';
78
+ export { GeneratorValidationError, GenerationError, ContextWindowError } from './core/response-generator.js';
79
+ export { supportsStreaming, isInstructModel, createGenerateFunction } from './core/response-generator.js';
80
+ export { SUPPORTED_GENERATORS, DEFAULT_GENERATOR_MODEL, GeneratorRegistry, getGeneratorType, isInstructionTunedModel, getMaxContextLength, getRecommendedSettings, getDefaultMaxChunksForContext } from './core/generator-registry.js';
81
+ export { DEFAULT_SYSTEM_PROMPT, formatContextChunks, buildPrompt, estimateTokenCount, type ContextFormattingOptions, type FormattedContext, type PromptBuildOptions, type BuiltPrompt } from './core/prompt-templates.js';
82
+ export { InstructGenerator } from './text/generators/instruct-generator.js';
83
+ export { CausalLMGenerator } from './text/generators/causal-lm-generator.js';
84
+ export type { ExtendedSearchOptions, SearchResultWithGeneration } from './core/search.js';
75
85
  //# sourceMappingURL=index.d.ts.map
package/dist/esm/index.js CHANGED
@@ -83,7 +83,9 @@ export { validateRerankingStrategy, validateRerankingConfig, getDefaultReranking
83
83
  // CORE INFRASTRUCTURE (FOR ADVANCED USERS)
84
84
  // =============================================================================
85
85
  // Database operations
86
- export { openDatabase, initializeSchema, insertDocument, insertChunk, upsertDocument, getChunksByEmbeddingIds } from './core/db.js';
86
+ export { openDatabase, initializeSchema, insertDocument, insertChunk, upsertDocument, getChunksByEmbeddingIds, resetDatabase, hasDatabaseData } from './core/db.js';
87
+ // Knowledge Base Manager (for reset operations)
88
+ export { KnowledgeBaseManager } from './core/knowledge-base-manager.js';
87
89
  // Vector index management
88
90
  export { IndexManager } from './index-manager.js';
89
91
  export { VectorIndex } from './core/vector-index.js';
@@ -107,4 +109,20 @@ export { resolveRagLitePaths, ensureRagLiteStructure, migrateToRagLiteStructure,
107
109
  export { handleError, safeExecute, ErrorCategory, ErrorSeverity, createError } from './core/error-handler.js';
108
110
  // API-specific errors
109
111
  export { APIError, IngestionError, SearchError, ResourceError, ModelCompatibilityError, ErrorFactory, CommonErrors, handleAPIError } from './api-errors.js';
112
+ // =============================================================================
113
+ // EXPERIMENTAL: RESPONSE GENERATION
114
+ // =============================================================================
115
+ // Generator factory functions
116
+ export { createResponseGenerator, createGenerateFunctionFromModel, getDefaultGeneratorModel, listGeneratorModels, isValidGeneratorModel, getRecommendedGenerator } from './factories/generator-factory.js';
117
+ // Generator errors
118
+ export { GeneratorValidationError, GenerationError, ContextWindowError } from './core/response-generator.js';
119
+ // Generator utilities
120
+ export { supportsStreaming, isInstructModel, createGenerateFunction } from './core/response-generator.js';
121
+ // Generator registry
122
+ export { SUPPORTED_GENERATORS, DEFAULT_GENERATOR_MODEL, GeneratorRegistry, getGeneratorType, isInstructionTunedModel, getMaxContextLength, getRecommendedSettings, getDefaultMaxChunksForContext } from './core/generator-registry.js';
123
+ // Prompt templates
124
+ export { DEFAULT_SYSTEM_PROMPT, formatContextChunks, buildPrompt, estimateTokenCount } from './core/prompt-templates.js';
125
+ // Generator implementations
126
+ export { InstructGenerator } from './text/generators/instruct-generator.js';
127
+ export { CausalLMGenerator } from './text/generators/causal-lm-generator.js';
110
128
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,65 @@
1
+ /**
2
+ * TEXT IMPLEMENTATION — Causal LM Generator for DistilGPT2
3
+ *
4
+ * Implements ResponseGenerator interface for causal language models.
5
+ * Supports Xenova/distilgpt2 for fast, basic text generation.
6
+ *
7
+ * Features:
8
+ * - Simple prompt formatting (no chat template)
9
+ * - Fast generation with smaller model
10
+ * - Streaming generation support
11
+ * - Resource management via ResourceManager
12
+ *
13
+ * Note: Causal LM models don't support system prompts, so responses
14
+ * may be less focused than instruction-tuned models.
15
+ *
16
+ * @experimental This feature is experimental and may change in future versions.
17
+ */
18
+ import '../../dom-polyfills.js';
19
+ import { BaseResponseGenerator, type GeneratorOptions } from '../../core/abstract-generator.js';
20
+ /**
21
+ * Causal LM generator implementation for DistilGPT2
22
+ *
23
+ * Uses causal language models that generate text based on simple prompts.
24
+ * Faster but may produce less focused responses than instruct models.
25
+ */
26
+ export declare class CausalLMGenerator extends BaseResponseGenerator {
27
+ private pipeline;
28
+ private tokenizer;
29
+ private resourceManager;
30
+ private resourceId?;
31
+ constructor(modelName: string, options?: GeneratorOptions);
32
+ /**
33
+ * Load the causal LM model using transformers.js
34
+ */
35
+ loadModel(): Promise<void>;
36
+ /**
37
+ * Clean up model resources
38
+ */
39
+ cleanup(): Promise<void>;
40
+ /**
41
+ * Generate text using the causal LM model
42
+ */
43
+ protected generateText(prompt: string, options: {
44
+ maxTokens: number;
45
+ temperature: number;
46
+ topP: number;
47
+ topK: number;
48
+ repetitionPenalty: number;
49
+ stopSequences: string[];
50
+ }): Promise<{
51
+ text: string;
52
+ promptTokens: number;
53
+ completionTokens: number;
54
+ finishReason: 'complete' | 'length' | 'stop_sequence' | 'error';
55
+ }>;
56
+ /**
57
+ * Generate text with streaming output
58
+ */
59
+ generateStream(request: import('../../core/response-generator.js').GenerationRequest): AsyncIterable<string>;
60
+ /**
61
+ * Count tokens in a text string
62
+ */
63
+ private countTokens;
64
+ }
65
+ //# sourceMappingURL=causal-lm-generator.d.ts.map