bikky 0.3.5 → 0.3.7

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 (147) hide show
  1. package/README.md +11 -4
  2. package/dist/cli.js +26 -6
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config.d.ts +21 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +249 -2
  7. package/dist/config.js.map +1 -1
  8. package/dist/config.test.js +84 -1
  9. package/dist/config.test.js.map +1 -1
  10. package/dist/daemon/consolidation.d.ts +4 -1
  11. package/dist/daemon/consolidation.d.ts.map +1 -1
  12. package/dist/daemon/consolidation.js +18 -4
  13. package/dist/daemon/consolidation.js.map +1 -1
  14. package/dist/daemon/entity-typing.d.ts +33 -11
  15. package/dist/daemon/entity-typing.d.ts.map +1 -1
  16. package/dist/daemon/entity-typing.js +203 -74
  17. package/dist/daemon/entity-typing.js.map +1 -1
  18. package/dist/daemon/entity-typing.test.d.ts +2 -0
  19. package/dist/daemon/entity-typing.test.d.ts.map +1 -0
  20. package/dist/daemon/entity-typing.test.js +50 -0
  21. package/dist/daemon/entity-typing.test.js.map +1 -0
  22. package/dist/daemon/episode-summary.d.ts +1 -8
  23. package/dist/daemon/episode-summary.d.ts.map +1 -1
  24. package/dist/daemon/episode-summary.js +33 -16
  25. package/dist/daemon/episode-summary.js.map +1 -1
  26. package/dist/daemon/episode-summary.test.js +6 -3
  27. package/dist/daemon/episode-summary.test.js.map +1 -1
  28. package/dist/daemon/extraction.d.ts.map +1 -1
  29. package/dist/daemon/extraction.js +14 -5
  30. package/dist/daemon/extraction.js.map +1 -1
  31. package/dist/daemon/loop.d.ts.map +1 -1
  32. package/dist/daemon/loop.js +9 -1
  33. package/dist/daemon/loop.js.map +1 -1
  34. package/dist/daemon/loop.test.d.ts +2 -0
  35. package/dist/daemon/loop.test.d.ts.map +1 -0
  36. package/dist/daemon/loop.test.js +85 -0
  37. package/dist/daemon/loop.test.js.map +1 -0
  38. package/dist/daemon/maintenance-state.d.ts +36 -0
  39. package/dist/daemon/maintenance-state.d.ts.map +1 -0
  40. package/dist/daemon/maintenance-state.js +95 -0
  41. package/dist/daemon/maintenance-state.js.map +1 -0
  42. package/dist/daemon/maintenance-state.test.d.ts +2 -0
  43. package/dist/daemon/maintenance-state.test.d.ts.map +1 -0
  44. package/dist/daemon/maintenance-state.test.js +56 -0
  45. package/dist/daemon/maintenance-state.test.js.map +1 -0
  46. package/dist/daemon/qdrant.d.ts +22 -0
  47. package/dist/daemon/qdrant.d.ts.map +1 -1
  48. package/dist/daemon/qdrant.js +62 -10
  49. package/dist/daemon/qdrant.js.map +1 -1
  50. package/dist/daemon/qdrant.test.js +57 -1
  51. package/dist/daemon/qdrant.test.js.map +1 -1
  52. package/dist/daemon/relations.d.ts +47 -34
  53. package/dist/daemon/relations.d.ts.map +1 -1
  54. package/dist/daemon/relations.js +241 -155
  55. package/dist/daemon/relations.js.map +1 -1
  56. package/dist/daemon/relations.test.d.ts +2 -0
  57. package/dist/daemon/relations.test.d.ts.map +1 -0
  58. package/dist/daemon/relations.test.js +36 -0
  59. package/dist/daemon/relations.test.js.map +1 -0
  60. package/dist/daemon/session-index.d.ts +1 -8
  61. package/dist/daemon/session-index.d.ts.map +1 -1
  62. package/dist/daemon/session-index.js +8 -10
  63. package/dist/daemon/session-index.js.map +1 -1
  64. package/dist/daemon/session-index.test.js +14 -8
  65. package/dist/daemon/session-index.test.js.map +1 -1
  66. package/dist/daemon/session-summary.d.ts +1 -8
  67. package/dist/daemon/session-summary.d.ts.map +1 -1
  68. package/dist/daemon/session-summary.js +17 -12
  69. package/dist/daemon/session-summary.js.map +1 -1
  70. package/dist/daemon/session-summary.test.js +5 -3
  71. package/dist/daemon/session-summary.test.js.map +1 -1
  72. package/dist/daemon/watcher-health.d.ts +7 -0
  73. package/dist/daemon/watcher-health.d.ts.map +1 -1
  74. package/dist/daemon/watcher-health.js +24 -0
  75. package/dist/daemon/watcher-health.js.map +1 -1
  76. package/dist/daemon/watcher-health.test.js +24 -1
  77. package/dist/daemon/watcher-health.test.js.map +1 -1
  78. package/dist/daemon/workstream-summary.d.ts +1 -8
  79. package/dist/daemon/workstream-summary.d.ts.map +1 -1
  80. package/dist/daemon/workstream-summary.js +22 -14
  81. package/dist/daemon/workstream-summary.js.map +1 -1
  82. package/dist/daemon/workstream-summary.test.js +6 -3
  83. package/dist/daemon/workstream-summary.test.js.map +1 -1
  84. package/dist/lib/qdrant-client.d.ts +34 -0
  85. package/dist/lib/qdrant-client.d.ts.map +1 -1
  86. package/dist/lib/qdrant-client.js +54 -0
  87. package/dist/lib/qdrant-client.js.map +1 -1
  88. package/dist/lib/qdrant-client.test.js +49 -1
  89. package/dist/lib/qdrant-client.test.js.map +1 -1
  90. package/dist/llm/inference/index.d.ts +2 -1
  91. package/dist/llm/inference/index.d.ts.map +1 -1
  92. package/dist/llm/inference/index.js +37 -2
  93. package/dist/llm/inference/index.js.map +1 -1
  94. package/dist/llm/inference/index.test.js +44 -3
  95. package/dist/llm/inference/index.test.js.map +1 -1
  96. package/dist/llm/inference/providers/bedrock.d.ts +23 -0
  97. package/dist/llm/inference/providers/bedrock.d.ts.map +1 -1
  98. package/dist/llm/inference/providers/bedrock.js +10 -1
  99. package/dist/llm/inference/providers/bedrock.js.map +1 -1
  100. package/dist/llm/inference/providers/bedrock.test.js +49 -2
  101. package/dist/llm/inference/providers/bedrock.test.js.map +1 -1
  102. package/dist/llm/inference/providers/ollama.d.ts.map +1 -1
  103. package/dist/llm/inference/providers/ollama.js +7 -1
  104. package/dist/llm/inference/providers/ollama.js.map +1 -1
  105. package/dist/llm/inference/providers/openai.d.ts.map +1 -1
  106. package/dist/llm/inference/providers/openai.js +7 -1
  107. package/dist/llm/inference/providers/openai.js.map +1 -1
  108. package/dist/llm/inference/providers/openai.test.js +38 -2
  109. package/dist/llm/inference/providers/openai.test.js.map +1 -1
  110. package/dist/llm/inference/providers/portkey.d.ts.map +1 -1
  111. package/dist/llm/inference/providers/portkey.js +7 -1
  112. package/dist/llm/inference/providers/portkey.js.map +1 -1
  113. package/dist/llm/inference/types.d.ts +15 -0
  114. package/dist/llm/inference/types.d.ts.map +1 -1
  115. package/dist/llm/telemetry.d.ts +8 -1
  116. package/dist/llm/telemetry.d.ts.map +1 -1
  117. package/dist/llm/telemetry.js.map +1 -1
  118. package/dist/mcp/taxonomy.d.ts.map +1 -1
  119. package/dist/mcp/taxonomy.js +10 -0
  120. package/dist/mcp/taxonomy.js.map +1 -1
  121. package/dist/mcp/taxonomy.test.js +13 -2
  122. package/dist/mcp/taxonomy.test.js.map +1 -1
  123. package/dist/mcp/tools.d.ts.map +1 -1
  124. package/dist/mcp/tools.js +33 -26
  125. package/dist/mcp/tools.js.map +1 -1
  126. package/dist/mcp/tools.test.js +70 -5
  127. package/dist/mcp/tools.test.js.map +1 -1
  128. package/dist/privacy/redaction.d.ts +21 -0
  129. package/dist/privacy/redaction.d.ts.map +1 -0
  130. package/dist/privacy/redaction.js +83 -0
  131. package/dist/privacy/redaction.js.map +1 -0
  132. package/dist/privacy/redaction.test.d.ts +2 -0
  133. package/dist/privacy/redaction.test.d.ts.map +1 -0
  134. package/dist/privacy/redaction.test.js +51 -0
  135. package/dist/privacy/redaction.test.js.map +1 -0
  136. package/dist/prompts/relations.d.ts.map +1 -1
  137. package/dist/prompts/relations.js +60 -14
  138. package/dist/prompts/relations.js.map +1 -1
  139. package/dist/status.d.ts +94 -0
  140. package/dist/status.d.ts.map +1 -0
  141. package/dist/status.js +378 -0
  142. package/dist/status.js.map +1 -0
  143. package/dist/status.test.d.ts +5 -0
  144. package/dist/status.test.d.ts.map +1 -0
  145. package/dist/status.test.js +203 -0
  146. package/dist/status.test.js.map +1 -0
  147. package/package.json +1 -1
