@pellux/goodvibes-sdk 1.1.0 → 1.3.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 (139) hide show
  1. package/dist/contracts/artifacts/operator-contract.json +1416 -88
  2. package/dist/platform/companion/companion-chat-manager.d.ts +6 -12
  3. package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
  4. package/dist/platform/companion/companion-chat-manager.js +8 -2
  5. package/dist/platform/config/index.d.ts +2 -1
  6. package/dist/platform/config/index.d.ts.map +1 -1
  7. package/dist/platform/config/index.js +1 -0
  8. package/dist/platform/config/manager.d.ts +35 -0
  9. package/dist/platform/config/manager.d.ts.map +1 -1
  10. package/dist/platform/config/manager.js +98 -2
  11. package/dist/platform/config/shared-config-tier.d.ts +51 -0
  12. package/dist/platform/config/shared-config-tier.d.ts.map +1 -0
  13. package/dist/platform/config/shared-config-tier.js +127 -0
  14. package/dist/platform/control-plane/method-catalog-runtime.d.ts.map +1 -1
  15. package/dist/platform/control-plane/method-catalog-runtime.js +95 -1
  16. package/dist/platform/control-plane/operator-contract-schemas-knowledge.d.ts.map +1 -1
  17. package/dist/platform/control-plane/operator-contract-schemas-knowledge.js +6 -1
  18. package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +7 -0
  19. package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
  20. package/dist/platform/control-plane/operator-contract-schemas-runtime.js +40 -1
  21. package/dist/platform/daemon/facade-composition.d.ts.map +1 -1
  22. package/dist/platform/daemon/facade-composition.js +1 -0
  23. package/dist/platform/daemon/homeassistant-chat.d.ts +4 -1
  24. package/dist/platform/daemon/homeassistant-chat.d.ts.map +1 -1
  25. package/dist/platform/daemon/homeassistant-chat.js +1 -1
  26. package/dist/platform/daemon/http/homeassistant-routes.d.ts.map +1 -1
  27. package/dist/platform/daemon/http/homeassistant-routes.js +28 -2
  28. package/dist/platform/integrations/webhooks.d.ts +15 -0
  29. package/dist/platform/integrations/webhooks.d.ts.map +1 -1
  30. package/dist/platform/integrations/webhooks.js +18 -0
  31. package/dist/platform/knowledge/extraction-policy.d.ts +12 -1
  32. package/dist/platform/knowledge/extraction-policy.d.ts.map +1 -1
  33. package/dist/platform/knowledge/extraction-policy.js +19 -1
  34. package/dist/platform/knowledge/graphql-schema.d.ts +1 -1
  35. package/dist/platform/knowledge/graphql-schema.d.ts.map +1 -1
  36. package/dist/platform/knowledge/graphql-schema.js +5 -0
  37. package/dist/platform/knowledge/home-graph/index.d.ts.map +1 -1
  38. package/dist/platform/knowledge/home-graph/index.js +4 -0
  39. package/dist/platform/knowledge/home-graph/link.d.ts +2 -2
  40. package/dist/platform/knowledge/home-graph/link.d.ts.map +1 -1
  41. package/dist/platform/knowledge/home-graph/link.js +60 -9
  42. package/dist/platform/knowledge/home-graph/refinement.d.ts +14 -9
  43. package/dist/platform/knowledge/home-graph/refinement.d.ts.map +1 -1
  44. package/dist/platform/knowledge/home-graph/refinement.js +18 -3
  45. package/dist/platform/knowledge/home-graph/reset.js +21 -4
  46. package/dist/platform/knowledge/home-graph/service.d.ts +10 -11
  47. package/dist/platform/knowledge/home-graph/service.d.ts.map +1 -1
  48. package/dist/platform/knowledge/home-graph/triage.d.ts +103 -0
  49. package/dist/platform/knowledge/home-graph/triage.d.ts.map +1 -0
  50. package/dist/platform/knowledge/home-graph/triage.js +362 -0
  51. package/dist/platform/knowledge/home-graph/types.d.ts +15 -0
  52. package/dist/platform/knowledge/home-graph/types.d.ts.map +1 -1
  53. package/dist/platform/knowledge/knowledge-api.d.ts +6 -0
  54. package/dist/platform/knowledge/knowledge-api.d.ts.map +1 -1
  55. package/dist/platform/knowledge/knowledge-api.js +5 -0
  56. package/dist/platform/knowledge/knowledge-history-types.d.ts +56 -0
  57. package/dist/platform/knowledge/knowledge-history-types.d.ts.map +1 -0
  58. package/dist/platform/knowledge/knowledge-history-types.js +1 -0
  59. package/dist/platform/knowledge/packet.d.ts.map +1 -1
  60. package/dist/platform/knowledge/packet.js +27 -3
  61. package/dist/platform/knowledge/scope-records.js +4 -2
  62. package/dist/platform/knowledge/semantic/answer-gaps.d.ts +8 -0
  63. package/dist/platform/knowledge/semantic/answer-gaps.d.ts.map +1 -1
  64. package/dist/platform/knowledge/semantic/answer-gaps.js +26 -6
  65. package/dist/platform/knowledge/semantic/enrichment.d.ts.map +1 -1
  66. package/dist/platform/knowledge/semantic/enrichment.js +15 -13
  67. package/dist/platform/knowledge/semantic/graph-index.d.ts.map +1 -1
  68. package/dist/platform/knowledge/semantic/graph-index.js +3 -1
  69. package/dist/platform/knowledge/semantic/service.d.ts +7 -0
  70. package/dist/platform/knowledge/semantic/service.d.ts.map +1 -1
  71. package/dist/platform/knowledge/semantic/service.js +10 -1
  72. package/dist/platform/knowledge/service-node-admin.d.ts +46 -0
  73. package/dist/platform/knowledge/service-node-admin.d.ts.map +1 -0
  74. package/dist/platform/knowledge/service-node-admin.js +72 -0
  75. package/dist/platform/knowledge/service.d.ts +24 -20
  76. package/dist/platform/knowledge/service.d.ts.map +1 -1
  77. package/dist/platform/knowledge/service.js +23 -47
  78. package/dist/platform/knowledge/store-config.d.ts +34 -0
  79. package/dist/platform/knowledge/store-config.d.ts.map +1 -1
  80. package/dist/platform/knowledge/store-config.js +23 -0
  81. package/dist/platform/knowledge/store-load.d.ts +3 -1
  82. package/dist/platform/knowledge/store-load.d.ts.map +1 -1
  83. package/dist/platform/knowledge/store-load.js +3 -1
  84. package/dist/platform/knowledge/store-node-history.d.ts +49 -0
  85. package/dist/platform/knowledge/store-node-history.d.ts.map +1 -0
  86. package/dist/platform/knowledge/store-node-history.js +331 -0
  87. package/dist/platform/knowledge/store-record-delete.d.ts +25 -0
  88. package/dist/platform/knowledge/store-record-delete.d.ts.map +1 -0
  89. package/dist/platform/knowledge/store-record-delete.js +84 -0
  90. package/dist/platform/knowledge/store-schema.d.ts +3 -1
  91. package/dist/platform/knowledge/store-schema.d.ts.map +1 -1
  92. package/dist/platform/knowledge/store-schema.js +66 -0
  93. package/dist/platform/knowledge/store.d.ts +19 -1
  94. package/dist/platform/knowledge/store.d.ts.map +1 -1
  95. package/dist/platform/knowledge/store.js +69 -108
  96. package/dist/platform/knowledge/types.d.ts +18 -0
  97. package/dist/platform/knowledge/types.d.ts.map +1 -1
  98. package/dist/platform/providers/registry.d.ts +18 -0
  99. package/dist/platform/providers/registry.d.ts.map +1 -1
  100. package/dist/platform/providers/registry.js +49 -3
  101. package/dist/platform/providers/runtime-snapshot.d.ts.map +1 -1
  102. package/dist/platform/providers/runtime-snapshot.js +14 -2
  103. package/dist/platform/runtime/memory-spine/client.d.ts +137 -12
  104. package/dist/platform/runtime/memory-spine/client.d.ts.map +1 -1
  105. package/dist/platform/runtime/memory-spine/client.js +119 -1
  106. package/dist/platform/runtime/memory-spine/index.d.ts +8 -1
  107. package/dist/platform/runtime/memory-spine/index.d.ts.map +1 -1
  108. package/dist/platform/runtime/memory-spine/index.js +7 -0
  109. package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts +74 -0
  110. package/dist/platform/runtime/memory-spine/recall-snapshot.d.ts.map +1 -0
  111. package/dist/platform/runtime/memory-spine/recall-snapshot.js +87 -0
  112. package/dist/platform/runtime/memory-spine/wire-verb-availability.d.ts +59 -0
  113. package/dist/platform/runtime/memory-spine/wire-verb-availability.d.ts.map +1 -0
  114. package/dist/platform/runtime/memory-spine/wire-verb-availability.js +114 -0
  115. package/dist/platform/runtime/services.d.ts.map +1 -1
  116. package/dist/platform/runtime/services.js +3 -12
  117. package/dist/platform/state/memory-recall-contract.d.ts +7 -0
  118. package/dist/platform/state/memory-recall-contract.d.ts.map +1 -1
  119. package/dist/platform/state/memory-recall-contract.js +2 -0
  120. package/dist/platform/utils/notify.d.ts +25 -1
  121. package/dist/platform/utils/notify.d.ts.map +1 -1
  122. package/dist/platform/utils/notify.js +29 -1
  123. package/dist/platform/version.js +1 -1
  124. package/dist/platform/voice/index.d.ts +2 -0
  125. package/dist/platform/voice/index.d.ts.map +1 -1
  126. package/dist/platform/voice/index.js +3 -0
  127. package/dist/platform/voice/spoken-turn/audio-sink.d.ts +111 -0
  128. package/dist/platform/voice/spoken-turn/audio-sink.d.ts.map +1 -0
  129. package/dist/platform/voice/spoken-turn/audio-sink.js +1 -0
  130. package/dist/platform/voice/spoken-turn/controller.d.ts +117 -0
  131. package/dist/platform/voice/spoken-turn/controller.d.ts.map +1 -0
  132. package/dist/platform/voice/spoken-turn/controller.js +448 -0
  133. package/dist/platform/voice/spoken-turn/index.d.ts +16 -0
  134. package/dist/platform/voice/spoken-turn/index.d.ts.map +1 -0
  135. package/dist/platform/voice/spoken-turn/index.js +12 -0
  136. package/dist/platform/voice/spoken-turn/text-chunker.d.ts +33 -0
  137. package/dist/platform/voice/spoken-turn/text-chunker.d.ts.map +1 -0
  138. package/dist/platform/voice/spoken-turn/text-chunker.js +97 -0
  139. package/package.json +9 -9
