@pleaseai/context-please-core 0.2.1 → 0.5.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 (107) hide show
  1. package/README.md +113 -46
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/context.d.ts +37 -12
  4. package/dist/context.d.ts.map +1 -1
  5. package/dist/context.js +199 -73
  6. package/dist/context.js.map +1 -1
  7. package/dist/embedding/base-embedding.d.ts.map +1 -1
  8. package/dist/embedding/base-embedding.js +5 -1
  9. package/dist/embedding/base-embedding.js.map +1 -1
  10. package/dist/embedding/gemini-embedding.d.ts +43 -1
  11. package/dist/embedding/gemini-embedding.d.ts.map +1 -1
  12. package/dist/embedding/gemini-embedding.js +160 -31
  13. package/dist/embedding/gemini-embedding.js.map +1 -1
  14. package/dist/embedding/huggingface-embedding.d.ts +70 -0
  15. package/dist/embedding/huggingface-embedding.d.ts.map +1 -0
  16. package/dist/embedding/huggingface-embedding.js +270 -0
  17. package/dist/embedding/huggingface-embedding.js.map +1 -0
  18. package/dist/embedding/index.d.ts +3 -2
  19. package/dist/embedding/index.d.ts.map +1 -1
  20. package/dist/embedding/index.js +3 -2
  21. package/dist/embedding/index.js.map +1 -1
  22. package/dist/embedding/ollama-embedding.d.ts +2 -1
  23. package/dist/embedding/ollama-embedding.d.ts.map +1 -1
  24. package/dist/embedding/ollama-embedding.js +5 -5
  25. package/dist/embedding/ollama-embedding.js.map +1 -1
  26. package/dist/embedding/openai-embedding.d.ts +2 -1
  27. package/dist/embedding/openai-embedding.d.ts.map +1 -1
  28. package/dist/embedding/openai-embedding.js +10 -10
  29. package/dist/embedding/openai-embedding.js.map +1 -1
  30. package/dist/embedding/voyageai-embedding.d.ts +2 -1
  31. package/dist/embedding/voyageai-embedding.d.ts.map +1 -1
  32. package/dist/embedding/voyageai-embedding.js +23 -23
  33. package/dist/embedding/voyageai-embedding.js.map +1 -1
  34. package/dist/index.d.ts +4 -4
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +4 -4
  37. package/dist/index.js.map +1 -1
  38. package/dist/splitter/ast-splitter.d.ts +1 -1
  39. package/dist/splitter/ast-splitter.d.ts.map +1 -1
  40. package/dist/splitter/ast-splitter.js +29 -15
  41. package/dist/splitter/ast-splitter.js.map +1 -1
  42. package/dist/splitter/index.d.ts +4 -4
  43. package/dist/splitter/index.d.ts.map +1 -1
  44. package/dist/splitter/index.js +1 -1
  45. package/dist/splitter/index.js.map +1 -1
  46. package/dist/splitter/langchain-splitter.d.ts +1 -1
  47. package/dist/splitter/langchain-splitter.d.ts.map +1 -1
  48. package/dist/splitter/langchain-splitter.js.map +1 -1
  49. package/dist/sync/merkle.d.ts.map +1 -1
  50. package/dist/sync/merkle.js +9 -9
  51. package/dist/sync/merkle.js.map +1 -1
  52. package/dist/sync/synchronizer.d.ts.map +1 -1
  53. package/dist/sync/synchronizer.js +15 -15
  54. package/dist/sync/synchronizer.js.map +1 -1
  55. package/dist/types.d.ts.map +1 -1
  56. package/dist/utils/env-manager.d.ts.map +1 -1
  57. package/dist/utils/env-manager.js +3 -3
  58. package/dist/utils/env-manager.js.map +1 -1
  59. package/dist/utils/index.d.ts.map +1 -1
  60. package/dist/utils/index.js.map +1 -1
  61. package/dist/vectordb/base/base-vector-database.d.ts +1 -1
  62. package/dist/vectordb/base/base-vector-database.d.ts.map +1 -1
  63. package/dist/vectordb/base/base-vector-database.js.map +1 -1
  64. package/dist/vectordb/factory.d.ts +26 -7
  65. package/dist/vectordb/factory.d.ts.map +1 -1
  66. package/dist/vectordb/factory.js +68 -2
  67. package/dist/vectordb/factory.js.map +1 -1
  68. package/dist/vectordb/faiss-vectordb.d.ts +162 -0
  69. package/dist/vectordb/faiss-vectordb.d.ts.map +1 -0
  70. package/dist/vectordb/faiss-vectordb.js +762 -0
  71. package/dist/vectordb/faiss-vectordb.js.map +1 -0
  72. package/dist/vectordb/index.d.ts +10 -9
  73. package/dist/vectordb/index.d.ts.map +1 -1
  74. package/dist/vectordb/index.js +28 -9
  75. package/dist/vectordb/index.js.map +1 -1
  76. package/dist/vectordb/milvus-restful-vectordb.d.ts +6 -5
  77. package/dist/vectordb/milvus-restful-vectordb.d.ts.map +1 -1
  78. package/dist/vectordb/milvus-restful-vectordb.js +136 -136
  79. package/dist/vectordb/milvus-restful-vectordb.js.map +1 -1
  80. package/dist/vectordb/milvus-vectordb.d.ts +5 -4
  81. package/dist/vectordb/milvus-vectordb.d.ts.map +1 -1
  82. package/dist/vectordb/milvus-vectordb.js +31 -31
  83. package/dist/vectordb/milvus-vectordb.js.map +1 -1
  84. package/dist/vectordb/qdrant-vectordb.d.ts +28 -3
  85. package/dist/vectordb/qdrant-vectordb.d.ts.map +1 -1
  86. package/dist/vectordb/qdrant-vectordb.js +298 -73
  87. package/dist/vectordb/qdrant-vectordb.js.map +1 -1
  88. package/dist/vectordb/sparse/index.d.ts +2 -2
  89. package/dist/vectordb/sparse/index.d.ts.map +1 -1
  90. package/dist/vectordb/sparse/index.js +4 -4
  91. package/dist/vectordb/sparse/index.js.map +1 -1
  92. package/dist/vectordb/sparse/simple-bm25.d.ts +13 -2
  93. package/dist/vectordb/sparse/simple-bm25.d.ts.map +1 -1
  94. package/dist/vectordb/sparse/simple-bm25.js +80 -9
  95. package/dist/vectordb/sparse/simple-bm25.js.map +1 -1
  96. package/dist/vectordb/sparse/sparse-vector-generator.d.ts +7 -7
  97. package/dist/vectordb/sparse/sparse-vector-generator.d.ts.map +1 -1
  98. package/dist/vectordb/sparse/types.d.ts.map +1 -1
  99. package/dist/vectordb/types.d.ts +12 -12
  100. package/dist/vectordb/types.d.ts.map +1 -1
  101. package/dist/vectordb/types.js +1 -1
  102. package/dist/vectordb/types.js.map +1 -1
  103. package/dist/vectordb/zilliz-utils.d.ts +10 -10
  104. package/dist/vectordb/zilliz-utils.d.ts.map +1 -1
  105. package/dist/vectordb/zilliz-utils.js +16 -17
  106. package/dist/vectordb/zilliz-utils.js.map +1 -1
  107. package/package.json +16 -13
