@ai.ntellect/core 0.6.16 → 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.
Files changed (83) hide show
  1. package/.mocharc.json +1 -2
  2. package/README.md +123 -178
  3. package/dist/graph/controller.js +29 -6
  4. package/dist/graph/index.js +402 -0
  5. package/dist/index.js +22 -7
  6. package/dist/interfaces/index.js +15 -0
  7. package/dist/modules/agenda/adapters/node-cron/index.js +29 -0
  8. package/dist/modules/agenda/index.js +140 -0
  9. package/dist/{services/embedding.js → modules/embedding/adapters/ai/index.js} +24 -7
  10. package/dist/modules/embedding/index.js +59 -0
  11. package/dist/modules/memory/adapters/in-memory/index.js +210 -0
  12. package/dist/{memory → modules/memory}/adapters/meilisearch/index.js +97 -2
  13. package/dist/{memory → modules/memory}/adapters/redis/index.js +77 -15
  14. package/dist/modules/memory/index.js +103 -0
  15. package/dist/utils/{stringifiy-zod-schema.js → generate-action-schema.js} +5 -5
  16. package/graph/controller.ts +38 -14
  17. package/graph/index.ts +468 -0
  18. package/index.ts +25 -7
  19. package/interfaces/index.ts +346 -28
  20. package/modules/agenda/adapters/node-cron/index.ts +25 -0
  21. package/modules/agenda/index.ts +159 -0
  22. package/modules/embedding/adapters/ai/index.ts +42 -0
  23. package/modules/embedding/index.ts +45 -0
  24. package/modules/memory/adapters/in-memory/index.ts +203 -0
  25. package/{memory → modules/memory}/adapters/meilisearch/index.ts +114 -8
  26. package/modules/memory/adapters/redis/index.ts +164 -0
  27. package/modules/memory/index.ts +93 -0
  28. package/package.json +4 -4
  29. package/test/graph/index.test.ts +646 -0
  30. package/test/modules/agenda/node-cron.test.ts +286 -0
  31. package/test/modules/embedding/ai.test.ts +78 -0
  32. package/test/modules/memory/adapters/in-memory.test.ts +153 -0
  33. package/test/{memory → modules/memory}/adapters/meilisearch.test.ts +80 -94
  34. package/test/modules/memory/adapters/redis.test.ts +169 -0
  35. package/test/modules/memory/base.test.ts +230 -0
  36. package/test/services/agenda.test.ts +279 -280
  37. package/tsconfig.json +0 -3
  38. package/types/index.ts +82 -203
  39. package/utils/{stringifiy-zod-schema.ts → generate-action-schema.ts} +3 -3
  40. package/app/README.md +0 -36
  41. package/app/app/favicon.ico +0 -0
  42. package/app/app/globals.css +0 -21
  43. package/app/app/gun.ts +0 -0
  44. package/app/app/layout.tsx +0 -18
  45. package/app/app/page.tsx +0 -321
  46. package/app/eslint.config.mjs +0 -16
  47. package/app/next.config.ts +0 -7
  48. package/app/package-lock.json +0 -5912
  49. package/app/package.json +0 -31
  50. package/app/pnpm-lock.yaml +0 -4031
  51. package/app/postcss.config.mjs +0 -8
  52. package/app/public/file.svg +0 -1
  53. package/app/public/globe.svg +0 -1
  54. package/app/public/next.svg +0 -1
  55. package/app/public/vercel.svg +0 -1
  56. package/app/public/window.svg +0 -1
  57. package/app/tailwind.config.ts +0 -18
  58. package/app/tsconfig.json +0 -27
  59. package/dist/graph/graph.js +0 -162
  60. package/dist/memory/index.js +0 -9
  61. package/dist/services/agenda.js +0 -115
  62. package/dist/services/queue.js +0 -142
  63. package/dist/utils/experimental-graph-rag.js +0 -152
  64. package/dist/utils/generate-object.js +0 -111
  65. package/dist/utils/inject-actions.js +0 -16
  66. package/dist/utils/queue-item-transformer.js +0 -24
  67. package/dist/utils/sanitize-results.js +0 -60
  68. package/graph/graph.ts +0 -193
  69. package/memory/adapters/redis/index.ts +0 -103
  70. package/memory/index.ts +0 -22
  71. package/services/agenda.ts +0 -118
  72. package/services/embedding.ts +0 -26
  73. package/services/queue.ts +0 -145
  74. package/test/.env.test +0 -4
  75. package/test/graph/engine.test.ts +0 -533
  76. package/test/memory/adapters/redis.test.ts +0 -160
  77. package/test/memory/base.test.ts +0 -229
  78. package/test/services/queue.test.ts +0 -286
  79. package/utils/experimental-graph-rag.ts +0 -170
  80. package/utils/generate-object.ts +0 -117
  81. package/utils/inject-actions.ts +0 -19
  82. package/utils/queue-item-transformer.ts +0 -38
  83. package/utils/sanitize-results.ts +0 -66
