@jungjaehoon/mama-core 1.5.0 → 1.7.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 (103) hide show
  1. package/README.md +48 -10
  2. package/db/migrations/032-add-memory-provenance-columns.sql +21 -0
  3. package/db/migrations/033-create-model-runs-and-tool-traces.sql +53 -0
  4. package/db/migrations/034-add-connector-event-scope-columns.sql +14 -0
  5. package/db/migrations/035-create-twin-edges.sql +63 -0
  6. package/db/migrations/036-create-agent-situation-packets.sql +61 -0
  7. package/db/migrations/037-create-context-packets.sql +32 -0
  8. package/dist/agent-graph/alias-write.d.ts +3 -0
  9. package/dist/agent-graph/alias-write.js +231 -0
  10. package/dist/agent-graph/entity-resolve.d.ts +3 -0
  11. package/dist/agent-graph/entity-resolve.js +275 -0
  12. package/dist/agent-graph/errors.d.ts +4 -0
  13. package/dist/agent-graph/errors.js +11 -0
  14. package/dist/agent-graph/graph-query.d.ts +5 -0
  15. package/dist/agent-graph/graph-query.js +359 -0
  16. package/dist/agent-graph/index.d.ts +6 -0
  17. package/dist/agent-graph/index.js +22 -0
  18. package/dist/agent-graph/types.d.ts +162 -0
  19. package/dist/agent-graph/types.js +3 -0
  20. package/dist/agent-situation/builder.d.ts +8 -0
  21. package/dist/agent-situation/builder.js +239 -0
  22. package/dist/agent-situation/cache-key.d.ts +4 -0
  23. package/dist/agent-situation/cache-key.js +64 -0
  24. package/dist/agent-situation/index.d.ts +7 -0
  25. package/dist/agent-situation/index.js +28 -0
  26. package/dist/agent-situation/packet-store.d.ts +27 -0
  27. package/dist/agent-situation/packet-store.js +228 -0
  28. package/dist/agent-situation/ranking-policy.d.ts +18 -0
  29. package/dist/agent-situation/ranking-policy.js +75 -0
  30. package/dist/agent-situation/source-readers.d.ts +52 -0
  31. package/dist/agent-situation/source-readers.js +300 -0
  32. package/dist/agent-situation/types.d.ts +195 -0
  33. package/dist/agent-situation/types.js +3 -0
  34. package/dist/cases/search-rollup.d.ts +4 -0
  35. package/dist/cases/search-rollup.js +84 -0
  36. package/dist/cases/wiki-page-index.js +6 -2
  37. package/dist/connectors/event-index.d.ts +1 -0
  38. package/dist/connectors/event-index.js +19 -4
  39. package/dist/connectors/raw-query.d.ts +18 -0
  40. package/dist/connectors/raw-query.js +305 -0
  41. package/dist/connectors/types.d.ts +40 -0
  42. package/dist/context-compile/boundary-defaults.d.ts +12 -0
  43. package/dist/context-compile/boundary-defaults.js +105 -0
  44. package/dist/context-compile/compiler-policy.d.ts +39 -0
  45. package/dist/context-compile/compiler-policy.js +147 -0
  46. package/dist/context-compile/compiler.d.ts +18 -0
  47. package/dist/context-compile/compiler.js +401 -0
  48. package/dist/context-compile/index.d.ts +9 -0
  49. package/dist/context-compile/index.js +25 -0
  50. package/dist/context-compile/packet-store.d.ts +9 -0
  51. package/dist/context-compile/packet-store.js +255 -0
  52. package/dist/context-compile/ref.d.ts +7 -0
  53. package/dist/context-compile/ref.js +102 -0
  54. package/dist/context-compile/source-readers.d.ts +69 -0
  55. package/dist/context-compile/source-readers.js +707 -0
  56. package/dist/context-compile/types.d.ts +138 -0
  57. package/dist/context-compile/types.js +11 -0
  58. package/dist/context-compile/visibility.d.ts +21 -0
  59. package/dist/context-compile/visibility.js +200 -0
  60. package/dist/db-adapter/node-sqlite-adapter.d.ts +9 -0
  61. package/dist/db-adapter/node-sqlite-adapter.js +207 -0
  62. package/dist/db-manager.d.ts +8 -1
  63. package/dist/db-manager.js +53 -5
  64. package/dist/edges/ref-validation.d.ts +8 -0
  65. package/dist/edges/ref-validation.js +301 -0
  66. package/dist/edges/store.d.ts +10 -0
  67. package/dist/edges/store.js +343 -0
  68. package/dist/edges/types.d.ts +88 -0
  69. package/dist/edges/types.js +18 -0
  70. package/dist/embeddings.d.ts +3 -0
  71. package/dist/embeddings.js +49 -9
  72. package/dist/entities/store.d.ts +4 -1
  73. package/dist/entities/store.js +206 -78
  74. package/dist/entities/types.d.ts +5 -1
  75. package/dist/entities/types.js +1 -1
  76. package/dist/index.d.ts +18 -3
  77. package/dist/index.js +54 -4
  78. package/dist/mama-api.d.ts +32 -35
  79. package/dist/mama-api.js +173 -22
  80. package/dist/memory/api.d.ts +17 -56
  81. package/dist/memory/api.js +494 -52
  82. package/dist/memory/event-store.d.ts +3 -0
  83. package/dist/memory/event-store.js +21 -2
  84. package/dist/memory/provenance-audit.d.ts +22 -0
  85. package/dist/memory/provenance-audit.js +112 -0
  86. package/dist/memory/provenance-query.d.ts +11 -0
  87. package/dist/memory/provenance-query.js +193 -0
  88. package/dist/memory/provenance.d.ts +29 -0
  89. package/dist/memory/provenance.js +137 -0
  90. package/dist/memory/scope-backfill.d.ts +17 -0
  91. package/dist/memory/scope-backfill.js +77 -0
  92. package/dist/memory/types.d.ts +87 -14
  93. package/dist/model-runs/store.d.ts +13 -0
  94. package/dist/model-runs/store.js +457 -0
  95. package/dist/model-runs/tool-trace-store.d.ts +4 -0
  96. package/dist/model-runs/tool-trace-store.js +114 -0
  97. package/dist/model-runs/types.d.ts +69 -0
  98. package/dist/model-runs/types.js +5 -0
  99. package/dist/runtime/trusted-provenance.d.ts +3 -0
  100. package/dist/runtime/trusted-provenance.js +6 -0
  101. package/dist/search/search-quality.d.ts +36 -0
  102. package/dist/search/search-quality.js +29 -0
  103. package/package.json +11 -3
