@elizaos/core 1.5.1 → 1.5.2
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/browser/index.browser.js +120 -120
- package/dist/browser/index.browser.js.map +5 -21
- package/dist/browser/index.d.ts +3 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -5
- package/dist/node/index.d.ts +3 -1
- package/package.json +10 -4
- package/src/__tests__/action-chaining-simple.test.ts +203 -0
- package/src/__tests__/actions.test.ts +218 -0
- package/src/__tests__/buffer.test.ts +337 -0
- package/src/__tests__/character-validation.test.ts +309 -0
- package/src/__tests__/database.test.ts +750 -0
- package/src/__tests__/entities.test.ts +727 -0
- package/src/__tests__/env.test.ts +23 -0
- package/src/__tests__/environment.test.ts +285 -0
- package/src/__tests__/logger-browser-node.test.ts +716 -0
- package/src/__tests__/logger.test.ts +403 -0
- package/src/__tests__/messages.test.ts +196 -0
- package/src/__tests__/mockCharacter.ts +544 -0
- package/src/__tests__/parsing.test.ts +58 -0
- package/src/__tests__/prompts.test.ts +159 -0
- package/src/__tests__/roles.test.ts +331 -0
- package/src/__tests__/runtime-embedding.test.ts +343 -0
- package/src/__tests__/runtime.test.ts +978 -0
- package/src/__tests__/search.test.ts +15 -0
- package/src/__tests__/services-by-type.test.ts +204 -0
- package/src/__tests__/services.test.ts +136 -0
- package/src/__tests__/settings.test.ts +810 -0
- package/src/__tests__/utils.test.ts +1105 -0
- package/src/__tests__/uuid.test.ts +94 -0
- package/src/actions.ts +122 -0
- package/src/database.ts +579 -0
- package/src/entities.ts +406 -0
- package/src/index.browser.ts +48 -0
- package/src/index.node.ts +39 -0
- package/src/index.ts +50 -0
- package/src/logger.ts +527 -0
- package/src/prompts.ts +243 -0
- package/src/roles.ts +85 -0
- package/src/runtime.ts +2514 -0
- package/src/schemas/character.ts +149 -0
- package/src/search.ts +1543 -0
- package/src/sentry/instrument.browser.ts +65 -0
- package/src/sentry/instrument.node.ts +57 -0
- package/src/sentry/instrument.ts +82 -0
- package/src/services.ts +105 -0
- package/src/settings.ts +409 -0
- package/src/test_resources/constants.ts +12 -0
- package/src/test_resources/testSetup.ts +21 -0
- package/src/test_resources/types.ts +22 -0
- package/src/types/agent.ts +112 -0
- package/src/types/browser.ts +145 -0
- package/src/types/components.ts +184 -0
- package/src/types/database.ts +348 -0
- package/src/types/email.ts +162 -0
- package/src/types/environment.ts +129 -0
- package/src/types/events.ts +249 -0
- package/src/types/index.ts +29 -0
- package/src/types/knowledge.ts +65 -0
- package/src/types/lp.ts +124 -0
- package/src/types/memory.ts +228 -0
- package/src/types/message.ts +233 -0
- package/src/types/messaging.ts +57 -0
- package/src/types/model.ts +359 -0
- package/src/types/pdf.ts +77 -0
- package/src/types/plugin.ts +78 -0
- package/src/types/post.ts +271 -0
- package/src/types/primitives.ts +97 -0
- package/src/types/runtime.ts +190 -0
- package/src/types/service.ts +198 -0
- package/src/types/settings.ts +30 -0
- package/src/types/state.ts +60 -0
- package/src/types/task.ts +72 -0
- package/src/types/tee.ts +107 -0
- package/src/types/testing.ts +30 -0
- package/src/types/token.ts +96 -0
- package/src/types/transcription.ts +133 -0
- package/src/types/video.ts +108 -0
- package/src/types/wallet.ts +56 -0
- package/src/types/web-search.ts +146 -0
- package/src/utils/__tests__/buffer.test.ts +80 -0
- package/src/utils/__tests__/environment.test.ts +58 -0
- package/src/utils/__tests__/stringToUuid.test.ts +88 -0
- package/src/utils/buffer.ts +312 -0
- package/src/utils/environment.ts +316 -0
- package/src/utils/server-health.ts +117 -0
- package/src/utils.ts +1076 -0
- package/dist/tsconfig.build.tsbuildinfo +0 -1
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, mock } from 'bun:test';
|
|
2
|
+
import { AgentRuntime } from '../runtime.ts';
|
|
3
|
+
import { EventType, type Memory, type UUID } from '../types';
|
|
4
|
+
import { stringToUuid } from '../utils.ts';
|
|
5
|
+
|
|
6
|
+
describe('AgentRuntime - queueEmbeddingGeneration', () => {
|
|
7
|
+
let runtime: AgentRuntime;
|
|
8
|
+
let mockAdapter: any;
|
|
9
|
+
let emittedEvents: Array<{ event: string; payload: any }> = [];
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
emittedEvents = [];
|
|
13
|
+
|
|
14
|
+
// Create a mock database adapter
|
|
15
|
+
mockAdapter = {
|
|
16
|
+
init: mock().mockResolvedValue(undefined),
|
|
17
|
+
createAgent: mock().mockResolvedValue(true),
|
|
18
|
+
getAgent: mock().mockResolvedValue({
|
|
19
|
+
id: stringToUuid('test-agent'),
|
|
20
|
+
name: 'Test Agent',
|
|
21
|
+
}),
|
|
22
|
+
getAgents: mock().mockResolvedValue([]),
|
|
23
|
+
updateAgent: mock().mockResolvedValue(true),
|
|
24
|
+
createEntity: mock().mockResolvedValue(true),
|
|
25
|
+
getEntitiesByIds: mock().mockResolvedValue([]),
|
|
26
|
+
createEntities: mock().mockResolvedValue(true),
|
|
27
|
+
getParticipantsForRoom: mock().mockResolvedValue([]),
|
|
28
|
+
addParticipantsRoom: mock().mockResolvedValue(true),
|
|
29
|
+
createRoom: mock().mockResolvedValue(true),
|
|
30
|
+
createRooms: mock().mockResolvedValue([]),
|
|
31
|
+
getRoomsByIds: mock().mockResolvedValue([]),
|
|
32
|
+
createWorld: mock().mockResolvedValue(true),
|
|
33
|
+
getWorld: mock().mockResolvedValue(null),
|
|
34
|
+
ensureEmbeddingDimension: mock().mockResolvedValue(undefined),
|
|
35
|
+
log: mock().mockResolvedValue(undefined),
|
|
36
|
+
runMigrations: mock().mockResolvedValue(undefined),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Create runtime with test configuration
|
|
40
|
+
runtime = new AgentRuntime({
|
|
41
|
+
agentId: stringToUuid('test-agent'),
|
|
42
|
+
character: {
|
|
43
|
+
id: stringToUuid('test-character'),
|
|
44
|
+
name: 'Test Character',
|
|
45
|
+
username: 'test_character',
|
|
46
|
+
system: 'Test system prompt',
|
|
47
|
+
bio: 'Test bio',
|
|
48
|
+
},
|
|
49
|
+
adapter: mockAdapter,
|
|
50
|
+
conversationLength: 10,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Track emitted events
|
|
54
|
+
const originalEmitEvent = runtime.emitEvent.bind(runtime);
|
|
55
|
+
runtime.emitEvent = mock(async (event: string | string[], payload: any) => {
|
|
56
|
+
const events = Array.isArray(event) ? event : [event];
|
|
57
|
+
for (const e of events) {
|
|
58
|
+
emittedEvents.push({ event: e, payload });
|
|
59
|
+
}
|
|
60
|
+
return originalEmitEvent(event, payload);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('queueEmbeddingGeneration', () => {
|
|
65
|
+
it('should emit EMBEDDING_GENERATION_REQUESTED event for memory with text', async () => {
|
|
66
|
+
const memory: Memory = {
|
|
67
|
+
id: 'test-memory-id' as UUID,
|
|
68
|
+
entityId: 'test-entity' as UUID,
|
|
69
|
+
agentId: 'test-agent' as UUID,
|
|
70
|
+
roomId: 'test-room' as UUID,
|
|
71
|
+
content: { text: 'Test memory content' },
|
|
72
|
+
createdAt: Date.now(),
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
await runtime.queueEmbeddingGeneration(memory, 'normal');
|
|
76
|
+
|
|
77
|
+
const event = emittedEvents.find((e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED);
|
|
78
|
+
expect(event).toBeDefined();
|
|
79
|
+
expect(event?.payload).toMatchObject({
|
|
80
|
+
runtime,
|
|
81
|
+
memory,
|
|
82
|
+
priority: 'normal',
|
|
83
|
+
source: 'runtime',
|
|
84
|
+
retryCount: 0,
|
|
85
|
+
maxRetries: 3,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should skip memory that already has embeddings', async () => {
|
|
90
|
+
const memory: Memory = {
|
|
91
|
+
id: 'test-memory-id' as UUID,
|
|
92
|
+
entityId: 'test-entity' as UUID,
|
|
93
|
+
agentId: 'test-agent' as UUID,
|
|
94
|
+
roomId: 'test-room' as UUID,
|
|
95
|
+
content: { text: 'Test memory content' },
|
|
96
|
+
embedding: [0.1, 0.2, 0.3, 0.4, 0.5],
|
|
97
|
+
createdAt: Date.now(),
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
await runtime.queueEmbeddingGeneration(memory, 'normal');
|
|
101
|
+
|
|
102
|
+
const event = emittedEvents.find((e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED);
|
|
103
|
+
expect(event).toBeUndefined();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should skip memory without text content', async () => {
|
|
107
|
+
const memory: Memory = {
|
|
108
|
+
id: 'test-memory-id' as UUID,
|
|
109
|
+
entityId: 'test-entity' as UUID,
|
|
110
|
+
agentId: 'test-agent' as UUID,
|
|
111
|
+
roomId: 'test-room' as UUID,
|
|
112
|
+
content: {},
|
|
113
|
+
createdAt: Date.now(),
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
await runtime.queueEmbeddingGeneration(memory, 'normal');
|
|
117
|
+
|
|
118
|
+
const event = emittedEvents.find((e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED);
|
|
119
|
+
expect(event).toBeUndefined();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should support different priority levels', async () => {
|
|
123
|
+
const memories = [
|
|
124
|
+
{
|
|
125
|
+
memory: {
|
|
126
|
+
id: 'high-priority' as UUID,
|
|
127
|
+
entityId: 'test-entity' as UUID,
|
|
128
|
+
agentId: 'test-agent' as UUID,
|
|
129
|
+
roomId: 'test-room' as UUID,
|
|
130
|
+
content: { text: 'High priority content' },
|
|
131
|
+
createdAt: Date.now(),
|
|
132
|
+
},
|
|
133
|
+
priority: 'high' as const,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
memory: {
|
|
137
|
+
id: 'normal-priority' as UUID,
|
|
138
|
+
entityId: 'test-entity' as UUID,
|
|
139
|
+
agentId: 'test-agent' as UUID,
|
|
140
|
+
roomId: 'test-room' as UUID,
|
|
141
|
+
content: { text: 'Normal priority content' },
|
|
142
|
+
createdAt: Date.now(),
|
|
143
|
+
},
|
|
144
|
+
priority: 'normal' as const,
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
memory: {
|
|
148
|
+
id: 'low-priority' as UUID,
|
|
149
|
+
entityId: 'test-entity' as UUID,
|
|
150
|
+
agentId: 'test-agent' as UUID,
|
|
151
|
+
roomId: 'test-room' as UUID,
|
|
152
|
+
content: { text: 'Low priority content' },
|
|
153
|
+
createdAt: Date.now(),
|
|
154
|
+
},
|
|
155
|
+
priority: 'low' as const,
|
|
156
|
+
},
|
|
157
|
+
];
|
|
158
|
+
|
|
159
|
+
for (const { memory, priority } of memories) {
|
|
160
|
+
await runtime.queueEmbeddingGeneration(memory, priority);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const events = emittedEvents.filter(
|
|
164
|
+
(e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED
|
|
165
|
+
);
|
|
166
|
+
expect(events).toHaveLength(3);
|
|
167
|
+
|
|
168
|
+
expect(events[0].payload.priority).toBe('high');
|
|
169
|
+
expect(events[1].payload.priority).toBe('normal');
|
|
170
|
+
expect(events[2].payload.priority).toBe('low');
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('should use normal priority by default', async () => {
|
|
174
|
+
const memory: Memory = {
|
|
175
|
+
id: 'test-memory-id' as UUID,
|
|
176
|
+
entityId: 'test-entity' as UUID,
|
|
177
|
+
agentId: 'test-agent' as UUID,
|
|
178
|
+
roomId: 'test-room' as UUID,
|
|
179
|
+
content: { text: 'Default priority content' },
|
|
180
|
+
createdAt: Date.now(),
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
await runtime.queueEmbeddingGeneration(memory);
|
|
184
|
+
|
|
185
|
+
const event = emittedEvents.find((e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED);
|
|
186
|
+
expect(event?.payload.priority).toBe('normal');
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should be non-blocking', async () => {
|
|
190
|
+
const memory: Memory = {
|
|
191
|
+
id: 'test-memory-id' as UUID,
|
|
192
|
+
entityId: 'test-entity' as UUID,
|
|
193
|
+
agentId: 'test-agent' as UUID,
|
|
194
|
+
roomId: 'test-room' as UUID,
|
|
195
|
+
content: { text: 'Non-blocking test' },
|
|
196
|
+
createdAt: Date.now(),
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const startTime = Date.now();
|
|
200
|
+
await runtime.queueEmbeddingGeneration(memory, 'normal');
|
|
201
|
+
const elapsed = Date.now() - startTime;
|
|
202
|
+
|
|
203
|
+
// Should complete almost instantly (< 10ms)
|
|
204
|
+
expect(elapsed).toBeLessThan(10);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('should handle multiple queued embeddings efficiently', async () => {
|
|
208
|
+
const memories = Array.from({ length: 100 }, (_, i) => ({
|
|
209
|
+
id: `memory-${i}` as UUID,
|
|
210
|
+
entityId: 'test-entity' as UUID,
|
|
211
|
+
agentId: 'test-agent' as UUID,
|
|
212
|
+
roomId: 'test-room' as UUID,
|
|
213
|
+
content: { text: `Memory content ${i}` },
|
|
214
|
+
createdAt: Date.now(),
|
|
215
|
+
}));
|
|
216
|
+
|
|
217
|
+
const startTime = Date.now();
|
|
218
|
+
|
|
219
|
+
// Queue all memories
|
|
220
|
+
await Promise.all(
|
|
221
|
+
memories.map((memory) => runtime.queueEmbeddingGeneration(memory, 'normal'))
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const elapsed = Date.now() - startTime;
|
|
225
|
+
|
|
226
|
+
// Should complete very quickly even with 100 memories (< 50ms)
|
|
227
|
+
expect(elapsed).toBeLessThan(50);
|
|
228
|
+
|
|
229
|
+
// All events should be emitted
|
|
230
|
+
const events = emittedEvents.filter(
|
|
231
|
+
(e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED
|
|
232
|
+
);
|
|
233
|
+
expect(events).toHaveLength(100);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe('Integration with addEmbeddingToMemory', () => {
|
|
238
|
+
it('should work alongside synchronous embedding generation', async () => {
|
|
239
|
+
// Mock the useModel for synchronous embedding with a simulated delay
|
|
240
|
+
runtime.useModel = mock().mockImplementation(async (modelType: string) => {
|
|
241
|
+
if (modelType === 'TEXT_EMBEDDING') {
|
|
242
|
+
// Simulate a realistic embedding generation delay
|
|
243
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
244
|
+
return [0.1, 0.2, 0.3, 0.4, 0.5];
|
|
245
|
+
}
|
|
246
|
+
return Promise.resolve('mock response');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const syncMemory: Memory = {
|
|
250
|
+
id: 'sync-memory' as UUID,
|
|
251
|
+
entityId: 'test-entity' as UUID,
|
|
252
|
+
agentId: 'test-agent' as UUID,
|
|
253
|
+
roomId: 'test-room' as UUID,
|
|
254
|
+
content: { text: 'Synchronous embedding' },
|
|
255
|
+
createdAt: Date.now(),
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const asyncMemory: Memory = {
|
|
259
|
+
id: 'async-memory' as UUID,
|
|
260
|
+
entityId: 'test-entity' as UUID,
|
|
261
|
+
agentId: 'test-agent' as UUID,
|
|
262
|
+
roomId: 'test-room' as UUID,
|
|
263
|
+
content: { text: 'Asynchronous embedding' },
|
|
264
|
+
createdAt: Date.now(),
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// Synchronous embedding (blocking - will wait for the delay)
|
|
268
|
+
const startSync = Date.now();
|
|
269
|
+
const resultSync = await runtime.addEmbeddingToMemory(syncMemory);
|
|
270
|
+
const elapsedSync = Date.now() - startSync;
|
|
271
|
+
|
|
272
|
+
// Asynchronous embedding (non-blocking - just queues)
|
|
273
|
+
const startAsync = Date.now();
|
|
274
|
+
await runtime.queueEmbeddingGeneration(asyncMemory, 'normal');
|
|
275
|
+
const elapsedAsync = Date.now() - startAsync;
|
|
276
|
+
|
|
277
|
+
// Sync should have embeddings immediately
|
|
278
|
+
expect(resultSync.embedding).toBeDefined();
|
|
279
|
+
expect(resultSync.embedding).toEqual([0.1, 0.2, 0.3, 0.4, 0.5]);
|
|
280
|
+
|
|
281
|
+
// Async should be much faster (just queuing, no waiting)
|
|
282
|
+
expect(elapsedAsync).toBeLessThan(elapsedSync);
|
|
283
|
+
|
|
284
|
+
// Verify that sync took at least the simulated delay
|
|
285
|
+
expect(elapsedSync).toBeGreaterThanOrEqual(5);
|
|
286
|
+
|
|
287
|
+
// Event should be emitted for async
|
|
288
|
+
const event = emittedEvents.find((e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED);
|
|
289
|
+
expect(event).toBeDefined();
|
|
290
|
+
expect(event?.payload.memory.id).toBe('async-memory');
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
describe('Error Handling', () => {
|
|
295
|
+
it('should handle null or undefined memory gracefully', async () => {
|
|
296
|
+
// Test with undefined
|
|
297
|
+
await runtime.queueEmbeddingGeneration(undefined as any, 'normal');
|
|
298
|
+
|
|
299
|
+
// Test with null
|
|
300
|
+
await runtime.queueEmbeddingGeneration(null as any, 'normal');
|
|
301
|
+
|
|
302
|
+
// No events should be emitted
|
|
303
|
+
const events = emittedEvents.filter(
|
|
304
|
+
(e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED
|
|
305
|
+
);
|
|
306
|
+
expect(events).toHaveLength(0);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('should handle memory with null content gracefully', async () => {
|
|
310
|
+
const memory: Memory = {
|
|
311
|
+
id: 'null-content' as UUID,
|
|
312
|
+
entityId: 'test-entity' as UUID,
|
|
313
|
+
agentId: 'test-agent' as UUID,
|
|
314
|
+
roomId: 'test-room' as UUID,
|
|
315
|
+
content: null as any,
|
|
316
|
+
createdAt: Date.now(),
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
await runtime.queueEmbeddingGeneration(memory, 'normal');
|
|
320
|
+
|
|
321
|
+
// No event should be emitted
|
|
322
|
+
const event = emittedEvents.find((e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED);
|
|
323
|
+
expect(event).toBeUndefined();
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it('should handle empty text content gracefully', async () => {
|
|
327
|
+
const memory: Memory = {
|
|
328
|
+
id: 'empty-text' as UUID,
|
|
329
|
+
entityId: 'test-entity' as UUID,
|
|
330
|
+
agentId: 'test-agent' as UUID,
|
|
331
|
+
roomId: 'test-room' as UUID,
|
|
332
|
+
content: { text: '' },
|
|
333
|
+
createdAt: Date.now(),
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
await runtime.queueEmbeddingGeneration(memory, 'normal');
|
|
337
|
+
|
|
338
|
+
// No event should be emitted for empty text
|
|
339
|
+
const event = emittedEvents.find((e) => e.event === EventType.EMBEDDING_GENERATION_REQUESTED);
|
|
340
|
+
expect(event).toBeUndefined();
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
});
|