@@ -0,0 +1,84 @@
1
+ export function deleteKnowledgeNodeRecord(view, id) {
2
+ if (!view.nodes.has(id))
3
+ return false;
4
+ for (const [edgeId, edge] of [...view.edges.entries()]) {
5
+ if ((edge.fromKind === 'node' && edge.fromId === id) || (edge.toKind === 'node' && edge.toId === id)) {
6
+ view.sqlite.run('DELETE FROM knowledge_edges WHERE id = ?', [edgeId]);
7
+ view.edges.delete(edgeId);
8
+ }
9
+ }
10
+ for (const [issueId, issue] of [...view.issues.entries()]) {
11
+ if (issue.nodeId === id) {
12
+ view.sqlite.run('DELETE FROM knowledge_issues WHERE id = ?', [issueId]);
13
+ view.issues.delete(issueId);
14
+ }
15
+ }
16
+ for (const [usageId, usage] of [...view.usageRecords.entries()]) {
17
+ if (usage.targetKind === 'node' && usage.targetId === id) {
18
+ view.sqlite.run('DELETE FROM knowledge_usage_records WHERE id = ?', [usageId]);
19
+ view.usageRecords.delete(usageId);
20
+ }
21
+ }
22
+ for (const [candidateId, candidate] of [...view.consolidationCandidates.entries()]) {
23
+ if (candidate.subjectKind === 'node' && candidate.subjectId === id) {
24
+ view.sqlite.run('DELETE FROM knowledge_consolidation_candidates WHERE id = ?', [candidateId]);
25
+ view.consolidationCandidates.delete(candidateId);
26
+ }
27
+ }
28
+ for (const [taskId, task] of [...view.refinementTasks.entries()]) {
29
+ if ((task.subjectKind === 'node' && task.subjectId === id) || task.gapId === id) {
30
+ view.sqlite.run('DELETE FROM knowledge_refinement_tasks WHERE id = ?', [taskId]);
31
+ view.refinementTasks.delete(taskId);
32
+ }
33
+ }
34
+ view.sqlite.run('DELETE FROM knowledge_node_revisions WHERE node_id = ?', [id]);
35
+ view.nodeRevisions.delete(id);
36
+ view.sqlite.run('DELETE FROM knowledge_nodes WHERE id = ?', [id]);
37
+ view.nodes.delete(id);
38
+ return true;
39
+ }
40
+ export function deleteKnowledgeSourceRecord(view, id) {
41
+ if (!view.sources.has(id))
42
+ return false;
43
+ for (const [edgeId, edge] of [...view.edges.entries()]) {
44
+ if ((edge.fromKind === 'source' && edge.fromId === id) || (edge.toKind === 'source' && edge.toId === id)) {
45
+ view.sqlite.run('DELETE FROM knowledge_edges WHERE id = ?', [edgeId]);
46
+ view.edges.delete(edgeId);
47
+ }
48
+ }
49
+ for (const [extractionId, extraction] of [...view.extractions.entries()]) {
50
+ if (extraction.sourceId === id) {
51
+ view.sqlite.run('DELETE FROM knowledge_extractions WHERE id = ?', [extractionId]);
52
+ view.extractions.delete(extractionId);
53
+ }
54
+ }
55
+ for (const [issueId, issue] of [...view.issues.entries()]) {
56
+ if (issue.sourceId === id) {
57
+ view.sqlite.run('DELETE FROM knowledge_issues WHERE id = ?', [issueId]);
58
+ view.issues.delete(issueId);
59
+ }
60
+ }
61
+ for (const [usageId, usage] of [...view.usageRecords.entries()]) {
62
+ if (usage.targetKind === 'source' && usage.targetId === id) {
63
+ view.sqlite.run('DELETE FROM knowledge_usage_records WHERE id = ?', [usageId]);
64
+ view.usageRecords.delete(usageId);
65
+ }
66
+ }
67
+ for (const [candidateId, candidate] of [...view.consolidationCandidates.entries()]) {
68
+ if (candidate.subjectKind === 'source' && candidate.subjectId === id) {
69
+ view.sqlite.run('DELETE FROM knowledge_consolidation_candidates WHERE id = ?', [candidateId]);
70
+ view.consolidationCandidates.delete(candidateId);
71
+ }
72
+ }
73
+ for (const [taskId, task] of [...view.refinementTasks.entries()]) {
74
+ if (task.subjectKind === 'source' && task.subjectId === id) {
75
+ view.sqlite.run('DELETE FROM knowledge_refinement_tasks WHERE id = ?', [taskId]);
76
+ view.refinementTasks.delete(taskId);
77
+ }
78
+ }
79
+ view.sqlite.run('DELETE FROM knowledge_semantic_enrichment_state WHERE source_id = ?', [id]);
80
+ view.semanticEnrichmentStates.delete(id);
81
+ view.sqlite.run('DELETE FROM knowledge_sources WHERE id = ?', [id]);
82
+ view.sources.delete(id);
83
+ return true;
84
+ }
@@ -1,4 +1,4 @@
1
- import type { KnowledgeConsolidationCandidateRecord, KnowledgeConsolidationReportRecord, KnowledgeEdgeRecord, KnowledgeExtractionRecord, KnowledgeIssueRecord, KnowledgeIssueUpsertInput, KnowledgeJobRunRecord, KnowledgeNodeRecord, KnowledgeScheduleRecord, KnowledgeSourceRecord, KnowledgeRefinementTaskRecord, KnowledgeUsageRecord } from './types.js';
1
+ import type { KnowledgeConsolidationCandidateRecord, KnowledgeConsolidationReportRecord, KnowledgeEdgeRecord, KnowledgeExtractionRecord, KnowledgeIssueRecord, KnowledgeIssueUpsertInput, KnowledgeJobRunRecord, KnowledgeNodeRecord, KnowledgeScheduleRecord, KnowledgeSourceRecord, KnowledgeNodeRevisionRecord, KnowledgeSemanticEnrichmentStateRecord, KnowledgeRefinementTaskRecord, KnowledgeUsageRecord } from './types.js';
2
2
  export declare const DEFAULT_KNOWLEDGE_DB_FILE = "knowledge-wiki.sqlite";
