@jungjaehoon/mama-core 1.4.2 → 1.6.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 (181) hide show
  1. package/README.md +48 -10
  2. package/db/migrations/026-create-canonical-entity-tables.sql +99 -0
  3. package/db/migrations/027-create-entity-review-support.sql +44 -0
  4. package/db/migrations/028-create-entity-audit-tables.sql +45 -0
  5. package/db/migrations/029-extend-entity-observations-observation-type.sql +60 -0
  6. package/db/migrations/030-case-first-memory-substrate.sql +901 -0
  7. package/db/migrations/031-wiki-page-index-provenance-columns.sql +2 -0
  8. package/db/migrations/032-add-memory-provenance-columns.sql +21 -0
  9. package/db/migrations/033-create-model-runs-and-tool-traces.sql +53 -0
  10. package/db/migrations/034-add-connector-event-scope-columns.sql +14 -0
  11. package/db/migrations/035-create-twin-edges.sql +63 -0
  12. package/db/migrations/036-create-agent-situation-packets.sql +61 -0
  13. package/dist/agent-graph/alias-write.d.ts +3 -0
  14. package/dist/agent-graph/alias-write.js +231 -0
  15. package/dist/agent-graph/entity-resolve.d.ts +3 -0
  16. package/dist/agent-graph/entity-resolve.js +275 -0
  17. package/dist/agent-graph/errors.d.ts +4 -0
  18. package/dist/agent-graph/errors.js +11 -0
  19. package/dist/agent-graph/graph-query.d.ts +5 -0
  20. package/dist/agent-graph/graph-query.js +359 -0
  21. package/dist/agent-graph/index.d.ts +6 -0
  22. package/dist/agent-graph/index.js +22 -0
  23. package/dist/agent-graph/types.d.ts +162 -0
  24. package/dist/agent-graph/types.js +3 -0
  25. package/dist/agent-situation/builder.d.ts +8 -0
  26. package/dist/agent-situation/builder.js +239 -0
  27. package/dist/agent-situation/cache-key.d.ts +4 -0
  28. package/dist/agent-situation/cache-key.js +64 -0
  29. package/dist/agent-situation/index.d.ts +7 -0
  30. package/dist/agent-situation/index.js +28 -0
  31. package/dist/agent-situation/packet-store.d.ts +27 -0
  32. package/dist/agent-situation/packet-store.js +228 -0
  33. package/dist/agent-situation/ranking-policy.d.ts +18 -0
  34. package/dist/agent-situation/ranking-policy.js +75 -0
  35. package/dist/agent-situation/source-readers.d.ts +52 -0
  36. package/dist/agent-situation/source-readers.js +300 -0
  37. package/dist/agent-situation/types.d.ts +195 -0
  38. package/dist/agent-situation/types.js +3 -0
  39. package/dist/canonicalize.d.ts +38 -0
  40. package/dist/canonicalize.js +106 -0
  41. package/dist/cases/case-links.d.ts +116 -0
  42. package/dist/cases/case-links.js +794 -0
  43. package/dist/cases/composition-overrides.d.ts +90 -0
  44. package/dist/cases/composition-overrides.js +724 -0
  45. package/dist/cases/corrections.d.ts +156 -0
  46. package/dist/cases/corrections.js +1045 -0
  47. package/dist/cases/freshness.d.ts +57 -0
  48. package/dist/cases/freshness.js +283 -0
  49. package/dist/cases/live-state.d.ts +48 -0
  50. package/dist/cases/live-state.js +256 -0
  51. package/dist/cases/membership-explain.d.ts +56 -0
  52. package/dist/cases/membership-explain.js +140 -0
  53. package/dist/cases/membership-matcher.d.ts +23 -0
  54. package/dist/cases/membership-matcher.js +193 -0
  55. package/dist/cases/merge-split.d.ts +61 -0
  56. package/dist/cases/merge-split.js +368 -0
  57. package/dist/cases/role-inference.d.ts +10 -0
  58. package/dist/cases/role-inference.js +85 -0
  59. package/dist/cases/search-rollup.d.ts +27 -0
  60. package/dist/cases/search-rollup.js +309 -0
  61. package/dist/cases/sqlite-transaction.d.ts +10 -0
  62. package/dist/cases/sqlite-transaction.js +62 -0
  63. package/dist/cases/store.d.ts +74 -0
  64. package/dist/cases/store.js +816 -0
  65. package/dist/cases/target-ref.d.ts +25 -0
  66. package/dist/cases/target-ref.js +22 -0
  67. package/dist/cases/timeline-range.d.ts +6 -0
  68. package/dist/cases/timeline-range.js +322 -0
  69. package/dist/cases/tombstone-sweeper.d.ts +13 -0
  70. package/dist/cases/tombstone-sweeper.js +128 -0
  71. package/dist/cases/types.d.ts +244 -0
  72. package/dist/cases/types.js +47 -0
  73. package/dist/cases/wiki-page-index.d.ts +50 -0
  74. package/dist/cases/wiki-page-index.js +350 -0
  75. package/dist/connectors/event-index.d.ts +45 -0
  76. package/dist/connectors/event-index.js +381 -0
  77. package/dist/connectors/raw-query.d.ts +18 -0
  78. package/dist/connectors/raw-query.js +305 -0
  79. package/dist/connectors/types.d.ts +109 -0
  80. package/dist/connectors/types.js +3 -0
  81. package/dist/db-adapter/node-sqlite-adapter.d.ts +6 -0
  82. package/dist/db-adapter/node-sqlite-adapter.js +131 -0
  83. package/dist/db-manager.d.ts +12 -1
  84. package/dist/db-manager.js +60 -5
  85. package/dist/decision-formatter.d.ts +2 -0
  86. package/dist/decision-formatter.js +11 -8
  87. package/dist/edges/ref-validation.d.ts +8 -0
  88. package/dist/edges/ref-validation.js +262 -0
  89. package/dist/edges/store.d.ts +10 -0
  90. package/dist/edges/store.js +343 -0
  91. package/dist/edges/types.d.ts +86 -0
  92. package/dist/edges/types.js +18 -0
  93. package/dist/embedding-server/mobile/daemon.d.ts +1 -0
  94. package/dist/embedding-server/mobile/daemon.js +11 -1
  95. package/dist/embeddings.js +13 -0
  96. package/dist/entities/audit-metrics.d.ts +73 -0
  97. package/dist/entities/audit-metrics.js +128 -0
  98. package/dist/entities/candidate-generator.d.ts +9 -0
  99. package/dist/entities/candidate-generator.js +436 -0
  100. package/dist/entities/entity-impact.d.ts +41 -0
  101. package/dist/entities/entity-impact.js +140 -0
  102. package/dist/entities/entity-linked-decision-counts.d.ts +2 -0
  103. package/dist/entities/entity-linked-decision-counts.js +29 -0
  104. package/dist/entities/entity-list.d.ts +23 -0
  105. package/dist/entities/entity-list.js +99 -0
  106. package/dist/entities/entity-orphan-list.d.ts +26 -0
  107. package/dist/entities/entity-orphan-list.js +91 -0
  108. package/dist/entities/entity-search.d.ts +21 -0
  109. package/dist/entities/entity-search.js +150 -0
  110. package/dist/entities/errors.d.ts +65 -0
  111. package/dist/entities/errors.js +124 -0
  112. package/dist/entities/exact-merge-backfill.d.ts +11 -0
  113. package/dist/entities/exact-merge-backfill.js +161 -0
  114. package/dist/entities/lineage-backfill.d.ts +12 -0
  115. package/dist/entities/lineage-backfill.js +101 -0
  116. package/dist/entities/lineage-store.d.ts +51 -0
  117. package/dist/entities/lineage-store.js +308 -0
  118. package/dist/entities/normalization.d.ts +14 -0
  119. package/dist/entities/normalization.js +63 -0
  120. package/dist/entities/policy-store.d.ts +17 -0
  121. package/dist/entities/policy-store.js +263 -0
  122. package/dist/entities/policy-types.d.ts +72 -0
  123. package/dist/entities/policy-types.js +59 -0
  124. package/dist/entities/projection.d.ts +8 -0
  125. package/dist/entities/projection.js +82 -0
  126. package/dist/entities/provenance-query.d.ts +33 -0
  127. package/dist/entities/provenance-query.js +167 -0
  128. package/dist/entities/read-identity.d.ts +31 -0
  129. package/dist/entities/read-identity.js +264 -0
  130. package/dist/entities/recall-bridge.d.ts +5 -0
  131. package/dist/entities/recall-bridge.js +171 -0
  132. package/dist/entities/resolution-engine.d.ts +15 -0
  133. package/dist/entities/resolution-engine.js +69 -0
  134. package/dist/entities/rollback-preview.d.ts +39 -0
  135. package/dist/entities/rollback-preview.js +235 -0
  136. package/dist/entities/source-locator.d.ts +3 -0
  137. package/dist/entities/source-locator.js +32 -0
  138. package/dist/entities/store.d.ts +75 -0
  139. package/dist/entities/store.js +465 -0
  140. package/dist/entities/types.d.ts +162 -0
  141. package/dist/entities/types.js +30 -0
  142. package/dist/index.d.ts +62 -3
  143. package/dist/index.js +116 -26
  144. package/dist/mama-api.d.ts +53 -35
  145. package/dist/mama-api.js +437 -78
  146. package/dist/memory/api.d.ts +26 -38
  147. package/dist/memory/api.js +772 -68
  148. package/dist/memory/event-store.d.ts +3 -0
  149. package/dist/memory/event-store.js +21 -2
  150. package/dist/memory/provenance-audit.d.ts +22 -0
  151. package/dist/memory/provenance-audit.js +112 -0
  152. package/dist/memory/provenance-query.d.ts +11 -0
  153. package/dist/memory/provenance-query.js +193 -0
  154. package/dist/memory/provenance.d.ts +29 -0
  155. package/dist/memory/provenance.js +136 -0
  156. package/dist/memory/scope-backfill.d.ts +17 -0
  157. package/dist/memory/scope-backfill.js +77 -0
  158. package/dist/memory/types.d.ts +97 -16
  159. package/dist/model-runs/store.d.ts +13 -0
  160. package/dist/model-runs/store.js +457 -0
  161. package/dist/model-runs/tool-trace-store.d.ts +4 -0
  162. package/dist/model-runs/tool-trace-store.js +114 -0
  163. package/dist/model-runs/types.d.ts +69 -0
  164. package/dist/model-runs/types.js +5 -0
  165. package/dist/runtime/trusted-provenance.d.ts +3 -0
  166. package/dist/runtime/trusted-provenance.js +6 -0
  167. package/dist/search/feedback-store.d.ts +59 -0
  168. package/dist/search/feedback-store.js +211 -0
  169. package/dist/search/question-type.d.ts +5 -0
  170. package/dist/search/question-type.js +41 -0
  171. package/dist/search/ranker-features.d.ts +23 -0
  172. package/dist/search/ranker-features.js +104 -0
  173. package/dist/search/ranker-rescore.d.ts +31 -0
  174. package/dist/search/ranker-rescore.js +226 -0
  175. package/dist/search/ranker-trainer.d.ts +94 -0
  176. package/dist/search/ranker-trainer.js +860 -0
  177. package/dist/search/search-quality.d.ts +36 -0
  178. package/dist/search/search-quality.js +29 -0
  179. package/dist/test-utils.d.ts +14 -0
  180. package/dist/test-utils.js +52 -0
  181. package/package.json +28 -3
