miladyai 2.0.0-alpha.27

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 (241) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +7 -0
  2. package/dist/actions/emote.js +64 -0
  3. package/dist/actions/restart.js +81 -0
  4. package/dist/actions/send-message.js +152 -0
  5. package/dist/agent-admin-routes.js +82 -0
  6. package/dist/agent-lifecycle-routes.js +79 -0
  7. package/dist/agent-transfer-routes.js +102 -0
  8. package/dist/api/agent-admin-routes.js +82 -0
  9. package/dist/api/agent-lifecycle-routes.js +79 -0
  10. package/dist/api/agent-transfer-routes.js +102 -0
  11. package/dist/api/apps-hyperscape-routes.js +58 -0
  12. package/dist/api/apps-routes.js +114 -0
  13. package/dist/api/auth-routes.js +56 -0
  14. package/dist/api/autonomy-routes.js +44 -0
  15. package/dist/api/bug-report-routes.js +111 -0
  16. package/dist/api/character-routes.js +195 -0
  17. package/dist/api/cloud-routes.js +330 -0
  18. package/dist/api/cloud-status-routes.js +155 -0
  19. package/dist/api/compat-utils.js +111 -0
  20. package/dist/api/database.js +735 -0
  21. package/dist/api/diagnostics-routes.js +205 -0
  22. package/dist/api/drop-service.js +134 -0
  23. package/dist/api/early-logs.js +86 -0
  24. package/dist/api/http-helpers.js +131 -0
  25. package/dist/api/knowledge-routes.js +534 -0
  26. package/dist/api/memory-bounds.js +71 -0
  27. package/dist/api/models-routes.js +28 -0
  28. package/dist/api/og-tracker.js +36 -0
  29. package/dist/api/permissions-routes.js +109 -0
  30. package/dist/api/plugin-validation.js +198 -0
  31. package/dist/api/provider-switch-config.js +41 -0
  32. package/dist/api/registry-routes.js +86 -0
  33. package/dist/api/registry-service.js +164 -0
  34. package/dist/api/sandbox-routes.js +1112 -0
  35. package/dist/api/server.js +7949 -0
  36. package/dist/api/subscription-routes.js +172 -0
  37. package/dist/api/terminal-run-limits.js +24 -0
  38. package/dist/api/training-routes.js +158 -0
  39. package/dist/api/trajectory-routes.js +300 -0
  40. package/dist/api/trigger-routes.js +246 -0
  41. package/dist/api/twitter-verify.js +134 -0
  42. package/dist/api/tx-service.js +108 -0
  43. package/dist/api/wallet-routes.js +266 -0
  44. package/dist/api/wallet.js +568 -0
  45. package/dist/api/whatsapp-routes.js +182 -0
  46. package/dist/api/zip-utils.js +109 -0
  47. package/dist/apps-hyperscape-routes.js +58 -0
  48. package/dist/apps-routes.js +114 -0
  49. package/dist/ascii.js +20 -0
  50. package/dist/auth/anthropic.js +44 -0
  51. package/dist/auth/apply-stealth.js +41 -0
  52. package/dist/auth/claude-code-stealth.js +78 -0
  53. package/dist/auth/credentials.js +156 -0
  54. package/dist/auth/index.js +5 -0
  55. package/dist/auth/openai-codex.js +66 -0
  56. package/dist/auth/types.js +9 -0
  57. package/dist/auth-routes.js +56 -0
  58. package/dist/autonomy-routes.js +44 -0
  59. package/dist/bug-report-routes.js +111 -0
  60. package/dist/build-info.json +6 -0
  61. package/dist/character-routes.js +195 -0
  62. package/dist/cli/argv.js +63 -0
  63. package/dist/cli/banner.js +34 -0
  64. package/dist/cli/cli-name.js +21 -0
  65. package/dist/cli/cli-utils.js +16 -0
  66. package/dist/cli/git-commit.js +78 -0
  67. package/dist/cli/parse-duration.js +15 -0
  68. package/dist/cli/plugins-cli.js +590 -0
  69. package/dist/cli/profile-utils.js +9 -0
  70. package/dist/cli/profile.js +95 -0
  71. package/dist/cli/program/build-program.js +17 -0
  72. package/dist/cli/program/command-registry.js +23 -0
  73. package/dist/cli/program/help.js +47 -0
  74. package/dist/cli/program/preaction.js +33 -0
  75. package/dist/cli/program/register.config.js +106 -0
  76. package/dist/cli/program/register.configure.js +20 -0
  77. package/dist/cli/program/register.dashboard.js +124 -0
  78. package/dist/cli/program/register.models.js +23 -0
  79. package/dist/cli/program/register.setup.js +36 -0
  80. package/dist/cli/program/register.start.js +22 -0
  81. package/dist/cli/program/register.subclis.js +70 -0
  82. package/dist/cli/program/register.tui.js +163 -0
  83. package/dist/cli/program/register.update.js +154 -0
  84. package/dist/cli/program.js +3 -0
  85. package/dist/cli/run-main.js +37 -0
  86. package/dist/cli/version.js +7 -0
  87. package/dist/cloud/validate-url.js +93 -0
  88. package/dist/cloud-routes.js +330 -0
  89. package/dist/cloud-status-routes.js +155 -0
  90. package/dist/compat-utils.js +111 -0
  91. package/dist/config/config.js +69 -0
  92. package/dist/config/env-vars.js +19 -0
  93. package/dist/config/includes.js +121 -0
  94. package/dist/config/object-utils.js +7 -0
  95. package/dist/config/paths.js +38 -0
  96. package/dist/config/plugin-auto-enable.js +231 -0
  97. package/dist/config/schema.js +864 -0
  98. package/dist/config/telegram-custom-commands.js +76 -0
  99. package/dist/config/zod-schema.agent-runtime.js +519 -0
  100. package/dist/config/zod-schema.core.js +538 -0
  101. package/dist/config/zod-schema.hooks.js +103 -0
  102. package/dist/config/zod-schema.js +488 -0
  103. package/dist/config/zod-schema.providers-core.js +785 -0
  104. package/dist/config/zod-schema.session.js +73 -0
  105. package/dist/core-plugins.js +37 -0
  106. package/dist/custom-actions.js +250 -0
  107. package/dist/database.js +735 -0
  108. package/dist/diagnostics/integration-observability.js +57 -0
  109. package/dist/diagnostics-routes.js +205 -0
  110. package/dist/drop-service.js +134 -0
  111. package/dist/early-logs.js +24 -0
  112. package/dist/eliza.js +2061 -0
  113. package/dist/emotes/catalog.js +271 -0
  114. package/dist/entry.js +40 -0
  115. package/dist/hooks/discovery.js +167 -0
  116. package/dist/hooks/eligibility.js +64 -0
  117. package/dist/hooks/index.js +4 -0
  118. package/dist/hooks/loader.js +147 -0
  119. package/dist/hooks/registry.js +55 -0
  120. package/dist/http-helpers.js +131 -0
  121. package/dist/index.js +49 -0
  122. package/dist/knowledge-routes.js +534 -0
  123. package/dist/memory-bounds.js +71 -0
  124. package/dist/milady-plugin.js +90 -0
  125. package/dist/models-routes.js +28 -0
  126. package/dist/onboarding-names.js +78 -0
  127. package/dist/onboarding-presets.js +922 -0
  128. package/dist/package.json +1 -0
  129. package/dist/permissions-routes.js +109 -0
  130. package/dist/plugin-validation.js +107 -0
  131. package/dist/plugins/whatsapp/actions.js +91 -0
  132. package/dist/plugins/whatsapp/index.js +16 -0
  133. package/dist/plugins/whatsapp/service.js +270 -0
  134. package/dist/provider-switch-config.js +41 -0
  135. package/dist/providers/admin-trust.js +46 -0
  136. package/dist/providers/autonomous-state.js +101 -0
  137. package/dist/providers/session-bridge.js +86 -0
  138. package/dist/providers/session-utils.js +36 -0
  139. package/dist/providers/simple-mode.js +50 -0
  140. package/dist/providers/ui-catalog.js +15 -0
  141. package/dist/providers/workspace-provider.js +93 -0
  142. package/dist/providers/workspace.js +348 -0
  143. package/dist/registry-routes.js +86 -0
  144. package/dist/registry-service.js +164 -0
  145. package/dist/restart.js +40 -0
  146. package/dist/runtime/core-plugins.js +37 -0
  147. package/dist/runtime/custom-actions.js +250 -0
  148. package/dist/runtime/eliza.js +2061 -0
  149. package/dist/runtime/embedding-manager-support.js +185 -0
  150. package/dist/runtime/embedding-manager.js +193 -0
  151. package/dist/runtime/embedding-presets.js +54 -0
  152. package/dist/runtime/embedding-state.js +8 -0
  153. package/dist/runtime/milady-plugin.js +90 -0
  154. package/dist/runtime/onboarding-names.js +78 -0
  155. package/dist/runtime/restart.js +40 -0
  156. package/dist/runtime/version.js +7 -0
  157. package/dist/sandbox-routes.js +1112 -0
  158. package/dist/security/audit-log.js +149 -0
  159. package/dist/security/network-policy.js +70 -0
  160. package/dist/server.js +7949 -0
  161. package/dist/services/agent-export.js +559 -0
  162. package/dist/services/app-manager.js +389 -0
  163. package/dist/services/browser-capture.js +86 -0
  164. package/dist/services/fallback-training-service.js +128 -0
  165. package/dist/services/mcp-marketplace.js +134 -0
  166. package/dist/services/plugin-installer.js +396 -0
  167. package/dist/services/plugin-manager-types.js +15 -0
  168. package/dist/services/registry-client-app-meta.js +144 -0
  169. package/dist/services/registry-client-endpoints.js +166 -0
  170. package/dist/services/registry-client-local.js +271 -0
  171. package/dist/services/registry-client-network.js +93 -0
  172. package/dist/services/registry-client-queries.js +70 -0
  173. package/dist/services/registry-client.js +157 -0
  174. package/dist/services/sandbox-engine.js +511 -0
  175. package/dist/services/sandbox-manager.js +297 -0
  176. package/dist/services/self-updater.js +175 -0
  177. package/dist/services/skill-catalog-client.js +119 -0
  178. package/dist/services/skill-marketplace.js +521 -0
  179. package/dist/services/stream-manager.js +236 -0
  180. package/dist/services/update-checker.js +121 -0
  181. package/dist/services/update-notifier.js +29 -0
  182. package/dist/services/version-compat.js +78 -0
  183. package/dist/services/whatsapp-pairing.js +196 -0
  184. package/dist/shared/ui-catalog-prompt.js +728 -0
  185. package/dist/subscription-routes.js +172 -0
  186. package/dist/terminal/links.js +19 -0
  187. package/dist/terminal/palette.js +14 -0
  188. package/dist/terminal/theme.js +25 -0
  189. package/dist/terminal-run-limits.js +24 -0
  190. package/dist/training-routes.js +158 -0
  191. package/dist/trajectory-routes.js +300 -0
  192. package/dist/trigger-routes.js +246 -0
  193. package/dist/triggers/action.js +218 -0
  194. package/dist/triggers/runtime.js +281 -0
  195. package/dist/triggers/scheduling.js +295 -0
  196. package/dist/triggers/types.js +5 -0
  197. package/dist/tui/components/assistant-message.js +76 -0
  198. package/dist/tui/components/chat-editor.js +34 -0
  199. package/dist/tui/components/embeddings-overlay.js +46 -0
  200. package/dist/tui/components/footer.js +60 -0
  201. package/dist/tui/components/index.js +15 -0
  202. package/dist/tui/components/modal-frame.js +45 -0
  203. package/dist/tui/components/modal-style.js +15 -0
  204. package/dist/tui/components/model-selector.js +70 -0
  205. package/dist/tui/components/pinned-chat-layout.js +46 -0
  206. package/dist/tui/components/plugins-endpoints-tab.js +196 -0
  207. package/dist/tui/components/plugins-installed-tab-view.js +69 -0
  208. package/dist/tui/components/plugins-installed-tab.js +319 -0
  209. package/dist/tui/components/plugins-overlay-catalog.js +81 -0
  210. package/dist/tui/components/plugins-overlay-data-api.js +21 -0
  211. package/dist/tui/components/plugins-overlay-data-shared.js +20 -0
  212. package/dist/tui/components/plugins-overlay-data.js +323 -0
  213. package/dist/tui/components/plugins-overlay.js +117 -0
  214. package/dist/tui/components/plugins-store-tab.js +148 -0
  215. package/dist/tui/components/settings-overlay.js +61 -0
  216. package/dist/tui/components/status-bar.js +64 -0
  217. package/dist/tui/components/tool-execution.js +68 -0
  218. package/dist/tui/components/user-message.js +22 -0
  219. package/dist/tui/eliza-tui-bridge.js +606 -0
  220. package/dist/tui/index.js +370 -0
  221. package/dist/tui/modal-presets.js +33 -0
  222. package/dist/tui/model-spec.js +46 -0
  223. package/dist/tui/sse-parser.js +78 -0
  224. package/dist/tui/theme.js +110 -0
  225. package/dist/tui/titlebar-spinner.js +62 -0
  226. package/dist/tui/tui-app.js +311 -0
  227. package/dist/tui/ws-client.js +215 -0
  228. package/dist/twitter-verify.js +134 -0
  229. package/dist/tx-service.js +108 -0
  230. package/dist/utils/exec-safety.js +17 -0
  231. package/dist/utils/globals.js +20 -0
  232. package/dist/utils/milady-root.js +61 -0
  233. package/dist/utils/number-parsing.js +37 -0
  234. package/dist/version-resolver.js +37 -0
  235. package/dist/version.js +7 -0
  236. package/dist/wallet-routes.js +266 -0
  237. package/dist/wallet.js +568 -0
  238. package/dist/whatsapp-routes.js +182 -0
  239. package/dist/zip-utils.js +109 -0
  240. package/milady.mjs +14 -0
  241. package/package.json +111 -0