3
3
  export declare function resolveKnowledgeDbPathFromControlPlaneDir(controlPlaneDir: string, dbFileName?: string): string;
4
4
  export declare function nowMs(): number;
@@ -21,5 +21,7 @@ export declare function mapRefinementTaskRow(columns: string[], values: unknown[
21
21
  export declare function mapUsageRow(columns: string[], values: unknown[]): KnowledgeUsageRecord;
22
22
  export declare function mapCandidateRow(columns: string[], values: unknown[]): KnowledgeConsolidationCandidateRecord;
23
23
  export declare function mapReportRow(columns: string[], values: unknown[]): KnowledgeConsolidationReportRecord;
24
+ export declare function mapNodeRevisionRow(columns: string[], values: unknown[]): KnowledgeNodeRevisionRecord;
25
+ export declare function mapSemanticEnrichmentStateRow(columns: string[], values: unknown[]): KnowledgeSemanticEnrichmentStateRecord;
24
26
  export declare function mapScheduleRow(columns: string[], values: unknown[]): KnowledgeScheduleRecord;
25
27
  //# sourceMappingURL=store-schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"store-schema.d.ts","sourceRoot":"","sources":["../../../src/platform/knowledge/store-schema.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,qCAAqC,EACrC,kCAAkC,EAClC,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EAOrB,6BAA6B,EAQ7B,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,wBAAgB,yCAAyC,CACvD,eAAe,EAAE,MAAM,EACvB,UAAU,SAA4B,GACrC,MAAM,CAER;AAED,wBAAgB,KAAK,IAAI,MAAM,CAE9B;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAInE;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,GAAG,SAAS,EACjD,KAAK,EAAE,yBAAyB,GAC/B,oBAAoB,CAAC,QAAQ,CAAC,CAOhC;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,EAAE,CAWpE;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAOhE;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE;IAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CA4MjE;AAED,wBAAgB,4BAA4B,IAAI,SAAS,MAAM,EAAE,CAShE;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CAIjD;AAMD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,qBAAqB,CAuBxF;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,mBAAmB,CAgBpF;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,mBAAmB,CAcpF;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,oBAAoB,CActF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,yBAAyB,CAmBhG;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,qBAAqB,CAgBxF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,6BAA6B,CAqCxG;AAuBD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,oBAAoB,CAatF;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,qCAAqC,CAoB3G;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,kCAAkC,CAarG;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,uBAAuB,CAc5F"}
1
+ {"version":3,"file":"store-schema.d.ts","sourceRoot":"","sources":["../../../src/platform/knowledge/store-schema.ts"],"names":[],"mappings":"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"}
@@ -249,6 +249,39 @@ export function createSchema(db) {
249
249
  )
250
250
  `);
251
251
  db.run(`CREATE INDEX IF NOT EXISTS idx_knowledge_schedules_job_id ON knowledge_schedules(job_id)`);
252
+ db.run(`
253
+ CREATE TABLE IF NOT EXISTS knowledge_node_revisions (
254
+ id TEXT PRIMARY KEY,
255
+ node_id TEXT NOT NULL,
256
+ revision INTEGER NOT NULL,
257
+ change_kind TEXT NOT NULL,
258
+ changed_fields TEXT NOT NULL DEFAULT '[]',
259
+ kind TEXT NOT NULL,
260
+ slug TEXT NOT NULL,
261
+ title TEXT NOT NULL,
262
+ summary TEXT,
263
+ aliases TEXT NOT NULL DEFAULT '[]',
264
+ status TEXT NOT NULL,
265
+ confidence INTEGER NOT NULL,
266
+ source_id TEXT,
267
+ metadata TEXT NOT NULL DEFAULT '{}',
268
+ node_created_at INTEGER NOT NULL,
269
+ node_updated_at INTEGER NOT NULL,
270
+ recorded_at INTEGER NOT NULL
271
+ )
272
+ `);
273
+ db.run(`CREATE UNIQUE INDEX IF NOT EXISTS idx_knowledge_node_revisions_unique ON knowledge_node_revisions(node_id, revision)`);
274
+ db.run(`CREATE INDEX IF NOT EXISTS idx_knowledge_node_revisions_node ON knowledge_node_revisions(node_id)`);
275
+ db.run(`
276
+ CREATE TABLE IF NOT EXISTS knowledge_semantic_enrichment_state (
277
+ source_id TEXT PRIMARY KEY,
278
+ text_hash TEXT,
279
+ enriched_at INTEGER,
280
+ metadata TEXT NOT NULL DEFAULT '{}',
281
+ created_at INTEGER NOT NULL,
282
+ updated_at INTEGER NOT NULL
283
+ )
284
+ `);
252
285
  }
253
286
  export function getKnowledgeSchemaStatements() {
254
287
  const statements = [];
@@ -485,6 +518,39 @@ export function mapReportRow(columns, values) {
485
518
  updatedAt: Number(row.updated_at),
486
519
  };
487
520
  }
521
+ export function mapNodeRevisionRow(columns, values) {
522
+ const row = rowObject(columns, values);
523
+ return {
524
+ id: String(row.id),
525
+ nodeId: String(row.node_id),
526
+ revision: Number(row.revision),
527
+ changeKind: String(row.change_kind),
528
+ changedFields: parseJsonValue(row.changed_fields, []),
529
+ kind: String(row.kind),
530
+ slug: String(row.slug),
531
+ title: String(row.title),
532
+ ...(stableText(row.summary) ? { summary: String(row.summary) } : {}),
533
+ aliases: parseJsonValue(row.aliases, []),
534
+ status: String(row.status),
535
+ confidence: Number(row.confidence),
536
+ ...(stableText(row.source_id) ? { sourceId: String(row.source_id) } : {}),
537
+ metadata: parseJsonValue(row.metadata, {}),
538
+ nodeCreatedAt: Number(row.node_created_at),
539
+ nodeUpdatedAt: Number(row.node_updated_at),
540
+ recordedAt: Number(row.recorded_at),
541
+ };
542
+ }
543
+ export function mapSemanticEnrichmentStateRow(columns, values) {
544
+ const row = rowObject(columns, values);
545
+ return {
546
+ sourceId: String(row.source_id),
547
+ ...(stableText(row.text_hash) ? { textHash: String(row.text_hash) } : {}),
548
+ ...(typeof row.enriched_at === 'number' ? { enrichedAt: Number(row.enriched_at) } : {}),
549
+ metadata: parseJsonValue(row.metadata, {}),
550
+ createdAt: Number(row.created_at),
551
+ updatedAt: Number(row.updated_at),
552
+ };
553
+ }
488
554
  export function mapScheduleRow(columns, values) {
489
555
  const row = rowObject(columns, values);
490
556
  return {
@@ -1,4 +1,4 @@
1
- import type { KnowledgeConsolidationCandidateRecord, KnowledgeConsolidationCandidateUpsertInput, KnowledgeConsolidationReportRecord, KnowledgeConsolidationReportUpsertInput, KnowledgeEdgeRecord, KnowledgeEdgeUpsertInput, KnowledgeExtractionRecord, KnowledgeExtractionUpsertInput, KnowledgeIssueRecord, KnowledgeIssueUpsertInput, KnowledgeItemView, KnowledgeJobRunRecord, KnowledgeJobRunUpsertInput, KnowledgeRefinementTaskFilter, KnowledgeRefinementTaskRecord, KnowledgeRefinementTaskUpsertInput, KnowledgeNodeRecord, KnowledgeNodeUpsertInput, KnowledgeScheduleRecord, KnowledgeScheduleUpsertInput, KnowledgeSourceRecord, KnowledgeSourceUpsertInput, KnowledgeStatus, KnowledgeUsageRecord, KnowledgeUsageUpsertInput } from './types.js';
1
+ import type { KnowledgeConsolidationCandidateRecord, KnowledgeConsolidationCandidateUpsertInput, KnowledgeConsolidationReportRecord, KnowledgeConsolidationReportUpsertInput, KnowledgeEdgeRecord, KnowledgeEdgeUpsertInput, KnowledgeExtractionRecord, KnowledgeExtractionUpsertInput, KnowledgeIssueRecord, KnowledgeIssueUpsertInput, KnowledgeItemView, KnowledgeJobRunRecord, KnowledgeJobRunUpsertInput, KnowledgeRefinementTaskFilter, KnowledgeRefinementTaskRecord, KnowledgeRefinementTaskUpsertInput, KnowledgeNodeRecord, KnowledgeNodeRevisionRecord, KnowledgeNodeUpsertInput, KnowledgeScheduleRecord, KnowledgeScheduleUpsertInput, KnowledgeSemanticEnrichmentStateRecord, KnowledgeSourceRecord, KnowledgeSourceUpsertInput, KnowledgeStatus, KnowledgeUsageRecord, KnowledgeUsageUpsertInput } from './types.js';
2
2
  import { type KnowledgeStoreConfig } from './store-config.js';
3
3
  import { type KnowledgeSpaceDeleteResult } from './store-space-delete.js';
4
4
  export declare class KnowledgeStore {
@@ -17,6 +17,9 @@ export declare class KnowledgeStore {
17
17
  private readonly consolidationCandidates;
18
18
  private readonly consolidationReports;
19
19
  private readonly schedules;
20
+ private readonly nodeRevisions;
21
+ private readonly semanticEnrichmentStates;
22
+ private readonly nodeAutoAcceptConfidence;
20
23
  constructor(config: KnowledgeStoreConfig);
21
24
  get isReady(): boolean;
22
25
  get storagePath(): string;
@@ -66,10 +69,25 @@ export declare class KnowledgeStore {
66
69
  getItem(id: string): KnowledgeItemView | null;
67
70
  upsertSource(input: KnowledgeSourceUpsertInput): Promise<KnowledgeSourceRecord>;
68
71
  deleteSource(id: string): Promise<boolean>;
72
+ private asRecordDeleteView;
69
73
  replaceSourceRecord(record: KnowledgeSourceRecord): Promise<void>;
70
74
  upsertNode(input: KnowledgeNodeUpsertInput): Promise<KnowledgeNodeRecord>;
75
+ /** Read a node's append-only revision history, oldest first. (Invariant 8.) */
76
+ listNodeRevisions(nodeId: string): KnowledgeNodeRevisionRecord[];
71
77
  deleteNode(id: string): Promise<boolean>;
72
78
  replaceNodeRecord(record: KnowledgeNodeRecord): Promise<void>;
79
+ /** Merge one node into another, re-pointing cross-reference edges. (Invariant 7.) */
80
+ mergeNodes(loserId: string, winnerId: string): Promise<{
81
+ merged: boolean;
82
+ repointedEdges: number;
83
+ }>;
84
+ getSemanticEnrichmentState(sourceId: string): KnowledgeSemanticEnrichmentStateRecord | null;
85
+ upsertSemanticEnrichmentState(input: {
86
+ readonly sourceId: string;
87
+ readonly textHash?: string | undefined;
88
+ readonly enrichedAt?: number | undefined;
89
+ readonly metadata?: Record<string, unknown> | undefined;
90
+ }): Promise<KnowledgeSemanticEnrichmentStateRecord>;
73
91
  upsertEdge(input: KnowledgeEdgeUpsertInput): Promise<KnowledgeEdgeRecord>;
74
92
  deleteEdge(id: string): Promise<boolean>;
75
93
  replaceEdgeRecord(record: KnowledgeEdgeRecord): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/platform/knowledge/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/platform/knowledge/store.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,10 @@ import { SQLiteStore } from '../state/sqlite-store.js';
3
3
  import { summarizeError } from '../utils/error-display.js';
4
4
  import { logger } from '../utils/logger.js';
5
5
  import { createSchema, issueStatusForUpsert, nowMs, stableText, uniq, } from './store-schema.js';
6
- import { resolveKnowledgeDbPath } from './store-config.js';
6
+ import { DEFAULT_NODE_AUTO_ACCEPT_CONFIDENCE, resolveKnowledgeDbPath, } from './store-config.js';
7
+ import { KNOWLEDGE_EXTRACTOR_VERSION } from './extraction-policy.js';
8
+ import { clampConfidence, listKnowledgeNodeRevisions, mergeKnowledgeNodes, recordKnowledgeNodeRevisions, resolveNodeActivation, upsertKnowledgeSemanticEnrichmentState, writeKnowledgeNodeRow, } from './store-node-history.js';
9
+ import { deleteKnowledgeNodeRecord, deleteKnowledgeSourceRecord, } from './store-record-delete.js';
7
10
  import { upsertKnowledgeRefinementTask } from './store-refinement.js';
8
11
  import { deleteKnowledgeSpaceRows, planKnowledgeSpaceDeleteRows, } from './store-space-delete.js';
9
12
  import { deleteKnowledgeSchedule, upsertKnowledgeSchedule, } from './store-schedules.js';
@@ -26,8 +29,12 @@ export class KnowledgeStore {
26
29
  consolidationCandidates = new Map();
27
30
  consolidationReports = new Map();
28
31
  schedules = new Map();
32
+ nodeRevisions = new Map();
33
+ semanticEnrichmentStates = new Map();
34
+ nodeAutoAcceptConfidence;
29
35
  constructor(config) {
30
36
  this.dbPath = resolveKnowledgeDbPath(config);
37
+ this.nodeAutoAcceptConfidence = clampConfidence(config.nodeAutoAcceptConfidence ?? DEFAULT_NODE_AUTO_ACCEPT_CONFIDENCE);
31
38
  this.sqlite = new SQLiteStore(this.dbPath);
32
39
  void this.init().catch((error) => {
33
40
  logger.error('[knowledge-store] initialization failed', {
@@ -245,42 +252,13 @@ export class KnowledgeStore {
245
252
  }
246
253
  async deleteSource(id) {
247
254
  await this.init();
248
- if (!this.sources.has(id))
249
- return false;
250
- for (const [edgeId, edge] of [...this.edges.entries()]) {
251
- if ((edge.fromKind === 'source' && edge.fromId === id) || (edge.toKind === 'source' && edge.toId === id)) {
252
- this.sqlite.run('DELETE FROM knowledge_edges WHERE id = ?', [edgeId]);
253
- this.edges.delete(edgeId);
254
- }
255
- }
256
- for (const [extractionId, extraction] of [...this.extractions.entries()]) {
257
- if (extraction.sourceId === id) {
258
- this.sqlite.run('DELETE FROM knowledge_extractions WHERE id = ?', [extractionId]);
259
- this.extractions.delete(extractionId);
260
- }
261
- }
262
- for (const [issueId, issue] of [...this.issues.entries()]) {
263
- if (issue.sourceId === id) {
264
- this.sqlite.run('DELETE FROM knowledge_issues WHERE id = ?', [issueId]);
265
- this.issues.delete(issueId);
266
- }
267
- }
268
- for (const [usageId, usage] of [...this.usageRecords.entries()]) {
269
- if (usage.targetKind === 'source' && usage.targetId === id) {
270
- this.sqlite.run('DELETE FROM knowledge_usage_records WHERE id = ?', [usageId]);
271
- this.usageRecords.delete(usageId);
272
- }
273
- }
274
- for (const [candidateId, candidate] of [...this.consolidationCandidates.entries()]) {
275
- if (candidate.subjectKind === 'source' && candidate.subjectId === id) {
276
- this.sqlite.run('DELETE FROM knowledge_consolidation_candidates WHERE id = ?', [candidateId]);
277
- this.consolidationCandidates.delete(candidateId);
278
- }
279
- }
280
- this.sqlite.run('DELETE FROM knowledge_sources WHERE id = ?', [id]);
281
- this.sources.delete(id);
282
- await this.sqlite.save();
283
- return true;
255
+ const deleted = deleteKnowledgeSourceRecord(this.asRecordDeleteView(), id);
256
+ if (deleted)
257
+ await this.sqlite.save();
258
+ return deleted;
259
+ }
260
+ asRecordDeleteView() {
261
+ return this;
284
262
  }
285
263
  async replaceSourceRecord(record) {
286
264
  await this.init();
@@ -316,9 +294,9 @@ export class KnowledgeStore {
316
294
  }
317
295
  async upsertNode(input) {
318
296
  await this.init();
319
- const existing = input.id
297
+ const existing = (input.id
320
298
  ? this.nodes.get(input.id)
321
- : this.getNodeByKindAndSlug(input.kind, input.slug);
299
+ : this.getNodeByKindAndSlug(input.kind, input.slug)) ?? undefined;
322
300
  const now = nowMs();
323
301
  const _summary = stableText(input.summary);
324
302
  const _sourceId = stableText(input.sourceId);
@@ -337,6 +315,13 @@ export class KnowledgeStore {
337
315
  const nodeMetadata = nodeSpaceId
338
316
  ? ensureKnowledgeSpaceMetadata(mergedNodeMetadata, nodeSpaceId)
339
317
  : mergedNodeMetadata;
318
+ // clampConfidence (not an inline min/max) so a non-finite confidence — NaN or
319
+ // Infinity slips past `??`, which only catches null/undefined — resolves to the
320
+ // auto-accept default instead of `NaN >= autoAcceptConfidence === false`
321
+ // silently holding a node as a draft forever.
322
+ const confidence = clampConfidence(input.confidence ?? existing?.confidence ?? 70);
323
+ // Review gate: never silently active — stamp honest activation provenance. (Invariants 2 & 4.)
324
+ const gated = resolveNodeActivation({ input, existing, confidence, metadata: nodeMetadata, now, autoAcceptConfidence: this.nodeAutoAcceptConfidence });
340
325
  const record = {
341
326
  id: existing?.id ?? input.id ?? `node-${randomUUID().slice(0, 8)}`,
342
327
  kind: input.kind,
@@ -344,91 +329,50 @@ export class KnowledgeStore {
344
329
  title: input.title.trim(),
345
330
  ...(_summary !== null ? { summary: _summary } : existing?.summary ? { summary: existing.summary } : {}),
346
331
  aliases: uniq(input.aliases ?? existing?.aliases),
347
- status: input.status ?? existing?.status ?? 'active',
348
- confidence: Math.max(0, Math.min(100, input.confidence ?? existing?.confidence ?? 70)),
332
+ status: gated.status,
333
+ confidence,
349
334
  ...(_sourceId !== null ? { sourceId: _sourceId } : existing?.sourceId ? { sourceId: existing.sourceId } : {}),
350
- metadata: nodeMetadata,
335
+ metadata: gated.metadata,
351
336
  createdAt: existing?.createdAt ?? now,
352
337
  updatedAt: now,
353
338
  };
354
- this.sqlite.run(`
355
- INSERT OR REPLACE INTO knowledge_nodes (
356
- id, kind, slug, title, summary, aliases, status, confidence, source_id, metadata, created_at, updated_at
357
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
358
- `, [
359
- record.id,
360
- record.kind,
361
- record.slug,
362
- record.title,
363
- record.summary ?? null,
364
- JSON.stringify([...record.aliases]),
365
- record.status,
366
- record.confidence,
367
- record.sourceId ?? null,
368
- JSON.stringify(record.metadata),
369
- record.createdAt,
370
- record.updatedAt,
371
- ]);
339
+ writeKnowledgeNodeRow(this.sqlite, record);
340
+ recordKnowledgeNodeRevisions(this.sqlite, this.nodeRevisions, record, existing, now); // preserve prior content (Invariant 8)
372
341
  this.nodes.set(record.id, record);
373
342
  await this.sqlite.save();
374
343
  return record;
375
344
  }
345
+ /** Read a node's append-only revision history, oldest first. (Invariant 8.) */
346
+ listNodeRevisions(nodeId) {
347
+ return listKnowledgeNodeRevisions(this.nodeRevisions, nodeId);
348
+ }
376
349
  async deleteNode(id) {
377
350
  await this.init();
378
- if (!this.nodes.has(id))
379
- return false;
380
- for (const [edgeId, edge] of [...this.edges.entries()]) {
381
- if ((edge.fromKind === 'node' && edge.fromId === id) || (edge.toKind === 'node' && edge.toId === id)) {
382
- this.sqlite.run('DELETE FROM knowledge_edges WHERE id = ?', [edgeId]);
383
- this.edges.delete(edgeId);
384
- }
385
- }
386
- for (const [issueId, issue] of [...this.issues.entries()]) {
387
- if (issue.nodeId === id) {
388
- this.sqlite.run('DELETE FROM knowledge_issues WHERE id = ?', [issueId]);
389
- this.issues.delete(issueId);
390
- }
391
- }
392
- for (const [usageId, usage] of [...this.usageRecords.entries()]) {
393
- if (usage.targetKind === 'node' && usage.targetId === id) {
394
- this.sqlite.run('DELETE FROM knowledge_usage_records WHERE id = ?', [usageId]);
395
- this.usageRecords.delete(usageId);
396
- }
397
- }
398
- for (const [candidateId, candidate] of [...this.consolidationCandidates.entries()]) {
399
- if (candidate.subjectKind === 'node' && candidate.subjectId === id) {
400
- this.sqlite.run('DELETE FROM knowledge_consolidation_candidates WHERE id = ?', [candidateId]);
401
- this.consolidationCandidates.delete(candidateId);
402
- }
403
- }
404
- this.sqlite.run('DELETE FROM knowledge_nodes WHERE id = ?', [id]);
405
- this.nodes.delete(id);
406
- await this.sqlite.save();
407
- return true;
351
+ const deleted = deleteKnowledgeNodeRecord(this.asRecordDeleteView(), id);
352
+ if (deleted)
353
+ await this.sqlite.save();
354
+ return deleted;
408
355
  }
409
356
  async replaceNodeRecord(record) {
410
357
  await this.init();
411
- this.sqlite.run(`
412
- INSERT OR REPLACE INTO knowledge_nodes (
413
- id, kind, slug, title, summary, aliases, status, confidence, source_id, metadata, created_at, updated_at
414
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
415
- `, [
416
- record.id,
417
- record.kind,
418
- record.slug,
419
- record.title,
420
- record.summary ?? null,
421
- JSON.stringify([...record.aliases]),
422
- record.status,
423
- record.confidence,
424
- record.sourceId ?? null,
425
- JSON.stringify(record.metadata),
426
- record.createdAt,
427
- record.updatedAt,
428
- ]);
358
+ writeKnowledgeNodeRow(this.sqlite, record);
429
359
  this.nodes.set(record.id, record);
430
360
  await this.sqlite.save();
431
361
  }
362
+ /** Merge one node into another, re-pointing cross-reference edges. (Invariant 7.) */
363
+ async mergeNodes(loserId, winnerId) {
364
+ await this.init();
365
+ return mergeKnowledgeNodes(this, loserId, winnerId);
366
+ }
367
+ getSemanticEnrichmentState(sourceId) {
368
+ return this.semanticEnrichmentStates.get(sourceId) ?? null;
369
+ }
370
+ async upsertSemanticEnrichmentState(input) {
371
+ await this.init();
372
+ const record = upsertKnowledgeSemanticEnrichmentState(this.sqlite, this.semanticEnrichmentStates, input);
373
+ await this.sqlite.save();
374
+ return record;
375
+ }
432
376
  async upsertEdge(input) {
433
377
  await this.init();
434
378
  const existing = [...this.edges.values()].find((edge) => (edge.fromKind === input.fromKind
@@ -620,6 +564,14 @@ export class KnowledgeStore {
620
564
  const mergedExtractionMetadata = {
621
565
  ...(existing?.metadata ?? {}),
622
566
  ...(input.metadata ?? {}),
567
+ // A freshly written extraction is produced by the current extractor
568
+ // generation, so it carries the current version (an explicit input version
569
+ // wins, e.g. import re-materialization). An advancing version then
570
+ // re-extracts only genuinely older stored captures (Defect 8) without
571
+ // looping on the extractions it just rewrote.
572
+ extractorVersion: typeof input.metadata?.extractorVersion === 'number'
573
+ ? input.metadata.extractorVersion
574
+ : KNOWLEDGE_EXTRACTOR_VERSION,
623
575
  };
624
576
  const extractionSource = this.sources.get(input.sourceId);
625
577
  const extractionMetadata = getExplicitKnowledgeSpaceId({ metadata: mergedExtractionMetadata }) || !extractionSource
@@ -925,6 +877,15 @@ export class KnowledgeStore {
925
877
  this.schedules.clear();
926
878
  for (const record of snapshot.schedules)
927
879
  this.schedules.set(record.id, record);
880
+ this.nodeRevisions.clear();
881
+ for (const record of snapshot.nodeRevisions) {
882
+ const list = this.nodeRevisions.get(record.nodeId) ?? [];
883
+ list.push(record);
884
+ this.nodeRevisions.set(record.nodeId, list.sort((a, b) => a.revision - b.revision));
885
+ }
886
+ this.semanticEnrichmentStates.clear();
887
+ for (const record of snapshot.semanticEnrichmentStates)
888
+ this.semanticEnrichmentStates.set(record.sourceId, record);
928
889
  this.ready = true;
929
890
  }
930
891
  }
@@ -58,6 +58,7 @@ export interface KnowledgeNodeRecord {
58
58
  readonly createdAt: number;
59
59
  readonly updatedAt: number;
60
60
  }
61
+ export type { KnowledgeNodeRevisionChangeKind, KnowledgeNodeRevisionRecord, KnowledgeNodeReviewState, KnowledgeNodeReviewProvenance, KnowledgeSemanticEnrichmentStateRecord, } from './knowledge-history-types.js';
61
62
  export interface KnowledgeEdgeRecord {
62
63
  readonly id: string;
63
64
  readonly fromKind: KnowledgeReferenceKind;
@@ -416,6 +417,23 @@ export interface KnowledgePacket {
416
417
  readonly budgetLimit: number;
417
418
  readonly estimatedTokens: number;
418
419
  readonly items: readonly KnowledgePacketItem[];
420
+ /**
421
+ * Honest truncation disclosure — mirrors the home-graph packet's `truncated`
422
+ * flag. `true` when candidates were dropped by the item limit or token budget,
423
+ * so a partial packet is never indistinguishable from a complete one.
424
+ */
425
+ readonly truncated: boolean;
426
+ readonly totalCandidates: number;
427
+ /** Total candidates dropped (rank/item cap AND token budget combined). */
428
+ readonly droppedCount: number;
429
+ /**
430
+ * The subset of `droppedCount` the token budget specifically forced out (as
431
+ * opposed to the rank/item cap). Lets a surface say "N omitted to fit the
432
+ * budget" truthfully instead of conflating cap-drops with budget-drops.
433
+ */
434
+ readonly droppedForBudget: number;
435
+ /** True when the token budget was a binding constraint (droppedForBudget > 0). */
436
+ readonly budgetExhausted: boolean;
419
437
  }
420
438
  export interface KnowledgeItemView {
421
439
  readonly source?: KnowledgeSourceRecord | undefined;