@hanhnd/agent-kit 1.0.38 → 1.0.40
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/cli.js +286 -140
- package/dist/entrypoints/server.js +3 -3
- package/dist/mcp/memory.d.ts +4 -9
- package/dist/mcp/memory.js +43 -19
- package/dist/server.js +445 -212
- package/dist/services/digest/digest-processor.test.js +1 -3
- package/dist/services/memory/index.d.ts +3 -1
- package/dist/services/memory/index.js +1 -0
- package/dist/services/memory/indexer.d.ts +5 -6
- package/dist/services/memory/indexer.js +71 -101
- package/dist/services/memory/indexer.test.js +347 -572
- package/dist/services/memory/memory.test.js +58 -0
- package/dist/services/memory/store.d.ts +4 -11
- package/dist/services/memory/store.js +200 -66
- package/dist/services/memory/store.test.js +359 -108
- package/dist/services/memory/subsystem.d.ts +19 -0
- package/dist/services/memory/subsystem.js +67 -0
- package/dist/services/memory/types.d.ts +48 -0
- package/dist/utils/async.d.ts +1 -0
- package/dist/utils/async.js +17 -0
- package/dist/utils/async.test.d.ts +1 -0
- package/dist/utils/async.test.js +48 -0
- package/package.json +1 -1
package/dist/mcp/memory.js
CHANGED
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import {
|
|
5
|
-
import { MemoryIndexer } from '../services/memory/indexer.js';
|
|
6
|
-
import { MemoryStore } from '../services/memory/store.js';
|
|
4
|
+
import { createMemorySubsystem, } from '../services/memory/subsystem.js';
|
|
7
5
|
import { SOURCE_TYPES } from '../services/memory/types.js';
|
|
8
6
|
import { initializeConversationDigestModel } from '../services/digest/processor.js';
|
|
9
7
|
import { DEFAULT_DIGEST_MODEL_ID } from '../services/digest/constants.js';
|
|
10
8
|
import { formatError, mcpJson, mcpText } from '../utils/utils.js';
|
|
11
|
-
import { loadGlobalSettings, resolveConversationDigestConfig
|
|
9
|
+
import { loadGlobalSettings, resolveConversationDigestConfig } from '../core/config/index.js';
|
|
12
10
|
/**
|
|
13
|
-
* Registers tool handlers
|
|
11
|
+
* Registers tool handlers against the current memory subsystem state.
|
|
14
12
|
*/
|
|
15
|
-
function registerMemoryToolHandlers(server,
|
|
13
|
+
function registerMemoryToolHandlers(server, subsystem, workspaceRoot = process.cwd()) {
|
|
14
|
+
const { config } = subsystem;
|
|
16
15
|
server.tool('kit_memory_search', 'Search persistent memory for factual or semantic matches (decisions, concepts, entities). Extract concise keywords only, removing stopwords and filler words from the user request before querying. Use kit_memory_recent for temporal or recency questions.', {
|
|
17
16
|
query: z.string().min(1).describe('Keyword-only search query with stopwords removed'),
|
|
18
17
|
top_k: z.number().int().positive().optional().describe('Number of results to return'),
|
|
19
18
|
}, async ({ query, top_k }) => {
|
|
20
19
|
try {
|
|
20
|
+
if (!subsystem.indexer || !subsystem.store) {
|
|
21
|
+
return mcpText(formatInitializationFailure(subsystem));
|
|
22
|
+
}
|
|
23
|
+
const { indexer, store } = subsystem;
|
|
21
24
|
const results = await indexer.search(query, top_k ?? config.topK);
|
|
25
|
+
const lifecycleNote = formatLifecycleNote(subsystem);
|
|
22
26
|
const degradedNote = !store.vecAvailable
|
|
23
27
|
? '⚠️ Vector search unavailable — showing keyword-only results.\n\n'
|
|
24
28
|
: '';
|
|
25
29
|
if (results.length === 0) {
|
|
26
|
-
return mcpText(`${degradedNote}No memories found for query: "${query}"`);
|
|
30
|
+
return mcpText(`${lifecycleNote}${degradedNote}No memories found for query: "${query}"`);
|
|
27
31
|
}
|
|
28
32
|
const formatted = results
|
|
29
33
|
.map((r) => {
|
|
@@ -34,7 +38,7 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
34
38
|
return `### ${displaySource} (score: ${r.score.toFixed(3)})\n${content}`;
|
|
35
39
|
})
|
|
36
40
|
.join('\n\n---\n\n');
|
|
37
|
-
return mcpText(`${degradedNote}${formatted}`);
|
|
41
|
+
return mcpText(`${lifecycleNote}${degradedNote}${formatted}`);
|
|
38
42
|
}
|
|
39
43
|
catch (err) {
|
|
40
44
|
return mcpText(`kit_memory_search failed: ${formatError(err)}`);
|
|
@@ -45,13 +49,17 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
45
49
|
source_type: z.enum(SOURCE_TYPES).optional().describe('Optional source type filter'),
|
|
46
50
|
}, async ({ n, source_type }) => {
|
|
47
51
|
try {
|
|
52
|
+
if (!subsystem.store) {
|
|
53
|
+
return mcpText(formatInitializationFailure(subsystem));
|
|
54
|
+
}
|
|
55
|
+
const store = subsystem.store;
|
|
48
56
|
const rows = store.getRecentSources({ limit: n ?? 5, sourceType: source_type });
|
|
49
57
|
if (rows.length === 0)
|
|
50
58
|
return mcpText('No recent sources found.');
|
|
51
59
|
const blocks = [];
|
|
52
60
|
for (const row of rows) {
|
|
53
61
|
try {
|
|
54
|
-
const content = fs.
|
|
62
|
+
const content = await fs.promises.readFile(path.join(config.wikiDir, row.source), 'utf8');
|
|
55
63
|
const displaySource = row.source.replace(/^compiled\//, '');
|
|
56
64
|
blocks.push(`### ${displaySource}\n${content}`);
|
|
57
65
|
}
|
|
@@ -71,6 +79,13 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
71
79
|
content: z.string().min(1).describe('Content to save to memory'),
|
|
72
80
|
}, async ({ content }) => {
|
|
73
81
|
try {
|
|
82
|
+
if (!subsystem.indexer) {
|
|
83
|
+
return mcpJson({
|
|
84
|
+
saved: false,
|
|
85
|
+
error: formatInitializationFailure(subsystem),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const indexer = subsystem.indexer;
|
|
74
89
|
await indexer.save(content);
|
|
75
90
|
return mcpJson({
|
|
76
91
|
saved: true,
|
|
@@ -109,22 +124,31 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
109
124
|
}
|
|
110
125
|
});
|
|
111
126
|
}
|
|
127
|
+
function formatLifecycleNote(subsystem) {
|
|
128
|
+
if (subsystem.status.state === 'warming' || subsystem.status.state === 'initializing') {
|
|
129
|
+
return '⚠️ Memory index is warming — results may be stale until startup indexing completes.\n\n';
|
|
130
|
+
}
|
|
131
|
+
if (subsystem.status.state === 'degraded') {
|
|
132
|
+
return `⚠️ Memory index is degraded${subsystem.status.error ? `: ${subsystem.status.error}` : ''}.\n\n`;
|
|
133
|
+
}
|
|
134
|
+
return '';
|
|
135
|
+
}
|
|
136
|
+
function formatInitializationFailure(subsystem) {
|
|
137
|
+
const detail = subsystem.status.error ? `: ${subsystem.status.error}` : '';
|
|
138
|
+
return `Memory initialization failed${detail}`;
|
|
139
|
+
}
|
|
112
140
|
/**
|
|
113
141
|
* Initializes the memory subsystem and registers all memory tools.
|
|
114
|
-
* Returns the
|
|
142
|
+
* Returns the MemorySubsystem so the caller can fire startWarmup() after server.connect().
|
|
115
143
|
* Returns null when memory is disabled (settings.memory.enabled !== true).
|
|
116
144
|
*/
|
|
117
145
|
export function registerMemoryTools(server, workspaceRoot, overrides) {
|
|
118
146
|
const settings = overrides?.settings ?? loadGlobalSettings();
|
|
119
147
|
if (settings.memory?.enabled !== true)
|
|
120
148
|
return null;
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return new MemoryIndexer(store, embedder, config);
|
|
127
|
-
})();
|
|
128
|
-
registerMemoryToolHandlers(server, indexer, store, config, workspaceRoot);
|
|
129
|
-
return indexer;
|
|
149
|
+
const subsystem = createMemorySubsystem(workspaceRoot, { ...overrides, settings });
|
|
150
|
+
if (!subsystem)
|
|
151
|
+
return null;
|
|
152
|
+
registerMemoryToolHandlers(server, subsystem, workspaceRoot);
|
|
153
|
+
return subsystem;
|
|
130
154
|
}
|