@@ -1,5 +1,8 @@
1
+ import type { DatabaseAdapter } from '../db-manager.js';
1
2
  import type { MemoryEventRecord } from './types.js';
2
3
  export declare function appendMemoryEvent(input: Omit<MemoryEventRecord, 'event_id'>): Promise<string>;
4
+ export declare function insertMemoryEventInTransaction(adapter: Pick<DatabaseAdapter, 'prepare'>, input: Omit<MemoryEventRecord, 'event_id'>): string;
3
5
  export declare function listMemoryEventsForTopic(topic: string): Promise<MemoryEventRecord[]>;
6
+ export declare function listMemoryEventsForMemory(memoryId: string): Promise<MemoryEventRecord[]>;
4
7
  export declare function listRecentMemoryEvents(limit?: number): Promise<MemoryEventRecord[]>;
5
8
  //# sourceMappingURL=event-store.d.ts.map
@@ -4,7 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.appendMemoryEvent = appendMemoryEvent;
7
+ exports.insertMemoryEventInTransaction = insertMemoryEventInTransaction;
7
8
  exports.listMemoryEventsForTopic = listMemoryEventsForTopic;
9
+ exports.listMemoryEventsForMemory = listMemoryEventsForMemory;
8
10
  exports.listRecentMemoryEvents = listRecentMemoryEvents;
9
11
  const node_crypto_1 = __importDefault(require("node:crypto"));
10
12
  const db_manager_js_1 = require("../db-manager.js");
