@gethmy/mcp 2.4.7 → 2.5.0
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 +34 -1
- package/dist/cli.js +20826 -18366
- package/dist/index.js +20924 -18464
- package/dist/lib/api-client.js +122 -925
- package/package.json +2 -2
- package/src/__tests__/mcp-integration.test.ts +141 -0
- package/src/__tests__/memory-floor.test.ts +126 -0
- package/src/__tests__/memory-park.test.ts +213 -0
- package/src/__tests__/memory-session.test.ts +77 -0
- package/src/__tests__/prompt-builder.test.ts +234 -0
- package/src/__tests__/skills.test.ts +111 -0
- package/src/__tests__/tool-dispatch.test.ts +260 -0
- package/src/api-client.ts +129 -96
- package/src/memory-floor.ts +264 -0
- package/src/memory-park.ts +252 -0
- package/src/memory-session.ts +61 -0
- package/src/prompt-builder.ts +93 -0
- package/src/server.ts +351 -1467
- package/src/__tests__/active-learning.test.ts +0 -483
- package/src/__tests__/agent-performance-profiles.test.ts +0 -468
- package/src/__tests__/context-assembly.test.ts +0 -506
- package/src/__tests__/lifecycle-maintenance.test.ts +0 -238
- package/src/__tests__/memory-audit.test.ts +0 -528
- package/src/__tests__/pattern-detection.test.ts +0 -438
- package/src/active-learning.ts +0 -1165
- package/src/consolidation.ts +0 -383
- package/src/context-assembly.ts +0 -1175
- package/src/lifecycle-maintenance.ts +0 -120
- package/src/memory-audit.ts +0 -578
- package/src/memory-cleanup.ts +0 -902
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for automatic lifecycle maintenance.
|
|
3
|
-
*
|
|
4
|
-
* Run with: bun test packages/mcp-server/src/__tests__/lifecycle-maintenance.test.ts
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, expect, mock, test } from "bun:test";
|
|
8
|
-
import { runLifecycleMaintenance } from "../lifecycle-maintenance.js";
|
|
9
|
-
|
|
10
|
-
function daysAgo(days: number): string {
|
|
11
|
-
return new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function makeMockClient(entities: unknown[]) {
|
|
15
|
-
const deletedIds: string[] = [];
|
|
16
|
-
const updatedEntities: Array<{
|
|
17
|
-
id: string;
|
|
18
|
-
updates: Record<string, unknown>;
|
|
19
|
-
}> = [];
|
|
20
|
-
|
|
21
|
-
return {
|
|
22
|
-
client: {
|
|
23
|
-
listMemoryEntities: mock(async () => ({
|
|
24
|
-
entities,
|
|
25
|
-
count: entities.length,
|
|
26
|
-
})),
|
|
27
|
-
deleteMemoryEntity: mock(async (id: string) => {
|
|
28
|
-
deletedIds.push(id);
|
|
29
|
-
return { success: true };
|
|
30
|
-
}),
|
|
31
|
-
updateMemoryEntity: mock(
|
|
32
|
-
async (id: string, updates: Record<string, unknown>) => {
|
|
33
|
-
updatedEntities.push({ id, updates });
|
|
34
|
-
return { entity: { id, ...updates } };
|
|
35
|
-
},
|
|
36
|
-
),
|
|
37
|
-
} as any,
|
|
38
|
-
deletedIds,
|
|
39
|
-
updatedEntities,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
describe("runLifecycleMaintenance", () => {
|
|
44
|
-
test("archives low-confidence entities", async () => {
|
|
45
|
-
const { client, deletedIds } = makeMockClient([
|
|
46
|
-
{
|
|
47
|
-
id: "low-conf-1",
|
|
48
|
-
title: "Bad memory",
|
|
49
|
-
memory_tier: "draft",
|
|
50
|
-
confidence: 0.1,
|
|
51
|
-
access_count: 0,
|
|
52
|
-
last_accessed_at: daysAgo(5),
|
|
53
|
-
created_at: daysAgo(10),
|
|
54
|
-
},
|
|
55
|
-
]);
|
|
56
|
-
|
|
57
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
58
|
-
expect(result.archived).toBe(1);
|
|
59
|
-
expect(deletedIds).toContain("low-conf-1");
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("prunes stale drafts older than 30 days with low decay", async () => {
|
|
63
|
-
const { client, deletedIds } = makeMockClient([
|
|
64
|
-
{
|
|
65
|
-
id: "stale-draft-1",
|
|
66
|
-
title: "Old draft",
|
|
67
|
-
memory_tier: "draft",
|
|
68
|
-
confidence: 0.5,
|
|
69
|
-
access_count: 0,
|
|
70
|
-
last_accessed_at: daysAgo(35),
|
|
71
|
-
created_at: daysAgo(35),
|
|
72
|
-
},
|
|
73
|
-
]);
|
|
74
|
-
|
|
75
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
76
|
-
expect(result.pruned).toBe(1);
|
|
77
|
-
expect(deletedIds).toContain("stale-draft-1");
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test("does NOT prune recent drafts", async () => {
|
|
81
|
-
const { client, deletedIds } = makeMockClient([
|
|
82
|
-
{
|
|
83
|
-
id: "fresh-draft",
|
|
84
|
-
title: "New draft",
|
|
85
|
-
memory_tier: "draft",
|
|
86
|
-
confidence: 0.5,
|
|
87
|
-
access_count: 1,
|
|
88
|
-
last_accessed_at: daysAgo(2),
|
|
89
|
-
created_at: daysAgo(5),
|
|
90
|
-
},
|
|
91
|
-
]);
|
|
92
|
-
|
|
93
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
94
|
-
expect(result.pruned).toBe(0);
|
|
95
|
-
expect(result.archived).toBe(0);
|
|
96
|
-
expect(deletedIds).toHaveLength(0);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
test("auto-promotes eligible draft to episode", async () => {
|
|
100
|
-
const { client, updatedEntities } = makeMockClient([
|
|
101
|
-
{
|
|
102
|
-
id: "promote-me",
|
|
103
|
-
title: "Well-used draft",
|
|
104
|
-
memory_tier: "draft",
|
|
105
|
-
confidence: 0.85,
|
|
106
|
-
access_count: 6,
|
|
107
|
-
last_accessed_at: daysAgo(0),
|
|
108
|
-
created_at: daysAgo(3),
|
|
109
|
-
},
|
|
110
|
-
]);
|
|
111
|
-
|
|
112
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
113
|
-
expect(result.promoted).toBe(1);
|
|
114
|
-
expect(updatedEntities[0].id).toBe("promote-me");
|
|
115
|
-
expect(updatedEntities[0].updates.memory_tier).toBe("episode");
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
test("auto-promotes eligible episode to reference", async () => {
|
|
119
|
-
const { client, updatedEntities } = makeMockClient([
|
|
120
|
-
{
|
|
121
|
-
id: "promote-ep",
|
|
122
|
-
title: "Proven episode",
|
|
123
|
-
memory_tier: "episode",
|
|
124
|
-
confidence: 0.95,
|
|
125
|
-
access_count: 12,
|
|
126
|
-
last_accessed_at: daysAgo(1),
|
|
127
|
-
created_at: daysAgo(10),
|
|
128
|
-
},
|
|
129
|
-
]);
|
|
130
|
-
|
|
131
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
132
|
-
expect(result.promoted).toBe(1);
|
|
133
|
-
expect(updatedEntities[0].updates.memory_tier).toBe("reference");
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
test("flags stale entities for review", async () => {
|
|
137
|
-
const { client, updatedEntities } = makeMockClient([
|
|
138
|
-
{
|
|
139
|
-
id: "stale-ep",
|
|
140
|
-
title: "Forgotten episode",
|
|
141
|
-
memory_tier: "episode",
|
|
142
|
-
confidence: 0.6,
|
|
143
|
-
access_count: 2,
|
|
144
|
-
last_accessed_at: daysAgo(100),
|
|
145
|
-
created_at: daysAgo(120),
|
|
146
|
-
},
|
|
147
|
-
]);
|
|
148
|
-
|
|
149
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
150
|
-
expect(result.reviewed).toBe(1);
|
|
151
|
-
expect(updatedEntities[0].id).toBe("stale-ep");
|
|
152
|
-
expect(updatedEntities[0].updates.metadata).toHaveProperty(
|
|
153
|
-
"needs_review",
|
|
154
|
-
true,
|
|
155
|
-
);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test("does not flag frequently accessed stale entities", async () => {
|
|
159
|
-
const { client, updatedEntities } = makeMockClient([
|
|
160
|
-
{
|
|
161
|
-
id: "old-but-used",
|
|
162
|
-
title: "Still relevant",
|
|
163
|
-
memory_tier: "episode",
|
|
164
|
-
confidence: 0.7,
|
|
165
|
-
access_count: 10,
|
|
166
|
-
last_accessed_at: daysAgo(100),
|
|
167
|
-
created_at: daysAgo(120),
|
|
168
|
-
},
|
|
169
|
-
]);
|
|
170
|
-
|
|
171
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
172
|
-
expect(result.reviewed).toBe(0);
|
|
173
|
-
expect(updatedEntities).toHaveLength(0);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
test("handles empty entity list", async () => {
|
|
177
|
-
const { client } = makeMockClient([]);
|
|
178
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
179
|
-
expect(result.archived).toBe(0);
|
|
180
|
-
expect(result.pruned).toBe(0);
|
|
181
|
-
expect(result.promoted).toBe(0);
|
|
182
|
-
expect(result.reviewed).toBe(0);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test("handles API errors gracefully", async () => {
|
|
186
|
-
const client = {
|
|
187
|
-
listMemoryEntities: mock(async () => {
|
|
188
|
-
throw new Error("API down");
|
|
189
|
-
}),
|
|
190
|
-
} as any;
|
|
191
|
-
|
|
192
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
193
|
-
expect(result.errors).toBe(0); // Early return, no entity-level errors
|
|
194
|
-
expect(result.archived).toBe(0);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
test("processes mixed entities correctly", async () => {
|
|
198
|
-
const { client, deletedIds, updatedEntities } = makeMockClient([
|
|
199
|
-
// Should be archived (low confidence)
|
|
200
|
-
{
|
|
201
|
-
id: "archive-me",
|
|
202
|
-
title: "Low conf",
|
|
203
|
-
memory_tier: "draft",
|
|
204
|
-
confidence: 0.2,
|
|
205
|
-
access_count: 1,
|
|
206
|
-
last_accessed_at: daysAgo(5),
|
|
207
|
-
created_at: daysAgo(10),
|
|
208
|
-
},
|
|
209
|
-
// Should be promoted (draft→episode)
|
|
210
|
-
{
|
|
211
|
-
id: "promote-me",
|
|
212
|
-
title: "Good draft",
|
|
213
|
-
memory_tier: "draft",
|
|
214
|
-
confidence: 0.85,
|
|
215
|
-
access_count: 7,
|
|
216
|
-
last_accessed_at: daysAgo(0),
|
|
217
|
-
created_at: daysAgo(5),
|
|
218
|
-
},
|
|
219
|
-
// Should be left alone (healthy reference)
|
|
220
|
-
{
|
|
221
|
-
id: "leave-me",
|
|
222
|
-
title: "Healthy ref",
|
|
223
|
-
memory_tier: "reference",
|
|
224
|
-
confidence: 0.95,
|
|
225
|
-
access_count: 20,
|
|
226
|
-
last_accessed_at: daysAgo(1),
|
|
227
|
-
created_at: daysAgo(60),
|
|
228
|
-
},
|
|
229
|
-
]);
|
|
230
|
-
|
|
231
|
-
const result = await runLifecycleMaintenance(client, "ws-1");
|
|
232
|
-
expect(result.archived).toBe(1);
|
|
233
|
-
expect(result.promoted).toBe(1);
|
|
234
|
-
expect(deletedIds).toContain("archive-me");
|
|
235
|
-
expect(updatedEntities[0].id).toBe("promote-me");
|
|
236
|
-
expect(updatedEntities[0].updates.memory_tier).toBe("episode");
|
|
237
|
-
});
|
|
238
|
-
});
|