forked from unkarelian/openvault
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathindex.js
More file actions
157 lines (144 loc) · 6.06 KB
/
index.js
File metadata and controls
157 lines (144 loc) · 6.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
* OpenVault - Agentic Memory Extension for SillyTavern
*
* Provides POV-aware memory with witness tracking, relationship dynamics,
* and emotional continuity for roleplay conversations.
*
* All data is stored in chatMetadata - no external services required.
*/
// Import from modular structure
import { extensionName, MEMORIES_KEY } from './src/constants.js';
import { getDeps } from './src/deps.js';
import { updateEventListeners } from './src/events.js';
import { isSessionDisabled, setChatLoadingCooldown } from './src/state.js';
import { getOpenVaultData } from './src/store/chat-data.js';
import { refreshAllUI } from './src/ui/render.js';
import { loadSettings } from './src/ui/settings.js';
import { setStatus } from './src/ui/status.js';
import { showToast } from './src/utils/dom.js';
import { logDebug, logError, logInfo } from './src/utils/logging.js';
// Re-export extensionName for external use
export { extensionName };
/**
* Register slash commands
*/
function registerCommands() {
const context = getDeps().getContext();
const parser = context.SlashCommandParser;
const command = context.SlashCommand;
// /openvault-extract - Extract memories from recent messages
parser.addCommandObject(
command.fromProps({
name: 'openvault-extract',
callback: async () => {
if (isSessionDisabled()) {
showToast('warning', 'OpenVault is disabled for this chat due to a data migration failure.');
return '';
}
const { extractMemories } = await import('./src/extraction/extract.js');
setStatus('extracting');
try {
const result = await extractMemories();
if (result.status === 'success' && result.events_created > 0) {
showToast('success', `Extracted ${result.events_created} memory events`);
refreshAllUI();
} else if (result.status === 'skipped') {
showToast(
'info',
result.reason === 'disabled'
? 'OpenVault is disabled'
: result.reason === 'no_new_messages'
? 'No new messages to extract'
: 'Cannot extract'
);
}
} catch (error) {
showToast('error', `Extraction failed: ${error.message}`);
}
setStatus('ready');
return '';
},
helpString: 'Extract memories from recent messages',
})
);
// /openvault-retrieve - Retrieve and inject context
parser.addCommandObject(
command.fromProps({
name: 'openvault-retrieve',
callback: async () => {
if (isSessionDisabled()) {
showToast('warning', 'OpenVault is disabled for this chat due to a data migration failure.');
return '';
}
const { retrieveAndInjectContext } = await import('./src/retrieval/retrieve.js');
setStatus('retrieving');
try {
const result = await retrieveAndInjectContext();
if (result) {
showToast('success', `Retrieved ${result.memories.length} relevant memories`);
} else {
showToast('info', 'No memories to retrieve');
}
} catch (error) {
showToast('error', `Retrieval failed: ${error.message}`);
}
setStatus('ready');
return '';
},
helpString: 'Retrieve relevant context and inject into prompt',
})
);
// /openvault-status - Show current status
parser.addCommandObject(
command.fromProps({
name: 'openvault-status',
callback: async () => {
const settings = getDeps().getExtensionSettings()[extensionName];
const data = getOpenVaultData();
const memoriesCount = data?.[MEMORIES_KEY]?.length || 0;
const status = `OpenVault: ${settings.enabled ? 'Enabled' : 'Disabled'}, Memories: ${memoriesCount}`;
showToast('info', status);
return status;
},
helpString: 'Show OpenVault status',
})
);
logDebug('Slash commands registered');
}
/**
* Initialize the extension
*
* Uses jQuery DOM-ready pattern to self-initialize when the script loads.
* Event listeners are registered synchronously to avoid race conditions.
*/
jQuery(() => {
// Register APP_READY listener synchronously to avoid race conditions
const { eventSource, eventTypes } = getDeps();
eventSource.on(eventTypes.APP_READY, async () => {
// Check SillyTavern version
try {
const response = await fetch('/version');
const version = await response.json();
const [_major, minor] = version.pkgVersion.split('.').map(Number);
if (minor < 13) {
showToast('error', 'OpenVault requires SillyTavern 1.13.0 or later');
return;
}
} catch (error) {
console.error('[OpenVault] Failed to check SillyTavern version:', error);
logError('Failed to check SillyTavern version', error);
showToast('error', 'OpenVault failed to verify SillyTavern version');
return;
}
await loadSettings();
registerCommands();
// Load perf data from current chat into memory store
const { loadFromChat } = await import('./src/perf/store.js');
loadFromChat();
// Set cooldown during initial load to prevent extraction from MESSAGE_RECEIVED events
setChatLoadingCooldown(2000, logDebug);
updateEventListeners();
setStatus('ready');
logInfo('Extension initialized successfully');
});
});