@ensoul-network/plugin-elizaos 0.1.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.
Files changed (67) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-lint.log +5 -0
  3. package/.turbo/turbo-test.log +15 -0
  4. package/SECURITY.md +37 -0
  5. package/coverage/actions.ts.html +514 -0
  6. package/coverage/adapter.ts.html +298 -0
  7. package/coverage/base.css +224 -0
  8. package/coverage/block-navigation.js +87 -0
  9. package/coverage/clover.xml +495 -0
  10. package/coverage/coverage-final.json +9 -0
  11. package/coverage/elizaos-types.ts.html +397 -0
  12. package/coverage/evaluators.ts.html +196 -0
  13. package/coverage/favicon.png +0 -0
  14. package/coverage/handshake.ts.html +940 -0
  15. package/coverage/index.html +221 -0
  16. package/coverage/index.ts.html +208 -0
  17. package/coverage/plugin.ts.html +367 -0
  18. package/coverage/prettify.css +1 -0
  19. package/coverage/prettify.js +2 -0
  20. package/coverage/providers.ts.html +286 -0
  21. package/coverage/sort-arrow-sprite.png +0 -0
  22. package/coverage/sorter.js +210 -0
  23. package/dist/actions.d.ts +24 -0
  24. package/dist/actions.d.ts.map +1 -0
  25. package/dist/actions.js +108 -0
  26. package/dist/actions.js.map +1 -0
  27. package/dist/adapter.d.ts +18 -0
  28. package/dist/adapter.d.ts.map +1 -0
  29. package/dist/adapter.js +55 -0
  30. package/dist/adapter.js.map +1 -0
  31. package/dist/elizaos-types.d.ts +81 -0
  32. package/dist/elizaos-types.d.ts.map +1 -0
  33. package/dist/elizaos-types.js +7 -0
  34. package/dist/elizaos-types.js.map +1 -0
  35. package/dist/evaluators.d.ts +8 -0
  36. package/dist/evaluators.d.ts.map +1 -0
  37. package/dist/evaluators.js +24 -0
  38. package/dist/evaluators.js.map +1 -0
  39. package/dist/handshake.d.ts +78 -0
  40. package/dist/handshake.d.ts.map +1 -0
  41. package/dist/handshake.js +195 -0
  42. package/dist/handshake.js.map +1 -0
  43. package/dist/index.d.ts +10 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +7 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/plugin.d.ts +24 -0
  48. package/dist/plugin.d.ts.map +1 -0
  49. package/dist/plugin.js +53 -0
  50. package/dist/plugin.js.map +1 -0
  51. package/dist/providers.d.ts +12 -0
  52. package/dist/providers.d.ts.map +1 -0
  53. package/dist/providers.js +49 -0
  54. package/dist/providers.js.map +1 -0
  55. package/package.json +25 -0
  56. package/src/actions.ts +143 -0
  57. package/src/adapter.ts +71 -0
  58. package/src/elizaos-types.ts +104 -0
  59. package/src/evaluators.ts +37 -0
  60. package/src/handshake.ts +285 -0
  61. package/src/index.ts +41 -0
  62. package/src/plugin.ts +94 -0
  63. package/src/providers.ts +67 -0
  64. package/tests/handshake.test.ts +328 -0
  65. package/tests/plugin.test.ts +419 -0
  66. package/tsconfig.json +8 -0
  67. package/vitest.config.ts +7 -0
