@ai.ntellect/core 0.6.17 → 0.6.19
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/.mocharc.json +1 -2
- package/README.md +123 -178
- package/dist/graph/controller.js +29 -6
- package/dist/graph/index.js +302 -62
- package/dist/index.js +21 -6
- package/dist/interfaces/index.js +15 -0
- package/dist/modules/agenda/adapters/node-cron/index.js +29 -0
- package/dist/modules/agenda/index.js +140 -0
- package/dist/{services/embedding.js → modules/embedding/adapters/ai/index.js} +24 -7
- package/dist/modules/embedding/index.js +59 -0
- package/dist/modules/memory/adapters/in-memory/index.js +210 -0
- package/dist/{memory → modules/memory}/adapters/meilisearch/index.js +97 -2
- package/dist/{memory → modules/memory}/adapters/redis/index.js +77 -15
- package/dist/modules/memory/index.js +103 -0
- package/dist/utils/{stringifiy-zod-schema.js → generate-action-schema.js} +5 -5
- package/graph/controller.ts +37 -13
- package/graph/index.ts +348 -73
- package/index.ts +24 -6
- package/interfaces/index.ts +346 -27
- package/modules/agenda/adapters/node-cron/index.ts +25 -0
- package/modules/agenda/index.ts +159 -0
- package/modules/embedding/adapters/ai/index.ts +42 -0
- package/modules/embedding/index.ts +45 -0
- package/modules/memory/adapters/in-memory/index.ts +203 -0
- package/{memory → modules/memory}/adapters/meilisearch/index.ts +114 -12
- package/modules/memory/adapters/redis/index.ts +164 -0
- package/modules/memory/index.ts +93 -0
- package/package.json +3 -1
- package/test/graph/index.test.ts +646 -0
- package/test/modules/agenda/node-cron.test.ts +286 -0
- package/test/modules/embedding/ai.test.ts +78 -0
- package/test/modules/memory/adapters/in-memory.test.ts +153 -0
- package/test/{memory → modules/memory}/adapters/meilisearch.test.ts +79 -75
- package/test/modules/memory/adapters/redis.test.ts +169 -0
- package/test/modules/memory/base.test.ts +230 -0
- package/test/services/agenda.test.ts +279 -280
- package/types/index.ts +82 -203
- package/utils/{stringifiy-zod-schema.ts → generate-action-schema.ts} +3 -3
- package/app/README.md +0 -36
- package/app/app/favicon.ico +0 -0
- package/app/app/globals.css +0 -21
- package/app/app/gun.ts +0 -0
- package/app/app/layout.tsx +0 -18
- package/app/app/page.tsx +0 -321
- package/app/eslint.config.mjs +0 -16
- package/app/next.config.ts +0 -7
- package/app/package-lock.json +0 -5912
- package/app/package.json +0 -31
- package/app/pnpm-lock.yaml +0 -4031
- package/app/postcss.config.mjs +0 -8
- package/app/public/file.svg +0 -1
- package/app/public/globe.svg +0 -1
- package/app/public/next.svg +0 -1
- package/app/public/vercel.svg +0 -1
- package/app/public/window.svg +0 -1
- package/app/tailwind.config.ts +0 -18
- package/app/tsconfig.json +0 -27
- package/dist/memory/index.js +0 -9
- package/dist/services/agenda.js +0 -115
- package/dist/services/queue.js +0 -142
- package/dist/utils/experimental-graph-rag.js +0 -152
- package/dist/utils/generate-object.js +0 -111
- package/dist/utils/inject-actions.js +0 -16
- package/dist/utils/queue-item-transformer.js +0 -24
- package/dist/utils/sanitize-results.js +0 -60
- package/memory/adapters/redis/index.ts +0 -103
- package/memory/index.ts +0 -22
- package/services/agenda.ts +0 -118
- package/services/embedding.ts +0 -26
- package/services/queue.ts +0 -145
- package/test/memory/adapters/redis.test.ts +0 -159
- package/test/memory/base.test.ts +0 -225
- package/test/services/queue.test.ts +0 -286
- package/utils/experimental-graph-rag.ts +0 -170
- package/utils/generate-object.ts +0 -117
- package/utils/inject-actions.ts +0 -19
- package/utils/queue-item-transformer.ts +0 -38
- package/utils/sanitize-results.ts +0 -66
@@ -1,8 +1,7 @@
|
|
1
|
-
import { BaseMemoryService } from "../../../interfaces";
|
2
|
-
import { MeilisearchAdapter } from "../../../memory/adapters/meilisearch";
|
3
|
-
import { BaseMemoryType } from "../../../types";
|
4
1
|
import { expect } from "chai";
|
5
2
|
import dotenv from "dotenv";
|
3
|
+
import { MeilisearchAdapter } from "../../../memory/adapters/meilisearch";
|
4
|
+
import { BaseMemoryType } from "../../../types";
|
6
5
|
|
7
6
|
// Load environment variables
|
8
7
|
dotenv.config();
|
@@ -14,81 +13,55 @@ describe("MeilisearchAdapter", () => {
|
|
14
13
|
const testMemory: BaseMemoryType = {
|
15
14
|
id: "test-id",
|
16
15
|
data: "test data",
|
17
|
-
embedding: [0.1, 0.2, 0.3],
|
18
16
|
roomId: "test-room",
|
19
17
|
createdAt: new Date(),
|
20
18
|
};
|
21
19
|
|
22
|
-
beforeEach(()
|
23
|
-
//
|
24
|
-
if (process.env.MEILISEARCH_HOST && process.env.MEILISEARCH_API_KEY) {
|
25
|
-
// Real Meilisearch configuration
|
26
|
-
// console.log("Real Meilisearch configuration");
|
27
|
-
meilisearchAdapter = new MeilisearchAdapter({
|
28
|
-
host: process.env.MEILISEARCH_HOST,
|
29
|
-
apiKey: process.env.MEILISEARCH_API_KEY,
|
30
|
-
searchableAttributes: ["content"],
|
31
|
-
sortableAttributes: ["createdAt"],
|
32
|
-
});
|
33
|
-
} else {
|
34
|
-
// Mock fetch implementation
|
35
|
-
// console.log("Mock Meilisearch configuration");
|
36
|
-
global.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
|
37
|
-
const url = input.toString();
|
20
|
+
beforeEach(async function () {
|
21
|
+
this.timeout(10000); // Augmenter le timeout
|
38
22
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
return new Response(JSON.stringify({ taskUid: 1 }));
|
43
|
-
}
|
44
|
-
if (url.endsWith("/indexes")) {
|
45
|
-
return new Response(JSON.stringify({ results: [] }));
|
46
|
-
}
|
47
|
-
// Mock for specific index check
|
48
|
-
if (url.includes(`/indexes/${TEST_ROOM_ID}`)) {
|
49
|
-
return new Response(
|
50
|
-
JSON.stringify({
|
51
|
-
uid: TEST_ROOM_ID,
|
52
|
-
primaryKey: "id",
|
53
|
-
})
|
54
|
-
);
|
55
|
-
}
|
56
|
-
if (url.includes("/indexes/memories")) {
|
57
|
-
return new Response(
|
58
|
-
JSON.stringify({
|
59
|
-
uid: "memories",
|
60
|
-
primaryKey: "id",
|
61
|
-
})
|
62
|
-
);
|
63
|
-
}
|
64
|
-
}
|
23
|
+
// Mock fetch pour simuler l'existence de l'index
|
24
|
+
global.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
|
25
|
+
const url = input.toString();
|
65
26
|
|
66
|
-
|
67
|
-
|
68
|
-
|
27
|
+
// Mock pour index check/creation
|
28
|
+
if (url.includes("/indexes")) {
|
29
|
+
if (init?.method === "POST") {
|
30
|
+
return new Response(JSON.stringify({ taskUid: 1 }));
|
69
31
|
}
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
if (init?.method === "DELETE") {
|
77
|
-
return new Response(JSON.stringify({ taskUid: 3 }));
|
78
|
-
}
|
79
|
-
return new Response(JSON.stringify([testMemory]));
|
32
|
+
if (url.endsWith("/indexes")) {
|
33
|
+
return new Response(
|
34
|
+
JSON.stringify({
|
35
|
+
results: [{ uid: TEST_ROOM_ID }], // Simuler l'existence de l'index
|
36
|
+
})
|
37
|
+
);
|
80
38
|
}
|
39
|
+
if (url.includes(`/indexes/${TEST_ROOM_ID}`)) {
|
40
|
+
return new Response(
|
41
|
+
JSON.stringify({
|
42
|
+
uid: TEST_ROOM_ID,
|
43
|
+
primaryKey: "id",
|
44
|
+
})
|
45
|
+
);
|
46
|
+
}
|
47
|
+
}
|
81
48
|
|
82
|
-
|
83
|
-
|
49
|
+
// Mock pour settings et autres endpoints
|
50
|
+
if (url.includes("/settings")) {
|
51
|
+
return new Response(JSON.stringify({ acknowledged: true }));
|
52
|
+
}
|
84
53
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
54
|
+
return new Response(JSON.stringify({}));
|
55
|
+
};
|
56
|
+
|
57
|
+
meilisearchAdapter = new MeilisearchAdapter({
|
58
|
+
host: "http://localhost:7700",
|
59
|
+
apiKey: "test_key",
|
60
|
+
searchableAttributes: ["content"],
|
61
|
+
sortableAttributes: ["createdAt"],
|
62
|
+
});
|
63
|
+
|
64
|
+
await meilisearchAdapter.init(TEST_ROOM_ID);
|
92
65
|
});
|
93
66
|
|
94
67
|
describe("Initialization", () => {
|
@@ -163,7 +136,6 @@ describe("MeilisearchAdapter", () => {
|
|
163
136
|
it("should create memory", async () => {
|
164
137
|
const result = await meilisearchAdapter.createMemory({
|
165
138
|
data: "test data",
|
166
|
-
query: "test query",
|
167
139
|
roomId: TEST_ROOM_ID,
|
168
140
|
});
|
169
141
|
|
@@ -225,28 +197,60 @@ describe("MeilisearchAdapter", () => {
|
|
225
197
|
});
|
226
198
|
|
227
199
|
it("should clear all memories", async () => {
|
200
|
+
// S'assurer que l'index existe avant de le supprimer
|
201
|
+
await meilisearchAdapter.init(TEST_ROOM_ID);
|
228
202
|
await expect(meilisearchAdapter.clearAllMemories()).to.not.throw;
|
229
203
|
});
|
230
204
|
|
231
205
|
it("should not create duplicate memory with same data", async () => {
|
232
|
-
//
|
206
|
+
// Override fetch mock for this test
|
207
|
+
const firstMemoryId = "test-memory-id";
|
208
|
+
const mockMemory = {
|
209
|
+
id: firstMemoryId,
|
210
|
+
data: "test data",
|
211
|
+
roomId: TEST_ROOM_ID,
|
212
|
+
embedding: null,
|
213
|
+
createdAt: new Date().toISOString(),
|
214
|
+
};
|
215
|
+
|
216
|
+
global.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
|
217
|
+
const url = input.toString();
|
218
|
+
|
219
|
+
if (url.includes("/search")) {
|
220
|
+
return new Response(
|
221
|
+
JSON.stringify({
|
222
|
+
hits: [{ ...mockMemory }],
|
223
|
+
})
|
224
|
+
);
|
225
|
+
}
|
226
|
+
|
227
|
+
if (url.includes("/indexes")) {
|
228
|
+
if (init?.method === "POST") {
|
229
|
+
return new Response(JSON.stringify({ taskUid: 1 }));
|
230
|
+
}
|
231
|
+
return new Response(
|
232
|
+
JSON.stringify({
|
233
|
+
uid: TEST_ROOM_ID,
|
234
|
+
primaryKey: "id",
|
235
|
+
})
|
236
|
+
);
|
237
|
+
}
|
238
|
+
|
239
|
+
return new Response(JSON.stringify({}));
|
240
|
+
};
|
241
|
+
|
233
242
|
const firstMemory = await meilisearchAdapter.createMemory({
|
234
243
|
data: "test data",
|
235
|
-
query: "test query",
|
236
244
|
roomId: TEST_ROOM_ID,
|
237
245
|
});
|
238
246
|
|
239
|
-
// Try to create second memory with same data
|
240
247
|
const secondMemory = await meilisearchAdapter.createMemory({
|
241
248
|
data: "test data",
|
242
|
-
query: "test query",
|
243
249
|
roomId: TEST_ROOM_ID,
|
244
250
|
});
|
245
251
|
|
246
|
-
expect(secondMemory).to.exist;
|
247
252
|
expect(secondMemory?.id).to.equal(firstMemory?.id);
|
248
253
|
expect(secondMemory?.data).to.equal(firstMemory?.data);
|
249
|
-
expect(secondMemory?.query).to.equal(firstMemory?.query);
|
250
254
|
expect(secondMemory?.roomId).to.equal(firstMemory?.roomId);
|
251
255
|
});
|
252
256
|
|
@@ -0,0 +1,169 @@
|
|
1
|
+
import { expect } from "chai";
|
2
|
+
import dotenv from "dotenv";
|
3
|
+
import Redis from "ioredis";
|
4
|
+
import { IMemoryAdapter } from "../../../interfaces";
|
5
|
+
import { RedisAdapter } from "../../../memory/adapters/redis";
|
6
|
+
import { BaseMemoryType } from "../../../types";
|
7
|
+
|
8
|
+
// Load environment variables
|
9
|
+
dotenv.config();
|
10
|
+
|
11
|
+
describe("RedisAdapter", () => {
|
12
|
+
before(function () {
|
13
|
+
this.timeout(30000);
|
14
|
+
});
|
15
|
+
|
16
|
+
let redisAdapter: RedisAdapter;
|
17
|
+
let mockAdapter: IMemoryAdapter;
|
18
|
+
let redisClient: Redis | null = null;
|
19
|
+
const fixedDate = new Date("2025-01-30T07:43:50.626Z");
|
20
|
+
const fixedDateString = fixedDate.toISOString();
|
21
|
+
|
22
|
+
const testMemory: BaseMemoryType = {
|
23
|
+
id: "test-id",
|
24
|
+
data: "test data",
|
25
|
+
roomId: "test-room",
|
26
|
+
createdAt: new Date(fixedDateString),
|
27
|
+
};
|
28
|
+
|
29
|
+
beforeEach(async function () {
|
30
|
+
this.timeout(10000);
|
31
|
+
|
32
|
+
try {
|
33
|
+
mockAdapter = {
|
34
|
+
init: async () => {},
|
35
|
+
createMemory: async (input) => testMemory,
|
36
|
+
getMemoryById: async () => testMemory,
|
37
|
+
getMemoryByIndex: async () => [testMemory],
|
38
|
+
getAllMemories: async () => [testMemory],
|
39
|
+
clearMemoryById: async () => {},
|
40
|
+
clearAllMemories: async () => {},
|
41
|
+
};
|
42
|
+
|
43
|
+
if (process.env.REDIS_URL) {
|
44
|
+
redisClient = new Redis(process.env.REDIS_URL);
|
45
|
+
redisAdapter = new RedisAdapter(process.env.REDIS_URL, {
|
46
|
+
cachePrefix: "test-prefix",
|
47
|
+
cacheTTL: 3600,
|
48
|
+
});
|
49
|
+
} else {
|
50
|
+
const mockRedis = {
|
51
|
+
connect: async () => Promise.resolve(),
|
52
|
+
disconnect: async () => Promise.resolve(),
|
53
|
+
set: async () => "OK",
|
54
|
+
get: async (key: string) => {
|
55
|
+
if (key.includes("test-id")) {
|
56
|
+
return JSON.stringify({
|
57
|
+
id: "test-id",
|
58
|
+
data: "test data",
|
59
|
+
embedding: null,
|
60
|
+
roomId: "test-room",
|
61
|
+
createdAt: fixedDateString,
|
62
|
+
});
|
63
|
+
}
|
64
|
+
return null;
|
65
|
+
},
|
66
|
+
keys: async () => [`test-id`],
|
67
|
+
mget: async (keys: string[]) =>
|
68
|
+
keys.map(() =>
|
69
|
+
JSON.stringify({
|
70
|
+
id: "test-id",
|
71
|
+
data: "test data",
|
72
|
+
embedding: null,
|
73
|
+
roomId: "test-room",
|
74
|
+
createdAt: fixedDateString,
|
75
|
+
})
|
76
|
+
),
|
77
|
+
del: async () => 1,
|
78
|
+
flushall: async () => "OK",
|
79
|
+
quit: async () => Promise.resolve(),
|
80
|
+
};
|
81
|
+
|
82
|
+
redisAdapter = new RedisAdapter(mockRedis as any, {
|
83
|
+
cachePrefix: "test-prefix",
|
84
|
+
cacheTTL: 3600,
|
85
|
+
});
|
86
|
+
}
|
87
|
+
|
88
|
+
await redisAdapter.init("test-room");
|
89
|
+
} catch (error) {
|
90
|
+
console.error("Error in beforeEach:", error);
|
91
|
+
throw error;
|
92
|
+
}
|
93
|
+
});
|
94
|
+
|
95
|
+
afterEach(async function () {
|
96
|
+
this.timeout(5000);
|
97
|
+
try {
|
98
|
+
if (redisClient) {
|
99
|
+
await redisClient.quit();
|
100
|
+
redisClient = null;
|
101
|
+
}
|
102
|
+
if (redisAdapter) {
|
103
|
+
await redisAdapter.quit();
|
104
|
+
}
|
105
|
+
} catch (error) {
|
106
|
+
console.error("Error in afterEach:", error);
|
107
|
+
}
|
108
|
+
});
|
109
|
+
|
110
|
+
describe("Initialization", () => {
|
111
|
+
it("should initialize storage", async () => {
|
112
|
+
await expect(redisAdapter.init("test-room")).to.not.throw;
|
113
|
+
});
|
114
|
+
});
|
115
|
+
|
116
|
+
describe("Memory Operations", () => {
|
117
|
+
const TEST_ROOM_ID = "test-room";
|
118
|
+
|
119
|
+
it("should create memory", async () => {
|
120
|
+
await expect(
|
121
|
+
redisAdapter.createMemory({
|
122
|
+
data: "test data",
|
123
|
+
roomId: TEST_ROOM_ID,
|
124
|
+
id: "test-id",
|
125
|
+
embedding: [0.1, 0.2, 0.3],
|
126
|
+
})
|
127
|
+
).to.not.throw;
|
128
|
+
});
|
129
|
+
|
130
|
+
it("should get memory by ID", async () => {
|
131
|
+
const result = await redisAdapter.getMemoryById("test-id", TEST_ROOM_ID);
|
132
|
+
if (result) {
|
133
|
+
result.createdAt = new Date(fixedDateString);
|
134
|
+
}
|
135
|
+
expect(result).to.deep.equal(testMemory);
|
136
|
+
});
|
137
|
+
|
138
|
+
it("should get memories by index", async () => {
|
139
|
+
const results = await redisAdapter.getMemoryByIndex("test", {
|
140
|
+
roomId: TEST_ROOM_ID,
|
141
|
+
limit: 10,
|
142
|
+
});
|
143
|
+
|
144
|
+
expect(results).to.be.an("array");
|
145
|
+
if (results[0]) {
|
146
|
+
results[0].createdAt = new Date(fixedDateString);
|
147
|
+
}
|
148
|
+
expect(results[0]).to.deep.equal(testMemory);
|
149
|
+
});
|
150
|
+
|
151
|
+
it("should get all memories", async () => {
|
152
|
+
const results = await redisAdapter.getAllMemories(TEST_ROOM_ID);
|
153
|
+
expect(results).to.be.an("array");
|
154
|
+
if (results[0]) {
|
155
|
+
results[0].createdAt = new Date(fixedDateString);
|
156
|
+
}
|
157
|
+
expect(results[0]).to.deep.equal(testMemory);
|
158
|
+
});
|
159
|
+
|
160
|
+
it("should clear memory by ID", async () => {
|
161
|
+
await expect(redisAdapter.clearMemoryById("test-id", TEST_ROOM_ID)).to.not
|
162
|
+
.throw;
|
163
|
+
});
|
164
|
+
|
165
|
+
it("should clear all memories", async () => {
|
166
|
+
await expect(redisAdapter.clearAllMemories()).to.not.throw;
|
167
|
+
});
|
168
|
+
});
|
169
|
+
});
|
@@ -0,0 +1,230 @@
|
|
1
|
+
import { expect } from "chai";
|
2
|
+
import { IMemoryAdapter } from "../../../interfaces";
|
3
|
+
import { Memory } from "../../../modules/memory";
|
4
|
+
import { BaseMemoryType, CreateMemoryInput } from "../../../types";
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @module MemoryTests
|
8
|
+
* @description Test suite for the Memory service implementation.
|
9
|
+
* Tests the core functionality of memory management including:
|
10
|
+
* - Initialization
|
11
|
+
* - Memory creation
|
12
|
+
* - Memory retrieval
|
13
|
+
* - Memory deletion
|
14
|
+
*/
|
15
|
+
|
16
|
+
describe("Memory", () => {
|
17
|
+
let memory: Memory;
|
18
|
+
let mockAdapter: IMemoryAdapter;
|
19
|
+
const TEST_ROOM_ID = "test-room";
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Test data fixture
|
23
|
+
* @type {BaseMemoryType}
|
24
|
+
*/
|
25
|
+
const testMemory: BaseMemoryType = {
|
26
|
+
id: "test-id",
|
27
|
+
data: "test data",
|
28
|
+
embedding: [0.1, 0.2, 0.3],
|
29
|
+
roomId: TEST_ROOM_ID,
|
30
|
+
createdAt: new Date(),
|
31
|
+
};
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Set up test environment before each test
|
35
|
+
* Creates a mock adapter and initializes the memory service
|
36
|
+
*/
|
37
|
+
beforeEach(() => {
|
38
|
+
// Create mock implementation of IMemoryAdapter
|
39
|
+
mockAdapter = {
|
40
|
+
init: async () => Promise.resolve(),
|
41
|
+
createMemory: async (input: CreateMemoryInput) => ({
|
42
|
+
...testMemory,
|
43
|
+
data: input.data,
|
44
|
+
embedding: input.embedding,
|
45
|
+
}),
|
46
|
+
getMemoryById: async () => testMemory,
|
47
|
+
getMemoryByIndex: async () => [testMemory],
|
48
|
+
getAllMemories: async () => [testMemory],
|
49
|
+
clearMemoryById: async () => Promise.resolve(),
|
50
|
+
clearAllMemories: async () => Promise.resolve(),
|
51
|
+
};
|
52
|
+
|
53
|
+
memory = new Memory(mockAdapter);
|
54
|
+
});
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Test suite for initialization functionality
|
58
|
+
*/
|
59
|
+
describe("Initialization", () => {
|
60
|
+
/**
|
61
|
+
* Test case: Verify adapter initialization
|
62
|
+
*/
|
63
|
+
it("should initialize the memory adapter", async () => {
|
64
|
+
let initCalled = false;
|
65
|
+
mockAdapter.init = async () => {
|
66
|
+
initCalled = true;
|
67
|
+
};
|
68
|
+
|
69
|
+
await memory.init();
|
70
|
+
expect(initCalled).to.be.true;
|
71
|
+
});
|
72
|
+
});
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Test suite for memory creation functionality
|
76
|
+
*/
|
77
|
+
describe("Memory Creation", () => {
|
78
|
+
/**
|
79
|
+
* Test case: Verify memory creation with valid input
|
80
|
+
*/
|
81
|
+
it("should create a new memory entry", async () => {
|
82
|
+
const input = {
|
83
|
+
data: "test data",
|
84
|
+
roomId: TEST_ROOM_ID,
|
85
|
+
};
|
86
|
+
|
87
|
+
const result = await memory.createMemory(input);
|
88
|
+
expect(result).to.deep.include(input);
|
89
|
+
});
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Test case: Verify memory creation with embedding
|
93
|
+
*/
|
94
|
+
it("should create a memory entry with embedding", async () => {
|
95
|
+
const input = {
|
96
|
+
data: "test data",
|
97
|
+
roomId: TEST_ROOM_ID,
|
98
|
+
embedding: [0.1, 0.2, 0.3],
|
99
|
+
};
|
100
|
+
|
101
|
+
const result = await memory.createMemory(input);
|
102
|
+
expect(result).to.deep.include(input);
|
103
|
+
});
|
104
|
+
});
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Test suite for memory retrieval functionality
|
108
|
+
*/
|
109
|
+
describe("Memory Retrieval", () => {
|
110
|
+
/**
|
111
|
+
* Test case: Verify memory retrieval by ID
|
112
|
+
*/
|
113
|
+
it("should retrieve a memory by ID", async () => {
|
114
|
+
const result = await memory.getMemoryById("test-id", TEST_ROOM_ID);
|
115
|
+
expect(result).to.deep.equal(testMemory);
|
116
|
+
});
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Test case: Verify memory retrieval by index
|
120
|
+
*/
|
121
|
+
it("should retrieve memories by index", async () => {
|
122
|
+
const result = await memory.getMemoryByIndex("test", {
|
123
|
+
roomId: TEST_ROOM_ID,
|
124
|
+
});
|
125
|
+
expect(result).to.deep.equal([testMemory]);
|
126
|
+
});
|
127
|
+
|
128
|
+
/**
|
129
|
+
* Test case: Verify retrieval of all memories
|
130
|
+
*/
|
131
|
+
it("should retrieve all memories", async () => {
|
132
|
+
const result = await memory.getAllMemories(TEST_ROOM_ID);
|
133
|
+
expect(result).to.deep.equal([testMemory]);
|
134
|
+
});
|
135
|
+
});
|
136
|
+
|
137
|
+
/**
|
138
|
+
* Test suite for memory deletion functionality
|
139
|
+
*/
|
140
|
+
describe("Memory Deletion", () => {
|
141
|
+
/**
|
142
|
+
* Test case: Verify memory deletion by ID
|
143
|
+
*/
|
144
|
+
it("should delete a memory by ID", async () => {
|
145
|
+
let deleteCalled = false;
|
146
|
+
mockAdapter.clearMemoryById = async () => {
|
147
|
+
deleteCalled = true;
|
148
|
+
};
|
149
|
+
|
150
|
+
await memory.clearMemoryById("test-id", TEST_ROOM_ID);
|
151
|
+
expect(deleteCalled).to.be.true;
|
152
|
+
});
|
153
|
+
|
154
|
+
/**
|
155
|
+
* Test case: Verify deletion of all memories
|
156
|
+
*/
|
157
|
+
it("should clear all memories", async () => {
|
158
|
+
let clearAllCalled = false;
|
159
|
+
mockAdapter.clearAllMemories = async () => {
|
160
|
+
clearAllCalled = true;
|
161
|
+
};
|
162
|
+
|
163
|
+
await memory.clearAllMemories();
|
164
|
+
expect(clearAllCalled).to.be.true;
|
165
|
+
});
|
166
|
+
});
|
167
|
+
|
168
|
+
describe("Error Handling", () => {
|
169
|
+
it("should handle errors during memory creation", async () => {
|
170
|
+
mockAdapter.createMemory = async () => {
|
171
|
+
throw new Error("Creation failed");
|
172
|
+
};
|
173
|
+
|
174
|
+
try {
|
175
|
+
await memory.createMemory({
|
176
|
+
data: "test",
|
177
|
+
roomId: TEST_ROOM_ID,
|
178
|
+
});
|
179
|
+
expect.fail("Should have thrown an error");
|
180
|
+
} catch (error) {
|
181
|
+
expect(error).to.be.instanceOf(Error);
|
182
|
+
expect((error as Error).message).to.equal("Creation failed");
|
183
|
+
}
|
184
|
+
});
|
185
|
+
|
186
|
+
it("should handle errors during memory retrieval", async () => {
|
187
|
+
mockAdapter.getMemoryById = async () => {
|
188
|
+
throw new Error("Retrieval failed");
|
189
|
+
};
|
190
|
+
|
191
|
+
try {
|
192
|
+
await memory.getMemoryById("test-id", TEST_ROOM_ID);
|
193
|
+
expect.fail("Should have thrown an error");
|
194
|
+
} catch (error) {
|
195
|
+
expect(error).to.be.instanceOf(Error);
|
196
|
+
expect((error as Error).message).to.equal("Retrieval failed");
|
197
|
+
}
|
198
|
+
});
|
199
|
+
});
|
200
|
+
|
201
|
+
describe("Edge Cases", () => {
|
202
|
+
it("should handle undefined embedding", async () => {
|
203
|
+
const input = {
|
204
|
+
data: "test data",
|
205
|
+
query: "test query",
|
206
|
+
roomId: "test-room",
|
207
|
+
embedding: undefined,
|
208
|
+
};
|
209
|
+
|
210
|
+
const result = await memory.createMemory(input);
|
211
|
+
expect(result?.embedding).to.be.null;
|
212
|
+
});
|
213
|
+
|
214
|
+
it("should handle empty query results", async () => {
|
215
|
+
mockAdapter.getMemoryByIndex = async () => [];
|
216
|
+
|
217
|
+
const results = await memory.getMemoryByIndex("nonexistent", {
|
218
|
+
roomId: "test-room",
|
219
|
+
});
|
220
|
+
expect(results).to.be.an("array").that.is.empty;
|
221
|
+
});
|
222
|
+
|
223
|
+
it("should handle non-existent memory ID", async () => {
|
224
|
+
mockAdapter.getMemoryById = async () => null;
|
225
|
+
|
226
|
+
const result = await memory.getMemoryById("nonexistent", TEST_ROOM_ID);
|
227
|
+
expect(result).to.be.null;
|
228
|
+
});
|
229
|
+
});
|
230
|
+
});
|