minimem 0.0.4 → 0.0.6

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.
@@ -0,0 +1,858 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ import { DebugFn, MemoryFileEntry, MemoryChunk } from './internal.cjs';
3
+ export { buildFileEntry, chunkMarkdown, cosineSimilarity, extractChunkMetadata, hashText, isMemoryPath, listMemoryFiles, stripPrivateContent } from './internal.cjs';
4
+ export { KnowledgeLink, KnowledgeSource, MemoryFrontmatter, SessionContext, addFrontmatter, addSessionToContent, extractSession, parseFrontmatter, serializeFrontmatter } from './session.cjs';
5
+
6
+ /**
7
+ * A knowledge graph link between two nodes
8
+ */
9
+ type GraphLink = {
10
+ fromId: string;
11
+ toId: string;
12
+ relation: string;
13
+ layer: string | null;
14
+ weight: number;
15
+ sourcePath: string | null;
16
+ };
17
+ /**
18
+ * A neighbor node discovered during graph traversal
19
+ */
20
+ type GraphNeighbor = {
21
+ id: string;
22
+ depth: number;
23
+ link: GraphLink;
24
+ };
25
+ /**
26
+ * Get all outgoing links from a node.
27
+ */
28
+ declare function getLinksFrom(db: DatabaseSync, fromId: string, opts?: {
29
+ relation?: string;
30
+ layer?: string;
31
+ }): GraphLink[];
32
+ /**
33
+ * Get all incoming links to a node.
34
+ */
35
+ declare function getLinksTo(db: DatabaseSync, toId: string, opts?: {
36
+ relation?: string;
37
+ layer?: string;
38
+ }): GraphLink[];
39
+ /**
40
+ * BFS traversal to find neighbors up to a given depth.
41
+ *
42
+ * @param db - Database handle
43
+ * @param startId - The starting node ID
44
+ * @param depth - Maximum traversal depth (default: 1)
45
+ * @param opts - Optional filters for relation and layer
46
+ * @returns Array of neighbor nodes with their depth and connecting link
47
+ */
48
+ declare function getNeighbors(db: DatabaseSync, startId: string, depth?: number, opts?: {
49
+ relation?: string;
50
+ layer?: string;
51
+ }): GraphNeighbor[];
52
+ /**
53
+ * BFS shortest path between two nodes, max depth 3.
54
+ *
55
+ * @returns Array of links forming the path, or empty if no path found.
56
+ */
57
+ declare function getPathBetween(db: DatabaseSync, fromId: string, toId: string, maxDepth?: number): GraphLink[];
58
+
59
+ type EmbeddingProvider = {
60
+ id: string;
61
+ model: string;
62
+ embedQuery: (text: string) => Promise<number[]>;
63
+ embedBatch: (texts: string[]) => Promise<number[][]>;
64
+ };
65
+ type EmbeddingProviderResult = {
66
+ provider: EmbeddingProvider;
67
+ requestedProvider: "openai" | "local" | "gemini" | "auto" | "none";
68
+ fallbackFrom?: "openai" | "local" | "gemini" | "auto";
69
+ fallbackReason?: string;
70
+ openAi?: OpenAiEmbeddingClient;
71
+ gemini?: GeminiEmbeddingClient;
72
+ };
73
+ type EmbeddingProviderOptions = {
74
+ provider: "openai" | "local" | "gemini" | "auto" | "none";
75
+ model?: string;
76
+ fallback?: "openai" | "gemini" | "local" | "none";
77
+ openai?: {
78
+ apiKey?: string;
79
+ baseUrl?: string;
80
+ headers?: Record<string, string>;
81
+ };
82
+ gemini?: {
83
+ apiKey?: string;
84
+ baseUrl?: string;
85
+ headers?: Record<string, string>;
86
+ };
87
+ local?: {
88
+ modelPath?: string;
89
+ modelCacheDir?: string;
90
+ };
91
+ };
92
+ type OpenAiEmbeddingClient = {
93
+ baseUrl: string;
94
+ headers: Record<string, string>;
95
+ model: string;
96
+ };
97
+ type GeminiEmbeddingClient = {
98
+ baseUrl: string;
99
+ headers: Record<string, string>;
100
+ model: string;
101
+ modelPath: string;
102
+ };
103
+ declare function createOpenAiEmbeddingProvider(options: EmbeddingProviderOptions): Promise<{
104
+ provider: EmbeddingProvider;
105
+ client: OpenAiEmbeddingClient;
106
+ }>;
107
+ declare function createGeminiEmbeddingProvider(options: EmbeddingProviderOptions): Promise<{
108
+ provider: EmbeddingProvider;
109
+ client: GeminiEmbeddingClient;
110
+ }>;
111
+ declare function createEmbeddingProvider(options: EmbeddingProviderOptions): Promise<EmbeddingProviderResult>;
112
+
113
+ type MinimemConfig = {
114
+ /** Directory containing memory files (MEMORY.md, memory/*.md) */
115
+ memoryDir: string;
116
+ /** Path to SQLite database. Defaults to memoryDir/.minimem/index.db */
117
+ dbPath?: string;
118
+ /** Embedding provider options */
119
+ embedding: EmbeddingProviderOptions;
120
+ /** Chunking configuration */
121
+ chunking?: {
122
+ /** Tokens per chunk (default: 256) */
123
+ tokens?: number;
124
+ /** Overlap tokens between chunks (default: 32) */
125
+ overlap?: number;
126
+ };
127
+ /** Embedding cache configuration */
128
+ cache?: {
129
+ /** Enable embedding cache (default: true) */
130
+ enabled?: boolean;
131
+ /** Max cache entries before LRU pruning (default: 10000) */
132
+ maxEntries?: number;
133
+ };
134
+ /** Hybrid search configuration */
135
+ hybrid?: {
136
+ /** Enable hybrid search (default: true) */
137
+ enabled?: boolean;
138
+ /** Weight for vector search (default: 0.7) */
139
+ vectorWeight?: number;
140
+ /** Weight for keyword search (default: 0.3) */
141
+ textWeight?: number;
142
+ /** Candidate multiplier for search (default: 2.0) */
143
+ candidateMultiplier?: number;
144
+ };
145
+ /** Query configuration */
146
+ query?: {
147
+ /** Max results (default: 10) */
148
+ maxResults?: number;
149
+ /** Min score threshold (default: 0.3) */
150
+ minScore?: number;
151
+ };
152
+ /** File watching configuration */
153
+ watch?: {
154
+ /** Enable file watching (default: true) */
155
+ enabled?: boolean;
156
+ /** Debounce delay in ms (default: 1000) */
157
+ debounceMs?: number;
158
+ };
159
+ /** Batch embedding configuration */
160
+ batch?: {
161
+ /** Enable batch embedding API (default: false) */
162
+ enabled?: boolean;
163
+ /** Wait for batch completion (default: true) */
164
+ wait?: boolean;
165
+ /** Concurrent batch requests (default: 2) */
166
+ concurrency?: number;
167
+ /** Poll interval in ms (default: 2000) */
168
+ pollIntervalMs?: number;
169
+ /** Timeout in ms (default: 60 minutes) */
170
+ timeoutMs?: number;
171
+ };
172
+ /** sqlite-vec extension path (optional) */
173
+ vectorExtensionPath?: string;
174
+ /** Debug logging function */
175
+ debug?: (message: string, data?: Record<string, unknown>) => void;
176
+ };
177
+ type MinimemSearchResult = {
178
+ path: string;
179
+ startLine: number;
180
+ endLine: number;
181
+ score: number;
182
+ snippet: string;
183
+ };
184
+ declare class Minimem {
185
+ private readonly memoryDir;
186
+ private readonly dbPath;
187
+ private readonly chunking;
188
+ private readonly cache;
189
+ private readonly hybrid;
190
+ private readonly queryConfig;
191
+ private readonly watchConfig;
192
+ private readonly batchConfig;
193
+ private readonly vectorExtensionPath?;
194
+ private readonly debug?;
195
+ private provider;
196
+ private openAi?;
197
+ private gemini?;
198
+ private providerKey;
199
+ private providerFallbackReason?;
200
+ private db;
201
+ private readonly vector;
202
+ private readonly fts;
203
+ private vectorReady;
204
+ private watcher;
205
+ private watchTimer;
206
+ private closed;
207
+ private dirty;
208
+ private syncing;
209
+ private syncLock;
210
+ private embeddingOptions;
211
+ private constructor();
212
+ static create(config: MinimemConfig): Promise<Minimem>;
213
+ private initialize;
214
+ private openDatabase;
215
+ private ensureSchema;
216
+ private computeProviderKey;
217
+ private readMeta;
218
+ private writeMeta;
219
+ private ensureWatcher;
220
+ /**
221
+ * Check if the index is stale by comparing file mtimes against stored values.
222
+ * This is a lightweight check (stat calls only, no file reads).
223
+ */
224
+ private isStale;
225
+ search(query: string, opts?: {
226
+ maxResults?: number;
227
+ minScore?: number;
228
+ type?: string;
229
+ }): Promise<MinimemSearchResult[]>;
230
+ sync(opts?: {
231
+ reason?: string;
232
+ force?: boolean;
233
+ }): Promise<void>;
234
+ private runSync;
235
+ private indexFile;
236
+ private embedChunks;
237
+ private embedBatchWithRetry;
238
+ private embedWithBatchApi;
239
+ private embedQueryWithTimeout;
240
+ private loadEmbeddingCache;
241
+ private upsertEmbeddingCache;
242
+ private pruneEmbeddingCacheIfNeeded;
243
+ private ensureVectorReady;
244
+ private loadVectorExtension;
245
+ private ensureVectorTable;
246
+ readFile(relativePath: string): Promise<string | null>;
247
+ /**
248
+ * Read specific lines from a memory file
249
+ */
250
+ readLines(relativePath: string, opts?: {
251
+ from?: number;
252
+ lines?: number;
253
+ }): Promise<{
254
+ content: string;
255
+ startLine: number;
256
+ endLine: number;
257
+ } | null>;
258
+ /**
259
+ * Write content to a memory file (creates or overwrites)
260
+ */
261
+ writeFile(relativePath: string, content: string): Promise<void>;
262
+ /**
263
+ * Append content to a memory file (creates if doesn't exist)
264
+ */
265
+ appendFile(relativePath: string, content: string): Promise<void>;
266
+ /**
267
+ * Append content to today's daily log (memory/YYYY-MM-DD.md)
268
+ */
269
+ appendToday(content: string): Promise<string>;
270
+ /**
271
+ * List all memory files
272
+ */
273
+ listFiles(): Promise<string[]>;
274
+ /**
275
+ * Validate that a path is within allowed memory locations
276
+ */
277
+ private validateMemoryPath;
278
+ status(): Promise<{
279
+ memoryDir: string;
280
+ dbPath: string;
281
+ provider: string;
282
+ model: string;
283
+ vectorAvailable: boolean;
284
+ ftsAvailable: boolean;
285
+ bm25Only: boolean;
286
+ fallbackReason?: string;
287
+ fileCount: number;
288
+ chunkCount: number;
289
+ cacheCount: number;
290
+ }>;
291
+ /**
292
+ * Search with knowledge metadata filters (domain, entities, confidence, type).
293
+ * Runs a standard search then post-filters by knowledge columns.
294
+ */
295
+ knowledgeSearch(query: string, opts?: {
296
+ maxResults?: number;
297
+ minScore?: number;
298
+ domain?: string[];
299
+ entities?: string[];
300
+ minConfidence?: number;
301
+ knowledgeType?: string;
302
+ }): Promise<MinimemSearchResult[]>;
303
+ /**
304
+ * Get knowledge graph links from or to a node.
305
+ */
306
+ getLinks(nodeId: string, direction?: "from" | "to", opts?: {
307
+ relation?: string;
308
+ layer?: string;
309
+ }): GraphLink[];
310
+ /**
311
+ * Get neighbor nodes via BFS traversal.
312
+ */
313
+ getGraphNeighbors(nodeId: string, depth?: number, opts?: {
314
+ relation?: string;
315
+ layer?: string;
316
+ }): GraphNeighbor[];
317
+ /**
318
+ * Find shortest path between two knowledge nodes.
319
+ */
320
+ getGraphPath(fromId: string, toId: string, maxDepth?: number): GraphLink[];
321
+ close(): void;
322
+ }
323
+
324
+ type OpenAiBatchRequest = {
325
+ custom_id: string;
326
+ method: "POST";
327
+ url: "/v1/embeddings";
328
+ body: {
329
+ model: string;
330
+ input: string;
331
+ };
332
+ };
333
+ declare function runOpenAiEmbeddingBatches(params: {
334
+ openAi: OpenAiEmbeddingClient;
335
+ source: string;
336
+ requests: OpenAiBatchRequest[];
337
+ wait: boolean;
338
+ pollIntervalMs: number;
339
+ timeoutMs: number;
340
+ concurrency: number;
341
+ debug?: (message: string, data?: Record<string, unknown>) => void;
342
+ }): Promise<Map<string, number[]>>;
343
+
344
+ type GeminiBatchRequest = {
345
+ custom_id: string;
346
+ content: {
347
+ parts: Array<{
348
+ text: string;
349
+ }>;
350
+ };
351
+ taskType: "RETRIEVAL_DOCUMENT" | "RETRIEVAL_QUERY";
352
+ };
353
+ declare function runGeminiEmbeddingBatches(params: {
354
+ gemini: GeminiEmbeddingClient;
355
+ source: string;
356
+ requests: GeminiBatchRequest[];
357
+ wait: boolean;
358
+ pollIntervalMs: number;
359
+ timeoutMs: number;
360
+ concurrency: number;
361
+ debug?: (message: string, data?: Record<string, unknown>) => void;
362
+ }): Promise<Map<string, number[]>>;
363
+
364
+ /**
365
+ * Tool definitions for memory operations
366
+ *
367
+ * These tools are compatible with:
368
+ * - MCP (Model Context Protocol)
369
+ * - Anthropic Claude tool use
370
+ * - OpenAI function calling
371
+ *
372
+ * Note: Only memory_search is provided since the memory system is file-based.
373
+ * Agents can use filesystem tools directly for read/write operations.
374
+ */
375
+
376
+ /**
377
+ * JSON Schema for tool parameters (MCP/OpenAI/Anthropic compatible)
378
+ */
379
+ type ToolInputSchema = {
380
+ type: "object";
381
+ properties: Record<string, {
382
+ type: string;
383
+ description?: string;
384
+ enum?: string[];
385
+ items?: {
386
+ type: string;
387
+ };
388
+ default?: unknown;
389
+ }>;
390
+ required?: string[];
391
+ };
392
+ /**
393
+ * Tool definition compatible with MCP, Anthropic, and OpenAI
394
+ */
395
+ type ToolDefinition = {
396
+ name: string;
397
+ description: string;
398
+ inputSchema: ToolInputSchema;
399
+ };
400
+ /**
401
+ * Tool execution result
402
+ */
403
+ type ToolResult = {
404
+ content: Array<{
405
+ type: "text";
406
+ text: string;
407
+ }>;
408
+ isError?: boolean;
409
+ };
410
+ /**
411
+ * Memory search tool parameters
412
+ */
413
+ type MemorySearchParams = {
414
+ query: string;
415
+ maxResults?: number;
416
+ minScore?: number;
417
+ directories?: string[];
418
+ /** "compact" returns lightweight index; "full" returns complete snippets (default: "compact") */
419
+ detail?: "compact" | "full";
420
+ /** Filter by observation type (e.g., "decision", "bugfix", "feature", "discovery") */
421
+ type?: string;
422
+ };
423
+ /**
424
+ * Memory get details tool parameters
425
+ */
426
+ type MemoryGetDetailsParams = {
427
+ results: Array<{
428
+ path: string;
429
+ startLine: number;
430
+ endLine: number;
431
+ }>;
432
+ directories?: string[];
433
+ };
434
+ /**
435
+ * Knowledge search tool parameters
436
+ */
437
+ type KnowledgeSearchParams = {
438
+ query: string;
439
+ domain?: string[];
440
+ entities?: string[];
441
+ minConfidence?: number;
442
+ knowledgeType?: string;
443
+ maxResults?: number;
444
+ minScore?: number;
445
+ directories?: string[];
446
+ };
447
+ /**
448
+ * Knowledge graph traversal parameters
449
+ */
450
+ type KnowledgeGraphParams = {
451
+ nodeId: string;
452
+ depth?: number;
453
+ relation?: string;
454
+ layer?: string;
455
+ directories?: string[];
456
+ };
457
+ /**
458
+ * Knowledge path parameters
459
+ */
460
+ type KnowledgePathParams = {
461
+ fromId: string;
462
+ toId: string;
463
+ maxDepth?: number;
464
+ directories?: string[];
465
+ };
466
+ declare const MEMORY_SEARCH_TOOL: ToolDefinition;
467
+ declare const MEMORY_GET_DETAILS_TOOL: ToolDefinition;
468
+ declare const KNOWLEDGE_SEARCH_TOOL: ToolDefinition;
469
+ declare const KNOWLEDGE_GRAPH_TOOL: ToolDefinition;
470
+ declare const KNOWLEDGE_PATH_TOOL: ToolDefinition;
471
+ /**
472
+ * All available memory tools
473
+ */
474
+ declare const MEMORY_TOOLS: ToolDefinition[];
475
+ /**
476
+ * Get tool definitions for use with LLM APIs
477
+ */
478
+ declare function getToolDefinitions(): ToolDefinition[];
479
+ /**
480
+ * Memory instance with its directory path
481
+ */
482
+ type MemoryInstance = {
483
+ minimem: Minimem;
484
+ memoryDir: string;
485
+ name?: string;
486
+ };
487
+ /**
488
+ * Tool executor that handles memory search across multiple directories
489
+ */
490
+ declare class MemoryToolExecutor {
491
+ private instances;
492
+ constructor(instances: Minimem | MemoryInstance | MemoryInstance[]);
493
+ /**
494
+ * Get list of configured directory names/paths
495
+ */
496
+ getDirectories(): string[];
497
+ /**
498
+ * Execute a tool by name with given parameters
499
+ */
500
+ execute(toolName: string, params: Record<string, unknown>): Promise<ToolResult>;
501
+ /**
502
+ * Filter instances by directory names/paths
503
+ */
504
+ private filterInstances;
505
+ private memorySearch;
506
+ private formatCompactResults;
507
+ private formatFullResults;
508
+ private memoryGetDetails;
509
+ private knowledgeSearch;
510
+ private knowledgeGraph;
511
+ private knowledgePath;
512
+ }
513
+ /**
514
+ * Create a tool executor for the given Minimem instance(s)
515
+ */
516
+ declare function createToolExecutor(instances: Minimem | MemoryInstance | MemoryInstance[]): MemoryToolExecutor;
517
+
518
+ /**
519
+ * MCP (Model Context Protocol) Server for Minimem
520
+ *
521
+ * Provides memory tools via JSON-RPC 2.0 over stdio.
522
+ * Compatible with Claude Desktop, Cursor, and other MCP clients.
523
+ *
524
+ * Usage:
525
+ * import { Minimem } from "minimem";
526
+ * import { createMcpServer, runMcpServer } from "minimem/mcp";
527
+ *
528
+ * const minimem = await Minimem.create({ ... });
529
+ * const server = createMcpServer(minimem);
530
+ * await runMcpServer(server); // Runs over stdio
531
+ */
532
+
533
+ /**
534
+ * JSON-RPC 2.0 request
535
+ */
536
+ type JsonRpcRequest = {
537
+ jsonrpc: "2.0";
538
+ id: string | number;
539
+ method: string;
540
+ params?: Record<string, unknown>;
541
+ };
542
+ /**
543
+ * JSON-RPC 2.0 response
544
+ */
545
+ type JsonRpcResponse = {
546
+ jsonrpc: "2.0";
547
+ id: string | number | null;
548
+ result?: unknown;
549
+ error?: {
550
+ code: number;
551
+ message: string;
552
+ data?: unknown;
553
+ };
554
+ };
555
+ /**
556
+ * MCP Server implementation
557
+ */
558
+ declare class McpServer {
559
+ private executor;
560
+ private initialized;
561
+ constructor(instances: Minimem | MemoryInstance | MemoryInstance[]);
562
+ /**
563
+ * Handle a JSON-RPC request and return a response
564
+ */
565
+ handleRequest(request: JsonRpcRequest): Promise<JsonRpcResponse>;
566
+ /**
567
+ * Dispatch a method call
568
+ */
569
+ private dispatch;
570
+ /**
571
+ * Handle initialize request
572
+ */
573
+ private initialize;
574
+ /**
575
+ * List available tools
576
+ */
577
+ private listTools;
578
+ /**
579
+ * Call a tool
580
+ */
581
+ private callTool;
582
+ }
583
+ /**
584
+ * Create an MCP server for the given Minimem instance(s)
585
+ */
586
+ declare function createMcpServer(instances: Minimem | MemoryInstance | MemoryInstance[]): McpServer;
587
+ /**
588
+ * Run the MCP server over stdio
589
+ */
590
+ declare function runMcpServer(server: McpServer): Promise<void>;
591
+ /**
592
+ * MCP server configuration for claude_desktop_config.json
593
+ *
594
+ * Example:
595
+ * {
596
+ * "mcpServers": {
597
+ * "minimem": {
598
+ * "command": "node",
599
+ * "args": ["path/to/your/mcp-server.js"],
600
+ * "env": {
601
+ * "MEMORY_DIR": "/path/to/memory"
602
+ * }
603
+ * }
604
+ * }
605
+ * }
606
+ */
607
+ type McpServerConfig = {
608
+ command: string;
609
+ args: string[];
610
+ env?: Record<string, string>;
611
+ };
612
+ /**
613
+ * Generate MCP server config for Claude Desktop
614
+ */
615
+ declare function generateMcpConfig(opts: {
616
+ serverPath: string;
617
+ memoryDir: string;
618
+ embeddingProvider?: "openai" | "gemini" | "local" | "auto";
619
+ }): McpServerConfig;
620
+
621
+ /**
622
+ * Options for filtering search results by knowledge metadata
623
+ */
624
+ type KnowledgeSearchOptions = {
625
+ /** Filter to chunks matching any of these domains */
626
+ domain?: string[];
627
+ /** Filter to chunks referencing any of these entities */
628
+ entities?: string[];
629
+ /** Minimum confidence threshold */
630
+ minConfidence?: number;
631
+ /** Filter to a specific knowledge type */
632
+ knowledgeType?: string;
633
+ };
634
+ /**
635
+ * Build SQL WHERE clause fragments for knowledge filters.
636
+ * Uses json_each() for array column filtering.
637
+ */
638
+ declare function buildKnowledgeFilterSql(opts: KnowledgeSearchOptions): {
639
+ sql: string;
640
+ params: (string | number)[];
641
+ };
642
+
643
+ /**
644
+ * MemoryIndexer - Handles file indexing and embedding management
645
+ *
646
+ * Responsible for:
647
+ * - Processing memory files into chunks
648
+ * - Computing and caching embeddings
649
+ * - Managing file records in the database
650
+ * - Detecting stale content
651
+ */
652
+
653
+ type IndexerConfig = {
654
+ memoryDir: string;
655
+ chunking: {
656
+ tokens: number;
657
+ overlap: number;
658
+ };
659
+ cache: {
660
+ enabled: boolean;
661
+ maxEntries: number;
662
+ };
663
+ batch: {
664
+ enabled: boolean;
665
+ wait: boolean;
666
+ concurrency: number;
667
+ pollIntervalMs: number;
668
+ timeoutMs: number;
669
+ };
670
+ ftsEnabled: boolean;
671
+ debug?: DebugFn;
672
+ };
673
+ type MemoryIndexMeta = {
674
+ model: string;
675
+ provider: string;
676
+ providerKey?: string;
677
+ chunkTokens: number;
678
+ chunkOverlap: number;
679
+ vectorDims?: number;
680
+ };
681
+ type IndexStats = {
682
+ filesProcessed: number;
683
+ chunksCreated: number;
684
+ staleRemoved: number;
685
+ };
686
+ /**
687
+ * MemoryIndexer handles file indexing, chunking, and embedding management
688
+ */
689
+ declare class MemoryIndexer {
690
+ private readonly config;
691
+ private readonly db;
692
+ private readonly provider;
693
+ private readonly providerKey;
694
+ private readonly openAi?;
695
+ private readonly gemini?;
696
+ private vectorState;
697
+ private ftsAvailable;
698
+ constructor(db: DatabaseSync, provider: EmbeddingProvider, config: IndexerConfig, options?: {
699
+ openAi?: OpenAiEmbeddingClient;
700
+ gemini?: GeminiEmbeddingClient;
701
+ vectorState?: {
702
+ available: boolean;
703
+ dims?: number;
704
+ };
705
+ ftsAvailable?: boolean;
706
+ });
707
+ /**
708
+ * Update vector/FTS availability (called by parent when extensions load)
709
+ */
710
+ setVectorState(state: {
711
+ available: boolean;
712
+ dims?: number;
713
+ }): void;
714
+ setFtsAvailable(available: boolean): void;
715
+ getVectorDims(): number | undefined;
716
+ /**
717
+ * Compute a unique key for the current provider configuration
718
+ */
719
+ private computeProviderKey;
720
+ /**
721
+ * Read index metadata from database
722
+ */
723
+ readMeta(): MemoryIndexMeta | null;
724
+ /**
725
+ * Write index metadata to database
726
+ */
727
+ writeMeta(meta: MemoryIndexMeta): void;
728
+ /**
729
+ * Check if the index is stale by comparing file mtimes
730
+ */
731
+ isStale(): Promise<boolean>;
732
+ /**
733
+ * Check if a full reindex is needed based on configuration changes
734
+ */
735
+ needsFullReindex(force?: boolean): boolean;
736
+ /**
737
+ * Index all memory files, returns stats
738
+ */
739
+ indexAll(force?: boolean): Promise<IndexStats>;
740
+ /**
741
+ * Index a single file
742
+ */
743
+ indexFile(entry: MemoryFileEntry): Promise<number>;
744
+ /**
745
+ * Delete all chunks for a file
746
+ */
747
+ private deleteChunksForFile;
748
+ /**
749
+ * Insert a chunk into the database
750
+ */
751
+ private insertChunk;
752
+ /**
753
+ * Remove stale file entries that no longer exist
754
+ */
755
+ private removeStaleEntries;
756
+ /**
757
+ * Create vector table with the given dimensions
758
+ */
759
+ ensureVectorTable(dimensions: number): void;
760
+ /**
761
+ * Get embeddings for chunks, using cache when available
762
+ */
763
+ embedChunks(chunks: MemoryChunk[]): Promise<number[][]>;
764
+ /**
765
+ * Embed texts with retry logic
766
+ */
767
+ private embedBatchWithRetry;
768
+ /**
769
+ * Use batch API for large embedding jobs
770
+ */
771
+ private embedWithBatchApi;
772
+ /**
773
+ * Load embeddings from cache
774
+ */
775
+ private loadEmbeddingCache;
776
+ /**
777
+ * Save embedding to cache
778
+ */
779
+ private upsertEmbeddingCache;
780
+ /**
781
+ * Prune old cache entries if over limit
782
+ */
783
+ private pruneEmbeddingCacheIfNeeded;
784
+ }
785
+
786
+ /**
787
+ * MemorySearcher - Handles search operations
788
+ *
789
+ * Responsible for:
790
+ * - Executing vector searches
791
+ * - Executing keyword (FTS) searches
792
+ * - Merging results with hybrid scoring
793
+ */
794
+
795
+ type SearchConfig = {
796
+ hybrid: {
797
+ enabled: boolean;
798
+ vectorWeight: number;
799
+ textWeight: number;
800
+ candidateMultiplier: number;
801
+ };
802
+ query: {
803
+ maxResults: number;
804
+ minScore: number;
805
+ };
806
+ debug?: DebugFn;
807
+ };
808
+ type SearchResult = {
809
+ path: string;
810
+ startLine: number;
811
+ endLine: number;
812
+ score: number;
813
+ snippet: string;
814
+ };
815
+ /**
816
+ * MemorySearcher handles search queries against the indexed memory
817
+ */
818
+ declare class MemorySearcher {
819
+ private readonly db;
820
+ private readonly provider;
821
+ private readonly config;
822
+ private vectorState;
823
+ private ftsAvailable;
824
+ private ensureVectorReadyFn?;
825
+ constructor(db: DatabaseSync, provider: EmbeddingProvider, config: SearchConfig, options?: {
826
+ vectorState?: {
827
+ available: boolean;
828
+ dims?: number;
829
+ };
830
+ ftsAvailable?: boolean;
831
+ ensureVectorReady?: (dims?: number) => Promise<boolean>;
832
+ });
833
+ /**
834
+ * Update vector/FTS availability (called by parent when extensions load)
835
+ */
836
+ setVectorState(state: {
837
+ available: boolean;
838
+ dims?: number;
839
+ }): void;
840
+ setFtsAvailable(available: boolean): void;
841
+ /**
842
+ * Execute a search query
843
+ */
844
+ search(query: string, opts?: {
845
+ maxResults?: number;
846
+ minScore?: number;
847
+ }): Promise<SearchResult[]>;
848
+ /**
849
+ * Embed a query string with timeout
850
+ */
851
+ private embedQueryWithTimeout;
852
+ /**
853
+ * Ensure vector extension is ready
854
+ */
855
+ private ensureVectorReady;
856
+ }
857
+
858
+ export { type SearchResult as CoreSearchResult, DebugFn, type EmbeddingProvider, type EmbeddingProviderOptions, type EmbeddingProviderResult, type GeminiBatchRequest, type GeminiEmbeddingClient, type GraphLink, type GraphNeighbor, type IndexStats, type IndexerConfig, KNOWLEDGE_GRAPH_TOOL, KNOWLEDGE_PATH_TOOL, KNOWLEDGE_SEARCH_TOOL, type KnowledgeGraphParams, type KnowledgePathParams, type KnowledgeSearchOptions, type KnowledgeSearchParams, MEMORY_GET_DETAILS_TOOL, MEMORY_SEARCH_TOOL, MEMORY_TOOLS, McpServer, type McpServerConfig, MemoryChunk, MemoryFileEntry, type MemoryGetDetailsParams, type MemoryIndexMeta, MemoryIndexer, type MemoryInstance, type MemorySearchParams, MemorySearcher, MemoryToolExecutor, Minimem, type MinimemConfig, type MinimemSearchResult, type OpenAiBatchRequest, type OpenAiEmbeddingClient, type SearchConfig, type MinimemSearchResult as SearchResult, type ToolDefinition, type ToolInputSchema, type ToolResult, buildKnowledgeFilterSql, createEmbeddingProvider, createGeminiEmbeddingProvider, createMcpServer, createOpenAiEmbeddingProvider, createToolExecutor, generateMcpConfig, getLinksFrom, getLinksTo, getNeighbors, getPathBetween, getToolDefinitions, runGeminiEmbeddingBatches, runMcpServer, runOpenAiEmbeddingBatches };