@jungjaehoon/mama-core 4.1.0 → 5.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/README.md +10 -10
- package/db/migrations/099-commitment-revision-graph.sql +3 -0
- package/dist/api/catalog.js +3 -6
- package/dist/api/dispatch.js +12 -1
- package/dist/db-adapter/node-sqlite-adapter.d.ts +5 -1
- package/dist/db-adapter/node-sqlite-adapter.js +27 -24
- package/dist/db-manager.d.ts +2 -13
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -6
- package/dist/knowledge/commitments.d.ts +2 -0
- package/dist/knowledge/commitments.js +1 -0
- package/dist/knowledge/graph-query.d.ts +10 -1
- package/dist/knowledge/graph-query.js +118 -25
- package/dist/knowledge/index.d.ts +11 -3
- package/dist/knowledge/index.js +9 -10
- package/dist/knowledge/judgments.d.ts +3 -1
- package/dist/knowledge/judgments.js +46 -26
- package/dist/knowledge/links.d.ts +50 -0
- package/dist/knowledge/links.js +152 -0
- package/dist/mama-api.d.ts +22 -7
- package/dist/mama-api.js +64 -15
- package/dist/memory/api.d.ts +16 -11
- package/dist/memory/api.js +376 -400
- package/dist/memory/decision-links.d.ts +54 -0
- package/dist/memory/decision-links.js +195 -0
- package/dist/memory/graph-read.d.ts +0 -16
- package/dist/memory/graph-read.js +10 -51
- package/dist/memory/judgment-types.d.ts +1 -20
- package/dist/memory/types.d.ts +13 -0
- package/dist/memory/write-adapters.d.ts +1 -39
- package/dist/memory/write-adapters.js +0 -98
- package/package.json +1 -1
- package/dist/knowledge/commitment-revision-migration.d.ts +0 -4
- package/dist/knowledge/commitment-revision-migration.js +0 -50
- package/dist/knowledge/decision-edges.d.ts +0 -70
- package/dist/knowledge/decision-edges.js +0 -123
- package/dist/memory/evolution-engine.d.ts +0 -22
- package/dist/memory/evolution-engine.js +0 -133
package/dist/mama-api.js
CHANGED
|
@@ -19,9 +19,11 @@
|
|
|
19
19
|
* @date 2025-11-26
|
|
20
20
|
*/
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.createAuditAck =
|
|
22
|
+
exports.createAuditAck = void 0;
|
|
23
23
|
exports.createMamaApi = createMamaApi;
|
|
24
24
|
exports.save = save;
|
|
25
|
+
exports.link = link;
|
|
26
|
+
exports.getDecision = getDecision;
|
|
25
27
|
exports.suggest = suggest;
|
|
26
28
|
exports.saveMemory = saveMemory;
|
|
27
29
|
exports.recallMemory = recallMemory;
|
|
@@ -63,13 +65,28 @@ const decision_formatter_js_1 = require("./decision-formatter.js");
|
|
|
63
65
|
const progress_indicator_js_1 = require("./progress-indicator.js");
|
|
64
66
|
const debug_logger_js_1 = require("./debug-logger.js");
|
|
65
67
|
const api_js_2 = require("./memory/api.js");
|
|
66
|
-
Object.defineProperty(exports, "evolveMemory", { enumerable: true, get: function () { return api_js_2.evolveMemory; } });
|
|
67
68
|
Object.defineProperty(exports, "createAuditAck", { enumerable: true, get: function () { return api_js_2.createAuditAck; } });
|
|
68
69
|
const finding_store_js_1 = require("./memory/finding-store.js");
|
|
69
70
|
const event_store_js_1 = require("./memory/event-store.js");
|
|
70
71
|
const provenance_query_js_1 = require("./memory/provenance-query.js");
|
|
71
72
|
const model_run_store_js_1 = require("./runtime/model-run-store.js");
|
|
72
73
|
const tool_trace_store_js_1 = require("./runtime/tool-trace-store.js");
|
|
74
|
+
const decision_links_js_1 = require("./memory/decision-links.js");
|
|
75
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
76
|
+
// Type Definitions
|
|
77
|
+
// ════════════════════════════════════════════════════════════════════════════
|
|
78
|
+
/**
|
|
79
|
+
* Parameters for mama.save()
|
|
80
|
+
*/
|
|
81
|
+
/** Relations a save names; replacing is `replaces`, which also moves the replaced record's state. */
|
|
82
|
+
const SAVE_LINK_RELATIONS = [
|
|
83
|
+
'builds_on',
|
|
84
|
+
'refines',
|
|
85
|
+
'contradicts',
|
|
86
|
+
'debates',
|
|
87
|
+
'synthesizes',
|
|
88
|
+
'mentions',
|
|
89
|
+
];
|
|
73
90
|
// Prevents spam by tracking warned topics per session
|
|
74
91
|
/**
|
|
75
92
|
* Save a decision or insight to MAMA's memory
|
|
@@ -98,7 +115,7 @@ const tool_trace_store_js_1 = require("./runtime/tool-trace-store.js");
|
|
|
98
115
|
* outcome: 'success'
|
|
99
116
|
* });
|
|
100
117
|
*/
|
|
101
|
-
async function saveInternal(adapter, { topic, decision, reasoning, confidence = 0.5, type = 'user_decision', outcome = 'pending', failure_reason = null, limitation = null, trust_context: _trust_context = null, is_static, scopes: inputScopes, item, actors, event_date, }) {
|
|
118
|
+
async function saveInternal(adapter, { topic, decision, reasoning, confidence = 0.5, type = 'user_decision', outcome = 'pending', failure_reason = null, limitation = null, trust_context: _trust_context = null, is_static, scopes: inputScopes, item, actors, event_date, links, replaces, }) {
|
|
102
119
|
// Validate required fields
|
|
103
120
|
if (!topic || typeof topic !== 'string') {
|
|
104
121
|
throw new Error('mama.save() requires topic (string)');
|
|
@@ -155,9 +172,8 @@ async function saveInternal(adapter, { topic, decision, reasoning, confidence =
|
|
|
155
172
|
superseded: null,
|
|
156
173
|
};
|
|
157
174
|
const dbOutcome = outcome in outcomeMap ? outcomeMap[outcome] : outcome;
|
|
158
|
-
// Reasoning text is evidence, not authority:
|
|
159
|
-
//
|
|
160
|
-
// twin-edge links). Parsing IDs out of prose fabricated edges, so it is gone.
|
|
175
|
+
// Reasoning text is evidence, not authority: a relation is written only when the caller names
|
|
176
|
+
// its target and reason (`links`, `replaces`). Parsing ids out of prose fabricated edges.
|
|
161
177
|
(0, progress_indicator_js_1.logProgress)(`Saving decision: ${topic.substring(0, 30)}...`);
|
|
162
178
|
const { id: decisionId } = await (0, api_js_2.saveLegacyMemory)(adapter, {
|
|
163
179
|
topic,
|
|
@@ -173,6 +189,33 @@ async function saveInternal(adapter, { topic, decision, reasoning, confidence =
|
|
|
173
189
|
eventDate: event_date ?? undefined,
|
|
174
190
|
itemId: item ?? undefined,
|
|
175
191
|
actors: actors?.map((actor) => ({ personId: actor.person, role: actor.role })),
|
|
192
|
+
...(links?.length
|
|
193
|
+
? {
|
|
194
|
+
links: links.map((link) => {
|
|
195
|
+
if (typeof link.reason !== 'string' || link.reason.trim() === '') {
|
|
196
|
+
throw new Error('mama.save() each link needs a reason');
|
|
197
|
+
}
|
|
198
|
+
if (!SAVE_LINK_RELATIONS.includes(link.relation)) {
|
|
199
|
+
throw new Error(`mama.save() link relation must be one of ${SAVE_LINK_RELATIONS.join(', ')}; a replaced decision goes in replaces`);
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
relation: link.relation,
|
|
203
|
+
target: { kind: 'memory', id: link.id },
|
|
204
|
+
attrs: { reason: link.reason.trim() },
|
|
205
|
+
};
|
|
206
|
+
}),
|
|
207
|
+
}
|
|
208
|
+
: {}),
|
|
209
|
+
...(replaces?.length
|
|
210
|
+
? {
|
|
211
|
+
replaces: replaces.map((replacement) => {
|
|
212
|
+
if (typeof replacement.reason !== 'string' || replacement.reason.trim() === '') {
|
|
213
|
+
throw new Error('mama.save() each replaced decision needs a reason');
|
|
214
|
+
}
|
|
215
|
+
return { id: replacement.id, reason: replacement.reason.trim() };
|
|
216
|
+
}),
|
|
217
|
+
}
|
|
218
|
+
: {}),
|
|
176
219
|
}, {
|
|
177
220
|
userInvolvement: _userInvolvement,
|
|
178
221
|
outcome: dbOutcome,
|
|
@@ -271,11 +314,7 @@ function _generateCollaborationHint(similarDecisions) {
|
|
|
271
314
|
if (count === 0) {
|
|
272
315
|
return null;
|
|
273
316
|
}
|
|
274
|
-
return `Found ${count} related decision(s).
|
|
275
|
-
- SUPERSEDE: Add "supersedes: <id>" in reasoning to replace a specific prior decision
|
|
276
|
-
- BUILD-ON: Add "builds_on: <id>" in reasoning to extend
|
|
277
|
-
- DEBATE: Add "debates: <id>" in reasoning for alternative view
|
|
278
|
-
- SYNTHESIZE: Add "synthesizes: [id1, id2]" in reasoning to unify`;
|
|
317
|
+
return `Found ${count} related decision(s). If the new decision replaces, extends, debates or combines one of them, link it with the reason you judged: replaces [{id, reason}] or links [{id, relation, reason}] when saving, or a link afterwards. Nothing is linked for you.`;
|
|
279
318
|
}
|
|
280
319
|
/**
|
|
281
320
|
* Get reasoning graph info for a topic
|
|
@@ -456,6 +495,16 @@ async function updateOutcome(decisionId, outcome) {
|
|
|
456
495
|
await (0, db_manager_js_1.initDB)();
|
|
457
496
|
return (0, api_js_1.updateOutcomeInAdapter)((0, db_manager_js_1.getAdapter)(), decisionId, outcome);
|
|
458
497
|
}
|
|
498
|
+
/** Link one decision to another, or correct a link, with the reason the caller judged. */
|
|
499
|
+
async function link(input) {
|
|
500
|
+
await (0, db_manager_js_1.initDB)();
|
|
501
|
+
return (0, decision_links_js_1.appendDecisionLink)((0, db_manager_js_1.getAdapter)(), input);
|
|
502
|
+
}
|
|
503
|
+
/** One decision with every edge in and out, each with its reason and who wrote it. */
|
|
504
|
+
async function getDecision(id) {
|
|
505
|
+
await (0, db_manager_js_1.initDB)();
|
|
506
|
+
return (0, decision_links_js_1.readDecisionWithEdges)((0, db_manager_js_1.getAdapter)(), id);
|
|
507
|
+
}
|
|
459
508
|
async function listDecisions(options = {}) {
|
|
460
509
|
await (0, db_manager_js_1.initDB)();
|
|
461
510
|
return (0, api_js_1.listDecisionsInAdapter)((0, db_manager_js_1.getAdapter)(), options);
|
|
@@ -627,7 +676,6 @@ function createMamaApi(adapter) {
|
|
|
627
676
|
buildProfile: (scopes) => (0, api_js_2.buildProfile)(adapter, scopes),
|
|
628
677
|
ingestMemory: (input) => (0, api_js_2.ingestMemory)(adapter, input),
|
|
629
678
|
ingestConversation: (input) => (0, api_js_2.ingestConversation)(adapter, input),
|
|
630
|
-
evolveMemory: (input) => (0, api_js_2.evolveMemory)(input),
|
|
631
679
|
buildMemoryBootstrap: (params) => (0, api_js_2.buildMemoryBootstrap)(adapter, params),
|
|
632
680
|
createAuditAck: (input) => (0, api_js_2.createAuditAck)(input),
|
|
633
681
|
recordMemoryAudit: (input) => (0, api_js_2.recordMemoryAudit)(adapter, input),
|
|
@@ -660,8 +708,10 @@ function createMamaApi(adapter) {
|
|
|
660
708
|
};
|
|
661
709
|
}
|
|
662
710
|
const mama = {
|
|
663
|
-
// Core functions (used by
|
|
711
|
+
// Core functions (used by the MCP tools)
|
|
664
712
|
save,
|
|
713
|
+
link,
|
|
714
|
+
getDecision,
|
|
665
715
|
suggest,
|
|
666
716
|
saveMemory,
|
|
667
717
|
recallMemory,
|
|
@@ -671,7 +721,6 @@ const mama = {
|
|
|
671
721
|
buildProfile,
|
|
672
722
|
ingestMemory,
|
|
673
723
|
ingestConversation,
|
|
674
|
-
evolveMemory: api_js_2.evolveMemory,
|
|
675
724
|
buildMemoryBootstrap,
|
|
676
725
|
createAuditAck: api_js_2.createAuditAck,
|
|
677
726
|
recordMemoryAudit,
|
|
@@ -706,7 +755,7 @@ exports.default = mama;
|
|
|
706
755
|
// ambient `mama` facade methods at top level. Merge instead of replacing
|
|
707
756
|
// module.exports: the compiled `exports.X = X` named exports (suggestInAdapter,
|
|
708
757
|
// saveCheckpointInAdapter, ...) are how api/catalog.ts reaches them from dist.
|
|
709
|
-
// Getter-only named exports (
|
|
758
|
+
// Getter-only named exports (createAuditAck) keep their getter —
|
|
710
759
|
// it already returns the same function the facade carries.
|
|
711
760
|
if (typeof module !== 'undefined' && module.exports) {
|
|
712
761
|
const target = module.exports;
|
package/dist/memory/api.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { DatabaseAdapter } from '../db-manager.js';
|
|
2
2
|
import type { TextCompletion } from '../runtime/text-completion.js';
|
|
3
|
+
import { type DecisionCorrection } from './decision-links.js';
|
|
3
4
|
import type { SearchQualityOptions } from '../knowledge/search-quality.js';
|
|
4
5
|
import type { DecisionRecord } from '../db-manager.js';
|
|
5
6
|
import type { DatabaseInstance } from '../db-manager.js';
|
|
6
|
-
import { resolveMemoryEvolution } from './evolution-engine.js';
|
|
7
7
|
import { getChannelSummary, upsertChannelSummary } from './channel-summary-store.js';
|
|
8
8
|
import { type SearchHitDiagnostics } from '../knowledge/search-quality.js';
|
|
9
9
|
import type { MemoryKind, MemoryKindFilter, MemoryAgentBootstrap, MemoryAuditAck, MemoryEdge, MemoryRecord, MemoryScopeRef, MemoryStatus, ProfileSnapshot, PublicIngestMemoryInput, PublicSaveMemoryInput, RecallBundle, IngestConversationInput, IngestConversationResult, RecallMemoryOptions } from './types.js';
|
|
@@ -17,10 +17,6 @@ export interface LegacyMemoryPersistence {
|
|
|
17
17
|
failureReason?: string | null;
|
|
18
18
|
limitation?: string | null;
|
|
19
19
|
isStatic?: number;
|
|
20
|
-
relationships?: Array<{
|
|
21
|
-
type: string;
|
|
22
|
-
targetIds: string[];
|
|
23
|
-
}>;
|
|
24
20
|
}
|
|
25
21
|
export interface FusedHit {
|
|
26
22
|
source_type: 'decision';
|
|
@@ -74,11 +70,6 @@ export declare function saveJudgmentRecord(adapter: DatabaseInstance, input: Sav
|
|
|
74
70
|
*/
|
|
75
71
|
export declare function boundReadScopesFor(access: JudgmentAccess, requested?: MemoryScopeRef[]): MemoryScopeRef[];
|
|
76
72
|
export declare function saveLegacyMemory(adapter: DatabaseInstance, input: SaveMemoryInput, legacy: LegacyMemoryPersistence, access?: JudgmentAccess): Promise<SaveMemoryResult>;
|
|
77
|
-
export declare function promoteMemoryStatus(adapter: DatabaseInstance, input: {
|
|
78
|
-
memoryId: string;
|
|
79
|
-
status: MemoryStatus;
|
|
80
|
-
nowMs?: number;
|
|
81
|
-
}): Promise<void>;
|
|
82
73
|
export type MemoryRetirementStatus = Extract<MemoryStatus, 'stale' | 'superseded'>;
|
|
83
74
|
/** Append an access-checked status amendment for one stored memory record. */
|
|
84
75
|
export declare function retireMemoryRecord(adapter: DatabaseInstance, input: {
|
|
@@ -98,7 +89,6 @@ export declare function ingestMemory(adapter: DatabaseInstance, input: IngestMem
|
|
|
98
89
|
success: boolean;
|
|
99
90
|
id: string;
|
|
100
91
|
}>;
|
|
101
|
-
export declare function evolveMemory(input: Parameters<typeof resolveMemoryEvolution>[0]): Promise<import("./evolution-engine.js").EvolutionResult>;
|
|
102
92
|
export declare function buildMemoryBootstrap(adapter: DatabaseInstance, params: {
|
|
103
93
|
scopes: MemoryScopeRef[];
|
|
104
94
|
channelKey?: string;
|
|
@@ -148,6 +138,8 @@ export interface SearchCandidate {
|
|
|
148
138
|
graph_rank?: number;
|
|
149
139
|
related_to?: string | null;
|
|
150
140
|
edge_reason?: string | null;
|
|
141
|
+
/** Later links that contradict the link this record was reached through. */
|
|
142
|
+
edge_corrected_by?: DecisionCorrection[];
|
|
151
143
|
recency_score?: number;
|
|
152
144
|
recency_age_days?: number;
|
|
153
145
|
final_score?: number;
|
|
@@ -203,6 +195,19 @@ export interface SuggestFunctionOptions extends SearchQualityOptions {
|
|
|
203
195
|
*/
|
|
204
196
|
runner?: TextCompletion;
|
|
205
197
|
}
|
|
198
|
+
/** One stated link from or to a search hit: a pointer the reader opens. */
|
|
199
|
+
export interface SearchHitLink {
|
|
200
|
+
id: string;
|
|
201
|
+
topic: string;
|
|
202
|
+
/** The record's first line. */
|
|
203
|
+
summary: string;
|
|
204
|
+
/** Present when the record is no longer active, e.g. `superseded`. */
|
|
205
|
+
status?: string;
|
|
206
|
+
/** Seen from the hit: `builds_on` out, `built_on_by` in, and so on. */
|
|
207
|
+
relation: string;
|
|
208
|
+
reason: string | null;
|
|
209
|
+
corrected_by?: DecisionCorrection[];
|
|
210
|
+
}
|
|
206
211
|
export declare function suggestInAdapter(adapter: DatabaseInstance, userQuestion: string, options?: SuggestFunctionOptions): Promise<any>;
|
|
207
212
|
/**
|
|
208
213
|
* List recent decisions (all topics, chronological)
|