@hanhnd/agent-kit 1.0.34 → 1.0.36
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/commands/cli-digest-pending.test.js +19 -10
- package/dist/cli/commands/memory.js +44 -4
- package/dist/cli.js +348 -179
- package/dist/core/config/index.d.ts +3 -0
- package/dist/core/config/index.js +20 -0
- package/dist/entrypoints/server.js +1 -3
- package/dist/mcp/memory.d.ts +2 -1
- package/dist/mcp/memory.js +45 -18
- package/dist/server.js +294 -200
- package/dist/services/digest/constants.d.ts +3 -3
- package/dist/services/digest/constants.js +3 -3
- package/dist/services/digest/digest-background.test.js +19 -8
- package/dist/services/digest/digest-init.test.js +13 -2
- package/dist/services/digest/digest-pending.test.js +13 -2
- package/dist/services/digest/digest-processor.test.js +52 -0
- package/dist/services/digest/files.js +3 -3
- package/dist/services/digest/model-registry.js +2 -2
- package/dist/services/digest/processor.js +43 -13
- package/dist/services/digest/providers/llama-local.js +17 -28
- package/dist/services/digest/types.d.ts +3 -1
- package/dist/services/digest/types.js +1 -1
- package/dist/services/memory/chunker.d.ts +5 -2
- package/dist/services/memory/chunker.js +3 -1
- package/dist/services/memory/chunker.test.js +21 -11
- package/dist/services/memory/constants.js +1 -1
- package/dist/services/memory/embedder.js +1 -1
- package/dist/services/memory/index.d.ts +1 -1
- package/dist/services/memory/indexer.d.ts +2 -1
- package/dist/services/memory/indexer.js +24 -8
- package/dist/services/memory/indexer.test.js +38 -2
- package/dist/services/memory/memory.test.js +172 -15
- package/dist/services/memory/store.d.ts +9 -3
- package/dist/services/memory/store.js +132 -98
- package/dist/services/memory/store.test.js +239 -14
- package/dist/services/memory/types.d.ts +9 -1
- package/dist/services/memory/types.js +2 -1
- package/dist/utils/paths.d.ts +2 -0
- package/dist/utils/paths.js +2 -1
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.js +3 -3
- package/package.json +3 -5
|
@@ -24,6 +24,9 @@ export { MemoryConfig };
|
|
|
24
24
|
export declare function resolveMemoryConfig(settings: ProjectSettings, workspaceRoot: string): MemoryConfig;
|
|
25
25
|
export declare function loadProjectSettings(projectDir: string): ProjectSettings;
|
|
26
26
|
export declare function writeProjectSettings(workspaceRoot: string, patch: Partial<ProjectSettings>): void;
|
|
27
|
+
export declare function getGlobalSettingsFile(): string;
|
|
28
|
+
export declare function loadGlobalSettings(): ProjectSettings;
|
|
29
|
+
export declare function writeGlobalSettings(patch: Partial<ProjectSettings>): void;
|
|
27
30
|
export declare function resolveConversationDigestConfig(settings: ProjectSettings): ConversationDigestSettings | undefined;
|
|
28
31
|
/**
|
|
29
32
|
* Sensitive files that agents are FORBIDDEN from reading/writing.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Shared configuration constants and loaders
|
|
4
4
|
*/
|
|
5
5
|
import * as fs from 'fs';
|
|
6
|
+
import * as os from 'os';
|
|
6
7
|
import * as path from 'path';
|
|
7
8
|
import { DEFAULT_MEMORY_CONFIG } from '../../services/memory/constants.js';
|
|
8
9
|
import { atomicWriteJsonFile } from '../../utils/files.js';
|
|
@@ -65,6 +66,25 @@ export function writeProjectSettings(workspaceRoot, patch) {
|
|
|
65
66
|
const current = loadProjectSettings(workspaceRoot);
|
|
66
67
|
atomicWriteJsonFile(settingsPath, { ...current, ...patch });
|
|
67
68
|
}
|
|
69
|
+
export function getGlobalSettingsFile() {
|
|
70
|
+
return path.join(os.homedir(), '.agent-kit', 'settings.json');
|
|
71
|
+
}
|
|
72
|
+
export function loadGlobalSettings() {
|
|
73
|
+
const file = getGlobalSettingsFile();
|
|
74
|
+
if (fs.existsSync(file)) {
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(`[agent-kit] Warning: Failed to parse ${file}:`, error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return {};
|
|
83
|
+
}
|
|
84
|
+
export function writeGlobalSettings(patch) {
|
|
85
|
+
const current = loadGlobalSettings();
|
|
86
|
+
atomicWriteJsonFile(getGlobalSettingsFile(), { ...current, ...patch });
|
|
87
|
+
}
|
|
68
88
|
export function resolveConversationDigestConfig(settings) {
|
|
69
89
|
const digest = settings.memory?.conversationDigest;
|
|
70
90
|
if (!digest?.initialized || typeof digest.modelId !== 'string' || typeof digest.initializedAt !== 'string') {
|
|
@@ -10,7 +10,6 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
10
10
|
import { registerCoreTools } from '../mcp/core.js';
|
|
11
11
|
import { registerAgentTools } from '../mcp/agent.js';
|
|
12
12
|
import { registerIntegrationTools } from '../mcp/integration.js';
|
|
13
|
-
import { loadProjectSettings } from '../core/config/index.js';
|
|
14
13
|
import { registerMemoryTools } from '../mcp/memory.js';
|
|
15
14
|
import { getWorkspaceRoot } from '../utils/utils.js';
|
|
16
15
|
const server = new McpServer({
|
|
@@ -24,8 +23,7 @@ registerIntegrationTools(server);
|
|
|
24
23
|
registerCoreTools(server);
|
|
25
24
|
registerAgentTools(server);
|
|
26
25
|
const workspaceRoot = getWorkspaceRoot();
|
|
27
|
-
const
|
|
28
|
-
const memoryIndexer = registerMemoryTools(server, settings, workspaceRoot);
|
|
26
|
+
const memoryIndexer = registerMemoryTools(server, workspaceRoot);
|
|
29
27
|
// ═══════════════════════════════════════════════════════════════
|
|
30
28
|
// START SERVER
|
|
31
29
|
// ═══════════════════════════════════════════════════════════════
|
package/dist/mcp/memory.d.ts
CHANGED
|
@@ -8,8 +8,9 @@ import { type ProjectSettings } from '../core/config/index.js';
|
|
|
8
8
|
* Returns the MemoryIndexer so the caller can fire startupIndex() after server.connect().
|
|
9
9
|
* Returns null when memory is disabled (settings.memory.enabled !== true).
|
|
10
10
|
*/
|
|
11
|
-
export declare function registerMemoryTools(server: McpServer,
|
|
11
|
+
export declare function registerMemoryTools(server: McpServer, workspaceRoot: string, overrides?: {
|
|
12
12
|
indexer?: MemoryIndexer;
|
|
13
13
|
store?: MemoryStore;
|
|
14
14
|
config?: MemoryConfig;
|
|
15
|
+
settings?: ProjectSettings;
|
|
15
16
|
}): MemoryIndexer | null;
|
package/dist/mcp/memory.js
CHANGED
|
@@ -1,31 +1,30 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
1
2
|
import * as path from 'path';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { Embedder } from '../services/memory/embedder.js';
|
|
4
5
|
import { MemoryIndexer } from '../services/memory/indexer.js';
|
|
5
6
|
import { MemoryStore } from '../services/memory/store.js';
|
|
7
|
+
import { SOURCE_TYPES } from '../services/memory/types.js';
|
|
6
8
|
import { initializeConversationDigestModel } from '../services/digest/processor.js';
|
|
7
9
|
import { DEFAULT_DIGEST_MODEL_ID } from '../services/digest/constants.js';
|
|
8
|
-
import { mcpJson, mcpText } from '../utils/utils.js';
|
|
9
|
-
import {
|
|
10
|
+
import { formatError, mcpJson, mcpText } from '../utils/utils.js';
|
|
11
|
+
import { loadGlobalSettings, resolveConversationDigestConfig, resolveMemoryConfig, } from '../core/config/index.js';
|
|
10
12
|
/**
|
|
11
13
|
* Registers tool handlers onto an already-constructed indexer/store pair.
|
|
12
14
|
*/
|
|
13
15
|
function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoot = process.cwd()) {
|
|
14
|
-
server.tool('kit_memory_search', 'Search persistent memory for
|
|
15
|
-
query: z.string().min(1).describe('
|
|
16
|
+
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
|
+
query: z.string().min(1).describe('Keyword-only search query with stopwords removed'),
|
|
16
18
|
top_k: z.number().int().positive().optional().describe('Number of results to return'),
|
|
17
19
|
}, async ({ query, top_k }) => {
|
|
18
20
|
try {
|
|
19
21
|
const results = await indexer.search(query, top_k ?? config.topK);
|
|
20
|
-
if (results.length === 0) {
|
|
21
|
-
const degradedNote = !store.vecAvailable
|
|
22
|
-
? '⚠️ Vector search unavailable — showing keyword-only results.\n\n'
|
|
23
|
-
: '';
|
|
24
|
-
return mcpText(`${degradedNote}No memories found for query: "${query}"`);
|
|
25
|
-
}
|
|
26
22
|
const degradedNote = !store.vecAvailable
|
|
27
23
|
? '⚠️ Vector search unavailable — showing keyword-only results.\n\n'
|
|
28
24
|
: '';
|
|
25
|
+
if (results.length === 0) {
|
|
26
|
+
return mcpText(`${degradedNote}No memories found for query: "${query}"`);
|
|
27
|
+
}
|
|
29
28
|
const formatted = results
|
|
30
29
|
.map((r) => {
|
|
31
30
|
const displaySource = r.chunk.source.replace(/^compiled\//, '');
|
|
@@ -38,8 +37,34 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
38
37
|
return mcpText(`${degradedNote}${formatted}`);
|
|
39
38
|
}
|
|
40
39
|
catch (err) {
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
return mcpText(`kit_memory_search failed: ${formatError(err)}`);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
server.tool('kit_memory_recent', 'Return the N most recently updated memory sources. Optionally filter by source type. Use for temporal questions like "what did we do last session" or "recent".', {
|
|
44
|
+
n: z.number().int().positive().max(50).optional().describe('How many recent sources to return (default 5)'),
|
|
45
|
+
source_type: z.enum(SOURCE_TYPES).optional().describe('Optional source type filter'),
|
|
46
|
+
}, async ({ n, source_type }) => {
|
|
47
|
+
try {
|
|
48
|
+
const rows = store.getRecentSources({ limit: n ?? 5, sourceType: source_type });
|
|
49
|
+
if (rows.length === 0)
|
|
50
|
+
return mcpText('No recent sources found.');
|
|
51
|
+
const blocks = [];
|
|
52
|
+
for (const row of rows) {
|
|
53
|
+
try {
|
|
54
|
+
const content = fs.readFileSync(path.join(config.wikiDir, row.source), 'utf8');
|
|
55
|
+
const displaySource = row.source.replace(/^compiled\//, '');
|
|
56
|
+
blocks.push(`### ${displaySource}\n${content}`);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
console.warn(`[memory] Skipping unavailable recent source ${row.source}:`, err);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (blocks.length === 0)
|
|
63
|
+
return mcpText('No recent sources found.');
|
|
64
|
+
return mcpText(blocks.join('\n\n---\n\n'));
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
return mcpText(`kit_memory_recent failed: ${formatError(err)}`);
|
|
43
68
|
}
|
|
44
69
|
});
|
|
45
70
|
server.tool('kit_memory_save', 'Save content to wiki/raw for inclusion after the next /wiki compile.', {
|
|
@@ -54,8 +79,10 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
54
79
|
});
|
|
55
80
|
}
|
|
56
81
|
catch (err) {
|
|
57
|
-
|
|
58
|
-
|
|
82
|
+
return mcpJson({
|
|
83
|
+
saved: false,
|
|
84
|
+
error: formatError(err),
|
|
85
|
+
});
|
|
59
86
|
}
|
|
60
87
|
});
|
|
61
88
|
server.tool('kit_memory_digest_init', 'Initialize or toggle local conversation digesting. Downloads/cache-loads the pinned local model only when explicitly invoked.', {
|
|
@@ -63,7 +90,7 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
63
90
|
enabled: z.boolean().optional().describe('Enable or disable conversation digesting'),
|
|
64
91
|
}, async ({ model_id, enabled }) => {
|
|
65
92
|
try {
|
|
66
|
-
const existingConfig = resolveConversationDigestConfig(
|
|
93
|
+
const existingConfig = resolveConversationDigestConfig(loadGlobalSettings());
|
|
67
94
|
const result = await initializeConversationDigestModel({
|
|
68
95
|
workspaceRoot,
|
|
69
96
|
modelId: model_id ?? existingConfig?.modelId ?? DEFAULT_DIGEST_MODEL_ID,
|
|
@@ -78,8 +105,7 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
78
105
|
});
|
|
79
106
|
}
|
|
80
107
|
catch (err) {
|
|
81
|
-
|
|
82
|
-
return mcpJson({ initialized: false, error: message });
|
|
108
|
+
return mcpJson({ initialized: false, error: formatError(err) });
|
|
83
109
|
}
|
|
84
110
|
});
|
|
85
111
|
}
|
|
@@ -88,7 +114,8 @@ function registerMemoryToolHandlers(server, indexer, store, config, workspaceRoo
|
|
|
88
114
|
* Returns the MemoryIndexer so the caller can fire startupIndex() after server.connect().
|
|
89
115
|
* Returns null when memory is disabled (settings.memory.enabled !== true).
|
|
90
116
|
*/
|
|
91
|
-
export function registerMemoryTools(server,
|
|
117
|
+
export function registerMemoryTools(server, workspaceRoot, overrides) {
|
|
118
|
+
const settings = overrides?.settings ?? loadGlobalSettings();
|
|
92
119
|
if (settings.memory?.enabled !== true)
|
|
93
120
|
return null;
|
|
94
121
|
const config = overrides?.config ?? resolveMemoryConfig(settings, workspaceRoot);
|