@@ -1,117 +1,72 @@
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();
9
8
 
10
9
  describe("MeilisearchAdapter", () => {
11
10
  let meilisearchAdapter: MeilisearchAdapter;
12
- let mockBaseMemoryService: BaseMemoryService;
13
11
  const TEST_ROOM_ID = "test-room";
14
12
 
15
13
  const testMemory: BaseMemoryType = {
16
14
  id: "test-id",
17
15
  data: "test data",
18
- query: "test query",
19
- embedding: [0.1, 0.2, 0.3],
20
16
  roomId: "test-room",
21
17
  createdAt: new Date(),
22
18
  };
23
19
 
24
- beforeEach(() => {
25
- // Use real Meilisearch if environment variables are set, otherwise mock
26
- if (process.env.MEILISEARCH_HOST && process.env.MEILISEARCH_API_KEY) {
27
- // Real Meilisearch configuration
28
- // console.log("Real Meilisearch configuration");
29
- meilisearchAdapter = new MeilisearchAdapter(
30
- {
31
- host: process.env.MEILISEARCH_HOST,
32
- apiKey: process.env.MEILISEARCH_API_KEY,
33
- searchableAttributes: ["content"],
34
- sortableAttributes: ["createdAt"],
35
- },
36
- mockBaseMemoryService
37
- );
38
- } else {
39
- // Mock fetch implementation
40
- // console.log("Mock Meilisearch configuration");
41
- global.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
42
- const url = input.toString();
20
+ beforeEach(async function () {
21
+ this.timeout(10000); // Augmenter le timeout
43
22
 
44
- // Mock for index check/creation
45
- if (url.includes("/indexes")) {
46
- if (init?.method === "POST") {
47
- return new Response(JSON.stringify({ taskUid: 1 }));
48
- }
49
- if (url.endsWith("/indexes")) {
50
- return new Response(JSON.stringify({ results: [] }));
51
- }
52
- // Mock for specific index check
53
- if (url.includes(`/indexes/${TEST_ROOM_ID}`)) {
54
- return new Response(
55
- JSON.stringify({
56
- uid: TEST_ROOM_ID,
57
- primaryKey: "id",
58
- })
59
- );
60
- }
61
- if (url.includes("/indexes/memories")) {
62
- return new Response(
63
- JSON.stringify({
64
- uid: "memories",
65
- primaryKey: "id",
66
- })
67
- );
68
- }
69
- }
23
+ // Mock fetch pour simuler l'existence de l'index
24
+ global.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
25
+ const url = input.toString();
70
26
 
71
- // Mock for settings
72
- if (url.includes("/settings")) {
73
- return new Response(JSON.stringify({ acknowledged: true }));
27
+ // Mock pour index check/creation
28
+ if (url.includes("/indexes")) {
29
+ if (init?.method === "POST") {
30
+ return new Response(JSON.stringify({ taskUid: 1 }));
74
31
  }
75
-
76
- // Mock for documents
77
- if (url.includes("/documents")) {
78
- if (init?.method === "POST") {
79
- return new Response(JSON.stringify({ taskUid: 2 }));
80
- }
81
- if (init?.method === "DELETE") {
82
- return new Response(JSON.stringify({ taskUid: 3 }));
83
- }
84
- 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
+ );
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
+ );
85
46
  }
47
+ }
86
48
 
87
- return new Response(JSON.stringify({}));
88
- };
49
+ // Mock pour settings et autres endpoints
50
+ if (url.includes("/settings")) {
51
+ return new Response(JSON.stringify({ acknowledged: true }));
52
+ }
89
53
 
90
- mockBaseMemoryService = {
91
- initializeConnection: async () => {},
92
- createMemory: async () => {},
93
- getMemoryById: async () => testMemory,
94
- getMemoryByIndex: async () => [testMemory],
95
- getAllMemories: async () => [testMemory],
96
- clearMemoryById: async () => {},
97
- clearAllMemories: async () => {},
98
- };
54
+ return new Response(JSON.stringify({}));
55
+ };
99
56
 
100
- meilisearchAdapter = new MeilisearchAdapter(
101
- {
102
- host: "http://localhost:7700",
103
- apiKey: "aSampleMasterKey",
104
- searchableAttributes: ["content"],
105
- sortableAttributes: ["createdAt"],
106
- },
107
- mockBaseMemoryService
108
- );
109
- }
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);
110
65
  });
