@jungjaehoon/mama-core 1.0.2 → 1.1.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/package.json +33 -21
- package/src/config-loader.js +0 -218
- package/src/db-adapter/README.md +0 -110
- package/src/db-adapter/base-adapter.js +0 -91
- package/src/db-adapter/index.js +0 -31
- package/src/db-adapter/sqlite-adapter.js +0 -364
- package/src/db-adapter/statement.js +0 -127
- package/src/db-manager.js +0 -671
- package/src/debug-logger.js +0 -86
- package/src/decision-formatter.js +0 -1276
- package/src/decision-tracker.js +0 -621
- package/src/embedding-cache.js +0 -222
- package/src/embedding-client.js +0 -141
- package/src/embedding-server/index.js +0 -424
- package/src/embedding-server/mobile/auth.js +0 -160
- package/src/embedding-server/mobile/daemon.js +0 -313
- package/src/embedding-server/mobile/output-parser.js +0 -281
- package/src/embedding-server/mobile/session-api.js +0 -279
- package/src/embedding-server/mobile/session-manager.js +0 -377
- package/src/embedding-server/mobile/websocket-handler.js +0 -443
- package/src/embeddings.js +0 -305
- package/src/errors.js +0 -326
- package/src/index.js +0 -41
- package/src/mama-api.js +0 -2614
- package/src/memory-inject.js +0 -174
- package/src/memory-store.js +0 -89
- package/src/notification-manager.js +0 -3
- package/src/ollama-client.js +0 -391
- package/src/outcome-tracker.js +0 -351
- package/src/progress-indicator.js +0 -110
- package/src/query-intent.js +0 -237
- package/src/relevance-scorer.js +0 -286
- package/src/tier-validator.js +0 -269
- package/src/time-formatter.js +0 -98
package/src/embeddings.js
DELETED
|
@@ -1,305 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MAMA (Memory-Augmented MCP Architecture) - Embedding Generation
|
|
3
|
-
*
|
|
4
|
-
* Story M1.4: Configurable embedding model selection
|
|
5
|
-
* Generates embeddings using configurable model (default: multilingual-e5-small)
|
|
6
|
-
* Supports: Korean-English cross-lingual similarity, enhanced metadata
|
|
7
|
-
*
|
|
8
|
-
* @module embeddings
|
|
9
|
-
* @version 1.1
|
|
10
|
-
* @date 2025-11-20
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
// eslint-disable-next-line no-unused-vars
|
|
14
|
-
const { info, error: logError } = require('./debug-logger');
|
|
15
|
-
const { logProgress: _logProgress, logComplete, logLoading } = require('./progress-indicator');
|
|
16
|
-
const os = require('os');
|
|
17
|
-
const path = require('path');
|
|
18
|
-
// Lazy-load @huggingface/transformers to avoid loading sharp at module load time (Story 014.12.7)
|
|
19
|
-
// const { pipeline } = require('@huggingface/transformers');
|
|
20
|
-
const { embeddingCache } = require('./embedding-cache');
|
|
21
|
-
const { loadConfig, getModelName, getEmbeddingDim } = require('./config-loader');
|
|
22
|
-
|
|
23
|
-
// Shared cache directory (not in node_modules)
|
|
24
|
-
const DEFAULT_CACHE_DIR = path.join(os.homedir(), '.cache', 'huggingface', 'transformers');
|
|
25
|
-
|
|
26
|
-
// Singleton pattern for model loading
|
|
27
|
-
let embeddingPipeline = null;
|
|
28
|
-
let currentModelName = null;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Load embedding model (configurable)
|
|
32
|
-
*
|
|
33
|
-
* Story M1.4 AC #2: Transformers.js singleton initialization
|
|
34
|
-
* Story M1.4 AC #3: Changing model via config triggers informative log + resets caches
|
|
35
|
-
*
|
|
36
|
-
* @returns {Promise<Function>} Embedding pipeline
|
|
37
|
-
*/
|
|
38
|
-
async function loadModel() {
|
|
39
|
-
const modelName = getModelName();
|
|
40
|
-
|
|
41
|
-
// Check if model has changed (Story M1.4 AC #3)
|
|
42
|
-
if (embeddingPipeline && currentModelName && currentModelName !== modelName) {
|
|
43
|
-
info('[MAMA] ⚠️ Embedding model changed - resetting pipeline');
|
|
44
|
-
info(`[MAMA] Old model: ${currentModelName}`);
|
|
45
|
-
info(`[MAMA] New model: ${modelName}`);
|
|
46
|
-
|
|
47
|
-
// Reset pipeline and cache
|
|
48
|
-
embeddingPipeline = null;
|
|
49
|
-
currentModelName = null;
|
|
50
|
-
embeddingCache.clear();
|
|
51
|
-
|
|
52
|
-
info('[MAMA] ⚡ Model cache cleared');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Load model if not already loaded
|
|
56
|
-
if (!embeddingPipeline) {
|
|
57
|
-
logLoading(`Loading embedding model: ${modelName}...`);
|
|
58
|
-
const startTime = Date.now();
|
|
59
|
-
|
|
60
|
-
// Dynamic import for ES Module compatibility (Railway deployment)
|
|
61
|
-
const transformers = await import('@huggingface/transformers');
|
|
62
|
-
const { pipeline, env } = transformers;
|
|
63
|
-
|
|
64
|
-
// Set shared cache directory (not in node_modules)
|
|
65
|
-
// This prevents re-downloading models on every npm install
|
|
66
|
-
const cacheDir = process.env.HF_HOME || process.env.TRANSFORMERS_CACHE || DEFAULT_CACHE_DIR;
|
|
67
|
-
env.cacheDir = cacheDir;
|
|
68
|
-
info(`[MAMA] Model cache directory: ${cacheDir}`);
|
|
69
|
-
|
|
70
|
-
embeddingPipeline = await pipeline('feature-extraction', modelName);
|
|
71
|
-
currentModelName = modelName;
|
|
72
|
-
|
|
73
|
-
const loadTime = Date.now() - startTime;
|
|
74
|
-
const config = loadConfig();
|
|
75
|
-
logComplete(`Embedding model ready (${loadTime}ms, ${config.embeddingDim}-dim)`);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return embeddingPipeline;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Generate embedding vector from text
|
|
83
|
-
*
|
|
84
|
-
* Story M1.4 AC #1: Uses configurable embeddingDim from config
|
|
85
|
-
* Target: < 30ms latency
|
|
86
|
-
*
|
|
87
|
-
* @param {string} text - Input text to embed
|
|
88
|
-
* @returns {Promise<Float32Array>} Embedding vector (dimension from config)
|
|
89
|
-
* @throws {Error} If text is empty or embedding fails
|
|
90
|
-
*/
|
|
91
|
-
async function generateEmbedding(text) {
|
|
92
|
-
if (!text || text.trim().length === 0) {
|
|
93
|
-
throw new Error('Text cannot be empty');
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Task 2: Check cache first (AC #3)
|
|
97
|
-
const cached = embeddingCache.get(text);
|
|
98
|
-
if (cached) {
|
|
99
|
-
return cached;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const startTime = Date.now();
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
const model = await loadModel();
|
|
106
|
-
const expectedDim = getEmbeddingDim();
|
|
107
|
-
|
|
108
|
-
// Generate embedding
|
|
109
|
-
const output = await model(text, {
|
|
110
|
-
pooling: 'mean', // Mean pooling over tokens
|
|
111
|
-
normalize: true, // L2 normalization
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Extract Float32Array
|
|
115
|
-
const embedding = output.data;
|
|
116
|
-
|
|
117
|
-
// Verify dimensions match config
|
|
118
|
-
if (embedding.length !== expectedDim) {
|
|
119
|
-
throw new Error(`Expected ${expectedDim}-dim, got ${embedding.length}-dim`);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// eslint-disable-next-line no-unused-vars
|
|
123
|
-
const latency = Date.now() - startTime;
|
|
124
|
-
|
|
125
|
-
// Task 2: Store in cache (AC #3)
|
|
126
|
-
embeddingCache.set(text, embedding);
|
|
127
|
-
|
|
128
|
-
return embedding;
|
|
129
|
-
} catch (error) {
|
|
130
|
-
throw new Error(`Failed to generate embedding: ${error.message}`);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Generate enhanced embedding with content + metadata
|
|
136
|
-
*
|
|
137
|
-
* Task 3.4: Implement enhanced embedding format
|
|
138
|
-
* Inspired by A-mem: Content + Metadata for richer semantic representation
|
|
139
|
-
*
|
|
140
|
-
* @param {Object} decision - Decision object
|
|
141
|
-
* @param {string} decision.topic - Decision topic
|
|
142
|
-
* @param {string} decision.decision - Decision value
|
|
143
|
-
* @param {string} decision.reasoning - Decision reasoning
|
|
144
|
-
* @param {string} decision.outcome - Decision outcome (optional)
|
|
145
|
-
* @param {number} decision.confidence - Confidence score (optional)
|
|
146
|
-
* @param {string} decision.user_involvement - User involvement (optional)
|
|
147
|
-
* @returns {Promise<Float32Array>} 384-dim enhanced embedding
|
|
148
|
-
*/
|
|
149
|
-
async function generateEnhancedEmbedding(decision) {
|
|
150
|
-
// Construct enriched text representation with narrative fields (Story 2.2)
|
|
151
|
-
const parts = [
|
|
152
|
-
`Topic: ${decision.topic}`,
|
|
153
|
-
`Decision: ${decision.decision}`,
|
|
154
|
-
`Reasoning: ${decision.reasoning || 'N/A'}`,
|
|
155
|
-
`Outcome: ${decision.outcome || 'ONGOING'}`,
|
|
156
|
-
`Confidence: ${decision.confidence !== undefined ? decision.confidence : 0.5}`,
|
|
157
|
-
`User Involvement: ${decision.user_involvement || 'N/A'}`,
|
|
158
|
-
];
|
|
159
|
-
|
|
160
|
-
// Add narrative fields if present (Story 2.2: Narrative-Based Search)
|
|
161
|
-
if (decision.evidence) {
|
|
162
|
-
const evidenceText = Array.isArray(decision.evidence)
|
|
163
|
-
? decision.evidence.join('; ')
|
|
164
|
-
: typeof decision.evidence === 'string'
|
|
165
|
-
? decision.evidence
|
|
166
|
-
: JSON.stringify(decision.evidence);
|
|
167
|
-
parts.push(`Evidence: ${evidenceText}`);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (decision.alternatives) {
|
|
171
|
-
const alternativesText = Array.isArray(decision.alternatives)
|
|
172
|
-
? decision.alternatives.join('; ')
|
|
173
|
-
: typeof decision.alternatives === 'string'
|
|
174
|
-
? decision.alternatives
|
|
175
|
-
: JSON.stringify(decision.alternatives);
|
|
176
|
-
parts.push(`Alternatives: ${alternativesText}`);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (decision.risks) {
|
|
180
|
-
parts.push(`Risks: ${decision.risks}`);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const enrichedText = parts.join('\n').trim();
|
|
184
|
-
|
|
185
|
-
return generateEmbedding(enrichedText);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Batch generate embeddings (optimized)
|
|
190
|
-
*
|
|
191
|
-
* Task 1: Implement Batch Embedding Generation
|
|
192
|
-
* AC #3: Target - 30ms for 10 embeddings (vs 300ms sequential)
|
|
193
|
-
*
|
|
194
|
-
* Strategy: Use native transformer batch processing for parallel inference
|
|
195
|
-
*
|
|
196
|
-
* @param {string[]} texts - Array of texts to embed (max 10 per batch)
|
|
197
|
-
* @returns {Promise<Float32Array[]>} Array of embeddings
|
|
198
|
-
*/
|
|
199
|
-
async function generateBatchEmbeddings(texts) {
|
|
200
|
-
if (!Array.isArray(texts) || texts.length === 0) {
|
|
201
|
-
throw new Error('Texts must be a non-empty array');
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Validate all texts
|
|
205
|
-
for (const text of texts) {
|
|
206
|
-
if (!text || text.trim().length === 0) {
|
|
207
|
-
throw new Error('All texts must be non-empty');
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const startTime = Date.now();
|
|
212
|
-
|
|
213
|
-
try {
|
|
214
|
-
const model = await loadModel();
|
|
215
|
-
const expectedDim = getEmbeddingDim();
|
|
216
|
-
|
|
217
|
-
// Native batch processing - single model forward pass
|
|
218
|
-
// This is significantly faster than sequential calls
|
|
219
|
-
const outputs = await model(texts, {
|
|
220
|
-
pooling: 'mean',
|
|
221
|
-
normalize: true,
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
// Extract embeddings from batch output
|
|
225
|
-
const embeddings = [];
|
|
226
|
-
const batchSize = texts.length;
|
|
227
|
-
|
|
228
|
-
for (let i = 0; i < batchSize; i++) {
|
|
229
|
-
// Each embedding is expectedDim consecutive elements
|
|
230
|
-
const start = i * expectedDim;
|
|
231
|
-
const end = start + expectedDim;
|
|
232
|
-
const embedding = outputs.data.slice(start, end);
|
|
233
|
-
|
|
234
|
-
// Verify dimensions
|
|
235
|
-
if (embedding.length !== expectedDim) {
|
|
236
|
-
throw new Error(`Expected ${expectedDim}-dim, got ${embedding.length}-dim at index ${i}`);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
embeddings.push(embedding);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const latency = Date.now() - startTime;
|
|
243
|
-
const avgLatency = latency / batchSize;
|
|
244
|
-
|
|
245
|
-
// Log for performance tracking
|
|
246
|
-
if (process.env.MAMA_DEBUG) {
|
|
247
|
-
info(
|
|
248
|
-
`[MAMA] Batch(${batchSize}) embeddings: ${latency}ms total (${avgLatency.toFixed(1)}ms avg)`
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
return embeddings;
|
|
253
|
-
} catch (error) {
|
|
254
|
-
throw new Error(`Failed to generate batch embeddings: ${error.message}`);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Calculate cosine similarity between two embeddings
|
|
260
|
-
*
|
|
261
|
-
* Utility for testing and validation
|
|
262
|
-
*
|
|
263
|
-
* @param {Float32Array} embA - First embedding
|
|
264
|
-
* @param {Float32Array} embB - Second embedding
|
|
265
|
-
* @returns {number} Cosine similarity (0-1)
|
|
266
|
-
*/
|
|
267
|
-
function cosineSimilarity(embA, embB) {
|
|
268
|
-
if (embA.length !== embB.length) {
|
|
269
|
-
throw new Error('Embeddings must have same dimension');
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
let dotProduct = 0;
|
|
273
|
-
let normA = 0;
|
|
274
|
-
let normB = 0;
|
|
275
|
-
|
|
276
|
-
for (let i = 0; i < embA.length; i++) {
|
|
277
|
-
dotProduct += embA[i] * embB[i];
|
|
278
|
-
normA += embA[i] * embA[i];
|
|
279
|
-
normB += embB[i] * embB[i];
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const similarity = dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
283
|
-
|
|
284
|
-
return similarity;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Export API
|
|
288
|
-
module.exports = {
|
|
289
|
-
generateEmbedding,
|
|
290
|
-
generateEnhancedEmbedding,
|
|
291
|
-
generateBatchEmbeddings,
|
|
292
|
-
cosineSimilarity,
|
|
293
|
-
embeddingCache,
|
|
294
|
-
// Dynamic getters for config values (Story M1.4)
|
|
295
|
-
get EMBEDDING_DIM() {
|
|
296
|
-
return getEmbeddingDim();
|
|
297
|
-
},
|
|
298
|
-
get MODEL_NAME() {
|
|
299
|
-
return getModelName();
|
|
300
|
-
},
|
|
301
|
-
// Expose config functions for external use
|
|
302
|
-
loadConfig,
|
|
303
|
-
getModelName,
|
|
304
|
-
getEmbeddingDim,
|
|
305
|
-
};
|
package/src/errors.js
DELETED
|
@@ -1,326 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MAMA Error Classes - Typed Error Handling
|
|
3
|
-
*
|
|
4
|
-
* Story 8.3: Typed Error Classes
|
|
5
|
-
* Provides consistent error handling across MCP tools and core modules
|
|
6
|
-
*
|
|
7
|
-
* Error codes follow MCP standard response format:
|
|
8
|
-
* {error: {code: 'ERROR_CODE', message: '...', details: {}}}
|
|
9
|
-
*
|
|
10
|
-
* @module errors
|
|
11
|
-
* @version 1.0
|
|
12
|
-
* @date 2025-11-25
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Base error class for all MAMA errors
|
|
17
|
-
*
|
|
18
|
-
* @class MAMAError
|
|
19
|
-
* @extends Error
|
|
20
|
-
*/
|
|
21
|
-
class MAMAError extends Error {
|
|
22
|
-
/**
|
|
23
|
-
* @param {string} message - Error message
|
|
24
|
-
* @param {string} code - Error code (e.g., 'DECISION_NOT_FOUND')
|
|
25
|
-
* @param {Object} details - Additional error details
|
|
26
|
-
*/
|
|
27
|
-
constructor(message, code = 'MAMA_ERROR', details = {}) {
|
|
28
|
-
super(message);
|
|
29
|
-
this.name = 'MAMAError';
|
|
30
|
-
this.code = code;
|
|
31
|
-
this.details = details;
|
|
32
|
-
this.timestamp = new Date().toISOString();
|
|
33
|
-
|
|
34
|
-
// Capture stack trace
|
|
35
|
-
if (Error.captureStackTrace) {
|
|
36
|
-
Error.captureStackTrace(this, this.constructor);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Convert to MCP-compatible error response format
|
|
42
|
-
*
|
|
43
|
-
* @returns {Object} {error: {code, message, details}}
|
|
44
|
-
*/
|
|
45
|
-
toResponse() {
|
|
46
|
-
return {
|
|
47
|
-
error: {
|
|
48
|
-
code: this.code,
|
|
49
|
-
message: this.message,
|
|
50
|
-
details: this.details,
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Convert to JSON for logging
|
|
57
|
-
*
|
|
58
|
-
* @returns {Object} JSON representation
|
|
59
|
-
*/
|
|
60
|
-
toJSON() {
|
|
61
|
-
return {
|
|
62
|
-
name: this.name,
|
|
63
|
-
code: this.code,
|
|
64
|
-
message: this.message,
|
|
65
|
-
details: this.details,
|
|
66
|
-
timestamp: this.timestamp,
|
|
67
|
-
stack: this.stack,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Error thrown when a decision is not found
|
|
74
|
-
*
|
|
75
|
-
* @class NotFoundError
|
|
76
|
-
* @extends MAMAError
|
|
77
|
-
*/
|
|
78
|
-
class NotFoundError extends MAMAError {
|
|
79
|
-
/**
|
|
80
|
-
* @param {string} resourceType - Type of resource (e.g., 'decision', 'checkpoint')
|
|
81
|
-
* @param {string} identifier - Resource identifier
|
|
82
|
-
* @param {Object} details - Additional details
|
|
83
|
-
*/
|
|
84
|
-
constructor(resourceType, identifier, details = {}) {
|
|
85
|
-
super(`${resourceType} not found: ${identifier}`, `${resourceType.toUpperCase()}_NOT_FOUND`, {
|
|
86
|
-
resourceType,
|
|
87
|
-
identifier,
|
|
88
|
-
...details,
|
|
89
|
-
});
|
|
90
|
-
this.name = 'NotFoundError';
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Error thrown when input validation fails
|
|
96
|
-
*
|
|
97
|
-
* @class ValidationError
|
|
98
|
-
* @extends MAMAError
|
|
99
|
-
*/
|
|
100
|
-
class ValidationError extends MAMAError {
|
|
101
|
-
/**
|
|
102
|
-
* @param {string} field - Field that failed validation
|
|
103
|
-
* @param {string} message - Validation error message
|
|
104
|
-
* @param {*} received - Received value
|
|
105
|
-
* @param {Object} details - Additional details
|
|
106
|
-
*/
|
|
107
|
-
constructor(field, message, received = undefined, details = {}) {
|
|
108
|
-
super(`Validation failed for '${field}': ${message}`, 'INVALID_INPUT', {
|
|
109
|
-
field,
|
|
110
|
-
received: received !== undefined ? String(received).substring(0, 100) : undefined,
|
|
111
|
-
...details,
|
|
112
|
-
});
|
|
113
|
-
this.name = 'ValidationError';
|
|
114
|
-
this.field = field;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Error thrown when database operations fail
|
|
120
|
-
*
|
|
121
|
-
* @class DatabaseError
|
|
122
|
-
* @extends MAMAError
|
|
123
|
-
*/
|
|
124
|
-
class DatabaseError extends MAMAError {
|
|
125
|
-
/**
|
|
126
|
-
* @param {string} operation - Database operation (e.g., 'insert', 'query', 'update')
|
|
127
|
-
* @param {string} message - Error message
|
|
128
|
-
* @param {Object} details - Additional details
|
|
129
|
-
*/
|
|
130
|
-
constructor(operation, message, details = {}) {
|
|
131
|
-
super(`Database ${operation} failed: ${message}`, 'DATABASE_ERROR', {
|
|
132
|
-
operation,
|
|
133
|
-
...details,
|
|
134
|
-
});
|
|
135
|
-
this.name = 'DatabaseError';
|
|
136
|
-
this.operation = operation;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Error thrown when embedding generation fails
|
|
142
|
-
*
|
|
143
|
-
* @class EmbeddingError
|
|
144
|
-
* @extends MAMAError
|
|
145
|
-
*/
|
|
146
|
-
class EmbeddingError extends MAMAError {
|
|
147
|
-
/**
|
|
148
|
-
* @param {string} message - Error message
|
|
149
|
-
* @param {Object} details - Additional details (model, input length, etc.)
|
|
150
|
-
*/
|
|
151
|
-
constructor(message, details = {}) {
|
|
152
|
-
super(`Embedding generation failed: ${message}`, 'EMBEDDING_ERROR', details);
|
|
153
|
-
this.name = 'EmbeddingError';
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Error thrown when configuration is invalid
|
|
159
|
-
*
|
|
160
|
-
* @class ConfigurationError
|
|
161
|
-
* @extends MAMAError
|
|
162
|
-
*/
|
|
163
|
-
class ConfigurationError extends MAMAError {
|
|
164
|
-
/**
|
|
165
|
-
* @param {string} configKey - Configuration key
|
|
166
|
-
* @param {string} message - Error message
|
|
167
|
-
* @param {Object} details - Additional details
|
|
168
|
-
*/
|
|
169
|
-
constructor(configKey, message, details = {}) {
|
|
170
|
-
super(`Configuration error for '${configKey}': ${message}`, 'CONFIG_ERROR', {
|
|
171
|
-
configKey,
|
|
172
|
-
...details,
|
|
173
|
-
});
|
|
174
|
-
this.name = 'ConfigurationError';
|
|
175
|
-
this.configKey = configKey;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Error thrown when a link operation fails
|
|
181
|
-
*
|
|
182
|
-
* @class LinkError
|
|
183
|
-
* @extends MAMAError
|
|
184
|
-
*/
|
|
185
|
-
class LinkError extends MAMAError {
|
|
186
|
-
/**
|
|
187
|
-
* @param {string} operation - Link operation (e.g., 'propose', 'approve', 'reject')
|
|
188
|
-
* @param {string} message - Error message
|
|
189
|
-
* @param {Object} details - Additional details (from_id, to_id, etc.)
|
|
190
|
-
*/
|
|
191
|
-
constructor(operation, message, details = {}) {
|
|
192
|
-
super(`Link ${operation} failed: ${message}`, 'LINK_ERROR', {
|
|
193
|
-
operation,
|
|
194
|
-
...details,
|
|
195
|
-
});
|
|
196
|
-
this.name = 'LinkError';
|
|
197
|
-
this.operation = operation;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Error thrown when rate limit is exceeded
|
|
203
|
-
*
|
|
204
|
-
* @class RateLimitError
|
|
205
|
-
* @extends MAMAError
|
|
206
|
-
*/
|
|
207
|
-
class RateLimitError extends MAMAError {
|
|
208
|
-
/**
|
|
209
|
-
* @param {string} operation - Operation that was rate limited
|
|
210
|
-
* @param {number} retryAfterMs - Time to wait before retry (ms)
|
|
211
|
-
* @param {Object} details - Additional details
|
|
212
|
-
*/
|
|
213
|
-
constructor(operation, retryAfterMs, details = {}) {
|
|
214
|
-
super(`Rate limit exceeded for ${operation}. Retry after ${retryAfterMs}ms`, 'RATE_LIMITED', {
|
|
215
|
-
operation,
|
|
216
|
-
retryAfterMs,
|
|
217
|
-
...details,
|
|
218
|
-
});
|
|
219
|
-
this.name = 'RateLimitError';
|
|
220
|
-
this.retryAfterMs = retryAfterMs;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Error thrown when operation times out
|
|
226
|
-
*
|
|
227
|
-
* @class TimeoutError
|
|
228
|
-
* @extends MAMAError
|
|
229
|
-
*/
|
|
230
|
-
class TimeoutError extends MAMAError {
|
|
231
|
-
/**
|
|
232
|
-
* @param {string} operation - Operation that timed out
|
|
233
|
-
* @param {number} timeoutMs - Timeout duration (ms)
|
|
234
|
-
* @param {Object} details - Additional details
|
|
235
|
-
*/
|
|
236
|
-
constructor(operation, timeoutMs, details = {}) {
|
|
237
|
-
super(`Operation '${operation}' timed out after ${timeoutMs}ms`, 'TIMEOUT', {
|
|
238
|
-
operation,
|
|
239
|
-
timeoutMs,
|
|
240
|
-
...details,
|
|
241
|
-
});
|
|
242
|
-
this.name = 'TimeoutError';
|
|
243
|
-
this.timeoutMs = timeoutMs;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Error codes enum for reference
|
|
249
|
-
*/
|
|
250
|
-
const ErrorCodes = {
|
|
251
|
-
// Resource errors
|
|
252
|
-
DECISION_NOT_FOUND: 'DECISION_NOT_FOUND',
|
|
253
|
-
CHECKPOINT_NOT_FOUND: 'CHECKPOINT_NOT_FOUND',
|
|
254
|
-
LINK_NOT_FOUND: 'LINK_NOT_FOUND',
|
|
255
|
-
|
|
256
|
-
// Validation errors
|
|
257
|
-
INVALID_INPUT: 'INVALID_INPUT',
|
|
258
|
-
MISSING_REQUIRED_FIELD: 'MISSING_REQUIRED_FIELD',
|
|
259
|
-
INVALID_FORMAT: 'INVALID_FORMAT',
|
|
260
|
-
|
|
261
|
-
// Database errors
|
|
262
|
-
DATABASE_ERROR: 'DATABASE_ERROR',
|
|
263
|
-
CONNECTION_FAILED: 'CONNECTION_FAILED',
|
|
264
|
-
QUERY_FAILED: 'QUERY_FAILED',
|
|
265
|
-
|
|
266
|
-
// Processing errors
|
|
267
|
-
EMBEDDING_ERROR: 'EMBEDDING_ERROR',
|
|
268
|
-
CONFIG_ERROR: 'CONFIG_ERROR',
|
|
269
|
-
LINK_ERROR: 'LINK_ERROR',
|
|
270
|
-
|
|
271
|
-
// Operational errors
|
|
272
|
-
RATE_LIMITED: 'RATE_LIMITED',
|
|
273
|
-
TIMEOUT: 'TIMEOUT',
|
|
274
|
-
INTERNAL_ERROR: 'INTERNAL_ERROR',
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Helper function to wrap unknown errors
|
|
279
|
-
*
|
|
280
|
-
* @param {Error|unknown} error - Error to wrap
|
|
281
|
-
* @param {string} context - Context for the error
|
|
282
|
-
* @returns {MAMAError} Wrapped MAMA error
|
|
283
|
-
*/
|
|
284
|
-
function wrapError(error, context = 'Unknown operation') {
|
|
285
|
-
if (error instanceof MAMAError) {
|
|
286
|
-
return error;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
290
|
-
const stack = error instanceof Error ? error.stack : undefined;
|
|
291
|
-
|
|
292
|
-
return new MAMAError(`${context}: ${message}`, 'INTERNAL_ERROR', {
|
|
293
|
-
originalError: message,
|
|
294
|
-
originalStack: stack,
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Helper function to check if an error is a MAMA error
|
|
300
|
-
*
|
|
301
|
-
* @param {unknown} error - Error to check
|
|
302
|
-
* @returns {boolean} True if MAMA error
|
|
303
|
-
*/
|
|
304
|
-
function isMAMAError(error) {
|
|
305
|
-
return error instanceof MAMAError;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
module.exports = {
|
|
309
|
-
// Base class
|
|
310
|
-
MAMAError,
|
|
311
|
-
|
|
312
|
-
// Specific error types
|
|
313
|
-
NotFoundError,
|
|
314
|
-
ValidationError,
|
|
315
|
-
DatabaseError,
|
|
316
|
-
EmbeddingError,
|
|
317
|
-
ConfigurationError,
|
|
318
|
-
LinkError,
|
|
319
|
-
RateLimitError,
|
|
320
|
-
TimeoutError,
|
|
321
|
-
|
|
322
|
-
// Utilities
|
|
323
|
-
ErrorCodes,
|
|
324
|
-
wrapError,
|
|
325
|
-
isMAMAError,
|
|
326
|
-
};
|
package/src/index.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MAMA Core - Main exports
|
|
3
|
-
*
|
|
4
|
-
* Shared modules for Memory-Augmented MCP Assistant.
|
|
5
|
-
* Used by mcp-server, claude-code-plugin, and standalone packages.
|
|
6
|
-
*
|
|
7
|
-
* @module mama-core
|
|
8
|
-
* @version 1.0.0
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const embeddings = require('./embeddings');
|
|
12
|
-
const embeddingCache = require('./embedding-cache');
|
|
13
|
-
const embeddingClient = require('./embedding-client');
|
|
14
|
-
|
|
15
|
-
const dbManager = require('./db-manager');
|
|
16
|
-
const dbAdapter = require('./db-adapter');
|
|
17
|
-
const memoryStore = require('./memory-store');
|
|
18
|
-
|
|
19
|
-
const mamaApi = require('./mama-api');
|
|
20
|
-
const configLoader = require('./config-loader');
|
|
21
|
-
const relevanceScorer = require('./relevance-scorer');
|
|
22
|
-
const decisionTracker = require('./decision-tracker');
|
|
23
|
-
const tierValidator = require('./tier-validator');
|
|
24
|
-
const progressIndicator = require('./progress-indicator');
|
|
25
|
-
|
|
26
|
-
module.exports = {
|
|
27
|
-
...embeddings,
|
|
28
|
-
embeddingCache,
|
|
29
|
-
...embeddingClient,
|
|
30
|
-
|
|
31
|
-
...dbManager,
|
|
32
|
-
...dbAdapter,
|
|
33
|
-
...memoryStore,
|
|
34
|
-
|
|
35
|
-
...mamaApi,
|
|
36
|
-
...configLoader,
|
|
37
|
-
...relevanceScorer,
|
|
38
|
-
...decisionTracker,
|
|
39
|
-
...tierValidator,
|
|
40
|
-
...progressIndicator,
|
|
41
|
-
};
|