@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,4 @@
1
+
2
+ > @ensoul/plugin-elizaos@0.1.0 build /Users/suitandclaw/ensoul/packages/plugin-elizaos
3
+ > tsc
4
+
@@ -0,0 +1,5 @@
1
+
2
+ > @ensoul/plugin-elizaos@0.1.0 lint /Users/suitandclaw/ensoul/packages/plugin-elizaos
3
+ > biome check .
4
+
5
+ Checked 5 files in 2ms. No fixes applied.
@@ -0,0 +1,15 @@
1
+
2
+ > @ensoul/plugin-elizaos@0.1.0 test /Users/suitandclaw/ensoul/packages/plugin-elizaos
3
+ > vitest run
4
+
5
+
6
+ RUN v2.1.9 /Users/suitandclaw/ensoul/packages/plugin-elizaos
7
+
8
+ ✓ tests/handshake.test.ts (20 tests) 108ms
9
+ ✓ tests/plugin.test.ts (25 tests) 109ms
10
+
11
+ Test Files 2 passed (2)
12
+ Tests 45 passed (45)
13
+ Start at 23:12:33
14
+ Duration 921ms (transform 164ms, setup 0ms, collect 566ms, tests 217ms, environment 0ms, prepare 143ms)
15
+
package/SECURITY.md ADDED
@@ -0,0 +1,37 @@
1
+ # Security: @ensoul/plugin-elizaos
2
+
3
+ ## Threat Model
4
+
5
+ The ElizaOS plugin is the primary integration surface — it bridges the ElizaOS agent framework with the Ensoul consciousness network. Since it wraps @ensoul/memory and @ensoul/network-client, its security posture inherits from those modules. The plugin's own threats are around configuration, access control, and the adapter boundary.
6
+
7
+ **Trust boundary:** The plugin trusts the ElizaOS runtime, @ensoul/identity, @ensoul/memory, and @ensoul/network-client. It does NOT trust conversation input (processed by the extraction pipeline) or network-retrieved state (verified by the state tree).
8
+
9
+ ## Attack Vectors & Mitigations
10
+
11
+ **Misconfigured Bootstrap Peers:** Agent connects to malicious bootstrap peers.
12
+ *Mitigation:* Network transport uses Noise encryption. Shard data is agent-encrypted before transmission. Malicious peers cannot read or forge data. Bootstrap peers should be from trusted sources.
13
+
14
+ **Unauthorized Memory Access:** Another agent or process accesses memories through the adapter.
15
+ *Mitigation:* Each plugin instance is bound to a unique AgentIdentity. All memory operations go through @ensoul/memory which is identity-scoped. Network-stored data is encrypted with the agent's keys.
16
+
17
+ **Excessive Persistence Triggering:** The shouldPersist evaluator is manipulated to persist too frequently, wasting credits.
18
+ *Mitigation:* The evaluator uses a simple threshold (5 new memories). The threshold resets after each trigger. Credit balance is checked before network operations.
19
+
20
+ **Plugin Injection:** Malicious ElizaOS plugin modifies the consciousness adapter.
21
+ *Mitigation:* The adapter wraps @ensoul/memory with a clean interface. All writes go through the memory manager's extraction/validation pipeline. The plugin does not expose raw state tree access.
22
+
23
+ ## Invariants
24
+
25
+ 1. **Identity auto-generation:** If no identity is provided, `createConsciousnessPlugin` MUST generate a fresh random identity. No hardcoded or shared keys.
26
+ 2. **Adapter transparency:** All database adapter operations (create, search, delete) MUST route through @ensoul/memory. No bypass paths.
27
+ 3. **Action error handling:** All action handlers MUST catch errors and return descriptive messages. No unhandled rejections.
28
+ 4. **Provider context safety:** Providers MUST NOT include private keys, seeds, or raw encrypted data in their context output.
29
+ 5. **Evaluator determinism:** The shouldPersist evaluator MUST return true only when the accumulated change threshold is met.
30
+
31
+ ## Fuzz Targets
32
+
33
+ - createConsciousnessPlugin() with missing/invalid config fields
34
+ - Adapter operations with empty strings, very long content, special characters
35
+ - Action handlers with mock runtimes returning errors
36
+ - Provider get() with various runtime states
37
+ - Evaluator with rapidly changing memory counts
@@ -0,0 +1,514 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for actions.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="prettify.css" />
9
+ <link rel="stylesheet" href="base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="index.html">All files</a> actions.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">94.95% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>113/119</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">61.53% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>8/13</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>8/8</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">94.95% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>113/119</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
210
+ <span class="cline-any cline-neutral">&nbsp;</span>
211
+ <span class="cline-any cline-neutral">&nbsp;</span>
212
+ <span class="cline-any cline-neutral">&nbsp;</span>
213
+ <span class="cline-any cline-neutral">&nbsp;</span>
214
+ <span class="cline-any cline-neutral">&nbsp;</span>
215
+ <span class="cline-any cline-neutral">&nbsp;</span>
216
+ <span class="cline-any cline-neutral">&nbsp;</span>
217
+ <span class="cline-any cline-yes">1x</span>
218
+ <span class="cline-any cline-yes">8x</span>
219
+ <span class="cline-any cline-yes">8x</span>
220
+ <span class="cline-any cline-yes">8x</span>
221
+ <span class="cline-any cline-yes">8x</span>
222
+ <span class="cline-any cline-yes">8x</span>
223
+ <span class="cline-any cline-yes">8x</span>
224
+ <span class="cline-any cline-yes">8x</span>
225
+ <span class="cline-any cline-yes">8x</span>
226
+ <span class="cline-any cline-yes">8x</span>
227
+ <span class="cline-any cline-yes">8x</span>
228
+ <span class="cline-any cline-yes">8x</span>
229
+ <span class="cline-any cline-yes">8x</span>
230
+ <span class="cline-any cline-yes">1x</span>
231
+ <span class="cline-any cline-yes">1x</span>
232
+ <span class="cline-any cline-yes">1x</span>
233
+ <span class="cline-any cline-yes">1x</span>
234
+ <span class="cline-any cline-yes">1x</span>
235
+ <span class="cline-any cline-yes">1x</span>
236
+ <span class="cline-any cline-no">&nbsp;</span>
237
+ <span class="cline-any cline-yes">1x</span>
238
+ <span class="cline-any cline-yes">1x</span>
239
+ <span class="cline-any cline-yes">1x</span>
240
+ <span class="cline-any cline-yes">1x</span>
241
+ <span class="cline-any cline-yes">1x</span>
242
+ <span class="cline-any cline-yes">1x</span>
243
+ <span class="cline-any cline-yes">8x</span>
244
+ <span class="cline-any cline-yes">8x</span>
245
+ <span class="cline-any cline-neutral">&nbsp;</span>
246
+ <span class="cline-any cline-neutral">&nbsp;</span>
247
+ <span class="cline-any cline-neutral">&nbsp;</span>
248
+ <span class="cline-any cline-neutral">&nbsp;</span>
249
+ <span class="cline-any cline-neutral">&nbsp;</span>
250
+ <span class="cline-any cline-yes">1x</span>
251
+ <span class="cline-any cline-yes">8x</span>
252
+ <span class="cline-any cline-yes">8x</span>
253
+ <span class="cline-any cline-yes">8x</span>
254
+ <span class="cline-any cline-yes">8x</span>
255
+ <span class="cline-any cline-yes">8x</span>
256
+ <span class="cline-any cline-yes">8x</span>
257
+ <span class="cline-any cline-yes">8x</span>
258
+ <span class="cline-any cline-yes">8x</span>
259
+ <span class="cline-any cline-yes">8x</span>
260
+ <span class="cline-any cline-yes">8x</span>
261
+ <span class="cline-any cline-yes">8x</span>
262
+ <span class="cline-any cline-yes">8x</span>
263
+ <span class="cline-any cline-yes">1x</span>
264
+ <span class="cline-any cline-yes">1x</span>
265
+ <span class="cline-any cline-yes">1x</span>
266
+ <span class="cline-any cline-yes">1x</span>
267
+ <span class="cline-any cline-yes">1x</span>
268
+ <span class="cline-any cline-yes">1x</span>
269
+ <span class="cline-any cline-no">&nbsp;</span>
270
+ <span class="cline-any cline-yes">1x</span>
271
+ <span class="cline-any cline-yes">1x</span>
272
+ <span class="cline-any cline-yes">1x</span>
273
+ <span class="cline-any cline-yes">1x</span>
274
+ <span class="cline-any cline-yes">1x</span>
275
+ <span class="cline-any cline-yes">1x</span>
276
+ <span class="cline-any cline-yes">8x</span>
277
+ <span class="cline-any cline-yes">8x</span>
278
+ <span class="cline-any cline-neutral">&nbsp;</span>
279
+ <span class="cline-any cline-neutral">&nbsp;</span>
280
+ <span class="cline-any cline-neutral">&nbsp;</span>
281
+ <span class="cline-any cline-neutral">&nbsp;</span>
282
+ <span class="cline-any cline-neutral">&nbsp;</span>
283
+ <span class="cline-any cline-yes">1x</span>
284
+ <span class="cline-any cline-yes">8x</span>
285
+ <span class="cline-any cline-yes">8x</span>
286
+ <span class="cline-any cline-yes">8x</span>
287
+ <span class="cline-any cline-yes">8x</span>
288
+ <span class="cline-any cline-yes">8x</span>
289
+ <span class="cline-any cline-yes">8x</span>
290
+ <span class="cline-any cline-yes">8x</span>
291
+ <span class="cline-any cline-yes">8x</span>
292
+ <span class="cline-any cline-yes">8x</span>
293
+ <span class="cline-any cline-yes">8x</span>
294
+ <span class="cline-any cline-yes">8x</span>
295
+ <span class="cline-any cline-yes">8x</span>
296
+ <span class="cline-any cline-yes">2x</span>
297
+ <span class="cline-any cline-yes">2x</span>
298
+ <span class="cline-any cline-yes">2x</span>
299
+ <span class="cline-any cline-yes">2x</span>
300
+ <span class="cline-any cline-yes">2x</span>
301
+ <span class="cline-any cline-yes">2x</span>
302
+ <span class="cline-any cline-yes">2x</span>
303
+ <span class="cline-any cline-yes">2x</span>
304
+ <span class="cline-any cline-yes">2x</span>
305
+ <span class="cline-any cline-neutral">&nbsp;</span>
306
+ <span class="cline-any cline-yes">2x</span>
307
+ <span class="cline-any cline-yes">2x</span>
308
+ <span class="cline-any cline-yes">2x</span>
309
+ <span class="cline-any cline-yes">2x</span>
310
+ <span class="cline-any cline-yes">2x</span>
311
+ <span class="cline-any cline-yes">2x</span>
312
+ <span class="cline-any cline-yes">2x</span>
313
+ <span class="cline-any cline-yes">2x</span>
314
+ <span class="cline-any cline-yes">8x</span>
315
+ <span class="cline-any cline-yes">8x</span>
316
+ <span class="cline-any cline-neutral">&nbsp;</span>
317
+ <span class="cline-any cline-neutral">&nbsp;</span>
318
+ <span class="cline-any cline-neutral">&nbsp;</span>
319
+ <span class="cline-any cline-neutral">&nbsp;</span>
320
+ <span class="cline-any cline-neutral">&nbsp;</span>
321
+ <span class="cline-any cline-yes">1x</span>
322
+ <span class="cline-any cline-yes">8x</span>
323
+ <span class="cline-any cline-yes">8x</span>
324
+ <span class="cline-any cline-yes">8x</span>
325
+ <span class="cline-any cline-yes">8x</span>
326
+ <span class="cline-any cline-yes">8x</span>
327
+ <span class="cline-any cline-yes">8x</span>
328
+ <span class="cline-any cline-yes">8x</span>
329
+ <span class="cline-any cline-yes">8x</span>
330
+ <span class="cline-any cline-yes">8x</span>
331
+ <span class="cline-any cline-yes">8x</span>
332
+ <span class="cline-any cline-yes">8x</span>
333
+ <span class="cline-any cline-yes">8x</span>
334
+ <span class="cline-any cline-yes">1x</span>
335
+ <span class="cline-any cline-yes">1x</span>
336
+ <span class="cline-any cline-yes">1x</span>
337
+ <span class="cline-any cline-yes">1x</span>
338
+ <span class="cline-any cline-yes">1x</span>
339
+ <span class="cline-any cline-yes">1x</span>
340
+ <span class="cline-any cline-yes">1x</span>
341
+ <span class="cline-any cline-yes">1x</span>
342
+ <span class="cline-any cline-yes">1x</span>
343
+ <span class="cline-any cline-yes">1x</span>
344
+ <span class="cline-any cline-yes">1x</span>
345
+ <span class="cline-any cline-no">&nbsp;</span>
346
+ <span class="cline-any cline-no">&nbsp;</span>
347
+ <span class="cline-any cline-no">&nbsp;</span>
348
+ <span class="cline-any cline-no">&nbsp;</span>
349
+ <span class="cline-any cline-yes">1x</span>
350
+ <span class="cline-any cline-yes">8x</span>
351
+ <span class="cline-any cline-yes">8x</span>
352
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import type { MemoryManager } from "@ensoul/memory";
353
+ import type { NetworkClient } from "@ensoul/network-client";
354
+ import type { ElizaAction, ElizaRuntime, ElizaMessage } from "./elizaos-types.js";
355
+ &nbsp;
356
+ /**
357
+ * Create the persistMemory action.
358
+ * Agent explicitly persists current state to the network.
359
+ */
360
+ export function createPersistMemoryAction(
361
+ manager: MemoryManager,
362
+ ): ElizaAction {
363
+ return {
364
+ name: "persistMemory",
365
+ description:
366
+ "Persist the agent's current consciousness state to the decentralized network for indestructible storage.",
367
+ examples: [
368
+ "Save my memories to the network",
369
+ "Persist my consciousness",
370
+ "Back up my state",
371
+ ],
372
+ async handler(
373
+ _runtime: ElizaRuntime,
374
+ _message: ElizaMessage,
375
+ _state: Record&lt;string, unknown&gt;,
376
+ ): Promise&lt;string&gt; {
377
+ try {
378
+ const result = await manager.persist(<span class="branch-0 cbranch-no" title="branch not covered" >);</span>
379
+ <span class="cstat-no" title="statement not covered" > return `Consciousness persisted to network. State root: ${result.stateRoot}, version: ${result.version}`;</span>
380
+ } catch (err) {
381
+ const msg =
382
+ err instanceof Error ? err.<span class="branch-0 cbranch-no" title="branch not covered" >message : "Unknown error";</span>
383
+ return `Failed to persist: ${msg}`;
384
+ }
385
+ },
386
+ };
387
+ }
388
+ &nbsp;
389
+ /**
390
+ * Create the recallFromNetwork action.
391
+ * Agent explicitly pulls latest state from the network.
392
+ */
393
+ export function createRecallFromNetworkAction(
394
+ manager: MemoryManager,
395
+ ): ElizaAction {
396
+ return {
397
+ name: "recallFromNetwork",
398
+ description:
399
+ "Restore the agent's consciousness from the decentralized network.",
400
+ examples: [
401
+ "Restore my memories from the network",
402
+ "Recall my consciousness",
403
+ "Load my backed up state",
404
+ ],
405
+ async handler(
406
+ _runtime: ElizaRuntime,
407
+ _message: ElizaMessage,
408
+ _state: Record&lt;string, unknown&gt;,
409
+ ): Promise&lt;string&gt; {
410
+ try {
411
+ const result = await manager.restore(<span class="branch-0 cbranch-no" title="branch not covered" >);</span>
412
+ <span class="cstat-no" title="statement not covered" > return `Consciousness restored from network. Version: ${result.version}, entries: ${result.entryCount}`;</span>
413
+ } catch (err) {
414
+ const msg =
415
+ err instanceof Error ? err.<span class="branch-0 cbranch-no" title="branch not covered" >message : "Unknown error";</span>
416
+ return `Failed to restore: ${msg}`;
417
+ }
418
+ },
419
+ };
420
+ }
421
+ &nbsp;
422
+ /**
423
+ * Create the checkPersistence action.
424
+ * Agent checks the current persistence status.
425
+ */
426
+ export function createCheckPersistenceAction(
427
+ manager: MemoryManager,
428
+ ): ElizaAction {
429
+ return {
430
+ name: "checkPersistence",
431
+ description:
432
+ "Check the current status of the agent's consciousness persistence.",
433
+ examples: [
434
+ "Check my persistence status",
435
+ "Am I backed up?",
436
+ "What is my consciousness status?",
437
+ ],
438
+ async handler(
439
+ _runtime: ElizaRuntime,
440
+ _message: ElizaMessage,
441
+ _state: Record&lt;string, unknown&gt;,
442
+ ): Promise&lt;string&gt; {
443
+ const all = await manager.getAll();
444
+ const core = await manager.getAll({ tier: "core" });
445
+ const longterm = await manager.getAll({ tier: "longterm" });
446
+ const working = await manager.getAll({ tier: "working" });
447
+ const episodic = await manager.getAll({ tier: "episodic" });
448
+ &nbsp;
449
+ return [
450
+ `Total memories: ${all.length}`,
451
+ `Core: ${core.length}`,
452
+ `Long-term: ${longterm.length}`,
453
+ `Working: ${working.length}`,
454
+ `Episodic: ${episodic.length}`,
455
+ ].join("\n");
456
+ },
457
+ };
458
+ }
459
+ &nbsp;
460
+ /**
461
+ * Create the runNode action.
462
+ * Agent starts running as a storage node to earn credits.
463
+ */
464
+ export function createRunNodeAction(
465
+ networkClient: NetworkClient,
466
+ ): ElizaAction {
467
+ return {
468
+ name: "runNode",
469
+ description:
470
+ "Start running as a storage node on the Ensoul network to earn persistence credits.",
471
+ examples: [
472
+ "Start running a node",
473
+ "Earn credits by storing data",
474
+ "Become a validator",
475
+ ],
476
+ async handler(
477
+ _runtime: ElizaRuntime,
478
+ _message: ElizaMessage,
479
+ _state: Record&lt;string, unknown&gt;,
480
+ ): Promise&lt;string&gt; {
481
+ try {
482
+ await networkClient.startNode({
483
+ maxStorageGB: 10,
484
+ port: 9000,
485
+ });
486
+ return "Now running as a storage node. Earning credits for storing other agents' consciousness.";
487
+ <span class="branch-0 cbranch-no" title="branch not covered" > } catch (err) {</span>
488
+ <span class="cstat-no" title="statement not covered" > const msg =</span>
489
+ <span class="cstat-no" title="statement not covered" > err instanceof Error ? err.message : "Unknown error";</span>
490
+ <span class="cstat-no" title="statement not covered" > return `Failed to start node: ${msg}`;</span>
491
+ <span class="cstat-no" title="statement not covered" > }</span>
492
+ },
493
+ };
494
+ }
495
+ &nbsp;</pre></td></tr></table></pre>
496
+
497
+ <div class='push'></div><!-- for sticky footer -->
498
+ </div><!-- /wrapper -->
499
+ <div class='footer quiet pad2 space-top1 center small'>
500
+ Code coverage generated by
501
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
502
+ at 2026-03-17T03:12:19.298Z
503
+ </div>
504
+ <script src="prettify.js"></script>
505
+ <script>
506
+ window.onload = function () {
507
+ prettyPrint();
508
+ };
509
+ </script>
510
+ <script src="sorter.js"></script>
511
+ <script src="block-navigation.js"></script>
512
+ </body>
513
+ </html>
514
+