bikky 0.3.3 → 0.3.6

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 (218) hide show
  1. package/README.md +26 -6
  2. package/dist/cli.js +26 -6
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config.d.ts +22 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +255 -3
  7. package/dist/config.js.map +1 -1
  8. package/dist/config.test.d.ts +3 -2
  9. package/dist/config.test.d.ts.map +1 -1
  10. package/dist/config.test.js +95 -6
  11. package/dist/config.test.js.map +1 -1
  12. package/dist/daemon/capture-policy.d.ts +4 -4
  13. package/dist/daemon/capture-policy.d.ts.map +1 -1
  14. package/dist/daemon/capture-policy.js +8 -17
  15. package/dist/daemon/capture-policy.js.map +1 -1
  16. package/dist/daemon/capture-policy.test.js +2 -2
  17. package/dist/daemon/capture-policy.test.js.map +1 -1
  18. package/dist/daemon/consolidation.d.ts +4 -1
  19. package/dist/daemon/consolidation.d.ts.map +1 -1
  20. package/dist/daemon/consolidation.js +18 -4
  21. package/dist/daemon/consolidation.js.map +1 -1
  22. package/dist/daemon/entity-typing.d.ts +42 -0
  23. package/dist/daemon/entity-typing.d.ts.map +1 -0
  24. package/dist/daemon/entity-typing.js +295 -0
  25. package/dist/daemon/entity-typing.js.map +1 -0
  26. package/dist/daemon/entity-typing.test.d.ts +2 -0
  27. package/dist/daemon/entity-typing.test.d.ts.map +1 -0
  28. package/dist/daemon/entity-typing.test.js +50 -0
  29. package/dist/daemon/entity-typing.test.js.map +1 -0
  30. package/dist/daemon/episode-summary.d.ts +4 -8
  31. package/dist/daemon/episode-summary.d.ts.map +1 -1
  32. package/dist/daemon/episode-summary.js +52 -18
  33. package/dist/daemon/episode-summary.js.map +1 -1
  34. package/dist/daemon/episode-summary.test.js +10 -7
  35. package/dist/daemon/episode-summary.test.js.map +1 -1
  36. package/dist/daemon/extraction-quality.test.d.ts +2 -0
  37. package/dist/daemon/extraction-quality.test.d.ts.map +1 -0
  38. package/dist/daemon/extraction-quality.test.js +283 -0
  39. package/dist/daemon/extraction-quality.test.js.map +1 -0
  40. package/dist/daemon/extraction-rules.d.ts +131 -0
  41. package/dist/daemon/extraction-rules.d.ts.map +1 -0
  42. package/dist/daemon/extraction-rules.js +321 -0
  43. package/dist/daemon/extraction-rules.js.map +1 -0
  44. package/dist/daemon/extraction-rules.test.d.ts +2 -0
  45. package/dist/daemon/extraction-rules.test.d.ts.map +1 -0
  46. package/dist/daemon/extraction-rules.test.js +183 -0
  47. package/dist/daemon/extraction-rules.test.js.map +1 -0
  48. package/dist/daemon/extraction.d.ts +19 -1
  49. package/dist/daemon/extraction.d.ts.map +1 -1
  50. package/dist/daemon/extraction.js +183 -26
  51. package/dist/daemon/extraction.js.map +1 -1
  52. package/dist/daemon/extraction.test.js +96 -2
  53. package/dist/daemon/extraction.test.js.map +1 -1
  54. package/dist/daemon/loop.d.ts.map +1 -1
  55. package/dist/daemon/loop.js +22 -0
  56. package/dist/daemon/loop.js.map +1 -1
  57. package/dist/daemon/loop.test.d.ts +2 -0
  58. package/dist/daemon/loop.test.d.ts.map +1 -0
  59. package/dist/daemon/loop.test.js +85 -0
  60. package/dist/daemon/loop.test.js.map +1 -0
  61. package/dist/daemon/maintenance-state.d.ts +36 -0
  62. package/dist/daemon/maintenance-state.d.ts.map +1 -0
  63. package/dist/daemon/maintenance-state.js +95 -0
  64. package/dist/daemon/maintenance-state.js.map +1 -0
  65. package/dist/daemon/maintenance-state.test.d.ts +2 -0
  66. package/dist/daemon/maintenance-state.test.d.ts.map +1 -0
  67. package/dist/daemon/maintenance-state.test.js +56 -0
  68. package/dist/daemon/maintenance-state.test.js.map +1 -0
  69. package/dist/daemon/qdrant.d.ts +37 -1
  70. package/dist/daemon/qdrant.d.ts.map +1 -1
  71. package/dist/daemon/qdrant.js +107 -12
  72. package/dist/daemon/qdrant.js.map +1 -1
  73. package/dist/daemon/qdrant.test.js +57 -1
  74. package/dist/daemon/qdrant.test.js.map +1 -1
  75. package/dist/daemon/relations-vocab.d.ts +44 -0
  76. package/dist/daemon/relations-vocab.d.ts.map +1 -0
  77. package/dist/daemon/relations-vocab.js +168 -0
  78. package/dist/daemon/relations-vocab.js.map +1 -0
  79. package/dist/daemon/relations-vocab.test.d.ts +2 -0
  80. package/dist/daemon/relations-vocab.test.d.ts.map +1 -0
  81. package/dist/daemon/relations-vocab.test.js +69 -0
  82. package/dist/daemon/relations-vocab.test.js.map +1 -0
  83. package/dist/daemon/relations.d.ts +49 -34
  84. package/dist/daemon/relations.d.ts.map +1 -1
  85. package/dist/daemon/relations.js +249 -153
  86. package/dist/daemon/relations.js.map +1 -1
  87. package/dist/daemon/relations.test.d.ts +2 -0
  88. package/dist/daemon/relations.test.d.ts.map +1 -0
  89. package/dist/daemon/relations.test.js +36 -0
  90. package/dist/daemon/relations.test.js.map +1 -0
  91. package/dist/daemon/session-index.d.ts +1 -8
  92. package/dist/daemon/session-index.d.ts.map +1 -1
  93. package/dist/daemon/session-index.js +8 -10
  94. package/dist/daemon/session-index.js.map +1 -1
  95. package/dist/daemon/session-index.test.js +15 -9
  96. package/dist/daemon/session-index.test.js.map +1 -1
  97. package/dist/daemon/session-summary.d.ts +1 -8
  98. package/dist/daemon/session-summary.d.ts.map +1 -1
  99. package/dist/daemon/session-summary.js +17 -12
  100. package/dist/daemon/session-summary.js.map +1 -1
  101. package/dist/daemon/session-summary.test.js +5 -3
  102. package/dist/daemon/session-summary.test.js.map +1 -1
  103. package/dist/daemon/watcher-health.d.ts +20 -0
  104. package/dist/daemon/watcher-health.d.ts.map +1 -0
  105. package/dist/daemon/watcher-health.js +78 -0
  106. package/dist/daemon/watcher-health.js.map +1 -0
  107. package/dist/daemon/watcher-health.test.d.ts +5 -0
  108. package/dist/daemon/watcher-health.test.d.ts.map +1 -0
  109. package/dist/daemon/watcher-health.test.js +96 -0
  110. package/dist/daemon/watcher-health.test.js.map +1 -0
  111. package/dist/daemon/watcher.test.d.ts +3 -2
  112. package/dist/daemon/watcher.test.d.ts.map +1 -1
  113. package/dist/daemon/watcher.test.js +9 -19
  114. package/dist/daemon/watcher.test.js.map +1 -1
  115. package/dist/daemon/workstream-resolver.d.ts +76 -0
  116. package/dist/daemon/workstream-resolver.d.ts.map +1 -0
  117. package/dist/daemon/workstream-resolver.js +180 -0
  118. package/dist/daemon/workstream-resolver.js.map +1 -0
  119. package/dist/daemon/workstream-resolver.test.d.ts +2 -0
  120. package/dist/daemon/workstream-resolver.test.d.ts.map +1 -0
  121. package/dist/daemon/workstream-resolver.test.js +128 -0
  122. package/dist/daemon/workstream-resolver.test.js.map +1 -0
  123. package/dist/daemon/workstream-summary.d.ts +1 -8
  124. package/dist/daemon/workstream-summary.d.ts.map +1 -1
  125. package/dist/daemon/workstream-summary.js +22 -14
  126. package/dist/daemon/workstream-summary.js.map +1 -1
  127. package/dist/daemon/workstream-summary.test.js +9 -6
  128. package/dist/daemon/workstream-summary.test.js.map +1 -1
  129. package/dist/lib/qdrant-client.d.ts +34 -0
  130. package/dist/lib/qdrant-client.d.ts.map +1 -1
  131. package/dist/lib/qdrant-client.js +54 -0
  132. package/dist/lib/qdrant-client.js.map +1 -1
  133. package/dist/lib/qdrant-client.test.js +49 -1
  134. package/dist/lib/qdrant-client.test.js.map +1 -1
  135. package/dist/llm/inference/index.d.ts +2 -1
  136. package/dist/llm/inference/index.d.ts.map +1 -1
  137. package/dist/llm/inference/index.js +37 -2
  138. package/dist/llm/inference/index.js.map +1 -1
  139. package/dist/llm/inference/index.test.js +44 -3
  140. package/dist/llm/inference/index.test.js.map +1 -1
  141. package/dist/llm/inference/providers/bedrock.d.ts +23 -0
  142. package/dist/llm/inference/providers/bedrock.d.ts.map +1 -1
  143. package/dist/llm/inference/providers/bedrock.js +10 -1
  144. package/dist/llm/inference/providers/bedrock.js.map +1 -1
  145. package/dist/llm/inference/providers/bedrock.test.js +49 -2
  146. package/dist/llm/inference/providers/bedrock.test.js.map +1 -1
  147. package/dist/llm/inference/providers/ollama.d.ts.map +1 -1
  148. package/dist/llm/inference/providers/ollama.js +7 -1
  149. package/dist/llm/inference/providers/ollama.js.map +1 -1
  150. package/dist/llm/inference/providers/openai.d.ts.map +1 -1
  151. package/dist/llm/inference/providers/openai.js +7 -1
  152. package/dist/llm/inference/providers/openai.js.map +1 -1
  153. package/dist/llm/inference/providers/openai.test.js +38 -2
  154. package/dist/llm/inference/providers/openai.test.js.map +1 -1
  155. package/dist/llm/inference/providers/portkey.d.ts.map +1 -1
  156. package/dist/llm/inference/providers/portkey.js +7 -1
  157. package/dist/llm/inference/providers/portkey.js.map +1 -1
  158. package/dist/llm/inference/types.d.ts +15 -0
  159. package/dist/llm/inference/types.d.ts.map +1 -1
  160. package/dist/llm/telemetry.d.ts +8 -1
  161. package/dist/llm/telemetry.d.ts.map +1 -1
  162. package/dist/llm/telemetry.js.map +1 -1
  163. package/dist/mcp/helpers.d.ts.map +1 -1
  164. package/dist/mcp/helpers.js +17 -2
  165. package/dist/mcp/helpers.js.map +1 -1
  166. package/dist/mcp/taxonomy.d.ts +6 -18
  167. package/dist/mcp/taxonomy.d.ts.map +1 -1
  168. package/dist/mcp/taxonomy.js +15 -25
  169. package/dist/mcp/taxonomy.js.map +1 -1
  170. package/dist/mcp/taxonomy.test.js +23 -7
  171. package/dist/mcp/taxonomy.test.js.map +1 -1
  172. package/dist/mcp/tools.d.ts.map +1 -1
  173. package/dist/mcp/tools.js +355 -17
  174. package/dist/mcp/tools.js.map +1 -1
  175. package/dist/mcp/tools.test.js +279 -5
  176. package/dist/mcp/tools.test.js.map +1 -1
  177. package/dist/privacy/redaction.d.ts +21 -0
  178. package/dist/privacy/redaction.d.ts.map +1 -0
  179. package/dist/privacy/redaction.js +83 -0
  180. package/dist/privacy/redaction.js.map +1 -0
  181. package/dist/privacy/redaction.test.d.ts +2 -0
  182. package/dist/privacy/redaction.test.d.ts.map +1 -0
  183. package/dist/privacy/redaction.test.js +51 -0
  184. package/dist/privacy/redaction.test.js.map +1 -0
  185. package/dist/prompts/distill.d.ts.map +1 -1
  186. package/dist/prompts/distill.js +3 -2
  187. package/dist/prompts/distill.js.map +1 -1
  188. package/dist/prompts/entity-typing.d.ts +18 -0
  189. package/dist/prompts/entity-typing.d.ts.map +1 -0
  190. package/dist/prompts/entity-typing.js +60 -0
  191. package/dist/prompts/entity-typing.js.map +1 -0
  192. package/dist/prompts/episode-summary.d.ts.map +1 -1
  193. package/dist/prompts/episode-summary.js +17 -3
  194. package/dist/prompts/episode-summary.js.map +1 -1
  195. package/dist/prompts/extraction.d.ts.map +1 -1
  196. package/dist/prompts/extraction.js +114 -5
  197. package/dist/prompts/extraction.js.map +1 -1
  198. package/dist/prompts/index.d.ts +1 -0
  199. package/dist/prompts/index.d.ts.map +1 -1
  200. package/dist/prompts/index.js +1 -0
  201. package/dist/prompts/index.js.map +1 -1
  202. package/dist/prompts/relations.d.ts.map +1 -1
  203. package/dist/prompts/relations.js +72 -4
  204. package/dist/prompts/relations.js.map +1 -1
  205. package/dist/render.d.ts.map +1 -1
  206. package/dist/render.js +7 -1
  207. package/dist/render.js.map +1 -1
  208. package/dist/render.test.js +3 -2
  209. package/dist/render.test.js.map +1 -1
  210. package/dist/status.d.ts +94 -0
  211. package/dist/status.d.ts.map +1 -0
  212. package/dist/status.js +378 -0
  213. package/dist/status.js.map +1 -0
  214. package/dist/status.test.d.ts +5 -0
  215. package/dist/status.test.d.ts.map +1 -0
  216. package/dist/status.test.js +203 -0
  217. package/dist/status.test.js.map +1 -0
  218. package/package.json +1 -1
