morpheus-cli 0.2.7 → 0.3.1
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 +51 -8
- package/dist/channels/telegram.js +229 -22
- package/dist/cli/commands/doctor.js +11 -11
- package/dist/cli/commands/init.js +34 -34
- package/dist/cli/commands/restart.js +1 -1
- package/dist/cli/commands/session.js +79 -0
- package/dist/cli/commands/start.js +4 -1
- package/dist/cli/index.js +3 -1
- package/dist/config/manager.js +16 -15
- package/dist/config/schemas.js +2 -1
- package/dist/http/__tests__/config_api.test.js +6 -1
- package/dist/http/api.js +160 -3
- package/dist/http/server.js +4 -2
- package/dist/runtime/memory/backfill-embeddings.js +54 -0
- package/dist/runtime/memory/embedding.service.js +21 -0
- package/dist/runtime/memory/sati/index.js +5 -5
- package/dist/runtime/memory/sati/repository.js +323 -116
- package/dist/runtime/memory/sati/service.js +58 -33
- package/dist/runtime/memory/sati/system-prompts.js +19 -8
- package/dist/runtime/memory/session-embedding-worker.js +94 -0
- package/dist/runtime/memory/sqlite-vec.js +6 -0
- package/dist/runtime/memory/sqlite.js +432 -3
- package/dist/runtime/migration.js +40 -0
- package/dist/runtime/oracle.js +69 -1
- package/dist/runtime/session-embedding-scheduler.js +21 -0
- package/dist/types/config.js +8 -0
- package/dist/ui/assets/index-DqzvLXXS.js +109 -0
- package/dist/ui/assets/index-f1sqiqOo.css +1 -0
- package/dist/ui/index.html +2 -2
- package/package.json +11 -4
- package/dist/ui/assets/index-Dx1lwaMu.js +0 -96
- package/dist/ui/assets/index-QHZ08tDL.css +0 -1
|
@@ -27,6 +27,8 @@ export async function migrateConfigFile() {
|
|
|
27
27
|
}
|
|
28
28
|
// Migrate memory.limit to llm.context_window
|
|
29
29
|
await migrateContextWindow();
|
|
30
|
+
// Migrate santi -> sati
|
|
31
|
+
await migrateSantiToSati();
|
|
30
32
|
}
|
|
31
33
|
/**
|
|
32
34
|
* Migrates memory.limit to llm.context_window
|
|
@@ -78,3 +80,41 @@ async function migrateContextWindow() {
|
|
|
78
80
|
});
|
|
79
81
|
}
|
|
80
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Migrates santi config section to sati
|
|
85
|
+
* Fixes typo in previous versions
|
|
86
|
+
*/
|
|
87
|
+
async function migrateSantiToSati() {
|
|
88
|
+
const display = DisplayManager.getInstance();
|
|
89
|
+
const configPath = PATHS.config;
|
|
90
|
+
try {
|
|
91
|
+
// Check if config file exists
|
|
92
|
+
if (!await fs.pathExists(configPath)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Read current config
|
|
96
|
+
const configContent = await fs.readFile(configPath, 'utf8');
|
|
97
|
+
const config = yaml.load(configContent);
|
|
98
|
+
// Check if migration is needed
|
|
99
|
+
if (config?.santi !== undefined && config?.sati === undefined) {
|
|
100
|
+
// Create backup before migration
|
|
101
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
102
|
+
const backupPath = `${configPath}.backup-${timestamp}`;
|
|
103
|
+
await fs.copy(configPath, backupPath);
|
|
104
|
+
display.log(`Created config backup: ${backupPath}`, { source: 'Migration', level: 'info' });
|
|
105
|
+
// Perform migration
|
|
106
|
+
config.sati = config.santi;
|
|
107
|
+
delete config.santi;
|
|
108
|
+
// Write migrated config
|
|
109
|
+
const migratedYaml = yaml.dump(config);
|
|
110
|
+
await fs.writeFile(configPath, migratedYaml, 'utf8');
|
|
111
|
+
display.log('Migrated santi → sati in configuration', { source: 'Migration', level: 'info' });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
display.log(`Config migration (santi->sati) failed: ${error.message}`, {
|
|
116
|
+
source: 'Migration',
|
|
117
|
+
level: 'warning'
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
package/dist/runtime/oracle.js
CHANGED
|
@@ -37,7 +37,7 @@ export class Oracle {
|
|
|
37
37
|
const contextWindow = this.config.llm?.context_window ?? this.config.memory?.limit ?? 100;
|
|
38
38
|
this.display.log(`Using context window: ${contextWindow} messages`, { source: 'Oracle' });
|
|
39
39
|
this.history = new SQLiteChatMessageHistory({
|
|
40
|
-
sessionId:
|
|
40
|
+
sessionId: '', // Let the history manage session IDs internally
|
|
41
41
|
databasePath: this.databasePath,
|
|
42
42
|
limit: contextWindow,
|
|
43
43
|
});
|
|
@@ -245,6 +245,74 @@ You maintain intent until resolution.
|
|
|
245
245
|
}
|
|
246
246
|
return await this.history.getMessages();
|
|
247
247
|
}
|
|
248
|
+
async createNewSession() {
|
|
249
|
+
if (!this.history) {
|
|
250
|
+
throw new Error("Message history not initialized. Call initialize() first.");
|
|
251
|
+
}
|
|
252
|
+
if (this.history instanceof SQLiteChatMessageHistory) {
|
|
253
|
+
await this.history.createNewSession();
|
|
254
|
+
this.display.log('Session rolled over successfully.', { source: 'Oracle' });
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
throw new Error("Current history provider does not support session rollover.");
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
async setSessionId(sessionId) {
|
|
261
|
+
if (!this.history) {
|
|
262
|
+
throw new Error("Message history not initialized. Call initialize() first.");
|
|
263
|
+
}
|
|
264
|
+
// Check if the history provider supports switching sessions
|
|
265
|
+
// SQLiteChatMessageHistory does support it via constructor (new instance) or maybe we can add a method there too?
|
|
266
|
+
// Actually SQLiteChatMessageHistory has `switchSession(targetSessionId)` but that one logic is "pause current, activate target".
|
|
267
|
+
// For API usage, we might just want to *target* a session without necessarily changing the global "active" state regarding the Daemon?
|
|
268
|
+
//
|
|
269
|
+
// However, the user request implies this is "the" chat.
|
|
270
|
+
// If we use `switchSession` it pauses others. That seems correct for a single-user agent model.
|
|
271
|
+
//
|
|
272
|
+
// But `SQLiteChatMessageHistory` properties are `sessionId`.
|
|
273
|
+
// It seems `switchSession` in `sqlite.ts` updates the DB state.
|
|
274
|
+
// We also need to update the `sessionId` property of the `SQLiteChatMessageHistory` instance held by Oracle.
|
|
275
|
+
//
|
|
276
|
+
// Let's check `SQLiteChatMessageHistory` again.
|
|
277
|
+
// It has `sessionId` property.
|
|
278
|
+
// It does NOT have a method to just update `sessionId` property without DB side effects?
|
|
279
|
+
//
|
|
280
|
+
// Use `switchSession` from `sqlite.ts` is good for "Active/Paused" state management.
|
|
281
|
+
// But we also need the `history` instance to know it is now pointing to `sessionId`.
|
|
282
|
+
if (this.history instanceof SQLiteChatMessageHistory) {
|
|
283
|
+
// Logic:
|
|
284
|
+
// 1. If currently active session is different, switch.
|
|
285
|
+
// 2. Update internal sessionId.
|
|
286
|
+
// Actually `switchSession` in `sqlite.ts` takes `targetSessionId`.
|
|
287
|
+
// It updates the DB status.
|
|
288
|
+
// It DOES NOT seem to update `this.sessionId` of the instance?
|
|
289
|
+
// Wait, let me check `sqlite.ts` content from memory or view it again alongside.
|
|
290
|
+
//
|
|
291
|
+
// In `sqlite.ts`:
|
|
292
|
+
// public async switchSession(targetSessionId: string): Promise<void> { ... }
|
|
293
|
+
// It updates DB.
|
|
294
|
+
// It DOES NOT update `this.sessionId`.
|
|
295
|
+
//
|
|
296
|
+
// So we need to ensure `this.history` points to the new session.
|
|
297
|
+
// Since `SQLiteChatMessageHistory` might not allow changing `sessionId` publicly if it's protected/private...
|
|
298
|
+
// It is `private sessionId: string;`.
|
|
299
|
+
//
|
|
300
|
+
// So simple fix: Re-instantiate `this.history`?
|
|
301
|
+
// `this.history = new SQLiteChatMessageHistory({ sessionId: sessionId, ... })`
|
|
302
|
+
//
|
|
303
|
+
// This is safe and clean.
|
|
304
|
+
await this.history.switchSession(sessionId);
|
|
305
|
+
// Re-instantiate to point to new session
|
|
306
|
+
this.history = new SQLiteChatMessageHistory({
|
|
307
|
+
sessionId: sessionId,
|
|
308
|
+
databasePath: this.databasePath,
|
|
309
|
+
limit: this.config.llm?.context_window ?? 100
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
throw new Error("Current history provider does not support session switching.");
|
|
314
|
+
}
|
|
315
|
+
}
|
|
248
316
|
async clearMemory() {
|
|
249
317
|
if (!this.history) {
|
|
250
318
|
throw new Error("Message history not initialized. Call initialize() first.");
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { runSessionEmbeddingWorker } from './memory/session-embedding-worker.js';
|
|
2
|
+
import { DisplayManager } from './display.js';
|
|
3
|
+
const INTERVAL_MS = 60_000 * 5; // 5 minutos
|
|
4
|
+
export function startSessionEmbeddingScheduler() {
|
|
5
|
+
const display = DisplayManager.getInstance();
|
|
6
|
+
display.log('🕒 Scheduler de embeddings iniciado', { source: 'SessionEmbeddingScheduler' });
|
|
7
|
+
// roda imediatamente na inicialização
|
|
8
|
+
runSessionEmbeddingWorker().catch(console.error);
|
|
9
|
+
let isRunning = false;
|
|
10
|
+
setInterval(async () => {
|
|
11
|
+
if (isRunning)
|
|
12
|
+
return;
|
|
13
|
+
isRunning = true;
|
|
14
|
+
try {
|
|
15
|
+
await runSessionEmbeddingWorker();
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
isRunning = false;
|
|
19
|
+
}
|
|
20
|
+
}, INTERVAL_MS);
|
|
21
|
+
}
|
package/dist/types/config.js
CHANGED