package/dist/context.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Splitter } from './splitter';
2
- import { Embedding } from './embedding';
3
- import { VectorDatabase } from './vectordb';
4
- import { SemanticSearchResult } from './types';
1
+ import type { Embedding } from './embedding';
2
+ import type { Splitter } from './splitter';
3
+ import type { SemanticSearchResult } from './types';
4
+ import type { VectorDatabase } from './vectordb';
5
5
  import { FileSynchronizer } from './sync/synchronizer';
6
6
  export interface ContextConfig {
7
7
  embedding?: Embedding;
@@ -106,6 +106,31 @@ export declare class Context {
106
106
  * @returns Whether index exists
107
107
  */
108
108
  hasIndex(codebasePath: string): Promise<boolean>;
109
+ /**
110
+ * Get collection statistics from vector database
111
+ *
112
+ * Retrieves actual counts of indexed files and chunks by querying the vector database.
113
+ * This is more accurate than snapshot data which may be out of sync.
114
+ *
115
+ * @param codebasePath Codebase path to get stats for
116
+ * @returns Object with indexedFiles (unique files) and totalChunks, or null if:
117
+ * - Collection doesn't exist in vector database
118
+ * - Collection cannot be loaded (expected error)
119
+ * - Query fails with known recoverable error
120
+ *
121
+ * @throws Error for unexpected failures (network errors, auth failures, programming bugs)
122
+ *
123
+ * @remarks
124
+ * - Uses a limit of 100k chunks. For larger codebases, stats may be underreported.
125
+ * - Queries only relativePath field to minimize data transfer
126
+ * - File count is derived by counting unique relativePath values
127
+ * - Performance: O(n) where n is min(actualChunks, 100000)
128
+ * - Warns if limit is reached (may indicate incomplete stats)
129
+ */
130
+ getCollectionStats(codebasePath: string): Promise<{
131
+ indexedFiles: number;
132
+ totalChunks: number;
133
+ } | null>;
109
134
  /**
110
135
  * Clear index
111
136
  * @param codebasePath Codebase path to clear index for
@@ -155,16 +180,16 @@ export declare class Context {
155
180
  */
156
181
  private getCodeFiles;
157
182
  /**
158
- * Process a list of files with streaming chunk processing
159
- * @param filePaths Array of file paths to process
160
- * @param codebasePath Base path for the codebase
161
- * @param onFileProcessed Callback called when each file is processed
162
- * @returns Object with processed file count and total chunk count
163
- */
183
+ * Process a list of files with streaming chunk processing
184
+ * @param filePaths Array of file paths to process
185
+ * @param codebasePath Base path for the codebase
186
+ * @param onFileProcessed Callback called when each file is processed
187
+ * @returns Object with processed file count and total chunk count
188
+ */
164
189
  private processFileList;
165
190
  /**
166
- * Process accumulated chunk buffer
167
- */
191
+ * Process accumulated chunk buffer
192
+ */
168
193
  private processChunkBuffer;
169
194
  /**
170
195
  * Process a batch of chunks
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
package/dist/context.js CHANGED
@@ -34,20 +34,40 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.Context = void 0;
37
- const splitter_1 = require("./splitter");
37
+ const crypto = __importStar(require("node:crypto"));
38
+ const fs = __importStar(require("node:fs"));
39
+ const path = __importStar(require("node:path"));
38
40
  const embedding_1 = require("./embedding");
39
- const qdrant_vectordb_1 = require("./vectordb/qdrant-vectordb");
40
- const env_manager_1 = require("./utils/env-manager");
41
- const fs = __importStar(require("fs"));
42
- const path = __importStar(require("path"));
43
- const crypto = __importStar(require("crypto"));
41
+ const splitter_1 = require("./splitter");
44
42
  const synchronizer_1 = require("./sync/synchronizer");
43
+ const env_manager_1 = require("./utils/env-manager");
44
+ const qdrant_vectordb_1 = require("./vectordb/qdrant-vectordb");
45
45
  const DEFAULT_SUPPORTED_EXTENSIONS = [
46
46
  // Programming languages
47
- '.ts', '.tsx', '.js', '.jsx', '.py', '.java', '.cpp', '.c', '.h', '.hpp',
48
- '.cs', '.go', '.rs', '.php', '.rb', '.swift', '.kt', '.scala', '.m', '.mm',
47
+ '.ts',
48
+ '.tsx',
49
+ '.js',
50
+ '.jsx',
51
+ '.py',
52
+ '.java',
53
+ '.cpp',
54
+ '.c',
55
+ '.h',
56
+ '.hpp',
57
+ '.cs',
58
+ '.go',
59
+ '.rs',
60
+ '.php',
61
+ '.rb',
62
+ '.swift',
63
+ '.kt',
64
+ '.scala',
65
+ '.m',
66
+ '.mm',
49
67
  // Text and markup files
50
- '.md', '.markdown', '.ipynb',
68
+ '.md',
69
+ '.markdown',
70
+ '.ipynb',
51
71
  // '.txt', '.json', '.yaml', '.yml', '.xml', '.html', '.htm',
52
72
  // '.css', '.scss', '.less', '.sql', '.sh', '.bash', '.env'
53
73
  ];
@@ -93,9 +113,23 @@ const DEFAULT_IGNORE_PATTERNS = [
93
113
  '*.polyfills.js',
94
114
  '*.runtime.js',
95
115
  '*.map', // source map files
96
- 'node_modules', '.git', '.svn', '.hg', 'build', 'dist', 'out',
97
- 'target', '.vscode', '.idea', '__pycache__', '.pytest_cache',
98
- 'coverage', '.nyc_output', 'logs', 'tmp', 'temp'
116
+ 'node_modules',
117
+ '.git',
118
+ '.svn',
119
+ '.hg',
120
+ 'build',
121
+ 'dist',
122
+ 'out',
123
+ 'target',
124
+ '.vscode',
125
+ '.idea',
126
+ '__pycache__',
127
+ '.pytest_cache',
128
+ 'coverage',
129
+ '.nyc_output',
130
+ 'logs',
131
+ 'tmp',
132
+ 'temp',
99
133
  ];
100
134
  class Context {
101
135
  constructor(config = {}) {
@@ -104,7 +138,7 @@ class Context {
104
138
  this.embedding = config.embedding || new embedding_1.OpenAIEmbedding({
105
139
  apiKey: env_manager_1.envManager.get('OPENAI_API_KEY') || 'your-openai-api-key',
106
140
  model: 'text-embedding-3-small',
107
- ...(env_manager_1.envManager.get('OPENAI_BASE_URL') && { baseURL: env_manager_1.envManager.get('OPENAI_BASE_URL') })
141
+ ...(env_manager_1.envManager.get('OPENAI_BASE_URL') && { baseURL: env_manager_1.envManager.get('OPENAI_BASE_URL') }),
108
142
  });
109
143
  if (!config.vectorDatabase) {
110
144
  throw new Error('VectorDatabase is required. Please provide a vectorDatabase instance in the config.');
@@ -118,18 +152,18 @@ class Context {
118
152
  ...DEFAULT_SUPPORTED_EXTENSIONS,
119
153
  ...(config.supportedExtensions || []),
120
154
  ...(config.customExtensions || []),
121
- ...envCustomExtensions
155
+ ...envCustomExtensions,
122
156
  ];
123
157
  // Remove duplicates
124
158
  this.supportedExtensions = [...new Set(allSupportedExtensions)];
125
- // Load custom ignore patterns from environment variables
159
+ // Load custom ignore patterns from environment variables
126
160
  const envCustomIgnorePatterns = this.getCustomIgnorePatternsFromEnv();
127
161
  // Start with default ignore patterns
128
162
  const allIgnorePatterns = [
129
163
  ...DEFAULT_IGNORE_PATTERNS,
130
164
  ...(config.ignorePatterns || []),
131
165
  ...(config.customIgnorePatterns || []),
132
- ...envCustomIgnorePatterns
166
+ ...envCustomIgnorePatterns,
133
167
  ];
134
168
  // Remove duplicates
135
169
  this.ignorePatterns = [...new Set(allIgnorePatterns)];
@@ -253,7 +287,7 @@ class Context {
253
287
  phase: `Processing files (${fileIndex}/${totalFiles})...`,
254
288
  current: fileIndex,
255
289
  total: totalFiles,
256
- percentage: Math.round(progressPercentage)
290
+ percentage: Math.round(progressPercentage),
257
291
  });
258
292
  });
259
293
  console.log(`[Context] ✅ Codebase indexing completed! Processed ${result.processedFiles} files in total, generated ${result.totalChunks} code chunks`);
@@ -261,12 +295,12 @@ class Context {
261
295
  phase: 'Indexing complete!',
262
296
  current: result.processedFiles,
263
297
  total: codeFiles.length,
264
- percentage: 100
298
+ percentage: 100,
265
299
  });
266
300
  return {
267
301
  indexedFiles: result.processedFiles,
268
302
  totalChunks: result.totalChunks,
269
- status: result.status
303
+ status: result.status,
270
304
  };
271
305
  }
272
306
  async reindexByChange(codebasePath, progressCallback) {
@@ -321,7 +355,7 @@ class Context {
321
355
  updateProgress(`Deleted old chunks for ${file}`);
322
356
  }
323
357
  // Handle added and modified files
324
- const filesToIndex = [...added, ...modified].map(f => path.join(codebasePath, f));
358
+ const filesToIndex = [...added, ...modified].map((f) => path.join(codebasePath, f));
325
359
  if (filesToIndex.length > 0) {
326
360
  await this.processFileList(filesToIndex, codebasePath, (filePath, fileIndex, totalFiles) => {
327
361
  updateProgress(`Indexed ${filePath} (${fileIndex}/${totalFiles})`);
@@ -336,7 +370,7 @@ class Context {
336
370
  const escapedPath = relativePath.replace(/\\/g, '\\\\');
337
371
  const results = await this.vectorDatabase.query(collectionName, `relativePath == "${escapedPath}"`, ['id']);
338
372
  if (results.length > 0) {
339
- const ids = results.map(r => r.id).filter(id => id);
373
+ const ids = results.map((r) => r.id).filter((id) => id);
340
374
  if (ids.length > 0) {
341
375
  await this.vectorDatabase.delete(collectionName, ids);
342
376
  console.log(`[Context] Deleted ${ids.length} chunks for file ${relativePath}`);
@@ -371,6 +405,17 @@ class Context {
371
405
  catch (error) {
372
406
  console.log(`[Context] ⚠️ Collection '${collectionName}' exists but may be empty or not properly indexed:`, error);
373
407
  }
408
+ // Load BM25 model if using Qdrant and model is not yet trained
409
+ if (this.vectorDatabase instanceof qdrant_vectordb_1.QdrantVectorDatabase) {
410
+ const bm25Generator = this.vectorDatabase.getBM25Generator();
411
+ if (!bm25Generator.isTrained()) {
412
+ console.log('[Context] 📂 BM25 model not loaded, attempting to load from disk...');
413
+ const loaded = await this.vectorDatabase.loadBM25Model(collectionName);
414
+ if (!loaded) {
415
+ console.warn('[Context] ⚠️ Failed to load BM25 model. Hybrid search quality may be degraded.');
416
+ }
417
+ }
418
+ }
374
419
  // 1. Generate query vector
375
420
  console.log(`[Context] 🔍 Generating embeddings for query: "${query}"`);
376
421
  const queryEmbedding = await this.embedding.embed(query);
@@ -380,16 +425,16 @@ class Context {
380
425
  const searchRequests = [
381
426
  {
382
427
  data: queryEmbedding.vector,
383
- anns_field: "vector",
384
- param: { "nprobe": 10 },
385
- limit: topK
428
+ anns_field: 'vector',
429
+ param: { nprobe: 10 },
430
+ limit: topK,
386
431
  },
387
432
  {
388
433
  data: query,
389
- anns_field: "sparse_vector",
390
- param: { "drop_ratio_search": 0.2 },
391
- limit: topK
392
- }
434
+ anns_field: 'sparse_vector',
435
+ param: { drop_ratio_search: 0.2 },
436
+ limit: topK,
437
+ },
393
438
  ];
394
439
  console.log(`[Context] 🔍 Search request 1 (dense): anns_field="${searchRequests[0].anns_field}", vector_dim=${queryEmbedding.vector.length}, limit=${searchRequests[0].limit}`);
395
440
  console.log(`[Context] 🔍 Search request 2 (sparse): anns_field="${searchRequests[1].anns_field}", query_text="${query}", limit=${searchRequests[1].limit}`);
@@ -398,20 +443,20 @@ class Context {
398
443
  const searchResults = await this.vectorDatabase.hybridSearch(collectionName, searchRequests, {
399
444
  rerank: {
400
445
  strategy: 'rrf',
401
- params: { k: 100 }
446
+ params: { k: 100 },
402
447
  },
403
448
  limit: topK,
404
- filterExpr
449
+ filterExpr,
405
450
  });
406
451
  console.log(`[Context] 🔍 Raw search results count: ${searchResults.length}`);
407
452
  // 4. Convert to semantic search result format
408
- const results = searchResults.map(result => ({
453
+ const results = searchResults.map((result) => ({
409
454
  content: result.document.content,
410
455
  relativePath: result.document.relativePath,
411
456
  startLine: result.document.startLine,
412
457
  endLine: result.document.endLine,
413
458
  language: result.document.metadata.language || 'unknown',
414
- score: result.score
459
+ score: result.score,
415
460
  }));
416
461
  console.log(`[Context] ✅ Found ${results.length} relevant hybrid results`);
417
462
  if (results.length > 0) {
@@ -426,13 +471,13 @@ class Context {
426
471
  // 2. Search in vector database
427
472
  const searchResults = await this.vectorDatabase.search(collectionName, queryEmbedding.vector, { topK, threshold, filterExpr });
428
473
  // 3. Convert to semantic search result format
429
- const results = searchResults.map(result => ({
474
+ const results = searchResults.map((result) => ({
430
475
  content: result.document.content,
431
476
  relativePath: result.document.relativePath,
432
477
  startLine: result.document.startLine,
433
478
  endLine: result.document.endLine,
434
479
  language: result.document.metadata.language || 'unknown',
435
- score: result.score
480
+ score: result.score,
436
481
  }));
437
482
  console.log(`[Context] ✅ Found ${results.length} relevant results`);
438
483
  return results;
@@ -447,6 +492,80 @@ class Context {
447
492
  const collectionName = this.getCollectionName(codebasePath);
448
493
  return await this.vectorDatabase.hasCollection(collectionName);
449
494
  }
495
+ /**
496
+ * Get collection statistics from vector database
497
+ *
498
+ * Retrieves actual counts of indexed files and chunks by querying the vector database.
499
+ * This is more accurate than snapshot data which may be out of sync.
500
+ *
501
+ * @param codebasePath Codebase path to get stats for
502
+ * @returns Object with indexedFiles (unique files) and totalChunks, or null if:
503
+ * - Collection doesn't exist in vector database
504
+ * - Collection cannot be loaded (expected error)
505
+ * - Query fails with known recoverable error
506
+ *
507
+ * @throws Error for unexpected failures (network errors, auth failures, programming bugs)
508
+ *
509
+ * @remarks
510
+ * - Uses a limit of 100k chunks. For larger codebases, stats may be underreported.
511
+ * - Queries only relativePath field to minimize data transfer
512
+ * - File count is derived by counting unique relativePath values
513
+ * - Performance: O(n) where n is min(actualChunks, 100000)
514
+ * - Warns if limit is reached (may indicate incomplete stats)
515
+ */
516
+ async getCollectionStats(codebasePath) {
517
+ const collectionName = this.getCollectionName(codebasePath);
518
+ // Check if collection exists
519
+ const hasCollection = await this.vectorDatabase.hasCollection(collectionName);
520
+ if (!hasCollection) {
521
+ return null;
522
+ }
523
+ try {
524
+ // Query documents up to limit (may not retrieve all chunks if codebase exceeds this limit)
525
+ // Note: This is a best-effort approach. For codebases with >100k chunks, consider pagination.
526
+ const allDocs = await this.vectorDatabase.query(collectionName, '', // Empty filter expression (no filtering, query all documents)
527
+ ['relativePath'], // Only need file path for counting
528
+ 100000);
529
+ const totalChunks = allDocs.length;
530
+ // Warn if we hit the query limit - actual collection may be larger
531
+ if (totalChunks === 100000) {
532
+ console.warn(`[Context] ⚠️ Retrieved maximum limit of 100k chunks for ${codebasePath}. ` +
533
+ `Actual total may be higher. Stats may be incomplete.`);
534
+ }
535
+ // Filter out documents with missing relativePath before counting
536
+ const validPaths = allDocs
537
+ .map((doc) => doc.relativePath)
538
+ .filter((path) => path != null && path !== '');
539
+ const uniqueFiles = new Set(validPaths).size;
540
+ return {
541
+ indexedFiles: uniqueFiles,
542
+ totalChunks,
543
+ };
544
+ }
545
+ catch (error) {
546
+ const dbType = this.vectorDatabase.constructor.name;
547
+ // Log with full context for debugging
548
+ console.error(`[Context] ❌ Failed to retrieve collection stats\n` +
549
+ ` Codebase: ${codebasePath}\n` +
550
+ ` Collection: ${collectionName}\n` +
551
+ ` Database: ${dbType}\n` +
552
+ ` Error:`, error);
553
+ // Only catch specific expected errors - let unexpected errors propagate
554
+ if (error instanceof Error) {
555
+ const errorMsg = error.message;
556
+ // Known recoverable errors that should return null
557
+ if (errorMsg.includes('collection not loaded') ||
558
+ errorMsg.includes('collection not exist') ||
559
+ errorMsg.includes('Failed to query')) {
560
+ console.warn(`[Context] ⚠️ Collection exists but query failed (recoverable): ${errorMsg}`);
561
+ return null;
562
+ }
563
+ }
564
+ // All other errors indicate serious problems and should propagate
565
+ // (network failures, auth errors, programming bugs, etc.)
566
+ throw error;
567
+ }
568
+ }
450
569
  /**
451
570
  * Clear index
452
571
  * @param codebasePath Codebase path to clear index for
@@ -461,6 +580,10 @@ class Context {
461
580
  if (collectionExists) {
462
581
  await this.vectorDatabase.dropCollection(collectionName);
463
582
  }
583
+ // Delete BM25 model if using Qdrant
584
+ if (this.vectorDatabase instanceof qdrant_vectordb_1.QdrantVectorDatabase) {
585
+ await this.vectorDatabase.deleteBM25Model(collectionName);
586
+ }
464
587
  // Delete snapshot file
465
588
  await synchronizer_1.FileSynchronizer.deleteSnapshot(codebasePath);
466
589
  progressCallback?.({ phase: 'Index cleared', current: 100, total: 100, percentage: 100 });
@@ -475,7 +598,7 @@ class Context {
475
598
  const mergedPatterns = [...DEFAULT_IGNORE_PATTERNS, ...ignorePatterns];
476
599
  const uniquePatterns = [];
477
600
  const patternSet = new Set(mergedPatterns);
478
- patternSet.forEach(pattern => uniquePatterns.push(pattern));
601
+ patternSet.forEach((pattern) => uniquePatterns.push(pattern));
479
602
  this.ignorePatterns = uniquePatterns;
480
603
  console.log(`[Context] 🚫 Updated ignore patterns: ${ignorePatterns.length} new + ${DEFAULT_IGNORE_PATTERNS.length} default = ${this.ignorePatterns.length} total patterns`);
481
604
  }
@@ -490,7 +613,7 @@ class Context {
490
613
  const mergedPatterns = [...this.ignorePatterns, ...customPatterns];
491
614
  const uniquePatterns = [];
492
615
  const patternSet = new Set(mergedPatterns);
493
- patternSet.forEach(pattern => uniquePatterns.push(pattern));
616
+ patternSet.forEach((pattern) => uniquePatterns.push(pattern));
494
617
  this.ignorePatterns = uniquePatterns;
495
618
  console.log(`[Context] 🚫 Added ${customPatterns.length} custom ignore patterns. Total: ${this.ignorePatterns.length} patterns`);
496
619
  }
@@ -584,15 +707,15 @@ class Context {
584
707
  return files;
585
708
  }
586
709
  /**
587
- * Process a list of files with streaming chunk processing
588
- * @param filePaths Array of file paths to process
589
- * @param codebasePath Base path for the codebase
590
- * @param onFileProcessed Callback called when each file is processed
591
- * @returns Object with processed file count and total chunk count
592
- */
710
+ * Process a list of files with streaming chunk processing
711
+ * @param filePaths Array of file paths to process
712
+ * @param codebasePath Base path for the codebase
713
+ * @param onFileProcessed Callback called when each file is processed
714
+ * @returns Object with processed file count and total chunk count
715
+ */
593
716
  async processFileList(filePaths, codebasePath, onFileProcessed) {
594
717
  const isHybrid = this.getIsHybrid();
595
- const EMBEDDING_BATCH_SIZE = Math.max(1, parseInt(env_manager_1.envManager.get('EMBEDDING_BATCH_SIZE') || '100', 10));
718
+ const EMBEDDING_BATCH_SIZE = Math.max(1, Number.parseInt(env_manager_1.envManager.get('EMBEDDING_BATCH_SIZE') || '100', 10));
596
719
  const CHUNK_LIMIT = 450000;
597
720
  console.log(`[Context] 🔧 Using EMBEDDING_BATCH_SIZE: ${EMBEDDING_BATCH_SIZE}`);
598
721
  // For Qdrant hybrid search, we need to train BM25 on the full corpus first
@@ -662,12 +785,15 @@ class Context {
662
785
  if (needsBM25Training && allChunks.length > 0) {
663
786
  console.log(`[Context] 🎓 Training BM25 on ${allChunks.length} chunks for Qdrant hybrid search...`);
664
787
  // Extract corpus texts for BM25 training
665
- const corpus = allChunks.map(item => item.chunk.content);
788
+ const corpus = allChunks.map((item) => item.chunk.content);
666
789
  // Get BM25 generator and train it
667
790
  if (this.vectorDatabase instanceof qdrant_vectordb_1.QdrantVectorDatabase) {
791
+ const collectionName = this.getCollectionName(codebasePath);
668
792
  const bm25Generator = this.vectorDatabase.getBM25Generator();
669
793
  bm25Generator.learn(corpus);
670
794
  console.log(`[Context] ✅ BM25 training completed on ${corpus.length} documents`);
795
+ // Save BM25 model to disk for future use
796
+ await this.vectorDatabase.saveBM25Model(collectionName);
671
797
  }
672
798
  // Now process all chunks in batches
673
799
  console.log(`[Context] 📝 Processing ${allChunks.length} chunks in batches of ${EMBEDDING_BATCH_SIZE}...`);
@@ -702,17 +828,17 @@ class Context {
702
828
  return {
703
829
  processedFiles,
704
830
  totalChunks,
705
- status: limitReached ? 'limit_reached' : 'completed'
831
+ status: limitReached ? 'limit_reached' : 'completed',
706
832
  };
707
833
  }
708
834
  /**
709
- * Process accumulated chunk buffer
710
- */
835
+ * Process accumulated chunk buffer
836
+ */
711
837
  async processChunkBuffer(chunkBuffer) {
712
838
  if (chunkBuffer.length === 0)
713
839
  return;
714
840
  // Extract chunks and ensure they all have the same codebasePath
715
- const chunks = chunkBuffer.map(item => item.chunk);
841
+ const chunks = chunkBuffer.map((item) => item.chunk);
716
842
  const codebasePath = chunkBuffer[0].codebasePath;
717
843
  // Estimate tokens (rough estimation: 1 token ≈ 4 characters)
718
844
  const estimatedTokens = chunks.reduce((sum, chunk) => sum + Math.ceil(chunk.content.length / 4), 0);
@@ -727,7 +853,7 @@ class Context {
727
853
  async processChunkBatch(chunks, codebasePath) {
728
854
  const isHybrid = this.getIsHybrid();
729
855
  // Generate embedding vectors
730
- const chunkContents = chunks.map(chunk => chunk.content);
856
+ const chunkContents = chunks.map((chunk) => chunk.content);
731
857
  const embeddings = await this.embedding.embedBatch(chunkContents);
732
858
  if (isHybrid === true) {
733
859
  // Create hybrid vector documents
@@ -750,8 +876,8 @@ class Context {
750
876
  ...restMetadata,
751
877
  codebasePath,
752
878
  language: chunk.metadata.language || 'unknown',
753
- chunkIndex: index
754
- }
879
+ chunkIndex: index,
880
+ },
755
881
  };
756
882
  });
757
883
  // Store to vector database
@@ -778,8 +904,8 @@ class Context {
778
904
  ...restMetadata,
779
905
  codebasePath,
780
906
  language: chunk.metadata.language || 'unknown',
781
- chunkIndex: index
782
- }
907
+ chunkIndex: index,
908
+ },
783
909
  };
784
910
  });
785
911
  // Store to vector database
@@ -811,7 +937,7 @@ class Context {
811
937
  '.scala': 'scala',
812
938
  '.m': 'objective-c',
813
939
  '.mm': 'objective-c',
814
- '.ipynb': 'jupyter'
940
+ '.ipynb': 'jupyter',
815
941
  };
816
942
  return languageMap[ext] || 'text';
817
943
  }