@@ -1,104 +1,72 @@
1
1
  /**
2
- * Relationship Inference
2
+ * Relationship inference.
3
3
  *
4
- * Periodic task that infers typed relationships between entities by analysing
5
- * their shared facts. Runs inside the consolidation tick cadence.
6
- *
7
- * Flow:
8
- * 1. Scroll all non-superseded facts → build entity co-occurrence map
9
- * 2. Filter out pairs that already have a `kind: "relation"` fact
10
- * 3. For the top N pairs by shared-fact count, fetch the actual shared facts
11
- * 4. Send to a cheap LLM for a 2-4 word relationship label
12
- * 5. Store via storeFact with kind: "relation", source: "daemon"
4
+ * Infers typed relationships between entities from recently changed facts. The
5
+ * daemon keeps a persistent cursor so each cycle considers new evidence first
6
+ * instead of rebuilding a whole-collection co-occurrence map.
13
7
  */
14
8
  import { createHash } from "node:crypto";
15
9
  import * as qdrant from "./qdrant.js";
16
10
  import { chatCompletion } from "../llm/index.js";
17
11
  import { relationsPrompt, RELATIONS_PROMPT_DESCRIPTOR, safeParseJson, } from "../prompts/index.js";
18
- // ─── State ───────────────────────────────────────────────────────────────────
12
+ import { DEFAULT_CAPTURE_CONTEXT } from "./capture-policy.js";
13
+ import { isGenericEntity, mapToCanonical } from "./relations-vocab.js";
14
+ import { isAttemptBackedOff, pruneRecentAttempts, readMaintenanceState, recordMaintenanceRun, shouldRunMaintenance, } from "./maintenance-state.js";
19
15
  let logFn = () => { };
