agent-world 0.11.1 → 0.12.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 (267) hide show
  1. package/README.md +17 -7
  2. package/dist/cli/commands.d.ts +109 -0
  3. package/dist/cli/commands.js +2024 -0
  4. package/dist/cli/display.d.ts +124 -0
  5. package/dist/cli/display.js +381 -0
  6. package/dist/cli/hitl.d.ts +33 -0
  7. package/dist/cli/hitl.js +81 -0
  8. package/dist/cli/index.d.ts +2 -0
  9. package/dist/cli/stream.d.ts +41 -0
  10. package/dist/cli/stream.js +222 -0
  11. package/dist/core/activity-tracker.d.ts +16 -0
  12. package/dist/core/activity-tracker.d.ts.map +1 -0
  13. package/dist/core/activity-tracker.js +91 -0
  14. package/dist/core/activity-tracker.js.map +1 -0
  15. package/dist/core/ai-commands.d.ts +16 -0
  16. package/dist/core/ai-commands.d.ts.map +1 -0
  17. package/dist/core/ai-commands.js +24 -0
  18. package/dist/core/ai-commands.js.map +1 -0
  19. package/dist/core/ai-sdk-patch.d.ts +24 -0
  20. package/dist/core/ai-sdk-patch.d.ts.map +1 -0
  21. package/dist/core/ai-sdk-patch.js +169 -0
  22. package/dist/core/ai-sdk-patch.js.map +1 -0
  23. package/dist/core/anthropic-direct.d.ts +52 -0
  24. package/dist/core/anthropic-direct.d.ts.map +1 -0
  25. package/dist/core/anthropic-direct.js +301 -0
  26. package/dist/core/anthropic-direct.js.map +1 -0
  27. package/dist/core/approval-cache.d.ts +104 -0
  28. package/dist/core/approval-cache.d.ts.map +1 -0
  29. package/dist/core/approval-cache.js +150 -0
  30. package/dist/core/approval-cache.js.map +1 -0
  31. package/dist/core/chat-constants.d.ts +20 -0
  32. package/dist/core/chat-constants.d.ts.map +1 -0
  33. package/dist/core/chat-constants.js +22 -0
  34. package/dist/core/chat-constants.js.map +1 -0
  35. package/dist/core/create-agent-tool.d.ts +66 -0
  36. package/dist/core/create-agent-tool.d.ts.map +1 -0
  37. package/dist/core/create-agent-tool.js +212 -0
  38. package/dist/core/create-agent-tool.js.map +1 -0
  39. package/dist/core/events/approval-checker.d.ts +61 -0
  40. package/dist/core/events/approval-checker.d.ts.map +1 -0
  41. package/dist/core/events/approval-checker.js +226 -0
  42. package/dist/core/events/approval-checker.js.map +1 -0
  43. package/dist/core/events/index.d.ts +25 -0
  44. package/dist/core/events/index.d.ts.map +1 -0
  45. package/dist/core/events/index.js +30 -0
  46. package/dist/core/events/index.js.map +1 -0
  47. package/dist/core/events/memory-manager.d.ts +73 -0
  48. package/dist/core/events/memory-manager.d.ts.map +1 -0
  49. package/dist/core/events/memory-manager.js +1218 -0
  50. package/dist/core/events/memory-manager.js.map +1 -0
  51. package/dist/core/events/mention-logic.d.ts +39 -0
  52. package/dist/core/events/mention-logic.d.ts.map +1 -0
  53. package/dist/core/events/mention-logic.js +163 -0
  54. package/dist/core/events/mention-logic.js.map +1 -0
  55. package/dist/core/events/orchestrator.d.ts +69 -0
  56. package/dist/core/events/orchestrator.d.ts.map +1 -0
  57. package/dist/core/events/orchestrator.js +883 -0
  58. package/dist/core/events/orchestrator.js.map +1 -0
  59. package/dist/core/events/persistence.d.ts +41 -0
  60. package/dist/core/events/persistence.d.ts.map +1 -0
  61. package/dist/core/events/persistence.js +296 -0
  62. package/dist/core/events/persistence.js.map +1 -0
  63. package/dist/core/events/publishers.d.ts +81 -0
  64. package/dist/core/events/publishers.d.ts.map +1 -0
  65. package/dist/core/events/publishers.js +272 -0
  66. package/dist/core/events/publishers.js.map +1 -0
  67. package/dist/core/events/subscribers.d.ts +45 -0
  68. package/dist/core/events/subscribers.d.ts.map +1 -0
  69. package/dist/core/events/subscribers.js +288 -0
  70. package/dist/core/events/subscribers.js.map +1 -0
  71. package/dist/core/events/tool-bridge-logging.d.ts +28 -0
  72. package/dist/core/events/tool-bridge-logging.d.ts.map +1 -0
  73. package/dist/core/events/tool-bridge-logging.js +94 -0
  74. package/dist/core/events/tool-bridge-logging.js.map +1 -0
  75. package/dist/core/events-metadata.d.ts +72 -0
  76. package/dist/core/events-metadata.d.ts.map +1 -0
  77. package/dist/core/events-metadata.js +167 -0
  78. package/dist/core/events-metadata.js.map +1 -0
  79. package/dist/core/events.d.ts +186 -0
  80. package/dist/core/events.d.ts.map +1 -0
  81. package/dist/core/events.js +1248 -0
  82. package/dist/core/events.js.map +1 -0
  83. package/dist/core/export.d.ts +106 -0
  84. package/dist/core/export.d.ts.map +1 -0
  85. package/dist/core/export.js +705 -0
  86. package/dist/core/export.js.map +1 -0
  87. package/dist/core/file-tools.d.ts +114 -0
  88. package/dist/core/file-tools.d.ts.map +1 -0
  89. package/dist/core/file-tools.js +370 -0
  90. package/dist/core/file-tools.js.map +1 -0
  91. package/dist/core/google-direct.d.ts +58 -0
  92. package/dist/core/google-direct.d.ts.map +1 -0
  93. package/dist/core/google-direct.js +298 -0
  94. package/dist/core/google-direct.js.map +1 -0
  95. package/dist/core/hitl.d.ts +54 -0
  96. package/dist/core/hitl.d.ts.map +1 -0
  97. package/dist/core/hitl.js +153 -0
  98. package/dist/core/hitl.js.map +1 -0
  99. package/dist/core/index.d.ts +59 -0
  100. package/dist/core/index.d.ts.map +1 -0
  101. package/dist/core/index.js +70 -0
  102. package/dist/core/index.js.map +1 -0
  103. package/dist/core/llm-config.d.ts +128 -0
  104. package/dist/core/llm-config.d.ts.map +1 -0
  105. package/dist/core/llm-config.js +164 -0
  106. package/dist/core/llm-config.js.map +1 -0
  107. package/dist/core/llm-manager.d.ts +163 -0
  108. package/dist/core/llm-manager.d.ts.map +1 -0
  109. package/dist/core/llm-manager.js +669 -0
  110. package/dist/core/llm-manager.js.map +1 -0
  111. package/dist/core/load-skill-tool.d.ts +55 -0
  112. package/dist/core/load-skill-tool.d.ts.map +1 -0
  113. package/dist/core/load-skill-tool.js +468 -0
  114. package/dist/core/load-skill-tool.js.map +1 -0
  115. package/dist/core/logger.d.ts +88 -0
  116. package/dist/core/logger.d.ts.map +1 -0
  117. package/dist/core/logger.js +358 -0
  118. package/dist/core/logger.js.map +1 -0
  119. package/dist/core/managers.d.ts +131 -0
  120. package/dist/core/managers.d.ts.map +1 -0
  121. package/dist/core/managers.js +1223 -0
  122. package/dist/core/managers.js.map +1 -0
  123. package/dist/core/mcp-server-registry.d.ts +304 -0
  124. package/dist/core/mcp-server-registry.d.ts.map +1 -0
  125. package/dist/core/mcp-server-registry.js +1769 -0
  126. package/dist/core/mcp-server-registry.js.map +1 -0
  127. package/dist/core/mcp-tools.d.ts +56 -0
  128. package/dist/core/mcp-tools.d.ts.map +1 -0
  129. package/dist/core/mcp-tools.js +186 -0
  130. package/dist/core/mcp-tools.js.map +1 -0
  131. package/dist/core/message-prep.d.ts +81 -0
  132. package/dist/core/message-prep.d.ts.map +1 -0
  133. package/dist/core/message-prep.js +223 -0
  134. package/dist/core/message-prep.js.map +1 -0
  135. package/dist/core/message-processing-control.d.ts +54 -0
  136. package/dist/core/message-processing-control.d.ts.map +1 -0
  137. package/dist/core/message-processing-control.js +139 -0
  138. package/dist/core/message-processing-control.js.map +1 -0
  139. package/dist/core/openai-direct.d.ts +80 -0
  140. package/dist/core/openai-direct.d.ts.map +1 -0
  141. package/dist/core/openai-direct.js +374 -0
  142. package/dist/core/openai-direct.js.map +1 -0
  143. package/dist/core/shell-cmd-tool.d.ts +235 -0
  144. package/dist/core/shell-cmd-tool.d.ts.map +1 -0
  145. package/dist/core/shell-cmd-tool.js +1157 -0
  146. package/dist/core/shell-cmd-tool.js.map +1 -0
  147. package/dist/core/shell-process-registry.d.ts +88 -0
  148. package/dist/core/shell-process-registry.d.ts.map +1 -0
  149. package/dist/core/shell-process-registry.js +309 -0
  150. package/dist/core/shell-process-registry.js.map +1 -0
  151. package/dist/core/skill-registry.d.ts +75 -0
  152. package/dist/core/skill-registry.d.ts.map +1 -0
  153. package/dist/core/skill-registry.js +369 -0
  154. package/dist/core/skill-registry.js.map +1 -0
  155. package/dist/core/skill-script-runner.d.ts +89 -0
  156. package/dist/core/skill-script-runner.d.ts.map +1 -0
  157. package/dist/core/skill-script-runner.js +274 -0
  158. package/dist/core/skill-script-runner.js.map +1 -0
  159. package/dist/core/skill-selector.d.ts +65 -0
  160. package/dist/core/skill-selector.d.ts.map +1 -0
  161. package/dist/core/skill-selector.js +190 -0
  162. package/dist/core/skill-selector.js.map +1 -0
  163. package/dist/core/skill-settings.d.ts +20 -0
  164. package/dist/core/skill-settings.d.ts.map +1 -0
  165. package/dist/core/skill-settings.js +40 -0
  166. package/dist/core/skill-settings.js.map +1 -0
  167. package/dist/core/storage/agent-storage.d.ts +134 -0
  168. package/dist/core/storage/agent-storage.d.ts.map +1 -0
  169. package/dist/core/storage/agent-storage.js +498 -0
  170. package/dist/core/storage/agent-storage.js.map +1 -0
  171. package/dist/core/storage/eventStorage/fileEventStorage.d.ts +100 -0
  172. package/dist/core/storage/eventStorage/fileEventStorage.d.ts.map +1 -0
  173. package/dist/core/storage/eventStorage/fileEventStorage.js +494 -0
  174. package/dist/core/storage/eventStorage/fileEventStorage.js.map +1 -0
  175. package/dist/core/storage/eventStorage/index.d.ts +31 -0
  176. package/dist/core/storage/eventStorage/index.d.ts.map +1 -0
  177. package/dist/core/storage/eventStorage/index.js +31 -0
  178. package/dist/core/storage/eventStorage/index.js.map +1 -0
  179. package/dist/core/storage/eventStorage/memoryEventStorage.d.ts +87 -0
  180. package/dist/core/storage/eventStorage/memoryEventStorage.d.ts.map +1 -0
  181. package/dist/core/storage/eventStorage/memoryEventStorage.js +244 -0
  182. package/dist/core/storage/eventStorage/memoryEventStorage.js.map +1 -0
  183. package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts +45 -0
  184. package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts.map +1 -0
  185. package/dist/core/storage/eventStorage/sqliteEventStorage.js +301 -0
  186. package/dist/core/storage/eventStorage/sqliteEventStorage.js.map +1 -0
  187. package/dist/core/storage/eventStorage/types.d.ts +142 -0
  188. package/dist/core/storage/eventStorage/types.d.ts.map +1 -0
  189. package/dist/core/storage/eventStorage/types.js +43 -0
  190. package/dist/core/storage/eventStorage/types.js.map +1 -0
  191. package/dist/core/storage/eventStorage/validation.d.ts +30 -0
  192. package/dist/core/storage/eventStorage/validation.d.ts.map +1 -0
  193. package/dist/core/storage/eventStorage/validation.js +68 -0
  194. package/dist/core/storage/eventStorage/validation.js.map +1 -0
  195. package/dist/core/storage/legacy-migrations.d.ts +45 -0
  196. package/dist/core/storage/legacy-migrations.d.ts.map +1 -0
  197. package/dist/core/storage/legacy-migrations.js +295 -0
  198. package/dist/core/storage/legacy-migrations.js.map +1 -0
  199. package/dist/core/storage/memory-storage.d.ts +105 -0
  200. package/dist/core/storage/memory-storage.d.ts.map +1 -0
  201. package/dist/core/storage/memory-storage.js +415 -0
  202. package/dist/core/storage/memory-storage.js.map +1 -0
  203. package/dist/core/storage/migration-runner.d.ts +96 -0
  204. package/dist/core/storage/migration-runner.d.ts.map +1 -0
  205. package/dist/core/storage/migration-runner.js +306 -0
  206. package/dist/core/storage/migration-runner.js.map +1 -0
  207. package/dist/core/storage/queue-storage.d.ts +147 -0
  208. package/dist/core/storage/queue-storage.d.ts.map +1 -0
  209. package/dist/core/storage/queue-storage.js +290 -0
  210. package/dist/core/storage/queue-storage.js.map +1 -0
  211. package/dist/core/storage/skill-storage.d.ts +136 -0
  212. package/dist/core/storage/skill-storage.d.ts.map +1 -0
  213. package/dist/core/storage/skill-storage.js +474 -0
  214. package/dist/core/storage/skill-storage.js.map +1 -0
  215. package/dist/core/storage/sqlite-schema.d.ts +95 -0
  216. package/dist/core/storage/sqlite-schema.d.ts.map +1 -0
  217. package/dist/core/storage/sqlite-schema.js +156 -0
  218. package/dist/core/storage/sqlite-schema.js.map +1 -0
  219. package/dist/core/storage/sqlite-storage.d.ts +146 -0
  220. package/dist/core/storage/sqlite-storage.d.ts.map +1 -0
  221. package/dist/core/storage/sqlite-storage.js +709 -0
  222. package/dist/core/storage/sqlite-storage.js.map +1 -0
  223. package/dist/core/storage/storage-factory.d.ts +61 -0
  224. package/dist/core/storage/storage-factory.d.ts.map +1 -0
  225. package/dist/core/storage/storage-factory.js +794 -0
  226. package/dist/core/storage/storage-factory.js.map +1 -0
  227. package/dist/core/storage/validation.d.ts +36 -0
  228. package/dist/core/storage/validation.d.ts.map +1 -0
  229. package/dist/core/storage/validation.js +79 -0
  230. package/dist/core/storage/validation.js.map +1 -0
  231. package/dist/core/storage/world-storage.d.ts +114 -0
  232. package/dist/core/storage/world-storage.d.ts.map +1 -0
  233. package/dist/core/storage/world-storage.js +378 -0
  234. package/dist/core/storage/world-storage.js.map +1 -0
  235. package/dist/core/subscription.d.ts +43 -0
  236. package/dist/core/subscription.d.ts.map +1 -0
  237. package/dist/core/subscription.js +227 -0
  238. package/dist/core/subscription.js.map +1 -0
  239. package/dist/core/tool-utils.d.ts +80 -0
  240. package/dist/core/tool-utils.d.ts.map +1 -0
  241. package/dist/core/tool-utils.js +273 -0
  242. package/dist/core/tool-utils.js.map +1 -0
  243. package/dist/core/types.d.ts +595 -0
  244. package/dist/core/types.d.ts.map +1 -0
  245. package/dist/core/types.js +158 -0
  246. package/dist/core/types.js.map +1 -0
  247. package/dist/core/utils.d.ts +138 -0
  248. package/dist/core/utils.d.ts.map +1 -0
  249. package/dist/core/utils.js +478 -0
  250. package/dist/core/utils.js.map +1 -0
  251. package/dist/core/world-class.d.ts +43 -0
  252. package/dist/core/world-class.d.ts.map +1 -0
  253. package/dist/core/world-class.js +90 -0
  254. package/dist/core/world-class.js.map +1 -0
  255. package/dist/index.d.ts +18 -0
  256. package/dist/public/assets/agent-sprites-DJFgj-zP.png +0 -0
  257. package/dist/public/assets/border-KHK37r8y.svg +83 -0
  258. package/dist/public/assets/index-C9kPXL6G.css +1 -0
  259. package/dist/public/assets/index-DOQEHGWt.js +96 -0
  260. package/dist/public/index.html +21 -0
  261. package/dist/server/api.d.ts +2 -0
  262. package/dist/server/api.js +1124 -0
  263. package/dist/server/index.d.ts +29 -0
  264. package/dist/server/sse-handler.d.ts +62 -0
  265. package/dist/server/sse-handler.js +234 -0
  266. package/package.json +15 -3
  267. package/scripts/launch-electron.js +0 -58
