@jungjaehoon/mama-core 1.1.4 → 1.1.5
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/db-manager.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ export interface DecisionRecord {
|
|
|
53
53
|
refined_from?: string | string[] | null;
|
|
54
54
|
created_at: number;
|
|
55
55
|
updated_at?: number;
|
|
56
|
-
edges?:
|
|
56
|
+
edges?: DecisionEdgeRow[];
|
|
57
57
|
}
|
|
58
58
|
export interface OutcomeData {
|
|
59
59
|
outcome?: string | null;
|
|
@@ -68,17 +68,40 @@ export interface VectorSearchParams {
|
|
|
68
68
|
threshold?: number;
|
|
69
69
|
timeWindow?: number;
|
|
70
70
|
}
|
|
71
|
+
export interface DecisionEdgeRow {
|
|
72
|
+
from_id: string;
|
|
73
|
+
to_id: string;
|
|
74
|
+
relationship: string;
|
|
75
|
+
reason?: string | null;
|
|
76
|
+
weight?: number;
|
|
77
|
+
created_at?: number;
|
|
78
|
+
created_by?: string;
|
|
79
|
+
approved_by_user?: number | null;
|
|
80
|
+
decision_id?: string | null;
|
|
81
|
+
evidence?: string | null;
|
|
82
|
+
}
|
|
83
|
+
export interface SemanticEdgeItem {
|
|
84
|
+
from_id: string;
|
|
85
|
+
to_id: string;
|
|
86
|
+
relationship: string;
|
|
87
|
+
reason?: string;
|
|
88
|
+
topic: string;
|
|
89
|
+
decision: string;
|
|
90
|
+
confidence?: number;
|
|
91
|
+
created_at?: string;
|
|
92
|
+
approved_by_user?: number | null;
|
|
93
|
+
}
|
|
71
94
|
export interface SemanticEdges {
|
|
72
|
-
refines:
|
|
73
|
-
refined_by:
|
|
74
|
-
contradicts:
|
|
75
|
-
contradicted_by:
|
|
76
|
-
builds_on:
|
|
77
|
-
built_on_by:
|
|
78
|
-
debates:
|
|
79
|
-
debated_by:
|
|
80
|
-
synthesizes:
|
|
81
|
-
synthesized_by:
|
|
95
|
+
refines: SemanticEdgeItem[];
|
|
96
|
+
refined_by: SemanticEdgeItem[];
|
|
97
|
+
contradicts: SemanticEdgeItem[];
|
|
98
|
+
contradicted_by: SemanticEdgeItem[];
|
|
99
|
+
builds_on: SemanticEdgeItem[];
|
|
100
|
+
built_on_by: SemanticEdgeItem[];
|
|
101
|
+
debates: SemanticEdgeItem[];
|
|
102
|
+
debated_by: SemanticEdgeItem[];
|
|
103
|
+
synthesizes: SemanticEdgeItem[];
|
|
104
|
+
synthesized_by: SemanticEdgeItem[];
|
|
82
105
|
}
|
|
83
106
|
/**
|
|
84
107
|
* Initialize SQLite database adapter and connect
|
|
@@ -20,9 +20,17 @@ import type { Server as HTTPServer } from 'http';
|
|
|
20
20
|
/**
|
|
21
21
|
* Message router interface
|
|
22
22
|
*/
|
|
23
|
+
interface StreamCallbacks {
|
|
24
|
+
onDelta?: (text: string) => void;
|
|
25
|
+
onToolUse?: (toolName: string, input: Record<string, unknown>) => void;
|
|
26
|
+
onToolComplete?: (toolName: string, toolUseId: string, isError: boolean) => void;
|
|
27
|
+
onFinal?: (response: unknown) => void;
|
|
28
|
+
onError?: (error: Error) => void;
|
|
29
|
+
}
|
|
23
30
|
interface MessageRouter {
|
|
24
31
|
process(message: NormalizedMessage, options?: {
|
|
25
32
|
onQueued?: () => void;
|
|
33
|
+
onStream?: StreamCallbacks;
|
|
26
34
|
}): Promise<RouterResult>;
|
|
27
35
|
}
|
|
28
36
|
/**
|
|
@@ -218,6 +218,8 @@ async function handleClientMessage(clientId, message, clientInfo, messageRouter,
|
|
|
218
218
|
}
|
|
219
219
|
}, 10000); // Every 10 seconds
|
|
220
220
|
let result;
|
|
221
|
+
let deltasSent = false;
|
|
222
|
+
let toolIndex = 0;
|
|
221
223
|
try {
|
|
222
224
|
// Build contentBlocks from attachments (files are pre-compressed by upload-handler)
|
|
223
225
|
let contentBlocks = undefined;
|
|
@@ -303,18 +305,33 @@ async function handleClientMessage(clientId, message, clientInfo, messageRouter,
|
|
|
303
305
|
}
|
|
304
306
|
logger.info(`Message queued for ${clientId} (session busy)`);
|
|
305
307
|
},
|
|
308
|
+
onStream: {
|
|
309
|
+
onDelta: (text) => {
|
|
310
|
+
deltasSent = true;
|
|
311
|
+
safeSend(clientInfo.ws, JSON.stringify({ type: 'stream', content: text }));
|
|
312
|
+
},
|
|
313
|
+
onToolUse: (tool, input) => {
|
|
314
|
+
const idx = toolIndex++;
|
|
315
|
+
safeSend(clientInfo.ws, JSON.stringify({ type: 'tool_use', tool, index: idx, input }));
|
|
316
|
+
},
|
|
317
|
+
onToolComplete: (tool, _toolUseId, isError) => {
|
|
318
|
+
safeSend(clientInfo.ws, JSON.stringify({ type: 'tool_complete', tool, index: toolIndex - 1, isError }));
|
|
319
|
+
},
|
|
320
|
+
},
|
|
306
321
|
});
|
|
307
322
|
}
|
|
308
323
|
finally {
|
|
309
324
|
clearInterval(keepAliveInterval);
|
|
310
325
|
}
|
|
311
|
-
//
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
326
|
+
// Only send full response if no deltas were streamed (Codex fallback)
|
|
327
|
+
if (!deltasSent) {
|
|
328
|
+
safeSend(clientInfo.ws, JSON.stringify({
|
|
329
|
+
type: 'stream',
|
|
330
|
+
content: result.response,
|
|
331
|
+
sessionId: result.sessionId,
|
|
332
|
+
}));
|
|
333
|
+
}
|
|
334
|
+
// Always send stream end
|
|
318
335
|
safeSend(clientInfo.ws, JSON.stringify({
|
|
319
336
|
type: 'stream_end',
|
|
320
337
|
sessionId: result.sessionId,
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
export { generateEmbedding, generateEnhancedEmbedding, generateBatchEmbeddings, cosineSimilarity, embeddingCache, EMBEDDING_DIM, MODEL_NAME, } from './embeddings.js';
|
|
11
11
|
export { EmbeddingCache } from './embedding-cache.js';
|
|
12
12
|
export { getEmbeddingFromServer, getServerStatus, isServerRunning, getServerPort, DEFAULT_PORT, HOST, TIMEOUT_MS, type ServerStatus, } from './embedding-client.js';
|
|
13
|
-
export { initDB, getDB, getAdapter, closeDB, insertEmbedding, vectorSearch, queryVectorSearch, insertDecisionWithEmbedding, queryDecisionGraph, querySemanticEdges, updateDecisionOutcome, getPreparedStmt, getDbPath, type DatabaseAdapter as DBManagerAdapter, type PreparedStatement, type DecisionRecord, type OutcomeData, type VectorSearchParams, type SemanticEdges, type DecisionInput, } from './db-manager.js';
|
|
13
|
+
export { initDB, getDB, getAdapter, closeDB, insertEmbedding, vectorSearch, queryVectorSearch, insertDecisionWithEmbedding, queryDecisionGraph, querySemanticEdges, updateDecisionOutcome, getPreparedStmt, getDbPath, type DatabaseAdapter as DBManagerAdapter, type PreparedStatement, type DecisionRecord, type OutcomeData, type VectorSearchParams, type SemanticEdges, type SemanticEdgeItem, type DecisionInput, } from './db-manager.js';
|
|
14
14
|
export { createAdapter, DatabaseAdapter, SQLiteAdapter, type AdapterConfig, type Statement, type VectorSearchResult, type RunResult, } from './db-adapter/index.js';
|
|
15
15
|
export { getSessionDecisions, incrementUsageSuccess, incrementUsageFailure, getDecisionById, traverseDecisionChain, DB_PATH, DB_DIR, LEGACY_DB_PATH, DEFAULT_DB_PATH, } from './memory-store.js';
|
|
16
16
|
import mama from './mama-api.js';
|
package/dist/mama-api.d.ts
CHANGED
|
@@ -172,6 +172,9 @@ export interface LoadCheckpointResult {
|
|
|
172
172
|
* Outcome badge map type
|
|
173
173
|
*/
|
|
174
174
|
export type OutcomeBadgeMap = Record<string, string | null>;
|
|
175
|
+
/**
|
|
176
|
+
* Raw semantic edge from database
|
|
177
|
+
*/
|
|
175
178
|
/**
|
|
176
179
|
* Recall options
|
|
177
180
|
*/
|
|
@@ -412,7 +415,51 @@ declare function save({ topic, decision, reasoning, confidence, type, outcome, f
|
|
|
412
415
|
* const markdown = await mama.recall('auth_strategy', { format: 'markdown' });
|
|
413
416
|
* // → "📋 Decision History: auth_strategy\n━━━━━━━━..."
|
|
414
417
|
*/
|
|
415
|
-
|
|
418
|
+
interface RecallEdgeRef {
|
|
419
|
+
to_topic?: string;
|
|
420
|
+
to_decision?: string;
|
|
421
|
+
to_id?: string;
|
|
422
|
+
from_topic?: string;
|
|
423
|
+
from_decision?: string;
|
|
424
|
+
from_id?: string;
|
|
425
|
+
reason?: string | null;
|
|
426
|
+
confidence?: number;
|
|
427
|
+
created_at?: string | number;
|
|
428
|
+
}
|
|
429
|
+
interface RecallGraphResult {
|
|
430
|
+
topic: string;
|
|
431
|
+
supersedes_chain: Array<{
|
|
432
|
+
id: string;
|
|
433
|
+
decision: string;
|
|
434
|
+
reasoning?: string | null;
|
|
435
|
+
confidence?: number;
|
|
436
|
+
outcome?: string | null;
|
|
437
|
+
failure_reason?: string | null;
|
|
438
|
+
created_at: number;
|
|
439
|
+
updated_at?: number;
|
|
440
|
+
superseded_by?: string | null;
|
|
441
|
+
supersedes?: string | null;
|
|
442
|
+
}>;
|
|
443
|
+
semantic_edges: {
|
|
444
|
+
refines: RecallEdgeRef[];
|
|
445
|
+
refined_by: RecallEdgeRef[];
|
|
446
|
+
contradicts: RecallEdgeRef[];
|
|
447
|
+
contradicted_by: RecallEdgeRef[];
|
|
448
|
+
};
|
|
449
|
+
meta: {
|
|
450
|
+
count: number;
|
|
451
|
+
latest_id?: string;
|
|
452
|
+
has_supersedes_chain: boolean;
|
|
453
|
+
has_semantic_edges: boolean;
|
|
454
|
+
semantic_edges_count: {
|
|
455
|
+
refines: number;
|
|
456
|
+
refined_by: number;
|
|
457
|
+
contradicts: number;
|
|
458
|
+
contradicted_by: number;
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
declare function recall(topic: string, options?: RecallOptions): Promise<string | RecallGraphResult>;
|
|
416
463
|
/**
|
|
417
464
|
* Update outcome of a decision
|
|
418
465
|
*
|
|
@@ -505,13 +552,21 @@ declare function saveCheckpoint(summary: string, openFiles?: string[], nextSteps
|
|
|
505
552
|
*
|
|
506
553
|
* @returns {Promise<Object|null>} Latest checkpoint or null
|
|
507
554
|
*/
|
|
555
|
+
interface ConversationMessage {
|
|
556
|
+
role: string;
|
|
557
|
+
content: string | Array<{
|
|
558
|
+
type: string;
|
|
559
|
+
text?: string;
|
|
560
|
+
[key: string]: unknown;
|
|
561
|
+
}>;
|
|
562
|
+
}
|
|
508
563
|
interface CheckpointRow {
|
|
509
564
|
id?: number;
|
|
510
565
|
timestamp?: number;
|
|
511
566
|
summary?: string;
|
|
512
567
|
open_files?: string | string[];
|
|
513
568
|
next_steps?: string;
|
|
514
|
-
recent_conversation?: string |
|
|
569
|
+
recent_conversation?: string | ConversationMessage[];
|
|
515
570
|
status?: string;
|
|
516
571
|
}
|
|
517
572
|
declare function loadCheckpoint(): Promise<CheckpointRow | null>;
|
package/dist/mama-api.js
CHANGED
|
@@ -347,26 +347,6 @@ async function _getReasoningGraphInfo(topic, currentId) {
|
|
|
347
347
|
};
|
|
348
348
|
}
|
|
349
349
|
}
|
|
350
|
-
/**
|
|
351
|
-
* Recall decisions by topic
|
|
352
|
-
*
|
|
353
|
-
* DEFAULT: Returns JSON object with decisions and edges (LLM-first design)
|
|
354
|
-
* OPTIONAL: Returns Markdown string if format='markdown' (for human display)
|
|
355
|
-
*
|
|
356
|
-
* @param {string} topic - Decision topic to recall
|
|
357
|
-
* @param {Object} [options] - Options
|
|
358
|
-
* @param {string} [options.format='json'] - Output format: 'json' (default) or 'markdown'
|
|
359
|
-
* @returns {Promise<Object|string>} Decision history as JSON or Markdown
|
|
360
|
-
*
|
|
361
|
-
* @example
|
|
362
|
-
* // LLM usage (default)
|
|
363
|
-
* const data = await mama.recall('auth_strategy');
|
|
364
|
-
* // → { topic, decisions: [...], edges: [...], meta: {...} }
|
|
365
|
-
*
|
|
366
|
-
* // Human display
|
|
367
|
-
* const markdown = await mama.recall('auth_strategy', { format: 'markdown' });
|
|
368
|
-
* // → "📋 Decision History: auth_strategy\n━━━━━━━━..."
|
|
369
|
-
*/
|
|
370
350
|
async function recall(topic, options = {}) {
|
|
371
351
|
if (!topic || typeof topic !== 'string') {
|
|
372
352
|
throw new Error('mama.recall() requires topic (string)');
|
|
@@ -382,18 +362,22 @@ async function recall(topic, options = {}) {
|
|
|
382
362
|
topic,
|
|
383
363
|
supersedes_chain: [],
|
|
384
364
|
semantic_edges: { refines: [], refined_by: [], contradicts: [], contradicted_by: [] },
|
|
385
|
-
meta: {
|
|
365
|
+
meta: {
|
|
366
|
+
count: 0,
|
|
367
|
+
has_supersedes_chain: false,
|
|
368
|
+
has_semantic_edges: false,
|
|
369
|
+
semantic_edges_count: { refines: 0, refined_by: 0, contradicts: 0, contradicted_by: 0 },
|
|
370
|
+
},
|
|
386
371
|
};
|
|
387
372
|
}
|
|
388
373
|
// Query semantic edges for all decisions
|
|
389
374
|
const decisionIds = decisions.map((d) => d.id);
|
|
390
|
-
const
|
|
391
|
-
const rawEdges = (rawEdgesResult || {});
|
|
375
|
+
const rawEdges = await (0, memory_store_js_1.querySemanticEdges)(decisionIds);
|
|
392
376
|
const semanticEdges = {
|
|
393
|
-
refines:
|
|
394
|
-
refined_by:
|
|
395
|
-
contradicts:
|
|
396
|
-
contradicted_by:
|
|
377
|
+
refines: rawEdges.refines || [],
|
|
378
|
+
refined_by: rawEdges.refined_by || [],
|
|
379
|
+
contradicts: rawEdges.contradicts || [],
|
|
380
|
+
contradicted_by: rawEdges.contradicted_by || [],
|
|
397
381
|
};
|
|
398
382
|
// Markdown format (for human display)
|
|
399
383
|
if (format === 'markdown') {
|
|
@@ -566,7 +550,6 @@ async function expandWithGraph(candidates) {
|
|
|
566
550
|
synthesized_by: rawEdges.synthesized_by || [],
|
|
567
551
|
};
|
|
568
552
|
// Helper to add edge to graph
|
|
569
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- dynamic property access with idField
|
|
570
553
|
const addEdge = (edge, idField, source, rank, simFactor) => {
|
|
571
554
|
const id = edge[idField];
|
|
572
555
|
if (!graphEnhanced.has(id)) {
|
|
@@ -698,8 +681,10 @@ async function suggest(userQuestion, options = {}) {
|
|
|
698
681
|
let results = [];
|
|
699
682
|
let searchMethod = 'vector';
|
|
700
683
|
try {
|
|
701
|
-
// Check if
|
|
702
|
-
(0, memory_store_js_1.
|
|
684
|
+
// Check if vector search is available (sqlite-vec loaded)
|
|
685
|
+
if (!(0, memory_store_js_1.getAdapter)().vectorSearchEnabled) {
|
|
686
|
+
throw new Error('Vector search not available');
|
|
687
|
+
}
|
|
703
688
|
// Generate query embedding
|
|
704
689
|
const queryEmbedding = await (0, embeddings_js_1.generateEmbedding)(userQuestion);
|
|
705
690
|
// Adaptive threshold (shorter queries need higher confidence)
|