20
- let internalTickCount = 0;
21
16
  const setLogger = (fn) => { logFn = fn; };
22
- // Run every 300 internal ticks. consolidation.tick calls us every 5 daemon
23
- // ticks (≈25 s each), so effective period ≈ 300 × 25 s ≈ 2 hours.
24
- const TICK_INTERVAL = 300;
25
- // Max relations to infer per cycle (keeps LLM cost bounded)
26
- const MAX_INFER_PER_CYCLE = 3;
27
- // Minimum shared facts before we consider inferring a relation
17
+ const CHANGED_FACTS_LIMIT = 200;
18
+ const SUPPORTING_FACTS_LIMIT = 10;
19
+ const DEFAULT_LOOKBACK_MS = 7 * 24 * 60 * 60 * 1000;
20
+ const RELATION_ATTEMPT_BACKOFF_MS = 7 * 24 * 60 * 60 * 1000;
28
21
  const MIN_SHARED_FACTS = 2;
29
- // ─── Helpers ─────────────────────────────────────────────────────────────────
30
- /** Canonical pair key — alphabetical so (a,b) === (b,a) */
22
+ const MIN_CONFIDENCE = 0.6;
23
+ /** Canonical pair key — alphabetical so (a,b) === (b,a). */
31
24
  const pairKey = (a, b) => {
32
- const sorted = [a, b].sort();
25
+ const sorted = [a, b].map((entity) => entity.toLowerCase()).sort();
33
26
  return `${sorted[0]}::${sorted[1]}`;
34
27
  };
