minimem 0.0.5 → 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.
- package/dist/index.cjs +3984 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +858 -0
- package/dist/internal.cjs +286 -0
- package/dist/internal.cjs.map +1 -0
- package/dist/internal.d.cts +65 -0
- package/dist/session.cjs +298 -0
- package/dist/session.cjs.map +1 -0
- package/dist/session.d.cts +96 -0
- package/package.json +7 -4
package/dist/index.d.cts
ADDED
|
@@ -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 };
|