agentgui 1.0.809 → 1.0.811
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/database.js +17 -0
- package/lib/db-queries.js +63 -18
- package/package.json +1 -1
package/database.js
CHANGED
|
@@ -40,6 +40,7 @@ try {
|
|
|
40
40
|
db.run('PRAGMA cache_size = -64000');
|
|
41
41
|
db.run('PRAGMA mmap_size = 268435456');
|
|
42
42
|
db.run('PRAGMA temp_store = MEMORY');
|
|
43
|
+
db.run('PRAGMA auto_vacuum = INCREMENTAL');
|
|
43
44
|
} catch (e) {
|
|
44
45
|
try {
|
|
45
46
|
const sqlite3 = require('better-sqlite3');
|
|
@@ -52,6 +53,7 @@ try {
|
|
|
52
53
|
db.pragma('cache_size = -64000');
|
|
53
54
|
db.pragma('mmap_size = 268435456');
|
|
54
55
|
db.pragma('temp_store = MEMORY');
|
|
56
|
+
db.pragma('auto_vacuum = INCREMENTAL');
|
|
55
57
|
} catch (e2) {
|
|
56
58
|
throw new Error('SQLite database is required. Please run with bun (recommended) or install better-sqlite3: npm install better-sqlite3');
|
|
57
59
|
}
|
|
@@ -612,6 +614,21 @@ try {
|
|
|
612
614
|
console.error('[Migration] FTS5 error:', err.message);
|
|
613
615
|
}
|
|
614
616
|
|
|
617
|
+
// One-time: enable incremental auto_vacuum on existing databases (requires VACUUM to activate)
|
|
618
|
+
try {
|
|
619
|
+
const autoVacuum = db.prepare('PRAGMA auto_vacuum').get();
|
|
620
|
+
const mode = autoVacuum?.auto_vacuum ?? autoVacuum;
|
|
621
|
+
if (mode !== 2) { // 2 = INCREMENTAL
|
|
622
|
+
console.log('[Migration] Enabling incremental auto_vacuum (one-time VACUUM)...');
|
|
623
|
+
db.exec('PRAGMA auto_vacuum = INCREMENTAL');
|
|
624
|
+
// VACUUM skipped intentionally — full VACUUM on large DBs blocks server startup
|
|
625
|
+
// INCREMENTAL auto_vacuum will apply to new pages going forward
|
|
626
|
+
console.log('[Migration] auto_vacuum = INCREMENTAL enabled (VACUUM skipped)');
|
|
627
|
+
}
|
|
628
|
+
} catch (err) {
|
|
629
|
+
console.error('[Migration] auto_vacuum setup error:', err.message);
|
|
630
|
+
}
|
|
631
|
+
|
|
615
632
|
const stmtCache = new Map();
|
|
616
633
|
function prep(sql) {
|
|
617
634
|
let s = stmtCache.get(sql);
|
package/lib/db-queries.js
CHANGED
|
@@ -598,24 +598,69 @@ export function createQueries(db, prep, generateId) {
|
|
|
598
598
|
}
|
|
599
599
|
},
|
|
600
600
|
|
|
601
|
-
cleanup() {
|
|
602
|
-
const thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);
|
|
603
|
-
const sevenDaysAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);
|
|
604
|
-
const now = Date.now();
|
|
605
|
-
|
|
606
|
-
const cleanupStmt = db.transaction(() => {
|
|
607
|
-
|
|
608
|
-
prep('DELETE FROM
|
|
609
|
-
prep('DELETE FROM
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
prep('DELETE FROM
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
601
|
+
cleanup() {
|
|
602
|
+
const thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);
|
|
603
|
+
const sevenDaysAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);
|
|
604
|
+
const now = Date.now();
|
|
605
|
+
|
|
606
|
+
const cleanupStmt = db.transaction(() => {
|
|
607
|
+
// Core tables - time-based retention
|
|
608
|
+
prep('DELETE FROM events WHERE created_at < ?').run(thirtyDaysAgo);
|
|
609
|
+
prep('DELETE FROM sessions WHERE completed_at IS NOT NULL AND completed_at < ?').run(thirtyDaysAgo);
|
|
610
|
+
prep('DELETE FROM idempotencyKeys WHERE (created_at + ttl) < ?').run(now);
|
|
611
|
+
|
|
612
|
+
// Chunks and stream_updates: completed sessions >7 days
|
|
613
|
+
prep('DELETE FROM chunks WHERE sessionId IN (SELECT id FROM sessions WHERE completed_at IS NOT NULL AND completed_at < ?)').run(sevenDaysAgo);
|
|
614
|
+
prep('DELETE FROM stream_updates WHERE sessionId IN (SELECT id FROM sessions WHERE completed_at IS NOT NULL AND completed_at < ?)').run(sevenDaysAgo);
|
|
615
|
+
|
|
616
|
+
// Chunks and stream_updates: orphaned (session missing or stuck non-completed >7 days)
|
|
617
|
+
prep('DELETE FROM chunks WHERE created_at < ? AND sessionId NOT IN (SELECT id FROM sessions WHERE completed_at IS NULL AND started_at >= ?)').run(sevenDaysAgo, sevenDaysAgo);
|
|
618
|
+
prep('DELETE FROM stream_updates WHERE created_at < ? AND sessionId NOT IN (SELECT id FROM sessions WHERE completed_at IS NULL AND started_at >= ?)').run(sevenDaysAgo, sevenDaysAgo);
|
|
619
|
+
|
|
620
|
+
// Clean expired voice cache
|
|
621
|
+
prep('DELETE FROM voice_cache WHERE expires_at <= ?').run(now);
|
|
622
|
+
|
|
623
|
+
// Hard-delete soft-deleted conversations and their orphaned data after 7 days
|
|
624
|
+
const deletedConvIds = prep("SELECT id FROM conversations WHERE status = 'deleted' AND updated_at < ?").all(sevenDaysAgo).map(r => r.id);
|
|
625
|
+
for (const cid of deletedConvIds) {
|
|
626
|
+
prep('DELETE FROM stream_updates WHERE conversationId = ?').run(cid);
|
|
627
|
+
prep('DELETE FROM chunks WHERE conversationId = ?').run(cid);
|
|
628
|
+
prep('DELETE FROM events WHERE conversationId = ?').run(cid);
|
|
629
|
+
prep('DELETE FROM sessions WHERE conversationId = ?').run(cid);
|
|
630
|
+
prep('DELETE FROM messages WHERE conversationId = ?').run(cid);
|
|
631
|
+
prep('DELETE FROM voice_cache WHERE conversationId = ?').run(cid);
|
|
632
|
+
prep('DELETE FROM thread_states WHERE thread_id = ?').run(cid);
|
|
633
|
+
prep('DELETE FROM checkpoints WHERE thread_id = ?').run(cid);
|
|
634
|
+
prep('DELETE FROM run_metadata WHERE thread_id = ?').run(cid);
|
|
635
|
+
prep('DELETE FROM conversations WHERE id = ?').run(cid);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// ACP tables: prune old thread_states, checkpoints, run_metadata (30 days)
|
|
639
|
+
prep('DELETE FROM thread_states WHERE created_at < ?').run(thirtyDaysAgo);
|
|
640
|
+
prep('DELETE FROM checkpoints WHERE created_at < ?').run(thirtyDaysAgo);
|
|
641
|
+
prep('DELETE FROM run_metadata WHERE created_at < ? AND status NOT IN (?, ?)').run(thirtyDaysAgo, 'active', 'pending');
|
|
642
|
+
|
|
643
|
+
// Workflow runs older than 30 days
|
|
644
|
+
prep('DELETE FROM workflow_runs WHERE created_at < ?').run(thirtyDaysAgo);
|
|
645
|
+
|
|
646
|
+
// Tool install history: keep last 50 per tool
|
|
647
|
+
const toolIds = prep('SELECT DISTINCT tool_id FROM tool_install_history').all().map(r => r.tool_id);
|
|
648
|
+
for (const tid of toolIds) {
|
|
649
|
+
prep(`DELETE FROM tool_install_history WHERE tool_id = ? AND id NOT IN (
|
|
650
|
+
SELECT id FROM tool_install_history WHERE tool_id = ? ORDER BY created_at DESC LIMIT 50
|
|
651
|
+
)`).run(tid, tid);
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
cleanupStmt();
|
|
656
|
+
|
|
657
|
+
// Incremental VACUUM to reclaim space without blocking (WAL-safe)
|
|
658
|
+
try {
|
|
659
|
+
db.exec('PRAGMA incremental_vacuum(1000)');
|
|
660
|
+
} catch (_) {
|
|
661
|
+
// incremental_vacuum requires auto_vacuum=INCREMENTAL, fall through
|
|
662
|
+
}
|
|
663
|
+
},
|
|
619
664
|
|
|
620
665
|
setIdempotencyKey(key, value) {
|
|
621
666
|
const now = Date.now();
|