@@ -0,0 +1,709 @@
1
+ /**
2
+ * SQLite Storage Implementation for Agent World System
3
+ *
4
+ * Features:
5
+ * - Full implementation of StorageAPI interface for SQLite backend
6
+ * - Complete chat operations with proper TypeScript types (WorldChat, ChatData, etc.)
7
+ * - Enhanced snapshot operations for world state preservation and restoration
8
+ * - Enhanced archive management with rich metadata and search capabilities
9
+ * - Optimized queries with prepared statements and transactions
10
+ * - Data integrity with foreign key constraints and validation
11
+ * - Migration support from file-based storage
12
+ * - Performance monitoring and analytics
13
+ *
14
+ * Enhanced Chat Features:
15
+ * - Full CRUD operations for world chats with proper type safety
16
+ * - Snapshot storage and restoration with atomic transactions
17
+ * - Foreign key relationships ensuring data consistency
18
+ * - Efficient querying with indexed columns
19
+ *
20
+ * Enhanced Archive Features:
21
+ * - Rich archive metadata (session names, reasons, statistics)
22
+ * - Content-based search across archived conversations
23
+ * - Archive usage analytics and trends
24
+ * - Efficient querying by date, agent, participants
25
+ * - Export capabilities in various formats
26
+ *
27
+ * Implementation:
28
+ * - Maintains compatibility with existing storage interfaces
29
+ * - Uses proper async/await patterns for SQLite operations
30
+ * - Implements batch operations for efficiency
31
+ * - Provides transaction support for data consistency
32
+ * - Includes comprehensive error handling and validation
33
+ * - Complete type safety with proper TypeScript interfaces
34
+ *
35
+ * Recent Changes:
36
+ * - 2026-02-13: Added atomic compare-and-set chat title update helper (`updateChatNameIfCurrent`).
37
+ * - 2026-02-13: Fixed migration directory resolution so Electron runtimes launched from `electron/` still run root `migrations/`.
38
+ * - 2025-08-01: Added proper TypeScript types for all chat operations
39
+ * - 2025-08-01: Implemented restoreFromSnapshot with atomic transactions
40
+ * - 2025-08-01: Enhanced type safety removing any types
41
+ * - 2025-08-06: Fixed initialization order - migration check before schema initialization
42
+ * - 2025-11-02: Integrated SQL migration runner, removed legacy migrations
43
+ */
44
+ import { createSQLiteSchemaContext, validateIntegrity as schemaValidateIntegrity, getDatabaseStats as schemaGetDatabaseStats, closeSchema } from './sqlite-schema.js';
45
+ import { runMigrations } from './migration-runner.js';
46
+ import * as path from 'path';
47
+ import * as fs from 'fs';
48
+ import { fileURLToPath } from 'url';
49
+ export async function createSQLiteStorageContext(config) {
50
+ const schemaCtx = await createSQLiteSchemaContext(config);
51
+ return {
52
+ schemaCtx,
53
+ db: schemaCtx.db,
54
+ isInitialized: false
55
+ };
56
+ }
57
+ function resolveMigrationsDir() {
58
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
59
+ const candidates = [
60
+ path.join(process.cwd(), 'migrations'),
61
+ path.resolve(process.cwd(), '..', 'migrations'),
62
+ path.resolve(moduleDir, '../../migrations'),
63
+ path.resolve(moduleDir, '../../../migrations')
64
+ ];
65
+ for (const candidate of candidates) {
66
+ if (fs.existsSync(candidate)) {
67
+ return candidate;
68
+ }
69
+ }
70
+ return candidates[0];
71
+ }
72
+ async function ensureInitialized(ctx) {
73
+ if (!ctx.isInitialized) {
74
+ const migrationsDir = resolveMigrationsDir();
75
+ // Always run migrations - this handles both fresh databases (starting with 0000)
76
+ // and existing databases that need updates
77
+ await runMigrations({
78
+ db: ctx.schemaCtx.db,
79
+ migrationsDir
80
+ });
81
+ ctx.isInitialized = true;
82
+ }
83
+ }
84
+ /**
85
+ * Utility to initialize the database schema and insert a default world and agent if not present.
86
+ * This is useful for first-time setup or testing.
87
+ */
88
+ export async function initializeWithDefaults(ctx) {
89
+ await ensureInitialized(ctx);
90
+ // Insert default world if not exists
91
+ const defaultWorldId = 'default-world';
92
+ // Only create the default world if no worlds exist in the database
93
+ const worldCountRow = await get(ctx, `SELECT COUNT(*) as count FROM worlds`);
94
+ if (worldCountRow && worldCountRow.count === 0) {
95
+ const defaultWorldId = 'default-world';
96
+ await run(ctx, `
97
+ INSERT INTO worlds (id, name, description, turn_limit, updated_at)
98
+ VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
99
+ `, defaultWorldId, 'Default World', 'The default world for Agent World system.', 100);
100
+ }
101
+ }
102
+ async function run(ctx, sql, ...params) {
103
+ return new Promise((resolve, reject) => {
104
+ ctx.db.run(sql, params, function (err) {
105
+ if (err)
106
+ reject(err);
107
+ else
108
+ resolve(this);
109
+ });
110
+ });
111
+ }
112
+ async function get(ctx, sql, ...params) {
113
+ return new Promise((resolve, reject) => {
114
+ ctx.db.get(sql, params, (err, row) => {
115
+ if (err)
116
+ reject(err);
117
+ else
118
+ resolve(row);
119
+ });
120
+ });
121
+ }
122
+ async function all(ctx, sql, ...params) {
123
+ return new Promise((resolve, reject) => {
124
+ ctx.db.all(sql, params, (err, rows) => {
125
+ if (err)
126
+ reject(err);
127
+ else
128
+ resolve(rows || []);
129
+ });
130
+ });
131
+ }
132
+ // WORLD OPERATIONS
133
+ export async function saveWorld(ctx, worldData) {
134
+ await ensureInitialized(ctx);
135
+ // Use INSERT with ON CONFLICT UPDATE instead of INSERT OR REPLACE to avoid foreign key cascade issues
136
+ await run(ctx, `
137
+ INSERT INTO worlds (id, name, description, turn_limit, main_agent, chat_llm_provider, chat_llm_model, current_chat_id, mcp_config, variables, updated_at)
138
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
139
+ ON CONFLICT(id) DO UPDATE SET
140
+ name = excluded.name,
141
+ description = excluded.description,
142
+ turn_limit = excluded.turn_limit,
143
+ main_agent = excluded.main_agent,
144
+ chat_llm_provider = excluded.chat_llm_provider,
145
+ chat_llm_model = excluded.chat_llm_model,
146
+ current_chat_id = excluded.current_chat_id,
147
+ variables = excluded.variables,
148
+ mcp_config = excluded.mcp_config,
149
+ updated_at = CURRENT_TIMESTAMP
150
+ `, worldData.id, worldData.name, worldData.description, worldData.turnLimit, worldData.mainAgent, worldData.chatLLMProvider, worldData.chatLLMModel, worldData.currentChatId, worldData.mcpConfig, worldData.variables);
151
+ }
152
+ export async function loadWorld(ctx, worldId) {
153
+ await ensureInitialized(ctx);
154
+ const result = await get(ctx, `
155
+ SELECT id, name, description, turn_limit as turnLimit,
156
+ main_agent as mainAgent,
157
+ chat_llm_provider as chatLLMProvider, chat_llm_model as chatLLMModel,
158
+ current_chat_id as currentChatId, mcp_config as mcpConfig,
159
+ variables as variables
160
+ FROM worlds WHERE id = ?
161
+ `, worldId);
162
+ return result || null;
163
+ }
164
+ export async function deleteWorld(ctx, worldId) {
165
+ await ensureInitialized(ctx);
166
+ try {
167
+ const result = await run(ctx, `DELETE FROM worlds WHERE id = ?`, worldId);
168
+ return result.changes > 0;
169
+ }
170
+ catch {
171
+ return false;
172
+ }
173
+ }
174
+ export async function listWorlds(ctx) {
175
+ await ensureInitialized(ctx);
176
+ const results = await all(ctx, `
177
+ SELECT id, name, description, turn_limit as turnLimit,
178
+ main_agent as mainAgent,
179
+ chat_llm_provider as chatLLMProvider, chat_llm_model as chatLLMModel,
180
+ current_chat_id as currentChatId, mcp_config as mcpConfig,
181
+ variables as variables
182
+ FROM worlds
183
+ ORDER BY name
184
+ `);
185
+ return results || [];
186
+ }
187
+ // AGENT OPERATIONS
188
+ export async function saveAgent(ctx, worldId, agent) {
189
+ await ensureInitialized(ctx);
190
+ await run(ctx, `
191
+ INSERT OR REPLACE INTO agents (
192
+ id, world_id, name, type, status, provider, model, system_prompt,
193
+ temperature, max_tokens, auto_reply, llm_call_count, last_active, last_llm_call
194
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
195
+ `, agent.id, worldId, agent.name, agent.type, agent.status || 'inactive', agent.provider, agent.model, agent.systemPrompt, agent.temperature, agent.maxTokens, agent.autoReply === false ? 0 : 1, agent.llmCallCount, agent.lastActive?.toISOString(), agent.lastLLMCall?.toISOString());
196
+ if (agent.memory && agent.memory.length > 0) {
197
+ await saveAgentMemory(ctx, worldId, agent.id, agent.memory);
198
+ }
199
+ }
200
+ export async function loadAgent(ctx, worldId, agentId) {
201
+ await ensureInitialized(ctx);
202
+ const agentData = await get(ctx, `
203
+ SELECT id, name, type, status, provider, model, system_prompt as systemPrompt,
204
+ temperature, max_tokens as maxTokens, auto_reply as autoReply, llm_call_count as llmCallCount,
205
+ created_at as createdAt, last_active as lastActive, last_llm_call as lastLLMCall
206
+ FROM agents WHERE id = ? AND world_id = ?
207
+ `, agentId, worldId);
208
+ if (!agentData)
209
+ return null;
210
+ const memoryData = await all(ctx, `
211
+ SELECT role, content, sender, chat_id as chatId, message_id as messageId, reply_to_message_id as replyToMessageId,
212
+ tool_calls as toolCalls, tool_call_id as toolCallId, created_at as createdAt
213
+ FROM agent_memory
214
+ WHERE agent_id = ? AND world_id = ?
215
+ ORDER BY created_at ASC
216
+ `, agentId, worldId);
217
+ const agent = {
218
+ ...agentData,
219
+ autoReply: agentData.autoReply === 0 ? false : true,
220
+ createdAt: agentData.createdAt ? new Date(agentData.createdAt) : new Date(),
221
+ lastActive: agentData.lastActive ? new Date(agentData.lastActive) : new Date(),
222
+ lastLLMCall: agentData.lastLLMCall ? new Date(agentData.lastLLMCall) : undefined,
223
+ memory: memoryData.map(msg => ({
224
+ ...msg,
225
+ createdAt: msg.createdAt ? new Date(msg.createdAt) : new Date(),
226
+ chatId: msg.chatId, // Preserve chatId field
227
+ tool_calls: msg.toolCalls ? JSON.parse(msg.toolCalls) : undefined,
228
+ tool_call_id: msg.toolCallId || undefined
229
+ })),
230
+ };
231
+ return agent;
232
+ }
233
+ export async function deleteAgent(ctx, worldId, agentId) {
234
+ await ensureInitialized(ctx);
235
+ try {
236
+ const result = await run(ctx, `
237
+ DELETE FROM agents WHERE id = ? AND world_id = ?
238
+ `, agentId, worldId);
239
+ return result.changes > 0;
240
+ }
241
+ catch {
242
+ return false;
243
+ }
244
+ }
245
+ export async function listAgents(ctx, worldId) {
246
+ await ensureInitialized(ctx);
247
+ const agents = await all(ctx, `
248
+ SELECT id, name, type, status, provider, model, system_prompt as systemPrompt,
249
+ temperature, max_tokens as maxTokens, auto_reply as autoReply, llm_call_count as llmCallCount,
250
+ created_at as createdAt, last_active as lastActive, last_llm_call as lastLLMCall
251
+ FROM agents WHERE world_id = ?
252
+ ORDER BY name
253
+ `, worldId);
254
+ const result = [];
255
+ for (const agentData of agents) {
256
+ const memoryData = await all(ctx, `
257
+ SELECT role, content, sender, chat_id as chatId, message_id as messageId, reply_to_message_id as replyToMessageId,
258
+ tool_calls as toolCalls, tool_call_id as toolCallId, created_at as createdAt
259
+ FROM agent_memory
260
+ WHERE agent_id = ? AND world_id = ?
261
+ ORDER BY created_at ASC
262
+ `, agentData.id, worldId);
263
+ const agent = {
264
+ ...agentData,
265
+ autoReply: agentData.autoReply === 0 ? false : true,
266
+ createdAt: agentData.createdAt ? new Date(agentData.createdAt) : new Date(),
267
+ lastActive: agentData.lastActive ? new Date(agentData.lastActive) : new Date(),
268
+ lastLLMCall: agentData.lastLLMCall ? new Date(agentData.lastLLMCall) : undefined,
269
+ memory: memoryData.map(msg => ({
270
+ ...msg,
271
+ createdAt: msg.createdAt ? new Date(msg.createdAt) : new Date(),
272
+ chatId: msg.chatId, // Preserve chatId field
273
+ replyToMessageId: msg.replyToMessageId, // Preserve replyToMessageId field
274
+ tool_calls: msg.tool_calls ? JSON.parse(msg.tool_calls) : undefined // Parse JSON string to object
275
+ })),
276
+ };
277
+ result.push(agent);
278
+ }
279
+ return result;
280
+ }
281
+ export async function saveAgentMemory(ctx, worldId, agentId, memory) {
282
+ await run(ctx, `DELETE FROM agent_memory WHERE agent_id = ? AND world_id = ?`, agentId, worldId);
283
+ // CRITICAL: Filter out system messages - they should NEVER be saved to storage
284
+ // System messages are generated dynamically during LLM preparation
285
+ const filteredMemory = memory.filter(msg => msg.role !== 'system');
286
+ if (filteredMemory.length < memory.length) {
287
+ const logger = await import('../logger.js').then(m => m.logger);
288
+ logger.warn('Filtered out system messages from agent memory before saving to SQLite', {
289
+ agentId,
290
+ worldId,
291
+ removedCount: memory.length - filteredMemory.length,
292
+ remainingCount: filteredMemory.length
293
+ });
294
+ }
295
+ for (const message of filteredMemory) {
296
+ await run(ctx, `
297
+ INSERT INTO agent_memory (agent_id, world_id, role, content, sender, chat_id, message_id, reply_to_message_id, tool_calls, tool_call_id, created_at)
298
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
299
+ `, agentId, worldId, message.role, message.content, message.sender, message.chatId, message.messageId, message.replyToMessageId, message.tool_calls ? JSON.stringify(message.tool_calls) : null, message.tool_call_id || null, message.createdAt instanceof Date ? message.createdAt.toISOString() : (message.createdAt || new Date().toISOString()));
300
+ }
301
+ }
302
+ // MEMORY CLEANUP OPERATIONS
303
+ export async function deleteMemoryByChatId(ctx, worldId, chatId) {
304
+ await ensureInitialized(ctx);
305
+ const result = await run(ctx, `
306
+ DELETE FROM agent_memory WHERE world_id = ? AND chat_id = ?
307
+ `, worldId, chatId);
308
+ return result.changes || 0;
309
+ }
310
+ // GET MEMORY (aggregated across agents for a given chat)
311
+ export async function getMemory(ctx, worldId, chatId) {
312
+ await ensureInitialized(ctx);
313
+ const rows = await all(ctx, `
314
+ SELECT role, content, sender, chat_id as chatId, message_id as messageId, reply_to_message_id as replyToMessageId,
315
+ tool_calls as toolCalls, tool_call_id as toolCallId, agent_id as agentId, created_at as createdAt
316
+ FROM agent_memory
317
+ WHERE world_id = ? AND (? = '' OR chat_id = ?)
318
+ ORDER BY datetime(created_at) ASC, rowid ASC
319
+ `, worldId, chatId || '', chatId || '');
320
+ return (rows || []).map((r) => ({
321
+ role: r.role,
322
+ content: r.content,
323
+ sender: r.sender,
324
+ chatId: r.chatId,
325
+ messageId: r.messageId,
326
+ replyToMessageId: r.replyToMessageId, // FIX: Include replyToMessageId from database
327
+ tool_calls: r.toolCalls ? JSON.parse(r.toolCalls) : undefined,
328
+ tool_call_id: r.toolCallId || undefined,
329
+ agentId: r.agentId,
330
+ createdAt: r.createdAt ? new Date(r.createdAt) : new Date()
331
+ }));
332
+ }
333
+ // BATCH OPERATIONS
334
+ export async function saveAgentsBatch(ctx, worldId, agents) {
335
+ await ensureInitialized(ctx);
336
+ for (const agent of agents) {
337
+ await saveAgent(ctx, worldId, agent);
338
+ }
339
+ }
340
+ export async function loadAgentsBatch(ctx, worldId, agentIds) {
341
+ await ensureInitialized(ctx);
342
+ const agents = [];
343
+ for (const agentId of agentIds) {
344
+ const agent = await loadAgent(ctx, worldId, agentId);
345
+ if (agent)
346
+ agents.push(agent);
347
+ }
348
+ return agents;
349
+ }
350
+ // INTEGRITY OPERATIONS
351
+ export async function validateIntegrity(ctx, worldId, agentId) {
352
+ await ensureInitialized(ctx);
353
+ const schemaValidation = await schemaValidateIntegrity(ctx.schemaCtx);
354
+ if (!schemaValidation.isValid)
355
+ return false;
356
+ try {
357
+ if (agentId) {
358
+ const agent = await get(ctx, `
359
+ SELECT id FROM agents WHERE id = ? AND world_id = ?
360
+ `, agentId, worldId);
361
+ return !!agent;
362
+ }
363
+ else {
364
+ const world = await get(ctx, `SELECT id FROM worlds WHERE id = ?`, worldId);
365
+ return !!world;
366
+ }
367
+ }
368
+ catch {
369
+ return false;
370
+ }
371
+ }
372
+ export async function repairData(ctx, worldId, agentId) {
373
+ await ensureInitialized(ctx);
374
+ return false;
375
+ }
376
+ // CHAT HISTORY OPERATIONS
377
+ export async function saveChatData(ctx, worldId, chat) {
378
+ await ensureInitialized(ctx);
379
+ await run(ctx, `
380
+ INSERT INTO world_chats (id, world_id, name, description, message_count, tags, updated_at)
381
+ VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
382
+ ON CONFLICT(id) DO UPDATE SET
383
+ name = excluded.name,
384
+ description = excluded.description,
385
+ message_count = excluded.message_count,
386
+ tags = excluded.tags,
387
+ updated_at = CURRENT_TIMESTAMP
388
+ `, chat.id, worldId, chat.name, chat.description, chat.messageCount || 0);
389
+ }
390
+ export async function loadChatData(ctx, worldId, chatId) {
391
+ await ensureInitialized(ctx);
392
+ const result = await get(ctx, `
393
+ SELECT id, world_id as worldId, name, description, message_count as messageCount,
394
+ tags, created_at as createdAt, updated_at as updatedAt
395
+ FROM world_chats
396
+ WHERE id = ? AND world_id = ?
397
+ `, chatId, worldId);
398
+ if (!result)
399
+ return null;
400
+ // Load chat if exists
401
+ const chat = await get(ctx, `
402
+ SELECT snapshot_data as snapshotData, captured_at as capturedAt, version
403
+ FROM chat_snapshots
404
+ WHERE chat_id = ? AND world_id = ?
405
+ ORDER BY captured_at DESC
406
+ LIMIT 1
407
+ `, chatId, worldId);
408
+ return {
409
+ ...result,
410
+ createdAt: new Date(result.createdAt),
411
+ updatedAt: new Date(result.updatedAt),
412
+ tags: JSON.parse(result.tags || '[]'),
413
+ chat: chat ? {
414
+ ...JSON.parse(chat.snapshotData),
415
+ metadata: {
416
+ ...JSON.parse(chat.snapshotData).metadata,
417
+ capturedAt: new Date(chat.capturedAt),
418
+ version: chat.version
419
+ }
420
+ } : undefined
421
+ };
422
+ }
423
+ export async function deleteChatData(ctx, worldId, chatId) {
424
+ await ensureInitialized(ctx);
425
+ const result = await run(ctx, `
426
+ DELETE FROM world_chats WHERE id = ? AND world_id = ?
427
+ `, chatId, worldId);
428
+ return result.changes > 0;
429
+ }
430
+ export async function listChatHistories(ctx, worldId) {
431
+ await ensureInitialized(ctx);
432
+ const results = await all(ctx, `
433
+ SELECT id, name, description, message_count as messageCount,
434
+ tags, created_at as createdAt, updated_at as updatedAt
435
+ FROM world_chats
436
+ WHERE world_id = ?
437
+ ORDER BY updated_at DESC
438
+ `, worldId);
439
+ return results.map(chat => ({
440
+ ...chat,
441
+ createdAt: new Date(chat.createdAt),
442
+ updatedAt: new Date(chat.updatedAt),
443
+ tags: JSON.parse(chat.tags || '[]')
444
+ }));
445
+ }
446
+ export async function updateChatData(ctx, worldId, chatId, updates) {
447
+ await ensureInitialized(ctx);
448
+ const setClauses = [];
449
+ const params = [];
450
+ if (updates.name !== undefined) {
451
+ setClauses.push('name = ?');
452
+ params.push(updates.name);
453
+ }
454
+ if (updates.description !== undefined) {
455
+ setClauses.push('description = ?');
456
+ params.push(updates.description);
457
+ }
458
+ if (updates.tags !== undefined) {
459
+ setClauses.push('tags = ?');
460
+ params.push(JSON.stringify(updates.tags));
461
+ }
462
+ if (updates.messageCount !== undefined) {
463
+ setClauses.push('message_count = ?');
464
+ params.push(updates.messageCount);
465
+ }
466
+ if (setClauses.length === 0) {
467
+ return await loadChatData(ctx, worldId, chatId);
468
+ }
469
+ setClauses.push('updated_at = CURRENT_TIMESTAMP');
470
+ params.push(chatId, worldId);
471
+ await run(ctx, `
472
+ UPDATE world_chats
473
+ SET ${setClauses.join(', ')}
474
+ WHERE id = ? AND world_id = ?
475
+ `, ...params);
476
+ return await loadChatData(ctx, worldId, chatId);
477
+ }
478
+ export async function updateChatNameIfCurrent(ctx, worldId, chatId, expectedName, nextName) {
479
+ await ensureInitialized(ctx);
480
+ const result = await run(ctx, `
481
+ UPDATE world_chats
482
+ SET name = ?, updated_at = CURRENT_TIMESTAMP
483
+ WHERE id = ? AND world_id = ? AND name = ?
484
+ `, nextName, chatId, worldId, expectedName);
485
+ return (result.changes || 0) > 0;
486
+ }
487
+ // CHAT OPERATIONS
488
+ export async function saveWorldChat(ctx, worldId, chatId, chat) {
489
+ await ensureInitialized(ctx);
490
+ await run(ctx, `
491
+ INSERT INTO chat_snapshots (chat_id, world_id, snapshot_data, version)
492
+ VALUES (?, ?, ?, ?)
493
+ `, chatId, worldId, JSON.stringify(chat), chat.metadata?.version || '1.0');
494
+ }
495
+ export async function loadWorldChatFull(ctx, worldId, chatId) {
496
+ await ensureInitialized(ctx);
497
+ // Get the chat metadata
498
+ const result = await get(ctx, `
499
+ SELECT id, name, description, message_count as messageCount,
500
+ tags, created_at as createdAt, updated_at as updatedAt
501
+ FROM world_chats
502
+ WHERE id = ? AND world_id = ?
503
+ `, chatId, worldId);
504
+ if (!result)
505
+ return null;
506
+ // Get the chat snapshot data
507
+ const chat = await get(ctx, `
508
+ SELECT snapshot_data as snapshotData, captured_at as capturedAt, version
509
+ FROM chat_snapshots
510
+ WHERE chat_id = ? AND world_id = ?
511
+ ORDER BY captured_at DESC
512
+ LIMIT 1
513
+ `, chatId, worldId);
514
+ if (!chat)
515
+ return null; // No snapshot data found
516
+ const snapshotData = JSON.parse(chat.snapshotData);
517
+ // Return merged WorldChat with snapshot fields accessible directly
518
+ // This matches the web interface expectation
519
+ return {
520
+ // Chat metadata (ChatInfo + worldId)
521
+ id: result.id,
522
+ worldId: worldId,
523
+ name: result.name,
524
+ description: result.description,
525
+ createdAt: new Date(result.createdAt),
526
+ updatedAt: new Date(result.updatedAt),
527
+ messageCount: result.messageCount,
528
+ tags: JSON.parse(result.tags || '[]'),
529
+ // Snapshot data (core WorldChat fields)
530
+ world: snapshotData.world,
531
+ agents: snapshotData.agents,
532
+ messages: snapshotData.messages,
533
+ metadata: {
534
+ ...snapshotData.metadata,
535
+ capturedAt: new Date(chat.capturedAt),
536
+ version: chat.version
537
+ }
538
+ }; // Use 'as any' since this is a merged type that differs between web and core
539
+ }
540
+ export async function loadWorldChat(ctx, worldId, chatId) {
541
+ await ensureInitialized(ctx);
542
+ const result = await get(ctx, `
543
+ SELECT snapshot_data as snapshotData, captured_at as capturedAt, version
544
+ FROM chat_snapshots
545
+ WHERE chat_id = ? AND world_id = ?
546
+ ORDER BY captured_at DESC
547
+ LIMIT 1
548
+ `, chatId, worldId);
549
+ if (!result)
550
+ return null;
551
+ const chat = JSON.parse(result.snapshotData);
552
+ return {
553
+ ...chat,
554
+ metadata: {
555
+ ...chat.metadata,
556
+ capturedAt: new Date(result.capturedAt),
557
+ version: result.version
558
+ }
559
+ };
560
+ }
561
+ export async function restoreFromWorldChat(ctx, worldId, chat) {
562
+ await ensureInitialized(ctx);
563
+ try {
564
+ // Begin transaction for atomic restore
565
+ await run(ctx, 'BEGIN TRANSACTION');
566
+ // Restore world data
567
+ if (chat.world) {
568
+ await run(ctx, `
569
+ UPDATE worlds
570
+ SET name = ?, description = ?, turn_limit = ?, main_agent = ?, chat_llm_provider = ?, chat_llm_model = ?
571
+ WHERE id = ?
572
+ `, chat.world.name, chat.world.description, chat.world.turnLimit, chat.world.mainAgent, chat.world.chatLLMProvider, chat.world.chatLLMModel, worldId);
573
+ }
574
+ // Clear existing agents for this world
575
+ await run(ctx, 'DELETE FROM agents WHERE world_id = ?', worldId);
576
+ // Restore agents
577
+ if (chat.agents && chat.agents.length > 0) {
578
+ for (const agent of chat.agents) {
579
+ await run(ctx, `
580
+ INSERT INTO agents (
581
+ id, world_id, name, type, status, provider, model, system_prompt,
582
+ temperature, max_tokens, auto_reply, created_at, last_active, llm_call_count, last_llm_call
583
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
584
+ `, agent.id, worldId, agent.name, agent.type, agent.status || 'active', agent.provider, agent.model, agent.systemPrompt, agent.temperature, agent.maxTokens, agent.autoReply === false ? 0 : 1, agent.createdAt instanceof Date ? agent.createdAt.toISOString() : agent.createdAt, agent.lastActive instanceof Date ? agent.lastActive.toISOString() : agent.lastActive, agent.llmCallCount || 0, agent.lastLLMCall instanceof Date ? agent.lastLLMCall.toISOString() : agent.lastLLMCall);
585
+ // Clear and restore agent memory
586
+ await run(ctx, 'DELETE FROM agent_memory WHERE agent_id = ? AND world_id = ?', agent.id, worldId);
587
+ if (agent.memory && agent.memory.length > 0) {
588
+ for (const message of agent.memory) {
589
+ await run(ctx, `
590
+ INSERT INTO agent_memory (agent_id, world_id, role, content, sender, chat_id, message_id, reply_to_message_id, tool_calls, tool_call_id, created_at)
591
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
592
+ `, agent.id, worldId, message.role, message.content, message.sender, message.chatId, message.messageId, message.replyToMessageId, message.tool_calls ? JSON.stringify(message.tool_calls) : null, message.tool_call_id || null, message.createdAt instanceof Date ? message.createdAt.toISOString() : (message.createdAt || new Date().toISOString()));
593
+ }
594
+ }
595
+ }
596
+ }
597
+ await run(ctx, 'COMMIT');
598
+ return true;
599
+ }
600
+ catch (error) {
601
+ await run(ctx, 'ROLLBACK');
602
+ console.error('[sqlite-storage] Failed to restore from world chat:', error);
603
+ return false;
604
+ }
605
+ }
606
+ // ARCHIVE OPERATIONS
607
+ export async function archiveAgentMemory(ctx, worldId, agentId, memory, metadata) {
608
+ await ensureInitialized(ctx);
609
+ const participants = metadata?.participants || [...new Set(memory.map(m => m.sender).filter(Boolean))];
610
+ const firstMessage = memory.length > 0 ? memory[0] : null;
611
+ const lastMessage = memory.length > 0 ? memory[memory.length - 1] : null;
612
+ const startTime = metadata?.startTime || (firstMessage?.createdAt ? (firstMessage.createdAt instanceof Date ? firstMessage.createdAt.toISOString() : firstMessage.createdAt) : new Date().toISOString());
613
+ const endTime = metadata?.endTime || (lastMessage?.createdAt ? (lastMessage.createdAt instanceof Date ? lastMessage.createdAt.toISOString() : lastMessage.createdAt) : new Date().toISOString());
614
+ const archiveResult = await run(ctx, `
615
+ INSERT INTO memory_archives (
616
+ agent_id, world_id, session_name, archive_reason, message_count,
617
+ start_time, end_time, participants, tags
618
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
619
+ `, agentId, worldId, metadata?.sessionName, metadata?.archiveReason, memory.length, startTime, endTime, JSON.stringify(participants), JSON.stringify(metadata?.tags || []));
620
+ const archiveId = archiveResult.lastID;
621
+ for (const message of memory) {
622
+ await run(ctx, `
623
+ INSERT INTO archived_messages (
624
+ archive_id, role, content, sender, original_created_at
625
+ ) VALUES (?, ?, ?, ?, ?)
626
+ `, archiveId, message.role, message.content, message.sender, message.createdAt instanceof Date ? message.createdAt.toISOString() : (message.createdAt || new Date().toISOString()));
627
+ }
628
+ return archiveId;
629
+ }
630
+ // SEARCH AND STATS
631
+ export async function searchArchives(ctx, options) {
632
+ await ensureInitialized(ctx);
633
+ const archives = await all(ctx, `
634
+ SELECT id, agent_id as agentId, world_id as worldId,
635
+ session_name as sessionName, archive_reason as archiveReason,
636
+ message_count as messageCount, start_time as startTime,
637
+ end_time as endTime, participants, tags,
638
+ created_at as createdAt
639
+ FROM memory_archives
640
+ WHERE world_id = ?
641
+ ORDER BY created_at DESC
642
+ LIMIT 50
643
+ `, options.worldId || '');
644
+ const result = archives.map(archive => ({
645
+ ...archive,
646
+ startTime: archive.startTime ? new Date(archive.startTime) : undefined,
647
+ endTime: archive.endTime ? new Date(archive.endTime) : undefined,
648
+ participants: JSON.parse(archive.participants || '[]'),
649
+ tags: JSON.parse(archive.tags || '[]'),
650
+ createdAt: new Date(archive.createdAt)
651
+ }));
652
+ return {
653
+ archives: result,
654
+ totalCount: result.length,
655
+ hasMore: false
656
+ };
657
+ }
658
+ export async function getArchiveStatistics(ctx, worldId, agentId) {
659
+ await ensureInitialized(ctx);
660
+ const basicStats = await get(ctx, `
661
+ SELECT COUNT(*) as totalArchives,
662
+ SUM(message_count) as totalMessages,
663
+ AVG(message_count) as averageSessionLength
664
+ FROM memory_archives
665
+ WHERE world_id = ?
666
+ `, worldId);
667
+ return {
668
+ totalArchives: basicStats?.totalArchives || 0,
669
+ totalMessages: basicStats?.totalMessages || 0,
670
+ averageSessionLength: basicStats?.averageSessionLength || 0,
671
+ mostActiveAgent: '',
672
+ archiveFrequency: {}
673
+ };
674
+ }
675
+ export async function exportArchive(ctx, archiveId, options) {
676
+ await ensureInitialized(ctx);
677
+ const archive = await get(ctx, `
678
+ SELECT * FROM memory_archives WHERE id = ?
679
+ `, archiveId);
680
+ if (!archive)
681
+ throw new Error('Archive not found');
682
+ let messages = [];
683
+ if (options.includeMessages) {
684
+ messages = await all(ctx, `
685
+ SELECT role, content, sender, original_created_at as createdAt
686
+ FROM archived_messages
687
+ WHERE archive_id = ?
688
+ ORDER BY id ASC
689
+ `, archiveId);
690
+ }
691
+ const exportData = {
692
+ metadata: options.includeMetadata ? {
693
+ id: archive.id,
694
+ agentId: archive.agent_id,
695
+ worldId: archive.world_id,
696
+ sessionName: archive.session_name,
697
+ createdAt: archive.created_at
698
+ } : undefined,
699
+ messages: options.includeMessages ? messages : undefined
700
+ };
701
+ return JSON.stringify(exportData, null, 2);
702
+ }
703
+ export async function close(ctx) {
704
+ return closeSchema(ctx.schemaCtx);
705
+ }
706
+ export async function getDatabaseStats(ctx) {
707
+ return schemaGetDatabaseStats(ctx.schemaCtx);
708
+ }
709
+ //# sourceMappingURL=sqlite-storage.js.map