@@ -1,105 +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";
12
+ import { DEFAULT_CAPTURE_CONTEXT } from "./capture-policy.js";
18
13
  import { isGenericEntity, mapToCanonical } from "./relations-vocab.js";
19
- // ─── State ───────────────────────────────────────────────────────────────────
14
+ import { isAttemptBackedOff, pruneRecentAttempts, readMaintenanceState, recordMaintenanceRun, shouldRunMaintenance, } from "./maintenance-state.js";
20
15
  let logFn = () => { };
21
- let internalTickCount = 0;
22
16
  const setLogger = (fn) => { logFn = fn; };
23
- // Run every 300 internal ticks. consolidation.tick calls us every 5 daemon
24
- // ticks (≈25 s each), so effective period ≈ 300 × 25 s ≈ 2 hours.
25
- const TICK_INTERVAL = 300;
26
- // Max relations to infer per cycle (keeps LLM cost bounded)
27
- const MAX_INFER_PER_CYCLE = 3;
28
- // 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;
29
21
  const MIN_SHARED_FACTS = 2;
30
- // ─── Helpers ─────────────────────────────────────────────────────────────────
31
- /** 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). */
32
24
  const pairKey = (a, b) => {
33
- const sorted = [a, b].sort();
25
+ const sorted = [a, b].map((entity) => entity.toLowerCase()).sort();
34
26
  return `${sorted[0]}::${sorted[1]}`;
35
27
  };