35
- /**
36
- * Scroll ALL non-superseded facts in batches and build a co-occurrence map.
37
- * Returns pairs sorted by count descending.
38
- */
39
- const buildCoOccurrenceMap = async () => {
28
+ const uniqueStrings = (values) => [...new Set(values.map((value) => value?.trim()).filter((value) => Boolean(value)))];
29
+ const sessionIdFromFact = (fact) => {
30
+ if (fact.session_id)
31
+ return fact.session_id;
32
+ const extracted = fact.metadata.extracted_from_session;
33
+ if (typeof extracted === "string" && extracted.trim())
34
+ return extracted;
35
+ const summarized = fact.metadata.summarized_from_session;
36
+ return typeof summarized === "string" && summarized.trim() ? summarized : null;
37
+ };
38
+ const buildChangedCoOccurrenceCandidates = (facts) => {
40
39
  const pairMap = new Map();
41
- let offset = null;
42
- const BATCH = 100;
43
- let totalScrolled = 0;
44
- // Scroll through all non-superseded, non-relation facts
45
- for (;;) {
46
- const body = {
47
- filter: {
48
- must: [
49
- { is_null: { key: "superseded_by" } },
50
- ],
51
- must_not: [
52
- { key: "kind", match: { value: "relation" } },
53
- ],
54
- },
55
- limit: BATCH,
56
- with_payload: { include: ["entities"] },
57
- };
58
- if (offset)
59
- body.offset = offset;
60
- const result = await qdrant.qdrantRequest("POST", `/collections/${qdrant.collection}/points/scroll`, body);
61
- const points = result.result?.points || [];
62
- if (points.length === 0)
63
- break;
64
- for (const pt of points) {
65
- const entities = pt.payload?.entities || [];
66
- if (entities.length < 2)
67
- continue;
68
- // Generate all pairs from this fact's entities
69
- for (let i = 0; i < entities.length; i++) {
70
- for (let j = i + 1; j < entities.length; j++) {
71
- const eA = entities[i];
72
- const eB = entities[j];
73
- const key = pairKey(eA, eB);
74
- const existing = pairMap.get(key);
75
- if (existing) {
76
- existing.count++;
77
- if (existing.factIds.length < 10)
78
- existing.factIds.push(pt.id);
79
- }
80
- else {
81
- const sorted = [eA, eB].sort();
82
- pairMap.set(key, {
83
- entityA: sorted[0],
84
- entityB: sorted[1],
85
- count: 1,
86
- factIds: [pt.id],
87
- });
88
- }
40
+ for (const fact of facts) {
41
+ const entities = [...new Set((fact.entities || [])
42
+ .map((entity) => entity.trim().toLowerCase())
43
+ .filter((entity) => entity.length >= 2 && !isGenericEntity(entity)))];
44
+ if (entities.length < 2)
45
+ continue;
46
+ for (let i = 0; i < entities.length; i++) {
47
+ for (let j = i + 1; j < entities.length; j++) {
48
+ const entityA = entities[i];
49
+ const entityB = entities[j];
50
+ const key = pairKey(entityA, entityB);
51
+ const sorted = [entityA, entityB].sort();
52
+ const existing = pairMap.get(key);
53
+ if (existing) {
54
+ existing.triggeringFactIds = uniqueStrings([...existing.triggeringFactIds, fact.id]);
55
+ existing.latestUpdatedAt = [existing.latestUpdatedAt, fact.updated_at || fact.created_at].filter(Boolean).sort().at(-1) ?? "";
56
+ }
57
+ else {
58
+ pairMap.set(key, {
59
+ entityA: sorted[0],
60
+ entityB: sorted[1],
61
+ triggeringFactIds: [fact.id],
62
+ latestUpdatedAt: fact.updated_at || fact.created_at,
63
+ });
89
64
  }
90
65
  }
91
66
  }
92
- totalScrolled += points.length;
93
- offset = result.result?.next_page_offset ?? null;
94
- if (!offset)
95
- break;
96
67
  }
97
- logFn("DEBUG", `Relations: scrolled ${totalScrolled} facts, found ${pairMap.size} co-occurrence pairs`);
98
- // Sort by count descending
99
- return Array.from(pairMap.values())
100
- .filter(p => p.count >= MIN_SHARED_FACTS)
101
- .sort((a, b) => b.count - a.count);
68
+ return [...pairMap.values()]
69
+ .sort((a, b) => a.latestUpdatedAt.localeCompare(b.latestUpdatedAt) || pairKey(a.entityA, a.entityB).localeCompare(pairKey(b.entityA, b.entityB)));
102
70
  };
103
71
  /**
104
72
  * Get the set of entity pairs that already have a daemon-inferred relation.
@@ -128,9 +96,8 @@ const getExistingRelations = async () => {
128
96
  for (const pt of points) {
129
97
  const from = pt.payload?.from_entity;
130
98
  const to = pt.payload?.to_entity;
131
- if (from && to) {
99
+ if (from && to)
132
100
  existing.add(pairKey(from, to));
133
- }
134
101
  }
135
102
  offset = result.result?.next_page_offset ?? null;
136
103
  if (!offset)
@@ -139,79 +106,154 @@ const getExistingRelations = async () => {
139
106
  logFn("DEBUG", `Relations: ${existing.size} existing daemon-inferred relations`);
140
107
  return existing;
141
108
  };
142
- /**
143
- * Fetch the full content of specific fact IDs for the LLM prompt.
144
- */
145
- const fetchFactContents = async (factIds) => {
146
- const result = await qdrant.qdrantRequest("POST", `/collections/${qdrant.collection}/points`, { ids: factIds, with_payload: { include: ["content", "category"] } });
147
- return (result.result || []).map(pt => ({
148
- id: pt.id,
149
- content: pt.payload?.content ?? "",
150
- category: pt.payload?.category ?? "",
109
+ const fetchSupportingFacts = async (entityA, entityB) => {
110
+ const result = await qdrant.qdrantRequest("POST", `/collections/${qdrant.collection}/points/scroll`, {
111
+ filter: {
112
+ must: [
113
+ { is_null: { key: "superseded_by" } },
114
+ { key: "entities", match: { value: entityA } },
115
+ { key: "entities", match: { value: entityB } },
116
+ ],
117
+ must_not: [
118
+ { key: "kind", match: { value: "relation" } },
119
+ { key: "kind", match: { value: "entity_type" } },
120
+ ],
121
+ },
122
+ order_by: { key: "updated_at", direction: "desc" },
123
+ limit: SUPPORTING_FACTS_LIMIT,
124
+ with_payload: true,
125
+ });
126
+ return (result.result?.points ?? []).map((point) => ({
127
+ id: point.id,
128
+ content: point.payload?.content ?? "",
129
+ category: point.payload?.category ?? "",
130
+ updated_at: point.payload?.updated_at ?? point.payload?.created_at ?? "",
131
+ session_id: point.payload?.session_id ?? null,
132
+ workstream_key: point.payload?.workstream_key ?? null,
133
+ metadata: point.payload?.metadata ?? {},
151
134
  }));
152
135
  };
153
- /**
154
- * Use LLM to infer a relationship label from shared facts.
155
- * Returns null if the LLM can't determine a meaningful relationship.
156
- * The LLM decides directionality — `from` is the subject, `to` is the object.
157
- */
158
- const inferRelation = async (entityA, entityB, sharedFacts) => {
159
- const rendered = relationsPrompt({ entityA, entityB, sharedFacts });
160
- const raw = await chatCompletion(rendered);
136
+ const buildRelationCandidate = async (changed) => {
137
+ const supportingFacts = await fetchSupportingFacts(changed.entityA, changed.entityB);
138
+ if (supportingFacts.length < MIN_SHARED_FACTS)
139
+ return null;
140
+ return {
141
+ entityA: changed.entityA,
142
+ entityB: changed.entityB,
143
+ triggeringFactIds: changed.triggeringFactIds,
144
+ supportingFactIds: supportingFacts.map((fact) => fact.id),
145
+ facts: supportingFacts.map((fact) => ({ id: fact.id, content: fact.content, category: fact.category })),
146
+ sessionIds: uniqueStrings(supportingFacts.map(sessionIdFromFact)),
147
+ workstreamKeys: uniqueStrings(supportingFacts.map((fact) => fact.workstream_key)),
148
+ latestUpdatedAt: [changed.latestUpdatedAt, ...supportingFacts.map((fact) => fact.updated_at)].filter(Boolean).sort().at(-1) ?? "",
149
+ };
150
+ };
151
+ const inferRelation = async (candidate) => {
152
+ const rendered = relationsPrompt({
153
+ entityA: candidate.entityA,
154
+ entityB: candidate.entityB,
155
+ sharedFacts: candidate.facts.map((fact) => ({ content: fact.content, category: fact.category })),
156
+ });
157
+ const raw = await chatCompletion({
158
+ ...rendered,
159
+ telemetry: {
160
+ subsystem: "relation-inference",
161
+ ...(candidate.sessionIds.length > 0 ? { session_id: candidate.sessionIds.join(",") } : {}),
162
+ ...(candidate.workstreamKeys.length > 0 ? { workstream_key: candidate.workstreamKeys.join(",") } : {}),
163
+ trigger: "infer_relation",
164
+ },
165
+ });
161
166
  if (!raw)
162
167
  return null;
163
168
  const parsed = safeParseJson(raw);
164
169
  if (!parsed || !parsed.type)
165
170
  return null;
166
- // Validate that from/to are the provided entities (not hallucinated)
167
- const entities = new Set([entityA.toLowerCase(), entityB.toLowerCase()]);
171
+ if (parsed.judgment) {
172
+ const j = parsed.judgment;
173
+ if (j.durability === "transient" || j.durability === "ephemeral") {
174
+ logFn("DEBUG", `Relations: rejected ${candidate.entityA}↔${candidate.entityB} — durability="${j.durability}"`);
175
+ return null;
176
+ }
177
+ if (j.directionality_clarity === "ambiguous") {
178
+ logFn("DEBUG", `Relations: rejected ${candidate.entityA}↔${candidate.entityB} — ambiguous directionality`);
179
+ return null;
180
+ }
181
+ if (typeof j.evidence_strength === "number" && j.evidence_strength < 0.5) {
182
+ logFn("DEBUG", `Relations: rejected ${candidate.entityA}↔${candidate.entityB} — evidence_strength=${j.evidence_strength}`);
183
+ return null;
184
+ }
185
+ }
186
+ const entities = new Set([candidate.entityA.toLowerCase(), candidate.entityB.toLowerCase()]);
168
187
  const from = parsed.from?.toLowerCase() ?? "";
169
188
  const to = parsed.to?.toLowerCase() ?? "";
170
189
  if (!entities.has(from) || !entities.has(to) || from === to) {
171
- logFn("WARN", `Relations: LLM returned invalid from/to for ${entityA}↔${entityB}: from="${parsed.from}", to="${parsed.to}"`);
190
+ logFn("WARN", `Relations: LLM returned invalid from/to for ${candidate.entityA}↔${candidate.entityB}: from="${parsed.from}", to="${parsed.to}"`);
172
191
  return null;
173
192
  }
174
- // Verify evidence quote actually appears in shared facts (anti-hallucination guard).
175
193
  if (parsed.evidence) {
176
- const haystack = sharedFacts.map((f) => f.content).join(" ").toLowerCase();
194
+ const haystack = candidate.facts.map((f) => f.content).join(" ").toLowerCase();
177
195
  const needle = parsed.evidence.toLowerCase().slice(0, 30);
178
196
  if (needle.length > 0 && !haystack.includes(needle)) {
179
- logFn("WARN", `Relations: evidence quote not found in source facts for ${entityA}↔${entityB}: "${parsed.evidence.slice(0, 80)}"`);
197
+ logFn("WARN", `Relations: evidence quote not found in source facts for ${candidate.entityA}↔${candidate.entityB}: "${parsed.evidence.slice(0, 80)}"`);
180
198
  return null;
181
199
  }
182
200
  }
183
- // Use the LLM's chosen direction (normalised to original casing)
184
- const resolvedFrom = from === entityA.toLowerCase() ? entityA : entityB;
185
- const resolvedTo = to === entityA.toLowerCase() ? entityA : entityB;
201
+ const resolvedFrom = from === candidate.entityA.toLowerCase() ? candidate.entityA : candidate.entityB;
202
+ const resolvedTo = to === candidate.entityA.toLowerCase() ? candidate.entityA : candidate.entityB;
203
+ const mapped = mapToCanonical(parsed.type);
204
+ if (mapped.changed) {
205
+ logFn("DEBUG", `Relations: mapped type "${parsed.type}" → "${mapped.canonical}"`);
206
+ }
207
+ if (!mapped.inVocabulary) {
208
+ logFn("DEBUG", `Relations: rejected ${candidate.entityA}↔${candidate.entityB} — out-of-vocab type "${parsed.type}"`);
209
+ return null;
210
+ }
211
+ const confidence = typeof parsed.confidence === "number" ? parsed.confidence : 0.5;
212
+ if (confidence < MIN_CONFIDENCE) {
213
+ logFn("DEBUG", `Relations: rejected ${candidate.entityA}↔${candidate.entityB} — confidence ${confidence} < ${MIN_CONFIDENCE}`);
214
+ return null;
215
+ }
186
216
  return {
187
217
  from: resolvedFrom,
188
- type: parsed.type,
218
+ type: mapped.canonical,
189
219
  to: resolvedTo,
190
- content: parsed.content || `${resolvedFrom} ${parsed.type} ${resolvedTo}`,
220
+ content: parsed.content || `${resolvedFrom} ${mapped.canonical} ${resolvedTo}`,
191
221
  evidence: parsed.evidence,
192
- confidence: typeof parsed.confidence === "number" ? parsed.confidence : undefined,
222
+ confidence,
223
+ inVocabulary: mapped.inVocabulary,
224
+ judgment: parsed.judgment,
193
225
  };
194
226
  };
195
- /**
196
- * Store an inferred relation as a memory fact.
197
- */
198
- const storeRelation = async (fromEntity, toEntity, relationType, content, sharedFactIds, extras = {}) => {
227
+ const storeRelation = async (fromEntity, toEntity, relationType, content, candidate, extras = {}) => {
199
228
  const hash = createHash("sha256")
200
229
  .update(`daemon-relation:${pairKey(fromEntity, toEntity)}:${relationType}`)
201
230
  .digest("hex");
202
231
  const metadata = {
203
- inferred_from: sharedFactIds.slice(0, 5).join(","),
204
- shared_fact_count: String(sharedFactIds.length),
232
+ inferred_from: candidate.supportingFactIds.slice(0, 5).join(","),
233
+ shared_fact_count: String(candidate.supportingFactIds.length),
205
234
  inferred_by_prompt: `${RELATIONS_PROMPT_DESCRIPTOR.id}@${RELATIONS_PROMPT_DESCRIPTOR.version}`,
235
+ triggering_fact_ids: candidate.triggeringFactIds.join(","),
236
+ supporting_fact_ids: candidate.supportingFactIds.join(","),
206
237
  };
207
- if (extras.evidence) {
208
- // Truncate to 500 chars to keep metadata payload bounded.
238
+ if (candidate.sessionIds.length > 0)
239
+ metadata.triggering_sessions = candidate.sessionIds.join(",");
240
+ if (candidate.workstreamKeys.length > 0)
241
+ metadata.triggering_workstreams = candidate.workstreamKeys.join(",");
242
+ if (extras.evidence)
209
243
  metadata.evidence_quote = extras.evidence.slice(0, 500);
244
+ if (extras.judgment) {
245
+ const j = extras.judgment;
246
+ if (j.evidence_strength != null)
247
+ metadata.evidence_strength = String(j.evidence_strength);
248
+ if (j.durability)
249
+ metadata.durability = j.durability;
250
+ if (j.directionality_clarity)
251
+ metadata.directionality_clarity = j.directionality_clarity;
210
252
  }
211
253
  const id = await qdrant.storeFact({
212
254
  content,
213
- category: "team", // relations are about entity structure
214
- domain: "work",
255
+ category: "people",
256
+ domain: DEFAULT_CAPTURE_CONTEXT.domain,
215
257
  kind: "relation",
216
258
  entities: [fromEntity, toEntity],
217
259
  source: "daemon",
@@ -219,6 +261,8 @@ const storeRelation = async (fromEntity, toEntity, relationType, content, shared
219
261
  importance: 0.6,
220
262
  content_hash: hash,
221
263
  metadata,
264
+ source_fact_ids: candidate.supportingFactIds,
265
+ ...(candidate.workstreamKeys.length > 0 ? { workstream_key: candidate.workstreamKeys[0] } : {}),
222
266
  relation: {
223
267
  from: fromEntity,
224
268
  type: relationType,
@@ -228,41 +272,76 @@ const storeRelation = async (fromEntity, toEntity, relationType, content, shared
228
272
  logFn("INFO", `Relations: inferred ${fromEntity} —[${relationType}]→ ${toEntity} (id: ${id})`);
229
273
  return id;
230
274
  };
231
- // ─── Main Tick ───────────────────────────────────────────────────────────────
232
275
  const tick = async (config) => {
233
276
  if (!qdrant.isReady())
234
277
  return;
235
278
  if (config.daemon.relation_inference_enabled === false)
236
279
  return;
237
- internalTickCount++;
238
- if (internalTickCount % TICK_INTERVAL !== 0)
280
+ const now = new Date();
281
+ const nowIso = now.toISOString();
282
+ const state = readMaintenanceState(logFn);
283
+ const job = state.jobs.relation_inference;
284
+ const intervalSec = config.daemon.relation_inference_interval_sec ?? 7200;
285
+ if (!shouldRunMaintenance(now, job.last_run_at, intervalSec))
239
286
  return;
240
- logFn("DEBUG", "Relations: starting inference cycle");
287
+ const attempts = pruneRecentAttempts(job.recent_attempts, now, RELATION_ATTEMPT_BACKOFF_MS);
288
+ const maxPairs = config.daemon.relation_inference_max_pairs_per_run ?? 3;
289
+ const since = job.cursor_updated_at ?? new Date(now.getTime() - DEFAULT_LOOKBACK_MS).toISOString();
241
290
  try {
242
- // 1. Build co-occurrence map
243
- const pairs = await buildCoOccurrenceMap();
244
- if (pairs.length === 0) {
245
- logFn("DEBUG", "Relations: no co-occurrence pairs above threshold");
291
+ const changedFacts = await qdrant.scrollFacts({
292
+ sinceUpdated: since,
293
+ excludeKinds: ["relation"],
294
+ orderBy: { key: "updated_at", direction: "asc" },
295
+ }, CHANGED_FACTS_LIMIT);
296
+ if (changedFacts.length === 0) {
297
+ recordMaintenanceRun("relation_inference", {
298
+ job: "relation_inference",
299
+ ran_at: nowIso,
300
+ status: "skipped",
301
+ candidates_seen: 0,
302
+ llm_calls: 0,
303
+ accepted: 0,
304
+ skipped_reason: "no_changed_facts",
305
+ }, { cursorUpdatedAt: nowIso, recentAttempts: attempts }, logFn);
246
306
  return;
247
307
  }
248
- // 2. Get existing relations to avoid duplicates
249
- const existing = await getExistingRelations();
250
- // 3. Find candidate pairs (not yet inferred)
251
- const candidates = pairs.filter(p => !existing.has(pairKey(p.entityA, p.entityB)));
252
- logFn("DEBUG", `Relations: ${candidates.length} candidate pairs (${pairs.length} total above threshold)`);
253
- if (candidates.length === 0)
308
+ const changedPairs = buildChangedCoOccurrenceCandidates(changedFacts);
309
+ if (changedPairs.length === 0) {
310
+ recordMaintenanceRun("relation_inference", {
311
+ job: "relation_inference",
312
+ ran_at: nowIso,
313
+ status: "skipped",
314
+ candidates_seen: 0,
315
+ llm_calls: 0,
316
+ accepted: 0,
317
+ skipped_reason: "no_entity_pairs",
318
+ }, { cursorUpdatedAt: changedFacts.map((fact) => fact.updated_at || fact.created_at).filter(Boolean).sort().at(-1) ?? nowIso, recentAttempts: attempts }, logFn);
254
319
  return;
255
- // 4. Infer relations for top N candidates
320
+ }
321
+ const existing = await getExistingRelations();
322
+ const touchedPairs = changedPairs
323
+ .filter((pair) => !existing.has(pairKey(pair.entityA, pair.entityB)))
324
+ .filter((pair) => !isAttemptBackedOff(attempts, pairKey(pair.entityA, pair.entityB), now, RELATION_ATTEMPT_BACKOFF_MS));
325
+ const supportLookupLimit = Math.max(maxPairs * 5, maxPairs);
326
+ const relationCandidates = [];
327
+ for (const changed of touchedPairs.slice(0, supportLookupLimit)) {
328
+ const candidate = await buildRelationCandidate(changed);
329
+ if (candidate)
330
+ relationCandidates.push(candidate);
331
+ if (relationCandidates.length >= maxPairs)
332
+ break;
333
+ }
256
334
  let inferred = 0;
257
- for (const candidate of candidates.slice(0, MAX_INFER_PER_CYCLE)) {
335
+ let llmCalls = 0;
336
+ let failures = 0;
337
+ for (const candidate of relationCandidates.slice(0, maxPairs)) {
338
+ const key = pairKey(candidate.entityA, candidate.entityB);
258
339
  try {
259
- const facts = await fetchFactContents(candidate.factIds);
260
- if (facts.length < MIN_SHARED_FACTS)
261
- continue;
262
- const result = await inferRelation(candidate.entityA, candidate.entityB, facts);
340
+ llmCalls++;
341
+ attempts[key] = nowIso;
342
+ const result = await inferRelation(candidate);
263
343
  if (!result)
264
344
  continue;
265
- // Dedup check before storing
266
345
  const hash = createHash("sha256")
267
346
  .update(`daemon-relation:${pairKey(result.from, result.to)}:${result.type}`)
268
347
  .digest("hex");
@@ -271,24 +350,41 @@ const tick = async (config) => {
271
350
  logFn("DEBUG", `Relations: skipping duplicate ${candidate.entityA}↔${candidate.entityB}`);
272
351
  continue;
273
352
  }
274
- await storeRelation(result.from, result.to, result.type, result.content, candidate.factIds, { evidence: result.evidence, confidence: result.confidence });
353
+ await storeRelation(result.from, result.to, result.type, result.content, candidate, { evidence: result.evidence, confidence: result.confidence, inVocabulary: result.inVocabulary, judgment: result.judgment });
275
354
  inferred++;
276
355
  }
277
356
  catch (e) {
357
+ failures++;
278
358
  logFn("WARN", `Relations: failed to infer ${candidate.entityA}↔${candidate.entityB}: ${e.message}`);
279
359
  }
280
360
  }
281
- logFn("INFO", `Relations: inference cycle complete ${inferred} new relations from ${candidates.length} candidates`);
361
+ const deferred = failures > 0 || touchedPairs.length > supportLookupLimit || relationCandidates.length > maxPairs;
362
+ const cursorUpdatedAt = deferred ? job.cursor_updated_at : changedFacts.map((fact) => fact.updated_at || fact.created_at).filter(Boolean).sort().at(-1) ?? nowIso;
363
+ recordMaintenanceRun("relation_inference", {
364
+ job: "relation_inference",
365
+ ran_at: nowIso,
366
+ status: "success",
367
+ candidates_seen: touchedPairs.length,
368
+ llm_calls: llmCalls,
369
+ accepted: inferred,
370
+ skipped_reason: deferred ? "work_deferred" : undefined,
371
+ }, { cursorUpdatedAt, recentAttempts: attempts }, logFn);
372
+ logFn("INFO", `Relations: inference cycle complete — ${inferred} new relations from ${touchedPairs.length} changed pair(s)`);
282
373
  }
283
374
  catch (e) {
375
+ recordMaintenanceRun("relation_inference", {
376
+ job: "relation_inference",
377
+ ran_at: nowIso,
378
+ status: "error",
379
+ candidates_seen: 0,
380
+ llm_calls: 0,
381
+ accepted: 0,
382
+ error: e.message,
383
+ }, { cursorUpdatedAt: job.cursor_updated_at, recentAttempts: attempts }, logFn);
284
384
  logFn("ERROR", `Relations: inference cycle failed: ${e.message}`);
285
385
  }
286
386
  };
287
387
  /** Reset state (for testing). */
288
- const _reset = () => {
289
- internalTickCount = 0;
290
- };
291
- export { tick, setLogger, _reset,
292
- // Exported for testing
293
- buildCoOccurrenceMap, getExistingRelations, inferRelation, storeRelation, pairKey, };
388
+ const _reset = () => { };
389
+ export { tick, setLogger, _reset, buildChangedCoOccurrenceCandidates, fetchSupportingFacts, getExistingRelations, inferRelation, storeRelation, pairKey, };
294
390
  //# sourceMappingURL=relations.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"relations.js","sourceRoot":"","sources":["../../src/daemon/relations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relations.js","sourceRoot":"","sources":["../../src/daemon/relations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=relations.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.test.d.ts","sourceRoot":"","sources":["../../src/daemon/relations.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { buildChangedCoOccurrenceCandidates, pairKey } from "./relations.js";
4
+ const fact = (overrides) => ({
5
+ id: "fact-1",
6
+ content: "Bikky uses Qdrant for memory storage.",
7
+ category: "codebase",
8
+ entities: [],
9
+ confidence: 0.9,
10
+ last_reinforced_at: "2026-04-27T09:00:00.000Z",
11
+ created_at: "2026-04-27T09:00:00.000Z",
12
+ updated_at: "2026-04-27T09:00:00.000Z",
13
+ metadata: {},
14
+ ...overrides,
15
+ });
16
+ describe("daemon/relations helpers", () => {
17
+ it("uses stable unordered pair keys", () => {
18
+ assert.equal(pairKey("Bikky", "Qdrant"), pairKey("qdrant", "bikky"));
19
+ });
20
+ it("builds changed-fact relation candidates instead of global co-occurrences", () => {
21
+ const candidates = buildChangedCoOccurrenceCandidates([
22
+ fact({ id: "fact-1", entities: ["bikky", "qdrant", "system"] }),
23
+ fact({
24
+ id: "fact-2",
25
+ entities: ["qdrant", "bikky"],
26
+ updated_at: "2026-04-27T09:10:00.000Z",
27
+ }),
28
+ ]);
29
+ assert.equal(candidates.length, 1);
30
+ assert.equal(candidates[0]?.entityA, "bikky");
31
+ assert.equal(candidates[0]?.entityB, "qdrant");
32
+ assert.deepEqual(candidates[0]?.triggeringFactIds, ["fact-1", "fact-2"]);
33
+ assert.equal(candidates[0]?.latestUpdatedAt, "2026-04-27T09:10:00.000Z");
34
+ });
35
+ });
36
+ //# sourceMappingURL=relations.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.test.js","sourceRoot":"","sources":["../../src/daemon/relations.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,kCAAkC,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG7E,MAAM,IAAI,GAAG,CAAC,SAAsC,EAAsB,EAAE,CAAC,CAAC;IAC5E,EAAE,EAAE,QAAQ;IACZ,OAAO,EAAE,uCAAuC;IAChD,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,GAAG;IACf,kBAAkB,EAAE,0BAA0B;IAC9C,UAAU,EAAE,0BAA0B;IACtC,UAAU,EAAE,0BAA0B;IACtC,QAAQ,EAAE,EAAE;IACZ,GAAG,SAAS;CACb,CAAC,CAAC;AAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,MAAM,UAAU,GAAG,kCAAkC,CAAC;YACpD,IAAI,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC;gBACH,EAAE,EAAE,QAAQ;gBACZ,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;gBAC7B,UAAU,EAAE,0BAA0B;aACvC,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/C,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QACzE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,0BAA0B,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}