@jungjaehoon/mama-core 1.8.1 → 2.0.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.
- package/dist/agent-graph/alias-write.js +3 -0
- package/dist/agent-graph/entity-resolve.js +3 -7
- package/dist/agent-graph/graph-query.js +5 -4
- package/dist/agent-graph/types.d.ts +30 -0
- package/dist/cases/store.d.ts +0 -4
- package/dist/cases/store.js +0 -66
- package/dist/cases/wiki-page-index.d.ts +0 -13
- package/dist/cases/wiki-page-index.js +0 -153
- package/dist/connectors/event-index.d.ts +1 -22
- package/dist/connectors/event-index.js +0 -157
- package/dist/context-compile/channel-grant.d.ts +46 -0
- package/dist/context-compile/channel-grant.js +66 -0
- package/dist/context-compile/compiler.js +5 -2
- package/dist/context-compile/index.d.ts +1 -0
- package/dist/context-compile/index.js +1 -0
- package/dist/context-compile/packet-store.d.ts +0 -1
- package/dist/context-compile/packet-store.js +0 -16
- package/dist/context-compile/source-readers.d.ts +1 -0
- package/dist/context-compile/source-readers.js +156 -23
- package/dist/context-compile/types.d.ts +17 -0
- package/dist/context-compile/visibility.js +28 -4
- package/dist/db-adapter/node-sqlite-adapter.js +4 -0
- package/dist/db-manager.d.ts +0 -13
- package/dist/db-manager.js +0 -66
- package/dist/decision-formatter.d.ts +0 -11
- package/dist/decision-formatter.js +0 -122
- package/dist/decision-tracker.d.ts +0 -12
- package/dist/decision-tracker.js +0 -50
- package/dist/edges/ref-validation.d.ts +1 -2
- package/dist/edges/ref-validation.js +33 -13
- package/dist/edges/store.d.ts +1 -3
- package/dist/edges/store.js +0 -214
- package/dist/edges/types.d.ts +10 -0
- package/dist/embedding-client.d.ts +0 -17
- package/dist/embedding-client.js +0 -80
- package/dist/embedding-server/mobile/auth.d.ts +1 -10
- package/dist/embedding-server/mobile/auth.js +0 -15
- package/dist/embeddings.d.ts +0 -12
- package/dist/embeddings.js +0 -68
- package/dist/entities/audit-metrics.d.ts +0 -5
- package/dist/entities/audit-metrics.js +0 -4
- package/dist/entities/candidate-generator.d.ts +1 -2
- package/dist/entities/candidate-generator.js +0 -412
- package/dist/entities/entity-list.d.ts +0 -1
- package/dist/entities/entity-list.js +0 -96
- package/dist/entities/entity-orphan-list.d.ts +0 -9
- package/dist/entities/entity-orphan-list.js +0 -88
- package/dist/entities/entity-search.d.ts +0 -1
- package/dist/entities/entity-search.js +0 -147
- package/dist/entities/errors.d.ts +0 -10
- package/dist/entities/errors.js +1 -25
- package/dist/entities/lineage-store.d.ts +0 -23
- package/dist/entities/lineage-store.js +0 -104
- package/dist/entities/policy-store.d.ts +0 -9
- package/dist/entities/policy-store.js +0 -188
- package/dist/entities/provenance-query.d.ts +0 -1
- package/dist/entities/provenance-query.js +0 -164
- package/dist/entities/resolution-engine.d.ts +1 -8
- package/dist/entities/resolution-engine.js +0 -66
- package/dist/entities/rollback-preview.d.ts +0 -4
- package/dist/entities/rollback-preview.js +0 -232
- package/dist/entities/store.d.ts +1 -10
- package/dist/entities/store.js +0 -49
- package/dist/index.d.ts +15 -31
- package/dist/index.js +4 -46
- package/dist/mama-api.d.ts +19 -1
- package/dist/mama-api.js +97 -2
- package/dist/memory/api.d.ts +9 -0
- package/dist/memory/api.js +68 -4
- package/dist/memory/event-store.d.ts +0 -1
- package/dist/memory/event-store.js +0 -15
- package/dist/memory/finding-store.d.ts +0 -1
- package/dist/memory/finding-store.js +0 -12
- package/dist/memory/scope-backfill.d.ts +0 -3
- package/dist/memory/scope-backfill.js +0 -74
- package/dist/memory/scope-store.d.ts +0 -1
- package/dist/memory/scope-store.js +0 -4
- package/dist/memory/truth-store.d.ts +0 -3
- package/dist/memory/truth-store.js +0 -22
- package/dist/memory/types.d.ts +0 -1
- package/dist/memory/types.js +0 -13
- package/dist/memory-store.d.ts +0 -16
- package/dist/memory-store.js +0 -51
- package/dist/ollama-client.d.ts +0 -9
- package/dist/ollama-client.js +0 -125
- package/dist/outcome-tracker.d.ts +0 -14
- package/dist/outcome-tracker.js +0 -44
- package/dist/progress-indicator.d.ts +0 -4
- package/dist/progress-indicator.js +0 -7
- package/dist/provenance/source-ref.d.ts +0 -9
- package/dist/provenance/source-ref.js +0 -145
- package/dist/query-intent.d.ts +0 -4
- package/dist/query-intent.js +0 -30
- package/dist/relevance-scorer.d.ts +0 -9
- package/dist/relevance-scorer.js +0 -81
- package/dist/search/feedback-store.d.ts +0 -1
- package/dist/search/feedback-store.js +0 -4
- package/dist/search/ranker-rescore.d.ts +0 -3
- package/dist/search/ranker-rescore.js +0 -27
- package/dist/search/ranker-trainer.d.ts +0 -8
- package/dist/search/ranker-trainer.js +0 -376
- package/dist/tier-validator.d.ts +0 -12
- package/dist/tier-validator.js +0 -56
- package/package.json +1 -10
- package/dist/cases/case-links.d.ts +0 -116
- package/dist/cases/case-links.js +0 -794
- package/dist/cases/composition-overrides.d.ts +0 -90
- package/dist/cases/composition-overrides.js +0 -724
- package/dist/cases/corrections.d.ts +0 -156
- package/dist/cases/corrections.js +0 -1045
- package/dist/cases/freshness.d.ts +0 -57
- package/dist/cases/freshness.js +0 -283
- package/dist/cases/live-state.d.ts +0 -48
- package/dist/cases/live-state.js +0 -256
- package/dist/cases/membership-explain.d.ts +0 -56
- package/dist/cases/membership-explain.js +0 -140
- package/dist/cases/membership-matcher.d.ts +0 -23
- package/dist/cases/membership-matcher.js +0 -193
- package/dist/cases/merge-split.d.ts +0 -61
- package/dist/cases/merge-split.js +0 -368
- package/dist/cases/role-inference.d.ts +0 -10
- package/dist/cases/role-inference.js +0 -85
- package/dist/cases/sqlite-transaction.d.ts +0 -10
- package/dist/cases/sqlite-transaction.js +0 -62
- package/dist/cases/target-ref.d.ts +0 -25
- package/dist/cases/target-ref.js +0 -22
- package/dist/cases/tombstone-sweeper.d.ts +0 -13
- package/dist/cases/tombstone-sweeper.js +0 -128
- package/dist/entities/entity-impact.d.ts +0 -41
- package/dist/entities/entity-impact.js +0 -140
- package/dist/entities/exact-merge-backfill.d.ts +0 -11
- package/dist/entities/exact-merge-backfill.js +0 -161
- package/dist/entities/lineage-backfill.d.ts +0 -12
- package/dist/entities/lineage-backfill.js +0 -101
- package/dist/memory-inject.d.ts +0 -24
- package/dist/memory-inject.js +0 -116
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sweepStaleCaseMemberships = sweepStaleCaseMemberships;
|
|
4
|
-
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
const canonicalize_js_1 = require("../canonicalize.js");
|
|
6
|
-
const sqlite_transaction_js_1 = require("./sqlite-transaction.js");
|
|
7
|
-
const SWEEP_SOURCE_TYPES = ['decision', 'event', 'observation'];
|
|
8
|
-
const SOURCE_EXISTS_SQL = {
|
|
9
|
-
decision: 'SELECT 1 AS id FROM decisions WHERE id = ?',
|
|
10
|
-
event: 'SELECT 1 AS id FROM entity_timeline_events WHERE id = ?',
|
|
11
|
-
observation: 'SELECT 1 AS id FROM entity_observations WHERE id = ?',
|
|
12
|
-
};
|
|
13
|
-
function normalizeNow(value) {
|
|
14
|
-
return value ?? new Date().toISOString();
|
|
15
|
-
}
|
|
16
|
-
function createdAtMs(now) {
|
|
17
|
-
const parsed = Date.parse(now);
|
|
18
|
-
return Number.isFinite(parsed) ? parsed : Date.now();
|
|
19
|
-
}
|
|
20
|
-
function isSweptSourceType(value) {
|
|
21
|
-
return SWEEP_SOURCE_TYPES.includes(value);
|
|
22
|
-
}
|
|
23
|
-
function readCandidates(adapter, limit) {
|
|
24
|
-
const sql = `
|
|
25
|
-
SELECT source_type, source_id
|
|
26
|
-
FROM case_memberships
|
|
27
|
-
WHERE status IN ('active', 'candidate', 'removed', 'excluded')
|
|
28
|
-
AND source_type IN ('decision', 'event', 'observation')
|
|
29
|
-
GROUP BY source_type, source_id
|
|
30
|
-
ORDER BY source_type ASC, source_id ASC
|
|
31
|
-
${limit === undefined ? '' : 'LIMIT ?'}
|
|
32
|
-
`;
|
|
33
|
-
const stmt = adapter.prepare(sql);
|
|
34
|
-
return (limit === undefined ? stmt.all() : stmt.all(limit));
|
|
35
|
-
}
|
|
36
|
-
function sourceExists(adapter, sourceType, sourceId) {
|
|
37
|
-
const row = adapter.prepare(SOURCE_EXISTS_SQL[sourceType]).get(sourceId);
|
|
38
|
-
return row !== undefined;
|
|
39
|
-
}
|
|
40
|
-
function countTransitionTargets(adapter, sourceType, sourceId) {
|
|
41
|
-
return adapter
|
|
42
|
-
.prepare(`
|
|
43
|
-
SELECT COUNT(*) AS count,
|
|
44
|
-
SUM(CASE WHEN user_locked = 1 THEN 1 ELSE 0 END) AS locked_count
|
|
45
|
-
FROM case_memberships
|
|
46
|
-
WHERE status <> 'stale'
|
|
47
|
-
AND source_type = ?
|
|
48
|
-
AND source_id = ?
|
|
49
|
-
`)
|
|
50
|
-
.get(sourceType, sourceId);
|
|
51
|
-
}
|
|
52
|
-
function markSourceStale(adapter, sourceType, sourceId, now) {
|
|
53
|
-
const result = adapter
|
|
54
|
-
.prepare(`
|
|
55
|
-
UPDATE case_memberships
|
|
56
|
-
SET status = 'stale',
|
|
57
|
-
updated_at = ?
|
|
58
|
-
WHERE status <> 'stale'
|
|
59
|
-
AND source_type = ?
|
|
60
|
-
AND source_id = ?
|
|
61
|
-
AND NOT EXISTS (${SOURCE_EXISTS_SQL[sourceType]})
|
|
62
|
-
`)
|
|
63
|
-
.run(now, sourceType, sourceId, sourceId);
|
|
64
|
-
return result.changes;
|
|
65
|
-
}
|
|
66
|
-
function insertTombstoneAuditEvent(input) {
|
|
67
|
-
const eventId = `me_${(0, node_crypto_1.randomUUID)()}`;
|
|
68
|
-
input.adapter
|
|
69
|
-
.prepare(`
|
|
70
|
-
INSERT INTO memory_events (
|
|
71
|
-
event_id, event_type, actor, source_turn_id, memory_id, topic,
|
|
72
|
-
scope_refs, evidence_refs, reason, created_at
|
|
73
|
-
)
|
|
74
|
-
VALUES (?, 'case.membership_tombstoned', 'system', NULL, NULL, ?, ?, ?, ?, ?)
|
|
75
|
-
`)
|
|
76
|
-
.run(eventId, 'case:tombstone-sweeper', (0, canonicalize_js_1.canonicalizeJSON)([{ kind: 'project', id: 'case-first' }]), (0, canonicalize_js_1.canonicalizeJSON)(input.sources), (0, canonicalize_js_1.canonicalizeJSON)({
|
|
77
|
-
stale_count: input.stale_count,
|
|
78
|
-
locked_stale_count: input.locked_stale_count,
|
|
79
|
-
}), createdAtMs(input.now));
|
|
80
|
-
return eventId;
|
|
81
|
-
}
|
|
82
|
-
function sweepStaleCaseMemberships(adapter, options = {}) {
|
|
83
|
-
const sweepAdapter = adapter;
|
|
84
|
-
return (0, sqlite_transaction_js_1.runImmediateTransaction)(sweepAdapter, () => {
|
|
85
|
-
const now = normalizeNow(options.now);
|
|
86
|
-
const candidates = readCandidates(sweepAdapter, options.limit);
|
|
87
|
-
let staleCount = 0;
|
|
88
|
-
let lockedStaleCount = 0;
|
|
89
|
-
const tombstonedSources = [];
|
|
90
|
-
for (const candidate of candidates) {
|
|
91
|
-
if (!isSweptSourceType(candidate.source_type)) {
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
if (sourceExists(sweepAdapter, candidate.source_type, candidate.source_id)) {
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
const before = countTransitionTargets(sweepAdapter, candidate.source_type, candidate.source_id);
|
|
98
|
-
if (before.count === 0) {
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
const changes = markSourceStale(sweepAdapter, candidate.source_type, candidate.source_id, now);
|
|
102
|
-
if (changes === 0) {
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
staleCount += changes;
|
|
106
|
-
lockedStaleCount += Math.min(changes, before.locked_count ?? 0);
|
|
107
|
-
tombstonedSources.push(candidate);
|
|
108
|
-
}
|
|
109
|
-
const auditEventIds = staleCount > 0
|
|
110
|
-
? [
|
|
111
|
-
insertTombstoneAuditEvent({
|
|
112
|
-
adapter: sweepAdapter,
|
|
113
|
-
now,
|
|
114
|
-
stale_count: staleCount,
|
|
115
|
-
locked_stale_count: lockedStaleCount,
|
|
116
|
-
sources: tombstonedSources,
|
|
117
|
-
}),
|
|
118
|
-
]
|
|
119
|
-
: [];
|
|
120
|
-
return {
|
|
121
|
-
scanned_count: candidates.length,
|
|
122
|
-
stale_count: staleCount,
|
|
123
|
-
locked_stale_count: lockedStaleCount,
|
|
124
|
-
audit_event_ids: auditEventIds,
|
|
125
|
-
};
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
//# sourceMappingURL=tombstone-sweeper.js.map
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { type SourceLocatorKind } from './source-locator.js';
|
|
2
|
-
import type { EntityIngestRun, EntityLineageLink, EntityNode } from './types.js';
|
|
3
|
-
interface InspectorDetail {
|
|
4
|
-
entity: EntityNode;
|
|
5
|
-
history_incomplete: boolean;
|
|
6
|
-
}
|
|
7
|
-
interface InspectorLineageRow extends EntityLineageLink {
|
|
8
|
-
source_connector: string;
|
|
9
|
-
source_raw_record_id: string;
|
|
10
|
-
source_locator: string | null;
|
|
11
|
-
source_locator_kind: SourceLocatorKind;
|
|
12
|
-
surface_form: string;
|
|
13
|
-
}
|
|
14
|
-
interface InspectorLineageResult {
|
|
15
|
-
rows: InspectorLineageRow[];
|
|
16
|
-
history_incomplete: boolean;
|
|
17
|
-
}
|
|
18
|
-
interface ImpactMemoryRow {
|
|
19
|
-
id: string;
|
|
20
|
-
topic: string;
|
|
21
|
-
summary: string;
|
|
22
|
-
created_at: number;
|
|
23
|
-
}
|
|
24
|
-
interface ImpactAuditRunRow {
|
|
25
|
-
id: string;
|
|
26
|
-
classification: string | null;
|
|
27
|
-
status: string;
|
|
28
|
-
created_at: number;
|
|
29
|
-
completed_at: number | null;
|
|
30
|
-
}
|
|
31
|
-
interface EntityImpactResult {
|
|
32
|
-
related_memories: ImpactMemoryRow[];
|
|
33
|
-
ingest_runs: EntityIngestRun[];
|
|
34
|
-
audit_runs: ImpactAuditRunRow[];
|
|
35
|
-
}
|
|
36
|
-
export declare function getEntityInspectorDetail(entityId: string): Promise<InspectorDetail>;
|
|
37
|
-
export declare function listEntityLineageForInspector(entityId: string, limit?: number): Promise<InspectorLineageResult>;
|
|
38
|
-
export declare function getEntityImpact(entityId: string): Promise<EntityImpactResult>;
|
|
39
|
-
export declare function getEntityIngestRun(runId: string): Promise<EntityIngestRun | null>;
|
|
40
|
-
export {};
|
|
41
|
-
//# sourceMappingURL=entity-impact.d.ts.map
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getEntityInspectorDetail = getEntityInspectorDetail;
|
|
4
|
-
exports.listEntityLineageForInspector = listEntityLineageForInspector;
|
|
5
|
-
exports.getEntityImpact = getEntityImpact;
|
|
6
|
-
exports.getEntityIngestRun = getEntityIngestRun;
|
|
7
|
-
const db_manager_js_1 = require("../db-manager.js");
|
|
8
|
-
const source_locator_js_1 = require("./source-locator.js");
|
|
9
|
-
const lineage_store_js_1 = require("./lineage-store.js");
|
|
10
|
-
function mapEntityNode(row) {
|
|
11
|
-
return {
|
|
12
|
-
id: String(row.id),
|
|
13
|
-
kind: row.kind,
|
|
14
|
-
preferred_label: String(row.preferred_label),
|
|
15
|
-
status: row.status,
|
|
16
|
-
scope_kind: typeof row.scope_kind === 'string' ? row.scope_kind : null,
|
|
17
|
-
scope_id: typeof row.scope_id === 'string' ? row.scope_id : null,
|
|
18
|
-
merged_into: typeof row.merged_into === 'string' ? row.merged_into : null,
|
|
19
|
-
created_at: Number(row.created_at),
|
|
20
|
-
updated_at: Number(row.updated_at),
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
async function getEntityInspectorDetail(entityId) {
|
|
24
|
-
await (0, db_manager_js_1.initDB)();
|
|
25
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
26
|
-
const row = adapter.prepare(`SELECT * FROM entity_nodes WHERE id = ?`).get(entityId);
|
|
27
|
-
if (!row) {
|
|
28
|
-
throw new Error(`Entity not found: ${entityId}`);
|
|
29
|
-
}
|
|
30
|
-
const lineageCount = adapter
|
|
31
|
-
.prepare(`
|
|
32
|
-
SELECT COUNT(*) AS total
|
|
33
|
-
FROM entity_lineage_links
|
|
34
|
-
WHERE canonical_entity_id = ?
|
|
35
|
-
AND status = 'active'
|
|
36
|
-
`)
|
|
37
|
-
.get(entityId);
|
|
38
|
-
return {
|
|
39
|
-
entity: mapEntityNode(row),
|
|
40
|
-
history_incomplete: lineageCount.total === 0,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
async function listEntityLineageForInspector(entityId, limit = 50) {
|
|
44
|
-
await (0, db_manager_js_1.initDB)();
|
|
45
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
46
|
-
const safeLimit = Math.max(1, Math.min(limit, 500));
|
|
47
|
-
const rows = adapter
|
|
48
|
-
.prepare(`
|
|
49
|
-
SELECT
|
|
50
|
-
l.*,
|
|
51
|
-
o.source_connector,
|
|
52
|
-
o.source_raw_record_id,
|
|
53
|
-
o.source_locator,
|
|
54
|
-
o.surface_form
|
|
55
|
-
FROM entity_lineage_links l
|
|
56
|
-
JOIN entity_observations o ON o.id = l.entity_observation_id
|
|
57
|
-
WHERE l.canonical_entity_id = ?
|
|
58
|
-
AND l.status = 'active'
|
|
59
|
-
ORDER BY l.created_at ASC
|
|
60
|
-
LIMIT ?
|
|
61
|
-
`)
|
|
62
|
-
.all(entityId, safeLimit);
|
|
63
|
-
return {
|
|
64
|
-
rows: rows.map((row) => ({
|
|
65
|
-
id: String(row.id),
|
|
66
|
-
canonical_entity_id: String(row.canonical_entity_id),
|
|
67
|
-
entity_observation_id: String(row.entity_observation_id),
|
|
68
|
-
source_entity_id: typeof row.source_entity_id === 'string' ? row.source_entity_id : null,
|
|
69
|
-
contribution_kind: row.contribution_kind,
|
|
70
|
-
run_id: typeof row.run_id === 'string' ? row.run_id : null,
|
|
71
|
-
candidate_id: typeof row.candidate_id === 'string' ? row.candidate_id : null,
|
|
72
|
-
review_action_id: typeof row.review_action_id === 'string' ? row.review_action_id : null,
|
|
73
|
-
status: row.status,
|
|
74
|
-
capture_mode: row.capture_mode,
|
|
75
|
-
confidence: Number(row.confidence),
|
|
76
|
-
created_at: Number(row.created_at),
|
|
77
|
-
superseded_at: typeof row.superseded_at === 'number' ? row.superseded_at : null,
|
|
78
|
-
source_connector: String(row.source_connector),
|
|
79
|
-
source_raw_record_id: String(row.source_raw_record_id),
|
|
80
|
-
source_locator: typeof row.source_locator === 'string' ? row.source_locator : null,
|
|
81
|
-
source_locator_kind: (0, source_locator_js_1.detectSourceLocatorKind)(typeof row.source_locator === 'string' ? row.source_locator : null),
|
|
82
|
-
surface_form: String(row.surface_form),
|
|
83
|
-
})),
|
|
84
|
-
history_incomplete: rows.length === 0,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
async function getEntityImpact(entityId) {
|
|
88
|
-
await (0, db_manager_js_1.initDB)();
|
|
89
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
90
|
-
const relatedMemories = adapter
|
|
91
|
-
.prepare(`
|
|
92
|
-
SELECT DISTINCT d.id, d.topic, d.summary, d.created_at
|
|
93
|
-
FROM entity_lineage_links l
|
|
94
|
-
JOIN decision_entity_sources des ON des.entity_observation_id = l.entity_observation_id
|
|
95
|
-
JOIN decisions d ON d.id = des.decision_id
|
|
96
|
-
WHERE l.canonical_entity_id = ?
|
|
97
|
-
AND l.status = 'active'
|
|
98
|
-
ORDER BY d.created_at DESC
|
|
99
|
-
`)
|
|
100
|
-
.all(entityId);
|
|
101
|
-
const ingestRuns = adapter
|
|
102
|
-
.prepare(`
|
|
103
|
-
SELECT DISTINCT ir.*
|
|
104
|
-
FROM entity_lineage_links l
|
|
105
|
-
JOIN entity_ingest_runs ir ON ir.id = l.run_id
|
|
106
|
-
WHERE l.canonical_entity_id = ?
|
|
107
|
-
AND l.status = 'active'
|
|
108
|
-
ORDER BY ir.created_at DESC
|
|
109
|
-
`)
|
|
110
|
-
.all(entityId);
|
|
111
|
-
const auditRuns = adapter
|
|
112
|
-
.prepare(`
|
|
113
|
-
SELECT DISTINCT ar.id, ar.classification, ar.status, ar.created_at, ar.completed_at
|
|
114
|
-
FROM entity_lineage_links l
|
|
115
|
-
JOIN entity_ingest_runs ir ON ir.id = l.run_id
|
|
116
|
-
JOIN entity_audit_runs ar ON ar.id = ir.audit_run_id
|
|
117
|
-
WHERE l.canonical_entity_id = ?
|
|
118
|
-
AND l.status = 'active'
|
|
119
|
-
ORDER BY ar.created_at DESC
|
|
120
|
-
LIMIT 10
|
|
121
|
-
`)
|
|
122
|
-
.all(entityId);
|
|
123
|
-
return {
|
|
124
|
-
related_memories: relatedMemories.map((row) => ({
|
|
125
|
-
id: row.id,
|
|
126
|
-
topic: row.topic,
|
|
127
|
-
summary: row.summary ?? row.topic,
|
|
128
|
-
created_at: row.created_at,
|
|
129
|
-
})),
|
|
130
|
-
ingest_runs: ingestRuns.map(lineage_store_js_1.parseEntityIngestRunRow),
|
|
131
|
-
audit_runs: auditRuns,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
async function getEntityIngestRun(runId) {
|
|
135
|
-
await (0, db_manager_js_1.initDB)();
|
|
136
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
137
|
-
const row = adapter.prepare(`SELECT * FROM entity_ingest_runs WHERE id = ?`).get(runId);
|
|
138
|
-
return row ? (0, lineage_store_js_1.parseEntityIngestRunRow)(row) : null;
|
|
139
|
-
}
|
|
140
|
-
//# sourceMappingURL=entity-impact.js.map
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export interface ExactMergeBackfillOptions {
|
|
2
|
-
dryRun?: boolean;
|
|
3
|
-
}
|
|
4
|
-
export interface ExactMergeBackfillResult {
|
|
5
|
-
groups: number;
|
|
6
|
-
merged: number;
|
|
7
|
-
incomplete: number;
|
|
8
|
-
skipped: number;
|
|
9
|
-
}
|
|
10
|
-
export declare function backfillExactDuplicateCanonicals(opts?: ExactMergeBackfillOptions): Promise<ExactMergeBackfillResult>;
|
|
11
|
-
//# sourceMappingURL=exact-merge-backfill.d.ts.map
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.backfillExactDuplicateCanonicals = backfillExactDuplicateCanonicals;
|
|
4
|
-
const db_manager_js_1 = require("../db-manager.js");
|
|
5
|
-
const store_js_1 = require("./store.js");
|
|
6
|
-
const lineage_store_js_1 = require("./lineage-store.js");
|
|
7
|
-
function normalizeExactLabel(input) {
|
|
8
|
-
return input.normalize('NFKC').trim().replace(/\s+/gu, ' ').toLowerCase();
|
|
9
|
-
}
|
|
10
|
-
function buildExactGroupKey(row) {
|
|
11
|
-
if (row.normalized_form) {
|
|
12
|
-
return {
|
|
13
|
-
key: JSON.stringify([row.kind, row.scope_kind, row.scope_id ?? '', row.normalized_form]),
|
|
14
|
-
fromObservation: true,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
const fallback = normalizeExactLabel(row.preferred_label);
|
|
18
|
-
if (!fallback) {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
return {
|
|
22
|
-
key: JSON.stringify([row.kind, row.scope_kind, row.scope_id ?? '', fallback]),
|
|
23
|
-
fromObservation: false,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
function compareRows(left, right) {
|
|
27
|
-
if (left.created_at !== right.created_at) {
|
|
28
|
-
return left.created_at - right.created_at;
|
|
29
|
-
}
|
|
30
|
-
return left.id.localeCompare(right.id);
|
|
31
|
-
}
|
|
32
|
-
function runAdapterTransaction(adapter, fn) {
|
|
33
|
-
const result = adapter.transaction(fn);
|
|
34
|
-
return typeof result === 'function' ? result() : result;
|
|
35
|
-
}
|
|
36
|
-
function requireTransactionAdapter(adapter) {
|
|
37
|
-
if (!('transaction' in adapter) || typeof adapter.transaction !== 'function') {
|
|
38
|
-
throw new Error('exact-merge-backfill requires adapter.transaction');
|
|
39
|
-
}
|
|
40
|
-
return adapter;
|
|
41
|
-
}
|
|
42
|
-
function mergeAndAdoptLineage(input) {
|
|
43
|
-
const mergeResult = (0, store_js_1.mergeEntityNodes)({
|
|
44
|
-
adapter: input.adapter,
|
|
45
|
-
source_id: input.source.id,
|
|
46
|
-
target_id: input.target.id,
|
|
47
|
-
actor_type: 'system',
|
|
48
|
-
actor_id: 'exact-duplicate-backfill',
|
|
49
|
-
reason: 'Exact duplicate canonical backfill',
|
|
50
|
-
candidate_id: null,
|
|
51
|
-
evidence_json: JSON.stringify({
|
|
52
|
-
strategy: 'exact_duplicate_backfill',
|
|
53
|
-
group_key: input.groupKey,
|
|
54
|
-
normalized_form: input.source.normalized_form,
|
|
55
|
-
target_id: input.target.id,
|
|
56
|
-
}),
|
|
57
|
-
});
|
|
58
|
-
(0, lineage_store_js_1.adoptLineageAfterMergeSync)({
|
|
59
|
-
adapter: input.adapter,
|
|
60
|
-
source_entity_id: input.source.id,
|
|
61
|
-
target_entity_id: input.target.id,
|
|
62
|
-
candidate_id: null,
|
|
63
|
-
review_action_id: mergeResult.merge_action_id,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
async function backfillExactDuplicateCanonicals(opts = {}) {
|
|
67
|
-
await (0, db_manager_js_1.initDB)();
|
|
68
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
69
|
-
const dryRun = opts.dryRun === true;
|
|
70
|
-
let groups = 0;
|
|
71
|
-
let merged = 0;
|
|
72
|
-
let incomplete = 0;
|
|
73
|
-
let skipped = 0;
|
|
74
|
-
const rows = adapter
|
|
75
|
-
.prepare(`
|
|
76
|
-
SELECT
|
|
77
|
-
n.id,
|
|
78
|
-
n.kind,
|
|
79
|
-
n.preferred_label,
|
|
80
|
-
n.scope_kind,
|
|
81
|
-
n.scope_id,
|
|
82
|
-
n.created_at,
|
|
83
|
-
MIN(o.normalized_form) AS normalized_form
|
|
84
|
-
FROM entity_nodes n
|
|
85
|
-
LEFT JOIN entity_lineage_links l
|
|
86
|
-
ON l.canonical_entity_id = n.id
|
|
87
|
-
AND l.status = 'active'
|
|
88
|
-
LEFT JOIN entity_observations o
|
|
89
|
-
ON o.id = l.entity_observation_id
|
|
90
|
-
WHERE n.status = 'active'
|
|
91
|
-
AND n.merged_into IS NULL
|
|
92
|
-
GROUP BY n.id, n.kind, n.preferred_label, n.scope_kind, n.scope_id, n.created_at
|
|
93
|
-
`)
|
|
94
|
-
.all();
|
|
95
|
-
const grouped = new Map();
|
|
96
|
-
const fallbackRows = new Set();
|
|
97
|
-
for (const row of rows) {
|
|
98
|
-
const keyInfo = buildExactGroupKey(row);
|
|
99
|
-
if (!keyInfo) {
|
|
100
|
-
incomplete += 1;
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
if (!keyInfo.fromObservation) {
|
|
104
|
-
fallbackRows.add(row.id);
|
|
105
|
-
}
|
|
106
|
-
const bucket = grouped.get(keyInfo.key) ?? [];
|
|
107
|
-
bucket.push(row);
|
|
108
|
-
grouped.set(keyInfo.key, bucket);
|
|
109
|
-
}
|
|
110
|
-
for (const bucket of grouped.values()) {
|
|
111
|
-
if (bucket.length >= 2) {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
for (const row of bucket) {
|
|
115
|
-
if (fallbackRows.has(row.id)) {
|
|
116
|
-
incomplete += 1;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
for (const [groupKey, bucket] of grouped.entries()) {
|
|
121
|
-
if (bucket.length < 2) {
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
groups += 1;
|
|
125
|
-
const sorted = [...bucket].sort(compareRows);
|
|
126
|
-
const target = sorted[0];
|
|
127
|
-
const sources = sorted.slice(1);
|
|
128
|
-
if (dryRun) {
|
|
129
|
-
merged += sources.length;
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
try {
|
|
133
|
-
const transactionalAdapter = requireTransactionAdapter(adapter);
|
|
134
|
-
runAdapterTransaction(transactionalAdapter, () => {
|
|
135
|
-
for (const source of sources) {
|
|
136
|
-
mergeAndAdoptLineage({
|
|
137
|
-
adapter,
|
|
138
|
-
source,
|
|
139
|
-
target,
|
|
140
|
-
groupKey,
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
merged += sources.length;
|
|
145
|
-
}
|
|
146
|
-
catch (error) {
|
|
147
|
-
if (error instanceof store_js_1.EntityMergeError) {
|
|
148
|
-
skipped += sources.length;
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
throw error;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return {
|
|
155
|
-
groups,
|
|
156
|
-
merged,
|
|
157
|
-
incomplete,
|
|
158
|
-
skipped,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
//# sourceMappingURL=exact-merge-backfill.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
interface BackfillEntityLineageOptions {
|
|
2
|
-
dryRun?: boolean;
|
|
3
|
-
now?: number;
|
|
4
|
-
}
|
|
5
|
-
interface BackfillEntityLineageResult {
|
|
6
|
-
seeded: number;
|
|
7
|
-
adopted: number;
|
|
8
|
-
incomplete: number;
|
|
9
|
-
}
|
|
10
|
-
export declare function backfillEntityLineage(opts?: BackfillEntityLineageOptions): Promise<BackfillEntityLineageResult>;
|
|
11
|
-
export {};
|
|
12
|
-
//# sourceMappingURL=lineage-backfill.d.ts.map
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.backfillEntityLineage = backfillEntityLineage;
|
|
4
|
-
const db_manager_js_1 = require("../db-manager.js");
|
|
5
|
-
const lineage_store_js_1 = require("./lineage-store.js");
|
|
6
|
-
async function backfillEntityLineage(opts = {}) {
|
|
7
|
-
await (0, db_manager_js_1.initDB)();
|
|
8
|
-
const adapter = (0, db_manager_js_1.getAdapter)();
|
|
9
|
-
const dryRun = opts.dryRun === true;
|
|
10
|
-
const seedConfidence = 0.75;
|
|
11
|
-
const adoptConfidence = 0.6;
|
|
12
|
-
let seeded = 0;
|
|
13
|
-
let adopted = 0;
|
|
14
|
-
let incomplete = 0;
|
|
15
|
-
const activeRows = adapter
|
|
16
|
-
.prepare(`
|
|
17
|
-
SELECT n.id, o.id AS observation_id
|
|
18
|
-
FROM entity_nodes n
|
|
19
|
-
LEFT JOIN entity_observations o ON o.id = n.id
|
|
20
|
-
WHERE n.status = 'active'
|
|
21
|
-
AND n.merged_into IS NULL
|
|
22
|
-
`)
|
|
23
|
-
.all();
|
|
24
|
-
for (const row of activeRows) {
|
|
25
|
-
if (!row.observation_id) {
|
|
26
|
-
incomplete += 1;
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
const existing = adapter
|
|
30
|
-
.prepare(`
|
|
31
|
-
SELECT id
|
|
32
|
-
FROM entity_lineage_links
|
|
33
|
-
WHERE canonical_entity_id = ?
|
|
34
|
-
AND entity_observation_id = ?
|
|
35
|
-
AND status = 'active'
|
|
36
|
-
LIMIT 1
|
|
37
|
-
`)
|
|
38
|
-
.get(row.id, row.observation_id);
|
|
39
|
-
if (existing) {
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
seeded += 1;
|
|
43
|
-
if (!dryRun) {
|
|
44
|
-
await (0, lineage_store_js_1.appendEntityLineageLink)({
|
|
45
|
-
canonical_entity_id: row.id,
|
|
46
|
-
entity_observation_id: row.observation_id,
|
|
47
|
-
source_entity_id: null,
|
|
48
|
-
contribution_kind: 'seed',
|
|
49
|
-
run_id: null,
|
|
50
|
-
candidate_id: null,
|
|
51
|
-
review_action_id: null,
|
|
52
|
-
capture_mode: 'backfilled',
|
|
53
|
-
confidence: seedConfidence,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const mergedRows = adapter
|
|
58
|
-
.prepare(`
|
|
59
|
-
SELECT n.id AS source_entity_id, n.merged_into AS target_entity_id, o.id AS observation_id
|
|
60
|
-
FROM entity_nodes n
|
|
61
|
-
LEFT JOIN entity_observations o ON o.id = n.id
|
|
62
|
-
WHERE n.status = 'merged'
|
|
63
|
-
AND n.merged_into IS NOT NULL
|
|
64
|
-
`)
|
|
65
|
-
.all();
|
|
66
|
-
for (const row of mergedRows) {
|
|
67
|
-
if (!row.observation_id) {
|
|
68
|
-
incomplete += 1;
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
const existing = adapter
|
|
72
|
-
.prepare(`
|
|
73
|
-
SELECT id
|
|
74
|
-
FROM entity_lineage_links
|
|
75
|
-
WHERE canonical_entity_id = ?
|
|
76
|
-
AND entity_observation_id = ?
|
|
77
|
-
AND status = 'active'
|
|
78
|
-
LIMIT 1
|
|
79
|
-
`)
|
|
80
|
-
.get(row.target_entity_id, row.observation_id);
|
|
81
|
-
if (existing) {
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
adopted += 1;
|
|
85
|
-
if (!dryRun) {
|
|
86
|
-
await (0, lineage_store_js_1.appendEntityLineageLink)({
|
|
87
|
-
canonical_entity_id: row.target_entity_id,
|
|
88
|
-
entity_observation_id: row.observation_id,
|
|
89
|
-
source_entity_id: row.source_entity_id,
|
|
90
|
-
contribution_kind: 'merge_adopt',
|
|
91
|
-
run_id: null,
|
|
92
|
-
candidate_id: null,
|
|
93
|
-
review_action_id: null,
|
|
94
|
-
capture_mode: 'backfilled',
|
|
95
|
-
confidence: adoptConfidence,
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return { seeded, adopted, incomplete };
|
|
100
|
-
}
|
|
101
|
-
//# sourceMappingURL=lineage-backfill.js.map
|
package/dist/memory-inject.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MAMA (Memory-Augmented MCP Architecture) - Memory Injection Hook
|
|
3
|
-
*
|
|
4
|
-
* UserPromptSubmit hook that injects decision history into Claude's context
|
|
5
|
-
* Tasks: 1.1-1.9 (Hook setup, timeout handling, context injection)
|
|
6
|
-
* AC #1: Query intent → Graph query → Format → Inject (5s timeout for LLM latency)
|
|
7
|
-
* AC #2: No history → null (graceful fallback)
|
|
8
|
-
* AC #3: Timeout → graceful fallback
|
|
9
|
-
*
|
|
10
|
-
* @module memory-inject
|
|
11
|
-
* @version 1.0
|
|
12
|
-
* @date 2025-11-14
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* UserPromptSubmit Hook Handler
|
|
16
|
-
*
|
|
17
|
-
* Task 1.1-1.9: Main entry point for memory injection
|
|
18
|
-
* AC #1, #2, #3: Intent analysis → Query → Format → Inject
|
|
19
|
-
*
|
|
20
|
-
* @param userMessage - User's message from prompt
|
|
21
|
-
* @returns Injected context or null
|
|
22
|
-
*/
|
|
23
|
-
export declare function injectDecisionContext(userMessage: string): Promise<string | null>;
|
|
24
|
-
//# sourceMappingURL=memory-inject.d.ts.map
|