@@ -838,8 +964,8 @@ class Context {
838
964
  const content = await fs.promises.readFile(filePath, 'utf-8');
839
965
  return content
840
966
  .split('\n')
841
- .map(line => line.trim())
842
- .filter(line => line && !line.startsWith('#')); // Filter out empty lines and comments
967
+ .map((line) => line.trim())
968
+ .filter((line) => line && !line.startsWith('#')); // Filter out empty lines and comments
843
969
  }
844
970
  catch (error) {
845
971
  console.warn(`[Context] ⚠️ Could not read ignore file ${filePath}: ${error}`);
@@ -853,7 +979,7 @@ class Context {
853
979
  */
854
980
  async loadIgnorePatterns(codebasePath) {
855
981
  try {
856
- let fileBasedPatterns = [];
982
+ const fileBasedPatterns = [];
857
983
  // Load all .xxxignore files in codebase directory
858
984
  const ignoreFiles = await this.findIgnoreFiles(codebasePath);
859
985
  for (const ignoreFile of ignoreFiles) {
@@ -887,14 +1013,14 @@ class Context {
887
1013
  const entries = await fs.promises.readdir(codebasePath, { withFileTypes: true });
888
1014
  const ignoreFiles = [];
889
1015
  for (const entry of entries) {
890
- if (entry.isFile() &&
891
- entry.name.startsWith('.') &&
892
- entry.name.endsWith('ignore')) {
1016
+ if (entry.isFile()
1017
+ && entry.name.startsWith('.')
1018
+ && entry.name.endsWith('ignore')) {
893
1019
  ignoreFiles.push(path.join(codebasePath, entry.name));
894
1020
  }
895
1021
  }
896
1022
  if (ignoreFiles.length > 0) {
897
- console.log(`📄 Found ignore files: ${ignoreFiles.map(f => path.basename(f)).join(', ')}`);
1023
+ console.log(`📄 Found ignore files: ${ignoreFiles.map((f) => path.basename(f)).join(', ')}`);
898
1024
  }
899
1025
  return ignoreFiles;
900
1026
  }
@@ -909,7 +1035,7 @@ class Context {
909
1035
  */
910
1036
  async loadGlobalIgnoreFile() {
911
1037
  try {
912
- const homeDir = require('os').homedir();
1038
+ const homeDir = require('node:os').homedir();
913
1039
  const globalIgnorePath = path.join(homeDir, '.context', '.contextignore');
914
1040
  return await this.loadIgnoreFile(globalIgnorePath, 'global .contextignore');
915
1041
  }
@@ -975,7 +1101,7 @@ class Context {
975
1101
  if (pattern.endsWith('/')) {
976
1102
  const dirPattern = pattern.slice(0, -1);
977
1103
  const pathParts = filePath.split('/');
978
- return pathParts.some(part => this.simpleGlobMatch(part, dirPattern));
1104
+ return pathParts.some((part) => this.simpleGlobMatch(part, dirPattern));
979
1105
  }
980
1106
  // Handle file patterns
981
1107
  if (pattern.includes('/')) {
@@ -1015,9 +1141,9 @@ class Context {
1015
1141
  try {
1016
1142
  const extensions = envExtensions
1017
1143
  .split(',')
1018
- .map(ext => ext.trim())
1019
- .filter(ext => ext.length > 0)
1020
- .map(ext => ext.startsWith('.') ? ext : `.${ext}`); // Ensure extensions start with dot
1144
+ .map((ext) => ext.trim())
1145
+ .filter((ext) => ext.length > 0)
1146
+ .map((ext) => ext.startsWith('.') ? ext : `.${ext}`); // Ensure extensions start with dot
1021
1147
  return extensions;
1022
1148
  }
1023
1149
  catch (error) {
@@ -1038,8 +1164,8 @@ class Context {
1038
1164
  try {
1039
1165
  const patterns = envIgnorePatterns
1040
1166
  .split(',')
1041
- .map(pattern => pattern.trim())
1042
- .filter(pattern => pattern.length > 0);
1167
+ .map((pattern) => pattern.trim())
1168
+ .filter((pattern) => pattern.length > 0);
1043
1169
  return patterns;
1044
1170
  }
1045
1171
  catch (error) {
@@ -1055,7 +1181,7 @@ class Context {
1055
1181
  if (customExtensions.length === 0)
1056
1182
  return;
1057
1183
  // Ensure extensions start with dot
1058
- const normalizedExtensions = customExtensions.map(ext => ext.startsWith('.') ? ext : `.${ext}`);
1184
+ const normalizedExtensions = customExtensions.map((ext) => ext.startsWith('.') ? ext : `.${ext}`);
1059
1185
  // Merge current extensions with new custom extensions, avoiding duplicates
1060
1186
  const mergedExtensions = [...this.supportedExtensions, ...normalizedExtensions];
1061
1187
  const uniqueExtensions = [...new Set(mergedExtensions)];
@@ -1072,13 +1198,13 @@ class Context {
1072
1198
  return {
1073
1199
  type: 'ast',
1074
1200
  hasBuiltinFallback: true,
1075
- supportedLanguages: AstCodeSplitter.getSupportedLanguages()
1201
+ supportedLanguages: AstCodeSplitter.getSupportedLanguages(),
1076
1202
  };
1077
1203
  }
1078
1204
  else {
1079
1205
  return {
1080
1206
  type: 'langchain',
1081
- hasBuiltinFallback: false
1207
+ hasBuiltinFallback: false,
1082
1208
  };
1083
1209
  }
1084
1210
  }
@@ -1108,13 +1234,13 @@ class Context {
1108
1234
  strategy: isSupported ? 'ast' : 'langchain',
1109
1235
  reason: isSupported
1110
1236
  ? 'Language supported by AST parser'
1111
- : 'Language not supported by AST, will fallback to LangChain'
1237
+ : 'Language not supported by AST, will fallback to LangChain',
1112
1238
  };
1113
1239
  }
1114
1240
  else {
1115
1241
  return {
1116
1242
  strategy: 'langchain',
1117
- reason: 'Using LangChain splitter directly'
1243
+ reason: 'Using LangChain splitter directly',
1118
1244
  };
1119
1245
  }
1120
1246
  }