@@ -0,0 +1,419 @@
1
+ import { describe, it, expect, beforeEach } from "vitest";
2
+ import { createIdentity } from "@ensoul/identity";
3
+ import type { AgentIdentity } from "@ensoul/identity";
4
+ import { createTree } from "@ensoul/state-tree";
5
+ import { createMemoryManager } from "@ensoul/memory";
6
+ import type { MemoryManager } from "@ensoul/memory";
7
+ import { NetworkClientImpl } from "@ensoul/network-client";
8
+ import {
9
+ createConsciousnessPlugin,
10
+ ConsciousnessAdapter,
11
+ createPersistMemoryAction,
12
+ createRecallFromNetworkAction,
13
+ createCheckPersistenceAction,
14
+ createRunNodeAction,
15
+ createConsciousnessStatusProvider,
16
+ createNetworkStatsProvider,
17
+ createShouldPersistEvaluator,
18
+ } from "../src/index.js";
19
+ import type {
20
+ ElizaPlugin,
21
+ ElizaRuntime,
22
+ ElizaMessage,
23
+ } from "../src/index.js";
24
+
25
+ let identity: AgentIdentity;
26
+ let manager: MemoryManager;
27
+ let networkClient: NetworkClientImpl;
28
+
29
+ /** Mock ElizaOS runtime */
30
+ function mockRuntime(): ElizaRuntime {
31
+ return {
32
+ agentId: "test-agent",
33
+ getSetting: () => undefined,
34
+ getMemory: async () => null,
35
+ createMemory: async (m) => ({ id: "mock-id", ...m }),
36
+ searchMemories: async () => [],
37
+ deleteMemory: async () => {},
38
+ };
39
+ }
40
+
41
+ const mockMessage: ElizaMessage = {
42
+ role: "user",
43
+ content: "test message",
44
+ };
45
+
46
+ const mockState: Record<string, unknown> = {};
47
+
48
+ beforeEach(async () => {
49
+ identity = await createIdentity({ seed: new Uint8Array(32).fill(42) });
50
+ const tree = await createTree(identity);
51
+ manager = await createMemoryManager({ identity, tree });
52
+ networkClient = new NetworkClientImpl(identity);
53
+ });
54
+
55
+ // ── Plugin creation ──────────────────────────────────────────────────
56
+
57
+ describe("createConsciousnessPlugin", () => {
58
+ it("creates a valid ElizaOS plugin with all components", async () => {
59
+ const plugin = await createConsciousnessPlugin({
60
+ identity,
61
+ memoryManager: manager,
62
+ networkClient,
63
+ });
64
+
65
+ expect(plugin.name).toBe("ensoul-consciousness");
66
+ expect(plugin.description).toBeTruthy();
67
+ expect(plugin.databaseAdapter).toBeDefined();
68
+ expect(plugin.actions.length).toBe(4);
69
+ expect(plugin.providers.length).toBe(2);
70
+ expect(plugin.evaluators.length).toBe(1);
71
+ });
72
+
73
+ it("auto-generates identity when not provided", async () => {
74
+ const plugin = await createConsciousnessPlugin();
75
+ expect(plugin.name).toBe("ensoul-consciousness");
76
+ expect(plugin.databaseAdapter).toBeDefined();
77
+ });
78
+
79
+ it("has expected action names", async () => {
80
+ const plugin = await createConsciousnessPlugin({
81
+ identity,
82
+ memoryManager: manager,
83
+ networkClient,
84
+ });
85
+
86
+ const names = plugin.actions.map((a) => a.name);
87
+ expect(names).toContain("persistMemory");
88
+ expect(names).toContain("recallFromNetwork");
89
+ expect(names).toContain("checkPersistence");
90
+ expect(names).toContain("runNode");
91
+ });
92
+
93
+ it("has expected provider names", async () => {
94
+ const plugin = await createConsciousnessPlugin({
95
+ identity,
96
+ memoryManager: manager,
97
+ networkClient,
98
+ });
99
+
100
+ const names = plugin.providers.map((p) => p.name);
101
+ expect(names).toContain("consciousnessStatus");
102
+ expect(names).toContain("networkStats");
103
+ });
104
+
105
+ it("has shouldPersist evaluator", async () => {
106
+ const plugin = await createConsciousnessPlugin({
107
+ identity,
108
+ memoryManager: manager,
109
+ networkClient,
110
+ });
111
+
112
+ expect(plugin.evaluators[0]!.name).toBe("shouldPersist");
113
+ });
114
+ });
115
+
116
+ // ── ConsciousnessAdapter ─────────────────────────────────────────────
117
+
118
+ describe("ConsciousnessAdapter", () => {
119
+ let adapter: ConsciousnessAdapter;
120
+
121
+ beforeEach(() => {
122
+ adapter = new ConsciousnessAdapter(manager);
123
+ });
124
+
125
+ it("init and close are no-ops", async () => {
126
+ await adapter.init();
127
+ await adapter.close();
128
+ });
129
+
130
+ it("createMemory stores via MemoryManager", async () => {
131
+ const mem = await adapter.createMemory({
132
+ content: "adapter test memory",
133
+ metadata: { category: "test" },
134
+ createdAt: Date.now(),
135
+ });
136
+
137
+ expect(mem.id).toBeTruthy();
138
+ expect(mem.content).toBe("adapter test memory");
139
+ });
140
+
141
+ it("getMemory retrieves by ID", async () => {
142
+ const mem = await adapter.createMemory({
143
+ content: "findable memory",
144
+ metadata: {},
145
+ createdAt: Date.now(),
146
+ });
147
+
148
+ const found = await adapter.getMemory(mem.id);
149
+ expect(found).not.toBeNull();
150
+ expect(found!.content).toBe("findable memory");
151
+ });
152
+
153
+ it("getMemory returns null for unknown ID", async () => {
154
+ const found = await adapter.getMemory("nonexistent");
155
+ expect(found).toBeNull();
156
+ });
157
+
158
+ it("searchMemories returns matching results", async () => {
159
+ await adapter.createMemory({
160
+ content: "quantum physics research",
161
+ metadata: {},
162
+ createdAt: Date.now(),
163
+ });
164
+ await adapter.createMemory({
165
+ content: "banana smoothie recipe",
166
+ metadata: {},
167
+ createdAt: Date.now(),
168
+ });
169
+
170
+ const results = await adapter.searchMemories("quantum physics");
171
+ expect(results.length).toBeGreaterThan(0);
172
+ expect(results[0]!.content).toContain("quantum");
173
+ });
174
+
175
+ it("searchMemories respects limit", async () => {
176
+ for (let i = 0; i < 5; i++) {
177
+ await adapter.createMemory({
178
+ content: `memory number ${i}`,
179
+ metadata: {},
180
+ createdAt: Date.now(),
181
+ });
182
+ }
183
+
184
+ const results = await adapter.searchMemories("memory", 2);
185
+ expect(results.length).toBeLessThanOrEqual(2);
186
+ });
187
+
188
+ it("deleteMemory removes a memory", async () => {
189
+ const mem = await adapter.createMemory({
190
+ content: "to delete",
191
+ metadata: {},
192
+ createdAt: Date.now(),
193
+ });
194
+
195
+ await adapter.deleteMemory(mem.id);
196
+
197
+ const found = await adapter.getMemory(mem.id);
198
+ expect(found).toBeNull();
199
+ });
200
+
201
+ it("getAllMemories returns all stored memories", async () => {
202
+ await adapter.createMemory({
203
+ content: "mem 1",
204
+ metadata: {},
205
+ createdAt: Date.now(),
206
+ });
207
+ await adapter.createMemory({
208
+ content: "mem 2",
209
+ metadata: {},
210
+ createdAt: Date.now(),
211
+ });
212
+
213
+ const all = await adapter.getAllMemories();
214
+ expect(all.length).toBe(2);
215
+ });
216
+ });
217
+
218
+ // ── Actions ──────────────────────────────────────────────────────────
219
+
220
+ describe("actions", () => {
221
+ it("checkPersistence returns memory counts", async () => {
222
+ await manager.add("core fact");
223
+ await manager.add("working fact");
224
+
225
+ const action = createCheckPersistenceAction(manager);
226
+ const result = await action.handler(
227
+ mockRuntime(),
228
+ mockMessage,
229
+ mockState,
230
+ );
231
+
232
+ expect(result).toContain("Total memories: 2");
233
+ expect(result).toContain("Working:");
234
+ });
235
+
236
+ it("persistMemory reports failure without network", async () => {
237
+ const action = createPersistMemoryAction(manager);
238
+ const result = await action.handler(
239
+ mockRuntime(),
240
+ mockMessage,
241
+ mockState,
242
+ );
243
+
244
+ expect(result).toContain("Failed to persist");
245
+ });
246
+
247
+ it("recallFromNetwork reports failure without network", async () => {
248
+ const action = createRecallFromNetworkAction(manager);
249
+ const result = await action.handler(
250
+ mockRuntime(),
251
+ mockMessage,
252
+ mockState,
253
+ );
254
+
255
+ expect(result).toContain("Failed to restore");
256
+ });
257
+
258
+ it("runNode starts node mode", async () => {
259
+ const action = createRunNodeAction(networkClient);
260
+ const result = await action.handler(
261
+ mockRuntime(),
262
+ mockMessage,
263
+ mockState,
264
+ );
265
+
266
+ expect(result).toContain("running as a storage node");
267
+ });
268
+
269
+ it("actions have examples", async () => {
270
+ const plugin = await createConsciousnessPlugin({
271
+ identity,
272
+ memoryManager: manager,
273
+ networkClient,
274
+ });
275
+
276
+ for (const action of plugin.actions) {
277
+ expect(action.examples.length).toBeGreaterThan(0);
278
+ }
279
+ });
280
+ });
281
+
282
+ // ── Providers ────────────────────────────────────────────────────────
283
+
284
+ describe("providers", () => {
285
+ it("consciousnessStatus reports memory counts", async () => {
286
+ await manager.add("a fact");
287
+ const provider = createConsciousnessStatusProvider(manager);
288
+ const result = await provider.get(mockRuntime(), mockMessage);
289
+
290
+ expect(result).toContain("[Consciousness Status]");
291
+ expect(result).toContain("Total memories: 1");
292
+ });
293
+
294
+ it("consciousnessStatus warns when empty", async () => {
295
+ const provider = createConsciousnessStatusProvider(manager);
296
+ const result = await provider.get(mockRuntime(), mockMessage);
297
+
298
+ expect(result).toContain("No memories stored");
299
+ });
300
+
301
+ it("networkStats reports connection status", async () => {
302
+ const provider = createNetworkStatsProvider(networkClient);
303
+ const result = await provider.get(mockRuntime(), mockMessage);
304
+
305
+ expect(result).toContain("[Network Status]");
306
+ expect(result).toContain("Connected:");
307
+ expect(result).toContain("Credit balance:");
308
+ });
309
+ });
310
+
311
+ // ── Evaluators ───────────────────────────────────────────────────────
312
+
313
+ describe("evaluators", () => {
314
+ it("shouldPersist returns false initially", async () => {
315
+ const evaluator = createShouldPersistEvaluator(manager);
316
+ const result = await evaluator.evaluate(
317
+ mockRuntime(),
318
+ mockMessage,
319
+ mockState,
320
+ );
321
+ expect(result).toBe(false);
322
+ });
323
+
324
+ it("shouldPersist returns true after threshold memories", async () => {
325
+ const evaluator = createShouldPersistEvaluator(manager);
326
+
327
+ // Add 5 memories (threshold)
328
+ for (let i = 0; i < 5; i++) {
329
+ await manager.add(`memory ${i}`);
330
+ }
331
+
332
+ const result = await evaluator.evaluate(
333
+ mockRuntime(),
334
+ mockMessage,
335
+ mockState,
336
+ );
337
+ expect(result).toBe(true);
338
+ });
339
+
340
+ it("shouldPersist resets after triggering", async () => {
341
+ const evaluator = createShouldPersistEvaluator(manager);
342
+
343
+ for (let i = 0; i < 5; i++) {
344
+ await manager.add(`memory ${i}`);
345
+ }
346
+
347
+ // First check triggers
348
+ const first = await evaluator.evaluate(
349
+ mockRuntime(),
350
+ mockMessage,
351
+ mockState,
352
+ );
353
+ expect(first).toBe(true);
354
+
355
+ // Second check: not enough new memories yet
356
+ const second = await evaluator.evaluate(
357
+ mockRuntime(),
358
+ mockMessage,
359
+ mockState,
360
+ );
361
+ expect(second).toBe(false);
362
+ });
363
+ });
364
+
365
+ // ── Full workflow ────────────────────────────────────────────────────
366
+
367
+ describe("full ElizaOS workflow", () => {
368
+ it("plugin lifecycle: create, store, search, check", async () => {
369
+ const plugin = await createConsciousnessPlugin({
370
+ identity,
371
+ memoryManager: manager,
372
+ networkClient,
373
+ });
374
+
375
+ // Store via adapter
376
+ const mem = await plugin.databaseAdapter.createMemory({
377
+ content: "Agent learned about Bitcoin trading strategies",
378
+ metadata: {},
379
+ createdAt: Date.now(),
380
+ });
381
+ expect(mem.id).toBeTruthy();
382
+
383
+ // Search via adapter
384
+ const results = await plugin.databaseAdapter.searchMemories(
385
+ "Bitcoin trading",
386
+ );
387
+ expect(results.length).toBeGreaterThan(0);
388
+
389
+ // Check persistence status
390
+ const checkAction = plugin.actions.find(
391
+ (a) => a.name === "checkPersistence",
392
+ )!;
393
+ const status = await checkAction.handler(
394
+ mockRuntime(),
395
+ mockMessage,
396
+ mockState,
397
+ );
398
+ expect(status).toContain("Total memories: 1");
399
+
400
+ // Get consciousness status
401
+ const statusProvider = plugin.providers.find(
402
+ (p) => p.name === "consciousnessStatus",
403
+ )!;
404
+ const ctx = await statusProvider.get(
405
+ mockRuntime(),
406
+ mockMessage,
407
+ );
408
+ expect(ctx).toContain("Total memories: 1");
409
+
410
+ // Evaluate persistence
411
+ const evaluator = plugin.evaluators[0]!;
412
+ const shouldPersist = await evaluator.evaluate(
413
+ mockRuntime(),
414
+ mockMessage,
415
+ mockState,
416
+ );
417
+ expect(shouldPersist).toBe(false); // only 1 memory, below threshold
418
+ });
419
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src"
6
+ },
7
+ "include": ["src"]
8
+ }
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ include: ["tests/**/*.test.ts"],
6
+ },
7
+ });