36
- /**
37
- * Scroll ALL non-superseded facts in batches and build a co-occurrence map.
38
- * Returns pairs sorted by count descending.
39
- */
40
- 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) => {
41
39
  const pairMap = new Map();
42
- let offset = null;
43
- const BATCH = 100;
44
- let totalScrolled = 0;
45
- // Scroll through all non-superseded, non-relation facts
46
- for (;;) {
47
- const body = {
48
- filter: {
49
- must: [
50
- { is_null: { key: "superseded_by" } },
51
- ],
52
- must_not: [
53
- { key: "kind", match: { value: "relation" } },
54
- ],
55
- },
56
- limit: BATCH,
57
- with_payload: { include: ["entities"] },
58
- };
59
- if (offset)
60
- body.offset = offset;
61
- const result = await qdrant.qdrantRequest("POST", `/collections/${qdrant.collection}/points/scroll`, body);
62
- const points = result.result?.points || [];
63
- if (points.length === 0)
64
- break;
65
- for (const pt of points) {
66
- const entities = (pt.payload?.entities || []).filter((e) => !isGenericEntity(e));
67
- if (entities.length < 2)
68
- continue;
69
- // Generate all pairs from this fact's entities
70
- for (let i = 0; i < entities.length; i++) {
71
- for (let j = i + 1; j < entities.length; j++) {
72
- const eA = entities[i];
73
- const eB = entities[j];
74
- const key = pairKey(eA, eB);
75
- const existing = pairMap.get(key);
76
- if (existing) {
77
- existing.count++;
78
- if (existing.factIds.length < 10)
79
- existing.factIds.push(pt.id);
80
- }
81
- else {
82
- const sorted = [eA, eB].sort();
83
- pairMap.set(key, {
84
- entityA: sorted[0],
85
- entityB: sorted[1],
86
- count: 1,
87
- factIds: [pt.id],
88
- });
89
- }
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
+ });
90
64
  }
91
65
  }
92
66
  }