@@ -0,0 +1,2 @@
1
+ ALTER TABLE wiki_page_index ADD COLUMN source_ids TEXT;
2
+ ALTER TABLE wiki_page_index ADD COLUMN entity_refs TEXT;
@@ -0,0 +1,21 @@
1
+ ALTER TABLE decisions ADD COLUMN agent_id TEXT;
2
+ ALTER TABLE decisions ADD COLUMN model_run_id TEXT;
3
+ ALTER TABLE decisions ADD COLUMN envelope_hash TEXT;
4
+ ALTER TABLE decisions ADD COLUMN gateway_call_id TEXT;
5
+ ALTER TABLE decisions ADD COLUMN source_refs_json TEXT;
6
+ ALTER TABLE decisions ADD COLUMN provenance_json TEXT;
7
+
8
+ CREATE INDEX IF NOT EXISTS idx_decisions_envelope_hash
9
+ ON decisions(envelope_hash);
10
+
11
+ CREATE INDEX IF NOT EXISTS idx_decisions_model_run_id
12
+ ON decisions(model_run_id);
13
+
14
+ CREATE INDEX IF NOT EXISTS idx_decisions_gateway_call_id
15
+ ON decisions(gateway_call_id);
16
+
17
+ CREATE INDEX IF NOT EXISTS idx_memory_events_memory_created
18
+ ON memory_events(memory_id, created_at DESC);
19
+
20
+ INSERT OR IGNORE INTO schema_version (version, description)
21
+ VALUES (32, 'Add nullable memory provenance columns');
@@ -0,0 +1,53 @@
1
+ CREATE TABLE IF NOT EXISTS model_runs (
2
+ model_run_id TEXT PRIMARY KEY,
3
+ model_id TEXT,
4
+ model_provider TEXT,
5
+ prompt_version TEXT,
6
+ tool_manifest_version TEXT,
7
+ output_schema_version TEXT,
8
+ agent_id TEXT,
9
+ instance_id TEXT,
10
+ envelope_hash TEXT,
11
+ parent_model_run_id TEXT,
12
+ input_snapshot_ref TEXT,
13
+ input_refs_json TEXT,
14
+ completion_summary TEXT,
15
+ status TEXT NOT NULL CHECK (status IN ('running', 'committed', 'failed', 'legacy')),
16
+ error_summary TEXT,
17
+ token_count INTEGER DEFAULT 0,
18
+ cost_estimate REAL,
19
+ created_at INTEGER NOT NULL,
20
+ completed_at INTEGER
21
+ );
22
+
23
+ CREATE INDEX IF NOT EXISTS idx_model_runs_envelope_hash
24
+ ON model_runs(envelope_hash);
25
+
26
+ CREATE INDEX IF NOT EXISTS idx_model_runs_status_created
27
+ ON model_runs(status, created_at DESC);
28
+
29
+ CREATE INDEX IF NOT EXISTS idx_model_runs_agent_created
30
+ ON model_runs(agent_id, created_at DESC);
31
+
32
+ CREATE TABLE IF NOT EXISTS tool_traces (
33
+ trace_id TEXT PRIMARY KEY,
34
+ model_run_id TEXT NOT NULL,
35
+ gateway_call_id TEXT,
36
+ tool_name TEXT NOT NULL,
37
+ input_summary TEXT,
38
+ output_summary TEXT,
39
+ execution_status TEXT,
40
+ duration_ms INTEGER DEFAULT 0,
41
+ envelope_hash TEXT,
42
+ created_at INTEGER NOT NULL,
43
+ FOREIGN KEY (model_run_id) REFERENCES model_runs(model_run_id)
44
+ );
45
+
46
+ CREATE INDEX IF NOT EXISTS idx_tool_traces_model_run_id
47
+ ON tool_traces(model_run_id, created_at DESC);
48
+
49
+ CREATE INDEX IF NOT EXISTS idx_tool_traces_gateway_call_id
50
+ ON tool_traces(gateway_call_id);
51
+
52
+ INSERT OR IGNORE INTO schema_version (version, description)
53
+ VALUES (33, 'Create model runs and tool traces');
@@ -0,0 +1,14 @@
1
+ ALTER TABLE connector_event_index ADD COLUMN source_cursor TEXT;
2
+ ALTER TABLE connector_event_index ADD COLUMN tenant_id TEXT;
3
+ ALTER TABLE connector_event_index ADD COLUMN project_id TEXT;
4
+ ALTER TABLE connector_event_index ADD COLUMN memory_scope_kind TEXT;
5
+ ALTER TABLE connector_event_index ADD COLUMN memory_scope_id TEXT;
6
+
7
+ CREATE INDEX IF NOT EXISTS idx_connector_event_scope
8
+ ON connector_event_index(tenant_id, project_id, memory_scope_kind, memory_scope_id);
9
+
10
+ CREATE INDEX IF NOT EXISTS idx_connector_event_source_cursor
11
+ ON connector_event_index(source_connector, source_cursor);
12
+
13
+ INSERT OR IGNORE INTO schema_version (version, description)
14
+ VALUES (34, 'Add connector event scope columns');
@@ -0,0 +1,63 @@
1
+ CREATE TABLE IF NOT EXISTS twin_edges (
2
+ edge_id TEXT PRIMARY KEY,
3
+ edge_type TEXT NOT NULL CHECK (
4
+ edge_type IN (
5
+ 'supersedes',
6
+ 'builds_on',
7
+ 'debates',
8
+ 'synthesizes',
9
+ 'mentions',
10
+ 'derived_from',
11
+ 'case_member',
12
+ 'alias_of',
13
+ 'next_action_for',
14
+ 'blocks'
15
+ )
16
+ ),
17
+ subject_kind TEXT NOT NULL CHECK (
18
+ subject_kind IN ('memory', 'case', 'entity', 'report', 'edge')
19
+ ),
20
+ subject_id TEXT NOT NULL,
21
+ object_kind TEXT NOT NULL CHECK (
22
+ object_kind IN ('memory', 'case', 'entity', 'report', 'edge', 'raw')
23
+ ),
24
+ object_id TEXT NOT NULL,
25
+ relation_attrs_json TEXT,
26
+ confidence REAL NOT NULL DEFAULT 1.0 CHECK (confidence >= 0.0 AND confidence <= 1.0),
27
+ source TEXT NOT NULL CHECK (source IN ('agent', 'human', 'code')),
28
+ agent_id TEXT,
29
+ model_run_id TEXT,
30
+ envelope_hash TEXT,
31
+ human_actor_id TEXT,
32
+ human_actor_role TEXT,
33
+ authority_scope_json TEXT,
34
+ reason_classification TEXT,
35
+ reason_text TEXT,
36
+ evidence_refs_json TEXT,
37
+ request_idempotency_key TEXT,
38
+ edge_idempotency_key TEXT,
39
+ content_hash BLOB NOT NULL CHECK(length(content_hash)=32),
40
+ created_at INTEGER NOT NULL
41
+ );
42
+
43
+ CREATE INDEX IF NOT EXISTS idx_twin_edges_subject
44
+ ON twin_edges(subject_kind, subject_id, created_at DESC);
45
+
46
+ CREATE INDEX IF NOT EXISTS idx_twin_edges_object
47
+ ON twin_edges(object_kind, object_id, created_at DESC);
48
+
49
+ CREATE INDEX IF NOT EXISTS idx_twin_edges_model_run_id
50
+ ON twin_edges(model_run_id, created_at DESC);
51
+
52
+ CREATE INDEX IF NOT EXISTS idx_twin_edges_request_idempotency
53
+ ON twin_edges(model_run_id, request_idempotency_key, created_at DESC)
54
+ WHERE model_run_id IS NOT NULL
55
+ AND request_idempotency_key IS NOT NULL;
56
+
57
+ CREATE UNIQUE INDEX IF NOT EXISTS ux_twin_edges_model_run_edge_idempotency
58
+ ON twin_edges(model_run_id, edge_idempotency_key)
59
+ WHERE model_run_id IS NOT NULL
60
+ AND edge_idempotency_key IS NOT NULL;
61
+
62
+ INSERT OR IGNORE INTO schema_version (version, description)
63
+ VALUES (35, 'Create first-class twin edge ledger');
@@ -0,0 +1,61 @@
1
+ CREATE TABLE IF NOT EXISTS agent_situation_packets (
2
+ packet_id TEXT PRIMARY KEY,
3
+ cache_key TEXT NOT NULL,
4
+ scope_json TEXT NOT NULL,
5
+ scope_hash TEXT NOT NULL,
6
+ range_start_ms INTEGER NOT NULL CHECK (range_start_ms >= 0),
7
+ range_end_ms INTEGER NOT NULL CHECK (range_end_ms >= range_start_ms),
8
+ focus_json TEXT NOT NULL,
9
+ envelope_hash TEXT NOT NULL,
10
+ envelope_effective_filters_json TEXT NOT NULL,
11
+ envelope_effective_filters_hash TEXT NOT NULL,
12
+ ranking_policy_version TEXT NOT NULL,
13
+ generated_at INTEGER NOT NULL CHECK (generated_at >= 0),
14
+ expires_at INTEGER NOT NULL CHECK (expires_at >= generated_at),
15
+ ttl_seconds INTEGER NOT NULL CHECK (ttl_seconds > 0),
16
+ freshness_json TEXT NOT NULL,
17
+ source_coverage_json TEXT NOT NULL,
18
+ briefing_json TEXT NOT NULL,
19
+ ranked_items_json TEXT NOT NULL,
20
+ top_memory_refs_json TEXT NOT NULL,
21
+ pending_human_questions_json TEXT NOT NULL,
22
+ entity_clusters_json TEXT NOT NULL,
23
+ recommended_next_tools_json TEXT NOT NULL,
24
+ generated_from_slice_ids_json TEXT NOT NULL DEFAULT '[]',
25
+ caveats_json TEXT NOT NULL,
26
+ agent_id TEXT NOT NULL,
27
+ model_run_id TEXT NOT NULL,
28
+ input_snapshot_ref TEXT NOT NULL,
29
+ source_refs_json TEXT NOT NULL DEFAULT '[]',
30
+ tenant_id TEXT NOT NULL DEFAULT 'default',
31
+ project_id TEXT NOT NULL,
32
+ memory_scope_kind TEXT NOT NULL,
33
+ memory_scope_id TEXT NOT NULL,
34
+ created_at INTEGER NOT NULL
35
+ );
36
+
37
+ CREATE INDEX IF NOT EXISTS idx_agent_situation_cache_fresh
38
+ ON agent_situation_packets(cache_key, ranking_policy_version, expires_at DESC);
39
+
40
+ CREATE INDEX IF NOT EXISTS idx_agent_situation_envelope
41
+ ON agent_situation_packets(envelope_hash, generated_at DESC);
42
+
43
+ CREATE INDEX IF NOT EXISTS idx_agent_situation_model_run
44
+ ON agent_situation_packets(model_run_id, generated_at DESC);
45
+
46
+ CREATE INDEX IF NOT EXISTS idx_agent_situation_scope
47
+ ON agent_situation_packets(tenant_id, project_id, memory_scope_kind, memory_scope_id, generated_at DESC);
48
+
49
+ CREATE TABLE IF NOT EXISTS agent_situation_refresh_leases (
50
+ cache_key TEXT PRIMARY KEY,
51
+ ranking_policy_version TEXT NOT NULL,
52
+ lease_owner TEXT NOT NULL,
53
+ lease_expires_at INTEGER NOT NULL,
54
+ created_at INTEGER NOT NULL
55
+ );
56
+
57
+ CREATE INDEX IF NOT EXISTS idx_agent_situation_leases_expiry
58
+ ON agent_situation_refresh_leases(lease_expires_at);
59
+
60
+ INSERT OR IGNORE INTO schema_version (version, description)
61
+ VALUES (36, 'Create agent situation packet cache');
@@ -0,0 +1,3 @@
1
+ import type { AgentGraphAdapter, AttachEntityAliasWithEdgeInput, AttachEntityAliasWithEdgeResult } from './types.js';
2
+ export declare function attachEntityAliasWithEdge(adapter: AgentGraphAdapter, input: AttachEntityAliasWithEdgeInput): AttachEntityAliasWithEdgeResult;
3
+ //# sourceMappingURL=alias-write.d.ts.map
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.attachEntityAliasWithEdge = attachEntityAliasWithEdge;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const canonicalize_js_1 = require("../canonicalize.js");
6
+ const ref_validation_js_1 = require("../edges/ref-validation.js");
7
+ const store_js_1 = require("../edges/store.js");
8
+ const types_js_1 = require("../edges/types.js");
9
+ const normalization_js_1 = require("../entities/normalization.js");
10
+ const store_js_2 = require("../entities/store.js");
11
+ const errors_js_1 = require("./errors.js");
12
+ const TWIN_REF_KIND_SET = new Set(types_js_1.TWIN_REF_KINDS);
13
+ function stableAliasId(input, normalizedLabel) {
14
+ const replayKey = replayIdempotencyKey(input);
15
+ if (replayKey) {
16
+ const hash = (0, node_crypto_1.createHash)('sha256')
17
+ .update(`${input.entity_id}\0${normalizedLabel}\0${replayKey}`, 'utf8')
18
+ .digest('hex')
19
+ .slice(0, 32);
20
+ return `alias_${hash}`;
21
+ }
22
+ return `alias_${(0, node_crypto_1.randomUUID)().replace(/-/g, '')}`;
23
+ }
24
+ function replayIdempotencyKey(input) {
25
+ return input.edge_idempotency_key ?? input.request_idempotency_key;
26
+ }
27
+ function loadAlias(adapter, aliasId) {
28
+ const row = adapter.prepare('SELECT * FROM entity_aliases WHERE id = ?').get(aliasId);
29
+ if (!row) {
30
+ throw new Error(`Entity alias was not written: ${aliasId}`);
31
+ }
32
+ return {
33
+ id: String(row.id),
34
+ entity_id: String(row.entity_id),
35
+ label: String(row.label),
36
+ normalized_label: String(row.normalized_label),
37
+ lang: typeof row.lang === 'string' ? row.lang : null,
38
+ script: typeof row.script === 'string' ? row.script : null,
39
+ label_type: row.label_type,
40
+ source_type: String(row.source_type),
41
+ source_ref: typeof row.source_ref === 'string' ? row.source_ref : null,
42
+ confidence: typeof row.confidence === 'number' ? row.confidence : null,
43
+ status: row.status,
44
+ created_at: Number(row.created_at),
45
+ };
46
+ }
47
+ function normalizeConfidence(value) {
48
+ if (value === undefined || value === null) {
49
+ return 1;
50
+ }
51
+ if (typeof value === 'number' && Number.isFinite(value) && value >= 0 && value <= 1) {
52
+ return value;
53
+ }
54
+ throw new errors_js_1.AgentGraphValidationError(`confidence must be between 0 and 1: ${String(value)}`);
55
+ }
56
+ function selectExistingAliasEdge(adapter, modelRunId, edgeIdempotencyKey) {
57
+ if (!edgeIdempotencyKey) {
58
+ return null;
59
+ }
60
+ const row = adapter
61
+ .prepare(`
62
+ SELECT *
63
+ FROM twin_edges
64
+ WHERE model_run_id = ?
65
+ AND edge_idempotency_key = ?
66
+ LIMIT 1
67
+ `)
68
+ .get(modelRunId, edgeIdempotencyKey);
69
+ return row ? (0, store_js_1.mapTwinEdgeRow)(row) : null;
70
+ }
71
+ function normalizeSourceRefs(sourceRefs) {
72
+ if (!sourceRefs || sourceRefs.length === 0) {
73
+ return [];
74
+ }
75
+ const refs = [];
76
+ const seen = new Set();
77
+ for (const ref of sourceRefs) {
78
+ if (!ref ||
79
+ typeof ref !== 'object' ||
80
+ typeof ref.kind !== 'string' ||
81
+ typeof ref.id !== 'string' ||
82
+ ref.id.trim().length === 0 ||
83
+ !TWIN_REF_KIND_SET.has(ref.kind)) {
84
+ throw new errors_js_1.AgentGraphValidationError('source_refs must be TwinRef objects with kind and id.');
85
+ }
86
+ const normalized = { kind: ref.kind, id: ref.id.trim() };
87
+ const key = `${normalized.kind}:${normalized.id}`;
88
+ if (!seen.has(key)) {
89
+ seen.add(key);
90
+ refs.push(normalized);
91
+ }
92
+ }
93
+ return refs.sort((left, right) => `${left.kind}:${left.id}`.localeCompare(`${right.kind}:${right.id}`));
94
+ }
95
+ function expectedRelationAttrs(alias, sourceRefs) {
96
+ const attrs = {
97
+ alias_id: alias.id,
98
+ label: alias.label,
99
+ normalized_label: alias.normalized_label,
100
+ lang: alias.lang,
101
+ script: alias.script,
102
+ label_type: alias.label_type,
103
+ };
104
+ if (sourceRefs.length > 0) {
105
+ attrs.source_refs = sourceRefs.map((ref) => ({ kind: ref.kind, id: ref.id }));
106
+ }
107
+ return attrs;
108
+ }
109
+ function assertAliasReplayMatches(alias, input, normalized, confidence) {
110
+ const expectedScript = input.script ?? normalized.script;
111
+ const expectedLabelType = input.label_type ?? 'alt';
112
+ const expectedSourceRef = input.source_ref ?? null;
113
+ const matches = alias.entity_id === input.entity_id &&
114
+ alias.label === input.label &&
115
+ alias.normalized_label === normalized.normalized &&
116
+ alias.lang === (input.lang ?? null) &&
117
+ alias.script === expectedScript &&
118
+ alias.label_type === expectedLabelType &&
119
+ alias.source_type === input.source_type &&
120
+ alias.source_ref === expectedSourceRef &&
121
+ alias.confidence === confidence &&
122
+ alias.status === 'active';
123
+ if (!matches) {
124
+ throw new errors_js_1.AgentGraphValidationError(`Conflicting entity alias replay for request idempotency key: ${replayIdempotencyKey(input)}`);
125
+ }
126
+ }
127
+ function assertAliasEdgeReplayMatches(edge, input, alias, confidence, edgeIdempotencyKey, sourceRefs) {
128
+ const matches = edge.edge_type === 'alias_of' &&
129
+ edge.subject_ref.kind === 'entity' &&
130
+ edge.subject_ref.id === input.entity_id &&
131
+ edge.object_ref.kind === 'entity' &&
132
+ edge.object_ref.id === input.entity_id &&
133
+ edge.relation_attrs_json === (0, canonicalize_js_1.canonicalizeJSON)(expectedRelationAttrs(alias, sourceRefs)) &&
134
+ edge.confidence === confidence &&
135
+ edge.source === 'agent' &&
136
+ edge.agent_id === input.agent_id &&
137
+ edge.model_run_id === input.model_run_id &&
138
+ edge.envelope_hash === input.envelope_hash &&
139
+ edge.request_idempotency_key === (input.request_idempotency_key ?? null) &&
140
+ edge.edge_idempotency_key === (edgeIdempotencyKey ?? null);
141
+ if (!matches) {
142
+ throw new errors_js_1.AgentGraphValidationError(`Conflicting alias edge replay for request idempotency key: ${replayIdempotencyKey(input)}`);
143
+ }
144
+ }
145
+ function insertAliasEdge(adapter, input, alias, confidence, sourceRefs) {
146
+ const edgeIdempotencyKey = replayIdempotencyKey(input);
147
+ const existing = selectExistingAliasEdge(adapter, input.model_run_id, edgeIdempotencyKey);
148
+ const edgeId = `edge_${(0, node_crypto_1.randomUUID)().replace(/-/g, '')}`;
149
+ const relationAttrs = expectedRelationAttrs(alias, sourceRefs);
150
+ const relationAttrsJson = (0, canonicalize_js_1.canonicalizeJSON)(relationAttrs);
151
+ if (existing) {
152
+ assertAliasEdgeReplayMatches(existing, input, alias, confidence, edgeIdempotencyKey, sourceRefs);
153
+ return existing;
154
+ }
155
+ const contentHash = (0, node_crypto_1.createHash)('sha256')
156
+ .update((0, canonicalize_js_1.canonicalizeJSON)({
157
+ edge_type: 'alias_of',
158
+ subject_ref: { kind: 'entity', id: input.entity_id },
159
+ object_ref: { kind: 'entity', id: input.entity_id },
160
+ relation_attrs_json: relationAttrsJson,
161
+ confidence,
162
+ source: 'agent',
163
+ agent_id: input.agent_id,
164
+ model_run_id: input.model_run_id,
165
+ envelope_hash: input.envelope_hash,
166
+ }), 'utf8')
167
+ .digest();
168
+ adapter
169
+ .prepare(`
170
+ INSERT INTO twin_edges (
171
+ edge_id, edge_type, subject_kind, subject_id, object_kind, object_id,
172
+ relation_attrs_json, confidence, source, agent_id, model_run_id, envelope_hash,
173
+ request_idempotency_key, edge_idempotency_key, content_hash, created_at
174
+ )
175
+ VALUES (?, 'alias_of', 'entity', ?, 'entity', ?, ?, ?, 'agent', ?, ?, ?, ?, ?, ?, ?)
176
+ `)
177
+ .run(edgeId, input.entity_id, input.entity_id, relationAttrsJson, confidence, input.agent_id, input.model_run_id, input.envelope_hash, input.request_idempotency_key ?? null, edgeIdempotencyKey ?? null, contentHash, Date.now());
178
+ const row = adapter.prepare('SELECT * FROM twin_edges WHERE edge_id = ?').get(edgeId);
179
+ if (!row) {
180
+ throw new Error(`Entity alias edge was not written: ${edgeId}`);
181
+ }
182
+ return (0, store_js_1.mapTwinEdgeRow)(row);
183
+ }
184
+ function attachEntityAliasWithEdge(adapter, input) {
185
+ const entity = (0, store_js_2.getEntityNode)(input.entity_id, adapter);
186
+ if (!entity || entity.status !== 'active') {
187
+ throw new errors_js_1.AgentGraphValidationError(`Active entity not found: ${input.entity_id}`);
188
+ }
189
+ const visibility = {
190
+ scopes: input.scopes,
191
+ connectors: input.connectors,
192
+ projectRefs: input.project_refs,
193
+ tenantId: input.tenant_id,
194
+ };
195
+ const sourceRefs = normalizeSourceRefs(input.source_refs);
196
+ if (sourceRefs.length === 0) {
197
+ throw new errors_js_1.AgentGraphValidationError('source_refs must include at least one visible source.');
198
+ }
199
+ try {
200
+ (0, ref_validation_js_1.assertTwinRefsVisible)(adapter, [{ kind: 'entity', id: input.entity_id }, ...sourceRefs], visibility);
201
+ }
202
+ catch (error) {
203
+ throw new errors_js_1.AgentGraphValidationError(error instanceof Error ? error.message : String(error));
204
+ }
205
+ let normalized;
206
+ try {
207
+ normalized = (0, normalization_js_1.normalizeEntityLabel)(input.label);
208
+ }
209
+ catch (error) {
210
+ throw new errors_js_1.AgentGraphValidationError(error instanceof Error ? error.message : String(error));
211
+ }
212
+ const confidence = normalizeConfidence(input.confidence);
213
+ const aliasId = stableAliasId(input, normalized.normalized);
214
+ const createdAt = Date.now();
215
+ return adapter.transaction(() => {
216
+ adapter
217
+ .prepare(`
218
+ INSERT OR IGNORE INTO entity_aliases (
219
+ id, entity_id, label, normalized_label, lang, script, label_type,
220
+ source_type, source_ref, confidence, status, created_at
221
+ )
222
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?)
223
+ `)
224
+ .run(aliasId, input.entity_id, input.label, normalized.normalized, input.lang ?? null, input.script ?? normalized.script, input.label_type ?? 'alt', input.source_type, input.source_ref ?? null, confidence, createdAt);
225
+ const alias = loadAlias(adapter, aliasId);
226
+ assertAliasReplayMatches(alias, input, normalized, confidence);
227
+ const edge = insertAliasEdge(adapter, input, alias, confidence, sourceRefs);
228
+ return { alias, edge };
229
+ });
230
+ }
231
+ //# sourceMappingURL=alias-write.js.map
@@ -0,0 +1,3 @@
1
+ import type { AgentGraphAdapter, ResolveEntityInput, ResolveEntityResult } from './types.js';
2
+ export declare function resolveEntity(adapter: AgentGraphAdapter, input: ResolveEntityInput): ResolveEntityResult;
3
+ //# sourceMappingURL=entity-resolve.d.ts.map