@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.
Files changed (129) hide show
  1. package/dist/claude-call.d.ts +37 -0
  2. package/dist/claude-call.d.ts.map +1 -0
  3. package/dist/claude-call.js +55 -0
  4. package/dist/claude-call.js.map +1 -0
  5. package/dist/entity-graph.d.ts +79 -0
  6. package/dist/entity-graph.d.ts.map +1 -0
  7. package/dist/entity-graph.js +611 -0
  8. package/dist/entity-graph.js.map +1 -0
  9. package/dist/fact-contradiction.d.ts +25 -0
  10. package/dist/fact-contradiction.d.ts.map +1 -0
  11. package/dist/fact-contradiction.js +109 -0
  12. package/dist/fact-contradiction.js.map +1 -0
  13. package/dist/fact-extractor.d.ts +26 -0
  14. package/dist/fact-extractor.d.ts.map +1 -0
  15. package/dist/fact-extractor.js +98 -0
  16. package/dist/fact-extractor.js.map +1 -0
  17. package/dist/fact-retrieval.d.ts +51 -0
  18. package/dist/fact-retrieval.d.ts.map +1 -0
  19. package/dist/fact-retrieval.js +401 -0
  20. package/dist/fact-retrieval.js.map +1 -0
  21. package/dist/fact-store.d.ts +26 -0
  22. package/dist/fact-store.d.ts.map +1 -0
  23. package/dist/fact-store.js +181 -0
  24. package/dist/fact-store.js.map +1 -0
  25. package/dist/fact-temporal.d.ts +20 -0
  26. package/dist/fact-temporal.d.ts.map +1 -0
  27. package/dist/fact-temporal.js +79 -0
  28. package/dist/fact-temporal.js.map +1 -0
  29. package/dist/fts-sanitizer.d.ts +32 -0
  30. package/dist/fts-sanitizer.d.ts.map +1 -0
  31. package/dist/fts-sanitizer.js +61 -0
  32. package/dist/fts-sanitizer.js.map +1 -0
  33. package/dist/hybrid-search.d.ts +44 -0
  34. package/dist/hybrid-search.d.ts.map +1 -0
  35. package/dist/hybrid-search.js +410 -0
  36. package/dist/hybrid-search.js.map +1 -0
  37. package/dist/index.d.ts +33 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +19 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/ops.d.ts +28 -0
  42. package/dist/ops.d.ts.map +1 -0
  43. package/dist/ops.js +307 -0
  44. package/dist/ops.js.map +1 -0
  45. package/dist/queue.d.ts +13 -0
  46. package/dist/queue.d.ts.map +1 -0
  47. package/dist/queue.js +28 -0
  48. package/dist/queue.js.map +1 -0
  49. package/dist/relationship-extractor.d.ts +38 -0
  50. package/dist/relationship-extractor.d.ts.map +1 -0
  51. package/dist/relationship-extractor.js +119 -0
  52. package/dist/relationship-extractor.js.map +1 -0
  53. package/dist/sleep/config.d.ts +47 -0
  54. package/dist/sleep/config.d.ts.map +1 -0
  55. package/dist/sleep/config.js +46 -0
  56. package/dist/sleep/config.js.map +1 -0
  57. package/dist/sleep/db.d.ts +16 -0
  58. package/dist/sleep/db.d.ts.map +1 -0
  59. package/dist/sleep/db.js +114 -0
  60. package/dist/sleep/db.js.map +1 -0
  61. package/dist/sleep/index.d.ts +69 -0
  62. package/dist/sleep/index.d.ts.map +1 -0
  63. package/dist/sleep/index.js +99 -0
  64. package/dist/sleep/index.js.map +1 -0
  65. package/dist/sleep/steps/consolidate.d.ts +19 -0
  66. package/dist/sleep/steps/consolidate.d.ts.map +1 -0
  67. package/dist/sleep/steps/consolidate.js +74 -0
  68. package/dist/sleep/steps/consolidate.js.map +1 -0
  69. package/dist/sleep/steps/decay.d.ts +19 -0
  70. package/dist/sleep/steps/decay.d.ts.map +1 -0
  71. package/dist/sleep/steps/decay.js +121 -0
  72. package/dist/sleep/steps/decay.js.map +1 -0
  73. package/dist/sleep/steps/entity-hygiene.d.ts +29 -0
  74. package/dist/sleep/steps/entity-hygiene.d.ts.map +1 -0
  75. package/dist/sleep/steps/entity-hygiene.js +452 -0
  76. package/dist/sleep/steps/entity-hygiene.js.map +1 -0
  77. package/dist/sleep/steps/link.d.ts +20 -0
  78. package/dist/sleep/steps/link.d.ts.map +1 -0
  79. package/dist/sleep/steps/link.js +216 -0
  80. package/dist/sleep/steps/link.js.map +1 -0
  81. package/dist/sleep/steps/observe.d.ts +17 -0
  82. package/dist/sleep/steps/observe.d.ts.map +1 -0
  83. package/dist/sleep/steps/observe.js +192 -0
  84. package/dist/sleep/steps/observe.js.map +1 -0
  85. package/dist/sleep/steps/profile.d.ts +15 -0
  86. package/dist/sleep/steps/profile.d.ts.map +1 -0
  87. package/dist/sleep/steps/profile.js +26 -0
  88. package/dist/sleep/steps/profile.js.map +1 -0
  89. package/dist/sleep/steps/reasoning.d.ts +19 -0
  90. package/dist/sleep/steps/reasoning.d.ts.map +1 -0
  91. package/dist/sleep/steps/reasoning.js +173 -0
  92. package/dist/sleep/steps/reasoning.js.map +1 -0
  93. package/dist/sleep/steps/summarize.d.ts +21 -0
  94. package/dist/sleep/steps/summarize.d.ts.map +1 -0
  95. package/dist/sleep/steps/summarize.js +206 -0
  96. package/dist/sleep/steps/summarize.js.map +1 -0
  97. package/dist/sleep/steps/tag.d.ts +16 -0
  98. package/dist/sleep/steps/tag.d.ts.map +1 -0
  99. package/dist/sleep/steps/tag.js +84 -0
  100. package/dist/sleep/steps/tag.js.map +1 -0
  101. package/dist/sleep/steps/tier.d.ts +18 -0
  102. package/dist/sleep/steps/tier.d.ts.map +1 -0
  103. package/dist/sleep/steps/tier.js +112 -0
  104. package/dist/sleep/steps/tier.js.map +1 -0
  105. package/dist/sleep/utils/checkpoint.d.ts +11 -0
  106. package/dist/sleep/utils/checkpoint.d.ts.map +1 -0
  107. package/dist/sleep/utils/checkpoint.js +26 -0
  108. package/dist/sleep/utils/checkpoint.js.map +1 -0
  109. package/dist/sleep/utils/jaccard.d.ts +7 -0
  110. package/dist/sleep/utils/jaccard.d.ts.map +1 -0
  111. package/dist/sleep/utils/jaccard.js +19 -0
  112. package/dist/sleep/utils/jaccard.js.map +1 -0
  113. package/dist/store-conversation.d.ts +29 -0
  114. package/dist/store-conversation.d.ts.map +1 -0
  115. package/dist/store-conversation.js +227 -0
  116. package/dist/store-conversation.js.map +1 -0
  117. package/dist/timeline.d.ts +50 -0
  118. package/dist/timeline.d.ts.map +1 -0
  119. package/dist/timeline.js +389 -0
  120. package/dist/timeline.js.map +1 -0
  121. package/dist/user-profile.d.ts +30 -0
  122. package/dist/user-profile.d.ts.map +1 -0
  123. package/dist/user-profile.js +147 -0
  124. package/dist/user-profile.js.map +1 -0
  125. package/dist/vectors.d.ts +56 -0
  126. package/dist/vectors.d.ts.map +1 -0
  127. package/dist/vectors.js +132 -0
  128. package/dist/vectors.js.map +1 -0
  129. package/package.json +53 -0
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Link step — port of KAD's sleep/steps/link.ts.
3
+ *
4
+ * Builds memory_edges between timeline events with shared tags via Jaccard
5
+ * similarity. Excluded tags are noise/metadata terms ("pdf", "upload", etc).
6
+ * Edge type is determined by `determineRelationType` — same_person if shared
7
+ * entities, continuation if same channel, same_topic if ≥2 shared tags,
8
+ * referenced if one title contains the other, otherwise 'related'.
9
+ *
10
+ * Phase 2 retypes existing 'related' edges to more-specific relations.
11
+ */
12
+ import { getDb } from '@kybernesis/brain-storage-sqlite';
13
+ import { jaccardSimilarity } from '../utils/jaccard.js';
14
+ import { ensureSleepSchema } from '../db.js';
15
+ function safeParseArray(json) {
16
+ if (!json)
17
+ return [];
18
+ try {
19
+ return JSON.parse(json);
20
+ }
21
+ catch {
22
+ return [];
23
+ }
24
+ }
25
+ function determineRelationType(item, other, sharedTags) {
26
+ const itemEntities = safeParseArray(item.entities_json);
27
+ const otherEntities = safeParseArray(other.entities_json);
28
+ if (itemEntities.length > 0 && otherEntities.length > 0) {
29
+ const shared = itemEntities.filter(e => otherEntities.some(o => o.toLowerCase() === e.toLowerCase()));
30
+ if (shared.length > 0)
31
+ return 'same_person';
32
+ }
33
+ const itemChannel = item.source_path.match(/^channel:\/\/(\w+)\//)?.[1];
34
+ const otherChannel = other.source_path.match(/^channel:\/\/(\w+)\//)?.[1];
35
+ if (itemChannel && itemChannel === otherChannel)
36
+ return 'continuation';
37
+ if (sharedTags.size >= 2)
38
+ return 'same_topic';
39
+ const itemTitle = item.title.replace(/^\[.*?\]\s*/, '').toLowerCase();
40
+ const otherTitle = other.title.replace(/^\[.*?\]\s*/, '').toLowerCase();
41
+ if (itemTitle.length >= 4 && otherTitle.length >= 4) {
42
+ if (itemTitle.includes(otherTitle) || otherTitle.includes(itemTitle)) {
43
+ return 'referenced';
44
+ }
45
+ }
46
+ return 'related';
47
+ }
48
+ const EXCLUDED_TAGS = new Set([
49
+ 'pdf', 'upload', 'connector', 'note', 'file', 'document', 'markdown',
50
+ 'conversation', 'transcript', 'idea', 'json', 'text', 'audio',
51
+ ]);
52
+ export async function runLinkStep(t, config) {
53
+ const timeline = getDb(t, 'timeline');
54
+ const sleep = ensureSleepSchema(t);
55
+ let created = 0;
56
+ let retyped = 0;
57
+ const errors = [];
58
+ try {
59
+ const items = timeline.prepare(`
60
+ SELECT id, source_path, title, tier, tags_json, topics_json, entities_json
61
+ FROM timeline_events
62
+ WHERE (tags_json IS NOT NULL AND tags_json != '[]')
63
+ OR (topics_json IS NOT NULL AND topics_json != '[]')
64
+ ORDER BY priority DESC
65
+ LIMIT ?
66
+ `).all(config.batchSize);
67
+ if (items.length < 2)
68
+ return { count: 0, processed: 0 };
69
+ const itemLookup = new Map();
70
+ for (const item of items) {
71
+ itemLookup.set(item.source_path, {
72
+ source_path: item.source_path,
73
+ title: item.title,
74
+ entities_json: item.entities_json,
75
+ });
76
+ }
77
+ const itemTags = new Map();
78
+ const itemTiers = new Map();
79
+ for (const item of items) {
80
+ const parsedTags = JSON.parse(item.tags_json || '[]');
81
+ const parsedTopics = JSON.parse(item.topics_json || '[]');
82
+ const tagList = Array.isArray(parsedTags) ? parsedTags :
83
+ (typeof parsedTags === 'string' ? parsedTags.split(',').map((s) => s.trim()).filter(Boolean) : []);
84
+ const topicList = Array.isArray(parsedTopics) ? parsedTopics :
85
+ (typeof parsedTopics === 'string' ? parsedTopics.split(',').map((s) => s.trim()).filter(Boolean) : []);
86
+ const tags = new Set([...tagList, ...topicList]
87
+ .map((s) => s.toLowerCase())
88
+ .filter(s => !EXCLUDED_TAGS.has(s) && s.length > 2));
89
+ if (tags.size > 0) {
90
+ itemTags.set(item.source_path, tags);
91
+ itemTiers.set(item.source_path, item.tier || 'warm');
92
+ }
93
+ }
94
+ const tagIndex = new Map();
95
+ for (const [path, tags] of itemTags) {
96
+ for (const tag of tags) {
97
+ if (!tagIndex.has(tag))
98
+ tagIndex.set(tag, []);
99
+ tagIndex.get(tag).push(path);
100
+ }
101
+ }
102
+ const seen = new Set();
103
+ for (const item of items) {
104
+ const tags = itemTags.get(item.source_path);
105
+ if (!tags || tags.size === 0)
106
+ continue;
107
+ const edgeCount = sleep.prepare(`
108
+ SELECT COUNT(*) as count FROM memory_edges
109
+ WHERE from_path = ? OR to_path = ?
110
+ `).get(item.source_path, item.source_path)?.count || 0;
111
+ if (edgeCount >= config.maxEdgesPerMemory)
112
+ continue;
113
+ const candidates = new Map();
114
+ for (const tag of tags) {
115
+ for (const otherPath of tagIndex.get(tag) || []) {
116
+ if (otherPath === item.source_path)
117
+ continue;
118
+ if (!candidates.has(otherPath))
119
+ candidates.set(otherPath, new Set());
120
+ candidates.get(otherPath).add(tag);
121
+ }
122
+ }
123
+ let itemEdgesCreated = 0;
124
+ for (const [otherPath, sharedTags] of candidates) {
125
+ if (edgeCount + itemEdgesCreated >= config.maxEdgesPerMemory)
126
+ break;
127
+ const pairKey = [item.source_path, otherPath].sort().join('|');
128
+ if (seen.has(pairKey))
129
+ continue;
130
+ seen.add(pairKey);
131
+ const otherEdgeCount = sleep.prepare(`
132
+ SELECT COUNT(*) as count FROM memory_edges
133
+ WHERE from_path = ? OR to_path = ?
134
+ `).get(otherPath, otherPath)?.count || 0;
135
+ if (otherEdgeCount >= config.maxEdgesPerMemory)
136
+ continue;
137
+ const existing = sleep.prepare(`
138
+ SELECT id FROM memory_edges
139
+ WHERE (from_path = ? AND to_path = ?) OR (from_path = ? AND to_path = ?)
140
+ `).get(item.source_path, otherPath, otherPath, item.source_path);
141
+ if (existing)
142
+ continue;
143
+ const otherTags = itemTags.get(otherPath);
144
+ if (!otherTags)
145
+ continue;
146
+ let confidence = jaccardSimilarity(tags, otherTags);
147
+ const sourceDir = item.source_path.split('/').slice(0, -1).join('/');
148
+ const otherDir = otherPath.split('/').slice(0, -1).join('/');
149
+ if (sourceDir === otherDir)
150
+ confidence += 0.15;
151
+ if (sharedTags.size >= 3)
152
+ confidence += 0.2;
153
+ else if (sharedTags.size >= 2)
154
+ confidence += 0.1;
155
+ const itemTier = itemTiers.get(item.source_path);
156
+ const otherTier = itemTiers.get(otherPath);
157
+ if (itemTier && itemTier === otherTier)
158
+ confidence += 0.05;
159
+ confidence = Math.min(1.0, confidence);
160
+ if (confidence >= config.minConfidenceForLink) {
161
+ const sharedTagsList = [...sharedTags];
162
+ const otherItem = itemLookup.get(otherPath);
163
+ const relation = otherItem
164
+ ? determineRelationType({
165
+ source_path: item.source_path,
166
+ title: item.title,
167
+ entities_json: item.entities_json,
168
+ }, otherItem, sharedTags)
169
+ : 'related';
170
+ sleep.prepare(`
171
+ INSERT INTO memory_edges
172
+ (from_path, to_path, relation, confidence, shared_tags, rationale, method, created_at, last_verified)
173
+ VALUES (?, ?, ?, ?, ?, ?, 'sleep-agent', datetime('now'), datetime('now'))
174
+ `).run(item.source_path, otherPath, relation, confidence, JSON.stringify(sharedTagsList), `Jaccard: ${(jaccardSimilarity(tags, otherTags) * 100).toFixed(1)}% + boosts on: ${sharedTagsList.slice(0, 5).join(', ')}${sharedTagsList.length > 5 ? '...' : ''}`);
175
+ created++;
176
+ itemEdgesCreated++;
177
+ if (created >= config.maxLinksPerRun)
178
+ break;
179
+ }
180
+ }
181
+ if (created >= config.maxLinksPerRun)
182
+ break;
183
+ }
184
+ // Phase 2: Retype 'related' edges to more-specific relations
185
+ try {
186
+ const untyped = sleep.prepare(`
187
+ SELECT id, from_path, to_path FROM memory_edges
188
+ WHERE relation = 'related'
189
+ LIMIT ?
190
+ `).all(config.maxLinksPerRun);
191
+ for (const edge of untyped) {
192
+ const fromItem = itemLookup.get(edge.from_path);
193
+ const toItem = itemLookup.get(edge.to_path);
194
+ if (!fromItem || !toItem)
195
+ continue;
196
+ const fromTags = itemTags.get(edge.from_path) || new Set();
197
+ const toTags = itemTags.get(edge.to_path) || new Set();
198
+ const shared = new Set([...fromTags].filter(t => toTags.has(t)));
199
+ const newRelation = determineRelationType(fromItem, toItem, shared);
200
+ if (newRelation !== 'related') {
201
+ sleep.prepare('UPDATE memory_edges SET relation = ? WHERE id = ?').run(newRelation, edge.id);
202
+ retyped++;
203
+ }
204
+ }
205
+ }
206
+ catch (err) {
207
+ errors.push(`edge retype: ${String(err)}`);
208
+ }
209
+ }
210
+ catch (err) {
211
+ console.warn('[brain-core/sleep/link] step failed', { err: String(err) });
212
+ errors.push(`link step: ${String(err)}`);
213
+ }
214
+ return { count: created + retyped, processed: created + retyped, errors: errors.length > 0 ? errors : undefined };
215
+ }
216
+ //# sourceMappingURL=link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link.js","sourceRoot":"","sources":["../../../src/sleep/steps/link.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Observe step — port of KAD's sleep/steps/observe.ts.
3
+ *
4
+ * Extracts structured facts from conversations and stores them in the facts
5
+ * table. AI-extracted facts are capped at 0.60 confidence (CANONICAL.md §2).
6
+ * Optionally runs contradiction detection: high confidence gap auto-resolves
7
+ * via markFactSuperseded; close gap records the contradiction for review.
8
+ */
9
+ import type { TenantContext } from '@kybernesis/brain-contracts';
10
+ import type { SleepConfig } from '../config.js';
11
+ export interface ObserveResult {
12
+ count: number;
13
+ processed: number;
14
+ errors?: string[];
15
+ }
16
+ export declare function runObserveStep(t: TenantContext, config: SleepConfig): Promise<ObserveResult>;
17
+ //# sourceMappingURL=observe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../../../src/sleep/steps/observe.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,6BAA6B,CAAC;AASrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAIhD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AA+DD,wBAAsB,cAAc,CAClC,CAAC,EAAE,aAAa,EAChB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAoJxB"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Observe step — port of KAD's sleep/steps/observe.ts.
3
+ *
4
+ * Extracts structured facts from conversations and stores them in the facts
5
+ * table. AI-extracted facts are capped at 0.60 confidence (CANONICAL.md §2).
6
+ * Optionally runs contradiction detection: high confidence gap auto-resolves
7
+ * via markFactSuperseded; close gap records the contradiction for review.
8
+ */
9
+ import { getDb } from '@kybernesis/brain-storage-sqlite';
10
+ import { callClaude } from '../../claude-call.js';
11
+ import { storeFact, ensureFactsTable, markFactSuperseded, getFactById, VALID_CATEGORIES, } from '../../fact-store.js';
12
+ import { detectContradictions } from '../../fact-contradiction.js';
13
+ import { detectTemporalExpiry } from '../../fact-temporal.js';
14
+ import { createContradiction } from '../../entity-graph.js';
15
+ const FACT_EXTRACTION_PROMPT = `Extract key facts from this conversation as a JSON array of objects.
16
+
17
+ Each fact object has:
18
+ - "content": The fact statement (8-25 words, specific and verifiable)
19
+ - "category": One of: biographical, preference, event, relationship, temporal, opinion, plan, general
20
+ - "confidence": 0.7-0.95 (how confident you are this is accurate)
21
+ - "entities": Array of person/entity names mentioned in this fact
22
+
23
+ Rules:
24
+ - Each fact must be SPECIFIC and verifiable — not vague
25
+ - Include the person's NAME in each fact (never use pronouns)
26
+ - Include dates, numbers, and proper nouns whenever mentioned
27
+ - Prefer: relationships, preferences, events, decisions, origins, occupations
28
+ - Skip: greetings, opinions about the conversation itself, meta-commentary
29
+ - 5-15 facts depending on conversation length
30
+
31
+ Example output:
32
+ [
33
+ {"content": "Caroline moved from Sweden 4 years ago", "category": "biographical", "confidence": 0.9, "entities": ["Caroline"]},
34
+ {"content": "Melanie's daughter's birthday is August 13", "category": "event", "confidence": 0.85, "entities": ["Melanie"]},
35
+ {"content": "Caroline wants to pursue counseling as a career", "category": "plan", "confidence": 0.8, "entities": ["Caroline"]}
36
+ ]
37
+
38
+ Conversation:
39
+ `;
40
+ function validateFacts(rawFacts) {
41
+ const out = [];
42
+ for (const raw of rawFacts) {
43
+ if (!raw || typeof raw !== 'object')
44
+ continue;
45
+ const fact = raw;
46
+ if (typeof fact.content !== 'string')
47
+ continue;
48
+ const content = fact.content.trim();
49
+ if (content.length < 10 || content.length > 200)
50
+ continue;
51
+ let category = 'general';
52
+ if (typeof fact.category === 'string' && VALID_CATEGORIES.has(fact.category)) {
53
+ category = fact.category;
54
+ }
55
+ let confidence = 0.7;
56
+ if (typeof fact.confidence === 'number' && isFinite(fact.confidence)) {
57
+ confidence = (fact.confidence < 0.5 || fact.confidence > 1.0) ? 0.7 : fact.confidence;
58
+ }
59
+ const entities = Array.isArray(fact.entities)
60
+ ? fact.entities.filter((e) => typeof e === 'string' && e.length > 0)
61
+ : [];
62
+ out.push({ content, category, confidence, entities });
63
+ }
64
+ return out;
65
+ }
66
+ export async function runObserveStep(t, config) {
67
+ if (!config.enableFactExtraction)
68
+ return { count: 0, processed: 0 };
69
+ await ensureFactsTable(t);
70
+ const timeline = getDb(t, 'timeline');
71
+ const entityDb = getDb(t, 'entityGraph');
72
+ let factsCreated = 0;
73
+ let processed = 0;
74
+ let contradictionChecks = 0;
75
+ const errors = [];
76
+ const maxPerRun = config.maxFactsPerRun || 20;
77
+ const maxContradictionChecks = config.maxContradictionChecksPerRun || 30;
78
+ try {
79
+ const unprocessed = timeline.prepare(`
80
+ SELECT te.id, te.source_path, te.title, te.summary, te.timestamp,
81
+ te.entities_json, te.topics_json
82
+ FROM timeline_events te
83
+ WHERE te.type = 'conversation'
84
+ AND te.summary IS NOT NULL
85
+ AND LENGTH(te.summary) > 50
86
+ AND NOT EXISTS (
87
+ SELECT 1 FROM timeline_events obs
88
+ WHERE obs.source_path LIKE 'observation://' || REPLACE(te.source_path, 'channel://', '') || '/%'
89
+ )
90
+ AND NOT EXISTS (
91
+ SELECT 1 FROM facts f
92
+ WHERE f.source_path LIKE 'fact://' || REPLACE(te.source_path, 'channel://', '') || '/%'
93
+ )
94
+ AND NOT EXISTS (
95
+ SELECT 1 FROM facts f
96
+ WHERE f.source_path LIKE 'realtime://' || REPLACE(te.source_path, 'channel://', '') || '/%'
97
+ )
98
+ ORDER BY te.timestamp DESC
99
+ LIMIT ?
100
+ `).all(maxPerRun);
101
+ if (unprocessed.length === 0)
102
+ return { count: 0, processed: 0 };
103
+ for (const event of unprocessed) {
104
+ processed++;
105
+ try {
106
+ const content = event.summary.slice(0, 4000);
107
+ const response = await callClaude(FACT_EXTRACTION_PROMPT + content, { model: 'haiku', maxTokens: 1024 });
108
+ const jsonMatch = (response ?? '').match(/\[[\s\S]*\]/);
109
+ if (!jsonMatch)
110
+ continue;
111
+ let rawFacts;
112
+ try {
113
+ const parsed = JSON.parse(jsonMatch[0]);
114
+ if (!Array.isArray(parsed))
115
+ continue;
116
+ rawFacts = parsed;
117
+ }
118
+ catch {
119
+ continue;
120
+ }
121
+ const parentId = event.source_path.replace('channel://', '');
122
+ const validFacts = validateFacts(rawFacts);
123
+ for (const [i, fact] of validFacts.entries()) {
124
+ const temporal = detectTemporalExpiry(fact.content, event.timestamp);
125
+ const factInput = {
126
+ content: fact.content,
127
+ sourcePath: `fact://${parentId}/${i}`,
128
+ sourceConversationId: parentId,
129
+ entities: fact.entities,
130
+ timestamp: event.timestamp,
131
+ confidence: Math.min(fact.confidence, 0.60),
132
+ category: fact.category,
133
+ sourceType: 'ai-extraction',
134
+ tags: [],
135
+ ...(temporal.expires_at ? { expiresAt: temporal.expires_at } : {}),
136
+ };
137
+ try {
138
+ const storedId = await storeFact(t, factInput);
139
+ factsCreated++;
140
+ if (config.enableContradictionDetection && contradictionChecks < maxContradictionChecks) {
141
+ try {
142
+ const contradictionResult = await detectContradictions(t, {
143
+ content: factInput.content,
144
+ entities: factInput.entities,
145
+ category: factInput.category,
146
+ });
147
+ contradictionChecks++;
148
+ for (const c of contradictionResult.contradictions) {
149
+ if (c.relationship === 'updates') {
150
+ const oldFact = await getFactById(t, c.oldFactId);
151
+ const confidenceGap = oldFact
152
+ ? Math.abs(factInput.confidence - oldFact.confidence)
153
+ : 1;
154
+ if (confidenceGap > 0.3 || !oldFact) {
155
+ await markFactSuperseded(t, c.oldFactId, storedId);
156
+ }
157
+ else {
158
+ try {
159
+ const entityName = (factInput.entities[0] || '').toLowerCase();
160
+ const entityRow = entityDb.prepare('SELECT id FROM entities WHERE LOWER(name) = ? OR LOWER(normalized_name) = ? LIMIT 1').get(entityName, entityName);
161
+ if (entityRow) {
162
+ await createContradiction(t, entityRow.id, c.oldFactId, storedId, oldFact.content, factInput.content, c.rationale);
163
+ }
164
+ }
165
+ catch (err) {
166
+ console.warn('[brain-core/sleep/observe] contradiction record failed', { err: String(err) });
167
+ }
168
+ }
169
+ }
170
+ }
171
+ }
172
+ catch (err) {
173
+ console.warn('[brain-core/sleep/observe] contradiction check failed', { err: String(err) });
174
+ }
175
+ }
176
+ }
177
+ catch (err) {
178
+ console.warn(`[brain-core/sleep/observe] storeFact failed`, { i, err: String(err) });
179
+ }
180
+ }
181
+ }
182
+ catch (err) {
183
+ errors.push(`observe ${event.source_path}: ${String(err)}`);
184
+ }
185
+ }
186
+ }
187
+ catch (err) {
188
+ errors.push(`observe step: ${String(err)}`);
189
+ }
190
+ return { count: factsCreated, processed, errors: errors.length > 0 ? errors : undefined };
191
+ }
192
+ //# sourceMappingURL=observe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe.js","sourceRoot":"","sources":["../../../src/sleep/steps/observe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Profile step — port of KAD's sleep/steps/profile.ts.
3
+ *
4
+ * Regenerates the cached user profile from the fact store when older than
5
+ * profileRefreshMinutes (default 60). Skipped entirely when cache is fresh.
6
+ */
7
+ import type { TenantContext } from '@kybernesis/brain-contracts';
8
+ import type { SleepConfig } from '../config.js';
9
+ export interface ProfileResult {
10
+ count: number;
11
+ processed: number;
12
+ errors?: string[];
13
+ }
14
+ export declare function runProfileStep(t: TenantContext, config: SleepConfig): Promise<ProfileResult>;
15
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../../src/sleep/steps/profile.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,cAAc,CAClC,CAAC,EAAE,aAAa,EAChB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,aAAa,CAAC,CAgBxB"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Profile step — port of KAD's sleep/steps/profile.ts.
3
+ *
4
+ * Regenerates the cached user profile from the fact store when older than
5
+ * profileRefreshMinutes (default 60). Skipped entirely when cache is fresh.
6
+ */
7
+ import { generateUserProfile, cacheProfile, getProfileAge } from '../../user-profile.js';
8
+ export async function runProfileStep(t, config) {
9
+ if (!config.enableUserProfile)
10
+ return { count: 0, processed: 0 };
11
+ const age = getProfileAge(t);
12
+ const refreshMinutes = config.profileRefreshMinutes || 60;
13
+ if (age < refreshMinutes)
14
+ return { count: 0, processed: 1 };
15
+ try {
16
+ const profile = await generateUserProfile(t);
17
+ cacheProfile(t, profile);
18
+ return { count: 1, processed: 1 };
19
+ }
20
+ catch (err) {
21
+ const message = `profile generation: ${err instanceof Error ? err.message : String(err)}`;
22
+ console.warn('[brain-core/sleep/profile]', { err: message });
23
+ return { count: 0, processed: 1, errors: [message] };
24
+ }
25
+ }
26
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../../src/sleep/steps/profile.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AASzF,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,CAAgB,EAChB,MAAmB;IAEnB,IAAI,CAAC,MAAM,CAAC,iBAAiB;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAEjE,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,cAAc,GAAG,MAAM,CAAC,qBAAqB,IAAI,EAAE,CAAC;IAC1D,IAAI,GAAG,GAAG,cAAc;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAE5D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC7C,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACzB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1F,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7D,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACvD,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Reasoning step — port of KAD's sleep/steps/reasoning.ts.
3
+ *
4
+ * Two LLM passes per entity (only entities with ≥3 facts):
5
+ * 1. Deduction (confidence 0.80-0.95) — logically certain conclusions
6
+ * 2. Induction (confidence 0.60-0.75) — probable patterns from ≥3 data points
7
+ *
8
+ * Marks existing insights stale before generating new ones; saves new
9
+ * insights tagged 'inference' (deduction) or 'pattern' (induction).
10
+ */
11
+ import type { TenantContext } from '@kybernesis/brain-contracts';
12
+ import type { SleepConfig } from '../config.js';
13
+ export interface ReasoningResult {
14
+ count: number;
15
+ processed: number;
16
+ errors?: string[];
17
+ }
18
+ export declare function runReasoningStep(t: TenantContext, config: SleepConfig): Promise<ReasoningResult>;
19
+ //# sourceMappingURL=reasoning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reasoning.d.ts","sourceRoot":"","sources":["../../../src/sleep/steps/reasoning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAQjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AA2DD,wBAAsB,gBAAgB,CACpC,CAAC,EAAE,aAAa,EAChB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,eAAe,CAAC,CAoH1B"}