@@ -0,0 +1,559 @@
1
+ import { logger } from "@elizaos/core";
2
+ import * as crypto$1 from "node:crypto";
3
+ import { Readable } from "node:stream";
4
+ import { createGunzip, gzipSync } from "node:zlib";
5
+ import { z } from "zod";
6
+
7
+ //#region src/services/agent-export.ts
8
+ /**
9
+ * Agent Export/Import Service
10
+ *
11
+ * Provides encrypted, portable agent archives for migrating agents between
12
+ * machines. Captures all database state (character, memories, entities,
13
+ * relationships, rooms, participants, worlds, tasks, and optionally logs)
14
+ * into a single password-encrypted binary file (.eliza-agent).
15
+ *
16
+ * Encryption: PBKDF2-SHA256 key derivation + AES-256-GCM
17
+ * Compression: gzip
18
+ *
19
+ * File format (binary):
20
+ * ELIZA_AGENT_V1\n (15 bytes magic header)
21
+ * iterations (4 bytes uint32 BE — PBKDF2 iteration count)
22
+ * salt (32 bytes — PBKDF2 salt)
23
+ * iv (12 bytes — AES-256-GCM nonce)
24
+ * tag (16 bytes — AES-GCM authentication tag)
25
+ * ciphertext (variable — gzip-compressed JSON, encrypted)
26
+ */
27
+ const MAGIC_BYTES = Buffer.from("ELIZA_AGENT_V1\n", "utf-8");
28
+ const PBKDF2_ITERATIONS = 6e5;
29
+ const MAX_PBKDF2_ITERATIONS = 12e5;
30
+ const SALT_LEN = 32;
31
+ const IV_LEN = 12;
32
+ const TAG_LEN = 16;
33
+ const KEY_LEN = 32;
34
+ const MIN_PASSWORD_LENGTH = 4;
35
+ const HEADER_SIZE = MAGIC_BYTES.length + 4 + SALT_LEN + IV_LEN + TAG_LEN;
36
+ const EXPORT_VERSION = 1;
37
+ const MAX_IMPORT_DECOMPRESSED_BYTES = 16 * 1024 * 1024;
38
+ const MEMORY_TABLES = [
39
+ "messages",
40
+ "facts",
41
+ "documents",
42
+ "fragments",
43
+ "descriptions",
44
+ "character_modifications",
45
+ "custom"
46
+ ];
47
+ const IdRecord = z.record(z.string(), z.unknown()).and(z.object({ id: z.string() }));
48
+ const IdRecordArray = z.array(IdRecord);
49
+ const LooseRecordArray = z.array(z.record(z.string(), z.unknown()));
50
+ const PayloadSchema = z.object({
51
+ version: z.number().int().min(1),
52
+ exportedAt: z.string(),
53
+ sourceAgentId: z.string(),
54
+ agent: z.record(z.string(), z.unknown()),
55
+ characterConfig: z.record(z.string(), z.unknown()).optional(),
56
+ entities: IdRecordArray,
57
+ memories: IdRecordArray,
58
+ components: IdRecordArray,
59
+ rooms: IdRecordArray,
60
+ participants: z.array(z.object({
61
+ entityId: z.string(),
62
+ roomId: z.string(),
63
+ userState: z.string().nullable()
64
+ })),
65
+ relationships: IdRecordArray,
66
+ worlds: IdRecordArray,
67
+ tasks: IdRecordArray,
68
+ logs: LooseRecordArray
69
+ });
70
+ function deriveKey(password, salt, iterations) {
71
+ return new Promise((resolve, reject) => {
72
+ crypto$1.pbkdf2(password, salt, iterations, KEY_LEN, "sha256", (err, key) => {
73
+ if (err) reject(err);
74
+ else resolve(key);
75
+ });
76
+ });
77
+ }
78
+ async function encrypt(plaintext, password) {
79
+ const salt = crypto$1.randomBytes(SALT_LEN);
80
+ const iv = crypto$1.randomBytes(IV_LEN);
81
+ const key = await deriveKey(password, salt, PBKDF2_ITERATIONS);
82
+ const cipher = crypto$1.createCipheriv("aes-256-gcm", key, iv);
83
+ const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
84
+ return {
85
+ salt,
86
+ iv,
87
+ tag: cipher.getAuthTag(),
88
+ ciphertext,
89
+ iterations: PBKDF2_ITERATIONS
90
+ };
91
+ }
92
+ async function decrypt(ciphertext, password, salt, iv, tag, iterations) {
93
+ const key = await deriveKey(password, salt, iterations);
94
+ const decipher = crypto$1.createDecipheriv("aes-256-gcm", key, iv);
95
+ decipher.setAuthTag(tag);
96
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
97
+ }
98
+ function packFile(encrypted) {
99
+ const iterBuf = Buffer.alloc(4);
100
+ iterBuf.writeUInt32BE(encrypted.iterations, 0);
101
+ return Buffer.concat([
102
+ MAGIC_BYTES,
103
+ iterBuf,
104
+ encrypted.salt,
105
+ encrypted.iv,
106
+ encrypted.tag,
107
+ encrypted.ciphertext
108
+ ]);
109
+ }
110
+ function unpackFile(fileBuffer) {
111
+ if (fileBuffer.length < HEADER_SIZE) throw new AgentExportError("File is too small to be a valid .eliza-agent export.");
112
+ if (!fileBuffer.subarray(0, MAGIC_BYTES.length).equals(MAGIC_BYTES)) throw new AgentExportError("Invalid file format — this does not appear to be an .eliza-agent export file.");
113
+ let offset = MAGIC_BYTES.length;
114
+ const iterations = fileBuffer.readUInt32BE(offset);
115
+ offset += 4;
116
+ if (iterations < 1 || iterations > MAX_PBKDF2_ITERATIONS) throw new AgentExportError(`Invalid PBKDF2 iteration count (${iterations}). Expected between 1 and ${MAX_PBKDF2_ITERATIONS.toLocaleString()}.`);
117
+ const salt = fileBuffer.subarray(offset, offset + SALT_LEN);
118
+ offset += SALT_LEN;
119
+ const iv = fileBuffer.subarray(offset, offset + IV_LEN);
120
+ offset += IV_LEN;
121
+ const tag = fileBuffer.subarray(offset, offset + TAG_LEN);
122
+ offset += TAG_LEN;
123
+ const ciphertext = fileBuffer.subarray(offset);
124
+ if (ciphertext.length === 0) throw new AgentExportError("Export file contains no encrypted data.");
125
+ return {
126
+ salt,
127
+ iv,
128
+ tag,
129
+ ciphertext,
130
+ iterations
131
+ };
132
+ }
133
+ var AgentExportError = class extends Error {
134
+ constructor(message) {
135
+ super(message);
136
+ this.name = "AgentExportError";
137
+ }
138
+ };
139
+ async function gunzipWithSizeLimit(compressed, maxBytes = MAX_IMPORT_DECOMPRESSED_BYTES) {
140
+ const source = Readable.from([compressed]);
141
+ const gunzip = createGunzip();
142
+ const chunks = [];
143
+ let total = 0;
144
+ source.pipe(gunzip);
145
+ for await (const chunk of gunzip) {
146
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
147
+ total += buf.length;
148
+ if (total > maxBytes) {
149
+ source.destroy();
150
+ gunzip.destroy();
151
+ throw new AgentExportError(`Decompressed payload exceeds import limit (${maxBytes} bytes).`);
152
+ }
153
+ chunks.push(buf);
154
+ }
155
+ return Buffer.concat(chunks, total);
156
+ }
157
+ /** Read agentId from a Task, accounting for proto vs DB naming. */
158
+ function taskAgentId(t) {
159
+ const rec = t;
160
+ return rec.agentId ?? rec.agent_id;
161
+ }
162
+ async function extractAgentData(runtime, options) {
163
+ const db = runtime.adapter;
164
+ const agentId = runtime.agentId;
165
+ logger.info(`[agent-export] Extracting data for agent ${agentId}`);
166
+ const agent = await db.getAgent(agentId);
167
+ if (!agent) throw new AgentExportError(`Agent ${agentId} not found in database.`);
168
+ const agentWorlds = (await db.getAllWorlds()).filter((w) => w.agentId === agentId);
169
+ logger.info(`[agent-export] Found ${agentWorlds.length} worlds`);
170
+ const roomMap = /* @__PURE__ */ new Map();
171
+ for (const world of agentWorlds) {
172
+ if (!world.id) continue;
173
+ const worldRooms = await db.getRoomsByWorld(world.id);
174
+ for (const room of worldRooms) if (room.id) roomMap.set(room.id, room);
175
+ }
176
+ const participantRoomIds = await db.getRoomsForParticipant(agentId);
177
+ if (participantRoomIds.length > 0) {
178
+ const participantRooms = await db.getRoomsByIds(participantRoomIds);
179
+ if (participantRooms) {
180
+ for (const room of participantRooms) if (room.id) roomMap.set(room.id, room);
181
+ }
182
+ }
183
+ const rooms = Array.from(roomMap.values());
184
+ logger.info(`[agent-export] Found ${rooms.length} rooms`);
185
+ const entityMap = /* @__PURE__ */ new Map();
186
+ const participantRecords = [];
187
+ for (const room of rooms) {
188
+ if (!room.id) continue;
189
+ const roomEntities = await db.getEntitiesForRoom(room.id, true);
190
+ for (const entity of roomEntities) if (entity.id) entityMap.set(entity.id, entity);
191
+ const participantIds = await db.getParticipantsForRoom(room.id);
192
+ for (const entityId of participantIds) {
193
+ const userState = await db.getParticipantUserState(room.id, entityId);
194
+ participantRecords.push({
195
+ entityId,
196
+ roomId: room.id,
197
+ userState
198
+ });
199
+ }
200
+ }
201
+ const entities = Array.from(entityMap.values());
202
+ logger.info(`[agent-export] Found ${entities.length} entities, ${participantRecords.length} participant records`);
203
+ const componentIds = /* @__PURE__ */ new Set();
204
+ const allComponents = [];
205
+ const addComponent = (c) => {
206
+ if (c.id && !componentIds.has(c.id)) {
207
+ componentIds.add(c.id);
208
+ allComponents.push(c);
209
+ }
210
+ };
211
+ for (const entity of entities) {
212
+ if (!entity.id) continue;
213
+ for (const c of await db.getComponents(entity.id)) addComponent(c);
214
+ for (const world of agentWorlds) {
215
+ if (!world.id) continue;
216
+ for (const c of await db.getComponents(entity.id, world.id)) addComponent(c);
217
+ }
218
+ }
219
+ logger.info(`[agent-export] Found ${allComponents.length} components`);
220
+ const allMemories = [];
221
+ const memoryIdSet = /* @__PURE__ */ new Set();
222
+ for (const tableName of MEMORY_TABLES) {
223
+ const memories = await db.getMemories({
224
+ agentId,
225
+ tableName,
226
+ count: Number.MAX_SAFE_INTEGER
227
+ });
228
+ for (const mem of memories) if (mem.id && !memoryIdSet.has(mem.id)) {
229
+ memoryIdSet.add(mem.id);
230
+ allMemories.push({
231
+ ...mem,
232
+ embedding: void 0
233
+ });
234
+ }
235
+ }
236
+ for (const world of agentWorlds) {
237
+ if (!world.id) continue;
238
+ for (const tableName of MEMORY_TABLES) {
239
+ const worldMemories = await db.getMemoriesByWorldId({
240
+ worldId: world.id,
241
+ count: Number.MAX_SAFE_INTEGER,
242
+ tableName
243
+ });
244
+ for (const mem of worldMemories) if (mem.id && !memoryIdSet.has(mem.id)) {
245
+ memoryIdSet.add(mem.id);
246
+ allMemories.push({
247
+ ...mem,
248
+ embedding: void 0
249
+ });
250
+ }
251
+ }
252
+ }
253
+ logger.info(`[agent-export] Found ${allMemories.length} memories`);
254
+ const relationships = await db.getRelationships({ entityId: agentId });
255
+ logger.info(`[agent-export] Found ${relationships.length} relationships`);
256
+ const agentTasks = (await db.getTasks({})).filter((t) => taskAgentId(t) === agentId);
257
+ logger.info(`[agent-export] Found ${agentTasks.length} tasks`);
258
+ let logs = [];
259
+ if (options.includeLogs) {
260
+ logs = await db.getLogs({ count: Number.MAX_SAFE_INTEGER });
261
+ logger.info(`[agent-export] Found ${logs.length} logs`);
262
+ }
263
+ let characterConfig;
264
+ if (runtime.character) {
265
+ const { secrets, ...safeChar } = runtime.character;
266
+ characterConfig = safeChar;
267
+ logger.info(`[agent-export] Captured runtime character config (${Object.keys(safeChar).length} fields)`);
268
+ }
269
+ return {
270
+ version: EXPORT_VERSION,
271
+ exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
272
+ sourceAgentId: agentId,
273
+ agent,
274
+ characterConfig,
275
+ entities,
276
+ memories: allMemories,
277
+ components: allComponents,
278
+ rooms,
279
+ participants: participantRecords,
280
+ relationships,
281
+ worlds: agentWorlds,
282
+ tasks: agentTasks,
283
+ logs
284
+ };
285
+ }
286
+ function createIdRemapper(fixed) {
287
+ const map = new Map(fixed);
288
+ return (oldId) => {
289
+ if (!oldId) return oldId;
290
+ const existing = map.get(oldId);
291
+ if (existing) return existing;
292
+ const newId = crypto$1.randomUUID();
293
+ map.set(oldId, newId);
294
+ return newId;
295
+ };
296
+ }
297
+ async function restoreAgentData(runtime, payload) {
298
+ const db = runtime.adapter;
299
+ const newAgentId = crypto$1.randomUUID();
300
+ const remap = createIdRemapper(new Map([[payload.sourceAgentId, newAgentId]]));
301
+ logger.info(`[agent-import] Importing agent "${payload.agent.name}" as ${newAgentId}`);
302
+ const charBase = payload.characterConfig ? { ...payload.characterConfig } : {};
303
+ delete charBase.secrets;
304
+ const agentData = {
305
+ ...charBase,
306
+ ...payload.agent
307
+ };
308
+ agentData.id = newAgentId;
309
+ agentData.enabled = true;
310
+ agentData.createdAt = Date.now();
311
+ agentData.updatedAt = Date.now();
312
+ if (!await db.createAgent(agentData)) throw new AgentExportError("Failed to create agent in database.");
313
+ logger.info(`[agent-import] Created agent record${payload.characterConfig ? " (merged with characterConfig)" : ""}`);
314
+ let worldsImported = 0;
315
+ for (const world of payload.worlds) {
316
+ const newWorld = {
317
+ ...world,
318
+ id: remap(world.id ?? ""),
319
+ agentId: newAgentId
320
+ };
321
+ await db.createWorld(newWorld);
322
+ worldsImported++;
323
+ }
324
+ logger.info(`[agent-import] Imported ${worldsImported} worlds`);
325
+ let roomsImported = 0;
326
+ const roomBatch = [];
327
+ for (const room of payload.rooms) {
328
+ const newRoom = {
329
+ ...room,
330
+ id: remap(room.id ?? ""),
331
+ agentId: newAgentId,
332
+ worldId: room.worldId ? remap(room.worldId) : void 0
333
+ };
334
+ roomBatch.push(newRoom);
335
+ }
336
+ if (roomBatch.length > 0) {
337
+ await db.createRooms(roomBatch);
338
+ roomsImported = roomBatch.length;
339
+ }
340
+ logger.info(`[agent-import] Imported ${roomsImported} rooms`);
341
+ let entitiesImported = 0;
342
+ const entityBatch = [];
343
+ for (const entity of payload.entities) {
344
+ const newEntity = {
345
+ ...entity,
346
+ id: remap(entity.id ?? ""),
347
+ agentId: newAgentId,
348
+ components: void 0
349
+ };
350
+ entityBatch.push(newEntity);
351
+ }
352
+ if (entityBatch.length > 0) {
353
+ await db.createEntities(entityBatch);
354
+ entitiesImported = entityBatch.length;
355
+ }
356
+ logger.info(`[agent-import] Imported ${entitiesImported} entities`);
357
+ let participantsImported = 0;
358
+ for (const p of payload.participants) {
359
+ const newEntityId = remap(p.entityId);
360
+ const newRoomId = remap(p.roomId);
361
+ await db.addParticipantsRoom([newEntityId], newRoomId);
362
+ if (p.userState === "FOLLOWED" || p.userState === "MUTED") await db.setParticipantUserState(newRoomId, newEntityId, p.userState);
363
+ participantsImported++;
364
+ }
365
+ logger.info(`[agent-import] Imported ${participantsImported} participants`);
366
+ let componentsImported = 0;
367
+ for (const comp of payload.components) {
368
+ const newComp = {
369
+ ...comp,
370
+ id: remap(comp.id ?? ""),
371
+ ...comp.entityId ? { entityId: remap(comp.entityId) } : {},
372
+ ...comp.agentId ? { agentId: newAgentId } : {},
373
+ ...comp.roomId ? { roomId: remap(comp.roomId) } : {},
374
+ ...comp.worldId ? { worldId: remap(comp.worldId) } : {},
375
+ ...comp.sourceEntityId ? { sourceEntityId: remap(comp.sourceEntityId) } : {}
376
+ };
377
+ await db.createComponent(newComp);
378
+ componentsImported++;
379
+ }
380
+ logger.info(`[agent-import] Imported ${componentsImported} components`);
381
+ let memoriesImported = 0;
382
+ for (const mem of payload.memories) {
383
+ const tableName = resolveMemoryTableName(mem);
384
+ const newMem = {
385
+ ...mem,
386
+ id: remap(mem.id ?? ""),
387
+ agentId: newAgentId,
388
+ ...mem.entityId ? { entityId: remap(mem.entityId) } : {},
389
+ ...mem.roomId ? { roomId: remap(mem.roomId) } : {},
390
+ ...mem.worldId ? { worldId: remap(mem.worldId) } : {},
391
+ embedding: void 0
392
+ };
393
+ await db.createMemory(newMem, tableName);
394
+ memoriesImported++;
395
+ }
396
+ logger.info(`[agent-import] Imported ${memoriesImported} memories`);
397
+ let relationshipsImported = 0;
398
+ for (const rel of payload.relationships) {
399
+ await db.createRelationship({
400
+ sourceEntityId: remap(rel.sourceEntityId ?? ""),
401
+ targetEntityId: remap(rel.targetEntityId ?? ""),
402
+ tags: rel.tags,
403
+ metadata: rel.metadata
404
+ });
405
+ relationshipsImported++;
406
+ }
407
+ logger.info(`[agent-import] Imported ${relationshipsImported} relationships`);
408
+ let tasksImported = 0;
409
+ for (const task of payload.tasks) {
410
+ const newTask = {
411
+ ...task,
412
+ id: remap(task.id ?? ""),
413
+ agentId: newAgentId,
414
+ roomId: task.roomId ? remap(task.roomId) : void 0,
415
+ worldId: task.worldId ? remap(task.worldId) : void 0,
416
+ entityId: task.entityId ? remap(task.entityId) : void 0
417
+ };
418
+ await db.createTask(newTask);
419
+ tasksImported++;
420
+ }
421
+ logger.info(`[agent-import] Imported ${tasksImported} tasks`);
422
+ let logsImported = 0;
423
+ for (const logEntry of payload.logs) {
424
+ await db.log({
425
+ body: logEntry.body,
426
+ entityId: logEntry.entityId ? remap(logEntry.entityId) : logEntry.entityId,
427
+ roomId: logEntry.roomId ? remap(logEntry.roomId) : newAgentId,
428
+ type: logEntry.type ?? "action"
429
+ });
430
+ logsImported++;
431
+ }
432
+ logger.info(`[agent-import] Imported ${logsImported} logs`);
433
+ return {
434
+ success: true,
435
+ agentId: newAgentId,
436
+ agentName: payload.agent.name ?? "Unknown",
437
+ counts: {
438
+ memories: memoriesImported,
439
+ entities: entitiesImported,
440
+ components: componentsImported,
441
+ rooms: roomsImported,
442
+ participants: participantsImported,
443
+ relationships: relationshipsImported,
444
+ worlds: worldsImported,
445
+ tasks: tasksImported,
446
+ logs: logsImported
447
+ }
448
+ };
449
+ }
450
+ /**
451
+ * Resolve the memory table name from a memory record's metadata.
452
+ * The ElizaOS adapter requires a tableName for createMemory.
453
+ */
454
+ function resolveMemoryTableName(mem) {
455
+ const metaType = mem.metadata?.type;
456
+ if (metaType === "message") return "messages";
457
+ if (metaType === "document") return "documents";
458
+ if (metaType === "fragment") return "fragments";
459
+ if (metaType === "description") return "descriptions";
460
+ if (metaType === "custom") return "custom";
461
+ const memType = mem.type;
462
+ if (typeof memType === "string" && memType.length > 0) return memType;
463
+ return "messages";
464
+ }
465
+ /**
466
+ * Export the current agent's full state as a password-encrypted binary file.
467
+ *
468
+ * @param runtime - The running AgentRuntime with an active database adapter
469
+ * @param password - User-provided password for encryption
470
+ * @param options - Export options (e.g., whether to include logs)
471
+ * @returns A Buffer containing the encrypted .eliza-agent file
472
+ */
473
+ async function exportAgent(runtime, password, options = {}) {
474
+ if (!password || password.length < MIN_PASSWORD_LENGTH) throw new AgentExportError(`A password of at least ${MIN_PASSWORD_LENGTH} characters is required to encrypt the export.`);
475
+ if (!runtime.adapter) throw new AgentExportError("No database adapter available on the runtime.");
476
+ const payload = await extractAgentData(runtime, { includeLogs: options.includeLogs ?? false });
477
+ const jsonString = JSON.stringify(payload);
478
+ const compressed = gzipSync(Buffer.from(jsonString, "utf-8"));
479
+ logger.info(`[agent-export] Payload: ${jsonString.length} bytes JSON → ${compressed.length} bytes compressed`);
480
+ const fileBuffer = packFile(await encrypt(compressed, password));
481
+ logger.info(`[agent-export] Final file size: ${fileBuffer.length} bytes`);
482
+ return fileBuffer;
483
+ }
484
+ /**
485
+ * Import an agent from a password-encrypted .eliza-agent file.
486
+ *
487
+ * @param runtime - An AgentRuntime with an active database adapter (the agent
488
+ * will be created in this database, not overwriting the current agent)
489
+ * @param fileBuffer - The raw bytes of the .eliza-agent file
490
+ * @param password - The password used when the file was exported
491
+ * @returns An ImportResult describing what was imported
492
+ */
493
+ async function importAgent(runtime, fileBuffer, password) {
494
+ if (!password || password.length < MIN_PASSWORD_LENGTH) throw new AgentExportError(`A password of at least ${MIN_PASSWORD_LENGTH} characters is required to decrypt the import.`);
495
+ if (!runtime.adapter) throw new AgentExportError("No database adapter available on the runtime.");
496
+ const { salt, iv, tag, ciphertext, iterations } = unpackFile(fileBuffer);
497
+ let compressed;
498
+ try {
499
+ compressed = await decrypt(ciphertext, password, salt, iv, tag, iterations);
500
+ } catch (err) {
501
+ if (err instanceof Error && (err.message.includes("Unsupported state") || err.message.includes("unable to authenticate") || err.message.includes("auth"))) throw new AgentExportError("Incorrect password — decryption failed. Please check your password and try again.");
502
+ throw new AgentExportError(`Decryption failed: ${err instanceof Error ? err.message : String(err)}`);
503
+ }
504
+ let jsonString;
505
+ try {
506
+ jsonString = (await gunzipWithSizeLimit(compressed)).toString("utf-8");
507
+ } catch (err) {
508
+ if (err instanceof AgentExportError) throw err;
509
+ throw new AgentExportError(`Decompression failed — the file may be corrupt: ${err instanceof Error ? err.message : String(err)}`);
510
+ }
511
+ let rawPayload;
512
+ try {
513
+ rawPayload = JSON.parse(jsonString);
514
+ } catch (err) {
515
+ throw new AgentExportError(`JSON parse failed — the export data is malformed: ${err instanceof Error ? err.message : String(err)}`);
516
+ }
517
+ const parseResult = PayloadSchema.safeParse(rawPayload);
518
+ if (!parseResult.success) throw new AgentExportError(`Export file schema validation failed: ${parseResult.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`);
519
+ const payload = rawPayload;
520
+ if (payload.version > EXPORT_VERSION) throw new AgentExportError(`Unsupported export version ${payload.version}. This build supports up to version ${EXPORT_VERSION}. Please update your software to import this file.`);
521
+ logger.info(`[agent-import] Importing agent "${payload.agent.name}" exported at ${payload.exportedAt}`);
522
+ return restoreAgentData(runtime, payload);
523
+ }
524
+ /**
525
+ * Estimate the size of an agent export without actually creating it.
526
+ * Useful for showing the user how large the export will be.
527
+ */
528
+ async function estimateExportSize(runtime) {
529
+ const db = runtime.adapter;
530
+ const agentId = runtime.agentId;
531
+ let memoriesCount = 0;
532
+ for (const tableName of MEMORY_TABLES) {
533
+ const mems = await db.getMemories({
534
+ agentId,
535
+ tableName,
536
+ count: Number.MAX_SAFE_INTEGER
537
+ });
538
+ memoriesCount += mems.length;
539
+ }
540
+ const agentWorlds = (await db.getAllWorlds()).filter((w) => w.agentId === agentId);
541
+ const roomIds = await db.getRoomsForParticipant(agentId);
542
+ const entityIdSet = /* @__PURE__ */ new Set();
543
+ for (const roomId of roomIds) {
544
+ const roomEntities = await db.getEntitiesForRoom(roomId);
545
+ for (const e of roomEntities) if (e.id) entityIdSet.add(e.id);
546
+ }
547
+ const agentTasks = (await db.getTasks({})).filter((t) => taskAgentId(t) === agentId);
548
+ return {
549
+ estimatedBytes: memoriesCount * 500 + entityIdSet.size * 200 + roomIds.length * 300 + agentWorlds.length * 200 + agentTasks.length * 400 + 2e3,
550
+ memoriesCount,
551
+ entitiesCount: entityIdSet.size,
552
+ roomsCount: roomIds.length,
553
+ worldsCount: agentWorlds.length,
554
+ tasksCount: agentTasks.length
555
+ };
556
+ }
557
+
558
+ //#endregion
559
+ export { AgentExportError, estimateExportSize, exportAgent, importAgent };