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.
- package/README.md +17 -7
- package/dist/cli/commands.d.ts +109 -0
- package/dist/cli/commands.js +2024 -0
- package/dist/cli/display.d.ts +124 -0
- package/dist/cli/display.js +381 -0
- package/dist/cli/hitl.d.ts +33 -0
- package/dist/cli/hitl.js +81 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/stream.d.ts +41 -0
- package/dist/cli/stream.js +222 -0
- package/dist/core/activity-tracker.d.ts +16 -0
- package/dist/core/activity-tracker.d.ts.map +1 -0
- package/dist/core/activity-tracker.js +91 -0
- package/dist/core/activity-tracker.js.map +1 -0
- package/dist/core/ai-commands.d.ts +16 -0
- package/dist/core/ai-commands.d.ts.map +1 -0
- package/dist/core/ai-commands.js +24 -0
- package/dist/core/ai-commands.js.map +1 -0
- package/dist/core/ai-sdk-patch.d.ts +24 -0
- package/dist/core/ai-sdk-patch.d.ts.map +1 -0
- package/dist/core/ai-sdk-patch.js +169 -0
- package/dist/core/ai-sdk-patch.js.map +1 -0
- package/dist/core/anthropic-direct.d.ts +52 -0
- package/dist/core/anthropic-direct.d.ts.map +1 -0
- package/dist/core/anthropic-direct.js +301 -0
- package/dist/core/anthropic-direct.js.map +1 -0
- package/dist/core/approval-cache.d.ts +104 -0
- package/dist/core/approval-cache.d.ts.map +1 -0
- package/dist/core/approval-cache.js +150 -0
- package/dist/core/approval-cache.js.map +1 -0
- package/dist/core/chat-constants.d.ts +20 -0
- package/dist/core/chat-constants.d.ts.map +1 -0
- package/dist/core/chat-constants.js +22 -0
- package/dist/core/chat-constants.js.map +1 -0
- package/dist/core/create-agent-tool.d.ts +66 -0
- package/dist/core/create-agent-tool.d.ts.map +1 -0
- package/dist/core/create-agent-tool.js +212 -0
- package/dist/core/create-agent-tool.js.map +1 -0
- package/dist/core/events/approval-checker.d.ts +61 -0
- package/dist/core/events/approval-checker.d.ts.map +1 -0
- package/dist/core/events/approval-checker.js +226 -0
- package/dist/core/events/approval-checker.js.map +1 -0
- package/dist/core/events/index.d.ts +25 -0
- package/dist/core/events/index.d.ts.map +1 -0
- package/dist/core/events/index.js +30 -0
- package/dist/core/events/index.js.map +1 -0
- package/dist/core/events/memory-manager.d.ts +73 -0
- package/dist/core/events/memory-manager.d.ts.map +1 -0
- package/dist/core/events/memory-manager.js +1218 -0
- package/dist/core/events/memory-manager.js.map +1 -0
- package/dist/core/events/mention-logic.d.ts +39 -0
- package/dist/core/events/mention-logic.d.ts.map +1 -0
- package/dist/core/events/mention-logic.js +163 -0
- package/dist/core/events/mention-logic.js.map +1 -0
- package/dist/core/events/orchestrator.d.ts +69 -0
- package/dist/core/events/orchestrator.d.ts.map +1 -0
- package/dist/core/events/orchestrator.js +883 -0
- package/dist/core/events/orchestrator.js.map +1 -0
- package/dist/core/events/persistence.d.ts +41 -0
- package/dist/core/events/persistence.d.ts.map +1 -0
- package/dist/core/events/persistence.js +296 -0
- package/dist/core/events/persistence.js.map +1 -0
- package/dist/core/events/publishers.d.ts +81 -0
- package/dist/core/events/publishers.d.ts.map +1 -0
- package/dist/core/events/publishers.js +272 -0
- package/dist/core/events/publishers.js.map +1 -0
- package/dist/core/events/subscribers.d.ts +45 -0
- package/dist/core/events/subscribers.d.ts.map +1 -0
- package/dist/core/events/subscribers.js +288 -0
- package/dist/core/events/subscribers.js.map +1 -0
- package/dist/core/events/tool-bridge-logging.d.ts +28 -0
- package/dist/core/events/tool-bridge-logging.d.ts.map +1 -0
- package/dist/core/events/tool-bridge-logging.js +94 -0
- package/dist/core/events/tool-bridge-logging.js.map +1 -0
- package/dist/core/events-metadata.d.ts +72 -0
- package/dist/core/events-metadata.d.ts.map +1 -0
- package/dist/core/events-metadata.js +167 -0
- package/dist/core/events-metadata.js.map +1 -0
- package/dist/core/events.d.ts +186 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +1248 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/export.d.ts +106 -0
- package/dist/core/export.d.ts.map +1 -0
- package/dist/core/export.js +705 -0
- package/dist/core/export.js.map +1 -0
- package/dist/core/file-tools.d.ts +114 -0
- package/dist/core/file-tools.d.ts.map +1 -0
- package/dist/core/file-tools.js +370 -0
- package/dist/core/file-tools.js.map +1 -0
- package/dist/core/google-direct.d.ts +58 -0
- package/dist/core/google-direct.d.ts.map +1 -0
- package/dist/core/google-direct.js +298 -0
- package/dist/core/google-direct.js.map +1 -0
- package/dist/core/hitl.d.ts +54 -0
- package/dist/core/hitl.d.ts.map +1 -0
- package/dist/core/hitl.js +153 -0
- package/dist/core/hitl.js.map +1 -0
- package/dist/core/index.d.ts +59 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +70 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/llm-config.d.ts +128 -0
- package/dist/core/llm-config.d.ts.map +1 -0
- package/dist/core/llm-config.js +164 -0
- package/dist/core/llm-config.js.map +1 -0
- package/dist/core/llm-manager.d.ts +163 -0
- package/dist/core/llm-manager.d.ts.map +1 -0
- package/dist/core/llm-manager.js +669 -0
- package/dist/core/llm-manager.js.map +1 -0
- package/dist/core/load-skill-tool.d.ts +55 -0
- package/dist/core/load-skill-tool.d.ts.map +1 -0
- package/dist/core/load-skill-tool.js +468 -0
- package/dist/core/load-skill-tool.js.map +1 -0
- package/dist/core/logger.d.ts +88 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +358 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/managers.d.ts +131 -0
- package/dist/core/managers.d.ts.map +1 -0
- package/dist/core/managers.js +1223 -0
- package/dist/core/managers.js.map +1 -0
- package/dist/core/mcp-server-registry.d.ts +304 -0
- package/dist/core/mcp-server-registry.d.ts.map +1 -0
- package/dist/core/mcp-server-registry.js +1769 -0
- package/dist/core/mcp-server-registry.js.map +1 -0
- package/dist/core/mcp-tools.d.ts +56 -0
- package/dist/core/mcp-tools.d.ts.map +1 -0
- package/dist/core/mcp-tools.js +186 -0
- package/dist/core/mcp-tools.js.map +1 -0
- package/dist/core/message-prep.d.ts +81 -0
- package/dist/core/message-prep.d.ts.map +1 -0
- package/dist/core/message-prep.js +223 -0
- package/dist/core/message-prep.js.map +1 -0
- package/dist/core/message-processing-control.d.ts +54 -0
- package/dist/core/message-processing-control.d.ts.map +1 -0
- package/dist/core/message-processing-control.js +139 -0
- package/dist/core/message-processing-control.js.map +1 -0
- package/dist/core/openai-direct.d.ts +80 -0
- package/dist/core/openai-direct.d.ts.map +1 -0
- package/dist/core/openai-direct.js +374 -0
- package/dist/core/openai-direct.js.map +1 -0
- package/dist/core/shell-cmd-tool.d.ts +235 -0
- package/dist/core/shell-cmd-tool.d.ts.map +1 -0
- package/dist/core/shell-cmd-tool.js +1157 -0
- package/dist/core/shell-cmd-tool.js.map +1 -0
- package/dist/core/shell-process-registry.d.ts +88 -0
- package/dist/core/shell-process-registry.d.ts.map +1 -0
- package/dist/core/shell-process-registry.js +309 -0
- package/dist/core/shell-process-registry.js.map +1 -0
- package/dist/core/skill-registry.d.ts +75 -0
- package/dist/core/skill-registry.d.ts.map +1 -0
- package/dist/core/skill-registry.js +369 -0
- package/dist/core/skill-registry.js.map +1 -0
- package/dist/core/skill-script-runner.d.ts +89 -0
- package/dist/core/skill-script-runner.d.ts.map +1 -0
- package/dist/core/skill-script-runner.js +274 -0
- package/dist/core/skill-script-runner.js.map +1 -0
- package/dist/core/skill-selector.d.ts +65 -0
- package/dist/core/skill-selector.d.ts.map +1 -0
- package/dist/core/skill-selector.js +190 -0
- package/dist/core/skill-selector.js.map +1 -0
- package/dist/core/skill-settings.d.ts +20 -0
- package/dist/core/skill-settings.d.ts.map +1 -0
- package/dist/core/skill-settings.js +40 -0
- package/dist/core/skill-settings.js.map +1 -0
- package/dist/core/storage/agent-storage.d.ts +134 -0
- package/dist/core/storage/agent-storage.d.ts.map +1 -0
- package/dist/core/storage/agent-storage.js +498 -0
- package/dist/core/storage/agent-storage.js.map +1 -0
- package/dist/core/storage/eventStorage/fileEventStorage.d.ts +100 -0
- package/dist/core/storage/eventStorage/fileEventStorage.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/fileEventStorage.js +494 -0
- package/dist/core/storage/eventStorage/fileEventStorage.js.map +1 -0
- package/dist/core/storage/eventStorage/index.d.ts +31 -0
- package/dist/core/storage/eventStorage/index.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/index.js +31 -0
- package/dist/core/storage/eventStorage/index.js.map +1 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.d.ts +87 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.js +244 -0
- package/dist/core/storage/eventStorage/memoryEventStorage.js.map +1 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts +45 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.js +301 -0
- package/dist/core/storage/eventStorage/sqliteEventStorage.js.map +1 -0
- package/dist/core/storage/eventStorage/types.d.ts +142 -0
- package/dist/core/storage/eventStorage/types.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/types.js +43 -0
- package/dist/core/storage/eventStorage/types.js.map +1 -0
- package/dist/core/storage/eventStorage/validation.d.ts +30 -0
- package/dist/core/storage/eventStorage/validation.d.ts.map +1 -0
- package/dist/core/storage/eventStorage/validation.js +68 -0
- package/dist/core/storage/eventStorage/validation.js.map +1 -0
- package/dist/core/storage/legacy-migrations.d.ts +45 -0
- package/dist/core/storage/legacy-migrations.d.ts.map +1 -0
- package/dist/core/storage/legacy-migrations.js +295 -0
- package/dist/core/storage/legacy-migrations.js.map +1 -0
- package/dist/core/storage/memory-storage.d.ts +105 -0
- package/dist/core/storage/memory-storage.d.ts.map +1 -0
- package/dist/core/storage/memory-storage.js +415 -0
- package/dist/core/storage/memory-storage.js.map +1 -0
- package/dist/core/storage/migration-runner.d.ts +96 -0
- package/dist/core/storage/migration-runner.d.ts.map +1 -0
- package/dist/core/storage/migration-runner.js +306 -0
- package/dist/core/storage/migration-runner.js.map +1 -0
- package/dist/core/storage/queue-storage.d.ts +147 -0
- package/dist/core/storage/queue-storage.d.ts.map +1 -0
- package/dist/core/storage/queue-storage.js +290 -0
- package/dist/core/storage/queue-storage.js.map +1 -0
- package/dist/core/storage/skill-storage.d.ts +136 -0
- package/dist/core/storage/skill-storage.d.ts.map +1 -0
- package/dist/core/storage/skill-storage.js +474 -0
- package/dist/core/storage/skill-storage.js.map +1 -0
- package/dist/core/storage/sqlite-schema.d.ts +95 -0
- package/dist/core/storage/sqlite-schema.d.ts.map +1 -0
- package/dist/core/storage/sqlite-schema.js +156 -0
- package/dist/core/storage/sqlite-schema.js.map +1 -0
- package/dist/core/storage/sqlite-storage.d.ts +146 -0
- package/dist/core/storage/sqlite-storage.d.ts.map +1 -0
- package/dist/core/storage/sqlite-storage.js +709 -0
- package/dist/core/storage/sqlite-storage.js.map +1 -0
- package/dist/core/storage/storage-factory.d.ts +61 -0
- package/dist/core/storage/storage-factory.d.ts.map +1 -0
- package/dist/core/storage/storage-factory.js +794 -0
- package/dist/core/storage/storage-factory.js.map +1 -0
- package/dist/core/storage/validation.d.ts +36 -0
- package/dist/core/storage/validation.d.ts.map +1 -0
- package/dist/core/storage/validation.js +79 -0
- package/dist/core/storage/validation.js.map +1 -0
- package/dist/core/storage/world-storage.d.ts +114 -0
- package/dist/core/storage/world-storage.d.ts.map +1 -0
- package/dist/core/storage/world-storage.js +378 -0
- package/dist/core/storage/world-storage.js.map +1 -0
- package/dist/core/subscription.d.ts +43 -0
- package/dist/core/subscription.d.ts.map +1 -0
- package/dist/core/subscription.js +227 -0
- package/dist/core/subscription.js.map +1 -0
- package/dist/core/tool-utils.d.ts +80 -0
- package/dist/core/tool-utils.d.ts.map +1 -0
- package/dist/core/tool-utils.js +273 -0
- package/dist/core/tool-utils.js.map +1 -0
- package/dist/core/types.d.ts +595 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +158 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/utils.d.ts +138 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/core/utils.js +478 -0
- package/dist/core/utils.js.map +1 -0
- package/dist/core/world-class.d.ts +43 -0
- package/dist/core/world-class.d.ts.map +1 -0
- package/dist/core/world-class.js +90 -0
- package/dist/core/world-class.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/public/assets/agent-sprites-DJFgj-zP.png +0 -0
- package/dist/public/assets/border-KHK37r8y.svg +83 -0
- package/dist/public/assets/index-C9kPXL6G.css +1 -0
- package/dist/public/assets/index-DOQEHGWt.js +96 -0
- package/dist/public/index.html +21 -0
- package/dist/server/api.d.ts +2 -0
- package/dist/server/api.js +1124 -0
- package/dist/server/index.d.ts +29 -0
- package/dist/server/sse-handler.d.ts +62 -0
- package/dist/server/sse-handler.js +234 -0
- package/package.json +15 -3
- package/scripts/launch-electron.js +0 -58
|
@@ -0,0 +1,794 @@
|
|
|
1
|
+
import { validateAgentMessageIds } from './validation.js';
|
|
2
|
+
import { createCategoryLogger } from '../logger.js';
|
|
3
|
+
import { isNodeEnvironment } from '../utils.js';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
const logger = createCategoryLogger('storage.init');
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
/**
|
|
8
|
+
* Creates storage wrappers that implement StorageAPI and delegate to storage instance.
|
|
9
|
+
* Provides unified interface across all storage backends with graceful NoOp fallbacks.
|
|
10
|
+
*/
|
|
11
|
+
export function createStorageWrappers(storageInstance) {
|
|
12
|
+
const wrappers = {
|
|
13
|
+
// World operations
|
|
14
|
+
async saveWorld(worldData) {
|
|
15
|
+
if (!storageInstance)
|
|
16
|
+
return;
|
|
17
|
+
return storageInstance.saveWorld(worldData);
|
|
18
|
+
},
|
|
19
|
+
async loadWorld(worldId) {
|
|
20
|
+
if (!storageInstance)
|
|
21
|
+
return null;
|
|
22
|
+
return storageInstance.loadWorld(worldId);
|
|
23
|
+
},
|
|
24
|
+
async deleteWorld(worldId) {
|
|
25
|
+
if (!storageInstance)
|
|
26
|
+
return false;
|
|
27
|
+
return storageInstance.deleteWorld(worldId);
|
|
28
|
+
},
|
|
29
|
+
async listWorlds() {
|
|
30
|
+
if (!storageInstance)
|
|
31
|
+
return [];
|
|
32
|
+
return storageInstance.listWorlds();
|
|
33
|
+
},
|
|
34
|
+
async worldExists(worldId) {
|
|
35
|
+
if (!storageInstance)
|
|
36
|
+
return false;
|
|
37
|
+
try {
|
|
38
|
+
const world = await storageInstance.loadWorld(worldId);
|
|
39
|
+
return !!world;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
async getMemory(worldId, chatId) {
|
|
46
|
+
if (!storageInstance)
|
|
47
|
+
return [];
|
|
48
|
+
if ('getMemory' in storageInstance) {
|
|
49
|
+
return storageInstance.getMemory(worldId, chatId);
|
|
50
|
+
}
|
|
51
|
+
return [];
|
|
52
|
+
},
|
|
53
|
+
// Agent operations
|
|
54
|
+
async saveAgent(worldId, agent) {
|
|
55
|
+
if (!storageInstance)
|
|
56
|
+
return;
|
|
57
|
+
return storageInstance.saveAgent(worldId, agent);
|
|
58
|
+
},
|
|
59
|
+
async saveAgentMemory(worldId, agentId, memory) {
|
|
60
|
+
if (!storageInstance)
|
|
61
|
+
return;
|
|
62
|
+
// Call the storage instance's saveAgentMemory directly instead of load-modify-save
|
|
63
|
+
if ('saveAgentMemory' in storageInstance && typeof storageInstance.saveAgentMemory === 'function') {
|
|
64
|
+
return storageInstance.saveAgentMemory(worldId, agentId, memory);
|
|
65
|
+
}
|
|
66
|
+
// Fallback to load-modify-save for storages without dedicated saveAgentMemory
|
|
67
|
+
const agent = await storageInstance.loadAgent(worldId, agentId);
|
|
68
|
+
if (agent) {
|
|
69
|
+
agent.memory = memory;
|
|
70
|
+
return storageInstance.saveAgent(worldId, agent);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
async loadAgent(worldId, agentId) {
|
|
74
|
+
if (!storageInstance)
|
|
75
|
+
return null;
|
|
76
|
+
return storageInstance.loadAgent(worldId, agentId);
|
|
77
|
+
},
|
|
78
|
+
async loadAgentWithRetry(worldId, agentId, options) {
|
|
79
|
+
if (!storageInstance)
|
|
80
|
+
return null;
|
|
81
|
+
return storageInstance.loadAgent(worldId, agentId);
|
|
82
|
+
},
|
|
83
|
+
async deleteAgent(worldId, agentId) {
|
|
84
|
+
if (!storageInstance)
|
|
85
|
+
return false;
|
|
86
|
+
return storageInstance.deleteAgent(worldId, agentId);
|
|
87
|
+
},
|
|
88
|
+
async listAgents(worldId) {
|
|
89
|
+
if (!storageInstance)
|
|
90
|
+
return [];
|
|
91
|
+
return storageInstance.listAgents(worldId);
|
|
92
|
+
},
|
|
93
|
+
async agentExists(worldId, agentId) {
|
|
94
|
+
if (!storageInstance)
|
|
95
|
+
return false;
|
|
96
|
+
try {
|
|
97
|
+
const agent = await storageInstance.loadAgent(worldId, agentId);
|
|
98
|
+
return !!agent;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
// Chat operations
|
|
105
|
+
async saveChatData(worldId, chat) {
|
|
106
|
+
if (!storageInstance)
|
|
107
|
+
return;
|
|
108
|
+
try {
|
|
109
|
+
return await storageInstance.saveChatData(worldId, chat);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
throw new Error(`Failed to save chat history: ${err instanceof Error ? err.message : String(err)}`);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
async loadChatData(worldId, chatId) {
|
|
116
|
+
if (!storageInstance)
|
|
117
|
+
return null;
|
|
118
|
+
try {
|
|
119
|
+
return await storageInstance.loadChatData(worldId, chatId);
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
throw new Error(`Failed to load chat history: ${err instanceof Error ? err.message : String(err)}`);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
async deleteChatData(worldId, chatId) {
|
|
126
|
+
if (!storageInstance)
|
|
127
|
+
return false;
|
|
128
|
+
try {
|
|
129
|
+
return await storageInstance.deleteChatData(worldId, chatId);
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
throw new Error(`Failed to delete chat history: ${err instanceof Error ? err.message : String(err)}`);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
async listChats(worldId) {
|
|
136
|
+
if (!storageInstance)
|
|
137
|
+
return [];
|
|
138
|
+
try {
|
|
139
|
+
return await storageInstance.listChats(worldId);
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
throw new Error(`Failed to list chats: ${err instanceof Error ? err.message : String(err)}`);
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
async updateChatData(worldId, chatId, updates) {
|
|
146
|
+
if (!storageInstance)
|
|
147
|
+
return null;
|
|
148
|
+
try {
|
|
149
|
+
return await storageInstance.updateChatData(worldId, chatId, updates);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
throw new Error(`Failed to update chat history: ${err instanceof Error ? err.message : String(err)}`);
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
async updateChatNameIfCurrent(worldId, chatId, expectedName, nextName) {
|
|
156
|
+
if (!storageInstance)
|
|
157
|
+
return false;
|
|
158
|
+
if (typeof storageInstance.updateChatNameIfCurrent === 'function') {
|
|
159
|
+
return storageInstance.updateChatNameIfCurrent(worldId, chatId, expectedName, nextName);
|
|
160
|
+
}
|
|
161
|
+
// Fallback path for backends without compare-and-set support.
|
|
162
|
+
const current = await storageInstance.loadChatData(worldId, chatId);
|
|
163
|
+
if (!current || current.name !== expectedName) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
const updated = await storageInstance.updateChatData(worldId, chatId, { name: nextName });
|
|
167
|
+
return !!updated;
|
|
168
|
+
},
|
|
169
|
+
async saveWorldChat(worldId, chatId, chat) {
|
|
170
|
+
if (!storageInstance)
|
|
171
|
+
return;
|
|
172
|
+
try {
|
|
173
|
+
return await storageInstance.saveWorldChat(worldId, chatId, chat);
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
throw new Error(`Failed to save world chat: ${err instanceof Error ? err.message : String(err)}`);
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
async loadWorldChat(worldId, chatId) {
|
|
180
|
+
if (!storageInstance)
|
|
181
|
+
return null;
|
|
182
|
+
try {
|
|
183
|
+
return await storageInstance.loadWorldChat(worldId, chatId);
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
throw new Error(`Failed to load world chat: ${err instanceof Error ? err.message : String(err)}`);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
async loadWorldChatFull(worldId, chatId) {
|
|
190
|
+
if (!storageInstance)
|
|
191
|
+
return null;
|
|
192
|
+
try {
|
|
193
|
+
return await storageInstance.loadWorldChatFull(worldId, chatId);
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
throw new Error(`Failed to load full world chat: ${err instanceof Error ? err.message : String(err)}`);
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
async restoreFromWorldChat(worldId, chat) {
|
|
200
|
+
if (!storageInstance)
|
|
201
|
+
return false;
|
|
202
|
+
try {
|
|
203
|
+
return await storageInstance.restoreFromWorldChat(worldId, chat);
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
throw new Error(`Failed to restore from world chat: ${err instanceof Error ? err.message : String(err)}`);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
async archiveMemory(worldId, agentId, memory) {
|
|
210
|
+
if (!storageInstance)
|
|
211
|
+
return;
|
|
212
|
+
if ('archiveAgentMemory' in storageInstance) {
|
|
213
|
+
return storageInstance.archiveAgentMemory(worldId, agentId, memory);
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
async deleteMemoryByChatId(worldId, chatId) {
|
|
217
|
+
if (!storageInstance)
|
|
218
|
+
return 0;
|
|
219
|
+
if ('deleteMemoryByChatId' in storageInstance) {
|
|
220
|
+
return storageInstance.deleteMemoryByChatId(worldId, chatId);
|
|
221
|
+
}
|
|
222
|
+
return 0;
|
|
223
|
+
},
|
|
224
|
+
// Batch operations
|
|
225
|
+
async saveAgentsBatch(worldId, agents) {
|
|
226
|
+
if (!storageInstance)
|
|
227
|
+
return;
|
|
228
|
+
if ('saveAgentsBatch' in storageInstance) {
|
|
229
|
+
return storageInstance.saveAgentsBatch(worldId, agents);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
for (const agent of agents) {
|
|
233
|
+
await this.saveAgent(worldId, agent);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
async loadAgentsBatch(worldId, agentIds) {
|
|
238
|
+
if (!storageInstance)
|
|
239
|
+
return [];
|
|
240
|
+
if ('loadAgentsBatch' in storageInstance) {
|
|
241
|
+
return storageInstance.loadAgentsBatch(worldId, agentIds);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
const agents = [];
|
|
245
|
+
for (const agentId of agentIds) {
|
|
246
|
+
const agent = await this.loadAgent(worldId, agentId);
|
|
247
|
+
if (agent)
|
|
248
|
+
agents.push(agent);
|
|
249
|
+
}
|
|
250
|
+
return agents;
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
// Integrity operations
|
|
254
|
+
async validateIntegrity(worldId, agentId) {
|
|
255
|
+
if (!storageInstance)
|
|
256
|
+
return false;
|
|
257
|
+
if ('validateIntegrity' in storageInstance) {
|
|
258
|
+
return storageInstance.validateIntegrity(worldId, agentId);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
try {
|
|
262
|
+
if (agentId) {
|
|
263
|
+
const agent = await this.loadAgent(worldId, agentId);
|
|
264
|
+
return !!agent;
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
const world = await this.loadWorld(worldId);
|
|
268
|
+
return !!world;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
async repairData(worldId, agentId) {
|
|
277
|
+
if (!storageInstance)
|
|
278
|
+
return false;
|
|
279
|
+
if ('repairData' in storageInstance) {
|
|
280
|
+
return storageInstance.repairData(worldId, agentId);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
try {
|
|
284
|
+
if (agentId) {
|
|
285
|
+
await this.loadAgent(worldId, agentId);
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
await this.loadWorld(worldId);
|
|
289
|
+
}
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
// Expose eventStorage if it exists on the storage instance
|
|
299
|
+
if (storageInstance && storageInstance.eventStorage) {
|
|
300
|
+
wrappers.eventStorage = storageInstance.eventStorage;
|
|
301
|
+
}
|
|
302
|
+
return wrappers;
|
|
303
|
+
}
|
|
304
|
+
// File storage adapter with dynamic module loading
|
|
305
|
+
function createFileStorageAdapter(rootPath) {
|
|
306
|
+
let worldStorage;
|
|
307
|
+
let agentStorage;
|
|
308
|
+
async function ensureModulesLoaded() {
|
|
309
|
+
if (!worldStorage || !agentStorage) {
|
|
310
|
+
if (!isNodeEnvironment()) {
|
|
311
|
+
throw new Error('File storage not available in browser environment');
|
|
312
|
+
}
|
|
313
|
+
try {
|
|
314
|
+
worldStorage = await import('./world-storage.js');
|
|
315
|
+
agentStorage = await import('./agent-storage.js');
|
|
316
|
+
}
|
|
317
|
+
catch (error) {
|
|
318
|
+
throw new Error('Failed to load storage modules: ' + (error instanceof Error ? error.message : error));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return {
|
|
323
|
+
async saveWorld(worldData) {
|
|
324
|
+
await ensureModulesLoaded();
|
|
325
|
+
if (worldStorage?.saveWorld) {
|
|
326
|
+
return worldStorage.saveWorld(rootPath, worldData);
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
async loadWorld(worldId) {
|
|
330
|
+
await ensureModulesLoaded();
|
|
331
|
+
if (worldStorage?.loadWorld) {
|
|
332
|
+
return worldStorage.loadWorld(rootPath, worldId);
|
|
333
|
+
}
|
|
334
|
+
return null;
|
|
335
|
+
},
|
|
336
|
+
async deleteWorld(worldId) {
|
|
337
|
+
await ensureModulesLoaded();
|
|
338
|
+
if (worldStorage?.deleteWorld) {
|
|
339
|
+
return worldStorage.deleteWorld(rootPath, worldId);
|
|
340
|
+
}
|
|
341
|
+
return false;
|
|
342
|
+
},
|
|
343
|
+
async listWorlds() {
|
|
344
|
+
await ensureModulesLoaded();
|
|
345
|
+
if (worldStorage?.listWorlds) {
|
|
346
|
+
return worldStorage.listWorlds(rootPath);
|
|
347
|
+
}
|
|
348
|
+
return [];
|
|
349
|
+
},
|
|
350
|
+
async getMemory(worldId, chatId) {
|
|
351
|
+
await ensureModulesLoaded();
|
|
352
|
+
if (worldStorage?.getMemory) {
|
|
353
|
+
return worldStorage.getMemory(rootPath, worldId, chatId);
|
|
354
|
+
}
|
|
355
|
+
return [];
|
|
356
|
+
},
|
|
357
|
+
async saveAgent(worldId, agent) {
|
|
358
|
+
await ensureModulesLoaded();
|
|
359
|
+
// Auto-migrate legacy messages without messageId
|
|
360
|
+
const migrated = validateAgentMessageIds(agent);
|
|
361
|
+
if (migrated) {
|
|
362
|
+
logger.info('Auto-migrated agent messages with missing messageIds', {
|
|
363
|
+
agentId: agent.id,
|
|
364
|
+
worldId,
|
|
365
|
+
messageCount: agent.memory.length
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
if (agentStorage?.saveAgent) {
|
|
369
|
+
return agentStorage.saveAgent(rootPath, worldId, agent);
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
async loadAgent(worldId, agentId) {
|
|
373
|
+
await ensureModulesLoaded();
|
|
374
|
+
if (agentStorage?.loadAgent) {
|
|
375
|
+
const agent = await agentStorage.loadAgent(rootPath, worldId, agentId);
|
|
376
|
+
if (agent) {
|
|
377
|
+
// Auto-migrate on load if needed
|
|
378
|
+
const migrated = validateAgentMessageIds(agent);
|
|
379
|
+
if (migrated) {
|
|
380
|
+
logger.info('Auto-migrated agent messages on load', {
|
|
381
|
+
agentId,
|
|
382
|
+
worldId,
|
|
383
|
+
messageCount: agent.memory.length
|
|
384
|
+
});
|
|
385
|
+
// Save back the migrated agent
|
|
386
|
+
if (agentStorage?.saveAgent) {
|
|
387
|
+
await agentStorage.saveAgent(rootPath, worldId, agent);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return agent;
|
|
392
|
+
}
|
|
393
|
+
return null;
|
|
394
|
+
},
|
|
395
|
+
async deleteAgent(worldId, agentId) {
|
|
396
|
+
await ensureModulesLoaded();
|
|
397
|
+
if (agentStorage?.deleteAgent) {
|
|
398
|
+
return agentStorage.deleteAgent(rootPath, worldId, agentId);
|
|
399
|
+
}
|
|
400
|
+
return false;
|
|
401
|
+
},
|
|
402
|
+
async listAgents(worldId) {
|
|
403
|
+
await ensureModulesLoaded();
|
|
404
|
+
if (agentStorage?.listAgents) {
|
|
405
|
+
return agentStorage.listAgents(rootPath, worldId);
|
|
406
|
+
}
|
|
407
|
+
return [];
|
|
408
|
+
},
|
|
409
|
+
async saveAgentsBatch(worldId, agents) {
|
|
410
|
+
await ensureModulesLoaded();
|
|
411
|
+
if (agentStorage?.saveAgent) {
|
|
412
|
+
for (const agent of agents) {
|
|
413
|
+
await agentStorage.saveAgent(rootPath, worldId, agent);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
async loadAgentsBatch(worldId, agentIds) {
|
|
418
|
+
await ensureModulesLoaded();
|
|
419
|
+
if (agentStorage?.loadAgent) {
|
|
420
|
+
const agents = [];
|
|
421
|
+
for (const agentId of agentIds) {
|
|
422
|
+
const agent = await agentStorage.loadAgent(rootPath, worldId, agentId);
|
|
423
|
+
if (agent)
|
|
424
|
+
agents.push(agent);
|
|
425
|
+
}
|
|
426
|
+
return agents;
|
|
427
|
+
}
|
|
428
|
+
return [];
|
|
429
|
+
},
|
|
430
|
+
async validateIntegrity(worldId, agentId) {
|
|
431
|
+
await ensureModulesLoaded();
|
|
432
|
+
if (agentId) {
|
|
433
|
+
if (agentStorage?.validateAgentIntegrity) {
|
|
434
|
+
const result = await agentStorage.validateAgentIntegrity(rootPath, worldId, agentId);
|
|
435
|
+
return result.isValid;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
if (worldStorage?.worldExists) {
|
|
440
|
+
return worldStorage.worldExists(rootPath, worldId);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return false;
|
|
444
|
+
},
|
|
445
|
+
async repairData(worldId, agentId) {
|
|
446
|
+
await ensureModulesLoaded();
|
|
447
|
+
if (agentId) {
|
|
448
|
+
if (agentStorage?.repairAgentData) {
|
|
449
|
+
return agentStorage.repairAgentData(rootPath, worldId, agentId);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return false;
|
|
453
|
+
},
|
|
454
|
+
async saveChatData(worldId, chat) {
|
|
455
|
+
await ensureModulesLoaded();
|
|
456
|
+
if (worldStorage?.saveChatData) {
|
|
457
|
+
return worldStorage.saveChatData(rootPath, worldId, chat);
|
|
458
|
+
}
|
|
459
|
+
},
|
|
460
|
+
async loadChatData(worldId, chatId) {
|
|
461
|
+
await ensureModulesLoaded();
|
|
462
|
+
if (worldStorage?.loadChatData) {
|
|
463
|
+
return worldStorage.loadChatData(rootPath, worldId, chatId);
|
|
464
|
+
}
|
|
465
|
+
return null;
|
|
466
|
+
},
|
|
467
|
+
async deleteChatData(worldId, chatId) {
|
|
468
|
+
await ensureModulesLoaded();
|
|
469
|
+
if (worldStorage?.deleteChatData) {
|
|
470
|
+
return worldStorage.deleteChatData(rootPath, worldId, chatId);
|
|
471
|
+
}
|
|
472
|
+
return false;
|
|
473
|
+
},
|
|
474
|
+
async listChats(worldId) {
|
|
475
|
+
await ensureModulesLoaded();
|
|
476
|
+
if (worldStorage?.listChatHistories) {
|
|
477
|
+
return worldStorage.listChatHistories(rootPath, worldId);
|
|
478
|
+
}
|
|
479
|
+
return [];
|
|
480
|
+
},
|
|
481
|
+
async updateChatData(worldId, chatId, updates) {
|
|
482
|
+
await ensureModulesLoaded();
|
|
483
|
+
if (worldStorage?.updateChatData) {
|
|
484
|
+
return worldStorage.updateChatData(rootPath, worldId, chatId, updates);
|
|
485
|
+
}
|
|
486
|
+
return null;
|
|
487
|
+
},
|
|
488
|
+
async updateChatNameIfCurrent(worldId, chatId, expectedName, nextName) {
|
|
489
|
+
await ensureModulesLoaded();
|
|
490
|
+
if (worldStorage?.updateChatNameIfCurrent) {
|
|
491
|
+
return worldStorage.updateChatNameIfCurrent(rootPath, worldId, chatId, expectedName, nextName);
|
|
492
|
+
}
|
|
493
|
+
const current = await this.loadChatData(worldId, chatId);
|
|
494
|
+
if (!current || current.name !== expectedName) {
|
|
495
|
+
return false;
|
|
496
|
+
}
|
|
497
|
+
const updated = await this.updateChatData(worldId, chatId, { name: nextName });
|
|
498
|
+
return !!updated;
|
|
499
|
+
},
|
|
500
|
+
async saveWorldChat(worldId, chatId, chat) {
|
|
501
|
+
await ensureModulesLoaded();
|
|
502
|
+
if (worldStorage?.saveWorldChat) {
|
|
503
|
+
return worldStorage.saveWorldChat(rootPath, worldId, chatId, chat);
|
|
504
|
+
}
|
|
505
|
+
},
|
|
506
|
+
async loadWorldChat(worldId, chatId) {
|
|
507
|
+
await ensureModulesLoaded();
|
|
508
|
+
if (worldStorage?.loadWorldChat) {
|
|
509
|
+
return worldStorage.loadWorldChat(rootPath, worldId, chatId);
|
|
510
|
+
}
|
|
511
|
+
return null;
|
|
512
|
+
},
|
|
513
|
+
async loadWorldChatFull(worldId, chatId) {
|
|
514
|
+
await ensureModulesLoaded();
|
|
515
|
+
if (worldStorage?.loadWorldChatFull) {
|
|
516
|
+
return worldStorage.loadWorldChatFull(rootPath, worldId, chatId);
|
|
517
|
+
}
|
|
518
|
+
return null;
|
|
519
|
+
},
|
|
520
|
+
async restoreFromWorldChat(worldId, chat) {
|
|
521
|
+
await ensureModulesLoaded();
|
|
522
|
+
console.warn('[file-storage] World chat restoration not yet implemented for file storage');
|
|
523
|
+
return false;
|
|
524
|
+
},
|
|
525
|
+
async loadAgentWithRetry(worldId, agentId, options) {
|
|
526
|
+
await ensureModulesLoaded();
|
|
527
|
+
let retries = options?.retries || 3;
|
|
528
|
+
while (retries > 0) {
|
|
529
|
+
try {
|
|
530
|
+
const agent = await this.loadAgent(worldId, agentId);
|
|
531
|
+
if (agent)
|
|
532
|
+
return agent;
|
|
533
|
+
}
|
|
534
|
+
catch (error) {
|
|
535
|
+
console.warn(`[file-storage] Retry attempt ${retries} failed:`, error);
|
|
536
|
+
}
|
|
537
|
+
retries--;
|
|
538
|
+
if (retries > 0) {
|
|
539
|
+
await new Promise(resolve => setTimeout(resolve, options?.delay || 100));
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return null;
|
|
543
|
+
},
|
|
544
|
+
async agentExists(worldId, agentId) {
|
|
545
|
+
await ensureModulesLoaded();
|
|
546
|
+
try {
|
|
547
|
+
const agent = await this.loadAgent(worldId, agentId);
|
|
548
|
+
return !!agent;
|
|
549
|
+
}
|
|
550
|
+
catch {
|
|
551
|
+
return false;
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
async saveAgentMemory(worldId, agentId, memory) {
|
|
555
|
+
await ensureModulesLoaded();
|
|
556
|
+
// Use the direct saveAgentMemory function to avoid loading the entire agent
|
|
557
|
+
if (agentStorage?.saveAgentMemory) {
|
|
558
|
+
return agentStorage.saveAgentMemory(rootPath, worldId, agentId, memory);
|
|
559
|
+
}
|
|
560
|
+
// Fallback to load-modify-save if direct save not available
|
|
561
|
+
const agent = await this.loadAgent(worldId, agentId);
|
|
562
|
+
if (agent) {
|
|
563
|
+
agent.memory = memory;
|
|
564
|
+
await this.saveAgent(worldId, agent);
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
async archiveMemory(worldId, agentId, memory) {
|
|
568
|
+
await ensureModulesLoaded();
|
|
569
|
+
console.warn('[file-storage] Memory archiving not yet implemented for file storage');
|
|
570
|
+
},
|
|
571
|
+
async worldExists(worldId) {
|
|
572
|
+
await ensureModulesLoaded();
|
|
573
|
+
if (worldStorage?.worldExists) {
|
|
574
|
+
return worldStorage.worldExists(rootPath, worldId);
|
|
575
|
+
}
|
|
576
|
+
return false;
|
|
577
|
+
},
|
|
578
|
+
async deleteMemoryByChatId(worldId, chatId) {
|
|
579
|
+
await ensureModulesLoaded();
|
|
580
|
+
if (agentStorage?.deleteMemoryByChatId) {
|
|
581
|
+
return agentStorage.deleteMemoryByChatId(rootPath, worldId, chatId);
|
|
582
|
+
}
|
|
583
|
+
console.warn('[file-storage] Memory deletion by chat ID not available');
|
|
584
|
+
return 0;
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
// Instance caching for performance optimization
|
|
589
|
+
const storageCache = new Map();
|
|
590
|
+
// Flag to prevent duplicate log messages
|
|
591
|
+
let hasLoggedStorageInit = false;
|
|
592
|
+
/**
|
|
593
|
+
* Creates storage with environment-aware wrappers for browser/Node.js compatibility.
|
|
594
|
+
*/
|
|
595
|
+
export async function createStorageWithWrappers() {
|
|
596
|
+
if (isNodeEnvironment()) {
|
|
597
|
+
const storageInstance = await createStorageFromEnv();
|
|
598
|
+
return createStorageWrappers(storageInstance);
|
|
599
|
+
}
|
|
600
|
+
else {
|
|
601
|
+
// Use memory storage for non-Node environments (tests, browser)
|
|
602
|
+
const { createMemoryStorage } = await import('./memory-storage.js');
|
|
603
|
+
const memoryStorage = createMemoryStorage();
|
|
604
|
+
return createStorageWrappers(memoryStorage);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
export async function createStorage(config) {
|
|
608
|
+
const cacheKey = `${config.type}-${config.rootPath}`;
|
|
609
|
+
if (storageCache.has(cacheKey)) {
|
|
610
|
+
return storageCache.get(cacheKey);
|
|
611
|
+
}
|
|
612
|
+
let storage;
|
|
613
|
+
if (config.type === 'memory') {
|
|
614
|
+
// Use memory storage - available in all environments
|
|
615
|
+
const { createMemoryStorage } = await import('./memory-storage.js');
|
|
616
|
+
storage = createMemoryStorage();
|
|
617
|
+
// Add memory event storage
|
|
618
|
+
const { createMemoryEventStorage } = await import('./eventStorage/index.js');
|
|
619
|
+
storage.eventStorage = createMemoryEventStorage();
|
|
620
|
+
}
|
|
621
|
+
else if (config.type === 'sqlite') {
|
|
622
|
+
if (!isNodeEnvironment()) {
|
|
623
|
+
throw new Error('SQLite storage not available in browser environment');
|
|
624
|
+
}
|
|
625
|
+
const sqliteConfig = {
|
|
626
|
+
database: config.sqlite?.database || path.join(config.rootPath, 'database.db'),
|
|
627
|
+
enableWAL: config.sqlite?.enableWAL !== false,
|
|
628
|
+
busyTimeout: config.sqlite?.busyTimeout || 30000,
|
|
629
|
+
cacheSize: config.sqlite?.cacheSize || -64000,
|
|
630
|
+
enableForeignKeys: config.sqlite?.enableForeignKeys !== false
|
|
631
|
+
};
|
|
632
|
+
// Use function-based SQLite API with schema initialization
|
|
633
|
+
const { createSQLiteStorageContext, saveWorld, loadWorld, deleteWorld, listWorlds, saveAgent, loadAgent, deleteAgent, listAgents, saveAgentsBatch, loadAgentsBatch, validateIntegrity, repairData, close, getDatabaseStats, initializeWithDefaults, saveChatData, loadChatData, deleteChatData, listChatHistories, updateChatData, updateChatNameIfCurrent, saveWorldChat, loadWorldChat, loadWorldChatFull, restoreFromWorldChat, archiveAgentMemory, deleteMemoryByChatId, getMemory, saveAgentMemory } = await import('./sqlite-storage.js');
|
|
634
|
+
const ctx = await createSQLiteStorageContext(sqliteConfig);
|
|
635
|
+
// Note: ensureInitialized is called within sqlite-storage functions, no need to call here
|
|
636
|
+
// Only initialize with defaults if this is a fresh database
|
|
637
|
+
try {
|
|
638
|
+
await initializeWithDefaults(ctx);
|
|
639
|
+
}
|
|
640
|
+
catch (error) {
|
|
641
|
+
// If initialization fails (e.g., default world already exists), continue anyway
|
|
642
|
+
console.warn('[storage-factory] Warning during default initialization:', error instanceof Error ? error.message : error);
|
|
643
|
+
}
|
|
644
|
+
storage = {
|
|
645
|
+
saveWorld: (worldData) => saveWorld(ctx, worldData),
|
|
646
|
+
loadWorld: (worldId) => loadWorld(ctx, worldId),
|
|
647
|
+
deleteWorld: (worldId) => deleteWorld(ctx, worldId),
|
|
648
|
+
listWorlds: () => listWorlds(ctx),
|
|
649
|
+
saveAgent: (worldId, agent) => saveAgent(ctx, worldId, agent),
|
|
650
|
+
loadAgent: (worldId, agentId) => loadAgent(ctx, worldId, agentId),
|
|
651
|
+
deleteAgent: (worldId, agentId) => deleteAgent(ctx, worldId, agentId),
|
|
652
|
+
listAgents: (worldId) => listAgents(ctx, worldId),
|
|
653
|
+
saveAgentsBatch: (worldId, agents) => saveAgentsBatch(ctx, worldId, agents),
|
|
654
|
+
loadAgentsBatch: (worldId, agentIds) => loadAgentsBatch(ctx, worldId, agentIds),
|
|
655
|
+
validateIntegrity: (worldId, agentId) => validateIntegrity(ctx, worldId, agentId),
|
|
656
|
+
repairData: (worldId, agentId) => repairData(ctx, worldId, agentId),
|
|
657
|
+
saveChatData: (worldId, chat) => saveChatData(ctx, worldId, chat),
|
|
658
|
+
loadChatData: (worldId, chatId) => loadChatData(ctx, worldId, chatId),
|
|
659
|
+
deleteChatData: (worldId, chatId) => deleteChatData(ctx, worldId, chatId),
|
|
660
|
+
listChats: (worldId) => listChatHistories(ctx, worldId),
|
|
661
|
+
updateChatData: (worldId, chatId, updates) => updateChatData(ctx, worldId, chatId, updates),
|
|
662
|
+
updateChatNameIfCurrent: (worldId, chatId, expectedName, nextName) => updateChatNameIfCurrent(ctx, worldId, chatId, expectedName, nextName),
|
|
663
|
+
saveWorldChat: (worldId, chatId, chat) => saveWorldChat(ctx, worldId, chatId, chat),
|
|
664
|
+
loadWorldChat: (worldId, chatId) => loadWorldChat(ctx, worldId, chatId),
|
|
665
|
+
loadWorldChatFull: (worldId, chatId) => loadWorldChatFull(ctx, worldId, chatId),
|
|
666
|
+
restoreFromWorldChat: async (worldId, chat) => {
|
|
667
|
+
return await restoreFromWorldChat(ctx, worldId, chat);
|
|
668
|
+
},
|
|
669
|
+
// Additional methods for consistency with StorageAPI
|
|
670
|
+
worldExists: async (worldId) => {
|
|
671
|
+
try {
|
|
672
|
+
const world = await loadWorld(ctx, worldId);
|
|
673
|
+
return !!world;
|
|
674
|
+
}
|
|
675
|
+
catch {
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
loadAgentWithRetry: async (worldId, agentId, options) => {
|
|
680
|
+
let retries = options?.retries || 3;
|
|
681
|
+
while (retries > 0) {
|
|
682
|
+
try {
|
|
683
|
+
const agent = await loadAgent(ctx, worldId, agentId);
|
|
684
|
+
if (agent)
|
|
685
|
+
return agent;
|
|
686
|
+
}
|
|
687
|
+
catch (error) {
|
|
688
|
+
console.warn(`[sqlite-storage] Retry attempt ${retries} failed:`, error);
|
|
689
|
+
}
|
|
690
|
+
retries--;
|
|
691
|
+
if (retries > 0) {
|
|
692
|
+
await new Promise(resolve => setTimeout(resolve, options?.delay || 100));
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return null;
|
|
696
|
+
},
|
|
697
|
+
agentExists: async (worldId, agentId) => {
|
|
698
|
+
try {
|
|
699
|
+
const agent = await loadAgent(ctx, worldId, agentId);
|
|
700
|
+
return !!agent;
|
|
701
|
+
}
|
|
702
|
+
catch {
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
},
|
|
706
|
+
saveAgentMemory: async (worldId, agentId, memory) => {
|
|
707
|
+
await saveAgentMemory(ctx, worldId, agentId, memory);
|
|
708
|
+
},
|
|
709
|
+
archiveMemory: async (worldId, agentId, memory) => {
|
|
710
|
+
await archiveAgentMemory(ctx, worldId, agentId, memory);
|
|
711
|
+
},
|
|
712
|
+
deleteMemoryByChatId: async (worldId, chatId) => {
|
|
713
|
+
return await deleteMemoryByChatId(ctx, worldId, chatId);
|
|
714
|
+
},
|
|
715
|
+
getMemory: (worldId, chatId) => getMemory(ctx, worldId, chatId),
|
|
716
|
+
close: () => close(ctx),
|
|
717
|
+
getDatabaseStats: () => getDatabaseStats(ctx)
|
|
718
|
+
};
|
|
719
|
+
// Add SQLite event storage using same DB connection
|
|
720
|
+
const { createSQLiteEventStorage } = await import('./eventStorage/index.js');
|
|
721
|
+
storage.eventStorage = await createSQLiteEventStorage(ctx.db);
|
|
722
|
+
}
|
|
723
|
+
else {
|
|
724
|
+
storage = createFileStorageAdapter(config.rootPath);
|
|
725
|
+
// Add file-based event storage
|
|
726
|
+
const { createFileEventStorage } = await import('./eventStorage/index.js');
|
|
727
|
+
storage.eventStorage = createFileEventStorage({
|
|
728
|
+
baseDir: config.rootPath
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
storageCache.set(cacheKey, storage);
|
|
732
|
+
return storage;
|
|
733
|
+
}
|
|
734
|
+
export function getDefaultRootPath() {
|
|
735
|
+
let rootPath = process.env.AGENT_WORLD_DATA_PATH;
|
|
736
|
+
if (!rootPath) {
|
|
737
|
+
// Default to ~/agent-world if not defined
|
|
738
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
739
|
+
rootPath = homeDir ? path.join(homeDir, 'agent-world') : './agent-world';
|
|
740
|
+
}
|
|
741
|
+
// If AGENT_WORLD_DATA_PATH is absolute, use it as-is
|
|
742
|
+
// If relative, resolve relative to current working directory
|
|
743
|
+
if (path.isAbsolute(rootPath)) {
|
|
744
|
+
return rootPath;
|
|
745
|
+
}
|
|
746
|
+
else {
|
|
747
|
+
// For relative paths, don't use resolve if it's already in the correct format
|
|
748
|
+
if (rootPath === './agent-world') {
|
|
749
|
+
return './agent-world';
|
|
750
|
+
}
|
|
751
|
+
return path.resolve(process.cwd(), rootPath);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
export async function createStorageFromEnv() {
|
|
755
|
+
const type = process.env.AGENT_WORLD_STORAGE_TYPE || 'sqlite';
|
|
756
|
+
const rootPath = getDefaultRootPath();
|
|
757
|
+
// Use a special cache key for environment-based storage
|
|
758
|
+
const envCacheKey = `env-${type}-${rootPath}`;
|
|
759
|
+
if (storageCache.has(envCacheKey)) {
|
|
760
|
+
return storageCache.get(envCacheKey);
|
|
761
|
+
}
|
|
762
|
+
// Ensure directory exists (except for memory storage)
|
|
763
|
+
if (isNodeEnvironment() && rootPath && typeof fs.existsSync === 'function' && !fs.existsSync(rootPath) && type !== 'memory') {
|
|
764
|
+
if (typeof fs.mkdirSync === 'function') {
|
|
765
|
+
fs.mkdirSync(rootPath, { recursive: true });
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
const config = {
|
|
769
|
+
type,
|
|
770
|
+
rootPath,
|
|
771
|
+
sqlite: type === 'sqlite'
|
|
772
|
+
? {
|
|
773
|
+
database: process.env.AGENT_WORLD_SQLITE_DATABASE || path.join(rootPath, 'database.db'),
|
|
774
|
+
enableWAL: process.env.AGENT_WORLD_SQLITE_WAL !== 'false',
|
|
775
|
+
busyTimeout: parseInt(process.env.AGENT_WORLD_SQLITE_TIMEOUT || '30000'),
|
|
776
|
+
cacheSize: parseInt(process.env.AGENT_WORLD_SQLITE_CACHE || '-64000'),
|
|
777
|
+
enableForeignKeys: process.env.AGENT_WORLD_SQLITE_FK !== 'false'
|
|
778
|
+
}
|
|
779
|
+
: undefined
|
|
780
|
+
};
|
|
781
|
+
// Only log on first initialization to avoid duplicate logs
|
|
782
|
+
if (!hasLoggedStorageInit) {
|
|
783
|
+
logger.info('Storage initialized', {
|
|
784
|
+
path: config.rootPath,
|
|
785
|
+
type: config.type
|
|
786
|
+
});
|
|
787
|
+
hasLoggedStorageInit = true;
|
|
788
|
+
}
|
|
789
|
+
const storage = await createStorage(config);
|
|
790
|
+
// Cache with the special environment key
|
|
791
|
+
storageCache.set(envCacheKey, storage);
|
|
792
|
+
return storage;
|
|
793
|
+
}
|
|
794
|
+
//# sourceMappingURL=storage-factory.js.map
|