93
- totalScrolled += points.length;
94
- offset = result.result?.next_page_offset ?? null;
95
- if (!offset)
96
- break;
97
67
  }
98
- logFn("DEBUG", `Relations: scrolled ${totalScrolled} facts, found ${pairMap.size} co-occurrence pairs`);
99
- // Sort by count descending
100
- return Array.from(pairMap.values())
101
- .filter(p => p.count >= MIN_SHARED_FACTS)
102
- .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)));
103
70
  };
104
71
  /**
105
72
  * Get the set of entity pairs that already have a daemon-inferred relation.
@@ -129,9 +96,8 @@ const getExistingRelations = async () => {
129
96
  for (const pt of points) {
130
97
  const from = pt.payload?.from_entity;
131
98
  const to = pt.payload?.to_entity;
132
- if (from && to) {
99
+ if (from && to)
133
100
  existing.add(pairKey(from, to));
134
- }
135
101
  }
136
102
  offset = result.result?.next_page_offset ?? null;
137
103
  if (!offset)
@@ -140,88 +106,154 @@ const getExistingRelations = async () => {
140
106
  logFn("DEBUG", `Relations: ${existing.size} existing daemon-inferred relations`);
141
107
  return existing;
142
108
  };
143
- /**
144
- * Fetch the full content of specific fact IDs for the LLM prompt.
145
- */
146
- const fetchFactContents = async (factIds) => {
147
- const result = await qdrant.qdrantRequest("POST", `/collections/${qdrant.collection}/points`, { ids: factIds, with_payload: { include: ["content", "category"] } });
148
- return (result.result || []).map(pt => ({
149
- id: pt.id,
150
- content: pt.payload?.content ?? "",
151
- 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 ?? {},
152
134
  }));
153
135
  };
154
- /**
155
- * Use LLM to infer a relationship label from shared facts.
156
- * Returns null if the LLM can't determine a meaningful relationship.
157
- * The LLM decides directionality — `from` is the subject, `to` is the object.
158
- */
159
- const inferRelation = async (entityA, entityB, sharedFacts) => {
160
- const rendered = relationsPrompt({ entityA, entityB, sharedFacts });
161
- 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
+ });
162
166
  if (!raw)
163
167
  return null;
164
168
  const parsed = safeParseJson(raw);
165
169
  if (!parsed || !parsed.type)
166
170
  return null;
167
- // Validate that from/to are the provided entities (not hallucinated)
168
- 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()]);
169
187
  const from = parsed.from?.toLowerCase() ?? "";
