@kybernesis/brain-storage-sqlite 0.2.0 → 0.6.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/dist/entity-graph.d.ts +12 -0
- package/dist/entity-graph.d.ts.map +1 -0
- package/dist/entity-graph.js +620 -0
- package/dist/entity-graph.js.map +1 -0
- package/dist/fact-retrieval-queries.d.ts +12 -0
- package/dist/fact-retrieval-queries.d.ts.map +1 -0
- package/dist/fact-retrieval-queries.js +116 -0
- package/dist/fact-retrieval-queries.js.map +1 -0
- package/dist/fact-store.d.ts +8 -0
- package/dist/fact-store.d.ts.map +1 -0
- package/dist/fact-store.js +222 -0
- package/dist/fact-store.js.map +1 -0
- package/dist/fts-sanitizer.d.ts +30 -0
- package/dist/fts-sanitizer.d.ts.map +1 -0
- package/dist/fts-sanitizer.js +59 -0
- package/dist/fts-sanitizer.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/provider.d.ts +16 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +93 -0
- package/dist/provider.js.map +1 -0
- package/dist/search-queries.d.ts +14 -0
- package/dist/search-queries.d.ts.map +1 -0
- package/dist/search-queries.js +84 -0
- package/dist/search-queries.js.map +1 -0
- package/dist/sleep-maintenance.d.ts +15 -0
- package/dist/sleep-maintenance.d.ts.map +1 -0
- package/dist/sleep-maintenance.js +227 -0
- package/dist/sleep-maintenance.js.map +1 -0
- package/dist/sleep-store.d.ts +29 -0
- package/dist/sleep-store.d.ts.map +1 -0
- package/dist/sleep-store.js +377 -0
- package/dist/sleep-store.js.map +1 -0
- package/dist/timeline.d.ts +11 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +351 -0
- package/dist/timeline.js.map +1 -0
- package/package.json +6 -3
package/dist/provider.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite StorageProvider — the default backend wired by brain-core's seam.
|
|
3
|
+
*
|
|
4
|
+
* The persistence stores (timeline, entities, facts) + the minimal sleep read +
|
|
5
|
+
* the lazy vector store are all real as of 0.3.0. The sleep maintenance engine,
|
|
6
|
+
* hybrid-search, and fact-retrieval remain on guarded direct getDb (deferred to
|
|
7
|
+
* 0.4.0 — see docs/specs/storage-architecture-0.3-and-0.4.md).
|
|
8
|
+
*
|
|
9
|
+
* The SQL that lands here is moved verbatim (port-faithful) from the
|
|
10
|
+
* corresponding brain-core module; behaviour is held constant.
|
|
11
|
+
*/
|
|
12
|
+
import { sqliteFactStore } from './fact-store.js';
|
|
13
|
+
import { sqliteTimelineStore } from './timeline.js';
|
|
14
|
+
import { sqliteEntityGraphStore } from './entity-graph.js';
|
|
15
|
+
import { sqliteSleepStore } from './sleep-store.js';
|
|
16
|
+
import { sqliteSleepMaintenance } from './sleep-maintenance.js';
|
|
17
|
+
import { sqliteSearchQueries } from './search-queries.js';
|
|
18
|
+
import { sqliteFactRetrievalQueries } from './fact-retrieval-queries.js';
|
|
19
|
+
// ─── Lazy vector store ────────────────────────────────────────────────────────
|
|
20
|
+
// VectorRepository is a first-class member of the bundle (decision #3 Option A), but
|
|
21
|
+
// brain-storage-vec carries the sqlite-vec NATIVE binary. We load it lazily on
|
|
22
|
+
// first vector use so it never costs apps anything at provider-creation time,
|
|
23
|
+
// and brain-storage-sqlite keeps NO static dependency on sqlite-vec. If the
|
|
24
|
+
// package can't be loaded (not installed / wrong platform), the store degrades
|
|
25
|
+
// to safe no-ops — brain-core's vectors layer maps these to its graceful results.
|
|
26
|
+
let _vecStore = null;
|
|
27
|
+
let _vecAttempted = false;
|
|
28
|
+
async function loadVecStore() {
|
|
29
|
+
if (_vecAttempted)
|
|
30
|
+
return _vecStore;
|
|
31
|
+
_vecAttempted = true;
|
|
32
|
+
try {
|
|
33
|
+
const mod = await import('@kybernesis/brain-storage-vec');
|
|
34
|
+
_vecStore = mod.sqliteVecStore;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
_vecStore = null;
|
|
38
|
+
}
|
|
39
|
+
return _vecStore;
|
|
40
|
+
}
|
|
41
|
+
/** Reset the lazy vec-store cache (test/utility). */
|
|
42
|
+
export function resetLazyVectorStore() {
|
|
43
|
+
_vecStore = null;
|
|
44
|
+
_vecAttempted = false;
|
|
45
|
+
}
|
|
46
|
+
const lazyVectorStore = {
|
|
47
|
+
async available(t) {
|
|
48
|
+
const s = await loadVecStore();
|
|
49
|
+
return s ? s.available(t) : false;
|
|
50
|
+
},
|
|
51
|
+
async hasOrigin(t, originId) {
|
|
52
|
+
const s = await loadVecStore();
|
|
53
|
+
if (!s)
|
|
54
|
+
return false;
|
|
55
|
+
return s.hasOrigin(t, originId);
|
|
56
|
+
},
|
|
57
|
+
async insertChunk(t, chunk) {
|
|
58
|
+
const s = await loadVecStore();
|
|
59
|
+
if (!s)
|
|
60
|
+
throw new Error('[brain-storage-sqlite] vector backend unavailable');
|
|
61
|
+
return s.insertChunk(t, chunk);
|
|
62
|
+
},
|
|
63
|
+
async search(t, embedding, limit) {
|
|
64
|
+
const s = await loadVecStore();
|
|
65
|
+
if (!s)
|
|
66
|
+
return [];
|
|
67
|
+
return s.search(t, embedding, limit);
|
|
68
|
+
},
|
|
69
|
+
async stats(t) {
|
|
70
|
+
const s = await loadVecStore();
|
|
71
|
+
if (!s)
|
|
72
|
+
return { count: 0, available: false };
|
|
73
|
+
return s.stats(t);
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
export function createSqliteStorageProvider() {
|
|
77
|
+
return {
|
|
78
|
+
repositories: {
|
|
79
|
+
timeline: sqliteTimelineStore,
|
|
80
|
+
entities: sqliteEntityGraphStore,
|
|
81
|
+
facts: sqliteFactStore,
|
|
82
|
+
sleep: sqliteSleepStore,
|
|
83
|
+
vectors: lazyVectorStore,
|
|
84
|
+
},
|
|
85
|
+
// Business plane — populated per gate (U1 search, U2 fact-retrieval, U3 sleep).
|
|
86
|
+
domain: {
|
|
87
|
+
search: sqliteSearchQueries, // U1
|
|
88
|
+
factRetrieval: sqliteFactRetrievalQueries, // U2
|
|
89
|
+
sleep: sqliteSleepMaintenance, // U3b+
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearchQueries (SQLite impl) — the hybrid-search candidate/factor SQL.
|
|
3
|
+
*
|
|
4
|
+
* Business plane (gate U1 of the 0.6.0 untangle). The SQL here moved VERBATIM
|
|
5
|
+
* from brain-core/hybrid-search.ts; behaviour is held constant. Only candidate
|
|
6
|
+
* generation + score-factor fetches live here — the scoring itself (RRF fusion,
|
|
7
|
+
* metadata weights, tier boosts, segment dedup) stays in brain-core.
|
|
8
|
+
*
|
|
9
|
+
* Each method is tolerant of a bad FTS token / missing column exactly as the
|
|
10
|
+
* original inline code was (try/catch → []), so parity holds.
|
|
11
|
+
*/
|
|
12
|
+
import type { SearchQueries } from '@kybernesis/brain-contracts';
|
|
13
|
+
export declare const sqliteSearchQueries: SearchQueries;
|
|
14
|
+
//# sourceMappingURL=search-queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-queries.d.ts","sourceRoot":"","sources":["../src/search-queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAEV,aAAa,EAId,MAAM,6BAA6B,CAAC;AAIrC,eAAO,MAAM,mBAAmB,EAAE,aA0EjC,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SearchQueries (SQLite impl) — the hybrid-search candidate/factor SQL.
|
|
3
|
+
*
|
|
4
|
+
* Business plane (gate U1 of the 0.6.0 untangle). The SQL here moved VERBATIM
|
|
5
|
+
* from brain-core/hybrid-search.ts; behaviour is held constant. Only candidate
|
|
6
|
+
* generation + score-factor fetches live here — the scoring itself (RRF fusion,
|
|
7
|
+
* metadata weights, tier boosts, segment dedup) stays in brain-core.
|
|
8
|
+
*
|
|
9
|
+
* Each method is tolerant of a bad FTS token / missing column exactly as the
|
|
10
|
+
* original inline code was (try/catch → []), so parity holds.
|
|
11
|
+
*/
|
|
12
|
+
import { getDb } from './index.js';
|
|
13
|
+
import { sanitizeFtsQuery } from './fts-sanitizer.js';
|
|
14
|
+
export const sqliteSearchQueries = {
|
|
15
|
+
async temporalCandidates(t, term, limit) {
|
|
16
|
+
const db = getDb(t, 'timeline');
|
|
17
|
+
try {
|
|
18
|
+
const like = `%${term.toLowerCase()}%`;
|
|
19
|
+
return db.prepare(`
|
|
20
|
+
SELECT id, title, summary, source_path, timestamp, type
|
|
21
|
+
FROM timeline_events
|
|
22
|
+
WHERE LOWER(title) LIKE ? OR LOWER(summary) LIKE ?
|
|
23
|
+
ORDER BY timestamp DESC LIMIT ?
|
|
24
|
+
`).all(like, like, limit);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return []; // best-effort, matching the original inline behaviour
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
async metadataCandidates(t, query, limit) {
|
|
31
|
+
// Bug Fix #2: sanitize so hyphens / unicode / FTS5 reserved tokens don't throw.
|
|
32
|
+
const ftsQuery = sanitizeFtsQuery(query);
|
|
33
|
+
if (!ftsQuery)
|
|
34
|
+
return [];
|
|
35
|
+
const db = getDb(t, 'timeline');
|
|
36
|
+
try {
|
|
37
|
+
return db.prepare(`
|
|
38
|
+
SELECT t.id, t.source_path, t.title, t.summary, t.type, t.timestamp,
|
|
39
|
+
t.tier, t.priority, t.tags_json
|
|
40
|
+
FROM timeline_events t
|
|
41
|
+
JOIN timeline_fts fts ON t.id = fts.rowid
|
|
42
|
+
WHERE timeline_fts MATCH ? ORDER BY rank LIMIT ?
|
|
43
|
+
`).all(ftsQuery, limit);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return []; // FTS query failed (e.g. bad token) — candidates stays []
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
async entityAugmentedCandidates(t, query) {
|
|
50
|
+
const out = [];
|
|
51
|
+
try {
|
|
52
|
+
const db = getDb(t, 'timeline');
|
|
53
|
+
const entityDb = getDb(t, 'entityGraph');
|
|
54
|
+
const queryLower = query.toLowerCase();
|
|
55
|
+
const allEntities = entityDb.prepare('SELECT id, name FROM entities ORDER BY mention_count DESC LIMIT 100').all();
|
|
56
|
+
const matched = allEntities.filter(e => queryLower.includes(e.name.toLowerCase()) && e.name.length >= 3);
|
|
57
|
+
for (const ent of matched.slice(0, 3)) {
|
|
58
|
+
const mentions = entityDb.prepare('SELECT DISTINCT source_path FROM entity_mentions WHERE entity_id = ? ORDER BY timestamp DESC LIMIT 10').all(ent.id);
|
|
59
|
+
for (const m of mentions) {
|
|
60
|
+
const event = db.prepare('SELECT id, title, summary, source_path, timestamp, type FROM timeline_events WHERE source_path = ?').get(m.source_path);
|
|
61
|
+
if (event)
|
|
62
|
+
out.push(event);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.warn('[brain-storage-sqlite/search] entity augmentation failed', { err: String(err) });
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
},
|
|
71
|
+
async enrichByPath(t, sourcePath) {
|
|
72
|
+
const db = getDb(t, 'timeline');
|
|
73
|
+
try {
|
|
74
|
+
const row = db.prepare(`
|
|
75
|
+
SELECT tier, priority, tags_json, entities_json FROM timeline_events WHERE source_path = ?
|
|
76
|
+
`).get(sourcePath);
|
|
77
|
+
return row ?? null;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null; // non-critical
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=search-queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-queries.js","sourceRoot":"","sources":["../src/search-queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SleepMaintenance (SQLite impl) — the maintenance-engine policy encoded IN SQL.
|
|
3
|
+
*
|
|
4
|
+
* Business plane (gate U3 of the 0.6.0 untangle). Only statements whose business
|
|
5
|
+
* heuristic lives inside the SQL itself land here (policy UPDATEs, normalization
|
|
6
|
+
* GROUP BYs, multi-clause prune WHEREs, unprocessed-detection NOT EXISTS) —
|
|
7
|
+
* relocated VERBATIM from the brain-core sleep steps; behaviour held constant.
|
|
8
|
+
* The scoring/decision JS stays in the steps.
|
|
9
|
+
*
|
|
10
|
+
* Grows green per sub-gate (U3b decay; U3d consolidate; U3e entity-hygiene;
|
|
11
|
+
* U3f summarize/observe). See docs/specs/storage-untangle-0.6.0-progress.md.
|
|
12
|
+
*/
|
|
13
|
+
import type { SleepMaintenance } from '@kybernesis/brain-contracts';
|
|
14
|
+
export declare const sqliteSleepMaintenance: SleepMaintenance;
|
|
15
|
+
//# sourceMappingURL=sleep-maintenance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sleep-maintenance.d.ts","sourceRoot":"","sources":["../src/sleep-maintenance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACK,gBAAgB,EAGhC,MAAM,6BAA6B,CAAC;AAGrC,eAAO,MAAM,sBAAsB,EAAE,gBAmOpC,CAAC"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SleepMaintenance (SQLite impl) — the maintenance-engine policy encoded IN SQL.
|
|
3
|
+
*
|
|
4
|
+
* Business plane (gate U3 of the 0.6.0 untangle). Only statements whose business
|
|
5
|
+
* heuristic lives inside the SQL itself land here (policy UPDATEs, normalization
|
|
6
|
+
* GROUP BYs, multi-clause prune WHEREs, unprocessed-detection NOT EXISTS) —
|
|
7
|
+
* relocated VERBATIM from the brain-core sleep steps; behaviour held constant.
|
|
8
|
+
* The scoring/decision JS stays in the steps.
|
|
9
|
+
*
|
|
10
|
+
* Grows green per sub-gate (U3b decay; U3d consolidate; U3e entity-hygiene;
|
|
11
|
+
* U3f summarize/observe). See docs/specs/storage-untangle-0.6.0-progress.md.
|
|
12
|
+
*/
|
|
13
|
+
import { getDb } from './index.js';
|
|
14
|
+
export const sqliteSleepMaintenance = {
|
|
15
|
+
// ── decay: policy-bearing fact UPDATEs (U3b) ──
|
|
16
|
+
async expireTemporalFacts(t) {
|
|
17
|
+
const db = getDb(t, 'timeline');
|
|
18
|
+
const r = db.prepare(`
|
|
19
|
+
UPDATE facts SET is_latest = 0, updated_at = datetime('now')
|
|
20
|
+
WHERE expires_at IS NOT NULL
|
|
21
|
+
AND expires_at < datetime('now')
|
|
22
|
+
AND is_latest = 1
|
|
23
|
+
`).run();
|
|
24
|
+
return r.changes;
|
|
25
|
+
},
|
|
26
|
+
async lastFactConfidenceDecayAt(t) {
|
|
27
|
+
const db = getDb(t, 'timeline');
|
|
28
|
+
const row = db.prepare(`
|
|
29
|
+
SELECT MAX(updated_at) as last_decay FROM facts
|
|
30
|
+
WHERE updated_at IS NOT NULL AND confidence < 0.85
|
|
31
|
+
`).get();
|
|
32
|
+
return row?.last_decay ?? null;
|
|
33
|
+
},
|
|
34
|
+
async decayFactConfidence(t) {
|
|
35
|
+
const db = getDb(t, 'timeline');
|
|
36
|
+
const r = db.prepare(`
|
|
37
|
+
UPDATE facts
|
|
38
|
+
SET confidence = MAX(confidence * 0.95, 0.15),
|
|
39
|
+
updated_at = datetime('now')
|
|
40
|
+
WHERE source_type IN ('ai-extraction', 'chat')
|
|
41
|
+
AND created_at < datetime('now', '-90 days')
|
|
42
|
+
AND last_reinforced_at IS NULL
|
|
43
|
+
AND COALESCE(is_retracted, 0) = 0
|
|
44
|
+
AND confidence > 0.15
|
|
45
|
+
AND is_latest = 1
|
|
46
|
+
`).run();
|
|
47
|
+
return r.changes;
|
|
48
|
+
},
|
|
49
|
+
// ── consolidate: title-normalization grouping + merge (U3d; stays SQL) ──
|
|
50
|
+
async fetchConsolidationGroups(t, threshold, limit) {
|
|
51
|
+
const db = getDb(t, 'timeline');
|
|
52
|
+
// Normalization (strip `[channel] ` prefix + trailing `...`) is done IN SQL —
|
|
53
|
+
// decision 3: keep it SQL, relocated verbatim, parity-asserted. NOT JS.
|
|
54
|
+
return db.prepare(`
|
|
55
|
+
SELECT
|
|
56
|
+
TRIM(REPLACE(
|
|
57
|
+
CASE WHEN INSTR(title, '] ') > 0
|
|
58
|
+
THEN SUBSTR(title, INSTR(title, '] ') + 2)
|
|
59
|
+
ELSE title
|
|
60
|
+
END,
|
|
61
|
+
'...', ''
|
|
62
|
+
)) as normalized_title,
|
|
63
|
+
COUNT(*) as cnt,
|
|
64
|
+
GROUP_CONCAT(id) as ids,
|
|
65
|
+
MIN(timestamp) as first_ts,
|
|
66
|
+
MAX(timestamp) as last_ts
|
|
67
|
+
FROM timeline_events
|
|
68
|
+
WHERE (is_pinned IS NULL OR is_pinned = 0)
|
|
69
|
+
GROUP BY normalized_title
|
|
70
|
+
HAVING COUNT(*) >= ?
|
|
71
|
+
ORDER BY cnt DESC
|
|
72
|
+
LIMIT ?
|
|
73
|
+
`).all(threshold, limit);
|
|
74
|
+
},
|
|
75
|
+
async sumAccessCounts(t, ids) {
|
|
76
|
+
const db = getDb(t, 'timeline');
|
|
77
|
+
const placeholders = ids.map(() => '?').join(',');
|
|
78
|
+
const row = db.prepare(`
|
|
79
|
+
SELECT COALESCE(SUM(COALESCE(access_count, 0)), 0) as total
|
|
80
|
+
FROM timeline_events WHERE id IN (${placeholders})
|
|
81
|
+
`).get(...ids);
|
|
82
|
+
return row.total;
|
|
83
|
+
},
|
|
84
|
+
async consolidateInto(t, keepId, removeIds, addedAccess) {
|
|
85
|
+
const db = getDb(t, 'timeline');
|
|
86
|
+
const placeholders = removeIds.map(() => '?').join(',');
|
|
87
|
+
db.prepare(`
|
|
88
|
+
UPDATE timeline_events
|
|
89
|
+
SET access_count = COALESCE(access_count, 0) + ?,
|
|
90
|
+
last_accessed = datetime('now')
|
|
91
|
+
WHERE id = ?
|
|
92
|
+
`).run(addedAccess, keepId);
|
|
93
|
+
db.prepare(`
|
|
94
|
+
DELETE FROM timeline_events WHERE id IN (${placeholders})
|
|
95
|
+
`).run(...removeIds);
|
|
96
|
+
},
|
|
97
|
+
// ── entity-hygiene: policy filters (U3e) ──
|
|
98
|
+
async cleanOrphans(t) {
|
|
99
|
+
const db = getDb(t, 'entityGraph');
|
|
100
|
+
db.prepare(`
|
|
101
|
+
DELETE FROM entity_relations WHERE
|
|
102
|
+
source_id NOT IN (SELECT id FROM entities) OR
|
|
103
|
+
target_id NOT IN (SELECT id FROM entities)
|
|
104
|
+
`).run();
|
|
105
|
+
db.prepare(`
|
|
106
|
+
DELETE FROM entity_mentions WHERE
|
|
107
|
+
entity_id NOT IN (SELECT id FROM entities)
|
|
108
|
+
`).run();
|
|
109
|
+
},
|
|
110
|
+
async fetchAllEntities(t) {
|
|
111
|
+
const db = getDb(t, 'entityGraph');
|
|
112
|
+
return db.prepare('SELECT id, name, type, mention_count FROM entities').all();
|
|
113
|
+
},
|
|
114
|
+
async fetchSameNameGroups(t) {
|
|
115
|
+
const db = getDb(t, 'entityGraph');
|
|
116
|
+
return db.prepare(`
|
|
117
|
+
SELECT normalized_name,
|
|
118
|
+
GROUP_CONCAT(id ORDER BY type) as ids,
|
|
119
|
+
GROUP_CONCAT(type ORDER BY type) as types,
|
|
120
|
+
GROUP_CONCAT(name ORDER BY type) as names,
|
|
121
|
+
GROUP_CONCAT(mention_count ORDER BY type) as mention_counts
|
|
122
|
+
FROM entities
|
|
123
|
+
GROUP BY normalized_name
|
|
124
|
+
HAVING COUNT(DISTINCT type) > 1
|
|
125
|
+
`).all();
|
|
126
|
+
},
|
|
127
|
+
async fetchVariantEntities(t, limit) {
|
|
128
|
+
const db = getDb(t, 'entityGraph');
|
|
129
|
+
return db.prepare(`
|
|
130
|
+
SELECT id, name, normalized_name, type, mention_count
|
|
131
|
+
FROM entities ORDER BY mention_count DESC, normalized_name ASC, type ASC LIMIT ?
|
|
132
|
+
`).all(limit);
|
|
133
|
+
},
|
|
134
|
+
async fetchEntityProfile(t, entityId) {
|
|
135
|
+
const db = getDb(t, 'entityGraph');
|
|
136
|
+
const mentions = db.prepare(`
|
|
137
|
+
SELECT context FROM entity_mentions
|
|
138
|
+
WHERE entity_id = ? AND context IS NOT NULL AND context != ''
|
|
139
|
+
ORDER BY timestamp DESC, context ASC LIMIT 5
|
|
140
|
+
`).all(entityId);
|
|
141
|
+
const related = db.prepare(`
|
|
142
|
+
SELECT DISTINCT e.name FROM entity_relations r
|
|
143
|
+
JOIN entities e ON (
|
|
144
|
+
(r.source_id = ? AND e.id = r.target_id) OR
|
|
145
|
+
(r.target_id = ? AND e.id = r.source_id)
|
|
146
|
+
)
|
|
147
|
+
ORDER BY r.strength DESC, e.name ASC LIMIT 10
|
|
148
|
+
`).all(entityId, entityId);
|
|
149
|
+
return {
|
|
150
|
+
contexts: mentions.map(m => m.context),
|
|
151
|
+
related: related.map(r => r.name),
|
|
152
|
+
};
|
|
153
|
+
},
|
|
154
|
+
async fetchPruneCandidates(t, pruneDate) {
|
|
155
|
+
const db = getDb(t, 'entityGraph');
|
|
156
|
+
// Bug B11B: ALL 5 filters must apply (omitting any over-prunes the graph).
|
|
157
|
+
return db.prepare(`
|
|
158
|
+
SELECT e.id, e.name, e.type, e.mention_count, e.last_seen, e.is_pinned
|
|
159
|
+
FROM entities e
|
|
160
|
+
WHERE e.mention_count <= 1
|
|
161
|
+
AND e.type = 'topic'
|
|
162
|
+
AND e.last_seen < ?
|
|
163
|
+
AND (e.is_pinned IS NULL OR e.is_pinned = 0)
|
|
164
|
+
AND NOT EXISTS (SELECT 1 FROM entity_relations WHERE source_id = e.id OR target_id = e.id)
|
|
165
|
+
`).all(pruneDate);
|
|
166
|
+
},
|
|
167
|
+
async fetchProfileCandidates(t, limit) {
|
|
168
|
+
const db = getDb(t, 'entityGraph');
|
|
169
|
+
// SQL verbatim from KAD entity-hygiene phase 5 — 3 columns, no mention_count.
|
|
170
|
+
return db.prepare(`
|
|
171
|
+
SELECT id, name, type FROM entities
|
|
172
|
+
WHERE mention_count >= 3
|
|
173
|
+
ORDER BY mention_count DESC, name ASC, type ASC LIMIT ?
|
|
174
|
+
`).all(limit);
|
|
175
|
+
},
|
|
176
|
+
// ── summarize + observe + reasoning: detection/heuristic SQL (U3f) ──
|
|
177
|
+
async fetchStaleSummaryIds(t, limit) {
|
|
178
|
+
const db = getDb(t, 'timeline');
|
|
179
|
+
const rows = db.prepare(`
|
|
180
|
+
SELECT id FROM timeline_events
|
|
181
|
+
WHERE (summary IS NULL
|
|
182
|
+
OR length(summary) < 50
|
|
183
|
+
OR summary LIKE '{%'
|
|
184
|
+
OR summary LIKE '# %'
|
|
185
|
+
OR length(summary) > 500)
|
|
186
|
+
AND (last_enriched IS NULL OR last_enriched < datetime('now', '-3 days'))
|
|
187
|
+
ORDER BY priority DESC
|
|
188
|
+
LIMIT ?
|
|
189
|
+
`).all(limit);
|
|
190
|
+
return rows.map(r => r.id);
|
|
191
|
+
},
|
|
192
|
+
async fetchUnprocessedConversations(t, limit) {
|
|
193
|
+
const db = getDb(t, 'timeline');
|
|
194
|
+
return db.prepare(`
|
|
195
|
+
SELECT te.id, te.source_path, te.title, te.summary, te.timestamp,
|
|
196
|
+
te.entities_json, te.topics_json
|
|
197
|
+
FROM timeline_events te
|
|
198
|
+
WHERE te.type = 'conversation'
|
|
199
|
+
AND te.summary IS NOT NULL
|
|
200
|
+
AND LENGTH(te.summary) > 50
|
|
201
|
+
AND NOT EXISTS (
|
|
202
|
+
SELECT 1 FROM timeline_events obs
|
|
203
|
+
WHERE obs.source_path LIKE 'observation://' || REPLACE(te.source_path, 'channel://', '') || '/%'
|
|
204
|
+
)
|
|
205
|
+
AND NOT EXISTS (
|
|
206
|
+
SELECT 1 FROM facts f
|
|
207
|
+
WHERE f.source_path LIKE 'fact://' || REPLACE(te.source_path, 'channel://', '') || '/%'
|
|
208
|
+
)
|
|
209
|
+
AND NOT EXISTS (
|
|
210
|
+
SELECT 1 FROM facts f
|
|
211
|
+
WHERE f.source_path LIKE 'realtime://' || REPLACE(te.source_path, 'channel://', '') || '/%'
|
|
212
|
+
)
|
|
213
|
+
ORDER BY te.timestamp DESC
|
|
214
|
+
LIMIT ?
|
|
215
|
+
`).all(limit);
|
|
216
|
+
},
|
|
217
|
+
async fetchEntityCooccurrence(t, entityId, limit) {
|
|
218
|
+
const db = getDb(t, 'entityGraph');
|
|
219
|
+
return db.prepare(`
|
|
220
|
+
SELECT e2.name, er.strength FROM entity_relations er
|
|
221
|
+
JOIN entities e2 ON e2.id = CASE WHEN er.source_id = ? THEN er.target_id ELSE er.source_id END
|
|
222
|
+
WHERE (er.source_id = ? OR er.target_id = ?) AND er.strength > 1
|
|
223
|
+
ORDER BY er.strength DESC LIMIT ?
|
|
224
|
+
`).all(entityId, entityId, entityId, limit);
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
//# sourceMappingURL=sleep-maintenance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sleep-maintenance.js","sourceRoot":"","sources":["../src/sleep-maintenance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SleepRepository (SQLite impl) — CRUD/persistence for the maintenance engine.
|
|
3
|
+
*
|
|
4
|
+
* The cohesive sleep store (decision 1): each method opens whichever DB kind it
|
|
5
|
+
* needs. As of U3a it carries the run lifecycle (sleep_runs), checkpoints,
|
|
6
|
+
* telemetry, schema bootstrap, and the existing memory_edges read. The
|
|
7
|
+
* per-step CRUD (tier/decay/link/queue/event reads+writes) lands at U3b–U3f.
|
|
8
|
+
*
|
|
9
|
+
* SQL moved VERBATIM from brain-core/sleep/{db,index,utils/checkpoint}.ts;
|
|
10
|
+
* behaviour held constant.
|
|
11
|
+
*/
|
|
12
|
+
import type Database from 'better-sqlite3';
|
|
13
|
+
import type { TenantContext, SleepRepository } from '@kybernesis/brain-contracts';
|
|
14
|
+
/**
|
|
15
|
+
* Ensure the sleep schema exists; returns the pooled sleep handle.
|
|
16
|
+
*
|
|
17
|
+
* This is the PUBLIC re-export surface (brain-core/sleep/db.ts re-exports it),
|
|
18
|
+
* kept handle-returning for 0.5.0 API parity (U4 decision A: frozen public API).
|
|
19
|
+
* The sleep ENGINE no longer consumes the handle — 0.6.0 routes every step
|
|
20
|
+
* through the seam — so a future release can deprecate the handle return. Lives
|
|
21
|
+
* HERE (storage package) so brain-core/src stays free of raw getDb.
|
|
22
|
+
*/
|
|
23
|
+
export declare function ensureSleepSchema(t: TenantContext): Database.Database;
|
|
24
|
+
/** Reap >2h-old 'running' rows to 'failed'; returns rows changed. (public re-export) */
|
|
25
|
+
export declare function recoverStaleSleepRuns(t: TenantContext): number;
|
|
26
|
+
/** Reset the per-tenant schema-init cache. (public re-export; test/utility) */
|
|
27
|
+
export declare function resetSleepSchemaCache(slug?: string): void;
|
|
28
|
+
export declare const sqliteSleepStore: SleepRepository;
|
|
29
|
+
//# sourceMappingURL=sleep-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sleep-store.d.ts","sourceRoot":"","sources":["../src/sleep-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EACV,aAAa,EAAE,eAAe,EAI/B,MAAM,6BAA6B,CAAC;AAmFrC;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAOrE;AAED,wFAAwF;AACxF,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAW9D;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAGzD;AAED,eAAO,MAAM,gBAAgB,EAAE,eAkR9B,CAAC"}
|