@kybernesis/brain-core 0.1.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/claude-call.d.ts +37 -0
- package/dist/claude-call.d.ts.map +1 -0
- package/dist/claude-call.js +55 -0
- package/dist/claude-call.js.map +1 -0
- package/dist/entity-graph.d.ts +79 -0
- package/dist/entity-graph.d.ts.map +1 -0
- package/dist/entity-graph.js +611 -0
- package/dist/entity-graph.js.map +1 -0
- package/dist/fact-contradiction.d.ts +25 -0
- package/dist/fact-contradiction.d.ts.map +1 -0
- package/dist/fact-contradiction.js +109 -0
- package/dist/fact-contradiction.js.map +1 -0
- package/dist/fact-extractor.d.ts +26 -0
- package/dist/fact-extractor.d.ts.map +1 -0
- package/dist/fact-extractor.js +98 -0
- package/dist/fact-extractor.js.map +1 -0
- package/dist/fact-retrieval.d.ts +51 -0
- package/dist/fact-retrieval.d.ts.map +1 -0
- package/dist/fact-retrieval.js +401 -0
- package/dist/fact-retrieval.js.map +1 -0
- package/dist/fact-store.d.ts +26 -0
- package/dist/fact-store.d.ts.map +1 -0
- package/dist/fact-store.js +181 -0
- package/dist/fact-store.js.map +1 -0
- package/dist/fact-temporal.d.ts +20 -0
- package/dist/fact-temporal.d.ts.map +1 -0
- package/dist/fact-temporal.js +79 -0
- package/dist/fact-temporal.js.map +1 -0
- package/dist/fts-sanitizer.d.ts +32 -0
- package/dist/fts-sanitizer.d.ts.map +1 -0
- package/dist/fts-sanitizer.js +61 -0
- package/dist/fts-sanitizer.js.map +1 -0
- package/dist/hybrid-search.d.ts +44 -0
- package/dist/hybrid-search.d.ts.map +1 -0
- package/dist/hybrid-search.js +410 -0
- package/dist/hybrid-search.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/ops.d.ts +28 -0
- package/dist/ops.d.ts.map +1 -0
- package/dist/ops.js +307 -0
- package/dist/ops.js.map +1 -0
- package/dist/queue.d.ts +13 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +28 -0
- package/dist/queue.js.map +1 -0
- package/dist/relationship-extractor.d.ts +38 -0
- package/dist/relationship-extractor.d.ts.map +1 -0
- package/dist/relationship-extractor.js +119 -0
- package/dist/relationship-extractor.js.map +1 -0
- package/dist/sleep/config.d.ts +47 -0
- package/dist/sleep/config.d.ts.map +1 -0
- package/dist/sleep/config.js +46 -0
- package/dist/sleep/config.js.map +1 -0
- package/dist/sleep/db.d.ts +16 -0
- package/dist/sleep/db.d.ts.map +1 -0
- package/dist/sleep/db.js +114 -0
- package/dist/sleep/db.js.map +1 -0
- package/dist/sleep/index.d.ts +69 -0
- package/dist/sleep/index.d.ts.map +1 -0
- package/dist/sleep/index.js +99 -0
- package/dist/sleep/index.js.map +1 -0
- package/dist/sleep/steps/consolidate.d.ts +19 -0
- package/dist/sleep/steps/consolidate.d.ts.map +1 -0
- package/dist/sleep/steps/consolidate.js +74 -0
- package/dist/sleep/steps/consolidate.js.map +1 -0
- package/dist/sleep/steps/decay.d.ts +19 -0
- package/dist/sleep/steps/decay.d.ts.map +1 -0
- package/dist/sleep/steps/decay.js +121 -0
- package/dist/sleep/steps/decay.js.map +1 -0
- package/dist/sleep/steps/entity-hygiene.d.ts +29 -0
- package/dist/sleep/steps/entity-hygiene.d.ts.map +1 -0
- package/dist/sleep/steps/entity-hygiene.js +452 -0
- package/dist/sleep/steps/entity-hygiene.js.map +1 -0
- package/dist/sleep/steps/link.d.ts +20 -0
- package/dist/sleep/steps/link.d.ts.map +1 -0
- package/dist/sleep/steps/link.js +216 -0
- package/dist/sleep/steps/link.js.map +1 -0
- package/dist/sleep/steps/observe.d.ts +17 -0
- package/dist/sleep/steps/observe.d.ts.map +1 -0
- package/dist/sleep/steps/observe.js +192 -0
- package/dist/sleep/steps/observe.js.map +1 -0
- package/dist/sleep/steps/profile.d.ts +15 -0
- package/dist/sleep/steps/profile.d.ts.map +1 -0
- package/dist/sleep/steps/profile.js +26 -0
- package/dist/sleep/steps/profile.js.map +1 -0
- package/dist/sleep/steps/reasoning.d.ts +19 -0
- package/dist/sleep/steps/reasoning.d.ts.map +1 -0
- package/dist/sleep/steps/reasoning.js +173 -0
- package/dist/sleep/steps/reasoning.js.map +1 -0
- package/dist/sleep/steps/summarize.d.ts +21 -0
- package/dist/sleep/steps/summarize.d.ts.map +1 -0
- package/dist/sleep/steps/summarize.js +206 -0
- package/dist/sleep/steps/summarize.js.map +1 -0
- package/dist/sleep/steps/tag.d.ts +16 -0
- package/dist/sleep/steps/tag.d.ts.map +1 -0
- package/dist/sleep/steps/tag.js +84 -0
- package/dist/sleep/steps/tag.js.map +1 -0
- package/dist/sleep/steps/tier.d.ts +18 -0
- package/dist/sleep/steps/tier.d.ts.map +1 -0
- package/dist/sleep/steps/tier.js +112 -0
- package/dist/sleep/steps/tier.js.map +1 -0
- package/dist/sleep/utils/checkpoint.d.ts +11 -0
- package/dist/sleep/utils/checkpoint.d.ts.map +1 -0
- package/dist/sleep/utils/checkpoint.js +26 -0
- package/dist/sleep/utils/checkpoint.js.map +1 -0
- package/dist/sleep/utils/jaccard.d.ts +7 -0
- package/dist/sleep/utils/jaccard.d.ts.map +1 -0
- package/dist/sleep/utils/jaccard.js +19 -0
- package/dist/sleep/utils/jaccard.js.map +1 -0
- package/dist/store-conversation.d.ts +29 -0
- package/dist/store-conversation.d.ts.map +1 -0
- package/dist/store-conversation.js +227 -0
- package/dist/store-conversation.js.map +1 -0
- package/dist/timeline.d.ts +50 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +389 -0
- package/dist/timeline.js.map +1 -0
- package/dist/user-profile.d.ts +30 -0
- package/dist/user-profile.d.ts.map +1 -0
- package/dist/user-profile.js +147 -0
- package/dist/user-profile.js.map +1 -0
- package/dist/vectors.d.ts +56 -0
- package/dist/vectors.d.ts.map +1 -0
- package/dist/vectors.js +132 -0
- package/dist/vectors.js.map +1 -0
- package/package.json +53 -0
package/dist/timeline.js
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { getDb } from '@kybernesis/brain-storage-sqlite';
|
|
2
|
+
import { sanitizeFtsQuery } from './fts-sanitizer.js';
|
|
3
|
+
function rowToEvent(row) {
|
|
4
|
+
return {
|
|
5
|
+
id: row.id,
|
|
6
|
+
type: row.type,
|
|
7
|
+
timestamp: row.timestamp,
|
|
8
|
+
endTimestamp: row.end_timestamp ?? undefined,
|
|
9
|
+
title: row.title,
|
|
10
|
+
summary: row.summary ?? undefined,
|
|
11
|
+
sourcePath: row.source_path,
|
|
12
|
+
entities: JSON.parse(row.entities_json || '[]'),
|
|
13
|
+
topics: JSON.parse(row.topics_json || '[]'),
|
|
14
|
+
priority: row.priority ?? 0.5,
|
|
15
|
+
decayScore: row.decay_score ?? 0.0,
|
|
16
|
+
tier: (row.tier ?? 'warm'),
|
|
17
|
+
tags: JSON.parse(row.tags_json || '[]'),
|
|
18
|
+
lastEnriched: row.last_enriched ?? undefined,
|
|
19
|
+
accessCount: row.access_count ?? 0,
|
|
20
|
+
isPinned: (row.is_pinned ?? 0) === 1,
|
|
21
|
+
lastAccessed: row.last_accessed ?? undefined,
|
|
22
|
+
projectId: row.project_id ?? undefined,
|
|
23
|
+
classification: row.classification ?? undefined,
|
|
24
|
+
connectionId: row.connection_id ?? undefined,
|
|
25
|
+
sourceDid: row.source_did ?? undefined,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// ─── Schema initialization ────────────────────────────────────────────────────
|
|
29
|
+
const initialized = new Set();
|
|
30
|
+
function ensureSchema(t) {
|
|
31
|
+
if (initialized.has(t.slug))
|
|
32
|
+
return;
|
|
33
|
+
const db = getDb(t, 'timeline');
|
|
34
|
+
db.exec(`
|
|
35
|
+
CREATE TABLE IF NOT EXISTS timeline_events (
|
|
36
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
37
|
+
type TEXT NOT NULL CHECK(type IN ('conversation', 'idea', 'file', 'transcript', 'note', 'intake')),
|
|
38
|
+
timestamp TEXT NOT NULL,
|
|
39
|
+
end_timestamp TEXT,
|
|
40
|
+
title TEXT NOT NULL,
|
|
41
|
+
summary TEXT,
|
|
42
|
+
source_path TEXT NOT NULL UNIQUE,
|
|
43
|
+
entities_json TEXT DEFAULT '[]',
|
|
44
|
+
topics_json TEXT DEFAULT '[]',
|
|
45
|
+
priority REAL DEFAULT 0.5,
|
|
46
|
+
decay_score REAL DEFAULT 0.0,
|
|
47
|
+
tier TEXT DEFAULT 'warm',
|
|
48
|
+
tags_json TEXT DEFAULT '[]',
|
|
49
|
+
last_enriched TEXT,
|
|
50
|
+
access_count INTEGER DEFAULT 0,
|
|
51
|
+
is_pinned INTEGER DEFAULT 0,
|
|
52
|
+
last_accessed TEXT,
|
|
53
|
+
project_id TEXT,
|
|
54
|
+
classification TEXT,
|
|
55
|
+
connection_id TEXT,
|
|
56
|
+
source_did TEXT
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_timestamp ON timeline_events(timestamp);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_type ON timeline_events(type);
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_source ON timeline_events(source_path);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_tier ON timeline_events(tier);
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_priority ON timeline_events(priority DESC);
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_last_enriched ON timeline_events(last_enriched);
|
|
65
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_project ON timeline_events(project_id);
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_classification ON timeline_events(classification);
|
|
67
|
+
CREATE INDEX IF NOT EXISTS idx_timeline_connection ON timeline_events(connection_id);
|
|
68
|
+
|
|
69
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS timeline_fts USING fts5(
|
|
70
|
+
title, summary, entities, topics, content=''
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
CREATE TRIGGER IF NOT EXISTS timeline_ai AFTER INSERT ON timeline_events BEGIN
|
|
74
|
+
INSERT INTO timeline_fts(rowid, title, summary, entities, topics)
|
|
75
|
+
VALUES (new.id, new.title, new.summary, new.entities_json, new.topics_json);
|
|
76
|
+
END;
|
|
77
|
+
|
|
78
|
+
CREATE TRIGGER IF NOT EXISTS timeline_ad AFTER DELETE ON timeline_events BEGIN
|
|
79
|
+
INSERT INTO timeline_fts(timeline_fts, rowid, title, summary, entities, topics)
|
|
80
|
+
VALUES ('delete', old.id, old.title, old.summary, old.entities_json, old.topics_json);
|
|
81
|
+
END;
|
|
82
|
+
|
|
83
|
+
CREATE TRIGGER IF NOT EXISTS timeline_au AFTER UPDATE ON timeline_events BEGIN
|
|
84
|
+
INSERT INTO timeline_fts(timeline_fts, rowid, title, summary, entities, topics)
|
|
85
|
+
VALUES ('delete', old.id, old.title, old.summary, old.entities_json, old.topics_json);
|
|
86
|
+
INSERT INTO timeline_fts(rowid, title, summary, entities, topics)
|
|
87
|
+
VALUES (new.id, new.title, new.summary, new.entities_json, new.topics_json);
|
|
88
|
+
END;
|
|
89
|
+
|
|
90
|
+
CREATE TABLE IF NOT EXISTS facts (
|
|
91
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
92
|
+
content TEXT NOT NULL,
|
|
93
|
+
source_path TEXT NOT NULL UNIQUE,
|
|
94
|
+
source_conversation_id TEXT NOT NULL,
|
|
95
|
+
entities_json TEXT DEFAULT '[]',
|
|
96
|
+
timestamp TEXT NOT NULL,
|
|
97
|
+
confidence REAL DEFAULT 0.7,
|
|
98
|
+
category TEXT DEFAULT 'general',
|
|
99
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
100
|
+
is_latest INTEGER DEFAULT 1,
|
|
101
|
+
superseded_by INTEGER,
|
|
102
|
+
expires_at TEXT,
|
|
103
|
+
updated_at TEXT,
|
|
104
|
+
access_count INTEGER DEFAULT 0,
|
|
105
|
+
source_type TEXT DEFAULT 'chat',
|
|
106
|
+
is_retracted INTEGER DEFAULT 0,
|
|
107
|
+
retracted_by TEXT,
|
|
108
|
+
last_reinforced_at TEXT,
|
|
109
|
+
project_id TEXT,
|
|
110
|
+
tags_json TEXT DEFAULT '[]',
|
|
111
|
+
classification TEXT,
|
|
112
|
+
connection_id TEXT,
|
|
113
|
+
source_did TEXT
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
CREATE INDEX IF NOT EXISTS idx_facts_source_conv ON facts(source_conversation_id);
|
|
117
|
+
CREATE INDEX IF NOT EXISTS idx_facts_category ON facts(category);
|
|
118
|
+
CREATE INDEX IF NOT EXISTS idx_facts_timestamp ON facts(timestamp);
|
|
119
|
+
CREATE INDEX IF NOT EXISTS idx_facts_source_path ON facts(source_path);
|
|
120
|
+
CREATE INDEX IF NOT EXISTS idx_facts_is_latest ON facts(is_latest);
|
|
121
|
+
CREATE INDEX IF NOT EXISTS idx_facts_expires_at ON facts(expires_at);
|
|
122
|
+
CREATE INDEX IF NOT EXISTS idx_facts_project ON facts(project_id);
|
|
123
|
+
CREATE INDEX IF NOT EXISTS idx_facts_classification ON facts(classification);
|
|
124
|
+
CREATE INDEX IF NOT EXISTS idx_facts_connection ON facts(connection_id);
|
|
125
|
+
`);
|
|
126
|
+
initialized.add(t.slug);
|
|
127
|
+
}
|
|
128
|
+
export function resetTimelineDb(t) {
|
|
129
|
+
if (t) {
|
|
130
|
+
initialized.delete(t.slug);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
initialized.clear();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// ─── Event operations ─────────────────────────────────────────────────────────
|
|
137
|
+
export async function addToTimeline(t, event) {
|
|
138
|
+
ensureSchema(t);
|
|
139
|
+
const db = getDb(t, 'timeline');
|
|
140
|
+
const result = db.prepare(`
|
|
141
|
+
INSERT INTO timeline_events
|
|
142
|
+
(type, timestamp, end_timestamp, title, summary, source_path,
|
|
143
|
+
entities_json, topics_json,
|
|
144
|
+
project_id, tags_json, classification, connection_id, source_did)
|
|
145
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
146
|
+
ON CONFLICT(source_path) DO UPDATE SET
|
|
147
|
+
type = excluded.type,
|
|
148
|
+
timestamp = excluded.timestamp,
|
|
149
|
+
end_timestamp = excluded.end_timestamp,
|
|
150
|
+
title = excluded.title,
|
|
151
|
+
summary = excluded.summary,
|
|
152
|
+
entities_json = excluded.entities_json,
|
|
153
|
+
topics_json = excluded.topics_json,
|
|
154
|
+
project_id = COALESCE(excluded.project_id, timeline_events.project_id),
|
|
155
|
+
tags_json = COALESCE(excluded.tags_json, timeline_events.tags_json),
|
|
156
|
+
classification = COALESCE(excluded.classification, timeline_events.classification),
|
|
157
|
+
connection_id = COALESCE(excluded.connection_id, timeline_events.connection_id),
|
|
158
|
+
source_did = COALESCE(excluded.source_did, timeline_events.source_did)
|
|
159
|
+
`).run(event.type, event.timestamp, event.endTimestamp ?? null, event.title, event.summary ?? '', event.sourcePath, JSON.stringify(event.entities), JSON.stringify(event.topics), event.projectId ?? null, JSON.stringify(event.tags), event.classification ?? null, event.connectionId ?? null, event.sourceDid ?? null);
|
|
160
|
+
return result.lastInsertRowid;
|
|
161
|
+
}
|
|
162
|
+
export async function removeFromTimeline(t, sourcePath) {
|
|
163
|
+
ensureSchema(t);
|
|
164
|
+
const db = getDb(t, 'timeline');
|
|
165
|
+
const result = db.prepare('DELETE FROM timeline_events WHERE source_path = ?').run(sourcePath);
|
|
166
|
+
return result.changes > 0;
|
|
167
|
+
}
|
|
168
|
+
export async function updateTimelineEvent(t, id, updates) {
|
|
169
|
+
ensureSchema(t);
|
|
170
|
+
const db = getDb(t, 'timeline');
|
|
171
|
+
const parts = [];
|
|
172
|
+
const params = [];
|
|
173
|
+
if (updates.title !== undefined) {
|
|
174
|
+
parts.push('title = ?');
|
|
175
|
+
params.push(updates.title);
|
|
176
|
+
}
|
|
177
|
+
if (updates.summary !== undefined) {
|
|
178
|
+
parts.push('summary = ?');
|
|
179
|
+
params.push(updates.summary);
|
|
180
|
+
}
|
|
181
|
+
if (updates.timestamp !== undefined) {
|
|
182
|
+
parts.push('timestamp = ?');
|
|
183
|
+
params.push(updates.timestamp);
|
|
184
|
+
}
|
|
185
|
+
if (updates.endTimestamp !== undefined) {
|
|
186
|
+
parts.push('end_timestamp = ?');
|
|
187
|
+
params.push(updates.endTimestamp);
|
|
188
|
+
}
|
|
189
|
+
if (updates.entities !== undefined) {
|
|
190
|
+
parts.push('entities_json = ?');
|
|
191
|
+
params.push(JSON.stringify(updates.entities));
|
|
192
|
+
}
|
|
193
|
+
if (updates.topics !== undefined) {
|
|
194
|
+
parts.push('topics_json = ?');
|
|
195
|
+
params.push(JSON.stringify(updates.topics));
|
|
196
|
+
}
|
|
197
|
+
if (updates.tags !== undefined) {
|
|
198
|
+
parts.push('tags_json = ?');
|
|
199
|
+
params.push(JSON.stringify(updates.tags));
|
|
200
|
+
}
|
|
201
|
+
if (updates.priority !== undefined) {
|
|
202
|
+
parts.push('priority = ?');
|
|
203
|
+
params.push(updates.priority);
|
|
204
|
+
}
|
|
205
|
+
if (updates.decayScore !== undefined) {
|
|
206
|
+
parts.push('decay_score = ?');
|
|
207
|
+
params.push(updates.decayScore);
|
|
208
|
+
}
|
|
209
|
+
if (updates.tier !== undefined) {
|
|
210
|
+
parts.push('tier = ?');
|
|
211
|
+
params.push(updates.tier);
|
|
212
|
+
}
|
|
213
|
+
if (updates.lastEnriched !== undefined) {
|
|
214
|
+
parts.push('last_enriched = ?');
|
|
215
|
+
params.push(updates.lastEnriched);
|
|
216
|
+
}
|
|
217
|
+
if (updates.isPinned !== undefined) {
|
|
218
|
+
parts.push('is_pinned = ?');
|
|
219
|
+
params.push(updates.isPinned ? 1 : 0);
|
|
220
|
+
}
|
|
221
|
+
if (parts.length === 0)
|
|
222
|
+
return;
|
|
223
|
+
params.push(id);
|
|
224
|
+
db.prepare(`UPDATE timeline_events SET ${parts.join(', ')} WHERE id = ?`).run(...params);
|
|
225
|
+
}
|
|
226
|
+
export async function deleteTimelineEventById(t, id) {
|
|
227
|
+
ensureSchema(t);
|
|
228
|
+
const db = getDb(t, 'timeline');
|
|
229
|
+
const result = db.prepare('DELETE FROM timeline_events WHERE id = ?').run(id);
|
|
230
|
+
return result.changes > 0;
|
|
231
|
+
}
|
|
232
|
+
export async function getEventById(t, id) {
|
|
233
|
+
ensureSchema(t);
|
|
234
|
+
const db = getDb(t, 'timeline');
|
|
235
|
+
const row = db.prepare('SELECT * FROM timeline_events WHERE id = ?').get(id);
|
|
236
|
+
return row ? rowToEvent(row) : null;
|
|
237
|
+
}
|
|
238
|
+
export async function getEventByPath(t, sourcePath) {
|
|
239
|
+
ensureSchema(t);
|
|
240
|
+
const db = getDb(t, 'timeline');
|
|
241
|
+
const row = db.prepare('SELECT * FROM timeline_events WHERE source_path = ?').get(sourcePath);
|
|
242
|
+
return row ? rowToEvent(row) : null;
|
|
243
|
+
}
|
|
244
|
+
export async function queryTimeline(t, query = {}) {
|
|
245
|
+
ensureSchema(t);
|
|
246
|
+
const db = getDb(t, 'timeline');
|
|
247
|
+
const conditions = [];
|
|
248
|
+
const params = [];
|
|
249
|
+
if (query.start) {
|
|
250
|
+
conditions.push('timestamp >= ?');
|
|
251
|
+
params.push(query.start);
|
|
252
|
+
}
|
|
253
|
+
if (query.end) {
|
|
254
|
+
conditions.push('timestamp <= ?');
|
|
255
|
+
params.push(query.end);
|
|
256
|
+
}
|
|
257
|
+
if (query.type) {
|
|
258
|
+
conditions.push('type = ?');
|
|
259
|
+
params.push(query.type);
|
|
260
|
+
}
|
|
261
|
+
if (query.search) {
|
|
262
|
+
const sanitized = sanitizeFtsQuery(query.search);
|
|
263
|
+
if (sanitized) {
|
|
264
|
+
conditions.push('id IN (SELECT rowid FROM timeline_fts WHERE timeline_fts MATCH ?)');
|
|
265
|
+
params.push(sanitized);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (query.entities && query.entities.length > 0) {
|
|
269
|
+
const entityConds = query.entities.map(() => 'entities_json LIKE ?');
|
|
270
|
+
conditions.push(`(${entityConds.join(' OR ')})`);
|
|
271
|
+
for (const e of query.entities)
|
|
272
|
+
params.push(`%${e.toLowerCase()}%`);
|
|
273
|
+
}
|
|
274
|
+
if (query.topics && query.topics.length > 0) {
|
|
275
|
+
const topicConds = query.topics.map(() => 'topics_json LIKE ?');
|
|
276
|
+
conditions.push(`(${topicConds.join(' OR ')})`);
|
|
277
|
+
for (const topic of query.topics)
|
|
278
|
+
params.push(`%${topic.toLowerCase()}%`);
|
|
279
|
+
}
|
|
280
|
+
let sql = 'SELECT * FROM timeline_events';
|
|
281
|
+
if (conditions.length > 0)
|
|
282
|
+
sql += ' WHERE ' + conditions.join(' AND ');
|
|
283
|
+
sql += ' ORDER BY timestamp DESC';
|
|
284
|
+
sql += ' LIMIT ? OFFSET ?';
|
|
285
|
+
params.push(query.limit ?? 50, query.offset ?? 0);
|
|
286
|
+
const rows = db.prepare(sql).all(...params);
|
|
287
|
+
return rows.map(rowToEvent);
|
|
288
|
+
}
|
|
289
|
+
export async function getRecentActivity(t, limit = 20) {
|
|
290
|
+
return queryTimeline(t, { limit });
|
|
291
|
+
}
|
|
292
|
+
export async function getActivityOnDate(t, date) {
|
|
293
|
+
return queryTimeline(t, {
|
|
294
|
+
start: `${date}T00:00:00.000Z`,
|
|
295
|
+
end: `${date}T23:59:59.999Z`,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
export async function getActivityInRange(t, start, end) {
|
|
299
|
+
return queryTimeline(t, { start, end });
|
|
300
|
+
}
|
|
301
|
+
export async function searchTimeline(t, searchQuery, options = {}) {
|
|
302
|
+
return queryTimeline(t, { search: searchQuery, limit: options.limit, type: options.type });
|
|
303
|
+
}
|
|
304
|
+
// ─── Deduplication ────────────────────────────────────────────────────────────
|
|
305
|
+
export async function findRecentDuplicate(t, title, withinHours) {
|
|
306
|
+
ensureSchema(t);
|
|
307
|
+
const db = getDb(t, 'timeline');
|
|
308
|
+
const cutoff = new Date(Date.now() - withinHours * 60 * 60 * 1000).toISOString();
|
|
309
|
+
const normalized = title.replace(/^\[.*?\]\s*/, '').replace(/\.{3}$/, '').trim().toLowerCase();
|
|
310
|
+
const rows = db.prepare(`
|
|
311
|
+
SELECT id, title FROM timeline_events
|
|
312
|
+
WHERE timestamp >= ?
|
|
313
|
+
ORDER BY timestamp DESC
|
|
314
|
+
LIMIT 100
|
|
315
|
+
`).all(cutoff);
|
|
316
|
+
for (const row of rows) {
|
|
317
|
+
const rowNorm = row.title.replace(/^\[.*?\]\s*/, '').replace(/\.{3}$/, '').trim().toLowerCase();
|
|
318
|
+
if (rowNorm === normalized)
|
|
319
|
+
return row;
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
export async function incrementTimelineEventCount(t, eventId) {
|
|
324
|
+
ensureSchema(t);
|
|
325
|
+
const db = getDb(t, 'timeline');
|
|
326
|
+
db.prepare(`
|
|
327
|
+
UPDATE timeline_events
|
|
328
|
+
SET access_count = COALESCE(access_count, 0) + 1,
|
|
329
|
+
last_accessed = datetime('now')
|
|
330
|
+
WHERE id = ?
|
|
331
|
+
`).run(eventId);
|
|
332
|
+
}
|
|
333
|
+
export async function getTimelineStats(t) {
|
|
334
|
+
ensureSchema(t);
|
|
335
|
+
const db = getDb(t, 'timeline');
|
|
336
|
+
const { count } = db.prepare('SELECT COUNT(*) as count FROM timeline_events').get();
|
|
337
|
+
const byTypeRows = db.prepare('SELECT type, COUNT(*) as count FROM timeline_events GROUP BY type').all();
|
|
338
|
+
const dateRange = db.prepare('SELECT MIN(timestamp) as earliest, MAX(timestamp) as latest FROM timeline_events').get();
|
|
339
|
+
const byType = {
|
|
340
|
+
conversation: 0, idea: 0, file: 0, transcript: 0, note: 0, intake: 0,
|
|
341
|
+
};
|
|
342
|
+
for (const row of byTypeRows) {
|
|
343
|
+
byType[row.type] = row.count;
|
|
344
|
+
}
|
|
345
|
+
return { totalEvents: count, byType, dateRange };
|
|
346
|
+
}
|
|
347
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
348
|
+
export async function addConversationToTimeline(t, _conversationId, sourcePath, startedAt, finishedAt, title, summary, entities, topics, arpMetadata, eventType = 'conversation') {
|
|
349
|
+
return addToTimeline(t, {
|
|
350
|
+
type: eventType,
|
|
351
|
+
timestamp: startedAt,
|
|
352
|
+
endTimestamp: finishedAt,
|
|
353
|
+
title,
|
|
354
|
+
summary,
|
|
355
|
+
sourcePath,
|
|
356
|
+
entities,
|
|
357
|
+
topics,
|
|
358
|
+
priority: 0.5,
|
|
359
|
+
decayScore: 0.0,
|
|
360
|
+
tier: 'warm',
|
|
361
|
+
tags: arpMetadata?.tags ?? [],
|
|
362
|
+
isPinned: false,
|
|
363
|
+
accessCount: 0,
|
|
364
|
+
...(arpMetadata ? {
|
|
365
|
+
projectId: arpMetadata.projectId,
|
|
366
|
+
classification: arpMetadata.classification,
|
|
367
|
+
connectionId: arpMetadata.connectionId,
|
|
368
|
+
sourceDid: arpMetadata.sourceDid,
|
|
369
|
+
} : {}),
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
export async function addIdeaToTimeline(t, _ideaId, sourcePath, createdAt, title, description, tags) {
|
|
373
|
+
return addToTimeline(t, {
|
|
374
|
+
type: 'idea',
|
|
375
|
+
timestamp: createdAt,
|
|
376
|
+
title,
|
|
377
|
+
summary: description,
|
|
378
|
+
sourcePath,
|
|
379
|
+
entities: [],
|
|
380
|
+
topics: tags,
|
|
381
|
+
priority: 0.5,
|
|
382
|
+
decayScore: 0.0,
|
|
383
|
+
tier: 'warm',
|
|
384
|
+
tags: [],
|
|
385
|
+
isPinned: false,
|
|
386
|
+
accessCount: 0,
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
//# sourceMappingURL=timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../src/timeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User profile — port of KAD's user-profile.ts.
|
|
3
|
+
*
|
|
4
|
+
* Auto-generated profile from the fact store. Cached as JSON for instant
|
|
5
|
+
* (~1ms) access. Injected into system prompts so agents have key user context.
|
|
6
|
+
*/
|
|
7
|
+
import type { TenantContext } from '@kybernesis/brain-contracts';
|
|
8
|
+
export interface UserProfile {
|
|
9
|
+
generated_at: string;
|
|
10
|
+
fact_count: number;
|
|
11
|
+
sections: {
|
|
12
|
+
identity: string[];
|
|
13
|
+
preferences: string[];
|
|
14
|
+
relationships: string[];
|
|
15
|
+
current_plans: string[];
|
|
16
|
+
recent_events: string[];
|
|
17
|
+
};
|
|
18
|
+
top_entities: Array<{
|
|
19
|
+
name: string;
|
|
20
|
+
type: string;
|
|
21
|
+
mention_count: number;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
export declare function generateUserProfile(t: TenantContext): Promise<UserProfile>;
|
|
25
|
+
export declare function getCachedProfile(t: TenantContext): UserProfile | null;
|
|
26
|
+
export declare function cacheProfile(t: TenantContext, profile: UserProfile): void;
|
|
27
|
+
/** Returns age of cached profile in minutes, or Infinity if none. */
|
|
28
|
+
export declare function getProfileAge(t: TenantContext): number;
|
|
29
|
+
export declare function formatProfileForPrompt(profile: UserProfile): string;
|
|
30
|
+
//# sourceMappingURL=user-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-profile.d.ts","sourceRoot":"","sources":["../src/user-profile.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAKjE,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,aAAa,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC;IACF,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5E;AAID,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBhF;AA4DD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,aAAa,GAAG,WAAW,GAAG,IAAI,CAQrE;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAQzE;AAED,qEAAqE;AACrE,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAMtD;AAID,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAyBnE"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User profile — port of KAD's user-profile.ts.
|
|
3
|
+
*
|
|
4
|
+
* Auto-generated profile from the fact store. Cached as JSON for instant
|
|
5
|
+
* (~1ms) access. Injected into system prompts so agents have key user context.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
8
|
+
import { dirname } from 'node:path';
|
|
9
|
+
import { getDb } from '@kybernesis/brain-storage-sqlite';
|
|
10
|
+
import { ensureFactsTable } from './fact-store.js';
|
|
11
|
+
// ─── Generation ───────────────────────────────────────────────────────────────
|
|
12
|
+
export async function generateUserProfile(t) {
|
|
13
|
+
await ensureFactsTable(t);
|
|
14
|
+
const db = getDb(t, 'timeline');
|
|
15
|
+
const identity = queryFacts(db, 'biographical', 15);
|
|
16
|
+
const preferences = queryFacts(db, 'preference', 10);
|
|
17
|
+
const relationships = queryFacts(db, 'relationship', 10);
|
|
18
|
+
const current_plans = queryFacts(db, 'plan', 5);
|
|
19
|
+
const recent_events = queryRecentFacts(db, 'event', 5);
|
|
20
|
+
const totalFacts = identity.length + preferences.length + relationships.length
|
|
21
|
+
+ current_plans.length + recent_events.length;
|
|
22
|
+
const top_entities = queryTopEntities(t);
|
|
23
|
+
return {
|
|
24
|
+
generated_at: new Date().toISOString(),
|
|
25
|
+
fact_count: totalFacts,
|
|
26
|
+
sections: { identity, preferences, relationships, current_plans, recent_events },
|
|
27
|
+
top_entities,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function queryFacts(db, category, limit) {
|
|
31
|
+
try {
|
|
32
|
+
const rows = db.prepare(`
|
|
33
|
+
SELECT content FROM facts
|
|
34
|
+
WHERE category = ?
|
|
35
|
+
AND is_latest = 1
|
|
36
|
+
AND (expires_at IS NULL OR expires_at > datetime('now'))
|
|
37
|
+
ORDER BY confidence DESC, access_count DESC
|
|
38
|
+
LIMIT ?
|
|
39
|
+
`).all(category, limit);
|
|
40
|
+
return rows.map((r) => r.content);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// access_count column may not exist yet
|
|
44
|
+
try {
|
|
45
|
+
const rows = db.prepare(`
|
|
46
|
+
SELECT content FROM facts
|
|
47
|
+
WHERE category = ?
|
|
48
|
+
AND is_latest = 1
|
|
49
|
+
AND (expires_at IS NULL OR expires_at > datetime('now'))
|
|
50
|
+
ORDER BY confidence DESC
|
|
51
|
+
LIMIT ?
|
|
52
|
+
`).all(category, limit);
|
|
53
|
+
return rows.map((r) => r.content);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function queryRecentFacts(db, category, limit) {
|
|
61
|
+
try {
|
|
62
|
+
const rows = db.prepare(`
|
|
63
|
+
SELECT content FROM facts
|
|
64
|
+
WHERE category = ?
|
|
65
|
+
AND is_latest = 1
|
|
66
|
+
AND (expires_at IS NULL OR expires_at > datetime('now'))
|
|
67
|
+
ORDER BY timestamp DESC
|
|
68
|
+
LIMIT ?
|
|
69
|
+
`).all(category, limit);
|
|
70
|
+
return rows.map((r) => r.content);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function queryTopEntities(t) {
|
|
77
|
+
try {
|
|
78
|
+
const db = getDb(t, 'entityGraph');
|
|
79
|
+
return db.prepare('SELECT name, type, mention_count FROM entities ORDER BY mention_count DESC LIMIT 10').all();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// ─── Cache operations ─────────────────────────────────────────────────────────
|
|
86
|
+
export function getCachedProfile(t) {
|
|
87
|
+
const path = t.paths.userProfileJsonPath;
|
|
88
|
+
if (!existsSync(path))
|
|
89
|
+
return null;
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export function cacheProfile(t, profile) {
|
|
98
|
+
const path = t.paths.userProfileJsonPath;
|
|
99
|
+
try {
|
|
100
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
101
|
+
writeFileSync(path, JSON.stringify(profile, null, 2), 'utf-8');
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
console.warn('[brain-core/user-profile] cache write failed', { err: String(err) });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Returns age of cached profile in minutes, or Infinity if none. */
|
|
108
|
+
export function getProfileAge(t) {
|
|
109
|
+
const cached = getCachedProfile(t);
|
|
110
|
+
if (!cached?.generated_at)
|
|
111
|
+
return Infinity;
|
|
112
|
+
const generatedAt = new Date(cached.generated_at).getTime();
|
|
113
|
+
if (isNaN(generatedAt))
|
|
114
|
+
return Infinity;
|
|
115
|
+
return (Date.now() - generatedAt) / (1000 * 60);
|
|
116
|
+
}
|
|
117
|
+
// ─── Prompt formatting ────────────────────────────────────────────────────────
|
|
118
|
+
export function formatProfileForPrompt(profile) {
|
|
119
|
+
const lines = ['## Auto-Generated User Profile'];
|
|
120
|
+
if (profile.sections.identity.length > 0) {
|
|
121
|
+
lines.push('', '### Identity');
|
|
122
|
+
for (const f of profile.sections.identity)
|
|
123
|
+
lines.push(`- ${f}`);
|
|
124
|
+
}
|
|
125
|
+
if (profile.sections.preferences.length > 0) {
|
|
126
|
+
lines.push('', '### Preferences');
|
|
127
|
+
for (const f of profile.sections.preferences)
|
|
128
|
+
lines.push(`- ${f}`);
|
|
129
|
+
}
|
|
130
|
+
if (profile.sections.relationships.length > 0) {
|
|
131
|
+
lines.push('', '### Key Relationships');
|
|
132
|
+
for (const f of profile.sections.relationships)
|
|
133
|
+
lines.push(`- ${f}`);
|
|
134
|
+
}
|
|
135
|
+
if (profile.sections.current_plans.length > 0) {
|
|
136
|
+
lines.push('', '### Current Plans');
|
|
137
|
+
for (const f of profile.sections.current_plans)
|
|
138
|
+
lines.push(`- ${f}`);
|
|
139
|
+
}
|
|
140
|
+
if (profile.sections.recent_events.length > 0) {
|
|
141
|
+
lines.push('', '### Recent Events');
|
|
142
|
+
for (const f of profile.sections.recent_events)
|
|
143
|
+
lines.push(`- ${f}`);
|
|
144
|
+
}
|
|
145
|
+
return lines.join('\n');
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=user-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-profile.js","sourceRoot":"","sources":["../src/user-profile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vector indexing + semantic search — port of KAD's vectors.ts.
|
|
3
|
+
*
|
|
4
|
+
* Brain-core owns the operations; brain-storage-vec owns the connection
|
|
5
|
+
* + sqlite-vec extension. Embeddings are injected via setEmbeddingProvider
|
|
6
|
+
* (same pattern as setLLMProvider — see ADR-0009): the library has no
|
|
7
|
+
* default backend, the app wires one at startup. When no provider is set,
|
|
8
|
+
* indexChunk is a no-op and semanticSearch returns [].
|
|
9
|
+
*
|
|
10
|
+
* KAD's default backend is OpenAI text-embedding-3-small (1536-dim). Other
|
|
11
|
+
* backends (Voyage, local) can be wired identically.
|
|
12
|
+
*/
|
|
13
|
+
import type { TenantContext } from '@kybernesis/brain-contracts';
|
|
14
|
+
export declare const EMBEDDING_DIM = 1536;
|
|
15
|
+
export interface EmbeddingProvider {
|
|
16
|
+
/** Returns a 1536-dim vector, or null on failure. */
|
|
17
|
+
embed(text: string): Promise<number[] | null>;
|
|
18
|
+
}
|
|
19
|
+
export declare function setEmbeddingProvider(p: EmbeddingProvider): void;
|
|
20
|
+
export declare function resetEmbeddingProvider(): void;
|
|
21
|
+
export declare function embeddingAvailable(): boolean;
|
|
22
|
+
export interface IndexChunkMeta {
|
|
23
|
+
ts: string;
|
|
24
|
+
source?: string;
|
|
25
|
+
origin_id?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface IndexChunkResult {
|
|
28
|
+
indexed: boolean;
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function indexChunk(t: TenantContext, content: string, meta: IndexChunkMeta): Promise<IndexChunkResult>;
|
|
32
|
+
export interface SearchResult {
|
|
33
|
+
id: string;
|
|
34
|
+
content: string;
|
|
35
|
+
distance: number;
|
|
36
|
+
metadata: {
|
|
37
|
+
source_path: string;
|
|
38
|
+
title?: string;
|
|
39
|
+
timestamp?: string;
|
|
40
|
+
type?: string;
|
|
41
|
+
entities?: string[];
|
|
42
|
+
topics?: string[];
|
|
43
|
+
summary?: string;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export declare function semanticSearch(t: TenantContext, query: string, opts?: {
|
|
47
|
+
limit?: number;
|
|
48
|
+
type?: string;
|
|
49
|
+
}): Promise<SearchResult[]>;
|
|
50
|
+
export declare function vectorStats(t: TenantContext): Promise<{
|
|
51
|
+
count: number;
|
|
52
|
+
available: boolean;
|
|
53
|
+
}>;
|
|
54
|
+
/** Reset the cached storage module — for tests where we need a clean state. */
|
|
55
|
+
export declare function _resetVecStorageCache(): void;
|
|
56
|
+
//# sourceMappingURL=vectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vectors.d.ts","sourceRoot":"","sources":["../src/vectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,eAAO,MAAM,aAAa,OAAO,CAAC;AAGlC,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;CAC/C;AAID,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAmB;AACnF,wBAAgB,sBAAsB,IAAI,IAAI,CAAsB;AACpE,wBAAgB,kBAAkB,IAAI,OAAO,CAA+B;AAI5E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,UAAU,CAC9B,CAAC,EAAE,aAAa,EAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,gBAAgB,CAAC,CAoC3B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE;QACR,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAUD,wBAAsB,cAAc,CAClC,CAAC,EAAE,aAAa,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3C,OAAO,CAAC,YAAY,EAAE,CAAC,CAwCzB;AAED,wBAAsB,WAAW,CAC/B,CAAC,EAAE,aAAa,GACf,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAUhD;AA2BD,+EAA+E;AAC/E,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C"}
|