170
188
  const to = parsed.to?.toLowerCase() ?? "";
171
189
  if (!entities.has(from) || !entities.has(to) || from === to) {
172
- 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}"`);
173
191
  return null;
174
192
  }
175
- // Verify evidence quote actually appears in shared facts (anti-hallucination guard).
176
193
  if (parsed.evidence) {
177
- const haystack = sharedFacts.map((f) => f.content).join(" ").toLowerCase();
194
+ const haystack = candidate.facts.map((f) => f.content).join(" ").toLowerCase();
178
195
  const needle = parsed.evidence.toLowerCase().slice(0, 30);
179
196
  if (needle.length > 0 && !haystack.includes(needle)) {
180
- 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)}"`);
181
198
  return null;
182
199
  }
183
200
  }
184
- // Use the LLM's chosen direction (normalised to original casing)
185
- const resolvedFrom = from === entityA.toLowerCase() ? entityA : entityB;
186
- const resolvedTo = to === entityA.toLowerCase() ? entityA : entityB;
187
- // Map LLM type to canonical vocabulary; out-of-vocab types pass through
188
- // (and storeRelation flags them in metadata for human review).
201
+ const resolvedFrom = from === candidate.entityA.toLowerCase() ? candidate.entityA : candidate.entityB;
202
+ const resolvedTo = to === candidate.entityA.toLowerCase() ? candidate.entityA : candidate.entityB;
189
203
  const mapped = mapToCanonical(parsed.type);
190
204
  if (mapped.changed) {
191
205
  logFn("DEBUG", `Relations: mapped type "${parsed.type}" → "${mapped.canonical}"`);
192
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
+ }
193
216
  return {
194
217
  from: resolvedFrom,
195
218
  type: mapped.canonical,
196
219
  to: resolvedTo,
197
220
  content: parsed.content || `${resolvedFrom} ${mapped.canonical} ${resolvedTo}`,
198
221
  evidence: parsed.evidence,
199
- confidence: typeof parsed.confidence === "number" ? parsed.confidence : undefined,
222
+ confidence,
200
223
  inVocabulary: mapped.inVocabulary,
224
+ judgment: parsed.judgment,
201
225
  };
202
226
  };