@@ -29,6 +31,9 @@ function deserializeEvent(row) {
29
31
  async function appendMemoryEvent(input) {
30
32
  await (0, db_manager_js_1.initDB)();
31
33
  const adapter = (0, db_manager_js_1.getAdapter)();
34
+ return insertMemoryEventInTransaction(adapter, input);
35
+ }
36
+ function insertMemoryEventInTransaction(adapter, input) {
32
37
  const eventId = `evt_${node_crypto_1.default.randomUUID().replace(/-/g, '')}`;
33
38
  adapter
34
39
  .prepare(`
@@ -50,11 +55,25 @@ async function listMemoryEventsForTopic(topic) {
50
55
  scope_refs, evidence_refs, reason, created_at
51
56
  FROM memory_events
52
57
  WHERE topic = ?
53
- ORDER BY created_at DESC
58
+ ORDER BY created_at DESC, rowid DESC
54
59
  `)
55
60
  .all(topic);
56
61
  return rows.map(deserializeEvent);
57
62
  }
63
+ async function listMemoryEventsForMemory(memoryId) {
64
+ await (0, db_manager_js_1.initDB)();
65
+ const adapter = (0, db_manager_js_1.getAdapter)();
66
+ const rows = adapter
67
+ .prepare(`
68
+ SELECT event_id, event_type, actor, source_turn_id, memory_id, topic,
69
+ scope_refs, evidence_refs, reason, created_at
70
+ FROM memory_events
71
+ WHERE memory_id = ?
72
+ ORDER BY created_at DESC, rowid DESC
73
+ `)
74
+ .all(memoryId);
75
+ return rows.map(deserializeEvent);
76
+ }
58
77
  async function listRecentMemoryEvents(limit = 10) {
59
78
  await (0, db_manager_js_1.initDB)();
60
79
  const adapter = (0, db_manager_js_1.getAdapter)();
@@ -63,7 +82,7 @@ async function listRecentMemoryEvents(limit = 10) {
63
82
  SELECT event_id, event_type, actor, source_turn_id, memory_id, topic,
64
83
  scope_refs, evidence_refs, reason, created_at
65
84
  FROM memory_events
66
- ORDER BY created_at DESC
85
+ ORDER BY created_at DESC, rowid DESC
67
86
  LIMIT ?
68
87
  `)
69
88
  .all(limit);
@@ -0,0 +1,22 @@
1
+ import type { MemoryEventRecord, MemoryScopeRef } from './types.js';
2
+ export interface MemoryProvenanceAuditRecord {
3
+ memory_id: string;
4
+ topic: string;
5
+ summary: string;
6
+ envelope_hash: string | null;
7
+ model_run_id: string | null;
8
+ gateway_call_id: string | null;
9
+ tool_name: string | null;
10
+ latest_event?: MemoryEventRecord;
11
+ scope_refs: MemoryScopeRef[];
12
+ legacy_caveats: string[];
13
+ }
14
+ export interface MemoryProvenanceAuditListOptions {
15
+ envelope_hash?: string;
16
+ model_run_id?: string;
17
+ gateway_call_id?: string;
18
+ limit?: number;
19
+ }
20
+ export declare function getMemoryProvenanceAudit(memoryId: string): Promise<MemoryProvenanceAuditRecord | null>;
21
+ export declare function listMemoryProvenanceAudit(options: MemoryProvenanceAuditListOptions): Promise<MemoryProvenanceAuditRecord[]>;
22
+ //# sourceMappingURL=provenance-audit.d.ts.map
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMemoryProvenanceAudit = getMemoryProvenanceAudit;
4
+ exports.listMemoryProvenanceAudit = listMemoryProvenanceAudit;
5
+ const db_manager_js_1 = require("../db-manager.js");
6
+ const event_store_js_1 = require("./event-store.js");
7
+ async function getMemoryProvenanceAudit(memoryId) {
8
+ await (0, db_manager_js_1.initDB)();
9
+ const adapter = (0, db_manager_js_1.getAdapter)();
10
+ const row = adapter
11
+ .prepare(`
12
+ SELECT id, topic, decision, summary, envelope_hash, model_run_id, gateway_call_id,
13
+ provenance_json
14
+ FROM decisions
15
+ WHERE id = ?
16
+ `)
17
+ .get(memoryId);
18
+ return row ? toAuditRecord(row) : null;
19
+ }
20
+ async function listMemoryProvenanceAudit(options) {
21
+ await (0, db_manager_js_1.initDB)();
22
+ const adapter = (0, db_manager_js_1.getAdapter)();
23
+ const filter = buildAuditFilter(options);
24
+ const rows = adapter
25
+ .prepare(`
26
+ SELECT id, topic, decision, summary, envelope_hash, model_run_id, gateway_call_id,
27
+ provenance_json
28
+ FROM decisions
29
+ WHERE ${filter.sql}
30
+ ORDER BY created_at DESC, id DESC
31
+ LIMIT ?
32
+ `)
33
+ .all(...filter.params, normalizeLimit(options.limit));
34
+ const records = [];
35
+ for (const row of rows) {
36
+ records.push(await toAuditRecord(row));
37
+ }
38
+ return records;
39
+ }
40
+ function buildAuditFilter(options) {
41
+ const filters = [];
42
+ const params = [];
43
+ for (const column of ['envelope_hash', 'model_run_id', 'gateway_call_id']) {
44
+ const value = options[column];
45
+ if (value !== undefined) {
46
+ filters.push(`${column} = ?`);
47
+ params.push(value);
48
+ }
49
+ }
50
+ if (filters.length !== 1) {
51
+ throw new Error('Exactly one provenance audit filter is required.');
52
+ }
53
+ return { sql: filters[0], params };
54
+ }
55
+ async function toAuditRecord(row) {
56
+ const events = await (0, event_store_js_1.listMemoryEventsForMemory)(row.id);
57
+ const scopeRefs = listScopeRefs(row.id);
58
+ const provenance = parseObject(row.provenance_json);
59
+ const legacyCaveats = [];
60
+ if (provenance.source_type === 'legacy') {
61
+ legacyCaveats.push('legacy_provenance_backfill');
62
+ }
63
+ if (scopeRefs.length === 0) {
64
+ legacyCaveats.push('unscoped_memory');
65
+ }
66
+ return {
67
+ memory_id: row.id,
68
+ topic: row.topic,
69
+ summary: row.summary ?? row.decision ?? '',
70
+ envelope_hash: row.envelope_hash,
71
+ model_run_id: row.model_run_id,
72
+ gateway_call_id: row.gateway_call_id,
73
+ tool_name: typeof provenance.tool_name === 'string' ? provenance.tool_name : null,
74
+ latest_event: events[0],
75
+ scope_refs: scopeRefs,
76
+ legacy_caveats: legacyCaveats,
77
+ };
78
+ }
79
+ function listScopeRefs(memoryId) {
80
+ const adapter = (0, db_manager_js_1.getAdapter)();
81
+ const rows = adapter
82
+ .prepare(`
83
+ SELECT ms.kind, ms.external_id
84
+ FROM memory_scope_bindings msb
85
+ JOIN memory_scopes ms ON ms.id = msb.scope_id
86
+ WHERE msb.memory_id = ?
87
+ ORDER BY msb.is_primary DESC, ms.kind ASC, ms.external_id ASC
88
+ `)
89
+ .all(memoryId);
90
+ return rows.map((row) => ({ kind: row.kind, id: row.external_id }));
91
+ }
92
+ function normalizeLimit(limit) {
93
+ if (!Number.isFinite(limit)) {
94
+ return 50;
95
+ }
96
+ return Math.max(1, Math.min(200, Math.floor(limit)));
97
+ }
98
+ function parseObject(value) {
99
+ if (!value) {
100
+ return {};
101
+ }
102
+ try {
103
+ const parsed = JSON.parse(value);
104
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
105
+ ? parsed
106
+ : {};
107
+ }
108
+ catch {
109
+ return {};
110
+ }
111
+ }
112
+ //# sourceMappingURL=provenance-audit.js.map
@@ -0,0 +1,11 @@
1
+ import type { MemoryProvenanceRecord, MemoryScopeRef } from './types.js';
2
+ export interface MemoryProvenanceQueryOptions {
3
+ scopes?: MemoryScopeRef[];
4
+ includeLegacyUnscoped?: boolean;
5
+ limit?: number;
6
+ }
7
+ export declare function getMemoryProvenance(memoryId: string, options?: MemoryProvenanceQueryOptions): Promise<MemoryProvenanceRecord | null>;
8
+ export declare function listMemoriesByEnvelopeHash(envelopeHash: string, options?: MemoryProvenanceQueryOptions): Promise<MemoryProvenanceRecord[]>;
9
+ export declare function listMemoriesByGatewayCallId(gatewayCallId: string, options?: MemoryProvenanceQueryOptions): Promise<MemoryProvenanceRecord[]>;
10
+ export declare function listMemoriesByModelRunId(modelRunId: string, options?: MemoryProvenanceQueryOptions): Promise<MemoryProvenanceRecord[]>;
11
+ //# sourceMappingURL=provenance-query.d.ts.map
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMemoryProvenance = getMemoryProvenance;
4
+ exports.listMemoriesByEnvelopeHash = listMemoriesByEnvelopeHash;
5
+ exports.listMemoriesByGatewayCallId = listMemoriesByGatewayCallId;
6
+ exports.listMemoriesByModelRunId = listMemoriesByModelRunId;
7
+ const db_manager_js_1 = require("../db-manager.js");
8
+ const event_store_js_1 = require("./event-store.js");
9
+ async function getMemoryProvenance(memoryId, options = {}) {
10
+ await (0, db_manager_js_1.initDB)();
11
+ const adapter = (0, db_manager_js_1.getAdapter)();
12
+ const row = adapter
13
+ .prepare(`
14
+ SELECT id, agent_id, model_run_id, envelope_hash, gateway_call_id,
15
+ source_refs_json, provenance_json, created_at
16
+ FROM decisions
17
+ WHERE id = ?
18
+ `)
19
+ .get(memoryId);
20
+ if (!row || !(await isVisibleMemory(row.id, options))) {
21
+ return null;
22
+ }
23
+ return toProvenanceRecord(row);
24
+ }
25
+ async function listMemoriesByEnvelopeHash(envelopeHash, options = {}) {
26
+ return listMemoriesByColumn('envelope_hash', envelopeHash, options);
27
+ }
28
+ async function listMemoriesByGatewayCallId(gatewayCallId, options = {}) {
29
+ return listMemoriesByColumn('gateway_call_id', gatewayCallId, options);
30
+ }
31
+ async function listMemoriesByModelRunId(modelRunId, options = {}) {
32
+ return listMemoriesByColumn('model_run_id', modelRunId, options);
33
+ }
34
+ async function listMemoriesByColumn(column, value, options) {
35
+ await (0, db_manager_js_1.initDB)();
36
+ const adapter = (0, db_manager_js_1.getAdapter)();
37
+ const limit = normalizeLimit(options.limit);
38
+ const visibility = buildVisibilityPredicate(options);
39
+ const rows = adapter
40
+ .prepare(`
41
+ SELECT d.id, d.agent_id, d.model_run_id, d.envelope_hash, d.gateway_call_id,
42
+ d.source_refs_json, d.provenance_json, d.created_at
43
+ FROM decisions d
44
+ WHERE d.${column} = ?${visibility.sql}
45
+ ORDER BY d.created_at DESC, d.id DESC
46
+ LIMIT ?
47
+ `)
48
+ .all(value, ...visibility.params, limit);
49
+ const records = [];
50
+ for (const row of rows) {
51
+ records.push(await toProvenanceRecord(row));
52
+ }
53
+ return records;
54
+ }
55
+ function buildVisibilityPredicate(options) {
56
+ if (!hasScopeFilter(options)) {
57
+ return { sql: '', params: [] };
58
+ }
59
+ const scopeIds = resolveMemoryScopeIds(options.scopes);
60
+ const legacyUnscopedPredicate = `
61
+ NOT EXISTS (
62
+ SELECT 1
63
+ FROM memory_scope_bindings msb_legacy
64
+ WHERE msb_legacy.memory_id = d.id
65
+ )
66
+ `;
67
+ if (scopeIds.length === 0) {
68
+ return options.includeLegacyUnscoped === true
69
+ ? { sql: ` AND ${legacyUnscopedPredicate}`, params: [] }
70
+ : { sql: ' AND 0 = 1', params: [] };
71
+ }
72
+ const placeholders = scopeIds.map(() => '?').join(', ');
73
+ const scopedPredicate = `
74
+ EXISTS (
75
+ SELECT 1
76
+ FROM memory_scope_bindings msb_scope
77
+ WHERE msb_scope.memory_id = d.id
78
+ AND msb_scope.scope_id IN (${placeholders})
79
+ )
80
+ `;
81
+ if (options.includeLegacyUnscoped === true) {
82
+ return {
83
+ sql: ` AND (${scopedPredicate} OR ${legacyUnscopedPredicate})`,
84
+ params: scopeIds,
85
+ };
86
+ }
87
+ return { sql: ` AND ${scopedPredicate}`, params: scopeIds };
88
+ }
89
+ function hasScopeFilter(options) {
90
+ return Array.isArray(options.scopes) && options.scopes.length > 0;
91
+ }
92
+ function resolveMemoryScopeIds(scopes) {
93
+ const scopeIds = [];
94
+ for (const scope of scopes) {
95
+ const scopeId = resolveMemoryScopeId(scope.kind, scope.id);
96
+ if (scopeId) {
97
+ scopeIds.push(scopeId);
98
+ }
99
+ }
100
+ return scopeIds;
101
+ }
102
+ async function toProvenanceRecord(row) {
103
+ const events = await (0, event_store_js_1.listMemoryEventsForMemory)(row.id);
104
+ return {
105
+ memory_id: row.id,
106
+ agent_id: row.agent_id,
107
+ model_run_id: row.model_run_id,
108
+ envelope_hash: row.envelope_hash,
109
+ gateway_call_id: row.gateway_call_id,
110
+ source_refs: parseStringArray(row.source_refs_json),
111
+ provenance: parseObject(row.provenance_json),
112
+ latest_event: events[0],
113
+ };
114
+ }
115
+ async function isVisibleMemory(memoryId, options) {
116
+ if (!hasScopeFilter(options)) {
117
+ return true;
118
+ }
119
+ await (0, db_manager_js_1.initDB)();
120
+ const adapter = (0, db_manager_js_1.getAdapter)();
121
+ const scopeIds = resolveMemoryScopeIds(options.scopes);
122
+ const bindingCount = adapter
123
+ .prepare(`
124
+ SELECT COUNT(*) as count
125
+ FROM memory_scope_bindings
126
+ WHERE memory_id = ?
127
+ `)
128
+ .get(memoryId);
129
+ const count = bindingCount.count;
130
+ if (count === 0) {
131
+ return options.includeLegacyUnscoped === true;
132
+ }
133
+ if (scopeIds.length === 0) {
134
+ return false;
135
+ }
136
+ const placeholders = scopeIds.map(() => '?').join(', ');
137
+ const row = adapter
138
+ .prepare(`
139
+ SELECT 1 as visible
140
+ FROM memory_scope_bindings
141
+ WHERE memory_id = ? AND scope_id IN (${placeholders})
142
+ LIMIT 1
143
+ `)
144
+ .get(memoryId, ...scopeIds);
145
+ return row?.visible === 1;
146
+ }
147
+ function resolveMemoryScopeId(kind, externalId) {
148
+ const adapter = (0, db_manager_js_1.getAdapter)();
149
+ const row = adapter
150
+ .prepare(`
151
+ SELECT id
152
+ FROM memory_scopes
153
+ WHERE kind = ? AND external_id = ?
154
+ LIMIT 1
155
+ `)
156
+ .get(kind, externalId);
157
+ return row?.id ?? null;
158
+ }
159
+ function normalizeLimit(limit) {
160
+ if (!Number.isFinite(limit)) {
161
+ return 50;
162
+ }
163
+ return Math.max(1, Math.min(200, Math.floor(limit)));
164
+ }
165
+ function parseStringArray(value) {
166
+ if (!value) {
167
+ return [];
168
+ }
169
+ try {
170
+ const parsed = JSON.parse(value);
171
+ return Array.isArray(parsed)
172
+ ? parsed.filter((item) => typeof item === 'string')
173
+ : [];
174
+ }
175
+ catch {
176
+ return [];
177
+ }
178
+ }
179
+ function parseObject(value) {
180
+ if (!value) {
181
+ return {};
182
+ }
183
+ try {
184
+ const parsed = JSON.parse(value);
185
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
186
+ ? parsed
187
+ : {};
188
+ }
189
+ catch {
190
+ return {};
191
+ }
192
+ }
193
+ //# sourceMappingURL=provenance-query.js.map
@@ -0,0 +1,29 @@
1
+ import type { MemoryEventRecord, MemoryWriteProvenance, PublicIngestConversationInput, PublicIngestMemoryInput, PublicSaveMemoryInput } from './types.js';
2
+ export interface TrustedProvenanceCapability {
3
+ readonly __trustedProvenanceCapability: 'mama-core';
4
+ }
5
+ export interface TrustedMemoryWriteOptions {
6
+ provenance: MemoryWriteProvenance;
7
+ capability: TrustedProvenanceCapability;
8
+ }
9
+ export interface NormalizedMemoryProvenance {
10
+ actor: MemoryEventRecord['actor'];
11
+ agent_id: string | null;
12
+ model_run_id: string | null;
13
+ envelope_hash: string | null;
14
+ tool_name: string | null;
15
+ gateway_call_id: string | null;
16
+ source_turn_id: string | null;
17
+ source_message_ref: string | null;
18
+ source_refs: string[];
19
+ provenance: Record<string, unknown>;
20
+ }
21
+ export declare function createTrustedProvenanceCapability(): TrustedProvenanceCapability;
22
+ export declare function assertTrustedProvenanceCapability(capability: TrustedProvenanceCapability | undefined): asserts capability is TrustedProvenanceCapability;
23
+ export declare function stripCallerProvenance<T extends Record<string, unknown>>(input: T): T;
24
+ export declare function sanitizePublicSaveMemoryInput(input: PublicSaveMemoryInput): PublicSaveMemoryInput;
25
+ export declare function sanitizePublicIngestMemoryInput(input: PublicIngestMemoryInput): PublicIngestMemoryInput;
26
+ export declare function sanitizePublicIngestConversationInput(input: PublicIngestConversationInput): PublicIngestConversationInput;
27
+ export declare function normalizeMemoryWriteProvenance(options?: TrustedMemoryWriteOptions): NormalizedMemoryProvenance;
28
+ export declare function appendProvenanceSourceRefs(options: TrustedMemoryWriteOptions | undefined, refs: string[]): TrustedMemoryWriteOptions | undefined;
29
+ //# sourceMappingURL=provenance.d.ts.map
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTrustedProvenanceCapability = createTrustedProvenanceCapability;
4
+ exports.assertTrustedProvenanceCapability = assertTrustedProvenanceCapability;
5
+ exports.stripCallerProvenance = stripCallerProvenance;
6
+ exports.sanitizePublicSaveMemoryInput = sanitizePublicSaveMemoryInput;
7
+ exports.sanitizePublicIngestMemoryInput = sanitizePublicIngestMemoryInput;
8
+ exports.sanitizePublicIngestConversationInput = sanitizePublicIngestConversationInput;
9
+ exports.normalizeMemoryWriteProvenance = normalizeMemoryWriteProvenance;
10
+ exports.appendProvenanceSourceRefs = appendProvenanceSourceRefs;
11
+ const issuedCapabilities = new WeakSet();
12
+ const ALLOWED_PROVENANCE_FIELDS = new Set([
13
+ 'actor',
14
+ 'agent_id',
15
+ 'model_run_id',
16
+ 'envelope_hash',
17
+ 'tool_name',
18
+ 'gateway_call_id',
19
+ 'context_packet_id',
20
+ 'source_turn_id',
21
+ 'source_message_ref',
22
+ 'source_refs',
23
+ ]);
24
+ function createTrustedProvenanceCapability() {
25
+ const capability = Object.freeze({
26
+ __trustedProvenanceCapability: 'mama-core',
27
+ });
28
+ issuedCapabilities.add(capability);
29
+ return capability;
30
+ }
31
+ function assertTrustedProvenanceCapability(capability) {
32
+ if (!capability || typeof capability !== 'object' || !issuedCapabilities.has(capability)) {
33
+ throw new Error('Invalid trusted provenance capability');
34
+ }
35
+ }
36
+ function stripCallerProvenance(input) {
37
+ if (!Object.prototype.hasOwnProperty.call(input, 'provenance')) {
38
+ return input;
39
+ }
40
+ const { provenance: _provenance, ...rest } = input;
41
+ return rest;
42
+ }
43
+ function sanitizePublicSaveMemoryInput(input) {
44
+ return stripCallerProvenance(input);
45
+ }
46
+ function sanitizePublicIngestMemoryInput(input) {
47
+ return stripCallerProvenance(input);
48
+ }
49
+ function sanitizePublicIngestConversationInput(input) {
50
+ return stripCallerProvenance(input);
51
+ }
52
+ function normalizeMemoryWriteProvenance(options) {
53
+ if (!options) {
54
+ return buildFallbackProvenance();
55
+ }
56
+ assertTrustedProvenanceCapability(options.capability);
57
+ const provenance = options.provenance ?? {};
58
+ const actor = provenance.actor ?? 'main_agent';
59
+ const sourceRefs = normalizeStringArray(provenance.source_refs);
60
+ const compact = {
61
+ actor,
62
+ };
63
+ for (const [key, value] of Object.entries(provenance)) {
64
+ if (!ALLOWED_PROVENANCE_FIELDS.has(key)) {
65
+ continue;
66
+ }
67
+ if (key === 'source_refs') {
68
+ compact.source_refs = sourceRefs;
69
+ continue;
70
+ }
71
+ if (isCompactValue(value)) {
72
+ compact[key] = value;
73
+ }
74
+ }
75
+ return {
76
+ actor,
77
+ agent_id: normalizeNullableString(provenance.agent_id),
78
+ model_run_id: normalizeNullableString(provenance.model_run_id),
79
+ envelope_hash: normalizeNullableString(provenance.envelope_hash),
80
+ tool_name: normalizeNullableString(provenance.tool_name),
81
+ gateway_call_id: normalizeNullableString(provenance.gateway_call_id),
82
+ source_turn_id: normalizeNullableString(provenance.source_turn_id),
83
+ source_message_ref: normalizeNullableString(provenance.source_message_ref),
84
+ source_refs: sourceRefs,
85
+ provenance: compact,
86
+ };
87
+ }
88
+ function appendProvenanceSourceRefs(options, refs) {
89
+ if (!options) {
90
+ return undefined;
91
+ }
92
+ assertTrustedProvenanceCapability(options.capability);
93
+ return {
94
+ capability: options.capability,
95
+ provenance: {
96
+ ...options.provenance,
97
+ source_refs: [...(options.provenance.source_refs ?? []), ...refs],
98
+ },
99
+ };
100
+ }
101
+ function buildFallbackProvenance() {
102
+ const actor = 'actor:direct_client';
103
+ return {
104
+ actor,
105
+ agent_id: null,
106
+ model_run_id: null,
107
+ envelope_hash: null,
108
+ tool_name: null,
109
+ gateway_call_id: null,
110
+ source_turn_id: null,
111
+ source_message_ref: null,
112
+ source_refs: [],
113
+ provenance: {
114
+ actor,
115
+ source_type: 'direct_client',
116
+ },
117
+ };
118
+ }
119
+ function normalizeNullableString(value) {
120
+ return typeof value === 'string' && value.length > 0 ? value : null;
121
+ }
122
+ function normalizeStringArray(value) {
123
+ if (!Array.isArray(value)) {
124
+ return [];
125
+ }
126
+ return value.filter((item) => typeof item === 'string' && item.length > 0);
127
+ }
128
+ function isCompactValue(value) {
129
+ if (value === null) {
130
+ return true;
131
+ }
132
+ if (['string', 'number', 'boolean'].includes(typeof value)) {
133
+ return true;
134
+ }
135
+ return Array.isArray(value) && value.every((item) => typeof item === 'string');
136
+ }
137
+ //# sourceMappingURL=provenance.js.map
@@ -0,0 +1,17 @@
1
+ import { type DatabaseAdapter } from '../db-manager.js';
2
+ export interface BackfillResult {
3
+ scanned: number;
4
+ updated: number;
5
+ }
6
+ export interface ConnectorEventScopeBackfillInput {
7
+ source_connector?: string;
8
+ source_id?: string;
9
+ source_cursor?: string;
10
+ tenant_id?: string;
11
+ project_id?: string;
12
+ memory_scope_kind?: string;
13
+ memory_scope_id?: string;
14
+ }
15
+ export declare function backfillLegacyMemoryProvenance(adapter?: DatabaseAdapter | null): Promise<BackfillResult>;
16
+ export declare function backfillConnectorEventScopeMetadata(input: ConnectorEventScopeBackfillInput, adapter?: DatabaseAdapter | null): Promise<BackfillResult>;
17
+ //# sourceMappingURL=scope-backfill.d.ts.map
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.backfillLegacyMemoryProvenance = backfillLegacyMemoryProvenance;
4
+ exports.backfillConnectorEventScopeMetadata = backfillConnectorEventScopeMetadata;
5
+ const db_manager_js_1 = require("../db-manager.js");
6
+ const LEGACY_PROVENANCE_JSON = JSON.stringify({
7
+ actor: 'actor:legacy',
8
+ source_type: 'legacy',
9
+ });
10
+ async function backfillLegacyMemoryProvenance(adapter = null) {
11
+ await (0, db_manager_js_1.initDB)();
12
+ const db = adapter ?? (0, db_manager_js_1.getAdapter)();
13
+ const row = db
14
+ .prepare(`
15
+ SELECT COUNT(*) AS count
16
+ FROM decisions
17
+ WHERE provenance_json IS NULL
18
+ `)
19
+ .get();
20
+ const result = db
21
+ .prepare(`
22
+ UPDATE decisions
23
+ SET
24
+ source_refs_json = COALESCE(source_refs_json, '[]'),
25
+ provenance_json = ?
26
+ WHERE provenance_json IS NULL
27
+ `)
28
+ .run(LEGACY_PROVENANCE_JSON);
29
+ return {
30
+ scanned: row.count,
31
+ updated: result.changes,
32
+ };
33
+ }
34
+ async function backfillConnectorEventScopeMetadata(input, adapter = null) {
35
+ await (0, db_manager_js_1.initDB)();
36
+ const db = adapter ?? (0, db_manager_js_1.getAdapter)();
37
+ const assignments = [];
38
+ const assignmentParams = [];
39
+ for (const column of [
40
+ 'source_cursor',
41
+ 'tenant_id',
42
+ 'project_id',
43
+ 'memory_scope_kind',
44
+ 'memory_scope_id',
45
+ ]) {
46
+ const value = input[column];
47
+ if (value !== undefined) {
48
+ assignments.push(`${column} = COALESCE(${column}, ?)`);
49
+ assignmentParams.push(value);
50
+ }
51
+ }
52
+ if (assignments.length === 0) {
53
+ return { scanned: 0, updated: 0 };
54
+ }
55
+ const where = [];
56
+ const whereParams = [];
57
+ if (input.source_connector !== undefined) {
58
+ where.push('source_connector = ?');
59
+ whereParams.push(input.source_connector);
60
+ }
61
+ if (input.source_id !== undefined) {
62
+ where.push('source_id = ?');
63
+ whereParams.push(input.source_id);
64
+ }
65
+ const whereSql = where.length > 0 ? ` WHERE ${where.join(' AND ')}` : '';
66
+ const scanned = db
67
+ .prepare(`SELECT COUNT(*) AS count FROM connector_event_index${whereSql}`)
68
+ .get(...whereParams);
69
+ const result = db
70
+ .prepare(`UPDATE connector_event_index SET ${assignments.join(', ')}${whereSql}`)
71
+ .run(...assignmentParams, ...whereParams);
72
+ return {
73
+ scanned: scanned.count,
74
+ updated: result.changes,
75
+ };
76
+ }
77
+ //# sourceMappingURL=scope-backfill.js.map