111
66
 
112
67
  describe("Initialization", () => {
113
68
  it("should initialize storage", async () => {
114
- await expect(meilisearchAdapter.init()).to.not.throw;
69
+ await expect(meilisearchAdapter.init("test-room")).to.not.throw;
115
70
  });
116
71
  });
117
72
 
@@ -170,7 +125,7 @@ describe("MeilisearchAdapter", () => {
170
125
  }
171
126
 
172
127
  try {
173
- await meilisearchAdapter.init();
128
+ await meilisearchAdapter.init(TEST_ROOM_ID);
174
129
  await meilisearchAdapter.initializeStorage(TEST_ROOM_ID);
175
130
  } catch (error) {
176
131
  console.error("Failed to initialize:", error);
@@ -181,7 +136,6 @@ describe("MeilisearchAdapter", () => {
181
136
  it("should create memory", async () => {
182
137
  const result = await meilisearchAdapter.createMemory({
183
138
  data: "test data",
184
- query: "test query",
185
139
  roomId: TEST_ROOM_ID,
186
140
  });
187
141
 
@@ -243,28 +197,60 @@ describe("MeilisearchAdapter", () => {
243
197
  });
244
198
 
245
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);
246
202
  await expect(meilisearchAdapter.clearAllMemories()).to.not.throw;
247
203
  });
248
204
 
249
205
  it("should not create duplicate memory with same data", async () => {
250
- // Create first memory
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
+
251
242
  const firstMemory = await meilisearchAdapter.createMemory({
252
243
  data: "test data",
253
- query: "test query",
254
244
  roomId: TEST_ROOM_ID,
255
245
  });
256
246
 
257
- // Try to create second memory with same data
258
247
  const secondMemory = await meilisearchAdapter.createMemory({
259
248
  data: "test data",
260
- query: "test query",
261
249
  roomId: TEST_ROOM_ID,
262
250
  });
263
251
 
264
- expect(secondMemory).to.exist;
265
252
  expect(secondMemory?.id).to.equal(firstMemory?.id);
266
253
  expect(secondMemory?.data).to.equal(firstMemory?.data);
267
- expect(secondMemory?.query).to.equal(firstMemory?.query);
268
254
  expect(secondMemory?.roomId).to.equal(firstMemory?.roomId);
269
255
  });
270
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
+ });