203
- /**
204
- * Store an inferred relation as a memory fact.
205
- */
206
- const storeRelation = async (fromEntity, toEntity, relationType, content, sharedFactIds, extras = {}) => {
227
+ const storeRelation = async (fromEntity, toEntity, relationType, content, candidate, extras = {}) => {
207
228
  const hash = createHash("sha256")
208
229
  .update(`daemon-relation:${pairKey(fromEntity, toEntity)}:${relationType}`)
209
230
  .digest("hex");
210
231
  const metadata = {
211
- inferred_from: sharedFactIds.slice(0, 5).join(","),
212
- shared_fact_count: String(sharedFactIds.length),
232
+ inferred_from: candidate.supportingFactIds.slice(0, 5).join(","),
233
+ shared_fact_count: String(candidate.supportingFactIds.length),
213
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(","),
214
237
  };
215
- if (extras.evidence) {
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)
216
243
  metadata.evidence_quote = extras.evidence.slice(0, 500);
217
- }
218
- if (extras.inVocabulary === false) {
219
- metadata.relation_type_out_of_vocab = "true";
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;
220
252
  }
221
253
  const id = await qdrant.storeFact({
222
254
  content,
223
- category: "team", // relations are about entity structure
224
- domain: "work",
255
+ category: "people",
256
+ domain: DEFAULT_CAPTURE_CONTEXT.domain,
225
257
  kind: "relation",
226
258
  entities: [fromEntity, toEntity],
227
259
  source: "daemon",
@@ -229,6 +261,8 @@ const storeRelation = async (fromEntity, toEntity, relationType, content, shared
229
261
  importance: 0.6,
230
262
  content_hash: hash,
231
263
  metadata,
264
+ source_fact_ids: candidate.supportingFactIds,
265
+ ...(candidate.workstreamKeys.length > 0 ? { workstream_key: candidate.workstreamKeys[0] } : {}),
232
266
  relation: {
233
267
  from: fromEntity,
234
268
  type: relationType,
@@ -238,41 +272,76 @@ const storeRelation = async (fromEntity, toEntity, relationType, content, shared
238
272
  logFn("INFO", `Relations: inferred ${fromEntity} —[${relationType}]→ ${toEntity} (id: ${id})`);
239
273
  return id;
240
274
  };
241
- // ─── Main Tick ───────────────────────────────────────────────────────────────
242
275
  const tick = async (config) => {
243
276
  if (!qdrant.isReady())
244
277
  return;
245
278
  if (config.daemon.relation_inference_enabled === false)
246
279
  return;
247
- internalTickCount++;
248
- 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))
249
286
  return;
250
- 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();
251
290
  try {
252
- // 1. Build co-occurrence map
253
- const pairs = await buildCoOccurrenceMap();
254
- if (pairs.length === 0) {
255
- 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);
256
306
  return;
257
307
  }
258
- // 2. Get existing relations to avoid duplicates
259
- const existing = await getExistingRelations();
260
- // 3. Find candidate pairs (not yet inferred)
261
- const candidates = pairs.filter(p => !existing.has(pairKey(p.entityA, p.entityB)));
262
- logFn("DEBUG", `Relations: ${candidates.length} candidate pairs (${pairs.length} total above threshold)`);
263
- 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);
264
319
  return;
265
- // 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
+ }
266
334
  let inferred = 0;
267
- 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);
268
339
  try {
269
- const facts = await fetchFactContents(candidate.factIds);
270
- if (facts.length < MIN_SHARED_FACTS)
271
- continue;
272
- const result = await inferRelation(candidate.entityA, candidate.entityB, facts);
340
+ llmCalls++;
341
+ attempts[key] = nowIso;
342
+ const result = await inferRelation(candidate);
273
343
  if (!result)
274
344
  continue;
275
- // Dedup check before storing
276
345
  const hash = createHash("sha256")
277
346
  .update(`daemon-relation:${pairKey(result.from, result.to)}:${result.type}`)
278
347
  .digest("hex");
@@ -281,24 +350,41 @@ const tick = async (config) => {
281
350
  logFn("DEBUG", `Relations: skipping duplicate ${candidate.entityA}↔${candidate.entityB}`);
282
351
  continue;
283
352
  }
284
- await storeRelation(result.from, result.to, result.type, result.content, candidate.factIds, { evidence: result.evidence, confidence: result.confidence, inVocabulary: result.inVocabulary });
353
+ await storeRelation(result.from, result.to, result.type, result.content, candidate, { evidence: result.evidence, confidence: result.confidence, inVocabulary: result.inVocabulary, judgment: result.judgment });
285
354
  inferred++;
286
355
  }
287
356
  catch (e) {
357
+ failures++;
288
358
  logFn("WARN", `Relations: failed to infer ${candidate.entityA}↔${candidate.entityB}: ${e.message}`);
289
359
  }
290
360
  }
291
- 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)`);
292
373
  }
293
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);
294
384
  logFn("ERROR", `Relations: inference cycle failed: ${e.message}`);
295
385
  }
296
386
  };
297
387
  /** Reset state (for testing). */
298
- const _reset = () => {
299
- internalTickCount = 0;
300
- };
301
- export { tick, setLogger, _reset,
302
- // Exported for testing
303
- buildCoOccurrenceMap, getExistingRelations, inferRelation, storeRelation, pairKey, };
388
+ const _reset = () => { };
389
+ export { tick, setLogger, _reset, buildChangedCoOccurrenceCandidates, fetchSupportingFacts, getExistingRelations, inferRelation, storeRelation, pairKey, };
304
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"}