@easynet/agent-memory 1.0.57 → 1.0.59
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/test/integration/real-memory-features.test.js +3 -1
- package/dist/test/integration/real-memory-features.test.js.map +1 -1
- package/dist/test/integration/vlm-llm-live.test.js +1 -1
- package/dist/test/integration/vlm-llm-live.test.js.map +1 -1
- package/dist/test/unit/core/agent-memory.test.js +139 -141
- package/dist/test/unit/core/agent-memory.test.js.map +1 -1
- package/dist/test/unit/core/config.test.js +162 -164
- package/dist/test/unit/core/config.test.js.map +1 -1
- package/dist/test/unit/core/router.test.js +102 -104
- package/dist/test/unit/core/router.test.js.map +1 -1
- package/dist/test/unit/create-agent-memory.test.js +296 -298
- package/dist/test/unit/create-agent-memory.test.js.map +1 -1
- package/dist/test/unit/ingest/url-ingest.test.js +116 -118
- package/dist/test/unit/ingest/url-ingest.test.js.map +1 -1
- package/dist/test/unit/providers/rag-provider.test.js +96 -98
- package/dist/test/unit/providers/rag-provider.test.js.map +1 -1
- package/dist/test/unit/providers/sqlite-store.test.js +94 -96
- package/dist/test/unit/providers/sqlite-store.test.js.map +1 -1
- package/package.json +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { it } from "node:test";
|
|
2
2
|
import assert from "node:assert";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { writeFile, mkdir, rm } from "node:fs/promises";
|
|
@@ -6,146 +6,145 @@ import { tmpdir } from "node:os";
|
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
import { pathToFileURL } from "node:url";
|
|
8
8
|
import { createAgentMemory, createAgentMemoryRegistry } from "../../src/create-agent-memory.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
const memory = await memoryRegistry.getAgentMemory();
|
|
17
|
-
const item = await memory.memorize("user:1", "cross_thread", "User likes cats.");
|
|
18
|
-
assert.ok(item.id);
|
|
19
|
-
assert.strictEqual(item.content, "User likes cats.");
|
|
20
|
-
assert.strictEqual(item.type, "cross_thread");
|
|
21
|
-
const result = await memory.recall({
|
|
22
|
-
namespace: "user:1",
|
|
23
|
-
query: "cats",
|
|
24
|
-
topK: 5,
|
|
25
|
-
});
|
|
26
|
-
assert.strictEqual(result.items.length, 1);
|
|
27
|
-
});
|
|
28
|
-
it("memorize supports auto type when type is omitted", async () => {
|
|
29
|
-
const memory = await createAgentMemory({
|
|
30
|
-
config: {
|
|
31
|
-
stores: [{ id: "default", type: "in_memory" }],
|
|
32
|
-
},
|
|
33
|
-
classifyMemory: async (content) => (content.includes("manual") ? "knowledge" : "cross_thread"),
|
|
34
|
-
});
|
|
35
|
-
const item = await memory.memorize("user:auto", "Product manual summary");
|
|
36
|
-
assert.strictEqual(item.type, "knowledge");
|
|
9
|
+
it("memorize with content and type delegates to core memory", async () => {
|
|
10
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
11
|
+
config: {
|
|
12
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
13
|
+
},
|
|
37
14
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
assert.strictEqual(item.type, "knowledge");
|
|
48
|
-
assert.strictEqual(item.content, "Positional call.");
|
|
15
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
16
|
+
const item = await memory.memorize("user:1", "cross_thread", "User likes cats.");
|
|
17
|
+
assert.ok(item.id);
|
|
18
|
+
assert.strictEqual(item.content, "User likes cats.");
|
|
19
|
+
assert.strictEqual(item.type, "cross_thread");
|
|
20
|
+
const result = await memory.recall({
|
|
21
|
+
namespace: "user:1",
|
|
22
|
+
query: "cats",
|
|
23
|
+
topK: 5,
|
|
49
24
|
});
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
const memory = await memoryRegistry.getAgentMemory();
|
|
61
|
-
try {
|
|
62
|
-
const item = await memory.memorize("test", "knowledge", pathToFileURL(filePath));
|
|
63
|
-
assert.ok(item.id);
|
|
64
|
-
assert.strictEqual(item.type, "knowledge");
|
|
65
|
-
const result = await memory.recall({
|
|
66
|
-
namespace: "test",
|
|
67
|
-
query: "Chunk",
|
|
68
|
-
topK: 10,
|
|
69
|
-
});
|
|
70
|
-
assert.ok(result.items.length >= 1);
|
|
71
|
-
}
|
|
72
|
-
finally {
|
|
73
|
-
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
74
|
-
}
|
|
25
|
+
assert.strictEqual(result.items.length, 1);
|
|
26
|
+
});
|
|
27
|
+
it("memorize supports auto type when type is omitted", async () => {
|
|
28
|
+
const memory = await createAgentMemory({
|
|
29
|
+
config: {
|
|
30
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
31
|
+
},
|
|
32
|
+
classifyMemory: async (content) => (content.includes("manual") ? "knowledge" : "cross_thread"),
|
|
75
33
|
});
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
},
|
|
85
|
-
classifyMemory: async (content) => (content.includes("preference") ? "cross_thread" : "knowledge"),
|
|
86
|
-
});
|
|
87
|
-
try {
|
|
88
|
-
const item = await memory.memorize("user:url-auto", pathToFileURL(filePath));
|
|
89
|
-
assert.strictEqual(item.type, "cross_thread");
|
|
90
|
-
}
|
|
91
|
-
finally {
|
|
92
|
-
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
93
|
-
}
|
|
34
|
+
const item = await memory.memorize("user:auto", "Product manual summary");
|
|
35
|
+
assert.strictEqual(item.type, "knowledge");
|
|
36
|
+
});
|
|
37
|
+
it("memorize supports positional parameters", async () => {
|
|
38
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
39
|
+
config: {
|
|
40
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
41
|
+
},
|
|
94
42
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
43
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
44
|
+
const item = await memory.memorize("user:positional", "knowledge", "Positional call.");
|
|
45
|
+
assert.ok(item.id);
|
|
46
|
+
assert.strictEqual(item.type, "knowledge");
|
|
47
|
+
assert.strictEqual(item.content, "Positional call.");
|
|
48
|
+
});
|
|
49
|
+
it("memorize with url ingests file and stores chunks", async () => {
|
|
50
|
+
const dir = join(tmpdir(), `ingest-wrapper-${randomUUID()}`);
|
|
51
|
+
await mkdir(dir, { recursive: true });
|
|
52
|
+
const filePath = join(dir, "note.txt");
|
|
53
|
+
await writeFile(filePath, "Chunk one.\n\nChunk two.", "utf-8");
|
|
54
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
55
|
+
config: {
|
|
56
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
57
|
+
},
|
|
104
58
|
});
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
stores: [{ id: "default", type: "in_memory" }],
|
|
109
|
-
},
|
|
110
|
-
});
|
|
111
|
-
const memory = await memoryRegistry.getAgentMemory();
|
|
112
|
-
const item = await memory.memorize("user:1", "cross_thread", "Written via write.");
|
|
59
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
60
|
+
try {
|
|
61
|
+
const item = await memory.memorize("test", "knowledge", pathToFileURL(filePath));
|
|
113
62
|
assert.ok(item.id);
|
|
114
|
-
assert.strictEqual(item.
|
|
63
|
+
assert.strictEqual(item.type, "knowledge");
|
|
115
64
|
const result = await memory.recall({
|
|
116
|
-
namespace: "
|
|
117
|
-
query: "
|
|
118
|
-
topK:
|
|
65
|
+
namespace: "test",
|
|
66
|
+
query: "Chunk",
|
|
67
|
+
topK: 10,
|
|
119
68
|
});
|
|
120
|
-
assert.
|
|
69
|
+
assert.ok(result.items.length >= 1);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
it("memorize with url supports classifier when type is omitted", async () => {
|
|
76
|
+
const dir = join(tmpdir(), `ingest-auto-url-${randomUUID()}`);
|
|
77
|
+
await mkdir(dir, { recursive: true });
|
|
78
|
+
const filePath = join(dir, "preference.txt");
|
|
79
|
+
await writeFile(filePath, "User preference: always answer in short bullets.", "utf-8");
|
|
80
|
+
const memory = await createAgentMemory({
|
|
81
|
+
config: {
|
|
82
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
83
|
+
},
|
|
84
|
+
classifyMemory: async (content) => (content.includes("preference") ? "cross_thread" : "knowledge"),
|
|
121
85
|
});
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
86
|
+
try {
|
|
87
|
+
const item = await memory.memorize("user:url-auto", pathToFileURL(filePath));
|
|
88
|
+
assert.strictEqual(item.type, "cross_thread");
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
it("memorize without url and without content throws", async () => {
|
|
95
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
96
|
+
config: {
|
|
97
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
101
|
+
await assert.rejects(() => memory
|
|
102
|
+
.memorize("test", "knowledge", new URL("http://127.0.0.1:9/not-found.txt")), /request failed|fetch failed|ECONNREFUSED|Failed to fetch/);
|
|
103
|
+
});
|
|
104
|
+
it("memorize delegates to extended memorize", async () => {
|
|
105
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
106
|
+
config: {
|
|
107
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
111
|
+
const item = await memory.memorize("user:1", "cross_thread", "Written via write.");
|
|
112
|
+
assert.ok(item.id);
|
|
113
|
+
assert.strictEqual(item.content, "Written via write.");
|
|
114
|
+
const result = await memory.recall({
|
|
115
|
+
namespace: "user:1",
|
|
116
|
+
query: "any",
|
|
117
|
+
topK: 5,
|
|
118
|
+
});
|
|
119
|
+
assert.strictEqual(result.items.length, 1);
|
|
120
|
+
});
|
|
121
|
+
it("recall delegates to underlying memory", async () => {
|
|
122
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
123
|
+
config: {
|
|
124
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
125
|
+
},
|
|
143
126
|
});
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
127
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
128
|
+
await memory.memorize("ns", "knowledge", "Delegation test.");
|
|
129
|
+
const recallResult = await memory.recall({
|
|
130
|
+
namespace: "ns",
|
|
131
|
+
query: "Delegation",
|
|
132
|
+
topK: 5,
|
|
133
|
+
});
|
|
134
|
+
assert.strictEqual(recallResult.items.length, 1);
|
|
135
|
+
const promptResult = await memory.recall({
|
|
136
|
+
namespace: "ns",
|
|
137
|
+
query: "test",
|
|
138
|
+
topK: 5,
|
|
139
|
+
});
|
|
140
|
+
assert.strictEqual(promptResult.items.length, 1);
|
|
141
|
+
assert.ok(promptResult.traceId);
|
|
142
|
+
});
|
|
143
|
+
it("supports extension provider via local module path", async () => {
|
|
144
|
+
const dir = join(tmpdir(), `memory-ext-${randomUUID()}`);
|
|
145
|
+
await mkdir(dir, { recursive: true });
|
|
146
|
+
const extPath = join(dir, "provider.mjs");
|
|
147
|
+
await writeFile(extPath, `
|
|
149
148
|
export function createMemoryProvider() {
|
|
150
149
|
const rows = [];
|
|
151
150
|
return {
|
|
@@ -172,200 +171,199 @@ export function createMemoryProvider() {
|
|
|
172
171
|
};
|
|
173
172
|
}
|
|
174
173
|
`, "utf-8");
|
|
175
|
-
|
|
176
|
-
const memoryRegistry = await createAgentMemoryRegistry({
|
|
177
|
-
config: {
|
|
178
|
-
stores: [
|
|
179
|
-
{
|
|
180
|
-
id: "ext",
|
|
181
|
-
type: "extension",
|
|
182
|
-
options: { package: extPath },
|
|
183
|
-
},
|
|
184
|
-
],
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
const memory = await memoryRegistry.getAgentMemory();
|
|
188
|
-
const item = await memory.memorize("ext:ns", "knowledge", "Extension provider content");
|
|
189
|
-
assert.strictEqual(item.id, "ext-1");
|
|
190
|
-
const result = await memory.recall({
|
|
191
|
-
namespace: "ext:ns",
|
|
192
|
-
query: "Extension",
|
|
193
|
-
topK: 5,
|
|
194
|
-
});
|
|
195
|
-
assert.strictEqual(result.items.length, 1);
|
|
196
|
-
assert.strictEqual(result.items[0]?.content, "Extension provider content");
|
|
197
|
-
}
|
|
198
|
-
finally {
|
|
199
|
-
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
it("llamaindex provider falls back to knowledge type when metadata.type is missing", async () => {
|
|
203
|
-
class FakeKnowledgeProvider {
|
|
204
|
-
async remember(req) {
|
|
205
|
-
return {
|
|
206
|
-
id: "k-1",
|
|
207
|
-
content: req.content ?? "",
|
|
208
|
-
metadata: req.metadata,
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
async recall() {
|
|
212
|
-
return [
|
|
213
|
-
{
|
|
214
|
-
id: "k-1",
|
|
215
|
-
content: "knowledge-content",
|
|
216
|
-
metadata: {},
|
|
217
|
-
},
|
|
218
|
-
];
|
|
219
|
-
}
|
|
220
|
-
async forget() { }
|
|
221
|
-
}
|
|
174
|
+
try {
|
|
222
175
|
const memoryRegistry = await createAgentMemoryRegistry({
|
|
223
176
|
config: {
|
|
224
|
-
stores: [
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
177
|
+
stores: [
|
|
178
|
+
{
|
|
179
|
+
id: "ext",
|
|
180
|
+
type: "extension",
|
|
181
|
+
options: { package: extPath },
|
|
182
|
+
},
|
|
183
|
+
],
|
|
230
184
|
},
|
|
231
185
|
});
|
|
232
186
|
const memory = await memoryRegistry.getAgentMemory();
|
|
187
|
+
const item = await memory.memorize("ext:ns", "knowledge", "Extension provider content");
|
|
188
|
+
assert.strictEqual(item.id, "ext-1");
|
|
233
189
|
const result = await memory.recall({
|
|
234
|
-
namespace: "
|
|
235
|
-
query: "
|
|
190
|
+
namespace: "ext:ns",
|
|
191
|
+
query: "Extension",
|
|
236
192
|
topK: 5,
|
|
237
193
|
});
|
|
238
194
|
assert.strictEqual(result.items.length, 1);
|
|
239
|
-
assert.strictEqual(result.items[0]?.
|
|
195
|
+
assert.strictEqual(result.items[0]?.content, "Extension provider content");
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
it("llamaindex provider falls back to knowledge type when metadata.type is missing", async () => {
|
|
202
|
+
class FakeKnowledgeProvider {
|
|
203
|
+
async remember(req) {
|
|
204
|
+
return {
|
|
205
|
+
id: "k-1",
|
|
206
|
+
content: req.content ?? "",
|
|
207
|
+
metadata: req.metadata,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
async recall() {
|
|
211
|
+
return [
|
|
212
|
+
{
|
|
213
|
+
id: "k-1",
|
|
214
|
+
content: "knowledge-content",
|
|
215
|
+
metadata: {},
|
|
216
|
+
},
|
|
217
|
+
];
|
|
218
|
+
}
|
|
219
|
+
async forget() { }
|
|
220
|
+
}
|
|
221
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
222
|
+
config: {
|
|
223
|
+
stores: [{ id: "k", type: "llamaindex", options: {} }],
|
|
224
|
+
},
|
|
225
|
+
overrides: {
|
|
226
|
+
providerCtors: {
|
|
227
|
+
llamaindex: FakeKnowledgeProvider,
|
|
228
|
+
},
|
|
229
|
+
},
|
|
240
230
|
});
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
231
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
232
|
+
const result = await memory.recall({
|
|
233
|
+
namespace: "user:1",
|
|
234
|
+
query: "k",
|
|
235
|
+
topK: 5,
|
|
236
|
+
});
|
|
237
|
+
assert.strictEqual(result.items.length, 1);
|
|
238
|
+
assert.strictEqual(result.items[0]?.type, "knowledge");
|
|
239
|
+
});
|
|
240
|
+
it("sqlite_vec provider falls back to cross_thread type when metadata.type is missing", async () => {
|
|
241
|
+
class FakeLongTermProvider {
|
|
242
|
+
async remember(req) {
|
|
243
|
+
return {
|
|
244
|
+
id: "lt-1",
|
|
245
|
+
content: req.content ?? "",
|
|
246
|
+
metadata: req.metadata,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
async recall() {
|
|
250
|
+
return [
|
|
251
|
+
{
|
|
245
252
|
id: "lt-1",
|
|
246
|
-
content:
|
|
247
|
-
metadata:
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
async recall() {
|
|
251
|
-
return [
|
|
252
|
-
{
|
|
253
|
-
id: "lt-1",
|
|
254
|
-
content: "longterm-content",
|
|
255
|
-
metadata: {},
|
|
256
|
-
},
|
|
257
|
-
];
|
|
258
|
-
}
|
|
259
|
-
async forget() { }
|
|
253
|
+
content: "longterm-content",
|
|
254
|
+
metadata: {},
|
|
255
|
+
},
|
|
256
|
+
];
|
|
260
257
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
258
|
+
async forget() { }
|
|
259
|
+
}
|
|
260
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
261
|
+
config: {
|
|
262
|
+
stores: [{ id: "lt", type: "sqlite_vec", options: { dbPath: ":memory:", dimensions: 1024 } }],
|
|
263
|
+
},
|
|
264
|
+
overrides: {
|
|
265
|
+
providerCtors: {
|
|
266
|
+
sqliteVec: FakeLongTermProvider,
|
|
264
267
|
},
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
271
|
+
const result = await memory.recall({
|
|
272
|
+
namespace: "user:1",
|
|
273
|
+
query: "lt",
|
|
274
|
+
topK: 5,
|
|
275
|
+
});
|
|
276
|
+
assert.strictEqual(result.items.length, 1);
|
|
277
|
+
assert.strictEqual(result.items[0]?.type, "cross_thread");
|
|
278
|
+
});
|
|
279
|
+
it("llamaindex provider gets VLM model from overrides into context", async () => {
|
|
280
|
+
class FakeKnowledgeProviderWithContext {
|
|
281
|
+
options;
|
|
282
|
+
constructor(options) {
|
|
283
|
+
this.options = options;
|
|
284
|
+
}
|
|
285
|
+
async remember(req) {
|
|
286
|
+
const context = this.options.context;
|
|
287
|
+
const agentModel = context?.agentModel;
|
|
288
|
+
const vlm = agentModel?.vlm;
|
|
289
|
+
return {
|
|
290
|
+
id: "k-vlm-1",
|
|
291
|
+
content: req.content ?? "",
|
|
292
|
+
metadata: {
|
|
293
|
+
...(req.metadata ?? {}),
|
|
294
|
+
vlm_model_id: typeof vlm?.id === "string" ? vlm.id : undefined,
|
|
268
295
|
},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
async recall() {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
async forget() { }
|
|
302
|
+
}
|
|
303
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
304
|
+
config: {
|
|
305
|
+
stores: [{ id: "k", type: "llamaindex", options: {} }],
|
|
306
|
+
vlm: { useAgentModel: true },
|
|
307
|
+
},
|
|
308
|
+
overrides: {
|
|
309
|
+
agentModelVlm: { id: "vlm-demo", provider: "openai", model: "gpt-4o-mini" },
|
|
310
|
+
providerCtors: {
|
|
311
|
+
llamaindex: FakeKnowledgeProviderWithContext,
|
|
269
312
|
},
|
|
270
|
-
}
|
|
271
|
-
const memory = await memoryRegistry.getAgentMemory();
|
|
272
|
-
const result = await memory.recall({
|
|
273
|
-
namespace: "user:1",
|
|
274
|
-
query: "lt",
|
|
275
|
-
topK: 5,
|
|
276
|
-
});
|
|
277
|
-
assert.strictEqual(result.items.length, 1);
|
|
278
|
-
assert.strictEqual(result.items[0]?.type, "cross_thread");
|
|
313
|
+
},
|
|
279
314
|
});
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
315
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
316
|
+
const item = await memory.memorize("user:vlm", "knowledge", "Image summary.");
|
|
317
|
+
assert.strictEqual(item.metadata?.vlm_model_id, "vlm-demo");
|
|
318
|
+
});
|
|
319
|
+
it("supports session compaction from config", async () => {
|
|
320
|
+
const memoryRegistry = await createAgentMemoryRegistry({
|
|
321
|
+
config: {
|
|
322
|
+
stores: [{ id: "default", type: "in_memory" }],
|
|
323
|
+
memory: {
|
|
324
|
+
thread: {
|
|
325
|
+
sessionCompaction: {
|
|
326
|
+
enabled: true,
|
|
327
|
+
maxTokens: 8,
|
|
328
|
+
keepRecentTurns: 1,
|
|
329
|
+
summaryKey: "__summary__",
|
|
330
|
+
checkEveryTurns: 1,
|
|
296
331
|
},
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
async recall() {
|
|
300
|
-
return [];
|
|
301
|
-
}
|
|
302
|
-
async forget() { }
|
|
303
|
-
}
|
|
304
|
-
const memoryRegistry = await createAgentMemoryRegistry({
|
|
305
|
-
config: {
|
|
306
|
-
stores: [{ id: "k", type: "llamaindex", options: {} }],
|
|
307
|
-
vlm: { useAgentModel: true },
|
|
308
|
-
},
|
|
309
|
-
overrides: {
|
|
310
|
-
agentModelVlm: { id: "vlm-demo", provider: "openai", model: "gpt-4o-mini" },
|
|
311
|
-
providerCtors: {
|
|
312
|
-
llamaindex: FakeKnowledgeProviderWithContext,
|
|
313
332
|
},
|
|
314
333
|
},
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const item = await memory.memorize("user:vlm", "knowledge", "Image summary.");
|
|
318
|
-
assert.strictEqual(item.metadata?.vlm_model_id, "vlm-demo");
|
|
334
|
+
},
|
|
335
|
+
summarizeSessionTurns: async ({ oldTurns }) => `summary(${oldTurns.length})`,
|
|
319
336
|
});
|
|
320
|
-
|
|
337
|
+
const memory = await memoryRegistry.getAgentMemory();
|
|
338
|
+
await memory.memorize("session:demo", "thread", "A".repeat(40));
|
|
339
|
+
await memory.memorize("session:demo", "thread", "B".repeat(40));
|
|
340
|
+
const summary = await memory.getByKey("session:demo", "__summary__");
|
|
341
|
+
assert.ok(summary);
|
|
342
|
+
assert.strictEqual(summary?.type, "thread");
|
|
343
|
+
assert.strictEqual(summary?.content, "summary(1)");
|
|
344
|
+
});
|
|
345
|
+
it("rejects provider key in typed store config blocks", async () => {
|
|
346
|
+
await assert.rejects(async () => {
|
|
321
347
|
const memoryRegistry = await createAgentMemoryRegistry({
|
|
322
348
|
config: {
|
|
323
|
-
stores: [{ id: "default", type: "in_memory" }],
|
|
324
349
|
memory: {
|
|
325
|
-
thread: {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
},
|
|
334
|
-
},
|
|
335
|
-
},
|
|
336
|
-
summarizeSessionTurns: async ({ oldTurns }) => `summary(${oldTurns.length})`,
|
|
337
|
-
});
|
|
338
|
-
const memory = await memoryRegistry.getAgentMemory();
|
|
339
|
-
await memory.memorize("session:demo", "thread", "A".repeat(40));
|
|
340
|
-
await memory.memorize("session:demo", "thread", "B".repeat(40));
|
|
341
|
-
const summary = await memory.getByKey("session:demo", "__summary__");
|
|
342
|
-
assert.ok(summary);
|
|
343
|
-
assert.strictEqual(summary?.type, "thread");
|
|
344
|
-
assert.strictEqual(summary?.content, "summary(1)");
|
|
345
|
-
});
|
|
346
|
-
it("rejects provider key in typed store config blocks", async () => {
|
|
347
|
-
await assert.rejects(async () => {
|
|
348
|
-
const memoryRegistry = await createAgentMemoryRegistry({
|
|
349
|
-
config: {
|
|
350
|
-
memory: {
|
|
351
|
-
thread: { store: { type: "in_memory" } },
|
|
352
|
-
cross_thread: {
|
|
353
|
-
store: {
|
|
354
|
-
type: "mem0",
|
|
355
|
-
config: {
|
|
356
|
-
vectorStore: {
|
|
357
|
-
provider: "qdrant",
|
|
358
|
-
config: { host: "localhost", port: 6333 },
|
|
359
|
-
},
|
|
350
|
+
thread: { store: { type: "in_memory" } },
|
|
351
|
+
cross_thread: {
|
|
352
|
+
store: {
|
|
353
|
+
type: "mem0",
|
|
354
|
+
config: {
|
|
355
|
+
vectorStore: {
|
|
356
|
+
provider: "qdrant",
|
|
357
|
+
config: { host: "localhost", port: 6333 },
|
|
360
358
|
},
|
|
361
359
|
},
|
|
362
360
|
},
|
|
363
|
-
knowledge: { store: { type: "in_memory" } },
|
|
364
361
|
},
|
|
362
|
+
knowledge: { store: { type: "in_memory" } },
|
|
365
363
|
},
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
});
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
await memoryRegistry.getAgentMemory();
|
|
367
|
+
}, /provider.*type/i);
|
|
370
368
|
});
|
|
371
369
|
//# sourceMappingURL=create-agent-memory.test.js.map
|