@softerist/heuristic-mcp 3.0.15 → 3.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -104
- package/config.jsonc +173 -173
- package/features/ann-config.js +131 -0
- package/features/clear-cache.js +84 -0
- package/features/find-similar-code.js +291 -0
- package/features/hybrid-search.js +544 -0
- package/features/index-codebase.js +3268 -0
- package/features/lifecycle.js +1189 -0
- package/features/package-version.js +302 -0
- package/features/register.js +408 -0
- package/features/resources.js +156 -0
- package/features/set-workspace.js +265 -0
- package/index.js +96 -96
- package/lib/cache-ops.js +22 -22
- package/lib/cache-utils.js +565 -565
- package/lib/cache.js +1870 -1870
- package/lib/call-graph.js +396 -396
- package/lib/cli.js +1 -1
- package/lib/config.js +517 -517
- package/lib/constants.js +39 -39
- package/lib/embed-query-process.js +7 -7
- package/lib/embedding-process.js +7 -7
- package/lib/embedding-worker.js +299 -299
- package/lib/ignore-patterns.js +316 -316
- package/lib/json-worker.js +14 -14
- package/lib/json-writer.js +337 -337
- package/lib/logging.js +164 -164
- package/lib/memory-logger.js +13 -13
- package/lib/onnx-backend.js +193 -193
- package/lib/project-detector.js +84 -84
- package/lib/server-lifecycle.js +165 -165
- package/lib/settings-editor.js +754 -754
- package/lib/tokenizer.js +256 -256
- package/lib/utils.js +428 -428
- package/lib/vector-store-binary.js +627 -627
- package/lib/vector-store-sqlite.js +95 -95
- package/lib/workspace-env.js +28 -28
- package/mcp_config.json +9 -9
- package/package.json +86 -75
- package/scripts/clear-cache.js +20 -0
- package/scripts/download-model.js +43 -0
- package/scripts/mcp-launcher.js +49 -0
- package/scripts/postinstall.js +12 -0
- package/search-configs.js +36 -36
- package/.prettierrc +0 -7
- package/debug-pids.js +0 -30
- package/eslint.config.js +0 -36
- package/specs/plan.md +0 -23
- package/vitest.config.js +0 -39
package/lib/config.js
CHANGED
|
@@ -3,130 +3,130 @@ import path from 'path';
|
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import crypto from 'crypto';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
-
import { ProjectDetector } from './project-detector.js';
|
|
7
|
-
import { parseJsonc } from './settings-editor.js';
|
|
8
|
-
import {
|
|
9
|
-
EMBEDDING_PROCESS_DEFAULT_GC_MAX_REQUESTS_WITHOUT_COLLECTION,
|
|
10
|
-
EMBEDDING_PROCESS_DEFAULT_GC_MIN_INTERVAL_MS,
|
|
11
|
-
EMBEDDING_PROCESS_DEFAULT_GC_RSS_THRESHOLD_MB,
|
|
12
|
-
} from './constants.js';
|
|
13
|
-
import { getWorkspaceEnvKeys } from './workspace-env.js';
|
|
14
|
-
|
|
15
|
-
const DEFAULT_MEMORY_CLEANUP_CONFIG = {
|
|
16
|
-
enableExplicitGc: true, // Require --expose-gc for more aggressive memory cleanup
|
|
17
|
-
clearCacheAfterIndex: true, // Drop in-memory vectors after indexing completes
|
|
18
|
-
unloadModelAfterIndex: true, // Unload embedding model from memory after indexing completes to free RAM
|
|
19
|
-
shutdownQueryEmbeddingPoolAfterIndex: true, // Force shutdown search embedding child pool after index operations
|
|
20
|
-
unloadModelAfterSearch: true, // Unload embedding model after search queries to keep memory low (trades speed for RAM)
|
|
21
|
-
embeddingPoolIdleTimeoutMs: 2000, // Idle timeout before killing persistent embedding child process (ms)
|
|
22
|
-
incrementalGcThresholdMb: 512, // RSS threshold for optional incremental GC
|
|
23
|
-
incrementalMemoryProfile: false, // Enable phase-level incremental indexing memory traces (diagnostics)
|
|
24
|
-
recycleServerOnHighRssAfterIncremental: false, // Recycle server process after incremental cleanup if RSS remains high
|
|
25
|
-
recycleServerOnHighRssThresholdMb: 4096, // RSS threshold (MB) that triggers incremental recycle
|
|
26
|
-
recycleServerOnHighRssCooldownMs: 300000, // Minimum interval between recycle attempts
|
|
27
|
-
recycleServerOnHighRssDelayMs: 2000, // Delay before recycle to allow logs/responses to flush
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const DEFAULT_INDEXING_CONFIG = {
|
|
31
|
-
smartIndexing: true, // Enable automatic project type detection and smart ignore patterns
|
|
32
|
-
chunkSize: 16, // Lines per chunk (tuned for speed/memory balance)
|
|
33
|
-
chunkOverlap: 4, // Overlap between chunks for context continuity
|
|
34
|
-
batchSize: 50, // Number of files to process in a single indexing batch
|
|
35
|
-
maxFileSize: 1048576, // 1MB - skip files larger than this
|
|
36
|
-
prefilterContentMaxBytes: 512 * 1024, // 512KB - cache content during prefilter to avoid double reads
|
|
37
|
-
maxResults: 5, // Maximum number of semantic search results to return
|
|
38
|
-
watchFiles: true, // Enable file system watcher to re-index changed files in real-time
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const DEFAULT_LOGGING_CONFIG = {
|
|
42
|
-
verbose: false, // Enable detailed logging for debugging and progress tracking
|
|
43
|
-
memoryLogIntervalMs: 5000, // Verbose memory log cadence during indexing (ms)
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const DEFAULT_CACHE_CONFIG = {
|
|
47
|
-
enableCache: true, // Whether to persist and reload embeddings between sessions
|
|
48
|
-
saveReaderWaitTimeoutMs: 5000, // Max wait for active reads before saving binary cache
|
|
49
|
-
cacheVectorAssumeFinite: true, // Assume vectors are finite (skip validation)
|
|
50
|
-
cacheVectorFloatDigits: null, // Decimal precision for cached vectors (null = default)
|
|
51
|
-
cacheWriteHighWaterMark: 262144, // Write stream highWaterMark for cache files
|
|
52
|
-
cacheVectorFlushChars: 262144, // Flush threshold (chars) for JSON writer
|
|
53
|
-
cacheVectorCheckFinite: true, // Validate vectors contain only finite numbers
|
|
54
|
-
cacheVectorNoMutation: false, // Avoid mutating vectors during serialization
|
|
55
|
-
cacheVectorJoinThreshold: 8192, // Join threshold for JSON array chunks
|
|
56
|
-
cacheVectorJoinChunkSize: 2048, // Chunk size for JSON join optimization
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const DEFAULT_WORKER_CONFIG = {
|
|
60
|
-
workerThreads: 'auto', // 0 = run in main thread (no workers), "auto" = CPU cores - 1, or set a number
|
|
61
|
-
workerBatchTimeoutMs: 120000, // Timeout per worker batch before fallback (ms)
|
|
62
|
-
workerFailureThreshold: 1, // Open circuit after N worker failures
|
|
63
|
-
workerFailureCooldownMs: 10 * 60 * 1000, // Cooldown before retrying workers
|
|
64
|
-
workerMaxChunksPerBatch: 100, // Cap chunks per worker batch to reduce hang risk
|
|
65
|
-
allowSingleThreadFallback: false, // Allow fallback to main-thread embeddings if workers fail
|
|
66
|
-
failFastEmbeddingErrors: false, // Abort worker embedding batch after repeated consecutive embed failures
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const DEFAULT_EMBEDDING_CONFIG = {
|
|
70
|
-
embeddingModel: 'jinaai/jina-embeddings-v2-base-code', // AI model ID used for semantic search
|
|
71
|
-
embeddingDimension: null, // null = full dimensions, or 64/128/256/512/768 for MRL-trained models
|
|
72
|
-
preloadEmbeddingModel: true, // Preload the embedding model at startup (server mode)
|
|
73
|
-
embeddingProcessPerBatch: false, // Use child process per batch for memory isolation
|
|
74
|
-
autoEmbeddingProcessPerBatch: true, // Auto-enable child process embedding in single-threaded mode for heavy models
|
|
75
|
-
embeddingBatchSize: null, // Override embedding batch size (null = auto)
|
|
76
|
-
embeddingProcessNumThreads: 8, // ONNX threads used by embedding child process
|
|
77
|
-
embeddingProcessGcRssThresholdMb: EMBEDDING_PROCESS_DEFAULT_GC_RSS_THRESHOLD_MB, // RSS threshold for embedding-child adaptive GC
|
|
78
|
-
embeddingProcessGcMinIntervalMs: EMBEDDING_PROCESS_DEFAULT_GC_MIN_INTERVAL_MS, // Minimum interval between embedding-child GC runs
|
|
79
|
-
embeddingProcessGcMaxRequestsWithoutCollection:
|
|
80
|
-
EMBEDDING_PROCESS_DEFAULT_GC_MAX_REQUESTS_WITHOUT_COLLECTION, // Backstop GC cadence for embedding child
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const DEFAULT_VECTOR_STORE_CONFIG = {
|
|
84
|
-
vectorStoreFormat: 'binary', // json | binary | sqlite (binary uses mmap-friendly on-disk store)
|
|
85
|
-
vectorStoreContentMode: 'external', // external = content loaded on-demand for binary store
|
|
86
|
-
contentCacheEntries: 256, // In-memory content cache entries for binary store
|
|
87
|
-
vectorStoreLoadMode: 'memory', // memory | disk (disk streams vectors from disk / memory is faster but requires more RAM)
|
|
88
|
-
vectorCacheEntries: 0, // In-memory vector cache entries for disk-backed loads
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const DEFAULT_SEARCH_CONFIG = {
|
|
92
|
-
semanticWeight: 0.7, // Balance between semantic and keyword scores (0.0 to 1.0)
|
|
93
|
-
exactMatchBoost: 1.5, // Multiplier applied when an exact string match is found
|
|
94
|
-
recencyBoost: 0.1, // Boost for recently modified files (max 0.1 added to score)
|
|
95
|
-
recencyDecayDays: 30, // After this many days, recency boost is 0
|
|
96
|
-
textMatchMaxCandidates: 2000, // Max candidates for full text matching before deferring
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const DEFAULT_CALL_GRAPH_CONFIG = {
|
|
100
|
-
callGraphEnabled: true, // Enable call graph extraction for proximity boosting
|
|
101
|
-
callGraphBoost: 0.15, // Boost for files related via call graph (0-1)
|
|
102
|
-
callGraphMaxHops: 1, // How many levels of calls to follow (1 = direct only)
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const DEFAULT_ANN_CONFIG = {
|
|
106
|
-
annEnabled: true, // Enable Approximate Nearest Neighbor (ANN) index for large codebases
|
|
107
|
-
annMinChunks: 5000, // Minimum number of chunks required to trigger ANN indexing
|
|
108
|
-
annMinCandidates: 50, // Minimum initial candidates to pull from ANN before refinement
|
|
109
|
-
annMaxCandidates: 200, // Hard limit on the number of ANN candidates to process
|
|
110
|
-
annCandidateMultiplier: 20, // Scale initial search depth based on requested maxResults
|
|
111
|
-
annEfConstruction: 200, // HNSW index construction quality (higher = better index, slower build)
|
|
112
|
-
annEfSearch: 64, // HNSW search parameter (higher = more accurate, slower search)
|
|
113
|
-
annM: 16, // Number of connections per element in HNSW index
|
|
114
|
-
annIndexCache: true, // Whether to cache the built HNSW index on disk
|
|
115
|
-
annMetric: 'cosine', // Distance metric for similarity (currently locked to cosine)
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
const MEMORY_CLEANUP_KEYS = Object.freeze(Object.keys(DEFAULT_MEMORY_CLEANUP_CONFIG));
|
|
119
|
-
const INDEXING_KEYS = Object.freeze(Object.keys(DEFAULT_INDEXING_CONFIG));
|
|
120
|
-
const LOGGING_KEYS = Object.freeze(Object.keys(DEFAULT_LOGGING_CONFIG));
|
|
121
|
-
const CACHE_KEYS = Object.freeze(Object.keys(DEFAULT_CACHE_CONFIG));
|
|
122
|
-
const WORKER_KEYS = Object.freeze(Object.keys(DEFAULT_WORKER_CONFIG));
|
|
123
|
-
const EMBEDDING_KEYS = Object.freeze(Object.keys(DEFAULT_EMBEDDING_CONFIG));
|
|
124
|
-
const VECTOR_STORE_KEYS = Object.freeze(Object.keys(DEFAULT_VECTOR_STORE_CONFIG));
|
|
125
|
-
const SEARCH_KEYS = Object.freeze(Object.keys(DEFAULT_SEARCH_CONFIG));
|
|
126
|
-
const CALL_GRAPH_KEYS = Object.freeze(Object.keys(DEFAULT_CALL_GRAPH_CONFIG));
|
|
127
|
-
const ANN_KEYS = Object.freeze(Object.keys(DEFAULT_ANN_CONFIG));
|
|
128
|
-
|
|
129
|
-
const DEFAULT_CONFIG = {
|
|
6
|
+
import { ProjectDetector } from './project-detector.js';
|
|
7
|
+
import { parseJsonc } from './settings-editor.js';
|
|
8
|
+
import {
|
|
9
|
+
EMBEDDING_PROCESS_DEFAULT_GC_MAX_REQUESTS_WITHOUT_COLLECTION,
|
|
10
|
+
EMBEDDING_PROCESS_DEFAULT_GC_MIN_INTERVAL_MS,
|
|
11
|
+
EMBEDDING_PROCESS_DEFAULT_GC_RSS_THRESHOLD_MB,
|
|
12
|
+
} from './constants.js';
|
|
13
|
+
import { getWorkspaceEnvKeys } from './workspace-env.js';
|
|
14
|
+
|
|
15
|
+
const DEFAULT_MEMORY_CLEANUP_CONFIG = {
|
|
16
|
+
enableExplicitGc: true, // Require --expose-gc for more aggressive memory cleanup
|
|
17
|
+
clearCacheAfterIndex: true, // Drop in-memory vectors after indexing completes
|
|
18
|
+
unloadModelAfterIndex: true, // Unload embedding model from memory after indexing completes to free RAM
|
|
19
|
+
shutdownQueryEmbeddingPoolAfterIndex: true, // Force shutdown search embedding child pool after index operations
|
|
20
|
+
unloadModelAfterSearch: true, // Unload embedding model after search queries to keep memory low (trades speed for RAM)
|
|
21
|
+
embeddingPoolIdleTimeoutMs: 2000, // Idle timeout before killing persistent embedding child process (ms)
|
|
22
|
+
incrementalGcThresholdMb: 512, // RSS threshold for optional incremental GC
|
|
23
|
+
incrementalMemoryProfile: false, // Enable phase-level incremental indexing memory traces (diagnostics)
|
|
24
|
+
recycleServerOnHighRssAfterIncremental: false, // Recycle server process after incremental cleanup if RSS remains high
|
|
25
|
+
recycleServerOnHighRssThresholdMb: 4096, // RSS threshold (MB) that triggers incremental recycle
|
|
26
|
+
recycleServerOnHighRssCooldownMs: 300000, // Minimum interval between recycle attempts
|
|
27
|
+
recycleServerOnHighRssDelayMs: 2000, // Delay before recycle to allow logs/responses to flush
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const DEFAULT_INDEXING_CONFIG = {
|
|
31
|
+
smartIndexing: true, // Enable automatic project type detection and smart ignore patterns
|
|
32
|
+
chunkSize: 16, // Lines per chunk (tuned for speed/memory balance)
|
|
33
|
+
chunkOverlap: 4, // Overlap between chunks for context continuity
|
|
34
|
+
batchSize: 50, // Number of files to process in a single indexing batch
|
|
35
|
+
maxFileSize: 1048576, // 1MB - skip files larger than this
|
|
36
|
+
prefilterContentMaxBytes: 512 * 1024, // 512KB - cache content during prefilter to avoid double reads
|
|
37
|
+
maxResults: 5, // Maximum number of semantic search results to return
|
|
38
|
+
watchFiles: true, // Enable file system watcher to re-index changed files in real-time
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const DEFAULT_LOGGING_CONFIG = {
|
|
42
|
+
verbose: false, // Enable detailed logging for debugging and progress tracking
|
|
43
|
+
memoryLogIntervalMs: 5000, // Verbose memory log cadence during indexing (ms)
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const DEFAULT_CACHE_CONFIG = {
|
|
47
|
+
enableCache: true, // Whether to persist and reload embeddings between sessions
|
|
48
|
+
saveReaderWaitTimeoutMs: 5000, // Max wait for active reads before saving binary cache
|
|
49
|
+
cacheVectorAssumeFinite: true, // Assume vectors are finite (skip validation)
|
|
50
|
+
cacheVectorFloatDigits: null, // Decimal precision for cached vectors (null = default)
|
|
51
|
+
cacheWriteHighWaterMark: 262144, // Write stream highWaterMark for cache files
|
|
52
|
+
cacheVectorFlushChars: 262144, // Flush threshold (chars) for JSON writer
|
|
53
|
+
cacheVectorCheckFinite: true, // Validate vectors contain only finite numbers
|
|
54
|
+
cacheVectorNoMutation: false, // Avoid mutating vectors during serialization
|
|
55
|
+
cacheVectorJoinThreshold: 8192, // Join threshold for JSON array chunks
|
|
56
|
+
cacheVectorJoinChunkSize: 2048, // Chunk size for JSON join optimization
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const DEFAULT_WORKER_CONFIG = {
|
|
60
|
+
workerThreads: 'auto', // 0 = run in main thread (no workers), "auto" = CPU cores - 1, or set a number
|
|
61
|
+
workerBatchTimeoutMs: 120000, // Timeout per worker batch before fallback (ms)
|
|
62
|
+
workerFailureThreshold: 1, // Open circuit after N worker failures
|
|
63
|
+
workerFailureCooldownMs: 10 * 60 * 1000, // Cooldown before retrying workers
|
|
64
|
+
workerMaxChunksPerBatch: 100, // Cap chunks per worker batch to reduce hang risk
|
|
65
|
+
allowSingleThreadFallback: false, // Allow fallback to main-thread embeddings if workers fail
|
|
66
|
+
failFastEmbeddingErrors: false, // Abort worker embedding batch after repeated consecutive embed failures
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const DEFAULT_EMBEDDING_CONFIG = {
|
|
70
|
+
embeddingModel: 'jinaai/jina-embeddings-v2-base-code', // AI model ID used for semantic search
|
|
71
|
+
embeddingDimension: null, // null = full dimensions, or 64/128/256/512/768 for MRL-trained models
|
|
72
|
+
preloadEmbeddingModel: true, // Preload the embedding model at startup (server mode)
|
|
73
|
+
embeddingProcessPerBatch: false, // Use child process per batch for memory isolation
|
|
74
|
+
autoEmbeddingProcessPerBatch: true, // Auto-enable child process embedding in single-threaded mode for heavy models
|
|
75
|
+
embeddingBatchSize: null, // Override embedding batch size (null = auto)
|
|
76
|
+
embeddingProcessNumThreads: 8, // ONNX threads used by embedding child process
|
|
77
|
+
embeddingProcessGcRssThresholdMb: EMBEDDING_PROCESS_DEFAULT_GC_RSS_THRESHOLD_MB, // RSS threshold for embedding-child adaptive GC
|
|
78
|
+
embeddingProcessGcMinIntervalMs: EMBEDDING_PROCESS_DEFAULT_GC_MIN_INTERVAL_MS, // Minimum interval between embedding-child GC runs
|
|
79
|
+
embeddingProcessGcMaxRequestsWithoutCollection:
|
|
80
|
+
EMBEDDING_PROCESS_DEFAULT_GC_MAX_REQUESTS_WITHOUT_COLLECTION, // Backstop GC cadence for embedding child
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const DEFAULT_VECTOR_STORE_CONFIG = {
|
|
84
|
+
vectorStoreFormat: 'binary', // json | binary | sqlite (binary uses mmap-friendly on-disk store)
|
|
85
|
+
vectorStoreContentMode: 'external', // external = content loaded on-demand for binary store
|
|
86
|
+
contentCacheEntries: 256, // In-memory content cache entries for binary store
|
|
87
|
+
vectorStoreLoadMode: 'memory', // memory | disk (disk streams vectors from disk / memory is faster but requires more RAM)
|
|
88
|
+
vectorCacheEntries: 0, // In-memory vector cache entries for disk-backed loads
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const DEFAULT_SEARCH_CONFIG = {
|
|
92
|
+
semanticWeight: 0.7, // Balance between semantic and keyword scores (0.0 to 1.0)
|
|
93
|
+
exactMatchBoost: 1.5, // Multiplier applied when an exact string match is found
|
|
94
|
+
recencyBoost: 0.1, // Boost for recently modified files (max 0.1 added to score)
|
|
95
|
+
recencyDecayDays: 30, // After this many days, recency boost is 0
|
|
96
|
+
textMatchMaxCandidates: 2000, // Max candidates for full text matching before deferring
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const DEFAULT_CALL_GRAPH_CONFIG = {
|
|
100
|
+
callGraphEnabled: true, // Enable call graph extraction for proximity boosting
|
|
101
|
+
callGraphBoost: 0.15, // Boost for files related via call graph (0-1)
|
|
102
|
+
callGraphMaxHops: 1, // How many levels of calls to follow (1 = direct only)
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const DEFAULT_ANN_CONFIG = {
|
|
106
|
+
annEnabled: true, // Enable Approximate Nearest Neighbor (ANN) index for large codebases
|
|
107
|
+
annMinChunks: 5000, // Minimum number of chunks required to trigger ANN indexing
|
|
108
|
+
annMinCandidates: 50, // Minimum initial candidates to pull from ANN before refinement
|
|
109
|
+
annMaxCandidates: 200, // Hard limit on the number of ANN candidates to process
|
|
110
|
+
annCandidateMultiplier: 20, // Scale initial search depth based on requested maxResults
|
|
111
|
+
annEfConstruction: 200, // HNSW index construction quality (higher = better index, slower build)
|
|
112
|
+
annEfSearch: 64, // HNSW search parameter (higher = more accurate, slower search)
|
|
113
|
+
annM: 16, // Number of connections per element in HNSW index
|
|
114
|
+
annIndexCache: true, // Whether to cache the built HNSW index on disk
|
|
115
|
+
annMetric: 'cosine', // Distance metric for similarity (currently locked to cosine)
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const MEMORY_CLEANUP_KEYS = Object.freeze(Object.keys(DEFAULT_MEMORY_CLEANUP_CONFIG));
|
|
119
|
+
const INDEXING_KEYS = Object.freeze(Object.keys(DEFAULT_INDEXING_CONFIG));
|
|
120
|
+
const LOGGING_KEYS = Object.freeze(Object.keys(DEFAULT_LOGGING_CONFIG));
|
|
121
|
+
const CACHE_KEYS = Object.freeze(Object.keys(DEFAULT_CACHE_CONFIG));
|
|
122
|
+
const WORKER_KEYS = Object.freeze(Object.keys(DEFAULT_WORKER_CONFIG));
|
|
123
|
+
const EMBEDDING_KEYS = Object.freeze(Object.keys(DEFAULT_EMBEDDING_CONFIG));
|
|
124
|
+
const VECTOR_STORE_KEYS = Object.freeze(Object.keys(DEFAULT_VECTOR_STORE_CONFIG));
|
|
125
|
+
const SEARCH_KEYS = Object.freeze(Object.keys(DEFAULT_SEARCH_CONFIG));
|
|
126
|
+
const CALL_GRAPH_KEYS = Object.freeze(Object.keys(DEFAULT_CALL_GRAPH_CONFIG));
|
|
127
|
+
const ANN_KEYS = Object.freeze(Object.keys(DEFAULT_ANN_CONFIG));
|
|
128
|
+
|
|
129
|
+
const DEFAULT_CONFIG = {
|
|
130
130
|
searchDirectory: '.',
|
|
131
131
|
fileExtensions: [
|
|
132
132
|
// JavaScript/TypeScript
|
|
@@ -362,16 +362,16 @@ const DEFAULT_CONFIG = {
|
|
|
362
362
|
'**/scripts/**',
|
|
363
363
|
'**/tools/**',
|
|
364
364
|
],
|
|
365
|
-
chunkSize: DEFAULT_INDEXING_CONFIG.chunkSize,
|
|
366
|
-
chunkOverlap: DEFAULT_INDEXING_CONFIG.chunkOverlap,
|
|
367
|
-
batchSize: DEFAULT_INDEXING_CONFIG.batchSize,
|
|
368
|
-
maxFileSize: DEFAULT_INDEXING_CONFIG.maxFileSize,
|
|
369
|
-
prefilterContentMaxBytes: DEFAULT_INDEXING_CONFIG.prefilterContentMaxBytes,
|
|
370
|
-
maxResults: DEFAULT_INDEXING_CONFIG.maxResults,
|
|
371
|
-
enableCache: DEFAULT_CACHE_CONFIG.enableCache,
|
|
372
|
-
cacheDirectory: null, // Will be set dynamically by loadConfig()
|
|
373
|
-
// Cache cleanup behavior (consolidated namespace)
|
|
374
|
-
cacheCleanup: {
|
|
365
|
+
chunkSize: DEFAULT_INDEXING_CONFIG.chunkSize,
|
|
366
|
+
chunkOverlap: DEFAULT_INDEXING_CONFIG.chunkOverlap,
|
|
367
|
+
batchSize: DEFAULT_INDEXING_CONFIG.batchSize,
|
|
368
|
+
maxFileSize: DEFAULT_INDEXING_CONFIG.maxFileSize,
|
|
369
|
+
prefilterContentMaxBytes: DEFAULT_INDEXING_CONFIG.prefilterContentMaxBytes,
|
|
370
|
+
maxResults: DEFAULT_INDEXING_CONFIG.maxResults,
|
|
371
|
+
enableCache: DEFAULT_CACHE_CONFIG.enableCache,
|
|
372
|
+
cacheDirectory: null, // Will be set dynamically by loadConfig()
|
|
373
|
+
// Cache cleanup behavior (consolidated namespace)
|
|
374
|
+
cacheCleanup: {
|
|
375
375
|
autoCleanup: true, // Automatically remove stale caches on startup
|
|
376
376
|
staleNoMetaHours: 6, // Hours before incomplete cache (no meta.json) is considered stale
|
|
377
377
|
emptyThresholdHours: 24, // Hours before empty cache (0 files/chunks) is removed
|
|
@@ -379,86 +379,86 @@ const DEFAULT_CONFIG = {
|
|
|
379
379
|
maxUnusedDays: 30, // Days before unused cache is removed
|
|
380
380
|
tempThresholdHours: 24, // Hours before temp workspace cache is removed
|
|
381
381
|
staleProgressHours: 6, // Hours before stuck indexing is considered stale
|
|
382
|
-
safetyWindowMinutes: 10, // Minutes of recent activity to never delete
|
|
383
|
-
removeDuplicates: true, // Remove duplicate workspace caches
|
|
384
|
-
},
|
|
385
|
-
watchFiles: DEFAULT_INDEXING_CONFIG.watchFiles,
|
|
386
|
-
verbose: DEFAULT_LOGGING_CONFIG.verbose,
|
|
387
|
-
memoryLogIntervalMs: DEFAULT_LOGGING_CONFIG.memoryLogIntervalMs,
|
|
388
|
-
saveReaderWaitTimeoutMs: DEFAULT_CACHE_CONFIG.saveReaderWaitTimeoutMs,
|
|
389
|
-
workerThreads: DEFAULT_WORKER_CONFIG.workerThreads,
|
|
390
|
-
workerBatchTimeoutMs: DEFAULT_WORKER_CONFIG.workerBatchTimeoutMs,
|
|
391
|
-
workerFailureThreshold: DEFAULT_WORKER_CONFIG.workerFailureThreshold,
|
|
392
|
-
workerFailureCooldownMs: DEFAULT_WORKER_CONFIG.workerFailureCooldownMs,
|
|
393
|
-
workerMaxChunksPerBatch: DEFAULT_WORKER_CONFIG.workerMaxChunksPerBatch,
|
|
394
|
-
allowSingleThreadFallback: DEFAULT_WORKER_CONFIG.allowSingleThreadFallback,
|
|
395
|
-
failFastEmbeddingErrors: DEFAULT_WORKER_CONFIG.failFastEmbeddingErrors,
|
|
396
|
-
embeddingProcessPerBatch: DEFAULT_EMBEDDING_CONFIG.embeddingProcessPerBatch,
|
|
397
|
-
autoEmbeddingProcessPerBatch: DEFAULT_EMBEDDING_CONFIG.autoEmbeddingProcessPerBatch,
|
|
398
|
-
embeddingBatchSize: DEFAULT_EMBEDDING_CONFIG.embeddingBatchSize,
|
|
399
|
-
embeddingProcessNumThreads: DEFAULT_EMBEDDING_CONFIG.embeddingProcessNumThreads,
|
|
400
|
-
embeddingProcessGcRssThresholdMb: DEFAULT_EMBEDDING_CONFIG.embeddingProcessGcRssThresholdMb,
|
|
401
|
-
embeddingProcessGcMinIntervalMs: DEFAULT_EMBEDDING_CONFIG.embeddingProcessGcMinIntervalMs,
|
|
402
|
-
embeddingProcessGcMaxRequestsWithoutCollection:
|
|
403
|
-
DEFAULT_EMBEDDING_CONFIG.embeddingProcessGcMaxRequestsWithoutCollection,
|
|
404
|
-
enableExplicitGc: DEFAULT_MEMORY_CLEANUP_CONFIG.enableExplicitGc,
|
|
405
|
-
embeddingModel: DEFAULT_EMBEDDING_CONFIG.embeddingModel,
|
|
406
|
-
embeddingDimension: DEFAULT_EMBEDDING_CONFIG.embeddingDimension,
|
|
407
|
-
preloadEmbeddingModel: DEFAULT_EMBEDDING_CONFIG.preloadEmbeddingModel,
|
|
408
|
-
vectorStoreFormat: DEFAULT_VECTOR_STORE_CONFIG.vectorStoreFormat,
|
|
409
|
-
vectorStoreContentMode: DEFAULT_VECTOR_STORE_CONFIG.vectorStoreContentMode,
|
|
410
|
-
contentCacheEntries: DEFAULT_VECTOR_STORE_CONFIG.contentCacheEntries,
|
|
411
|
-
vectorStoreLoadMode: DEFAULT_VECTOR_STORE_CONFIG.vectorStoreLoadMode,
|
|
412
|
-
vectorCacheEntries: DEFAULT_VECTOR_STORE_CONFIG.vectorCacheEntries,
|
|
413
|
-
clearCacheAfterIndex: DEFAULT_MEMORY_CLEANUP_CONFIG.clearCacheAfterIndex,
|
|
414
|
-
unloadModelAfterIndex: DEFAULT_MEMORY_CLEANUP_CONFIG.unloadModelAfterIndex,
|
|
415
|
-
shutdownQueryEmbeddingPoolAfterIndex:
|
|
416
|
-
DEFAULT_MEMORY_CLEANUP_CONFIG.shutdownQueryEmbeddingPoolAfterIndex,
|
|
417
|
-
unloadModelAfterSearch: DEFAULT_MEMORY_CLEANUP_CONFIG.unloadModelAfterSearch,
|
|
418
|
-
embeddingPoolIdleTimeoutMs: DEFAULT_MEMORY_CLEANUP_CONFIG.embeddingPoolIdleTimeoutMs,
|
|
419
|
-
incrementalGcThresholdMb: DEFAULT_MEMORY_CLEANUP_CONFIG.incrementalGcThresholdMb,
|
|
420
|
-
incrementalMemoryProfile: DEFAULT_MEMORY_CLEANUP_CONFIG.incrementalMemoryProfile,
|
|
421
|
-
recycleServerOnHighRssAfterIncremental:
|
|
422
|
-
DEFAULT_MEMORY_CLEANUP_CONFIG.recycleServerOnHighRssAfterIncremental,
|
|
423
|
-
recycleServerOnHighRssThresholdMb:
|
|
424
|
-
DEFAULT_MEMORY_CLEANUP_CONFIG.recycleServerOnHighRssThresholdMb,
|
|
425
|
-
recycleServerOnHighRssCooldownMs:
|
|
426
|
-
DEFAULT_MEMORY_CLEANUP_CONFIG.recycleServerOnHighRssCooldownMs,
|
|
427
|
-
recycleServerOnHighRssDelayMs: DEFAULT_MEMORY_CLEANUP_CONFIG.recycleServerOnHighRssDelayMs,
|
|
428
|
-
memoryCleanup: { ...DEFAULT_MEMORY_CLEANUP_CONFIG },
|
|
429
|
-
semanticWeight: DEFAULT_SEARCH_CONFIG.semanticWeight,
|
|
430
|
-
exactMatchBoost: DEFAULT_SEARCH_CONFIG.exactMatchBoost,
|
|
431
|
-
recencyBoost: DEFAULT_SEARCH_CONFIG.recencyBoost,
|
|
432
|
-
recencyDecayDays: DEFAULT_SEARCH_CONFIG.recencyDecayDays,
|
|
433
|
-
textMatchMaxCandidates: DEFAULT_SEARCH_CONFIG.textMatchMaxCandidates,
|
|
434
|
-
smartIndexing: DEFAULT_INDEXING_CONFIG.smartIndexing,
|
|
435
|
-
callGraphEnabled: DEFAULT_CALL_GRAPH_CONFIG.callGraphEnabled,
|
|
436
|
-
callGraphBoost: DEFAULT_CALL_GRAPH_CONFIG.callGraphBoost,
|
|
437
|
-
callGraphMaxHops: DEFAULT_CALL_GRAPH_CONFIG.callGraphMaxHops,
|
|
438
|
-
annEnabled: DEFAULT_ANN_CONFIG.annEnabled,
|
|
439
|
-
annMinChunks: DEFAULT_ANN_CONFIG.annMinChunks,
|
|
440
|
-
annMinCandidates: DEFAULT_ANN_CONFIG.annMinCandidates,
|
|
441
|
-
annMaxCandidates: DEFAULT_ANN_CONFIG.annMaxCandidates,
|
|
442
|
-
annCandidateMultiplier: DEFAULT_ANN_CONFIG.annCandidateMultiplier,
|
|
443
|
-
annEfConstruction: DEFAULT_ANN_CONFIG.annEfConstruction,
|
|
444
|
-
annEfSearch: DEFAULT_ANN_CONFIG.annEfSearch,
|
|
445
|
-
annM: DEFAULT_ANN_CONFIG.annM,
|
|
446
|
-
annIndexCache: DEFAULT_ANN_CONFIG.annIndexCache,
|
|
447
|
-
annMetric: DEFAULT_ANN_CONFIG.annMetric,
|
|
448
|
-
indexing: { ...DEFAULT_INDEXING_CONFIG },
|
|
449
|
-
logging: { ...DEFAULT_LOGGING_CONFIG },
|
|
450
|
-
cache: { ...DEFAULT_CACHE_CONFIG },
|
|
451
|
-
worker: { ...DEFAULT_WORKER_CONFIG },
|
|
452
|
-
embedding: { ...DEFAULT_EMBEDDING_CONFIG },
|
|
453
|
-
vectorStore: { ...DEFAULT_VECTOR_STORE_CONFIG },
|
|
454
|
-
search: { ...DEFAULT_SEARCH_CONFIG },
|
|
455
|
-
callGraph: { ...DEFAULT_CALL_GRAPH_CONFIG },
|
|
456
|
-
ann: { ...DEFAULT_ANN_CONFIG },
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
let config = { ...DEFAULT_CONFIG };
|
|
460
|
-
|
|
461
|
-
const WORKSPACE_MARKERS = [
|
|
382
|
+
safetyWindowMinutes: 10, // Minutes of recent activity to never delete
|
|
383
|
+
removeDuplicates: true, // Remove duplicate workspace caches
|
|
384
|
+
},
|
|
385
|
+
watchFiles: DEFAULT_INDEXING_CONFIG.watchFiles,
|
|
386
|
+
verbose: DEFAULT_LOGGING_CONFIG.verbose,
|
|
387
|
+
memoryLogIntervalMs: DEFAULT_LOGGING_CONFIG.memoryLogIntervalMs,
|
|
388
|
+
saveReaderWaitTimeoutMs: DEFAULT_CACHE_CONFIG.saveReaderWaitTimeoutMs,
|
|
389
|
+
workerThreads: DEFAULT_WORKER_CONFIG.workerThreads,
|
|
390
|
+
workerBatchTimeoutMs: DEFAULT_WORKER_CONFIG.workerBatchTimeoutMs,
|
|
391
|
+
workerFailureThreshold: DEFAULT_WORKER_CONFIG.workerFailureThreshold,
|
|
392
|
+
workerFailureCooldownMs: DEFAULT_WORKER_CONFIG.workerFailureCooldownMs,
|
|
393
|
+
workerMaxChunksPerBatch: DEFAULT_WORKER_CONFIG.workerMaxChunksPerBatch,
|
|
394
|
+
allowSingleThreadFallback: DEFAULT_WORKER_CONFIG.allowSingleThreadFallback,
|
|
395
|
+
failFastEmbeddingErrors: DEFAULT_WORKER_CONFIG.failFastEmbeddingErrors,
|
|
396
|
+
embeddingProcessPerBatch: DEFAULT_EMBEDDING_CONFIG.embeddingProcessPerBatch,
|
|
397
|
+
autoEmbeddingProcessPerBatch: DEFAULT_EMBEDDING_CONFIG.autoEmbeddingProcessPerBatch,
|
|
398
|
+
embeddingBatchSize: DEFAULT_EMBEDDING_CONFIG.embeddingBatchSize,
|
|
399
|
+
embeddingProcessNumThreads: DEFAULT_EMBEDDING_CONFIG.embeddingProcessNumThreads,
|
|
400
|
+
embeddingProcessGcRssThresholdMb: DEFAULT_EMBEDDING_CONFIG.embeddingProcessGcRssThresholdMb,
|
|
401
|
+
embeddingProcessGcMinIntervalMs: DEFAULT_EMBEDDING_CONFIG.embeddingProcessGcMinIntervalMs,
|
|
402
|
+
embeddingProcessGcMaxRequestsWithoutCollection:
|
|
403
|
+
DEFAULT_EMBEDDING_CONFIG.embeddingProcessGcMaxRequestsWithoutCollection,
|
|
404
|
+
enableExplicitGc: DEFAULT_MEMORY_CLEANUP_CONFIG.enableExplicitGc,
|
|
405
|
+
embeddingModel: DEFAULT_EMBEDDING_CONFIG.embeddingModel,
|
|
406
|
+
embeddingDimension: DEFAULT_EMBEDDING_CONFIG.embeddingDimension,
|
|
407
|
+
preloadEmbeddingModel: DEFAULT_EMBEDDING_CONFIG.preloadEmbeddingModel,
|
|
408
|
+
vectorStoreFormat: DEFAULT_VECTOR_STORE_CONFIG.vectorStoreFormat,
|
|
409
|
+
vectorStoreContentMode: DEFAULT_VECTOR_STORE_CONFIG.vectorStoreContentMode,
|
|
410
|
+
contentCacheEntries: DEFAULT_VECTOR_STORE_CONFIG.contentCacheEntries,
|
|
411
|
+
vectorStoreLoadMode: DEFAULT_VECTOR_STORE_CONFIG.vectorStoreLoadMode,
|
|
412
|
+
vectorCacheEntries: DEFAULT_VECTOR_STORE_CONFIG.vectorCacheEntries,
|
|
413
|
+
clearCacheAfterIndex: DEFAULT_MEMORY_CLEANUP_CONFIG.clearCacheAfterIndex,
|
|
414
|
+
unloadModelAfterIndex: DEFAULT_MEMORY_CLEANUP_CONFIG.unloadModelAfterIndex,
|
|
415
|
+
shutdownQueryEmbeddingPoolAfterIndex:
|
|
416
|
+
DEFAULT_MEMORY_CLEANUP_CONFIG.shutdownQueryEmbeddingPoolAfterIndex,
|
|
417
|
+
unloadModelAfterSearch: DEFAULT_MEMORY_CLEANUP_CONFIG.unloadModelAfterSearch,
|
|
418
|
+
embeddingPoolIdleTimeoutMs: DEFAULT_MEMORY_CLEANUP_CONFIG.embeddingPoolIdleTimeoutMs,
|
|
419
|
+
incrementalGcThresholdMb: DEFAULT_MEMORY_CLEANUP_CONFIG.incrementalGcThresholdMb,
|
|
420
|
+
incrementalMemoryProfile: DEFAULT_MEMORY_CLEANUP_CONFIG.incrementalMemoryProfile,
|
|
421
|
+
recycleServerOnHighRssAfterIncremental:
|
|
422
|
+
DEFAULT_MEMORY_CLEANUP_CONFIG.recycleServerOnHighRssAfterIncremental,
|
|
423
|
+
recycleServerOnHighRssThresholdMb:
|
|
424
|
+
DEFAULT_MEMORY_CLEANUP_CONFIG.recycleServerOnHighRssThresholdMb,
|
|
425
|
+
recycleServerOnHighRssCooldownMs:
|
|
426
|
+
DEFAULT_MEMORY_CLEANUP_CONFIG.recycleServerOnHighRssCooldownMs,
|
|
427
|
+
recycleServerOnHighRssDelayMs: DEFAULT_MEMORY_CLEANUP_CONFIG.recycleServerOnHighRssDelayMs,
|
|
428
|
+
memoryCleanup: { ...DEFAULT_MEMORY_CLEANUP_CONFIG },
|
|
429
|
+
semanticWeight: DEFAULT_SEARCH_CONFIG.semanticWeight,
|
|
430
|
+
exactMatchBoost: DEFAULT_SEARCH_CONFIG.exactMatchBoost,
|
|
431
|
+
recencyBoost: DEFAULT_SEARCH_CONFIG.recencyBoost,
|
|
432
|
+
recencyDecayDays: DEFAULT_SEARCH_CONFIG.recencyDecayDays,
|
|
433
|
+
textMatchMaxCandidates: DEFAULT_SEARCH_CONFIG.textMatchMaxCandidates,
|
|
434
|
+
smartIndexing: DEFAULT_INDEXING_CONFIG.smartIndexing,
|
|
435
|
+
callGraphEnabled: DEFAULT_CALL_GRAPH_CONFIG.callGraphEnabled,
|
|
436
|
+
callGraphBoost: DEFAULT_CALL_GRAPH_CONFIG.callGraphBoost,
|
|
437
|
+
callGraphMaxHops: DEFAULT_CALL_GRAPH_CONFIG.callGraphMaxHops,
|
|
438
|
+
annEnabled: DEFAULT_ANN_CONFIG.annEnabled,
|
|
439
|
+
annMinChunks: DEFAULT_ANN_CONFIG.annMinChunks,
|
|
440
|
+
annMinCandidates: DEFAULT_ANN_CONFIG.annMinCandidates,
|
|
441
|
+
annMaxCandidates: DEFAULT_ANN_CONFIG.annMaxCandidates,
|
|
442
|
+
annCandidateMultiplier: DEFAULT_ANN_CONFIG.annCandidateMultiplier,
|
|
443
|
+
annEfConstruction: DEFAULT_ANN_CONFIG.annEfConstruction,
|
|
444
|
+
annEfSearch: DEFAULT_ANN_CONFIG.annEfSearch,
|
|
445
|
+
annM: DEFAULT_ANN_CONFIG.annM,
|
|
446
|
+
annIndexCache: DEFAULT_ANN_CONFIG.annIndexCache,
|
|
447
|
+
annMetric: DEFAULT_ANN_CONFIG.annMetric,
|
|
448
|
+
indexing: { ...DEFAULT_INDEXING_CONFIG },
|
|
449
|
+
logging: { ...DEFAULT_LOGGING_CONFIG },
|
|
450
|
+
cache: { ...DEFAULT_CACHE_CONFIG },
|
|
451
|
+
worker: { ...DEFAULT_WORKER_CONFIG },
|
|
452
|
+
embedding: { ...DEFAULT_EMBEDDING_CONFIG },
|
|
453
|
+
vectorStore: { ...DEFAULT_VECTOR_STORE_CONFIG },
|
|
454
|
+
search: { ...DEFAULT_SEARCH_CONFIG },
|
|
455
|
+
callGraph: { ...DEFAULT_CALL_GRAPH_CONFIG },
|
|
456
|
+
ann: { ...DEFAULT_ANN_CONFIG },
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
let config = { ...DEFAULT_CONFIG };
|
|
460
|
+
|
|
461
|
+
const WORKSPACE_MARKERS = [
|
|
462
462
|
'.git',
|
|
463
463
|
'package.json',
|
|
464
464
|
'pyproject.toml',
|
|
@@ -470,118 +470,118 @@ const WORKSPACE_MARKERS = [
|
|
|
470
470
|
'requirements.txt',
|
|
471
471
|
'Gemfile',
|
|
472
472
|
'Makefile',
|
|
473
|
-
'CMakeLists.txt',
|
|
474
|
-
];
|
|
475
|
-
|
|
476
|
-
function hasOwn(obj, key) {
|
|
477
|
-
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
const CONFIG_NAMESPACES = Object.freeze([
|
|
481
|
-
{
|
|
482
|
-
name: 'memoryCleanup',
|
|
483
|
-
keys: MEMORY_CLEANUP_KEYS,
|
|
484
|
-
defaults: DEFAULT_MEMORY_CLEANUP_CONFIG,
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
name: 'indexing',
|
|
488
|
-
keys: INDEXING_KEYS,
|
|
489
|
-
defaults: DEFAULT_INDEXING_CONFIG,
|
|
490
|
-
},
|
|
491
|
-
{
|
|
492
|
-
name: 'logging',
|
|
493
|
-
keys: LOGGING_KEYS,
|
|
494
|
-
defaults: DEFAULT_LOGGING_CONFIG,
|
|
495
|
-
},
|
|
496
|
-
{
|
|
497
|
-
name: 'cache',
|
|
498
|
-
keys: CACHE_KEYS,
|
|
499
|
-
defaults: DEFAULT_CACHE_CONFIG,
|
|
500
|
-
},
|
|
501
|
-
{
|
|
502
|
-
name: 'worker',
|
|
503
|
-
keys: WORKER_KEYS,
|
|
504
|
-
defaults: DEFAULT_WORKER_CONFIG,
|
|
505
|
-
},
|
|
506
|
-
{
|
|
507
|
-
name: 'embedding',
|
|
508
|
-
keys: EMBEDDING_KEYS,
|
|
509
|
-
defaults: DEFAULT_EMBEDDING_CONFIG,
|
|
510
|
-
},
|
|
511
|
-
{
|
|
512
|
-
name: 'vectorStore',
|
|
513
|
-
keys: VECTOR_STORE_KEYS,
|
|
514
|
-
defaults: DEFAULT_VECTOR_STORE_CONFIG,
|
|
515
|
-
},
|
|
516
|
-
{
|
|
517
|
-
name: 'search',
|
|
518
|
-
keys: SEARCH_KEYS,
|
|
519
|
-
defaults: DEFAULT_SEARCH_CONFIG,
|
|
520
|
-
},
|
|
521
|
-
{
|
|
522
|
-
name: 'callGraph',
|
|
523
|
-
keys: CALL_GRAPH_KEYS,
|
|
524
|
-
defaults: DEFAULT_CALL_GRAPH_CONFIG,
|
|
525
|
-
},
|
|
526
|
-
{
|
|
527
|
-
name: 'ann',
|
|
528
|
-
keys: ANN_KEYS,
|
|
529
|
-
defaults: DEFAULT_ANN_CONFIG,
|
|
530
|
-
},
|
|
531
|
-
]);
|
|
532
|
-
|
|
533
|
-
function applyNamespace(targetConfig, sourceConfig, namespaceName, keys, defaults) {
|
|
534
|
-
const sourceNamespace =
|
|
535
|
-
sourceConfig && typeof sourceConfig[namespaceName] === 'object'
|
|
536
|
-
? sourceConfig[namespaceName]
|
|
537
|
-
: {};
|
|
538
|
-
const mergedNamespace = {
|
|
539
|
-
...defaults,
|
|
540
|
-
...(targetConfig[namespaceName] && typeof targetConfig[namespaceName] === 'object'
|
|
541
|
-
? targetConfig[namespaceName]
|
|
542
|
-
: {}),
|
|
543
|
-
};
|
|
544
|
-
|
|
545
|
-
for (const key of keys) {
|
|
546
|
-
if (hasOwn(sourceNamespace, key)) {
|
|
547
|
-
targetConfig[key] = mergedNamespace[key];
|
|
548
|
-
} else {
|
|
549
|
-
mergedNamespace[key] = targetConfig[key];
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
targetConfig[namespaceName] = mergedNamespace;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
function syncNamespace(targetConfig, namespaceName, keys, defaults) {
|
|
557
|
-
const currentNamespace =
|
|
558
|
-
targetConfig[namespaceName] && typeof targetConfig[namespaceName] === 'object'
|
|
559
|
-
? targetConfig[namespaceName]
|
|
560
|
-
: {};
|
|
561
|
-
const mergedNamespace = { ...defaults, ...currentNamespace };
|
|
562
|
-
for (const key of keys) {
|
|
563
|
-
mergedNamespace[key] = targetConfig[key];
|
|
564
|
-
}
|
|
565
|
-
targetConfig[namespaceName] = mergedNamespace;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
function applyAllNamespaces(targetConfig, sourceConfig) {
|
|
569
|
-
for (const namespace of CONFIG_NAMESPACES) {
|
|
570
|
-
applyNamespace(
|
|
571
|
-
targetConfig,
|
|
572
|
-
sourceConfig,
|
|
573
|
-
namespace.name,
|
|
574
|
-
namespace.keys,
|
|
575
|
-
namespace.defaults
|
|
576
|
-
);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
function syncAllNamespaces(targetConfig) {
|
|
581
|
-
for (const namespace of CONFIG_NAMESPACES) {
|
|
582
|
-
syncNamespace(targetConfig, namespace.name, namespace.keys, namespace.defaults);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
473
|
+
'CMakeLists.txt',
|
|
474
|
+
];
|
|
475
|
+
|
|
476
|
+
function hasOwn(obj, key) {
|
|
477
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
const CONFIG_NAMESPACES = Object.freeze([
|
|
481
|
+
{
|
|
482
|
+
name: 'memoryCleanup',
|
|
483
|
+
keys: MEMORY_CLEANUP_KEYS,
|
|
484
|
+
defaults: DEFAULT_MEMORY_CLEANUP_CONFIG,
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
name: 'indexing',
|
|
488
|
+
keys: INDEXING_KEYS,
|
|
489
|
+
defaults: DEFAULT_INDEXING_CONFIG,
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
name: 'logging',
|
|
493
|
+
keys: LOGGING_KEYS,
|
|
494
|
+
defaults: DEFAULT_LOGGING_CONFIG,
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
name: 'cache',
|
|
498
|
+
keys: CACHE_KEYS,
|
|
499
|
+
defaults: DEFAULT_CACHE_CONFIG,
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
name: 'worker',
|
|
503
|
+
keys: WORKER_KEYS,
|
|
504
|
+
defaults: DEFAULT_WORKER_CONFIG,
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
name: 'embedding',
|
|
508
|
+
keys: EMBEDDING_KEYS,
|
|
509
|
+
defaults: DEFAULT_EMBEDDING_CONFIG,
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
name: 'vectorStore',
|
|
513
|
+
keys: VECTOR_STORE_KEYS,
|
|
514
|
+
defaults: DEFAULT_VECTOR_STORE_CONFIG,
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
name: 'search',
|
|
518
|
+
keys: SEARCH_KEYS,
|
|
519
|
+
defaults: DEFAULT_SEARCH_CONFIG,
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
name: 'callGraph',
|
|
523
|
+
keys: CALL_GRAPH_KEYS,
|
|
524
|
+
defaults: DEFAULT_CALL_GRAPH_CONFIG,
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
name: 'ann',
|
|
528
|
+
keys: ANN_KEYS,
|
|
529
|
+
defaults: DEFAULT_ANN_CONFIG,
|
|
530
|
+
},
|
|
531
|
+
]);
|
|
532
|
+
|
|
533
|
+
function applyNamespace(targetConfig, sourceConfig, namespaceName, keys, defaults) {
|
|
534
|
+
const sourceNamespace =
|
|
535
|
+
sourceConfig && typeof sourceConfig[namespaceName] === 'object'
|
|
536
|
+
? sourceConfig[namespaceName]
|
|
537
|
+
: {};
|
|
538
|
+
const mergedNamespace = {
|
|
539
|
+
...defaults,
|
|
540
|
+
...(targetConfig[namespaceName] && typeof targetConfig[namespaceName] === 'object'
|
|
541
|
+
? targetConfig[namespaceName]
|
|
542
|
+
: {}),
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
for (const key of keys) {
|
|
546
|
+
if (hasOwn(sourceNamespace, key)) {
|
|
547
|
+
targetConfig[key] = mergedNamespace[key];
|
|
548
|
+
} else {
|
|
549
|
+
mergedNamespace[key] = targetConfig[key];
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
targetConfig[namespaceName] = mergedNamespace;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
function syncNamespace(targetConfig, namespaceName, keys, defaults) {
|
|
557
|
+
const currentNamespace =
|
|
558
|
+
targetConfig[namespaceName] && typeof targetConfig[namespaceName] === 'object'
|
|
559
|
+
? targetConfig[namespaceName]
|
|
560
|
+
: {};
|
|
561
|
+
const mergedNamespace = { ...defaults, ...currentNamespace };
|
|
562
|
+
for (const key of keys) {
|
|
563
|
+
mergedNamespace[key] = targetConfig[key];
|
|
564
|
+
}
|
|
565
|
+
targetConfig[namespaceName] = mergedNamespace;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
function applyAllNamespaces(targetConfig, sourceConfig) {
|
|
569
|
+
for (const namespace of CONFIG_NAMESPACES) {
|
|
570
|
+
applyNamespace(
|
|
571
|
+
targetConfig,
|
|
572
|
+
sourceConfig,
|
|
573
|
+
namespace.name,
|
|
574
|
+
namespace.keys,
|
|
575
|
+
namespace.defaults
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function syncAllNamespaces(targetConfig) {
|
|
581
|
+
for (const namespace of CONFIG_NAMESPACES) {
|
|
582
|
+
syncNamespace(targetConfig, namespace.name, namespace.keys, namespace.defaults);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
585
|
|
|
586
586
|
async function pathExists(filePath) {
|
|
587
587
|
try {
|
|
@@ -602,7 +602,7 @@ async function readConfigFile(filePath) {
|
|
|
602
602
|
}
|
|
603
603
|
}
|
|
604
604
|
|
|
605
|
-
async function findWorkspaceRoot(startDir) {
|
|
605
|
+
async function findWorkspaceRoot(startDir) {
|
|
606
606
|
let current = path.resolve(startDir);
|
|
607
607
|
while (true) {
|
|
608
608
|
for (const marker of WORKSPACE_MARKERS) {
|
|
@@ -614,113 +614,113 @@ async function findWorkspaceRoot(startDir) {
|
|
|
614
614
|
if (parent === current) break;
|
|
615
615
|
current = parent;
|
|
616
616
|
}
|
|
617
|
-
return path.resolve(startDir);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
async function resolveWorkspaceCandidate(rawValue) {
|
|
621
|
-
if (!rawValue || rawValue.includes('${')) return null;
|
|
622
|
-
const candidate = path.resolve(rawValue);
|
|
623
|
-
if (!(await pathExists(candidate))) return null;
|
|
624
|
-
try {
|
|
625
|
-
const stats = await fs.stat(candidate);
|
|
626
|
-
if (!stats.isDirectory()) return null;
|
|
627
|
-
} catch {
|
|
628
|
-
return null;
|
|
629
|
-
}
|
|
630
|
-
return candidate;
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
function logWorkspaceResolution(resolution) {
|
|
634
|
-
if (!resolution || !resolution.path) return;
|
|
635
|
-
|
|
636
|
-
if (resolution.source === 'workspace-arg') {
|
|
637
|
-
console.info(`[Config] Workspace resolution: --workspace -> ${resolution.path}`);
|
|
638
|
-
return;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
if (resolution.source === 'env' && resolution.envKey) {
|
|
642
|
-
console.info(`[Config] Workspace resolution: env ${resolution.envKey} -> ${resolution.path}`);
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
if (resolution.source === 'test-cwd') {
|
|
647
|
-
console.info(`[Config] Workspace resolution: process.cwd() (test mode) -> ${resolution.path}`);
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
if (resolution.source === 'cwd-root-search') {
|
|
652
|
-
const from = resolution.fromPath || process.cwd();
|
|
653
|
-
console.info(
|
|
654
|
-
`[Config] Workspace resolution: workspace root from cwd (${from}) -> ${resolution.path}`
|
|
655
|
-
);
|
|
656
|
-
return;
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
console.info(`[Config] Workspace resolution: process.cwd() -> ${resolution.path}`);
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
async function resolveWorkspaceDir(workspaceDir) {
|
|
663
|
-
if (workspaceDir) {
|
|
664
|
-
return {
|
|
665
|
-
path: path.resolve(workspaceDir),
|
|
666
|
-
source: 'workspace-arg',
|
|
667
|
-
};
|
|
668
|
-
}
|
|
669
|
-
if (process.env.VITEST === 'true' || process.env.NODE_ENV === 'test') {
|
|
670
|
-
return {
|
|
671
|
-
path: path.resolve(process.cwd()),
|
|
672
|
-
source: 'test-cwd',
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
for (const key of getWorkspaceEnvKeys()) {
|
|
677
|
-
const candidate = await resolveWorkspaceCandidate(process.env[key]);
|
|
678
|
-
if (candidate) {
|
|
679
|
-
return {
|
|
680
|
-
path: candidate,
|
|
681
|
-
source: 'env',
|
|
682
|
-
envKey: key,
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
const cwd = path.resolve(process.cwd());
|
|
688
|
-
const root = await findWorkspaceRoot(cwd);
|
|
689
|
-
if (root !== cwd) {
|
|
690
|
-
return {
|
|
691
|
-
path: root,
|
|
692
|
-
source: 'cwd-root-search',
|
|
693
|
-
fromPath: cwd,
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
|
-
return {
|
|
697
|
-
path: cwd,
|
|
698
|
-
source: 'cwd',
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
export async function loadConfig(workspaceDir = null) {
|
|
703
|
-
try {
|
|
617
|
+
return path.resolve(startDir);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
async function resolveWorkspaceCandidate(rawValue) {
|
|
621
|
+
if (!rawValue || rawValue.includes('${')) return null;
|
|
622
|
+
const candidate = path.resolve(rawValue);
|
|
623
|
+
if (!(await pathExists(candidate))) return null;
|
|
624
|
+
try {
|
|
625
|
+
const stats = await fs.stat(candidate);
|
|
626
|
+
if (!stats.isDirectory()) return null;
|
|
627
|
+
} catch {
|
|
628
|
+
return null;
|
|
629
|
+
}
|
|
630
|
+
return candidate;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function logWorkspaceResolution(resolution) {
|
|
634
|
+
if (!resolution || !resolution.path) return;
|
|
635
|
+
|
|
636
|
+
if (resolution.source === 'workspace-arg') {
|
|
637
|
+
console.info(`[Config] Workspace resolution: --workspace -> ${resolution.path}`);
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
if (resolution.source === 'env' && resolution.envKey) {
|
|
642
|
+
console.info(`[Config] Workspace resolution: env ${resolution.envKey} -> ${resolution.path}`);
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (resolution.source === 'test-cwd') {
|
|
647
|
+
console.info(`[Config] Workspace resolution: process.cwd() (test mode) -> ${resolution.path}`);
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (resolution.source === 'cwd-root-search') {
|
|
652
|
+
const from = resolution.fromPath || process.cwd();
|
|
653
|
+
console.info(
|
|
654
|
+
`[Config] Workspace resolution: workspace root from cwd (${from}) -> ${resolution.path}`
|
|
655
|
+
);
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
console.info(`[Config] Workspace resolution: process.cwd() -> ${resolution.path}`);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
async function resolveWorkspaceDir(workspaceDir) {
|
|
663
|
+
if (workspaceDir) {
|
|
664
|
+
return {
|
|
665
|
+
path: path.resolve(workspaceDir),
|
|
666
|
+
source: 'workspace-arg',
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
if (process.env.VITEST === 'true' || process.env.NODE_ENV === 'test') {
|
|
670
|
+
return {
|
|
671
|
+
path: path.resolve(process.cwd()),
|
|
672
|
+
source: 'test-cwd',
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
for (const key of getWorkspaceEnvKeys()) {
|
|
677
|
+
const candidate = await resolveWorkspaceCandidate(process.env[key]);
|
|
678
|
+
if (candidate) {
|
|
679
|
+
return {
|
|
680
|
+
path: candidate,
|
|
681
|
+
source: 'env',
|
|
682
|
+
envKey: key,
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
const cwd = path.resolve(process.cwd());
|
|
688
|
+
const root = await findWorkspaceRoot(cwd);
|
|
689
|
+
if (root !== cwd) {
|
|
690
|
+
return {
|
|
691
|
+
path: root,
|
|
692
|
+
source: 'cwd-root-search',
|
|
693
|
+
fromPath: cwd,
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
return {
|
|
697
|
+
path: cwd,
|
|
698
|
+
source: 'cwd',
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
export async function loadConfig(workspaceDir = null) {
|
|
703
|
+
try {
|
|
704
704
|
// Determine the base directory for configuration
|
|
705
705
|
let baseDir;
|
|
706
706
|
let configPath;
|
|
707
|
-
|
|
708
|
-
let serverDir = null;
|
|
709
|
-
if (workspaceDir) {
|
|
710
|
-
// Workspace mode: load config from workspace root
|
|
711
|
-
const workspaceResolution = await resolveWorkspaceDir(workspaceDir);
|
|
712
|
-
baseDir = workspaceResolution.path;
|
|
713
|
-
console.info(`[Config] Workspace mode: ${baseDir}`);
|
|
714
|
-
logWorkspaceResolution(workspaceResolution);
|
|
715
|
-
} else {
|
|
716
|
-
// Server mode: load config from server directory for global settings,
|
|
717
|
-
// but use process.cwd() as base for searching if not specified otherwise
|
|
718
|
-
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
719
|
-
serverDir = path.resolve(scriptDir, '..');
|
|
720
|
-
const workspaceResolution = await resolveWorkspaceDir(null);
|
|
721
|
-
baseDir = workspaceResolution.path;
|
|
722
|
-
logWorkspaceResolution(workspaceResolution);
|
|
723
|
-
}
|
|
707
|
+
|
|
708
|
+
let serverDir = null;
|
|
709
|
+
if (workspaceDir) {
|
|
710
|
+
// Workspace mode: load config from workspace root
|
|
711
|
+
const workspaceResolution = await resolveWorkspaceDir(workspaceDir);
|
|
712
|
+
baseDir = workspaceResolution.path;
|
|
713
|
+
console.info(`[Config] Workspace mode: ${baseDir}`);
|
|
714
|
+
logWorkspaceResolution(workspaceResolution);
|
|
715
|
+
} else {
|
|
716
|
+
// Server mode: load config from server directory for global settings,
|
|
717
|
+
// but use process.cwd() as base for searching if not specified otherwise
|
|
718
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
719
|
+
serverDir = path.resolve(scriptDir, '..');
|
|
720
|
+
const workspaceResolution = await resolveWorkspaceDir(null);
|
|
721
|
+
baseDir = workspaceResolution.path;
|
|
722
|
+
logWorkspaceResolution(workspaceResolution);
|
|
723
|
+
}
|
|
724
724
|
|
|
725
725
|
let userConfig = {};
|
|
726
726
|
const configNames = ['config.jsonc', 'config.json'];
|
|
@@ -759,16 +759,16 @@ export async function loadConfig(workspaceDir = null) {
|
|
|
759
759
|
}
|
|
760
760
|
}
|
|
761
761
|
|
|
762
|
-
config = { ...DEFAULT_CONFIG, ...userConfig };
|
|
763
|
-
applyAllNamespaces(config, userConfig);
|
|
764
|
-
|
|
765
|
-
// Backward compatibility for legacy top-level cache cleanup toggle.
|
|
766
|
-
if (
|
|
767
|
-
hasOwn(userConfig, 'autoCleanStaleCaches') &&
|
|
768
|
-
!(userConfig.cacheCleanup && hasOwn(userConfig.cacheCleanup, 'autoCleanup'))
|
|
769
|
-
) {
|
|
770
|
-
config.cacheCleanup.autoCleanup = Boolean(userConfig.autoCleanStaleCaches);
|
|
771
|
-
}
|
|
762
|
+
config = { ...DEFAULT_CONFIG, ...userConfig };
|
|
763
|
+
applyAllNamespaces(config, userConfig);
|
|
764
|
+
|
|
765
|
+
// Backward compatibility for legacy top-level cache cleanup toggle.
|
|
766
|
+
if (
|
|
767
|
+
hasOwn(userConfig, 'autoCleanStaleCaches') &&
|
|
768
|
+
!(userConfig.cacheCleanup && hasOwn(userConfig.cacheCleanup, 'autoCleanup'))
|
|
769
|
+
) {
|
|
770
|
+
config.cacheCleanup.autoCleanup = Boolean(userConfig.autoCleanStaleCaches);
|
|
771
|
+
}
|
|
772
772
|
|
|
773
773
|
// Set search directory (respect user override when provided)
|
|
774
774
|
if (userConfig.searchDirectory) {
|
|
@@ -1050,74 +1050,74 @@ export async function loadConfig(workspaceDir = null) {
|
|
|
1050
1050
|
}
|
|
1051
1051
|
}
|
|
1052
1052
|
|
|
1053
|
-
if (process.env.SMART_CODING_INCREMENTAL_GC_THRESHOLD_MB !== undefined) {
|
|
1054
|
-
const value = parseInt(process.env.SMART_CODING_INCREMENTAL_GC_THRESHOLD_MB, 10);
|
|
1055
|
-
if (!isNaN(value) && value >= 0) {
|
|
1056
|
-
config.incrementalGcThresholdMb = value;
|
|
1053
|
+
if (process.env.SMART_CODING_INCREMENTAL_GC_THRESHOLD_MB !== undefined) {
|
|
1054
|
+
const value = parseInt(process.env.SMART_CODING_INCREMENTAL_GC_THRESHOLD_MB, 10);
|
|
1055
|
+
if (!isNaN(value) && value >= 0) {
|
|
1056
|
+
config.incrementalGcThresholdMb = value;
|
|
1057
1057
|
} else {
|
|
1058
1058
|
console.warn(
|
|
1059
1059
|
`[Config] Invalid SMART_CODING_INCREMENTAL_GC_THRESHOLD_MB: ${process.env.SMART_CODING_INCREMENTAL_GC_THRESHOLD_MB}, using default`
|
|
1060
|
-
);
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
if (process.env.SMART_CODING_INCREMENTAL_MEMORY_PROFILE !== undefined) {
|
|
1065
|
-
const value = process.env.SMART_CODING_INCREMENTAL_MEMORY_PROFILE;
|
|
1066
|
-
if (value === 'true' || value === 'false') {
|
|
1067
|
-
config.incrementalMemoryProfile = value === 'true';
|
|
1068
|
-
} else {
|
|
1069
|
-
console.warn(
|
|
1070
|
-
`[Config] Invalid SMART_CODING_INCREMENTAL_MEMORY_PROFILE: ${value}, using default`
|
|
1071
|
-
);
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
if (process.env.SMART_CODING_RECYCLE_SERVER_ON_HIGH_RSS_AFTER_INCREMENTAL !== undefined) {
|
|
1076
|
-
const value = process.env.SMART_CODING_RECYCLE_SERVER_ON_HIGH_RSS_AFTER_INCREMENTAL;
|
|
1077
|
-
if (value === 'true' || value === 'false') {
|
|
1078
|
-
config.recycleServerOnHighRssAfterIncremental = value === 'true';
|
|
1079
|
-
} else {
|
|
1080
|
-
console.warn(
|
|
1081
|
-
`[Config] Invalid SMART_CODING_RECYCLE_SERVER_ON_HIGH_RSS_AFTER_INCREMENTAL: ${value}, using default`
|
|
1082
|
-
);
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
if (process.env.SMART_CODING_RECYCLE_SERVER_RSS_THRESHOLD_MB !== undefined) {
|
|
1087
|
-
const value = parseInt(process.env.SMART_CODING_RECYCLE_SERVER_RSS_THRESHOLD_MB, 10);
|
|
1088
|
-
if (!isNaN(value) && value > 0) {
|
|
1089
|
-
config.recycleServerOnHighRssThresholdMb = value;
|
|
1090
|
-
} else {
|
|
1091
|
-
console.warn(
|
|
1092
|
-
`[Config] Invalid SMART_CODING_RECYCLE_SERVER_RSS_THRESHOLD_MB: ${process.env.SMART_CODING_RECYCLE_SERVER_RSS_THRESHOLD_MB}, using default`
|
|
1093
|
-
);
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
if (process.env.SMART_CODING_RECYCLE_SERVER_COOLDOWN_MS !== undefined) {
|
|
1098
|
-
const value = parseInt(process.env.SMART_CODING_RECYCLE_SERVER_COOLDOWN_MS, 10);
|
|
1099
|
-
if (!isNaN(value) && value >= 0) {
|
|
1100
|
-
config.recycleServerOnHighRssCooldownMs = value;
|
|
1101
|
-
} else {
|
|
1102
|
-
console.warn(
|
|
1103
|
-
`[Config] Invalid SMART_CODING_RECYCLE_SERVER_COOLDOWN_MS: ${process.env.SMART_CODING_RECYCLE_SERVER_COOLDOWN_MS}, using default`
|
|
1104
|
-
);
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
|
-
if (process.env.SMART_CODING_RECYCLE_SERVER_DELAY_MS !== undefined) {
|
|
1109
|
-
const value = parseInt(process.env.SMART_CODING_RECYCLE_SERVER_DELAY_MS, 10);
|
|
1110
|
-
if (!isNaN(value) && value >= 0) {
|
|
1111
|
-
config.recycleServerOnHighRssDelayMs = value;
|
|
1112
|
-
} else {
|
|
1113
|
-
console.warn(
|
|
1114
|
-
`[Config] Invalid SMART_CODING_RECYCLE_SERVER_DELAY_MS: ${process.env.SMART_CODING_RECYCLE_SERVER_DELAY_MS}, using default`
|
|
1115
|
-
);
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
if (process.env.SMART_CODING_CONTENT_CACHE_ENTRIES !== undefined) {
|
|
1120
|
-
const value = parseInt(process.env.SMART_CODING_CONTENT_CACHE_ENTRIES, 10);
|
|
1060
|
+
);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
if (process.env.SMART_CODING_INCREMENTAL_MEMORY_PROFILE !== undefined) {
|
|
1065
|
+
const value = process.env.SMART_CODING_INCREMENTAL_MEMORY_PROFILE;
|
|
1066
|
+
if (value === 'true' || value === 'false') {
|
|
1067
|
+
config.incrementalMemoryProfile = value === 'true';
|
|
1068
|
+
} else {
|
|
1069
|
+
console.warn(
|
|
1070
|
+
`[Config] Invalid SMART_CODING_INCREMENTAL_MEMORY_PROFILE: ${value}, using default`
|
|
1071
|
+
);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
if (process.env.SMART_CODING_RECYCLE_SERVER_ON_HIGH_RSS_AFTER_INCREMENTAL !== undefined) {
|
|
1076
|
+
const value = process.env.SMART_CODING_RECYCLE_SERVER_ON_HIGH_RSS_AFTER_INCREMENTAL;
|
|
1077
|
+
if (value === 'true' || value === 'false') {
|
|
1078
|
+
config.recycleServerOnHighRssAfterIncremental = value === 'true';
|
|
1079
|
+
} else {
|
|
1080
|
+
console.warn(
|
|
1081
|
+
`[Config] Invalid SMART_CODING_RECYCLE_SERVER_ON_HIGH_RSS_AFTER_INCREMENTAL: ${value}, using default`
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
if (process.env.SMART_CODING_RECYCLE_SERVER_RSS_THRESHOLD_MB !== undefined) {
|
|
1087
|
+
const value = parseInt(process.env.SMART_CODING_RECYCLE_SERVER_RSS_THRESHOLD_MB, 10);
|
|
1088
|
+
if (!isNaN(value) && value > 0) {
|
|
1089
|
+
config.recycleServerOnHighRssThresholdMb = value;
|
|
1090
|
+
} else {
|
|
1091
|
+
console.warn(
|
|
1092
|
+
`[Config] Invalid SMART_CODING_RECYCLE_SERVER_RSS_THRESHOLD_MB: ${process.env.SMART_CODING_RECYCLE_SERVER_RSS_THRESHOLD_MB}, using default`
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
if (process.env.SMART_CODING_RECYCLE_SERVER_COOLDOWN_MS !== undefined) {
|
|
1098
|
+
const value = parseInt(process.env.SMART_CODING_RECYCLE_SERVER_COOLDOWN_MS, 10);
|
|
1099
|
+
if (!isNaN(value) && value >= 0) {
|
|
1100
|
+
config.recycleServerOnHighRssCooldownMs = value;
|
|
1101
|
+
} else {
|
|
1102
|
+
console.warn(
|
|
1103
|
+
`[Config] Invalid SMART_CODING_RECYCLE_SERVER_COOLDOWN_MS: ${process.env.SMART_CODING_RECYCLE_SERVER_COOLDOWN_MS}, using default`
|
|
1104
|
+
);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
if (process.env.SMART_CODING_RECYCLE_SERVER_DELAY_MS !== undefined) {
|
|
1109
|
+
const value = parseInt(process.env.SMART_CODING_RECYCLE_SERVER_DELAY_MS, 10);
|
|
1110
|
+
if (!isNaN(value) && value >= 0) {
|
|
1111
|
+
config.recycleServerOnHighRssDelayMs = value;
|
|
1112
|
+
} else {
|
|
1113
|
+
console.warn(
|
|
1114
|
+
`[Config] Invalid SMART_CODING_RECYCLE_SERVER_DELAY_MS: ${process.env.SMART_CODING_RECYCLE_SERVER_DELAY_MS}, using default`
|
|
1115
|
+
);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
if (process.env.SMART_CODING_CONTENT_CACHE_ENTRIES !== undefined) {
|
|
1120
|
+
const value = parseInt(process.env.SMART_CODING_CONTENT_CACHE_ENTRIES, 10);
|
|
1121
1121
|
if (!isNaN(value) && value >= 0 && value <= 10000) {
|
|
1122
1122
|
config.contentCacheEntries = value;
|
|
1123
1123
|
} else {
|
|
@@ -1414,9 +1414,9 @@ export async function loadConfig(workspaceDir = null) {
|
|
|
1414
1414
|
}
|
|
1415
1415
|
}
|
|
1416
1416
|
|
|
1417
|
-
if (
|
|
1418
|
-
config.embeddingProcessGcMaxRequestsWithoutCollection !== null &&
|
|
1419
|
-
config.embeddingProcessGcMaxRequestsWithoutCollection !== undefined
|
|
1417
|
+
if (
|
|
1418
|
+
config.embeddingProcessGcMaxRequestsWithoutCollection !== null &&
|
|
1419
|
+
config.embeddingProcessGcMaxRequestsWithoutCollection !== undefined
|
|
1420
1420
|
) {
|
|
1421
1421
|
const value = parseInt(config.embeddingProcessGcMaxRequestsWithoutCollection, 10);
|
|
1422
1422
|
if (!isNaN(value) && value > 0) {
|
|
@@ -1425,14 +1425,14 @@ export async function loadConfig(workspaceDir = null) {
|
|
|
1425
1425
|
console.warn(
|
|
1426
1426
|
`[Config] Invalid embeddingProcessGcMaxRequestsWithoutCollection: ${config.embeddingProcessGcMaxRequestsWithoutCollection}, using default`
|
|
1427
1427
|
);
|
|
1428
|
-
config.embeddingProcessGcMaxRequestsWithoutCollection =
|
|
1429
|
-
DEFAULT_CONFIG.embeddingProcessGcMaxRequestsWithoutCollection;
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
|
|
1433
|
-
syncAllNamespaces(config);
|
|
1434
|
-
return config;
|
|
1435
|
-
}
|
|
1428
|
+
config.embeddingProcessGcMaxRequestsWithoutCollection =
|
|
1429
|
+
DEFAULT_CONFIG.embeddingProcessGcMaxRequestsWithoutCollection;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
syncAllNamespaces(config);
|
|
1434
|
+
return config;
|
|
1435
|
+
}
|
|
1436
1436
|
|
|
1437
1437
|
/**
|
|
1438
1438
|
* Get platform-specific global cache directory
|